pax_global_header00006660000000000000000000000064134335035500014513gustar00rootroot0000000000000052 comment=ba4af2bde7af8de383070598be28b5500694d14c xawtv-3.106/000077500000000000000000000000001343350355000126755ustar00rootroot00000000000000xawtv-3.106/.gitattributes000066400000000000000000000000641343350355000155700ustar00rootroot00000000000000Makefile export-ignore Makefile.clean export-ignore xawtv-3.106/.gitignore000066400000000000000000000015441343350355000146710ustar00rootroot00000000000000*.dep *.o *.so .pc/ arch-i686-linux/ arch-x86_64-linux/ autom4te.cache/ config.h config.h.in config.log config.status configure console/dump-mixers console/fbtv console/radio console/record console/scantv console/showqt console/showriff console/streamer console/ttv console/v4l-conf console/v4l-info console/webcam debug/xvideo libng/libng.a libng/plugins/drv0-v4l2.c.orig man/v4l-conf.8.orig mk/console_fbtv.tmp mk/console_ttv.tmp mk/libng_plugins_read-dv.tmp mk/libng_plugins_write-dv.tmp vbistuff/about.html.h vbistuff/alevt.css.h vbistuff/alevtd vbistuff/bottom.html.h vbistuff/ntsc-cc vbistuff/top.html.h x11/motv x11/MoTV.ad x11/MoTV.de.ad x11/MoTV.de_DE.UTF-8.ad x11/MoTV.fr_FR.UTF-8.ad x11/MoTV.it_IT.UTF-8.ad x11/MoTV.fr.ad x11/MoTV.h x11/MoTV.it.ad x11/mtt x11/mtt.h x11/pia x11/propwatch x11/rootv x11/v4lctl x11/xawtv x11/Xawtv.h x11/xawtv-remote patches/ xawtv-3.106/.travis.yml000066400000000000000000000011071343350355000150050ustar00rootroot00000000000000language: cpp compiler: gcc dist: bionic notifications: email: recipients: - mchehab@kernel.org on_success: change on_failure: always cache: directories: - $HOME/.ccache - $HOME/pbuilder-bases matrix: include: - env: TARGET_OS=bionic - compiler: clang env: TARGET_OS=bionic before_install: - "${TRAVIS_BUILD_DIR}/travis/${TRAVIS_OS_NAME}.${TARGET_OS}.before_install" install: - "${TRAVIS_BUILD_DIR}/travis/${TRAVIS_OS_NAME}.${TARGET_OS}.install" script: - "${TRAVIS_BUILD_DIR}/travis/${TRAVIS_OS_NAME}.${TARGET_OS}.script" after_script: - ccache -s xawtv-3.106/COPYING000066400000000000000000000430761343350355000137420ustar00rootroot00000000000000 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. Copyright (C) 19yy 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. , 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. xawtv-3.106/Changes000066400000000000000000001676401343350355000142060ustar00rootroot000000000000003.106 ===== * Use standard c99 designated initializers * Show if lirc is enabled or not when configuring it * Don't need need to call abs() for rdrift and vdrift * Get rid of an unused function at flt-smooth * Use hexa for non-printable codes at ntsc-cc code * Move -Llibng to LD_FLAGS at makefile * Add xawtv3 to Tavis CI build integration * Get rid of VIDIOC_G_PARM ioctl * Remove an unused file from git and ignore auto-generated files * Get rid of V4L1 support, as V4L1 API got removed from Kernel in 2010. * Update videodev2.h file to a later version * Update the error code at vbi-gui to reflect the name of the V4L2 ioctl * Fix fbtv application for it to properly handle camera bytesperpage aligments and to properly display texts over over the camera streaming screen 3.105 ===== * add fbtv support for modern console fonts * fix fbtv output when byterperline is greater than the number of filled bytes * add help for fbtv and improve its man page * allow using just the font name on fbtv * Cleanup most warnings when building it, fixing some potential bugs * Add support for AC_HEADER_MAJOR, in order to support upcoming glibc versions * Allow ./configure --disable-alsa to compile when alsa is available * x11: get rid of deprecated XKeycodeToKeysym function * get rid of unused libXp at Makefile 3.104 ===== * disable DGA if client is not local, fixing usage over ssh * Drop supplementary group IDs when dropping privileges * Add desktop and appdata files for xawtv, motv and mtt * Fix mtt not being able to tune tv channels * Remove superfluous ; add end of functions * Add a workaround for bttv kernel driver planar fmt width bug * Allow setting alsa_latency from ~/.xawtv * Fix not being able to get a larger latency on capture devices with small max period sizes * prefer CAP_STREAMING over CAP_READWRITE * Fix segfault under certain conditions 3.103 ===== * Improve alsa stream handling * Add support for alsa audio loopback to the radio app * Add support for multiple-band (AM+FM) tuners to radio app * Tons of other bugfixes + improvements for the radio app * Fix xawtv window flashing to black when changing channel or taking a snapshot * Fix crackle crackle sound on mp34xx cards when changing channel * Various other bugfixes 3.102 ===== * Improve alsa latency handler and document the -alsa-latency parameter * Improve alsa handling, fixing a cut and past error that causes breakages with some cards * Improve audio parameters detection * fix build with ld --as-needed --no-copy-dt-needed 3.101 ===== * Man fix to remove mention of v4l1, and describe libv4l instead * Fixes at fr/es manuals * Warning fixes * Addition of alsa streaming at xawtv: now, for devices with video associated with audio inputs. * Use X11 editres, instead of its on version, based on a port from a motif library released under a licence that is not GPL compatible * Add auto-detection logic for xawtv: by default, it will now seek for the first TV device. If not available, fall back to the first grabber device. * Add auto-detection logic for scanv: by default, it will now seek for the first TV device. If not available, fails. * Add optional support for libexplain at the v4l2/libv4l driver. Libexplain provides a more complete explanation for the error codes, helping developers to better track what's happened. * Don't expose tuner commands, on devices that are grabber or webcams at xawtv. 3.100 ===== * Update to the latest version of videodev2.h (kernel 2.6.38) * console/v4l-info: Fix control detection 3.99.rc6 ======== * Check the return value properly in debug print as well * fbtools: close file properly * use "dev/vbi0" instead of "dev/vbi" etc * MoTV: avoid some warnings when "motv" starts * Use modern fonts for MoTV and mtt * motif locale patch: use UTF-8 for charsets * Whitespace cleanups * Add an option on apps to select between libv4l and v4l2 driver * Add other XV attributes found on bttv + nv driver * Fix a small bug at the V4L2_CID_USER_BASE get ctrl logic * v4l-conf.c: Don't abend if VT_GETSTATE is not supported * v4l-info: Add support for V4L2_CID_USER_BASE * Check the return value for XF86DGAGetVideoLL() * Remove the remaining requirements for libFS * Remove a Fedora-specific comment * Fix xawtv DGA mode 3.99.rc5 ======== * Re-add locale to xawtv/motv/mtt * Print plugin info only when debug * avoid usage of "bool" * Change some obsoleted headers pathes * Remove dead code 3.99.rc4 ======== * Don't mix install-sh scripts * motv/mtt: Disable locale setting, as this cause failure * x11/xawtv: Disable locale setting, as this cause failure * Remove the legacy xfs connection for FB 3.99.rc3 ======== * Auto-detect libquicktime include directory * Add detection for glib2 * Fix a memory leak at drv0-v4l2 * Auto-detect KFreeBSD variant * vbi-conf.8 reports that it still in man1 section instead of man8 * Improve xft library detection 3.99.rc2 ======== * Add a libv4l driver, using it as default * Now, it displays the optional features that are configured at ./configure * Use fonts found on modern (Xorg) setups 3.99.rc1 ======== * Fixed radio backport to V4L2 * es,fr manpages are now in UTF-8 * Auto-detect Xorg default place for apps * Remove the old obsolete V4L2 driver 3.98 ==== * Re-added v4l-info/v4l-conf, just removing V4L1 bits * Some fixes, backported from Fedora tree 3.97 ==== * Fixed a compilation error * Ported a few applications to V4L2 * Removed V4L1 support 3.96 ==== * misc minor fixes collected at Fedora 12. * Fix requirement of /dev/vbi instead of /dev/vbi0 on scantv. * Fix compilation with Xorg and remove the --x_libraries parameter from the configure script (as, on Xorg, X11 libraries are at /usr/lib). * Now, providing that all build dependencies are satisfied, just typing make after the download is enough to generate/run configure and build the tools. 3.95 ==== * misc minor fixes collected over time. * make it build with gcc4. 3.91 ==== * misc minor bugfixes. 3.90 ==== * bugfix release (was intented to be 3.88.2, but a debian NMU f*cked up my version numbering ...). 3.87 => 3.88 ============ * removed xxl core file from source tree. 3.86 => 3.87 ============ * fixed "default = grabdisplay" not working. * added Xrandr support. * lots of mtt (motif teletext viewer) tweaks. * 64bit fixes for record + showriff 3.85 => 3.86 ============ * tweaked font sets. * some FreeBSD fixes. * various minor build fixes 3.84 => 3.85 ============ * added UYVY support. 3.83 => 3.84 ============ * fix startup segfault in xawtv + motv. 3.83 => 3.84 ============ * fixed a number of gcc 3.3 warnings, also did some other cleanups while being at it. * Multimedia keyboard support. * commented alsa-mixer plugin (segfaults for me). 3.82 => 3.83 ============ * compile fixes. * propwatch updates. * added config option to disable _NET_WM_STATE_FULLSCREEN support. * added config option to move the OSD (Alex Ibrado ). * minor radio tweaks (DAVID BALAZIC ). 3.81 => 3.82 ============ * compile fixes again ... * v4l-conf fix (Kyosti Malkki ). * wmhook fix (Marcin Krzyzanowski ). * still a few compile bug left ... * s/recode/iconv/. iconv should (unlike recode) be present on almost every system as it comes with glibc ... * wmhooks fixes. * added -driver command line switcht to xawtv/motv. 3.80 => 3.81 ============ * even more compile fixes. * fixed some core dumps (freqtab changes init bugs in fbtv + ttv). * new config option for webcam (times=, much like once). 3.79 => 3.80 ============ * misc small compile fixes and bugfixes. 3.78 => 3.79 ============ * More v4l2 fixes. * Some infrastructure for dumping structs. Used that for completely rewritten debug output of the video4linux plugins. There is also a new utility called "v4l-info" which uses this. * moved frequency tables into config files instead of having them compiled-in * added "group = " tag to channels. motv builds submenus per group using this. 3.77 => 3.78 ============ * build fixes. * new v4l2 module fixes. 3.76 => 3.77 ============ * fixed broken alevtd * swapped gnome + netwm protocol checks (wmhooks.c), netwm is preferred now. * Added showqt utility (dumps structure of QuickTime files like showriff does for AVI files). * Added vdr control code. * webcam's archive function now creates directories if needed. * fixed spec file. * started adding support for reading/writing raw dv files via libdv. Probably not that useful yet, at least my box is far away from being able to encode dv streams in real time. Even playback drops more than 50% of the frames. * added alsa mixer plugin (Malte Starostik ). * added plugin for new v4l2 api 3.75 => 3.76 ============ * reorganized screen blitting code (used for grabdisplay), moved that to another file. * Added OpenGL support (for hw-scaled RGB-images through gl-textures). * libng got support for reading movie files. Added libquicktime interface and AVI file parser. * started writing a playback utility (debug/play.c for now ...), should be able to playback all AVI/QuickTime movies recorded by xawtv/streamer. Other QuickTime files should work too as long as the codec is supported by libquicktime. * Added Australian Optus cable TV channels (contributor wishes to remain anonymous). * Added icons (by Pedro Romão , they are in contrib/) * some A/V sync tweaks for the recording code. * Correction of lens distortion for webcam (Frederic Helin ). 3.74 => 3.75 ============ * fixed fullscreen code. * webcam has a new option (wait=, see manpage). * selection / dnd / cut+paste fixes. * french translation (jose.jorge@cpam-auch.cnamts.fr) * webcam: support multiple ftp connections (idea from "D. Brian Larkins" ). * webcam: config options for text color (based on a patch from Bill Marr ) * lots of VBI changes: dropped libvbi directory, using libzvbi instead (http://zapping.ft.net, version 0.2.1 or newer). * unbundled the fonts, there is another tarball with all the fonts now. * some more Makefile tweaks. 3.73 => 3.74 ============ * rewrote Makefiles. No recursive make any more. Faster now, has sane dependences. Parallelizes (make -j) very good. Really needs GNU make now. * shuffled around source files. * xscreensaver support. xawtv/motv will prevent xscreensaver kick in when in fullscreen mode, and rootv can be used as xscreensaver hack now. * Changed the naming of the Xvideo extention command line switches, hope they are a bit less confusing now. * Changed motv mixer config, moved detection code to the oss sound plugin. * some spanish man pages (Ricardo Villalba ). * MoTV.ad: move osf* entries to the bottom of the translation tables. * minor alevtd fix (merge from webfsd). 3.72 => 3.73 ============ * new YUV4MPEG format support (Juan Antonio Zubimendi ). * made grabdisplay check the aspect ratio configuration. * dropped quicktime4linux support, using libquicktime (http://libquicktime.sf.net) instead. * added "fixed" as last fallback to all font sets. * made plugin Makefile delete old, incompatible plugins. * added iso8859-15 led font, for all these foobar@euro locales ... 3.71 => 3.72 ============ * v4l2 fixes. * irish frequency table fix (Dan Lindstrom). * made the snap command write files using "write tmpfile + rename" to allow atomic updates. 3.70 => 3.71 ============ * The idea to drop ~/.lircrc altogether wasn't that great, doesn't work well with multiple apps receiving lirc events... xawtv reads it again if present, but you don't need one. Check README.lirc for the details. * Fixed buffer overflow in "xawtv-remote vtx aaaaaa..." 3.69 => 3.70 ============ * Hacked up configureable input event mapping infrastructure. There is a new [eventmap] section in the config file. Check the xawtvrc man page for details. * Made lirc code use the event mapping. xawtv does not use the ~/.lircrc file config any more, but is configured using the [eventmap] mentioned above. xawtv also has a reasonable default configuration now, so lirc works out-of-the-box. * Made midi input configurable via event mapping. * Made joystick input configurable via event mapping. * Made fbtv's ncurses kbd keys go through event mapping. * added -a switch to scantv. * fixed some bugs in handling TV stations which are specified by frequency instead of channel name. * fixed volume control segfault. * added tooltips for motv (needs OpenMotif 2.2). * color support for bktr driver (Rolandas Naujikas ). 3.68 => 3.69 ============ * added API versioning to the plugins. * added attributes to struct ng_filter, so you can control filter settings via GUI. * added gamma filter plugin. * updated documentation (libng/OVERVIEW), added some hints for filter plugin programming. Note: motv has a menu to deal with filters, xawtv has no GUI elements yet. * more record tool improvements (level trigger for recording). * removed fixed 0-65535 range for integer attributes, using min and max values instead. This also affects the attributes specified within the config file. * Some improvements for the radio utility. * make v4l-conf run most code as real user, not root. That should improve security and also make v4l-conf not fail on ~/.Xauthority located at root-squash mounted NFS dirs. * hacked up a test app to play with OpenGL textures for video playback. Not built by default. Needs Motif. Check src/gl.c if you wanna have a look. 3.67 => 3.68 ============ * more build/install fixes. * various new switches for the record tool. * fixed channel switching bug, the long delay is gone now ... * xawtv/motv keep track of TV norm and input source per TV station now. * fixed audio mode (mono vs. stereo) handling for v4l2. * increased audio mode check delay to get better results. * replaced rpm specfile 3.66 => 3.67 ============ * NOTE: take this one a bit with care, it isn't tested that much and rushed out (after x-max + newyear holidays) because it has various build fixes. Also various patches from other people are integrated, I don't have anything pending in my inbox now. If I missed / broke something, please resend patches against this version. * more plugin support in libng. * some libng stuff is now implemented as plugin. * build plugins with -fPIC. * fixed FreeBSD build problems (due to new plugins). * fixed bugs in fbdev code. * moved OSS code to libng. * avevtd patches (Gerald Schnabel ). * ssh support for webcam. 3.65 => 3.66 ============ * various scantv fixes. * added "show" command for v4lctl, updated man-page. * LFS bug in showriff fixed, now it finally displays large files correctly. * Added experimental image filtering plugin interface, for now only works for the x11 screen in "grabdisplay" mode. * Made it build with both alsa 0.5.x and 0.9.x. * Made it build without X11 installed. 3.64 => 3.65 ============ * fixed FreeBSD build problems. * control *tv via joystick (based on patches from "W. Michael Petullo" ). * fixed fbtv cursor keys to work as documented (and like they work in xawtv). * splitted reading and parsing of the config file to fix some minor initialization order issues. * more alevtd fixes/patches (Alessandro Fausto). * added window clipping fixups (range checks, drop empty clips, try merge clip windows). * removed chromakey color flash on channel switches * added -c option for scantv. * full devfs support for fbtv. 3.63 => 3.64 ============ * fixed build problems without alsa installed. * alevtd: subpage link list tweaks. * alevtd: clear cache on SIGUSR1. * fixed a segfault in fbtv. 3.62 => 3.63 ============ * tried to reduce the channel switch delay a bit. * motv: italian translations (Mij ). * wrote README.translate * wrote some code to control xawtv/motv/fbtv via alsa midi. * moved lirc code to xt.c, added lirc support to motv. * "fbtv -M" + v4l2 fixed. * ttv: ignore aspect ratio. * ttv: segfault-at-exit fixed. * added subpage link list to alevtd pages (Alessandro Fausto ). * updated libvbi to alevt 1.6.0 code. 3.61 => 3.62 ============ * fixed italy frequency table (Gianluca ). * oss changes to improve audio/video sync with some sound cards. * Fancy DnD icon for motv. * preferences dialog for motv. * fixed segfault when typing '00' on the keypad. * fixed VIDIOCSWIN error handling. * major changes for the radio app: Added reasonable command line parsing, can be easily used non-interactively now. Added station scanner (Gunther Mayer ). * added frequency table for argentina ("KciNicK M. M." ). * MIT-SHM support is no longer a compile time option. * Fixed MIT-SHM bug in xv.c * v4l2 format assignments fixed (fixes swapped red+blue for yuv) 3.60 => 3.61 ============ * keypad-partial fix. * record utility documentation update. * movie recording: display audio/video times relative to real time. * added some examples to "streamer -h" output. * minor fix for v4lctl. * reactivated "xawtv-remote webcam" * fixed "xawtv-remove movie driver ..." for motv. * Some minor DnD fixes. * audio mode fixes * added keypad support for motv. * temporarely suspend grabdisplay for attribute changes. * mjpeg-quality config option is gone, jpeg-quality is used everythere now. 3.59 => 3.60 ============ * Added proper cleanup code for DnD. This breaks DnD with KDE apps because they _first_ signal the transfer is finished, _then_ try to read the tmp file which might be already deleted at that point ... * separated primary selection (aka clipboard) and DnD selection data. * fixed segfault with DnD + not capturing devices (i.e. Xvideo). 3.58 => 3.59 ============ * keypad-partial fixes. * added a few more buttons to motv's toolbar. * fixed v4l-conf compile problem with v4l2-patched kernels. * added console mode for record (Gergely Tamas ), also added a switch to set the sample rate and fixed some minor problems. * Added support for selections (clipboard & dnd) to motv. * Fixed missing "setinput next" 3.57 => 3.58 ============ * Makefile / build process updates. make depend is done automagically now if needed. Parallel builds (make -j) work better. Enabled a few more warnings. * new keypad-partial config option (Pawel Sakowski ). * made oss mixer work again for fbtv. * merged some stuff from Kawamata/Hitoshi 's patches. * finally multithreaded compression for those of you with SMP boxen. * text/plain support for alevtd (Adam Sampson ). * Documentation updates. 3.56 => 3.57 ============ * changed oss mixer control internals * made 4:3 aspect ratio the default. * more Motif GUI fixes. 3.55 => 3.56 ============ * chromakey tyops fixed. * updated / reorganized the manual pages. * wrote a manual page for motv. * lots of motv improvements. * streamer also accepts hh:mm:ss for -t now (W. Michael Petullo). * added color space conversion functions for yuv 420 planar (Sunjin Yang ). 3.54 => 3.55 ============ * some fbtv fixes. 3.53 => 3.54 ============ * NOTE: starting with 3.53 "make depend" is REQUIRED to build xawtv. * more motif code / fixes. * moved devices.c to libng, added init function for switching to devfs namespace. * made xawtv/motv more quiet by default, prefixed some messages with "if (debug)". * copyed new fb font rendering from fbi for fbtv. * Made grabdisplay in fbtv work again. * Added german application defaults for motv. * fixed default dsp device. * added v4l2 support to v4l-conf. 3.52 => 3.53 ============ * various build fixes (aa.c / build without Xvideo / FreeBSD). * s|/dev/video|/dev/video0|, also moved stuff to a single file. * ttv fixes, made ttv use the conversion functions. 3.51 => 3.52 ============ * Added ttv -- a aalib based tv viewer. * wrote some docs for libng. * optimized the tracking code for the window clipping. * more motif code / fixes. * added support for planar yuv (grabdisplay via Xvideo). * bytesex fixes for showriff. 3.50 => 3.51 ============ * Major documentation update * Some more motif tweaks. Build it with --enable-motif if you have openmotif installed and want to have a look, comments about the new GUI are welcome. motv is the exectutable (anyone has a idea for a better name ?). * disabled packed pixel yuv for FreeBSD (broken). * added -hwscan option. 3.49 => 3.50 ============ * lot of new motif stuff * added a workaround for a bttv bug. * minor fix in subtitles script. 3.48 => 3.49 ============ * added archive function to the webcam utility. * config file tags are case insensitive now. * changed webcam to use libng conversions (i.e. it can deal with yuv-only devices now). * raw yuv data support for quicktime (with help from W. Michael Petullo ) * more new motif stuff. 3.47 => 3.48 ============ * added config file entries for record settings. * fixed some minor FreeBSD build problems on. * Managed it to get the locate stuff right for the motif version. * fixed a rate control bug. * fixed a bug in vtx display code. * frequency table for south africa (Hendrik Visage ) 3.46 => 3.47 ============ * fixed more makefile flaws (which broke rpm -ta). * fixed a bug in color space conversion (FUKUCHI Kentarou ) * reactivated chromakeying code. Untested. * Bumped the timeout for VIDIOCSYNC from one to three seconds. Seems some USB-Devices need more time for the first frame. * dropped Xaw3d support altogether. * added back in some 3D effects using the new features of the XFree86 4 Athena widgets. 3.45 => 3.46 ============ * fixed Makefile bug (which caused fonts not being included in the tarball). 3.44 => 3.45 ============ * Xaw3d disabled by default -- it crashes xawtv with i18n turned on. 3.43 => 3.44 ============ * fixed minor bug in grab-v4l.c * rewrote much of the conversion/compression code, made it reentrant. * moved the conversion/compression code to a thread. * rewrote the grabdisplay code. * The -xvideo and -device switches implicitly turn on/off the Xvideo extention. * The vtx command (see xawtv-remote man-page) can parse ANSI color sequences too. * new shell script to display subtitles. * update for cc (Adam ). Moved the utility out of the contrib, renamed it to ntsc-cc (to avoid name clashes with the C compiler) and included it into the Makefile tree, so it gets compiled and installed by default. Wrote a short man page for it. * some progress on the motif version. * fixed a bug in webcam (Kelsey Hudson ). 3.42 => 3.43 ============ * webcam update (tmp file fix, allow to give a config file as argument) * turned off the *&%($ debugging code in grab-v4l.c * some bugfixes in sound recording code. * made the motif version compile again (still very incomplete and not built by default). 3.41 => 3.42 ============ * Added color space conversion functions for 4:2:2 yuv (packed) to rgb. * Added color space conversion functions for 4:2:2 yuv (planar) to rgb. * minor cleanups in the conversion functions. * some fixes from Kawamata/Hitoshi . 3.40 => 3.41 ============ * changed xawtv's internal time representation. * rewrote rate control again. xawtv can puts frames twice into the queue now, recording @ 25fps without frame drops is no problem any more. * made video stream recording optional. streamer can record video only, video/audio and audio only (xawtv GUI not updated yet). This implies that for avi and quicktime streams specifing a video format isn't optional any more. If no video format is given, streamer will not pick one for you, but will record audio only. * reorganized sound recording code a bit, added byteswapping support. * MIT SHM failures with XvImages are catched now (=> hw scaling on a remote display should work -- untested) * gracefully fallback to "normal" rgb ximages if hw scaling with Xvideo failes because the v4l driver can't capture packed yuv. * 0.05 MHz steps for the radio app (Nils Kassube ). * fixed one more segfault. * updated README.recording 3.39 => 3.40 [the segfault bugfix release] ========================================== * 3 lines fix in grab-v4l.c. 3.38 => 3.39 ============ * fixed a bug in color space conversion. * fixed minor initialization bugs in grab-v4l.c + grab-v4l2.c * added attribute reading for BSD. * added a switch to alevtd to set the vbi device. 3.37 => 3.38 ============ * attribute fixes for v4l and v4l2. * implemented boolean attributes. * deleted some obsoleted (by the new attr handling) status variables, fixed various places which used the old ones (with *ahem* intresting side effects). 3.36 => 3.37 ============ * minor fixes and tweaks in the capture code. * added missing libng initialization to fbtv, streamer and v4lctl (Oops...). 3.35 => 3.36 ============ * better fullscreen switching in xinerama. * added the missing config.h include to xvideo.c * moved some code into the new libng directory. * rewrote compression + color space conversion. * Fixed v4lctl segfault. * Fixed a minor bug in v4l code (PAL-M with bttv works again). * updated webcam, uses libng now. It expects TV norm and video source as strings ("PAL" instead of "0", ...) now. Works also on FreeBSD, switches between v4l + v4l2 at runtime not compile time. * made Makefiles portable. 3.34 => 3.35 ============ * fixed segfault in scantv. * don't list "normal" ioctl failures for v4l2 (i.e. the ones which are do *not* indicate some error the user should care about). * rewrote xawtv's attribute handling. * made the -bpp switch work again. * detect xinerama (not used yet). 3.33 => 3.34 ============ * attribute fixes for Xvideo and v4l2. * fbtv bugfixes. 3.32 => 3.33 ============ * lots of fixes: bugs in the new capture code, portability problems. * fixes in the bktr support, can do full framerate now, added yuv capture. Think it works reasonable well now (so I can list BSD as "supported" on the Homepage without getting flamed for it :-) 3.31 => 3.32 [non-public release] ================================= * fixed a few bugs in the new v4l code, re-added capture using read(). * removed videodev.h from the tarball, using the kernel's header file instead. This means xawtv will not build on 2.0.x kernels any more. * made v4l2 support working again, added ioctl tracking for easier debugging. I have no audio yet, althrouth this might be a bttv2 problem as bttv2 + v4l interface doesn't work either but bttv 0.7.x is fine. * It builds cleanly on FreeBSD, bktr support working again. Sort of. Overlay has some intresting clipping issues, capture works without rate control and 12 fps max. No yuv capture yet. 3.30 => 3.31 [non-public release] ================================= * Got a few pointers for malloc debuggers (http://www.dmalloc.com, http://freshmeat.net/projects/njamd/, http://www.cbmamiga.demon.co.uk/mpatrol). Thanks to all, I'll have a look next time I need one... * started rewriting the driver interfaces (new attribute handling, switch over to grab-ng.h structs + interfaces). v4l and Xvideo are ported and passed brief testing, v4l2 + bsd are temporarely broken. * some jpeg/mjpeg compression fiddeling. 3.29 => 3.30 ============ * fix build problems. 3.28 => 3.29 ============ * next chunk of the capture core rewrite. * moved audio recording to a thread, this hopefully fixes a few problems (should stop audio overruns, doesn't need select support in the driver any more). * Added a fancy status display which hopefully helps to trouble-shoot syncronisation problems. * major update for README.recording * killed the --enable-efence configure option. Isn't thread safe :-( Anyone knows a free malloc debugger which is? * added autoconf tests for getopt.h / getopt_long * streamer can write raw video data (again). 3.27 => 3.28 ============ * completed v4l ioctl tracking. * bug fixed in quicktime code. * scantv fixes. * fixed bugs in the movie recording code (memory leak, uncatched failures). 3.26 => 3.27 ============ * (hopefully) fixed rpm build problems. * started adding ioctl tracking to the v4l code. * fixed a bug in overlay code (uninitialized video_picture.depth) 3.25 => 3.26 ============ * initialization order bug in volume control fixed (thanks to rolf.siebrecht@t-online.de). * added a few options to scantv, allowing it to be used non-interactive. * added GUI support for the rewritten capture code, recording movies with xawtv works again. 3.24 => 3.25 [non-public release] ================================= * teached the v4l code to turn off (and back on) overlay when fiddeling with SPICT and SWIN ioctls for read() capture. Mixing overlay and read() capture works now without funny effects. * fixed a bug in grabdisplay error handling (which made xawtv die with "aiee: grab_fps==0" because it forgot to clean up on capture errors). * started a major rewrite of the core capture code. See grab-ng.h Step one: - rewrote the movie output code. - writeavi.c is reentrant now. - Added quicktime support (lousely based on W. Michael Petullo's quicktime patches). - Added support for recording image files with audio in a separate wav file. - xawtv's movie recording is temporarely broken, GUI updates not in place yet. You'll have to use streamer for now, sorry. 3.23 => 3.24 ============ * -xvport does _really_ work now... * Improved the OpenBSD port. Clipping works better now, single frame capture works. * decreased the timeout for hiding the mouse pointer. * fixed onscreen display logic. * removed 320x240 capture size limit for yuv (Xvideo-scaled) grabdisplay mode. * fixed rate control (and killed the anonying but harmless error message in grabdisplay mode). * Added cc.c patches (Adam ). 3.22 => 3.23 ============ * added -xvport option to set the Xv port. * Killed all the old mouse pointer handling code and the assorted config config options / cmd line switches. Replaced it with a simple timeout logic: If you don't move the mouse for some time xawtv will hide the pointer. Any pointer motion event will show the pointer again. * new xawtv-remote command: showtime. 3.21 => 3.22 ============ * FastText for alevtd (Malcolm Parsons ). * xawtv-remote patch (Adam ) * misc bugfixes * netwm support (Dirk Mueller ) 3.20 => 3.21 ============ * specfile fixed (app-defaults are missing). * compile fix for alevtd. * bugfix in v4l2 code. * removed the boring core dump from the source tree. 3.19 => 3.20 ============ * minor man-page updates. * OpenBSD port starts working: xawtv compiles, overlay works. Clipping doesn´t work for some reason (It´s me or the driver?). As FreeBSD uses the same driver it should be easy to make xawtv work there too. * Plenty of autoconf tweaks to make the whole package compile cleanly on BSD. * converted a number of structs to "field: value" style initialization. * Added audio= option to ~/.xawtv * manpage updates. 3.18 => 3.19 ============ * Added libvbi (vbi decoding code from alevt) * Added scantv: does a channel scan, picks up the station id from vbi, writes a xawtv config file. * minor webcam tweaks * Added alevtd - a http server for videotext pages. 3.17 => 3.18 ============ * off-by-one bug in colorspace.c fixed. * Documentation updates * webcam patches from les Niles * libjpeg dependency changed from optional to required (webcam never worked without libjpeg before, and libjpeg is present on nearly any linux system anyway, so...) * Added triggers to the webcam - compare the current image with the last uploaded one, try to figure if it has changed and upload only if it has... 3.16 => 3.17 ============ * new -w switch for streamer (Santiago Garcia Mantinan ) 3.15 => 3.16 ============ * The 3.15 tarball had a big binary included by mistake. * Some v4l2 fixes. 3.14 => 3.15 ============ * fixed a bug in the channel editor (did'nt saved the input for new channels) * shuffled around some code -- split Xaw and general Xt/X11 code. * added max size check to v4l2 overlay code. * added (un)mute to rootv 3.13 => 3.14 ============ * Added a "fix-aspect-ratio" option (quick guide: add "radio=4:3" to the [global] section). * fixed a few bugs in the new avi recording code. audio+video should work again. * A fullscreen option in the config file enables the VidMode extention now. * added read()-based capture support to the webcam. Untested. 3.12 => 3.13 ============ * some xvideo finetuning * Added xvideo support to v4lctl * Added rootv utility * Added debian package information * Added small script to pick up channels from videotext (*.de, Kabel1 pages, from Kai Fett, it is in contrib/vtx2xawtv) * webcam: moved ftp code to another source file, made it runtime configurable, wrote a man-page * wrote a manpage for showriff 3.11 => 3.12 ============ * Added the missing -D_REENTRANT to the Makefile * picked up the r@dio.mp3 client from the v4l list, put it into the contrib directory. * avi recording fix (audio+video stream length are identical now). * xawtv-remote protocol supports more than one command now. Commands are separated by a zero-length string, i.e. 'xawtv-remote foo "" bar' * new xawtv-remote command: vtx (interface for subtitles). Check the man-page for details. * webcam fixes. 3.10 => 3.11 ============ * fbtv grabdisplay fix, added G400 (works with G200 code too). * lirc code update (Ilya Konstantinov ). You might have to upgrade lirc to compile this version. * fixed the bool ressources. They are /really/ boolean now, i.e. "xawtv.vidmode: true" works now. * fixed a few bugs in the new recording code. * added support for freq= in ~/.xawtv. Untested. * avi writing code fix (broken size for one header field, found by David Gesswein ). Now the windows media player accepts xawtv's movies, cool... * Added command line parsing to showriff. Added a option to make it not stop on errors. * Fixed avi initialization code. It forgot to reset some counters, and thats why xawtv wrote broken avi files if you've recorded more than one... * Added new command to xawtv-remote: webcam. 3.09 => 3.10 ============ * fixed pthread compile problems. * first cut of the new recording code is active. It still needs some tweaking, but the basics work. v4l2 is'nt updated yet. audio+video syncronisation should work better. It is also possible to start/stop xawtv's avi-recording with xawtv-remote (see manpage). 3.08 => 3.09 ============ * extended showriff a bit * fixed broken rpm build * started rewriting the capture code. Switching over to threads, hope I get the audio/video syncronisation issues fixed this way. Right now it is dead code only... 3.07 => 3.08 ============ * reverted the frequency table split for europe. Turned out this was a bad idea... * Added options to enable dga/vidmode/... extentions. Vidmode is off by default now. This is the X Extention used for switching video modes, i.e. you'll have to start xawtv with "-vm" now to make it switching the video mode when going to fullscreen mode. * Added chroma keying support. * OpenDML support for avi. Now the intresting question: Who can playback or at least read these files? I don't know how to test this stuff... * Documentation updates 3.06 => 3.07 ============ * added troggle-mouse option (turn on/off mouse when swithing to fullscreen). * Added "stay on bottom". The "stay-on-top" command does now cycle between normal, top and bottom. * Added support for more than two capture buffers to grab-v4l.c 3.06 => 3.07 ============ * As usual, some bugfixes * values for volume, contrast, color, ... can be specified in percent too, just add '%' to the number: 50% == 32768 * more led fonts (latin2, koi8). Right now you have to set the app-defaults by hand to make use of them, need some more elegant way to switch charsets... * Added the UHF frequencies to europe-cable. It's used at least in Switzerland for cable TV. * some changes in yuv-to-offscreen handling for fbtv due to bttv changes. 3.05 => 3.06 ============ * Aiee, there was a stale .nfs file in the 3.05 archive... 3.04 => 3.05 ============ * new config options: turn on/off onscreen display, keypad mode, mjpeg quality. Check the man page for details. * Added XvPutImage support for grabdisplay mode. You'll need XFree86 3.9.17 to compile this release with Xv support. * rearranged the european frequency tables. They are splitted into broadcast and cable tv now. 3.03 => 3.04 ============ * fbtv font loader fixed. Nice showstopper, I should start the app at least once next time... * fbtv: ATI Mach64 backend scaler support works now with my revB iMac. Note: I still have some changes/minor bug reports in my incoming mailbox. Next release. I want to get this one out of the door quickly due to the fbtv problems. 3.02 => 3.03 ============ * broke fbtv font loading. * forgot writing Changes entries. 3.01 => 3.02 ============ * some finetuning for the keypad stuff. * G200 backend scaler support in fbtv. 3.0 => 3.01 =========== * Frequency table renaming was incomplete. The menu was'nt updated. * v4l-conf did'nt compile with 2.0.x kernel headers. * -c switch (select device) was broken. * added hard coded width limit for capture (buggy kernel bttv :-( ) 3.0rc1 => 3.0 ============= * Added station selection by "two-digit" selection. All stations are numbered in .xawtv order; entering two numbers within 5 seconds are interpreted as station number which should be tuned. You'll have to use the keypad in xawtv. Should work with lirc too (using the new "keypad" command). * global spellfix s/lauch/launch/. Attention, this might affect your config file too... * channel editor fixes. * F5-F12 (bright/color/... adjust by keyboard) is back. 3.0beta9 => 3.0rc1 ================== * updated v4l2 driver to the new interface. * some finetuning in the v4l2 driver. * cleaned up v4l-conf.c * renamed the frequency tables: removed the TV norm from the name to avoid confusion. * the usual set of bugfixes. 3.0beta8 => 3.0beta9 ==================== * webcam: can set input/norm now. * webcam: new cgi script for continously updated image (netscape only, uses serverpush). * the usual set of bugfixes. * write list index for avi files, mjpeg support (with some code from Michael Nastvogel ) mjpeg is still buggy... * added new frequency table for france (LOUIS-SIDNEY Rodolphe ) 3.0beta7 => 3.0beta8 ==================== * add a new switch (-a) to v4l-conf for setting the base address. This should make bttv configuration more easy if the X-Server lacks DGA support. * fixed the Makefiles for building in a subdirectory (i.e handle "mkdir build; cd build; ../configure && make" correctly). Now I can switch from ppc to i386 without "make distclean" :-) * Plenty of fixes for the channel editor. Seems nobody uses it, it must have been broken for weeks... * fbtv+xawtv refuse to work when installed suid root now. This is /not/ needed, only v4l-conf requires root priviliges. * v4l2: added tuner support, minor fixes. * added channel 36 for australia, this one was missing for some reason... 3.0beta6 => 3.0beta7 ==================== * Added autoscroll for the station menu. Xaw3d has some redraw problems with this. Probably some library bug, it does not happen with Xaw. Workaround idea anyone? * Misc bugfixes. * Documentation updates. To be continued... 3.0beta5 => 3.0beta6 ==================== * minor appdefauls fixes (wheel-mouse was broken). * config file parser rewritten. config file format is slightly modified, check the xawtv man page. * unbundled kradio to avoid the KDE compile hassle. * fullscreen fixes. * xawtv-remote supports multiple xawtv instances (querys all xawtv windows, not just the first one it finds, new switch '-i' to set the window ID when passing commands to xawtv). 3.0beta4 => 3.0beta5 ==================== * Added support for qcams (capture via read() system call) * yuv capture support (???, I've already deleted this mail) * radio fixes (from debian bugtraq) 3.0beta3 => 3.0beta4 ==================== * merged some new code for radio from Juli Merino * wrote a man-page for radio * added v4l-conf security fixes from Olaf Kirch * lirc bugfix. * xawtv can use another than the default visual now. Not bugfree yet. 3.0beta2 => 3.0beta3 ==================== * started updating the documentation. * reorganized source code tree. * removed the hardcoded maxsizes from grab-v4l.c * rewrote the attribute (color/hue/... + audio) handling 3.0beta1 => 3.0beta2 ==================== * ditched getopt(), using the Xt lib / X11 resources instead. This has the effect that the options work a bit different now. * added v4lctl utility. This allows to control alot v4l options from the command line. Obsoletes set-tv. * set-tv.c and streamer-old.c moved into the new "oldstuff" directory. * alot of xawtv fixes -- more features are working again. * fbtv is updated too. It should accept lirc commands now exactly like xawtv. 2.45 => 3.0beta1 ================ * Lot of internal changes. Separate the control code from the GUI. Simplifies the the xawtv-remote and lirc support, makes xawtv and fbtv share more code. Lot of stuff is broken currently... 2.44 => 2.45 ============ * Added a 'back' key which switches back to the last station tuned in. Mapped to BackSpace. Pressing backspace multiple times zaps between the last two stations. * The applications configured with "lauch=..." in ~/.xawtv are listed in a window now ('L' displays it). Allocation bug in the config file parser fixed. * switched back from double to float for X-Resources. 2.43 => 2.44 ============ * fbtv: added -q switch. This turns of status messages + clock, and fbtv does'nt reserve space for the status line (i.e. you'll can get true full screen) * started lirc support (currently some debug code only...) * changed float to double for X resources (Xaw scrollbars). This fixes problems on alpha and seems to work fine on intel. Hope I did'nt broke ppc... * fixed the radio programs (mute on exit). Untested. * webcam bugfix (switching to binary mode must be done _after_connecting). 2.42 => 2.43 ============ * Xvideo updates * some bttv changes to make it more compatible to the kernel version, added patches from Greg Alexander . * removed the "unmute-on-open", Updated the open/close for radio too. bttv radio should behave like all other radio drivers do (i.e. you have to open the device only if you want to change some settings). * Unbundled the bttv driver, my bttv code is available as another tar file at the same location (bttv-0.6.3a currently). * Errors (at least some :-) are reported with a dialog box now, not only to stderr. * channel handling is completely rewritten. If you change the frequency table, all frequencies for the programmed stations are recalculated now. * added some missing channels for japan. * streamer: the -i and -n switches work again. * xawtv dumped core with nonaudio devices, fixed (Pauline Middelink ) * updated videodev2.h 2.41 => 2.42 ============ * DON'T PANIC 2.40 => 2.41 ============ * completed avi recording code in xawtv. * renamed streamer to streamer-old and streamer-new to streamer. i.e. ther new streamer tool is the default now. * internal changes (for scanline length != image width) * added grabdisplay mode to fbtv. * Added some SR* channels to frequency table "pal-europe-east" (they are used in Poland). Hmm, maybe I should reorganize the whole channel setup, it starts getting difficuilt to maintain this the way it is implemented currently... * Alpha cleanups (use long for pointers etc.) from Ralf Uhlig * mklinux support for v4l-conf (Takashi Oe) * the "-x" option is gone, there are two new ones instead: "--nodga" to disable DGA and "--novm" to disable VidMode. * Added the capability to lauch programs from within xawtv. * removed the "mute-on-close" from the bttv driver. 2.39 => 2.40 ============ * Endian fixes from Takashi Oe (avi recording works now on big endian boxes). * xawtv can record avi movies directly. ^S brings you to this dialog. Please don't complain that you are missing options, this is on my TODO list. Everything you can set for streamer with command line options will be available in xawtv too. That stuff is work-in-progress, take the code as beta quality... * Bug fixes and internal changes. * security fixes from marc@suse.de: v4l-conf.c verifies the v4l major, /tmp symlink fix for vtx.sh. * msp3400 bug fixes, short programming (insmod option "simple=1") should work now. With newer msp34xx chip versions you'll should get stereo for NTSC TV and FM Radio. * more Xvideo code. 2.38 => 2.39 ============ * added --shift option to xawtv, this can be used to shift the image if it is outside the xawtv window. * added time display to fbtv. * stay-on-top added (works with gnome-compilant WM's) * patches from Takashi Oe for devices without audio/tuner support. * Found a new cool rpm feature (this one is new, eh?): "rpm -ta package.tar.gz" will build nice rpm. No extra spec file needed any more :-) * Started Xvideo support. * A few internal changes. 2.37 => 2.38 ============ * snapshot filename handling has changed: Files are saved with a timestamp (YYYYMMDD-HHMMSS) and channel in the filename. * xawtv is ^^^^ y2k compilant :-) * new config file entry: "jpeg-quality" * webcam utility updated. It's now working with the v4l2 winnov videum driver at http://www.BerlinOnline.de/spass/live_kamera/ * good news for *.fr: more msp3400 fixes, NICAM/AM should finally work now. 2.36 => 2.37 ============ * fixed minor compile problems on 2.0.x. 2.35 => 2.36 ============ * documentation updates, new FAQ for sound trouble. * streamer fixes (the endian fixes for 2.33 broke streamer) * driver synced up with bttv 0.6.3 * misc minor bug fixes 2.34 => 2.35 ============ * updated bttv to 0.6.2 and fixed the 2.0.x compile problems. * msp3400 problems with 2.2.0pre7+ fixed. 2.33 => 2.34 ============ * new NTSC-HRC frequency table, contributed by Erik Kiledal * 15 bpp was broken _again_. Fixed. * driver: msp3400 updates. Tried to make nicam mono/stereo switching work, but no success so far... * bttv updated to 0.6.1 * DPMS support (turn it off for fullscreen TV), contributed by Martin Denn 2.32 => 2.33 ============ * more patches from Takashi Oe (endian fixes, make fbtv work with DirectColor visual) * slighly modified audio handling (mono/stereo/bilangual, the driver returns the valid choices instead of the current state now). This affects both xawtv and driver and is _not_ backward compatible. * various minor changes. * new shell script for browsing videotext pages. requires a terminal with > 24 lines. 2.31 => 2.32 ============ * bugfix: changed bytesex.h to edian.h in x11.c * bugfix: overlay did'nt work without DGA. 2.30 => 2.31 ============ * more cleanups, the minor overlay flaws should be fixed. * coded up v4l2 overlay support -- completely untested. * minor fbtv fixes. * started to shuffle around some code from streamer. The new version has another name (streamer-new) for now. It can already handle v4l2, but can't be started from the xawtv's frontend dialog box. * remote display fixes (should work now if server and client have different bytesex). * Long options (thanks to Takashi Oe ). * "xawtv --help" prints all options. 2.29 => 2.30 ============ * much improved v4l2 support, it should be useable now. Only grabdisplay is supported so far, overlay-only drivers will not work (yet). * Some internal cleanups/rewrites, removed some hardcoded bttv stuff. Probably introduced a few new bugs... * pinned down the "segfault-on-exit" bug, credits to Electric Fence. * added the "webcam" tool (does capture, annotate, jpeg-compress, ftp-upload) * added showriff, for those who want to look into *.wav and *.avi files. * bttv: msp3400 + tuner compile problems due to 2.1.127 changes fixed. 2.28 => 2.29 ============ * rpm spec file fixes * minor msp3400 changes (for miro) * automatically generated diff's against Ralph's bttv version. * fixed the broken channel list length define (that only-79-ntsc-channels bug) * If there is a configuration problem, xawtv will disable overlay and continue instead of exiting. * remote display works. Don't try this unless you have a _real_ fast network or your own home network. Otherwise the network admin will ask what you are doing within five minutes... * started frontend dialog for streamer (Ctrl-S). Does already work, but needs some more options to be really useful. * started v4l2 support. 2.27 => 2.28 ============ * The 'V' key toggles capture on/off now. If capture is switched off, xawtv shows a static image. * Added options to set TV norm and input to streamer. Webcam cronjobs don't need set-tv any more :-) * Picked up some patches from video4linux@phunk.org for the bttv driver. The Miro PCTV pro might work in stereo, SECAM should work again. * Added autodetect for the Miro pro (untested). * RPMified xawtv, thx to Mark Cooke for the initial spec file. No, I'm not going to upload RPM's, neither source nor binaries. I'll upload the spec file, so you can easily build your own RPM's. * removed the experimental driver from the package, it will be available separate. * precompiled binaries are no longer included. 2.26 => 2.27 ============ * fixed the msp34xx problem with new (bt878) Hauppauge boards. 2.25 => 2.26 ============ * more driver PLL fixes * added Hauppauge tuner autodetect (using eeprom) * xawtv saves picture settings in channel switch now. 2.24 => 2.25 ============ * Moved E2-E4 to E1-E3 by mistake in 2.22. Reverted this. * radio is a nice curses application now. * The driver should work again for PAL. 2.23 => 2.24 ============ * v4l-conf changes * bugfixes in config file parser and channel editor. 2.22 => 2.23 ============ * bugfix: SExx channels did not work. (thanks to Michael Vogt ) * documentation updates. * increased the AUDIO_MUTE_DELAY value in bttv.c, this should reduce the channel-switch noise. * bttv: added changes from patch-2.1.120 2.21 => 2.22 ============ * up to date with bttv 0.5.15 * fbtv fixes and improvements (console switching works again) * streamer has a new switch to enable audio recording (off by default). * Channels renamed again: S1 .. S20 is SE1 .. SE20 now. This should be correct now. Reordered them (sorted by frequency now). * Channels map for east europe (PAL D/K) added. * channel editor bugfixes 2.20 => 2.21 ============ * Updated driver to 0.5.14, this one is NOT backward compatible older versions. * Updated Simon's i2c code. * Updated the programs too. * added avi recording to streamer. 2.19 => 2.20 ============ * Makefile fixes * Matrox off-by-1024 workaround improved. * fbtv fixes, moved generic fb stuff to a separate file. * grab-one is gone, there is streamer now. This one can do streaming capture (and of cource still grab single frames as special case). JPEG support added. 2.18 => 2.19 ============ * added man-pages for set-tv and fbtv * zapped SuSE and installed RH51, the included precompiled binaries are glibc now. * Unlocked the channel editor (overwrites the old config file now), it is in the man-page now and has the hotkey 'E'. Be carefull, it will kill all comments in the config file! 2.17 => 2.18 ============ * added xawtv-remote ("remote control" for xawtv) * hopefully completed channel list editor. But still in debugging mode, it writes the config file to $HOME/.xawtv.out 2.17 => 2.18 ============ * showstopper fixed: xawtv segfaults if there are channels without hotkeys in your $HOME/.xawtv (thanks to Enrico Scholz ) * v4l-conf fixed (was broken again for non-DGA Servers line AccelX) 2.16 => 2.17 ============ * started channel list editor (Ctrl-L for now, will be changed later). Not completed, you can't save your changes yet. * driver updates * added session management to kradio. Sort of. The KDE session management functions have a major design bug, probably this works with the bug-compatible kwm only :-( * updates README * wrote Programming-FAQ * And probably a few other changes I forgot about... 2.15 => 2.16 ============ * fixed v4l-conf, handles 15bpp now * configure changes: try "./configure --help", there are some --enable-foo/--disable-foo options now (default for them is enabled). * moved some common code to separate source files. * a few small driver fixes. * added the -c switch to grab-one 2.14 => 2.15 ============ * as allways, a few bug-fixes * added the -c switch to set-tv * i2c problems with hauppauge cards hopefully fixed now. Check bttv driver's Makefile, the code disabled by default (we don't know what happens with other boards...) * msp3400 uses soundcore instead of sound module (no oss needed any more, tnx to Thomas Sailer ) 2.13 => 2.14 ============ * station scan added (Ctrl-Up) * onscreen display in fullscreen mode * misc small enhancements. * The '-c n' switch is gone, you can start xawtv with the station name on the command line instead ("xawtv cnn" for example, like it already works for fbtv and set-tv). * Added a new '-c' switch, this is the video device now. Added this one for xawtv and fbtv, changed from '-v' to '-c' for v4l-conf. * removed vtx subdirectory. The driver is now in the 2.1.x tree. And for 2.0.x it is useless anyway, it does'nt compile... 2.12 => 2.13 ============ * Fixed Makefile bugs. * switched to the new device files: s|/dev/bttv|/dev/video| MAKEDEV in bttv/driver is updated * Tried to catch that VidMode problem by version check: #define XXX_VERSION (from xf86vmstr.h) against server's QueryVersion results. If this still does'nt work: remember, there is the '-x' switch to workaround this... * Fast channel scan (Ctrl-Z) 2.11 => 2.12 ============ * added support for 8 bit Servers: Run the Server with StaticGray visual (-cc 0x27 for XFree) -- and you should get a b/w TV picture. * fixed a few configure-script and #ifdef bugs * modified channel maps again -- hope I got the european map is ok now. there is only one map: pal-europe. This one should work for both cable and broadcast. * driver changes (capture code -- the SYNC ioctl takes the frame number as argument now) 2.10 => 2.11 ============ * bugfix: xawtv used to ignore "fine = ???" in the config file. * added grab-one, a small tool to grab single, full-sized images. Use the "-h" option for a short description. * added channel window (try the 'C' key). * Added "zap" mode: does channel hopping (tune in every station a few seconds). * added fbtv (for framebuffer devices). 2.09 => 2.10 ============ * glibc compile fixes (hopefully, have still libc5...) * updated driver to bttv-0.5.8 * updated applications according to the grabbing changes in the bttv driver * catched a bug in the config parser (was confused by spaces at end-of-line) 2.08 => 2.09 ============ * 15 bit HiColor works now (fixed bttv driver and v4l-conf) * renamed some frequency tables to make the names more consistent you might have to fix the freqtab= setting in $HOME/.xawtv again... * Added stereo support to the msp3400 volume mixer. * Improved non-overlayed displaying (called grabdisplay in xawtv). Not rock-solid yet, driver is'nt stable enouth wrt grabbing. BTW: if you get "ioctl VIDIOCMCAPTURE: Try again" on stderr, it just means that the bttv driver has no signal (i.e. no station tuned in, wrong TV norm, something like that...). * the doc subdirectory of the bttv distribution is included now. * updated the driver to bttv-0.5.7 2.07 => 2.08 ============ * Ha! Found a complete (?) frequency table on the web, using this one now (and a complete different channel-to-freqency mapping method). Expect a few new bugs and tuning problems -- pointers to frequency lists are welcome. Check channels.h for details. The names of the freqency mappings have changed, you have to adopt $HOME/.xawtv * fixed a bug in the msp3400 module (system hangs on control thread kill) * With the 2.1.x modular sound driver, the msp3400 module registers as mixer device. This allows to control volume, bass and treble with a mixer application of your choice. * the config file parser prints more detailed error messages and does not exit on errors. * Added a workaround for buggy (wrt static gravity) Window managers, see manpage (wm-off-by= ...) * Started non-overlay displaying (try Shift-ESC). Not completed, not stable yet. * Changed v4l-conf handling: It is installed suid-root now and called by xawtv. 2.06 => 2.07 ============ * Two hours after releasing 2.06 I noticed that the driver did'nt compile with 2.0.33 :-( 2.05 => 2.06 ============ * You can grab both full size and window size now (hold down Ctrl for window size). * Merged some of the latest vger CVS changes to bttv-0.5.6 to keep both versions in sync (at least the ioctl interface). The included driver version supports currently both the new VIDIOCMCAPTURE+VIDIOCSYNC and old BTTV_GRAB+BTTV_SYNC. xawtv uses the new ones. The minor numbers for vbi have changed (from 32 to 224) * hacked msp3400 stereo handling, it does permanent monitoring now and should handle mono/stereo/bilang switches by the TV station correctly. 2.04 => 2.05 ============ * Started writing a Changes file * fixed a quite stupid getopt bug * ditched support for the old-style bttv interface. * The screen saver is turned off now in fullscreen mode * xawtv can switch video modes now (for fullscreen mode). There is a new config file entry for this, check the manpage. * fixed configure script (check for c++ only if required) * For the bleeding edge people: Added some code for the new VIDIOCMCAPTURE and VIDIOCSYNC ioctl's (new video4linux code in the vger CVS tree) as compile time option. The configure script should detect the new version and use the kernel driver then. The ioctl's are'n really new, the are basically slightly modified BTTV_GRAB and BTTV_SYNC. Well, this change breaks _again_ grabbing applications, but now there is a standardized interface for mmap-based grabbing available. xawtv-3.106/MAKEDEV.v4l000066400000000000000000000010371343350355000144010ustar00rootroot00000000000000#!/bin/bash function makedev () { for dev in 0 1 2 3; do echo "/dev/$1$dev: char 81 $[ $2 + $dev ]" rm -f /dev/$1$dev mknod /dev/$1$dev c 81 $[ $2 + $dev ] chmod 666 /dev/$1$dev done # symlink for default device rm -f /dev/$1 ln -s /dev/${1}0 /dev/$1 } # see http://roadrunner.swansea.uk.linux.org/v4lapi.shtml echo "*** new device names ***" makedev video 0 makedev radio 64 makedev vtx 192 makedev vbi 224 #echo "*** old device names (for compatibility only) ***" #makedev bttv 0 #makedev bttv-fm 64 #makedev bttv-vbi 224 xawtv-3.106/Makefile.in000066400000000000000000000106411343350355000147440ustar00rootroot00000000000000srcdir := @srcdir@ VPATH := $(srcdir) # for package builds (buildroot install + no root privs needed) DESTDIR= SUID_ROOT=-m4755 -o root STRIP_FLAG= # install paths prefix := @prefix@ exec_prefix := @exec_prefix@ bindir := $(DESTDIR)@bindir@ mandir := $(DESTDIR)@mandir@ libdir := $(DESTDIR)@libdir@/xawtv datadir := $(DESTDIR)@datadir@/xawtv resdir := $(DESTDIR)@resdir@ config := @x11conf@/xawtvrc # programs CC := @CC@ CXX := @CXX@ INSTALL := @INSTALL@ INSTALL_PROGRAM := @INSTALL_PROGRAM@ $(STRIP_FLAG) INSTALL_DATA := @INSTALL_DATA@ INSTALL_DIR := @INSTALL@ -d -m 755 # misc VERSION := @VERSION@ # for CFLAGS WARN_FLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith -Wno-pointer-sign LFS_FLAGS := -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 X11_FLAGS := @X_CFLAGS@ @XFT_FLAGS@ -I/usr/include/X11/fonts LIB_FLAGS := -I. -I./vbistuff -I./x11 \ -I$(srcdir)/jwz -I$(srcdir)/common -I$(srcdir)/console \ -I$(srcdir)/x11 -I$(srcdir)/structs \ -I$(srcdir)/libng LD_FLAGS := -Llibng # various libraries ATHENA_LIBS := @X_LIBS@ @XFT_LIBS@ @LIBS@ @ATHENA@ MOTIF_LIBS := @X_LIBS@ @XFT_LIBS@ @LIBS@ -lXm -lXmu -lXt @X_PRE_LIBS@ \ -lXpm -lXext -lX11 @X_EXTRA_LIBS@ THREAD_LIBS := @LIBPTHREAD@ CURSES_LIBS := @LIBCURSES@ LIRC_LIBS := @LIRC@ OSS_LIBS := @LIBOSS@ ALSA_LIBS := @LIBALSA@ AA_LIBS := @AALIBS@ QT_LIBS := @QTLIBS@ QT_FLAGS := @QTFLAGS@ VBI_LIBS := @LIBZVBI@ GL_LIBS := @LIBGL@ DV_LIBS := @LIBDV@ DLFLAGS := @DLFLAGS@ # stuff configure has found FOUND_AALIB := @FOUND_AALIB@ FOUND_ALSA := @FOUND_ALSA@ FOUND_DV := @FOUND_DV@ FOUND_GL := @FOUND_GL@ FOUND_LQT := @FOUND_LQT@ FOUND_MOTIF := @FOUND_MOTIF@ FOUND_OS := @FOUND_OS@ FOUND_X11 := @FOUND_X11@ FOUND_ZVBI := @FOUND_ZVBI@ USE_MMX := @USE_MMX@ LIBV4L := @LIBV4L@ FOUND_EXPLAIN := @FOUND_EXPLAIN@ # build final cflags CFLAGS := @CFLAGS@ CFLAGS += $(WARN_FLAGS) CFLAGS += $(LFS_FLAGS) CFLAGS += $(X11_FLAGS) CFLAGS += $(LIB_FLAGS) CFLAGS += $(QT_FLAGS) CFLAGS += -DCONFIGFILE='"$(config)"' CFLAGS += -DLIBDIR='"$(libdir)"' CFLAGS += -DDATADIR='"$(datadir)"' CFLAGS += -DVERSION='"$(VERSION)"' CXXFLAGS := $(CFLAGS) # for gcc3 #CFLAGS += -std-gnu99 # shared objects need -fPIC %.so : CFLAGS += -fPIC %.so : CXXFLAGS += -fPIC # libraries LDLIBS := @LDLIBS@ ######################################################### # targets build: all Makefile: $(srcdir)/Makefile.in $(srcdir)/configure $(srcdir)/configure $(srcdir)/configure: $(srcdir)/configure.ac (cd $(srcdir); autoconf && autoheader && rm -rf autom4te.cache) install:: all $(INSTALL_DIR) $(bindir) clean:: find . -name \*~ -print | xargs rm -f find . -name \*.o -print | xargs rm -f find . -name \*.a -print | xargs rm -f find . -name \*.dep -print | xargs rm -f rm -f $(depfiles) distclean:: clean -rm -f Makefile Make.config -rm -f config.cache config.h config.log config.status cp Makefile.clean Makefile realclean:: distclean find . -name snap0*.ppm -print | xargs -i rm -f find . -name snap0*.jpeg -print | xargs -i rm -f find . -name .nfs* -print | xargs -i rm -f find . -name core.* -print | xargs -i rm -f ######################################################### # some rules ... include $(srcdir)/mk/Compile.mk %.h: %.in perl $(srcdir)/scripts/html.pl < $< > $@ %.h: %.ad perl $(srcdir)/scripts/fallback.pl < $< > $@ ######################################################### # include stuff # must come first include $(srcdir)/common/Subdir.mk # subdirs include $(srcdir)/console/Subdir.mk include $(srcdir)/debug/Subdir.mk include $(srcdir)/frequencies/Subdir.mk include $(srcdir)/libng/Subdir.mk include $(srcdir)/libng/plugins/Subdir.mk include $(srcdir)/libng/contrib-plugins/Subdir.mk include $(srcdir)/man/Subdir.mk include $(srcdir)/scripts/Subdir.mk include $(srcdir)/vbistuff/Subdir.mk include $(srcdir)/x11/Subdir.mk # dependencies -include $(depfiles) ######################################################### # just for me, some maintaining jobs. Don't use them tag: @git tag -a -m -s "Tag as xawtv-@VERSION@" xawtv-@VERSION@ @echo "Tagged as xawtv-@VERSION@" archive: @(cd $(srcdir) && git archive --format=tar --prefix=xawtv-@VERSION@/ xawtv-@VERSION@) > xawtv-@VERSION@.tar # Ensure these are newer then configure.in @touch $(srcdir)/configure $(srcdir)/config.h.in @tar --transform='s#config#xawtv-@VERSION@/config#' -rf xawtv-@VERSION@.tar $(srcdir)/configure $(srcdir)/config.h.in @bzip2 -f xawtv-@VERSION@.tar xawtv-3.106/README000066400000000000000000000174601343350355000135650ustar00rootroot00000000000000 Documentation overview ====================== README [this file] gives a overview over the package. Build instructions, short overview over every program, some maybe useful URL's. man pages For most programs a manual page is available. README.xfree4 Some notes about XFree86 4.x and the Xvideo extention. README.recording If you want record videos, have a look at this file. It also has some notes about how to process / playback the files recorded by xawtv/streamer. README.network How to stream video/audio over the net. Pointers to other software for the most part. README.lirc Some hints how make lirc work with xawtv. README.bttv Some hints to get bttv going, also lists some known problems. UPDATE_TO_v3.0 Some hints for upgrading from 2.x to 3.x (config file syntax changes, ...) before sending me email... ========================== IMPORTANT: Don't send me mails with images attached unless I ask you to do so. Mails with images attached will go to /dev/null unseen, you will never ever see an answer for these. If you have problems after upgrading, please check the ChangeLog for hints first. Looking into the ChangeLog is a good idea in general, because it is updated for every release, the other files are updated less frequently and might be a bit outdated. For problem/bug reports: * emails with questions answered in the documentation will go to /dev/null. * emails which don't have any useful informations (like "xawtv doesn't work, please help me") will go to /dev/null. "useful information" includes at least: - xawtv version - kernel version - which driver (+ version if you know) - which hardware (although I probably can help with bttv driver problems only). - which TV norms are used in your country. - if xawtv prints errors, include these too (cut+paste) - don't forget a description of your problem :-) If you are using bttv as driver: - the insmod arguments for the modules - the kernel messages printed by bttv while loading. If you are _really_sure_ some information isn't important for your problem, you can skip it. But if in doubt, better include it... For patches/changes: * Please add a comment on what is changed and why you changed it. * Please send unified diffs ("diff -u") against the latest version. * Please don't reformat my source code. * Complete patches have better chances to go in. Quick+dirty hacks which need cleanups and lack documentation updates are less likely to go in simply because I need more time to deal with them. compile & install ================= The commands $ ./configure [ options ] $ make should compile xawtv, v4l-conf, fbtv and a few other utilities. You can also simply type "make" if you don't want to pass any options to configure. If it fails, check that all required packages are installed. Note that the *-devel packages are also required to compile stuff, i.e. you need both libjpeg and libjpeg-devel for example. You can install the programs (as root) with: # make install If you want build RPMs: No problem, just run $ rpm -ta xawtv-3.xx.tar.gz and install them the usual way with "rpm -i". usage ===== bttv ---- bttv isn't bundled with xawtv any more. You can the latest version from http://bytesex.org/bttv/. If you are using kernel 2.4.x, it is very unlikely that you need an update, the bttv driver in 2.4.x is updated in regular intervals. v4l-conf -------- v4l-conf is a small tool which tells video4linux about the current video mode (size and color depth). This requires root privileges, because it is easy to crash the box by passing bogus values there. It requires the X-Server with DGA support up and running or a framebuffer device. It is a temporary hack, this problem will be solved in a better way with a X11 extention. See README.xfree4 for details. Try "v4l-conf -h" for a short description. It is installed suid-root, and xawtv runs it at startup. Should work out-of-the-box without extra configuration. Normally you shouldn't need to worry about it, but for debugging it is handy do run it from the shell and check the output. xawtv ----- There is a man page now, read it. Don't expect you can use xawtv without reading the documentation at least once. You are lost if you don't know the keyboard shortcuts, xawtv isn't a mouse-only program. xawtv will not work without the app-defaults. If you want to try xawtv without installing it, use this... $ XUSERFILESEARCHPATH=./%N.ad $ export XUSERFILESEARCHPATH $ ./xawtv ...to make sure xawtv finds the application defaults (the Xawtv.ad file). If v4l-conf isn't installed too, you have to run it once (as root) before starting xawtv. motv ---- That's basically xawtv with better (IMO), motif-based GUI. Feature set is very close to xawtv, they share a lot of code (basically everything but the athena/motif GUI code). motv uses Motif 2.x features (utm, render tables). This means you need openmotif, lesstif does *not* work. xawtv-remote ------------ remote control for xawtv. Works with motv too. Takes commands for xawtv as command line arguments. Check 'xawtv-remote -h' for details. A man-page exists too. ObSecurity: This uses X Properties, everyone who is allowed to connect to your X11 Display can control xawtv. There is a GUI (Qt) version at: http://www.ben2.ucla.edu/~wtho/xawtv-qremote/xawtv-qremote-0.01.tar.gz fbtv ---- TV program for the linux console. Runs on top of a framebuffer device. Check out man-page and source code for details. ttv --- aa-lib based TV app which renders the TV image on any text terminal. scantv ------ scans for tv stations and writes a initial config file for xawtv and motv. v4lctl ------ This tool allows to control a v4l device from the command line. Also can capture images. Check the man-page for details. streamer -------- Command line tool for streaming capture, including audio. Single frames work too. Try the '-h' switch for a description. A (short) man page is available too. pia --- simple movie player, should play every movie file (mov+avi) recorded by streamer, xawtv and motv. radio ----- You have to load the driver using "insmod bttv radio=1" for radio support. The MAKEDEV script should create the required /dev/radio* devices. radio is a console application (curses). up/down tune, 'q' quits, the function keys recall the programmed stations. radio reads the kradio config file. You can't configure anything with radio, you'll have to use kradio or vi for this. The config file format is documented in the man page. kradio (my KDE radio app) isn't included any more, it is available as separate tarball now. videotext / teletext -------------------- alevt is _the_ videotext application for bttv. URL below. A http server for videotext called 'alevtd' is in the vbistuff subdirectory. Recent xawtv version also come with mtt, which is a interactive videotext application for X11 (Motif) and console. webcam ------ This is a webcam tool. Captures a image, annotates with a text + current time and uploads it to the webserver using ftp in an endless loop. Needs the ftp utility. Should survive dropped ftp-connections (webserver reboot) without problems. It has a man-page... perl ---- Hint for all perl users/hackers: There is a Video::Capture::V4l module available at CPAN. It can do capture, vbi decoding, and it comes with a nifty tool to do a channel scan (decodes the station ID from vbi). resources ========= http://bytesex.org/xawtv/ - xawtv [me] http://bytesex.org/bttv/ - bttv [me] http://lecker.essen.de/~froese/ - alevt [Edgar] http://bttv-v4l2.sourceforge.net/ - bttv2 [Justin] http://roadrunner.swansea.uk.linux.org/v4l.shtml - v4l [Alan] http://www.thedirks.org/v4l2/ - v4l2 [Bill] http://www.tk.uni-linz.ac.at/~simon/private/i2c/ - i2c [Simon] http://www-mice.cs.ucl.ac.uk/multimedia/software/vic/ - vic Have fun! Gerd -- Gerd Knorr xawtv-3.106/README.bttv000066400000000000000000000104231343350355000145330ustar00rootroot00000000000000 Some hints to get the bttv driver up and running ================================================ general hints ------------- (1) Make sure if your board is recognized correctly. The bttv driver should print a line like this one (Use the 'dmesg' command to see the kernel messages): bttv0: model: BT848(Hauppauge old) If your card isn't autodetected correctly, you have to specify the board type as insmod argument (card=n). You might also have to specify tuner=x and pll=x. Check the driver documentation for details and a list of supported cards. The standard kernel has the bttv documentation in the Documentation/video4linux/bttv directory. (2) If you are using a vanilla 2.2.x kernel kernel, it is worth trying to upgrade as the very first step. Either download and build bttv 0.7.x for your 2.2.x kernel, or upgrade to 2.4.x which includes the 0.7.x driver already. bttv 0.7.x knows a lot more cards than the 2.2.x kernel driver, the autodetect is much improved and a number of known problems is fixed. (3) If you have problems with xawtv, you should open a xterm (or whatever your favorite terminal app is) and start xawtv from there. This way you'll see any error messages xawtv might print on stderr which should help to find the source of the problems. (4) If something broke after an update, have a look at the changelog. It might be mentioned there. common problems --------------- ?: I have a black screen in overlay mode !: The driver was not initialized correctly, v4l-conf (or the X-Server) has to configure the bttv driver with the current video mode and framebuffer address first. Check if v4l-conf is installed suid root, it needs root priviliges to do this. You can also start v4l-conf from a terminal and check the messages it prints. ?: I have a blue screen. !: Good, the overlay is working. A blue screen is what you get if the grabber chip has no input signal. You are probably using the wrong video source, pick another. Also happens sometimes if the tuner type is wrong, check the driver configuration. ?: I have a noisy screen and/or can't tune (some) stations. !: Most likely the tuner types is wrong, check the driver configuration. It's no problem to do trial-and-error here. ?: The video is outside the window and spread in thin lines over the screen. !: xawtv / v4l-conf didn't autodetect the color depth for your screen correctly. You can fix that with xawtv's -bpp switch. ?: Only the left part of the window is updated, the right one is updated never / sometimes / only if the window is small. !: Your graphics card and/or motherboard can't deal with the data rate going over the PCI bus, leading to canceled PCI transfers. Reduce the color depth, with 16 bpp instead of 32 bpp should work much better. ?: I get no sound. !: (a) If your TV-Card is connected to the sound card's line in with a short cable: Make sure the sound driver is loaded, sound cards are usually quiet until initialized by the driver. Also check the mixer settings. (b) Double-check the card type is correct (see above). (c) If there is still no go, have a look at the Sound-FAQ in the bttv documentation. hardware specific problems -------------------------- * bttv + DRI seem not to play nicely together with some cards (ATI Rage128). The linux box just freezes. Don't know why. Suspect it's either a hardware problem or a bug somewhere in DRI (either kernel or xfree86). The only workaround I know of is to turn off DRI. * Some motherboard chipsets have PCI bugs, especially with PCI-PCI transfers which are used for video overlay. The bt848/878 chips have some bug compatibility options, which can be enabled to workaround these problems. Have a look at the triton1 and vsfx insmod options. For some known-buggy chipsets these are enabled automagically. * Sometimes IRQ sharing causes trouble. It works most of the time, but in combination with some hardware and/or drivers it doesn't work. Especially graphic cards are known to cause trouble due to the lack of a IRQ handler. Try disabling the VGA IRQ in the BIOS. Try moving cards to another PCI slot. Your motherboard manual should tell you which PCI slots share IRQ's. xawtv-3.106/README.lirc000066400000000000000000000024611343350355000145100ustar00rootroot00000000000000 Starting with version 3.71 xawtv + friends do not need a ~/.lircrc config file any more. There is a new config mechanism to map input events (lirc, joystick, keyboard) into xawtv commands which is called "eventmap". Check the xawtvrc manpage ([eventmap] section) for details. There also is an default configuration now, so lirc support should simply work out-of-the-box. If there is no ~/.lircrc config file present, xawtv will generate lirc-key-* events for every key pressed on the IR remote. If ~/.lircrc is present, xawtv will still use it. As strings for "config" are the usual xawtv commands (the traditional way to configure lirc support, see "man xawtv-remote") and the keyword "eventmap" allowed. Specifying "eventmap" will make xawtv simply generate lirc-key-* events. The main difference between using no config file at all and one with "config = eventmap" is that the later allows you to filter the keypresses depending on the current mode. The simpliest way to make xawtv use the default eventmap configuration, but respond to key presses in xawtv mode only looks like this: begin xawtv begin prog = xawtv config = eventmap end end xawtv You probably need this if you are going to control multiple applications with your IR remote, check out the lirc documentation for details. Have fun, Gerd xawtv-3.106/README.network000066400000000000000000000026461343350355000152550ustar00rootroot00000000000000 How send audio/video data over the net? ======================================= Just some pointers where to look. I haven't tried everything myself. still images (webcam) --------------------- You can use the xawtv's webcam utility (in the webcam subdirectory) to capture single frames and upload them to a (web-)server using ftp. There are plenty of other tools for that purpose, http://freshmeat.net has a list. both audio and video -------------------- You can use video conferencing tools, see http://www.openh323.org. That should even interoperate with M$ Netmeeting. I've heard there is a project named "gnomemeeting" ... You might want to have a look at videolan (http://www.videolan.org). Using the mbone tools (i.e. vic for video, vat or rat for audio) works too, see http://www-mice.cs.ucl.ac.uk/multimedia/software/ Drawback is that these two work independent of each other, that's why there is no way to make audio and video sync properly. video only ---------- xawtv works with a remote display. Eats plenty of network bandwith as the X11 protocol is not optimized for streaming video. Can be used to max-out ATM cards. Don't even think about it with something slower than Ethernet. audio only ---------- Use some network sound daemon, esound for example: sox -w -c 2 -r 44100 -t ossdsp /dev/dsp -t raw - | esdcat -r 44100 Check out http://freshmeat.net, IIRC there are some tools to multicast audio data. xawtv-3.106/README.recording000066400000000000000000000144341343350355000155360ustar00rootroot00000000000000 Recording movies ================ Audio ===== If you don't get sound when recording avi movies, double-check the mixer settings first. The record source defaults to micro on many linux sound drivers, you probably have to change this to line-in with one of the available mixer tools. Some sound cards have a separate input gain control which needs to be set to some approximate value. Also keep in mind that ALSA has all mixer controls at 0 (i.e. muted) by default. /me uses kmix (because it doesn't need much space on the screen). The inputs where the sound cards record from have a red background color. With the right mouse botton you'll get a menu where you can change the settings. FreeBSD has a aumix version with X11 GUI in the ports collection which is very nice too (aumix-gtk in debian). If you want to see something while playing with the mixer settings you can use the record utility (ncurses terminal application, in the tools subdirectory), it has a nice input level meter. motv has one build-in too (Menu -> Tools -> Record level monitor). Note on stereo: xanim seems not be able to playback stereo sound correctly. Video ===== Note that video recording does not work if the Xvideo extension is in use. For recording stuff with xawtv you might have to start the application with the -noxv switch to disable Xvideo. xawtv/streamer handle video recording with multiple threads: - one thread records video (+ displays video on screen). - one (or more) thread(s) does color space conversion / compression. - one thread records audio (unless you do video only). - one thread writes the movie data to the disk. - one thread calls sync frequently to make the writeouts more smoothly (more smaller chunks instead of few very big ones). There are buffer fifo's between the recording threads and the compression / disk writer to avoid recording overruns due to a temporarily busy hard disk or CPU load peaks. If you see messages about a full fifo or about v4l(2) waiting for free buffers it is very likely that your hard disk is too slow, especially if you try to record uncompressed video. bttv 0.7.x allows you to use more than just two video buffers, you can configure the number at insmod time (gbuffers option). Using more buffers (say 4-8 instead of just two which is the default) should help to reduce the number of dropped frames. If you want to record quicktime movies install libquicktime (http://libquicktime.sf.net), then (re-)build xawtv. The configure script should find the library automatically. Known problems (and workarounds) ================================ The timestamping for the video frames isn't very exact as it does _not_ come from the v4l(1) driver but is just a gettimeofday() call after receiving the video frame. API design bug, needs fixing. With v4l2 xawtv uses the frame timestamps provided by the driver. Troubleshooting syncronisation problems ======================================= A/V sync should simply work if your box can keep up with the data rate. xawtv/streamer displays some debug info (time shift) on stderr. "a/r" is the difference between audio and real time, "a/v" is the difference between audio and video. Ff you see "fifo full" error messages your box likely can't keep up with the data rate. Possible fixes: Try using more buffers. Try recording compressed video. Try tuning the hard disk using hdparm. Buy a faster hard disk. Buy a faster computer. If xawtv/streamer says "queueing frame twice" it has put a the same video frame twice into the output queue to avoid video running out of sync. If this happens a lot it indicates that either your computer can't keep up with compressing the frames or that your v4l device can't capture frames with the frame rate you are asking for. A single message now and then is harmless. MPEG Encoding ============= Have a look at the mjpegtools (http://mjpeg.sourceforge.net). xawtv can write the yuv4mpeg format accepted by mpeg2enc directly. mp2enc accepts xawtv's wav files too. So you can use xawtv/streamer, mpeg2enc, mp3enc and mplex to build mpeg movies. If you don't have enough disk space to store uncompressed yuv video you can also record compressed quicktime/avi files and then recode stuff using lav2yuv + mpeg2enc in a pipe. The streamer help text (streamer -h) has a few examples. Large Files =========== xawtv has LFS support, i.e. it can write files >2GB without problems. The AVI format has a 2GB limit. There is a extension to overcome this [http://www.matrox.com/videoweb/news/press/papers/odmlff2.pdf], but not all applications can deal with it. The quicktime format usually works better as there is the quicktime4linux library everybody uses to read/write *.mov files, thus there are less compatibility issues. Read, Convert, Edit + Playback stuff ==================================== Recent xawtv versions come with the "pia" utility. That is a simple player which should be able to playback all AVI and QuickTime movies recorded by xawtv, motv and streamer. avi format * xanim plays everything without problems. * QuickTime[tm] (MacOS) plays the uncompressed formats just fine and complains about mjpeg/jpeg. * Windows Media Player plays the uncompressed formats fine. mjpeg/jpeg work too if a codec is installed (/me has a very old one from MainConcept). * avifile can't deal with the uncompressed video correctly [fixed in recent versions]. mjpeg/jpeg doesn't work either for me as it seems not to recognise the MainConcept codec, although I've copied stuff to /usr/lib/win32. Maybe it works with another one. * MainActor (linux) can read the mjpeg but not the jpeg compressed files. quicktime format * xmovie + broadcast2000 can read the files without problems (not exactly surprising as they use the quicktime4linux library too ...). * QuickTime[tm] (MacOS/Windows) plays them without problems. * xanim says it can't find any data in the mov file. It used to work with older versions of the quicktime4linux library (before 64bit support was added), so I suspect xanim simply can't deal with 64bit mov files. raw data * ImageMagick can deal with this, you have to specify the image format + size on the command line like this: display -size 320x240 rgb:file.raw It can handle multiple frames in one big file too. Have fun, Gerd -- Gerd Knorr xawtv-3.106/README.translate000066400000000000000000000024101343350355000155460ustar00rootroot00000000000000 translate motv app ================== The new motif-gui version has i18n support, it is handled by using different application default files for the different languages. All the strings are in the MoTV- files. MoTV-default is the english version. MoTV-fixed has the other (language-independant) app-default settings. The Makefile merges these into MoTV..ad files. To add another language you just need to create a new MoTV- file, edit x11/Subdir.mk and add the language to the LANGUAGES= line. You can test the translations without "make install" this way (bash): once at start: $ cd x11 $ export XUSERFILESEARCHPATH="./%N.%l.ad:./%N.ad" $ export LC_ALL= every time after editing MoTV-: $ make $ ./motv translate documentation ======================= The applications come with a manual page as documentation. Most manual pages are in the man/ subdirectory. Translated manual pages are very welcome, I can easily add them to the distribution tarball. It is a good idea to add your email address to the translated page, so people can reach you directly with spell fixes and stuff like that. I can't proof-read pages in foreign languages ... other stuff =========== Currently I have no plans to localize xawtv and the command line tools. xawtv-3.106/README.xfree4000066400000000000000000000075241343350355000147610ustar00rootroot00000000000000 XFree86 4.x tips & tricks ========================= DGA problems ------------ Release 4.0 has DGA turned off by default. This is true for the first release only, with current versions this shouldn't be a problem unless you have some old config file still in use. You'll have turn on DGA in XF86Config, otherwise v4l-conf will not work correctly (Modules section, extmod options). It should work for most cards this way, althrouth some drivers don't handle DGA correctly in 4.0 (that's why it is off...) If DGA doesn't work for you, you have to configure bttv by hand (or use Xvideo, see below). v4l-conf has the "-a" switch for this. using Xvideo ------------ XFree86 4.0 comes with a new X11 extention for video support. The X-Server will handle the grabber board then, not xawtv. This has the advantage that the X-Server knows about the video. Window moves can be handled without redraw problems. The refresh triggered by xawtv to fix it isn't required any more. It is possible to use the video scalers of modern graphics boards (see below). To use Xvideo you have to load the video4linux module into the X-Server. Just adding 'Load "v4l"' to the Modules section of XF86Config will do. You have to make sure xawtv is compiled on a box with with XFree86 4.0 installed. xawtv needs the new client libraries for Xvideo support. using hardware scaling ---------------------- Starting with XFree86 4.0.1 the Xvideo extention supports hardware-scaled video, i.e. the video isn't written directly to the visible area of the video memory. Instead the bt848 hardware writes yuv data to offscreen memory. The graphic card's video scaler does color space conversion and video scaling. This way fullscreen video works in 1024x768 (and greater) without a black border because we are not limited to the maximum size supported by the bt848 hardware any more. As this is very new stuff not all drivers support video scaling yet. It basically requires the overlay functions available to the applications via xvideo port to be exported using a X-Server internal interface too, so other X-Server modules are able to use them. The mga driver was the first one which supported this (matrox G200+G400). XFree86 4.1 adds a few more ones, a quick grep of the source tree returns this list: ct, i810, mga, nv, savage, smi, trident. For ati you might want to have a look at http://www.linuxvideo.org/gatos/. Detailed Status: * mga: works, I use that myself. On multihead cards the second head is not accelerated, that means hw scaling via Xvideo works on the first head only. * i810: works, according to the drivers author which asked me some questions about it and finally got it going. * tdfx: current CVS version works, next release (4.1.1) will have it. * nvidia: free nv driver not working correctly (4.1). nvidia's binary-only works starting with release 1512. * others: don't know, reports welcome. You also need a bttv version newer than 0.7.16 (the 2.2.x kernel version is /way/ to old, kernel 2.4.x is fine). If both bttv driver and xfree86 gfx driver support it, xfree86's video4linux driver will use hardware scaling automagically. drawbacks --------- capturing images/video doesn't work if xawtv runs using the Xvideo extention. With the '-noxv' switch Xvideo can be disabled. multiheaded setups ------------------ "regular" multihead with two screens works just fine. The one only thing you have to take care off is that you can't use the -display option to start xawtv on the second head if you are *not* using Xvideo. Use "DISPLAY=:0.1 xawtv" instead. Otherwise v4l-conf will use the wrong screen to configure the driver. Xvideo + xinerama works just fine starting with XFree86 4.1, older versions show video on the first physical screen only (the one listed first in your ServerLayout section). Without Xvideo you'll also see the video on the first head only. Gerd xawtv-3.106/TODO000066400000000000000000000014211343350355000133630ustar00rootroot00000000000000 TODO list isn't exactly right for this. It is more a collection of ideas I'm thinking about. It *might* mean I have plans to implement this in near future. general ======= * volume= option for .xawtv (not trivial - to make this a useful feature it should be a station-specific offset to the overall volume. Try to get this right for every soundcard / high + low volume / ... ). * mono/stereo config file options. * hotkeys/remote commands for mono/stereo/... * two (more?) channel lists: "all" & "frequently used". * record subtitles (QuickTime text track?). avi === * grayscale avi recording (anybody knows how to do this? 256 color with a gray palette?) * OpenDML index support * record even/odd fields separately instead of writing interlaced frames. xawtv-3.106/autogen.sh000077500000000000000000000001101343350355000146660ustar00rootroot00000000000000#!/bin/sh set -ex autoconf autoheader rm -rf autom4te.cache ./configure xawtv-3.106/common/000077500000000000000000000000001343350355000141655ustar00rootroot00000000000000xawtv-3.106/common/Subdir.mk000066400000000000000000000007351343350355000157530ustar00rootroot00000000000000 OBJS-common-capture := \ common/sound.o \ common/webcam.o \ common/frequencies.o \ common/commands.o \ common/parseconfig.o \ common/capture.o \ common/event.o \ libng/libng.a OBJS-common-input := \ common/lirc.o \ common/joystick.o \ common/midictrl.o common/channel-no-x11.o: CFLAGS += -DNO_X11=1 OBJS-common-alsa := common/alsa_stream.o common/get_media_devices.o common/channel-no-x11.o: common/channel.c @$(echo_compile_c) @$(compile_c) @$(fixup_deps) xawtv-3.106/common/alsa_stream.c000066400000000000000000000452741343350355000166400ustar00rootroot00000000000000/* * ALSA streaming support * * Originally written by: * Copyright (c) by Devin Heitmueller * for usage at tvtime * Derived from the alsa-driver test tool latency.c: * Copyright (c) by Jaroslav Kysela * * Copyright (c) 2011 - Mauro Carvalho Chehab * Ported to xawtv, with bug fixes and improvements * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "config.h" #if defined(HAVE_ALSA_ASOUNDLIB_H) && defined(HAVE_ALSA) #include #include #include #include #include #include #include #include #include #include #include "alsa_stream.h" #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) /* Private vars to control alsa thread status */ static int stop_alsa = 0; /* Error handlers */ snd_output_t *output = NULL; FILE *error_fp; int verbose = 0; struct final_params { int bufsize; int rate; int latency; int channels; }; static int setparams_stream(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_format_t format, int *channels, const char *id) { int err; err = snd_pcm_hw_params_any(handle, params); if (err < 0) { fprintf(error_fp, "alsa: Broken configuration for %s PCM: no configurations available: %s\n", snd_strerror(err), id); return err; } err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { fprintf(error_fp, "alsa: Access type not available for %s: %s\n", id, snd_strerror(err)); return err; } err = snd_pcm_hw_params_set_format(handle, params, format); if (err < 0) { fprintf(error_fp, "alsa: Sample format not available for %s: %s\n", id, snd_strerror(err)); return err; } retry: err = snd_pcm_hw_params_set_channels(handle, params, *channels); if (err < 0) { if (strcmp(id, "capture") == 0 && *channels == 2) { *channels = 1; goto retry; /* Retry with mono capture */ } fprintf(error_fp, "alsa: Channels count (%i) not available for %s: %s\n", *channels, id, snd_strerror(err)); return err; } return 0; } static void getparams_periods(snd_pcm_t *handle, snd_pcm_hw_params_t *params, unsigned int *usecs, unsigned int *count, int allow_adjust, const char *id) { unsigned min = 0, max = 0; unsigned desired = *usecs * *count; snd_pcm_hw_params_get_periods_min(params, &min, 0); snd_pcm_hw_params_get_periods_max(params, &max, 0); if (min && max) { if (verbose) fprintf(error_fp, "alsa: %s periods range between %u and %u. Want: %u\n", id, min, max, *count); if (*count < min) *count = min; if (*count > max) *count = max; } min = max = 0; snd_pcm_hw_params_get_period_time_min(params, &min, 0); snd_pcm_hw_params_get_period_time_max(params, &max, 0); if (min && max) { if (verbose) fprintf(error_fp, "alsa: %s period time range between %u and %u. Want: %u\n", id, min, max, *usecs); if (*usecs < min) *usecs = min; if (*usecs > max) *usecs = max; } /* If we deviate from the desired size by more then 20% adjust count */ if (allow_adjust && (((*usecs * *count) < (desired * 8 / 10)) || ((*usecs * *count) > (desired * 12 / 10)))) { *count = (desired + *usecs / 2) / *usecs; getparams_periods(handle, params, usecs, count, 0, id); } } static int setparams_periods(snd_pcm_t *handle, snd_pcm_hw_params_t *params, unsigned int *usecs, unsigned int *count, const char *id) { int err; err = snd_pcm_hw_params_set_period_time_near(handle, params, usecs, 0); if (err < 0) { fprintf(error_fp, "alsa: Unable to set period time %u for %s: %s\n", *usecs, id, snd_strerror(err)); return err; } err = snd_pcm_hw_params_set_periods_near(handle, params, count, 0); if (err < 0) { fprintf(error_fp, "alsa: Unable to set %u periods for %s: %s\n", *count, id, snd_strerror(err)); return err; } if (verbose) fprintf(error_fp, "alsa: %s period set to %u periods of %u time\n", id, *count, *usecs); return 0; } static int setparams_set(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_sw_params_t *swparams, snd_pcm_uframes_t start_treshold, const char *id) { int err; err = snd_pcm_hw_params(handle, params); if (err < 0) { fprintf(error_fp, "alsa: Unable to set hw params for %s: %s\n", id, snd_strerror(err)); return err; } err = snd_pcm_sw_params_current(handle, swparams); if (err < 0) { fprintf(error_fp, "alsa: Unable to determine current swparams for %s: %s\n", id, snd_strerror(err)); return err; } err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_treshold); if (err < 0) { fprintf(error_fp, "alsa: Unable to set start threshold mode for %s: %s\n", id, snd_strerror(err)); return err; } err = snd_pcm_sw_params_set_avail_min(handle, swparams, 4); if (err < 0) { fprintf(error_fp, "alsa: Unable to set avail min for %s: %s\n", id, snd_strerror(err)); return err; } err = snd_pcm_sw_params(handle, swparams); if (err < 0) { fprintf(error_fp, "alsa: Unable to set sw params for %s: %s\n", id, snd_strerror(err)); return err; } return 0; } static int alsa_try_rate(snd_pcm_t *phandle, snd_pcm_t *chandle, snd_pcm_hw_params_t *p_hwparams, snd_pcm_hw_params_t *c_hwparams, int allow_resample, unsigned *ratep, unsigned *ratec) { int err; err = snd_pcm_hw_params_set_rate_near(chandle, c_hwparams, ratec, 0); if (err) return err; *ratep = *ratec; err = snd_pcm_hw_params_set_rate_near(phandle, p_hwparams, ratep, 0); if (err) return err; if (*ratep == *ratec) return 0; if (verbose) fprintf(error_fp, "alsa_try_rate: capture wanted %u, playback wanted %u%s\n", *ratec, *ratep, allow_resample ? " with resample enabled": ""); return 1; /* No error, but also no match */ } static int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle, snd_pcm_format_t format, int latency, int allow_resample, struct final_params *negotiated) { int i; unsigned ratep, ratec = 0; unsigned ratemin = 32000, ratemax = 96000, val; int err, channels = 2; snd_pcm_hw_params_t *p_hwparams, *c_hwparams; snd_pcm_sw_params_t *p_swparams, *c_swparams; snd_pcm_uframes_t c_size, p_psize, c_psize; /* Our latency is 2 periods (in usecs) */ unsigned int c_periods = 2, p_periods; unsigned int c_periodtime, p_periodtime; const unsigned int prefered_rates[] = { 44100, 48000, 32000 }; snd_pcm_hw_params_alloca(&p_hwparams); snd_pcm_hw_params_alloca(&c_hwparams); snd_pcm_sw_params_alloca(&p_swparams); snd_pcm_sw_params_alloca(&c_swparams); if (setparams_stream(chandle, c_hwparams, format, &channels, "capture")) return 1; if (setparams_stream(phandle, p_hwparams, format, &channels, "playback")) return 1; if (allow_resample) { err = snd_pcm_hw_params_set_rate_resample(chandle, c_hwparams, 1); if (err < 0) { fprintf(error_fp, "alsa: Resample setup failed: %s\n", snd_strerror(err)); return 1; } else if (verbose) fprintf(error_fp, "alsa: Resample enabled.\n"); } err = snd_pcm_hw_params_get_rate_min(c_hwparams, &ratemin, 0); if (err >= 0 && verbose) fprintf(error_fp, "alsa: Capture min rate is %d\n", ratemin); err = snd_pcm_hw_params_get_rate_max(c_hwparams, &ratemax, 0); if (err >= 0 && verbose) fprintf(error_fp, "alsa: Capture max rate is %u\n", ratemax); err = snd_pcm_hw_params_get_rate_min(p_hwparams, &val, 0); if (err >= 0) { if (verbose) fprintf(error_fp, "alsa: Playback min rate is %u\n", val); if (val > ratemin) ratemin = val; } err = snd_pcm_hw_params_get_rate_max(p_hwparams, &val, 0); if (err >= 0) { if (verbose) fprintf(error_fp, "alsa: Playback max rate is %u\n", val); if (val < ratemax) ratemax = val; } if (verbose) fprintf(error_fp, "alsa: Will search a common rate between %u and %u\n", ratemin, ratemax); /* First try a set of common rates */ err = -1; for (i = 0; i < ARRAY_SIZE(prefered_rates); i++) { if (prefered_rates[i] < ratemin || prefered_rates[i] > ratemax) continue; ratep = ratec = prefered_rates[i]; err = alsa_try_rate(phandle, chandle, p_hwparams, c_hwparams, allow_resample, &ratep, &ratec); if (err == 0) break; } if (err != 0) { if (ratemin >= 44100) { for (i = ratemin; i <= ratemax; i += 100) { ratep = ratec = i; err = alsa_try_rate(phandle, chandle, p_hwparams, c_hwparams, allow_resample, &ratep, &ratec); if (err == 0) break; } } else { for (i = ratemax; i >= ratemin; i -= 100) { ratep = ratec = i; err = alsa_try_rate(phandle, chandle, p_hwparams, c_hwparams, allow_resample, &ratep, &ratec); if (err == 0) break; } } } if (err < 0) { fprintf(error_fp, "alsa: Failed to set a supported rate: %s\n", snd_strerror(err)); return 1; } if (ratep != ratec) { if (verbose || allow_resample) fprintf(error_fp, "alsa: Couldn't find a rate that it is supported by both playback and capture\n"); return 2; } if (verbose) fprintf(error_fp, "alsa: Using Rate %d\n", ratec); /* Negotiate period parameters */ c_periodtime = latency * 1000 / c_periods; getparams_periods(chandle, c_hwparams, &c_periodtime, &c_periods, 1, "capture"); p_periods = c_periods * 2; p_periodtime = c_periodtime; getparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, 0, "playback"); c_periods = p_periods / 2; if (verbose) fprintf(error_fp, "alsa: Capture %u periods of %u usecs, Playback %u periods of %u usecs\n", c_periods, c_periodtime, p_periods, p_periodtime); /* * Some playback devices support a very limited periodtime range. If the user needs to * use a higher latency to avoid overrun/underrun, use an alternate algorithm of incresing * the number of periods, to archive the needed latency */ if (p_periodtime < c_periodtime) { c_periodtime = p_periodtime; c_periods = round (latency * 1000.0 / c_periodtime + 0.5); getparams_periods(chandle, c_hwparams, &c_periodtime, &c_periods, 0, "capture"); p_periods = c_periods * 2; p_periodtime = c_periodtime; getparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, 0, "playback"); c_periods = p_periods / 2; } if (setparams_periods(chandle, c_hwparams, &c_periodtime, &c_periods, "capture")) return 1; /* Note we use twice as much periods for the playback buffer, since we will get a period size near the requested time and we don't want it to end up smaller then the capture buffer as then we could end up blocking on writing to it. Note we will configure the playback dev to start playing as soon as it has 2 capture periods worth of data, so this won't influence latency */ if (setparams_periods(phandle, p_hwparams, &p_periodtime, &p_periods, "playback")) return 1; snd_pcm_hw_params_get_period_size(p_hwparams, &p_psize, NULL); snd_pcm_hw_params_get_period_size(c_hwparams, &c_psize, NULL); snd_pcm_hw_params_get_buffer_size(c_hwparams, &c_size); latency = c_periods * c_psize; if (setparams_set(phandle, p_hwparams, p_swparams, latency, "playback")) return 1; if (setparams_set(chandle, c_hwparams, c_swparams, c_psize, "capture")) return 1; if ((err = snd_pcm_prepare(phandle)) < 0) { fprintf(error_fp, "alsa: Prepare error: %s\n", snd_strerror(err)); return 1; } if (verbose) { fprintf(error_fp, "alsa: Negociated configuration:\n"); snd_pcm_dump_setup(phandle, output); snd_pcm_dump_setup(chandle, output); fprintf(error_fp, "alsa: Parameters are %iHz, %s, %i channels\n", ratep, snd_pcm_format_name(format), channels); fprintf(error_fp, "alsa: Set bitrate to %u%s, buffer size is %u\n", ratec, allow_resample ? " with resample enabled at playback": "", (unsigned int)c_size); } negotiated->bufsize = c_size; negotiated->rate = ratep; negotiated->channels = channels; negotiated->latency = latency; return 0; } /* Read up to len frames */ static snd_pcm_sframes_t readbuf(snd_pcm_t *handle, char *buf, long len) { snd_pcm_sframes_t r; r = snd_pcm_readi(handle, buf, len); if (r < 0 && r != -EAGAIN) { r = snd_pcm_recover(handle, r, 0); if (r < 0) fprintf(error_fp, "alsa: overrun recover error: %s\n", snd_strerror(r)); } return r; } /* Write len frames (note not up to len, but all of len!) */ static snd_pcm_sframes_t writebuf(snd_pcm_t *handle, char *buf, long len) { snd_pcm_sframes_t r; while (1) { r = snd_pcm_writei(handle, buf, len); if (r == len) return 0; if (r < 0) { r = snd_pcm_recover(handle, r, 0); if (r < 0) { fprintf(error_fp, "alsa: underrun recover error: %s\n", snd_strerror(r)); return r; } } buf += r * 4; len -= r; snd_pcm_wait(handle, 100); } } static int alsa_stream(const char *pdevice, const char *cdevice, int latency) { snd_pcm_t *phandle, *chandle; char *buffer; int err; ssize_t r; struct final_params negotiated; snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; char pdevice_new[32]; err = snd_output_stdio_attach(&output, error_fp, 0); if (err < 0) { fprintf(error_fp, "alsa: Output failed: %s\n", snd_strerror(err)); return 0; } /* Open the devices */ if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n", pdevice, snd_strerror(err)); return 0; } if ((err = snd_pcm_open(&chandle, cdevice, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { fprintf(error_fp, "alsa: Cannot open capture device %s: %s\n", cdevice, snd_strerror(err)); snd_pcm_close(phandle); return 0; } err = setparams(phandle, chandle, format, latency, 0, &negotiated); /* Try to use plughw instead, as it allows emulating speed */ if (err == 2 && strncmp(pdevice, "hw", 2) == 0) { snd_pcm_close(phandle); sprintf(pdevice_new, "plug%s", pdevice); pdevice = pdevice_new; if (verbose) fprintf(error_fp, "alsa: Trying %s for playback\n", pdevice); if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n", pdevice, snd_strerror(err)); snd_pcm_close(chandle); return 0; } err = setparams(phandle, chandle, format, latency, 1, &negotiated); } if (err != 0) { fprintf(error_fp, "alsa: setparams failed\n"); snd_pcm_close(phandle); snd_pcm_close(chandle); return 1; } buffer = malloc((negotiated.bufsize * snd_pcm_format_width(format) / 8) * negotiated.channels); if (buffer == NULL) { fprintf(error_fp, "alsa: Failed allocating buffer for audio\n"); snd_pcm_close(phandle); snd_pcm_close(chandle); return 0; } if (verbose) fprintf(error_fp, "alsa: stream started from %s to %s (%i Hz, buffer delay = %.2f ms)\n", cdevice, pdevice, negotiated.rate, negotiated.latency * 1000.0 / negotiated.rate); while (!stop_alsa) { /* We start with a read and not a wait to auto(re)start the capture */ r = readbuf(chandle, buffer, negotiated.bufsize); if (r == 0) /* Succesfully recovered from an overrun? */ continue; /* Force restart of capture stream */ if (r > 0) writebuf(phandle, buffer, r); /* use poll to wait for next event */ while (!stop_alsa && !snd_pcm_wait(chandle, 50)) ; } snd_pcm_drop(chandle); snd_pcm_drop(phandle); snd_pcm_unlink(chandle); snd_pcm_hw_free(phandle); snd_pcm_hw_free(chandle); snd_pcm_close(phandle); snd_pcm_close(chandle); return 0; } struct input_params { char *pdevice; char *cdevice; int latency; }; static void *alsa_thread_entry(void *whatever) { struct input_params *inputs = (struct input_params *) whatever; if (verbose) fprintf(error_fp, "alsa: starting copying alsa stream from %s to %s\n", inputs->cdevice, inputs->pdevice); alsa_stream(inputs->pdevice, inputs->cdevice, inputs->latency); if (verbose) fprintf(error_fp, "alsa: stream stopped\n"); free(inputs->pdevice); free(inputs->cdevice); free(inputs); return NULL; } /************************************************************************* Public functions *************************************************************************/ static int alsa_is_running = 0; static pthread_t alsa_thread; int alsa_thread_startup(const char *pdevice, const char *cdevice, int latency, FILE *__error_fp, int __verbose) { int ret; struct input_params *inputs; if ((strcasecmp(pdevice, "disabled") == 0) || (strcasecmp(cdevice, "disabled") == 0)) return 0; if (__error_fp) error_fp = __error_fp; else error_fp = stderr; verbose = __verbose; if (alsa_is_running) { fprintf(error_fp, "alsa: Already running\n"); return EBUSY; } inputs = malloc(sizeof(struct input_params)); if (inputs == NULL) { fprintf(error_fp, "alsa: failed allocating memory for inputs\n"); return ENOMEM; } inputs->pdevice = strdup(pdevice); inputs->cdevice = strdup(cdevice); inputs->latency = latency; stop_alsa = 0; ret = pthread_create(&alsa_thread, NULL, &alsa_thread_entry, (void *) inputs); if (ret == 0) alsa_is_running = 1; return ret; } void alsa_thread_stop(void) { if (!alsa_is_running) return; stop_alsa = 1; pthread_join(alsa_thread, NULL); alsa_is_running = 0; } int alsa_thread_is_running(void) { return alsa_is_running; } #endif xawtv-3.106/common/alsa_stream.h000066400000000000000000000002661343350355000166350ustar00rootroot00000000000000int alsa_thread_startup(const char *pdevice, const char *cdevice, int latency, FILE *__error_fp, int __verbose); void alsa_thread_stop(void); int alsa_thread_is_running(void); xawtv-3.106/common/capture.c000066400000000000000000000405611343350355000160020ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "grab-ng.h" #include "commands.h" /* FIXME: *drv globals */ #include "sound.h" #include "capture.h" #include "webcam.h" #define MAX_THREADS 4 #define REORDER_SIZE 32 /*-------------------------------------------------------------------------*/ /* data fifos (audio/video) */ void fifo_init(struct FIFO *fifo, char *name, int slots, int writers) { pthread_mutex_init(&fifo->lock, NULL); pthread_cond_init(&fifo->hasdata, NULL); fifo->name = name; fifo->slots = slots; fifo->writers = writers; fifo->read = 0; fifo->write = 0; fifo->eof = 0; fifo->max = 0; } int fifo_put(struct FIFO *fifo, void *data) { int full; pthread_mutex_lock(&fifo->lock); if (NULL == data) { fifo->eof++; if (debug) fprintf(stderr,"fifo %s: EOF %d/%d\n", fifo->name,fifo->eof,fifo->writers); if (fifo->writers == fifo->eof) pthread_cond_broadcast(&fifo->hasdata); pthread_mutex_unlock(&fifo->lock); return 0; } if ((fifo->write + 1) % fifo->slots == fifo->read) { pthread_mutex_unlock(&fifo->lock); fprintf(stderr,"fifo %s is full\n",fifo->name); return -1; } if (debug > 1) fprintf(stderr,"put %s %d=%p [pid=%d]\n", fifo->name,fifo->write,data,getpid()); fifo->data[fifo->write] = data; fifo->write++; full = (fifo->write + fifo->slots - fifo->read) % fifo->slots; if (fifo->max < full) fifo->max = full; if (fifo->write >= fifo->slots) fifo->write = 0; pthread_cond_signal(&fifo->hasdata); pthread_mutex_unlock(&fifo->lock); return 0; } void* fifo_get(struct FIFO *fifo) { void *data; pthread_mutex_lock(&fifo->lock); while (fifo->write == fifo->read && fifo->writers != fifo->eof) { pthread_cond_wait(&fifo->hasdata, &fifo->lock); } if (fifo->write == fifo->read) { pthread_cond_signal(&fifo->hasdata); pthread_mutex_unlock(&fifo->lock); return NULL; } if (debug > 1) fprintf(stderr,"get %s %d=%p [pid=%d]\n", fifo->name,fifo->read,fifo->data[fifo->read],getpid()); data = fifo->data[fifo->read]; fifo->read++; if (fifo->read >= fifo->slots) fifo->read = 0; pthread_mutex_unlock(&fifo->lock); return data; } static void* flushit(void *arg) { int old; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&old); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&old); for (;;) { sleep(1); sync(); } return NULL; } /*-------------------------------------------------------------------------*/ /* color space conversion / compression thread */ struct ng_convthread_handle { /* converter data / state */ struct ng_convert_handle *c; /* thread data */ struct FIFO *in; struct FIFO *out; }; void* ng_convert_thread(void *arg) { struct ng_convthread_handle *h = arg; struct ng_video_buf *in, *out; if (debug) fprintf(stderr,"convert_thread start [pid=%d]\n",getpid()); ng_convert_init(h->c); for (;;) { in = fifo_get(h->in); if (NULL == in) break; out = ng_convert_frame(h->c,NULL,in); if (NULL != webcam && 0 == webcam_put(webcam,out)) { free(webcam); webcam = NULL; } fifo_put(h->out,out); } fifo_put(h->out,NULL); ng_convert_fini(h->c); if (debug) fprintf(stderr,"convert_thread done [pid=%d]\n",getpid()); return NULL; } /*-------------------------------------------------------------------------*/ /* parameter negotiation -- look what the driver can do and what */ /* convert functions are available */ int ng_grabber_setformat(struct ng_video_fmt *fmt, int fix_ratio) { struct ng_video_fmt gfmt; int rc; /* no capture support */ if (!(f_drv & CAN_CAPTURE)) return -1; /* try setting the format */ gfmt = *fmt; rc = drv->setformat(h_drv,&gfmt); if (debug) fprintf(stderr,"setformat: %s (%dx%d): %s\n", ng_vfmt_to_desc[gfmt.fmtid], gfmt.width,gfmt.height, (0 == rc) ? "ok" : "failed"); if (0 != rc) return -1; if (fix_ratio) { /* fixup aspect ratio if needed */ ng_ratio_fixup(&gfmt.width, &gfmt.height, NULL, NULL); gfmt.bytesperline = 0; if (0 != drv->setformat(h_drv,&gfmt)) { fprintf(stderr,"Oops: ratio size renegotiation failed\n"); exit(1); } } /* return the real format the grabber uses now */ *fmt = gfmt; return 0; } struct ng_video_conv* ng_grabber_findconv(struct ng_video_fmt *fmt, int fix_ratio) { struct ng_video_fmt gfmt; struct ng_video_conv *conv; int i; /* check all available conversion functions */ for (i = 0;;) { conv = ng_conv_find_to(fmt->fmtid, &i); if (NULL == conv) break; gfmt = *fmt; gfmt.fmtid = conv->fmtid_in; if (0 == ng_grabber_setformat(&gfmt,fix_ratio)) goto found; } fprintf(stderr,"no way to get: %dx%d %s\n", fmt->width,fmt->height,ng_vfmt_to_desc[fmt->fmtid]); return NULL; found: *fmt = gfmt; return conv; } struct ng_video_buf* ng_grabber_grab_image(int single) { return single ? drv->getimage(h_drv) : drv->nextframe(h_drv); } struct ng_video_buf* ng_grabber_get_image(struct ng_video_fmt *fmt) { struct ng_video_fmt gfmt; struct ng_video_conv *conv; struct ng_convert_handle *ch; struct ng_video_buf *buf; if (0 == ng_grabber_setformat(fmt,1)) return ng_grabber_grab_image(1); gfmt = *fmt; if (NULL == (conv = ng_grabber_findconv(&gfmt,1))) return NULL; ch = ng_convert_alloc(conv,&gfmt,fmt); if (NULL == (buf = ng_grabber_grab_image(1))) return NULL; buf = ng_convert_single(ch,buf); return buf; } /*-------------------------------------------------------------------------*/ struct movie_handle { /* general */ pthread_mutex_t lock; const struct ng_writer *writer; void *handle; pthread_t tflush; uint64_t start; uint64_t rts; uint64_t stopby; int slots; /* video */ struct ng_video_fmt vfmt; int fps; int frames; int seq; struct FIFO vfifo; pthread_t tvideo; uint64_t vts; /* video converter thread */ struct FIFO cfifo; int cthreads; struct ng_convthread_handle *hconv[MAX_THREADS]; pthread_t tconv[MAX_THREADS]; /* audio */ const struct ng_dsp_driver *dsp; void *hdsp; struct ng_audio_fmt afmt; unsigned long bytes_per_sec; unsigned long bytes; struct FIFO afifo; pthread_t taudio; pthread_t raudio; uint64_t ats; uint64_t rdrift; uint64_t vdrift; }; static void* writer_audio_thread(void *arg) { struct movie_handle *h = arg; struct ng_audio_buf *buf; if (debug) fprintf(stderr,"writer_audio_thread start [pid=%d]\n",getpid()); for (;;) { buf = fifo_get(&h->afifo); if (NULL == buf) break; pthread_mutex_lock(&h->lock); h->writer->wr_audio(h->handle,buf); pthread_mutex_unlock(&h->lock); free(buf); } if (debug) fprintf(stderr,"writer_audio_thread done\n"); return NULL; } /* * with multiple compression threads we might receive * the frames out-of-order */ static void* writer_video_thread(void *arg) { struct movie_handle *h = arg; struct ng_video_buf *buf; struct ng_video_buf *reorder[REORDER_SIZE]; int seq,slot; if (debug) fprintf(stderr,"writer_video_thread start [pid=%d]\n",getpid()); seq = 0; memset(&reorder,0,sizeof(reorder)); for (;;) { buf = fifo_get(&h->vfifo); if (NULL == buf) break; slot = buf->info.seq % REORDER_SIZE; if (debug > 1) fprintf(stderr,"video write: get seq=%d [%d]\n", buf->info.seq,slot); if (reorder[slot]) { fprintf(stderr,"panic: reorder buffer full\n"); exit(1); } reorder[slot] = buf; for (;;) { slot = seq % REORDER_SIZE; if (NULL == reorder[slot]) break; buf = reorder[slot]; reorder[slot] = NULL; if (debug > 1) fprintf(stderr,"video write: put seq=%d [%d/%d]\n", buf->info.seq,slot,seq); seq++; pthread_mutex_lock(&h->lock); h->writer->wr_video(h->handle,buf); if (buf->info.twice) h->writer->wr_video(h->handle,buf); pthread_mutex_unlock(&h->lock); ng_release_video_buf(buf); } } if (debug) fprintf(stderr,"writer_video_thread done\n"); return NULL; } static void* record_audio_thread(void *arg) { struct movie_handle *h = arg; struct ng_audio_buf *buf; if (debug) fprintf(stderr,"record_audio_thread start [pid=%d]\n",getpid()); for (;;) { buf = h->dsp->read(h->hdsp,h->stopby); if (NULL == buf) break; if (0 == buf->size) continue; h->ats = buf->info.ts; h->rts = ng_get_timestamp() - h->start; h->rdrift = h->rts - h->ats; h->vdrift = h->vts - h->ats; if (0 != fifo_put(&h->afifo,buf)) free(buf); } fifo_put(&h->afifo,NULL); if (debug) fprintf(stderr,"record_audio_thread done\n"); return NULL; } struct movie_handle* movie_writer_init(char *moviename, char *audioname, const struct ng_writer *writer, struct ng_video_fmt *video,const void *priv_video,int fps, struct ng_audio_fmt *audio,const void *priv_audio,char *dsp, int slots, int threads) { struct movie_handle *h; struct ng_video_conv *conv; void *dummy; int i; if (debug) fprintf(stderr,"movie_init_writer start\n"); h = malloc(sizeof(*h)); if (NULL == h) return NULL; memset(h,0,sizeof(*h)); pthread_mutex_init(&h->lock, NULL); h->writer = writer; h->slots = slots; /* audio */ if (audio->fmtid != AUDIO_NONE) { h->dsp = ng_dsp_open(dsp,audio,1,&h->hdsp); if (NULL == h->dsp) { free(h); return NULL; } fifo_init(&h->afifo,"audio",slots,1); pthread_create(&h->taudio,NULL,writer_audio_thread,h); h->bytes_per_sec = ng_afmt_to_bits[audio->fmtid] * ng_afmt_to_channels[audio->fmtid] * audio->rate / 8; h->afmt = *audio; } /* video */ if (video->fmtid != VIDEO_NONE) { if (0 == ng_grabber_setformat(video,1)) { /* native format works -- no conversion needed */ fifo_init(&h->vfifo,"video",slots,1); pthread_create(&h->tvideo,NULL,writer_video_thread,h); } else { /* have to convert video frames */ struct ng_video_fmt gfmt = *video; if (NULL == (conv = ng_grabber_findconv(&gfmt,1))) { if (h->afmt.fmtid != AUDIO_NONE) h->dsp->close(h->hdsp); free(h); return NULL; } h->cthreads = threads; if (h->cthreads < 1) h->cthreads = 1; if (h->cthreads > MAX_THREADS) h->cthreads = MAX_THREADS; fifo_init(&h->vfifo,"video",slots,h->cthreads); fifo_init(&h->cfifo,"conv",slots,1); pthread_create(&h->tvideo,NULL,writer_video_thread,h); for (i = 0; i < h->cthreads; i++) { h->hconv[i] = malloc(sizeof(struct ng_convthread_handle)); memset(h->hconv[i],0,sizeof(struct ng_convthread_handle)); h->hconv[i]->c = ng_convert_alloc(conv,&gfmt,video); h->hconv[i]->in = &h->cfifo; h->hconv[i]->out = &h->vfifo; pthread_create(&h->tconv[i],NULL,ng_convert_thread, h->hconv[i]); } } h->vfmt = *video; h->fps = fps; } /* open file */ h->handle = writer->wr_open(moviename,audioname, video,priv_video,fps, audio,priv_audio); if (debug) fprintf(stderr,"movie_init_writer end (h=%p)\n",h->handle); if (NULL != h->handle) return h; /* Oops -- wr_open() didn't work. cleanup. */ if (h->afmt.fmtid != AUDIO_NONE) { pthread_cancel(h->taudio); pthread_join(h->taudio,&dummy); h->dsp->close(h->hdsp); } if (h->vfmt.fmtid != VIDEO_NONE) { pthread_cancel(h->tvideo); pthread_join(h->tvideo,&dummy); } for (i = 0; i < h->cthreads; i++) { pthread_cancel(h->tconv[i]); pthread_join(h->tconv[i],&dummy); } free(h); return NULL; } int movie_writer_start(struct movie_handle *h) { int rc = 0; if (debug) fprintf(stderr,"movie_writer_start\n"); h->start = ng_get_timestamp(); if (h->afmt.fmtid != AUDIO_NONE) if (0 != h->dsp->startrec(h->hdsp)) rc = -1; if (h->vfmt.fmtid != VIDEO_NONE) if (0 != drv->startvideo(h_drv,h->fps,h->slots)) rc = -1; if (h->afmt.fmtid != AUDIO_NONE) pthread_create(&h->raudio,NULL,record_audio_thread,h); pthread_create(&h->tflush,NULL,flushit,NULL); return rc; } int movie_writer_stop(struct movie_handle *h) { char line[128]; uint64_t stopby; int frames,i; void *dummy; if (debug) fprintf(stderr,"movie_writer_stop\n"); if (h->vfmt.fmtid != VIDEO_NONE && h->afmt.fmtid != AUDIO_NONE) { for (frames = 0; frames < 16; frames++) { stopby = (uint64_t)(h->frames + frames) * (uint64_t)1000000000000ULL / h->fps; if (stopby > h->ats) break; } frames++; h->stopby = (uint64_t)(h->frames + frames) * (uint64_t)1000000000000ULL / h->fps; while (frames) { movie_grab_put_video(h,NULL); frames--; } } else if (h->afmt.fmtid != AUDIO_NONE) { h->stopby = h->ats; } /* send EOF */ if (h->cthreads) fifo_put(&h->cfifo,NULL); else fifo_put(&h->vfifo,NULL); /* join threads */ if (h->afmt.fmtid != AUDIO_NONE) { pthread_join(h->raudio,&dummy); pthread_join(h->taudio,&dummy); } if (h->vfmt.fmtid != VIDEO_NONE) pthread_join(h->tvideo,&dummy); for (i = 0; i < h->cthreads; i++) pthread_join(h->tconv[i],&dummy); pthread_cancel(h->tflush); pthread_join(h->tflush,&dummy); /* close file */ h->writer->wr_close(h->handle); if (h->afmt.fmtid != AUDIO_NONE) h->dsp->close(h->hdsp); if (h->vfmt.fmtid != VIDEO_NONE) drv->stopvideo(h_drv); /* fifo stats */ sprintf(line, "fifo max fill: audio %d/%d, video %d/%d, convert %d/%d", h->afifo.max,h->afifo.slots, h->vfifo.max,h->vfifo.slots, h->cfifo.max,h->cfifo.slots); rec_status(line); free(h); return 0; } /*-------------------------------------------------------------------------*/ static void movie_print_timestamps(struct movie_handle *h) { char line[128]; if (NULL == rec_status) return; sprintf(line,"rec %d:%02d.%02d - a/r: %c%d.%02ds [%d], a/v: %c%d.%02ds [%d]", (int)(h->rts / 1000000000 / 60), (int)(h->rts / 1000000000 % 60), (int)((h->rts % 1000000000) / 10000000), (h->rdrift > 0) ? '+' : '-', (int)((h->rdrift / 1000000000)), (int)((h->rdrift % 1000000000) / 10000000), (int)(h->rdrift * h->fps / (uint64_t)1000000000000ULL), (h->vdrift > 0) ? '+' : '-', (int)((h->vdrift / 1000000000)), (int)((h->vdrift % 1000000000) / 10000000), (int)(h->vdrift * h->fps / (uint64_t)1000000000000ULL)); rec_status(line); } int movie_grab_put_video(struct movie_handle *h, struct ng_video_buf **ret) { struct ng_video_buf *buf; int expected,rc; if (debug > 1) fprintf(stderr,"grab_put_video\n"); /* fetch next frame */ buf = ng_grabber_grab_image(0); if (NULL == buf) { if (debug) fprintf(stderr,"grab_put_video: grab image failed\n"); return -1; } #if 0 /* FIXME */ buf = ng_filter_single(cur_filter,buf); #endif /* rate control */ expected = (buf->info.ts - h->vdrift) * h->fps / (uint64_t)1000000000000ULL; if (expected < h->frames-1) { if (debug > 1) fprintf(stderr,"rate: ignoring frame [%d %d]\n", expected, h->frames); ng_release_video_buf(buf); return 0; } if (expected > h->frames+1) { fprintf(stderr,"rate: queueing frame twice (%d)\n", expected-h->frames); buf->info.twice++; h->frames++; } h->frames++; h->vts = buf->info.ts; buf->info.seq = h->seq; /* return a pointer to the frame if requested */ if (NULL != ret) { buf->refcount++; *ret = buf; } /* put into fifo */ if (h->cthreads) rc = fifo_put(&h->cfifo,buf); else rc = fifo_put(&h->vfifo,buf); if (0 != rc) { ng_release_video_buf(buf); return h->frames; } h->seq++; /* feedback */ movie_print_timestamps(h); return h->frames; } xawtv-3.106/common/capture.h000066400000000000000000000022621343350355000160030ustar00rootroot00000000000000#ifndef CAPTURE_H #define CAPTURE_H #define FIFO_MAX 64 struct FIFO { char *name; unsigned char *data[FIFO_MAX]; int slots,read,write,eof,max,writers; pthread_mutex_t lock; pthread_cond_t hasdata; }; void fifo_init(struct FIFO *fifo, char *name, int slots, int writers); int fifo_put(struct FIFO *fifo, void *data); void* fifo_get(struct FIFO *fifo); void* ng_convert_thread(void *arg); int ng_grabber_setformat(struct ng_video_fmt *fmt, int fix_ratio); struct ng_video_conv* ng_grabber_findconv(struct ng_video_fmt *fmt, int fix_ratio); struct ng_video_buf* ng_grabber_grab_image(int single); struct ng_video_buf* ng_grabber_get_image(struct ng_video_fmt *fmt); struct movie_handle* movie_writer_init(char *moviename, char *audioname, const struct ng_writer *writer, struct ng_video_fmt *video,const void *priv_video,int fps, struct ng_audio_fmt *audio,const void *priv_audio,char *dsp, int slots, int threads); int movie_writer_start(struct movie_handle*); int movie_writer_stop(struct movie_handle*); int movie_grab_put_video(struct movie_handle*, struct ng_video_buf **ret); int movie_grab_put_audio(struct movie_handle*); #endif /* CAPTURE_H */ xawtv-3.106/common/channel.c000066400000000000000000000520101343350355000157370ustar00rootroot00000000000000/* channel for Bt848 frame grabber driver Copyright (C) 1996,97 Marcus Metzler (mocm@thp.uni-koeln.de) (c) 1998-2003 Gerd Knorr 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 "config.h" #include #include #include #include #include #include #include #ifndef NO_X11 # include # include # include # include # include # include #endif #include "grab-ng.h" #include "channel.h" #include "commands.h" #include "frequencies.h" #include "sound.h" #include "parseconfig.h" #include "event.h" /* ----------------------------------------------------------------------- */ /* misc common stuff, not only channel related */ struct CHANNEL defaults = { .name = "defaults", .group = "main", .capture = CAPTURE_ON, .channel = -1, .audio = -1, .color = -1, .bright = -1, .hue = -1, .contrast = -1, }; struct CHANNEL **channels = NULL; int count = 0; int alloc_count = 0; int last_sender = -1, cur_sender = -1, cur_channel = -1, cur_fine = 0; int cur_freq; struct ng_filter *cur_filter; int cur_capture = CAPTURE_OFF; int have_config; int keypad_ntsc = 0; int keypad_partial = 1; int use_wm_fullscreen = 1; int use_osd = 1; int osd_x = 30; int osd_y = 20; int fs_width,fs_height,fs_xoff,fs_yoff; int pix_width=128, pix_height=96, pix_cols=1; char *mov_driver = NULL; char *mov_video = NULL; char *mov_fps = NULL; char *mov_audio = NULL; char *mov_rate = NULL; #ifndef NO_X11 extern Widget chan_box, chan_viewport, tv, opt_paned, launch_paned; #endif static char *mixer = NULL; char mixerdev[32],mixerctl[16]; char *midi = NULL; struct LAUNCH *launch = NULL; int nlaunch = 0; /* ----------------------------------------------------------------------- */ int lookup_channel(char *channel) { #if 0 /* Hmm, why the heck that used to be that complex? * Any good reason I forgot ? */ int i,nr1,nr2; char tag1[5],tag2[5]; if (NULL == channel) return -1; if (isdigit(channel[0])) { tag1[0] = 0; nr1 = atoi(channel); } else { sscanf(channel,"%4[A-Za-z]%d",tag1,&nr1); } for (i = 0; i < chancount; i++) { if (isdigit(chanlist[i].name[0])) { tag2[0] = 0; nr2 = atoi(chanlist[i].name); } else { sscanf(chanlist[i].name,"%4[A-Za-z]%d",tag2,&nr2); } if (tag1[0] && tag2[0]) if (nr1 == nr2 && 0 == strcmp(tag1,tag2)) break; if (!tag1[0] && !tag2[0]) if (nr1 == nr2) break; } if (i == chancount) return -1; return i; #else int i; if (NULL == channel) return -1; for (i = 0; i < chancount; i++) if (0 == strcasecmp(chanlist[i].name,channel)) break; if (i == chancount) return -1; return i; #endif } int get_freq(int i) { if (i < 0 || i >= chancount) return -1; return chanlist[i].freq*16/1000; } int cf2freq(char *name, int fine) { int i; if (-1 == (i = lookup_channel(name))) return -1; return get_freq(i)+fine; } /* ----------------------------------------------------------------------- */ struct STRTAB captab[] = { { CAPTURE_ON, "on" }, { CAPTURE_ON, "yes" }, { CAPTURE_ON, "true" }, { CAPTURE_OFF, "off" }, { CAPTURE_OFF, "no" }, { CAPTURE_OFF, "false" }, { CAPTURE_OVERLAY, "over" }, { CAPTURE_OVERLAY, "overlay" }, { CAPTURE_GRABDISPLAY, "grab" }, { CAPTURE_GRABDISPLAY, "grabdisplay" }, { -1, NULL, }, }; /* just malloc memory for a new channel ... */ struct CHANNEL* add_channel(char *name) { struct CHANNEL *channel; if (alloc_count == count) { alloc_count += 16; if (alloc_count == 16) channels = malloc(sizeof(struct CHANNEL*)*alloc_count); else channels = realloc(channels,sizeof(struct CHANNEL*)*alloc_count); } channel = channels[count++] = malloc(sizeof(struct CHANNEL)); memcpy(channel,&defaults,sizeof(struct CHANNEL)); channel->name = strdup(name); return channel; } #ifndef NO_X11 #define PANED_FIX \ XtNallowResize, False, \ XtNshowGrip, False, \ XtNskipAdjust, True void hotkey_channel(struct CHANNEL *channel) { char str[100],key[32],ctrl[16]; if (NULL == channel->key) return; if (2 == sscanf(channel->key,"%15[A-Za-z0-9_]+%31[A-Za-z0-9_]", ctrl,key)) sprintf(str,"%s%s: Command(setstation,\"%s\")", ctrl,key,channel->name); else sprintf(str,"%s: Command(setstation,\"%s\")", channel->key,channel->name); XtOverrideTranslations(tv,XtParseTranslationTable(str)); XtOverrideTranslations(opt_paned,XtParseTranslationTable(str)); XtOverrideTranslations(chan_viewport,XtParseTranslationTable(str)); } static void launch_cb(Widget widget, XtPointer clientdata, XtPointer call_data) { char *argv[2]; argv[0] = (char*)clientdata; argv[1] = NULL; XtCallActionProc(widget,"Launch",NULL,argv,1); } static void hotkey_launch(struct LAUNCH *launch) { Widget c; char str[100],key[32],ctrl[16],label[64]; if (NULL == launch->key) return; if (2 == sscanf(launch->key,"%15[A-Za-z0-9_]+%31[A-Za-z0-9_]", ctrl,key)) sprintf(str,"%s%s: Launch(\"%s\")",ctrl,key,launch->name); else sprintf(str,"%s: Launch(\"%s\")",launch->key,launch->name); XtOverrideTranslations(tv,XtParseTranslationTable(str)); XtOverrideTranslations(opt_paned,XtParseTranslationTable(str)); XtOverrideTranslations(chan_viewport,XtParseTranslationTable(str)); sprintf(label,"%-20s %s",launch->name,launch->key); c = XtVaCreateManagedWidget(launch->name, commandWidgetClass, launch_paned, PANED_FIX, XtNlabel,label, NULL); XtAddCallback(c,XtNcallback,launch_cb,(XtPointer)(launch->name)); } static void button_cb(Widget widget, XtPointer clientdata, XtPointer call_data) { struct CHANNEL *channel = clientdata; do_va_cmd(2,"setstation",channel->name); } /* ... and initalize later */ void configure_channel(struct CHANNEL *channel) { channel->button = XtVaCreateManagedWidget(channel->name, commandWidgetClass, chan_box, XtNwidth,pix_width, XtNheight,pix_height, NULL); XtAddCallback(channel->button,XtNcallback,button_cb,(XtPointer*)channel); hotkey_channel(channel); } #endif /* delete channel */ void del_channel(int i) { free(channels[i]->name); if (channels[i]->key) free(channels[i]->key); free(channels[i]); count--; if (i < count) memmove(channels+i,channels+i+1,(count-i)*sizeof(struct CHANNEL*)); } void calc_frequencies() { int i; for (i = 0; i < count; i++) { if (NULL == channels[i]->cname) continue; channels[i]->channel = lookup_channel(channels[i]->cname); if (-1 == channels[i]->channel) channels[i]->freq = -1; else channels[i]->freq = get_freq(channels[i]->channel) + channels[i]->fine; } } /* ----------------------------------------------------------------------- */ static void init_channel(char *name, struct CHANNEL *c) { struct ng_attribute *attr; char *val; int n,i; if (NULL != (val = cfg_get_str(name,"capture"))) { if (-1 != (i = str_to_int(val,captab))) c->capture = i; else fprintf(stderr,"config: invalid value for capture: %s\n",val); } if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_INPUT)) && (NULL != (val = cfg_get_str(name,"input")) || NULL != (val = cfg_get_str(name,"source")))) { /* obsolete */ if (-1 != (i = ng_attr_getint(attr,val))) c->input = i; else { fprintf(stderr,"config: invalid value for input: %s\n",val); ng_attr_listchoices(attr); } } if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_NORM)) && NULL != (val = cfg_get_str(name,"norm"))) { if (-1 != (i = ng_attr_getint(attr,val))) c->norm = i; else { fprintf(stderr,"config: invalid value for norm: %s\n",val); ng_attr_listchoices(attr); } } if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_AUDIO_MODE)) && NULL != (val = cfg_get_str(name,"audio"))) { if (-1 != (i = ng_attr_getint(attr,val))) c->audio = i; else { fprintf(stderr,"config: invalid value for audio: %s\n",val); ng_attr_listchoices(attr); } } if (NULL != (val = cfg_get_str(name,"channel"))) c->cname = strdup(val); if (NULL != (val = cfg_get_str(name,"freq"))) c->freq = (int)(atof(val)*16); if (0 != (n = cfg_get_signed_int(name,"fine"))) c->fine = n; if (NULL != (val = cfg_get_str(name,"key"))) c->key = strdup(val); if (NULL != (val = cfg_get_str(name,"group"))) c->group = strdup(val); if (NULL != (val = cfg_get_str(name,"midi"))) c->midi = atoi(val); attr = ng_attr_byid(attrs,ATTR_ID_COLOR); if (attr && NULL != (val = cfg_get_str(name,"color"))) c->color = ng_attr_parse_int(attr,val); attr = ng_attr_byid(attrs,ATTR_ID_BRIGHT); if (attr && NULL != (val = cfg_get_str(name,"bright"))) c->bright = ng_attr_parse_int(attr,val); attr = ng_attr_byid(attrs,ATTR_ID_HUE); if (attr && NULL != (val = cfg_get_str(name,"hue"))) c->hue = ng_attr_parse_int(attr,val); attr = ng_attr_byid(attrs,ATTR_ID_CONTRAST); if (attr && NULL != (val = cfg_get_str(name,"contrast"))) c->contrast = ng_attr_parse_int(attr,val); } void read_config(char *conffile, int *argc, char **argv) { struct list_head *item; char filename[100]; char *val; int i; if (conffile) { if (0 == cfg_parse_file(conffile)) have_config = 1; } else { sprintf(filename,"%.*s/%s",(int)sizeof(filename)-8, getenv("HOME"),".xawtv"); if (0 == cfg_parse_file(CONFIGFILE)) have_config = 1; if (0 == cfg_parse_file(filename)) have_config = 1; } if (argc) cfg_parse_options(argc,argv); /* misc global settings */ if (NULL != (val = cfg_get_str("global","mixer"))) { mixer = strdup(val); if (2 != sscanf(mixer,"%31[^:]:%15s",mixerdev,mixerctl)) { strcpy(mixerdev,ng_dev.mixer); strncpy(mixerctl,val,15); mixerctl[15] = 0; } } if (NULL != (val = cfg_get_str("global","midi"))) midi = strdup(val); if (NULL != (val = cfg_get_str("global","freqtab"))) { for (i = 0; chanlists[i].name != NULL; i++) if (0 == strcasecmp(val,chanlists[i].name)) break; if (chanlists[i].name != NULL) { freq_newtab(i); } else fprintf(stderr,"invalid value for freqtab: %s\n",val); } if (NULL != (val = cfg_get_str("global","fullscreen"))) { if (2 != sscanf(val,"%d x %d",&fs_width,&fs_height)) { fprintf(stderr,"invalid value for fullscreen: %s\n",val); fs_width = fs_height = 0; } } if (NULL != (val = cfg_get_str("global","pixsize"))) { if (2 != sscanf(val,"%d x %d",&pix_width,&pix_height)) { fprintf(stderr,"invalid value for pixsize: %s\n",val); pix_width = 128; pix_height = 96; } } if (-1 != (i = cfg_get_int("global","pixcols"))) pix_cols = i; if (NULL != (val = cfg_get_str("global","wm-off-by"))) { if (2 != sscanf(val,"%d %d",&fs_xoff,&fs_yoff)) { fprintf(stderr,"invalid value for wm-off-by: %s\n",val); fs_xoff = fs_yoff = 0; } } if (NULL != (val = cfg_get_str("global","ratio"))) { if (2 != sscanf(val,"%d:%d",&ng_ratio_x,&ng_ratio_y)) { fprintf(stderr,"invalid value for ratio: %s\n",val); ng_ratio_x = ng_ratio_y = 0; } } if (-1 != (i = cfg_get_int("global","jpeg-quality"))) ng_jpeg_quality = i; if (NULL != (val = cfg_get_str("global","keypad-ntsc"))) if (-1 != (i = str_to_int(val,booltab))) keypad_ntsc = i; if (NULL != (val = cfg_get_str("global","keypad-partial"))) if (-1 != (i = str_to_int(val,booltab))) keypad_partial = i; if (NULL != (val = cfg_get_str("global","osd"))) if (-1 != (i = str_to_int(val,booltab))) use_osd = i; if (NULL != (val = cfg_get_str("global","osd-position"))) if (2 != sscanf(val,"%d , %d",&osd_x,&osd_y)) fprintf(stderr,"invalid values for osd-position: %s\n",val); if (NULL != (val = cfg_get_str("global","use-wm-fullscreen"))) if (-1 != (i = str_to_int(val,booltab))) use_wm_fullscreen = i; if (NULL != (val = cfg_get_str("global","mov-driver"))) mov_driver = val; if (NULL != (val = cfg_get_str("global","mov-video"))) mov_video = val; if (NULL != (val = cfg_get_str("global","mov-fps"))) mov_fps = val; if (NULL != (val = cfg_get_str("global","mov-audio"))) mov_audio = val; if (NULL != (val = cfg_get_str("global","mov-rate"))) mov_rate = val; if (NULL != (val = cfg_get_str("global","filter"))) { list_for_each(item,&ng_filters) { struct ng_filter *f = list_entry(item, struct ng_filter, list); if (0 == strcasecmp(f->name, val)) cur_filter = f; } } } void parse_config(int parse_channels) { char key[16], cmdline[128]; char **list,*val; #ifndef NO_X11 int i; #endif /* launch */ list = cfg_list_entries("launch"); if (NULL != list) { for (; *list != NULL; list++) { if (NULL != (val = cfg_get_str("launch",*list)) && 2 == sscanf(val,"%15[^,], %127[^\n]", key,cmdline)) { launch = realloc(launch,sizeof(struct LAUNCH)*(nlaunch+1)); launch[nlaunch].name = strdup(*list); launch[nlaunch].key = strdup(key); launch[nlaunch].cmdline = strdup(cmdline); #ifndef NO_X11 hotkey_launch(launch+nlaunch); #endif nlaunch++; } else { fprintf(stderr,"invalid value in section [launch]: %s\n",val); } } } /* events */ event_readconfig(); if (!parse_channels) return; /* channels */ init_channel("defaults",&defaults); for (list = cfg_list_sections(); *list != NULL; list++) { if (0 == strcmp(*list,"defaults")) continue; if (0 == strcmp(*list,"global")) continue; if (0 == strcmp(*list,"launch")) continue; if (0 == strcmp(*list,"eventmap")) continue; init_channel(*list,add_channel(*list)); } /* calculate channel frequencies */ defaults.channel = lookup_channel(defaults.cname); defaults.freq = get_freq(defaults.channel) + defaults.fine; calc_frequencies(); #ifndef NO_X11 for (i = 0; i < count; i++) configure_channel(channels[i]); #endif } /* ----------------------------------------------------------------------- */ void save_config() { struct ng_attribute *attr; char filename1[100], filename2[100]; FILE *fp; int i; sprintf(filename1,"%s/%s",getenv("HOME"),".xawtv"); sprintf(filename2,"%s/%s",getenv("HOME"),".xawtv~"); /* delete old backup */ unlink(filename2); /* current becomes backup */ if (0 == link(filename1,filename2)) unlink(filename1); /* write new one... */ fp = fopen(filename1,"w"); if (NULL == fp) { fprintf(stderr,"can't open config file %s\n",filename1); return; } fprintf(fp,"[global]\n"); if (fs_width && fs_height) fprintf(fp,"fullscreen = %d x %d\n",fs_width,fs_height); if (fs_xoff || fs_yoff) fprintf(fp,"wm-off-by = %+d%+d\n",fs_xoff,fs_yoff); if (ng_ratio_x || ng_ratio_y) fprintf(fp,"ratio = %d:%d\n",ng_ratio_x,ng_ratio_y); fprintf(fp,"freqtab = %s\n",chanlists[chantab].name); fprintf(fp,"pixsize = %d x %d\n",pix_width,pix_height); fprintf(fp,"pixcols = %d\n",pix_cols); fprintf(fp,"jpeg-quality = %d\n",ng_jpeg_quality); fprintf(fp,"keypad-ntsc = %s\n",int_to_str(keypad_ntsc,booltab)); fprintf(fp,"keypad-partial = %s\n",int_to_str(keypad_partial,booltab)); fprintf(fp,"osd = %s\n",int_to_str(use_osd,booltab)); fprintf(fp,"osd-position = %d , %d\n",osd_x,osd_y); fprintf(fp,"use-wm-fullscreen = %s\n", int_to_str(use_wm_fullscreen,booltab)); if (mixer) fprintf(fp,"mixer = %s\n",mixer); if (midi) fprintf(fp,"midi = %s\n",midi); if (mov_driver) fprintf(fp,"mov-driver = %s\n",mov_driver); if (mov_video) fprintf(fp,"mov-video = %s\n",mov_video); if (mov_fps) fprintf(fp,"mov-fps = %s\n",mov_fps); if (mov_audio) fprintf(fp,"mov-audio = %s\n",mov_audio); if (mov_rate) fprintf(fp,"mov-rate = %s\n",mov_rate); fprintf(fp,"\n"); if (nlaunch > 0) { fprintf(fp,"[launch]\n"); for (i = 0; i < nlaunch; i++) { fprintf(fp,"%s = %s, %s\n", launch[i].name,launch[i].key,launch[i].cmdline); } fprintf(fp,"\n"); } /* events */ event_writeconfig(fp); /* write help */ fprintf(fp,"# [Station name]\n"); fprintf(fp,"# capture = overlay | grabdisplay | on | off\n"); fprintf(fp,"# input = Television | Composite1 | S-Video | ...\n"); fprintf(fp,"# norm = PAL | NTSC | SECAM | ... \n"); fprintf(fp,"# channel = #\n"); fprintf(fp,"# fine = # (-128..+127)\n"); fprintf(fp,"# key = keysym | modifier+keysym\n"); fprintf(fp,"# color = #\n"); fprintf(fp,"# bright = #\n"); fprintf(fp,"# hue = #\n"); fprintf(fp,"# contrast = #\n"); fprintf(fp,"\n"); /* write defaults */ fprintf(fp,"[defaults]\n"); fprintf(fp,"group = %s\n",defaults.group); fprintf(fp,"norm = %s\n", ng_attr_getstr(ng_attr_byid(attrs,ATTR_ID_NORM), cur_attrs[ATTR_ID_NORM])); fprintf(fp,"input = %s\n", ng_attr_getstr(ng_attr_byid(attrs,ATTR_ID_INPUT), cur_attrs[ATTR_ID_INPUT])); fprintf(fp,"capture = %s\n",int_to_str(cur_capture,captab)); attr = ng_attr_byid(attrs,ATTR_ID_COLOR); if (attr && attr->defval != cur_attrs[ATTR_ID_COLOR]) fprintf(fp,"color = %d%%\n", ng_attr_int2percent(attr,cur_attrs[ATTR_ID_COLOR])); attr = ng_attr_byid(attrs,ATTR_ID_BRIGHT); if (attr && attr->defval != cur_attrs[ATTR_ID_BRIGHT]) fprintf(fp,"bright = %d%%\n", ng_attr_int2percent(attr,cur_attrs[ATTR_ID_BRIGHT])); attr = ng_attr_byid(attrs,ATTR_ID_HUE); if (attr && attr->defval != cur_attrs[ATTR_ID_HUE]) fprintf(fp,"hue = %d%%\n", ng_attr_int2percent(attr,cur_attrs[ATTR_ID_HUE])); attr = ng_attr_byid(attrs,ATTR_ID_CONTRAST); if (attr && attr->defval != cur_attrs[ATTR_ID_CONTRAST]) fprintf(fp,"contrast = %d%%\n", ng_attr_int2percent(attr,cur_attrs[ATTR_ID_CONTRAST])); fprintf(fp,"\n"); /* write channels */ for (i = 0; i < count; i++) { fprintf(fp,"[%s]\n",channels[i]->name); if (NULL != channels[i]->cname) { fprintf(fp,"channel = %s\n",chanlist[channels[i]->channel].name); if (0 != channels[i]->fine) fprintf(fp,"fine = %+d\n", channels[i]->fine); } else { fprintf(fp,"freq = %.2f\n",(float)(channels[i]->freq)/16); } if ( channels[i]->norm != cur_attrs[ATTR_ID_NORM]) fprintf(fp,"norm = %s\n", ng_attr_getstr(ng_attr_byid(attrs,ATTR_ID_NORM), channels[i]->norm)); if (channels[i]->input != cur_attrs[ATTR_ID_INPUT]) fprintf(fp,"input = %s\n", ng_attr_getstr(ng_attr_byid(attrs,ATTR_ID_INPUT), channels[i]->input)); if (channels[i]->key != NULL) fprintf(fp,"key = %s\n",channels[i]->key); if (0 != strcmp(channels[i]->group,defaults.group)) fprintf(fp,"group = %s\n",channels[i]->group); if (channels[i]->midi != 0) fprintf(fp,"midi = %d\n",channels[i]->midi); if (channels[i]->capture != cur_capture) fprintf(fp,"capture = %s\n", int_to_str(channels[i]->capture,captab)); attr = ng_attr_byid(attrs,ATTR_ID_COLOR); if (attr && cur_attrs[ATTR_ID_COLOR] != channels[i]->color) fprintf(fp,"color = %d%%\n", ng_attr_int2percent(attr,channels[i]->color)); attr = ng_attr_byid(attrs,ATTR_ID_BRIGHT); if (attr && cur_attrs[ATTR_ID_BRIGHT] != channels[i]->bright) fprintf(fp,"bright = %d%%\n", ng_attr_int2percent(attr,channels[i]->bright)); attr = ng_attr_byid(attrs,ATTR_ID_HUE); if (attr && cur_attrs[ATTR_ID_HUE] != channels[i]->hue) fprintf(fp,"hue = %d%%\n", ng_attr_int2percent(attr,channels[i]->hue)); attr = ng_attr_byid(attrs,ATTR_ID_CONTRAST); if (attr && cur_attrs[ATTR_ID_CONTRAST] != channels[i]->contrast) fprintf(fp,"contrast = %d%%\n", ng_attr_int2percent(attr,channels[i]->contrast)); fprintf(fp,"\n"); } fclose(fp); } /* ----------------------------------------------------------------------- */ struct STRTAB booltab[] = { { 0, "no" }, { 0, "false" }, { 0, "off" }, { 1, "yes" }, { 1, "true" }, { 1, "on" }, { -1, NULL } }; int str_to_int(char *str, struct STRTAB *tab) { int i; if (str[0] >= '0' && str[0] <= '9') return atoi(str); for (i = 0; tab[i].str != NULL; i++) if (0 == strcasecmp(str,tab[i].str)) return(tab[i].nr); return -1; } const char* int_to_str(int n, struct STRTAB *tab) { int i; for (i = 0; tab[i].str != NULL; i++) if (tab[i].nr == n) return tab[i].str; return NULL; } xawtv-3.106/common/channel.h000066400000000000000000000042211343350355000157450ustar00rootroot00000000000000#ifndef X_DISPLAY_MISSING # include # include #endif #define CAPTURE_OFF 0 #define CAPTURE_OVERLAY 1 #define CAPTURE_GRABDISPLAY 2 #define CAPTURE_ON 9 struct CHANNEL { char *name; char *key; char *group; int midi; char *cname; /* name of the channel */ int channel; /* index into tvtuner[] */ int fine; int freq; int audio; int capture; int input; int norm; int color; int bright; int hue; int contrast; #ifndef X_DISPLAY_MISSING /* FIXME */ Pixmap pixmap; Widget button; #endif }; extern struct CHANNEL defaults; extern struct CHANNEL **channels; extern int count; extern int have_config; extern int jpeg_quality; extern int keypad_ntsc; extern int keypad_partial; extern int use_osd; extern int osd_x, osd_y; extern int use_wm_fullscreen; extern int fs_width,fs_height,fs_xoff,fs_yoff; extern int pix_width,pix_height,pix_cols; extern int last_sender, cur_sender; extern int cur_channel, cur_fine; extern int cur_capture, cur_freq; extern struct ng_filter *cur_filter; extern char *mov_driver; extern char *mov_video; extern char *mov_fps; extern char *mov_audio; extern char *mov_rate; extern char mixerdev[32],mixerctl[16]; extern char *midi; int lookup_channel(char *channel); int get_freq(int i); int cf2freq(char *name, int fine); struct CHANNEL* add_channel(char *name); void hotkey_channel(struct CHANNEL *channel); void configure_channel(struct CHANNEL *channel); void del_channel(int nr); void calc_frequencies(void); void read_config(char *conffile, int *argc, char **argv); void parse_config(int parse_channels); void save_config(void); /* ----------------------------------------------------------------------- */ struct LAUNCH { char *name; char *key; char *cmdline; }; extern struct LAUNCH *launch; extern int nlaunch; /* ----------------------------------------------------------------------- */ extern struct STRTAB booltab[]; extern struct STRTAB captab[]; int str_to_int(char *str, struct STRTAB *tab); const char* int_to_str(int n, struct STRTAB *tab); xawtv-3.106/common/commands.c000066400000000000000000001063331343350355000161400ustar00rootroot00000000000000#define _GNU_SOURCE #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "grab-ng.h" #include "capture.h" #include "commands.h" #include "writefile.h" #include "channel.h" #include "webcam.h" #include "frequencies.h" #include "sound.h" /* ----------------------------------------------------------------------- */ /* feedback for the user */ void (*update_title)(char *message); void (*display_message)(char *message); void (*rec_status)(char *message); #if TT void (*vtx_message)(struct TEXTELEM *tt); #endif #ifdef HAVE_ZVBI void (*vtx_subtitle)(struct vbi_page *pg, struct vbi_rect *rect); #endif /* for updating GUI elements / whatever */ void (*attr_notify)(struct ng_attribute *attr, int val); void (*mute_notify)(int val); void (*volume_notify)(void); void (*freqtab_notify)(void); void (*setfreqtab_notify)(void); void (*setstation_notify)(void); /* gets called _before_ channel switches */ void (*channel_switch_hook)(void); /* capture overlay/grab/off */ void (*set_capture_hook)(int old, int new, int tmp_switch); /* toggle fullscreen */ void (*fullscreen_hook)(void); void (*exit_hook)(void); void (*capture_get_hook)(void); void (*capture_rel_hook)(void); void (*movie_hook)(int argc, char **argv); int debug; int do_overlay; char *snapbase = "snap"; int have_shmem; unsigned int cur_tv_width,cur_tv_height; int cur_movie,cur_attrs[256]; /* current hardware driver */ const struct ng_vid_driver *drv; void *h_drv; int f_drv; struct ng_attribute *attrs = NULL; /* ----------------------------------------------------------------------- */ static int setfreqtab_handler(char *name, int argc, char **argv); static int setstation_handler(char *name, int argc, char **argv); static int setchannel_handler(char *name, int argc, char **argv); static int capture_handler(char *name, int argc, char **argv); static int volume_handler(char *name, int argc, char **argv); static int attr_handler(char *name, int argc, char **argv); static int show_handler(char *name, int argc, char **argv); static int list_handler(char *name, int argc, char **argv); static int dattr_handler(char *name, int argc, char **argv); static int snap_handler(char *name, int argc, char **argv); static int webcam_handler(char *name, int argc, char **argv); static int movie_handler(char *name, int argc, char **argv); static int fullscreen_handler(char *name, int argc, char **argv); static int msg_handler(char *name, int argc, char **argv); static int showtime_handler(char *name, int argc, char **argv); static int vdr_handler(char *name, int argc, char **argv); #if TT static int vtx_handler(char *name, int argc, char **argv); #endif static int exit_handler(char *name, int argc, char **argv); static int keypad_handler(char *name, int argc, char **argv); static struct COMMANDS { char *name; int min_args; int (*handler)(char *name, int argc, char **argv); } commands[] = { { "setstation", 0, setstation_handler }, { "setchannel", 0, setchannel_handler }, { "setfreq", 1, setchannel_handler }, { "setfreqtab", 1, setfreqtab_handler }, { "capture", 1, capture_handler }, { "setnorm", 1, attr_handler }, { "setinput", 1, attr_handler }, { "setattr", 1, attr_handler }, { "color", 0, attr_handler }, { "hue", 0, attr_handler }, { "bright", 0, attr_handler }, { "contrast", 0, attr_handler }, { "show", 0, show_handler }, { "list", 0, list_handler }, { "volume", 0, volume_handler }, { "attr", 0, dattr_handler }, { "snap", 0, snap_handler }, { "webcam", 1, webcam_handler }, { "movie", 1, movie_handler }, { "fullscreen", 0, fullscreen_handler }, { "msg", 1, msg_handler }, #if 0 { "vtx", 0, vtx_handler }, #endif { "message", 0, msg_handler }, { "exit", 0, exit_handler }, { "quit", 0, exit_handler }, { "bye", 0, exit_handler }, { "keypad", 1, keypad_handler }, { "showtime", 0, showtime_handler }, { "vdr", 1, vdr_handler }, { NULL, 0, NULL } }; static int cur_dattr = 0; static int dattr[] = { ATTR_ID_VOLUME, ATTR_ID_BRIGHT, ATTR_ID_CONTRAST, ATTR_ID_COLOR, ATTR_ID_HUE }; #define NUM_DATTR (sizeof(dattr)/sizeof(char*)) static int keypad_state = -1; /* ----------------------------------------------------------------------- */ void add_attrs(struct ng_attribute *new) { struct ng_attribute *all; int nold,nnew; if (attrs) for (nold = 0; attrs[nold].name != NULL; nold++) ; else nold = 0; for (nnew = 0; new[nnew].name != NULL; nnew++) ; all = malloc(sizeof(struct ng_attribute) * (nold + nnew + 1)); memset(all,0,sizeof(struct ng_attribute) * (nold + nnew + 1)); memcpy(all,new,sizeof(struct ng_attribute)*nnew); if (attrs) { memcpy(all+nnew,attrs,sizeof(struct ng_attribute)*nold); free(attrs); } attrs = all; #if 0 { int i; fprintf(stderr," \n"); for (i = 0; attrs[i].name != NULL; i++) { fprintf(stderr," attr[%p]: %s \n", attrs[i].handle,attrs[i].name); } fprintf(stderr," \n"); } #endif } void init_overlay(void) { do_va_cmd(2,"setfreqtab",(-1 != chantab) ? chanlist_names[chantab].str : "europe-west"); cur_capture = -1; switch (defaults.capture) { case CAPTURE_ON: case CAPTURE_OVERLAY: do_va_cmd(2,"capture","overlay"); break; case CAPTURE_GRABDISPLAY: do_va_cmd(2,"capture","grabdisplay"); break; default: do_va_cmd(2,"capture","off"); break; } } /* ----------------------------------------------------------------------- */ int do_va_cmd(int argc, ...) { va_list ap; int i; char *argv[32]; va_start(ap,argc); for (i = 0; i < argc; i++) argv[i] = va_arg(ap,char*); argv[i] = NULL; va_end (ap); return do_command(argc,argv); } int do_command(int argc, char **argv) { int i; if (argc == 0) { fprintf(stderr,"do_command: no argument\n"); return -1; } if (debug) { fprintf(stderr,"cmd:"); for (i = 0; i < argc; i++) { fprintf(stderr," \"%s\"",argv[i]); } fprintf(stderr,"\n"); } for (i = 0; commands[i].name != NULL; i++) if (0 == strcasecmp(commands[i].name,argv[0])) break; if (commands[i].name == NULL) { fprintf(stderr,"no handler for %s\n",argv[0]); return -1; } if (argc-1 < commands[i].min_args) { fprintf(stderr,"no enough args for %s\n",argv[0]); return -1; } else { return commands[i].handler(argv[0],argc-1,argv+1); } } char** split_cmdline(char *line, int *count) { static char cmdline[1024]; static char *argv[32]; int argc,i; strcpy(cmdline,line); for (argc=0, i=0; argc<31;) { argv[argc++] = cmdline+i; while (cmdline[i] != ' ' && cmdline[i] != '\t' && cmdline[i] != '\0') i++; if (cmdline[i] == '\0') break; cmdline[i++] = '\0'; while (cmdline[i] == ' ' || cmdline[i] == '\t') i++; if (cmdline[i] == '\0') break; } argv[argc] = NULL; *count = argc; return argv; } /* ----------------------------------------------------------------------- */ /* sharing code does'nt work well for this one ... */ static void set_capture(int capture, int tmp_switch) { static int last_on = CAPTURE_OVERLAY; if (set_capture_hook) { if (capture == CAPTURE_ON) capture = last_on; if (capture == CAPTURE_OVERLAY) { /* can we do overlay ?? */ if (!(f_drv & CAN_OVERLAY)) capture = CAPTURE_GRABDISPLAY; if (!do_overlay) capture = CAPTURE_GRABDISPLAY; } if (cur_capture != capture) { set_capture_hook(cur_capture,capture,tmp_switch); cur_capture = capture; } if (cur_capture != CAPTURE_OFF) last_on = cur_capture; } } static void set_attr(struct ng_attribute *attr, int val) { if (NULL == attr) return; attr->write(attr,val); cur_attrs[attr->id] = val; if (attr_notify) attr_notify(attr,val); } static void set_volume(int val) { struct ng_attribute *attr; cur_attrs[ATTR_ID_VOLUME] = val; if ((attr = ng_attr_byid(attrs, ATTR_ID_VOLUME)) != NULL) attr->write(attr, val); } static void set_mute(int val) { struct ng_attribute *attr; cur_attrs[ATTR_ID_MUTE] = val; if ((attr = ng_attr_byid(attrs, ATTR_ID_MUTE)) != NULL) attr->write(attr, val); if (mute_notify) mute_notify(val); } static void set_freqtab(int j) { if (!(f_drv & CAN_TUNE)) return; freq_newtab(j); /* cur_channel might be invalid (>chancount) right now */ cur_channel = -1; /* this is valid for (struct CHANNEL*)->channel too */ calc_frequencies(); if (freqtab_notify) freqtab_notify(); } static void set_title(void) { static char title[256]; const char *norm; keypad_state = -1; if (update_title) { if (-1 != cur_sender) { sprintf(title,"%s",channels[cur_sender]->name); } else if (-1 != cur_channel) { sprintf(title,"channel %s",chanlist[cur_channel].name); if (cur_fine != 0) sprintf(title+strlen(title)," (%d)",cur_fine); norm = ng_attr_getstr(ng_attr_byid(attrs,ATTR_ID_NORM), cur_attrs[ATTR_ID_NORM]); sprintf(title+strlen(title)," (%s/%s)", norm ? norm : "???", chanlists[chantab].name); } else { sprintf(title,"%.3f MHz",cur_freq/16.0); } update_title(title); } } static void set_msg_int(struct ng_attribute *attr, int val) { static char title[256]; if (display_message) { sprintf(title,"%s: %d%%",attr->name, ng_attr_int2percent(attr,val)); display_message(title); } } static void set_msg_bool(const char *name, int val) { static char title[256]; if (display_message) { sprintf(title,"%s: %s",name, val ? "on" : "off"); display_message(title); } } static void set_msg_str(const char *name, const char *val) { static char title[256]; if (display_message) { sprintf(title,"%s: %s",name,val); display_message(title); } } /* ----------------------------------------------------------------------- */ static int update_int(struct ng_attribute *attr, int old, char *new) { int value = old; int step; step = (attr->max - attr->min) * 3 / 100; if (step == 0) step = 1; if (0 == strcasecmp(new,"inc")) value += step; else if (0 == strcasecmp(new,"dec")) value -= step; else if (0 == strncasecmp(new,"+=",2)) value += ng_attr_parse_int(attr,new+2); else if (0 == strncasecmp(new,"-=",2)) value -= ng_attr_parse_int(attr,new+2); else if (isdigit(new[0]) || '+' == new[0] || '-' == new[0]) value = ng_attr_parse_int(attr,new); else fprintf(stderr,"update_int: can't parse %s\n",new); if (value < attr->min) value = attr->min; if (value > attr->max) value = attr->max; return value; } /* ----------------------------------------------------------------------- */ void attr_init(void) { struct ng_attribute *attr; int val; for (attr = attrs; attr != NULL && attr->name != NULL; attr++) { if (attr->id == ATTR_ID_VOLUME || attr->id == ATTR_ID_MUTE) continue; val = attr->read(attr); if (attr_notify) attr_notify(attr,val); cur_attrs[attr->id] = val; } if (-1 == defaults.color && NULL != ng_attr_byid(attrs,ATTR_ID_COLOR)) defaults.color = cur_attrs[ATTR_ID_COLOR]; if (-1 == defaults.bright && NULL != ng_attr_byid(attrs,ATTR_ID_BRIGHT)) defaults.bright = cur_attrs[ATTR_ID_BRIGHT]; if (-1 == defaults.hue && NULL != ng_attr_byid(attrs,ATTR_ID_HUE)) defaults.hue = cur_attrs[ATTR_ID_HUE]; if (-1 == defaults.contrast && NULL != ng_attr_byid(attrs,ATTR_ID_CONTRAST)) defaults.contrast = cur_attrs[ATTR_ID_CONTRAST]; } void audio_init(void) { struct ng_attribute *attr; if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_VOLUME))) cur_attrs[ATTR_ID_VOLUME] = attr->read(attr); if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_MUTE))) cur_attrs[ATTR_ID_MUTE] = attr->read(attr); if (volume_notify) volume_notify(); } void audio_on(void) { set_mute(0); } void audio_off(void) { set_mute(1); } void set_defaults(void) { struct ng_attribute *attr; /* image parameters */ if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_COLOR))) set_attr(attr,defaults.color); if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_BRIGHT))) set_attr(attr,defaults.bright); if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_HUE))) set_attr(attr,defaults.hue); if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_CONTRAST))) set_attr(attr,defaults.contrast); if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_INPUT))) set_attr(attr,defaults.input); if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_NORM))) set_attr(attr,defaults.norm); set_capture(defaults.capture,0); cur_channel = defaults.channel; cur_fine = defaults.fine; cur_freq = defaults.freq; if (f_drv & CAN_TUNE) drv->setfreq(h_drv,defaults.freq); } /* ----------------------------------------------------------------------- */ #ifndef HAVE_STRCASESTR static char* strcasestr(char *haystack, char *needle) { int hlen = strlen(haystack); int nlen = strlen(needle); int offset; for (offset = 0; offset <= hlen - nlen; offset++) if (0 == strncasecmp(haystack+offset,needle,nlen)) return haystack+offset; return NULL; } #endif static int setstation_handler(char *name, int argc, char **argv) { struct ng_attribute *attr; int i, orig_mute; if (!(f_drv & CAN_TUNE)) return 0; if (0 == argc) { set_title(); return 0; } if (cur_movie) { if (display_message) display_message("grabber busy"); return -1; } if (count && 0 == strcasecmp(argv[0],"next")) { i = (cur_sender+1) % count; } else if (count && 0 == strcasecmp(argv[0],"prev")) { i = (cur_sender+count-1) % count; } else if (count && 0 == strcasecmp(argv[0],"back")) { if (-1 == last_sender) return -1; i = last_sender; } else { /* search the configured channels first... */ for (i = 0; i < count; i++) if (0 == strcasecmp(channels[i]->name,argv[0])) break; /* ... next try substring matches ... */ if (i == count) for (i = 0; i < count; i++) if (NULL != strcasestr(channels[i]->name,argv[0])) break; /* ... next try using the argument as index ... */ if (i == count) if (isdigit(argv[0][0])) i = atoi(argv[0]); if (i == count) { /* ... sorry folks */ fprintf(stderr,"station \"%s\" not found\n",argv[0]); return -1; } } /* ok ?? */ if (i < 0 || i >= count) return -1; /* switch ... */ if (channel_switch_hook) channel_switch_hook(); set_capture(CAPTURE_OFF,1); orig_mute = cur_attrs[ATTR_ID_MUTE]; if (!orig_mute) set_mute(1); last_sender = cur_sender; cur_sender = i; /* image parameters */ if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_COLOR))) set_attr(attr,channels[i]->color); if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_BRIGHT))) set_attr(attr,channels[i]->bright); if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_HUE))) set_attr(attr,channels[i]->hue); if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_CONTRAST))) set_attr(attr,channels[i]->contrast); /* input / norm */ if (cur_attrs[ATTR_ID_INPUT] != channels[i]->input) if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_INPUT))) set_attr(attr,channels[i]->input); if (cur_attrs[ATTR_ID_NORM] != channels[i]->norm) if (NULL != (attr = ng_attr_byid(attrs,ATTR_ID_NORM))) set_attr(attr,channels[i]->norm); /* station */ cur_channel = channels[i]->channel; cur_fine = channels[i]->fine; cur_freq = channels[i]->freq; if (f_drv & CAN_TUNE) drv->setfreq(h_drv,channels[i]->freq); set_capture(channels[i]->capture,0); set_title(); if (setstation_notify) setstation_notify(); if (!orig_mute) { usleep(20000); set_mute(0); } return 0; } static int setchannel_handler(char *name, int argc, char **argv) { int i, c, orig_mute; if (!(f_drv & CAN_TUNE)) return 0; if (0 == argc) { set_title(); return 0; } if (cur_movie) { if (display_message) display_message("grabber busy"); return -1; } if (0 == strcasecmp("setfreq",name)) { cur_freq = (unsigned long)(atof(argv[0])*16); cur_sender = -1; cur_channel = -1; cur_fine = 0; } else { if (0 == strcasecmp(argv[0],"next")) { cur_channel = (cur_channel+1) % chancount; cur_fine = defaults.fine; } else if (0 == strcasecmp(argv[0],"prev")) { cur_channel = (cur_channel+chancount-1) % chancount; cur_fine = defaults.fine; } else if (0 == strcasecmp(argv[0],"fine_up")) { cur_fine++; } else if (0 == strcasecmp(argv[0],"fine_down")) { cur_fine--; } else { if (-1 != (c = lookup_channel(argv[0]))) { cur_channel = c; cur_fine = defaults.fine; } } if (0 != strncmp(argv[0],"fine",4)) { /* look if there is a known station on that channel */ for (i = 0; i < count; i++) { if (cur_channel == channels[i]->channel) { char *argv[2]; argv[0] = channels[i]->name; argv[1] = NULL; return setstation_handler("", argc, argv); } } } cur_sender = -1; if (-1 != cur_channel) cur_freq = get_freq(cur_channel)+cur_fine; else { cur_freq += cur_fine; cur_fine = 0; } } if (channel_switch_hook) channel_switch_hook(); set_capture(CAPTURE_OFF,1); orig_mute = cur_attrs[ATTR_ID_MUTE]; if (!orig_mute) set_mute(1); if (f_drv & CAN_TUNE) drv->setfreq(h_drv,cur_freq); set_capture(defaults.capture,0); set_title(); if (setstation_notify) setstation_notify(); if (!orig_mute) { usleep(20000); set_mute(0); } return 0; } /* ----------------------------------------------------------------------- */ static void print_choices(char *name, char *value, struct STRTAB *tab) { int i; fprintf(stderr,"unknown %s: '%s' (available: ",name,value); for (i = 0; tab[i].str != NULL; i++) fprintf(stderr,"%s'%s'", (0 == i) ? "" : ", ", tab[i].str); fprintf(stderr,")\n"); } static int setfreqtab_handler(char *name, int argc, char **argv) { int i; if (!(f_drv & CAN_TUNE)) return 0; i = str_to_int(argv[0],chanlist_names); if (i != -1) set_freqtab(i); else print_choices("freqtab",argv[0],chanlist_names); return 0; } static int capture_handler(char *name, int argc, char **argv) { int i, temp = 0; if (0 == strcasecmp(argv[0],"toggle")) { i = (cur_capture == CAPTURE_OFF) ? CAPTURE_ON : CAPTURE_OFF; } else { i = str_to_int(argv[0],captab); } if (argc == 2 && !strcasecmp(argv[1], "temp")) temp = 1; if (i != -1) set_capture(i, temp); return 0; } /* ----------------------------------------------------------------------- */ static int volume_handler(char *name, int argc, char **argv) { struct ng_attribute *vol = ng_attr_byid(attrs,ATTR_ID_VOLUME); if (0 == argc) goto display; if (0 == strcasecmp(argv[0],"mute")) { /* mute on/off/toggle */ if (argc > 1) { switch (str_to_int(argv[1],booltab)) { case 0: set_mute(0); break; case 1: set_mute(1); break; default: set_mute(!cur_attrs[ATTR_ID_MUTE]); } } else { set_mute(!cur_attrs[ATTR_ID_MUTE]); } } else if (vol) { /* volume */ set_volume(update_int(vol, vol->read(vol), argv[0])); } if (volume_notify) volume_notify(); display: if (cur_attrs[ATTR_ID_MUTE]) set_msg_str("volume","muted"); else { if (vol) set_msg_int(vol,cur_attrs[ATTR_ID_VOLUME]); else set_msg_str("volume","unmuted"); } return 0; } static int attr_handler(char *name, int argc, char **argv) { struct ng_attribute *attr; int val,arg=0; if (0 == strcasecmp(name,"setnorm")) { attr = ng_attr_byname(attrs,"norm"); } else if (0 == strcasecmp(name,"setinput")) { attr = ng_attr_byname(attrs,"input"); } else if (0 == strcasecmp(name,"setattr") && argc > 0) { attr = ng_attr_byname(attrs,argv[arg++]); } else { attr = ng_attr_byname(attrs,name); } if (NULL == attr) { fprintf(stderr,"cmd: %s: attribute not found\nvalid choices are:", (arg > 0) ? argv[0] : name); for (attr = attrs; attr->name != NULL; attr++) fprintf(stderr,"%s \"%s\"", (attr != attrs) ? "," : "", attr->name); fprintf(stderr,"\n"); return -1; } if (!cur_movie && capture_get_hook) capture_get_hook(); switch (attr->type) { case ATTR_TYPE_CHOICE: if (argc > arg) { if (0 == strcasecmp("next", argv[arg])) { val = cur_attrs[attr->id]; val++; if (NULL == attr->choices[val].str) val = 0; } else { val = ng_attr_getint(attr, argv[arg]); } if (-1 == val) { fprintf(stderr,"invalid value for %s: %s\n",attr->name,argv[arg]); ng_attr_listchoices(attr); } else { set_attr(attr,val); set_msg_str(attr->name,attr->choices[val].str); } } break; case ATTR_TYPE_INTEGER: if (argc > arg) { cur_attrs[attr->id] = attr->read(attr); val = update_int(attr,cur_attrs[attr->id],argv[arg]); set_attr(attr,val); } set_msg_int(attr,cur_attrs[attr->id]); break; case ATTR_TYPE_BOOL: if (argc > arg) { val = str_to_int(argv[arg],booltab); if (-1 == val) { if (0 == strcasecmp(argv[arg],"toggle")) val = !cur_attrs[attr->id]; } set_attr(attr,val); } set_msg_bool(attr->name,cur_attrs[attr->id]); break; } if (!cur_movie && capture_rel_hook) capture_rel_hook(); return 0; } static int show_handler(char *name, int argc, char **argv) { struct ng_attribute *attr; char *n[2] = { NULL, NULL }; int val; if (0 == argc) { for (attr = attrs; attr->name != NULL; attr++) { n[0] = (char*)attr->name; show_handler("show", 1, n); } return 0; } attr = ng_attr_byname(attrs,argv[0]); if (NULL == attr) { fprintf(stderr,"fixme: 404 %s\n",argv[0]); return 0; } val = cur_attrs[attr->id]; switch (attr->type) { case ATTR_TYPE_CHOICE: printf("%s: %s\n", attr->name, ng_attr_getstr(attr,val)); break; case ATTR_TYPE_INTEGER: printf("%s: %d\n", attr->name, val); break; case ATTR_TYPE_BOOL: printf("%s: %s\n", attr->name, val ? "on" : "off"); break; } return 0; } static int list_handler(char *name, int argc, char **argv) { struct ng_attribute *attr; int val,i; printf("%-10.10s | type | %-7.7s | %-7.7s | %s\n", "attribute","current","default","comment"); printf("-----------+--------+---------+--------" "-+-------------------------------------\n"); for (attr = attrs; attr->name != NULL; attr++) { val = cur_attrs[attr->id]; switch (attr->type) { case ATTR_TYPE_CHOICE: printf("%-10.10s | choice | %-7.7s | %-7.7s |", attr->name, ng_attr_getstr(attr,val), ng_attr_getstr(attr,attr->defval)); for (i = 0; attr->choices[i].str != NULL; i++) printf(" %s",attr->choices[i].str); printf("\n"); break; case ATTR_TYPE_INTEGER: printf("%-10.10s | int | %7d | %7d | range is %d => %d\n", attr->name, val, attr->defval, attr->min, attr->max); break; case ATTR_TYPE_BOOL: printf("%-10.10s | bool | %-7.7s | %-7.7s |\n", attr->name, val ? "on" : "off", attr->defval ? "on" : "off"); break; } } return 0; } static int dattr_handler(char *name, int argc, char **argv) { struct ng_attribute *attr = NULL; unsigned int i; if (argc > 0 && 0 == strcasecmp(argv[0],"next")) { for (i = 0; i < NUM_DATTR; i++) { cur_dattr++; cur_dattr %= NUM_DATTR; attr = ng_attr_byid(attrs,dattr[cur_dattr]); if (NULL != attr) break; } if (NULL == attr) return 0; argc = 0; } if (NULL == attr) attr = ng_attr_byid(attrs,dattr[cur_dattr]); if (NULL == attr) return 0; return attr_handler((char*)attr->name,argc,argv); } /* ----------------------------------------------------------------------- */ static int snap_handler(char *hname, int argc, char **argv) { char message[512]; char *tmpfilename = NULL; char *filename = NULL; char *name; int jpeg = 0; int ret = 0; struct ng_video_fmt fmt; struct ng_video_buf *buf = NULL; if (!(f_drv & CAN_CAPTURE)) { fprintf(stderr,"grabbing: not supported [try -noxv switch?]\n"); return -1; } if (cur_movie) { if (display_message) display_message("grabber busy"); return -1; } if (capture_get_hook) capture_get_hook(); /* format */ if (argc > 0) { if (0 == strcasecmp(argv[0],"jpeg")) jpeg = 1; if (0 == strcasecmp(argv[0],"ppm")) jpeg = 0; } /* size */ memset(&fmt,0,sizeof(fmt)); fmt.fmtid = VIDEO_RGB24; fmt.width = 2048; fmt.height = 1572; if (argc > 1) { if (0 == strcasecmp(argv[1],"full")) { /* nothing */ } else if (0 == strcasecmp(argv[1],"win")) { fmt.width = cur_tv_width; fmt.height = cur_tv_height; } else if (2 == sscanf(argv[1],"%dx%d",&fmt.width,&fmt.height)) { /* nothing */ } else { return -1; } } /* filename */ if (argc > 2) filename = argv[2]; if (NULL == (buf = ng_grabber_get_image(&fmt))) { if (display_message) display_message("grabbing failed"); ret = -1; goto done; } buf = ng_filter_single(cur_filter,buf); if (NULL == filename) { if (-1 != cur_sender) { name = channels[cur_sender]->name; } else if (-1 != cur_channel) { name = chanlist[cur_channel].name; } else { name = "unknown"; } filename = snap_filename(snapbase, name, jpeg ? "jpeg" : "ppm"); } tmpfilename = malloc(strlen(filename)+8); sprintf(tmpfilename,"%s.$$$",filename); if (jpeg) { if (-1 == write_jpeg(tmpfilename, buf, ng_jpeg_quality, 0)) { sprintf(message,"open %s: %s\n",tmpfilename,strerror(errno)); } else { sprintf(message,"saved jpeg: %s",filename); } } else { if (-1 == write_ppm(tmpfilename, buf)) { sprintf(message,"open %s: %s\n",tmpfilename,strerror(errno)); } else { sprintf(message,"saved ppm: %s",filename); } } unlink(filename); if (-1 == link(tmpfilename,filename)) { fprintf(stderr,"link(%s,%s): %s\n", tmpfilename,filename,strerror(errno)); goto done; } unlink(tmpfilename); if (display_message) display_message(message); done: if (tmpfilename) free(tmpfilename); if (NULL != buf) ng_release_video_buf(buf); if (capture_rel_hook) capture_rel_hook(); return ret; } static int webcam_handler(char *hname, int argc, char **argv) { struct ng_video_fmt fmt; struct ng_video_buf *buf; if (webcam) free(webcam); webcam = strdup(argv[0]); /* if either avi recording or grabdisplay is active, we do /not/ stop capture and switch the video format. The next capture will send a copy of the frame to the webcam thread and it has to deal with it as-is */ if (cur_movie) return 0; if (cur_capture == CAPTURE_GRABDISPLAY) return 0; /* if no capture is running we can switch to RGB first to make the webcam happy */ if (capture_get_hook) capture_get_hook(); memset(&fmt,0,sizeof(fmt)); fmt.fmtid = VIDEO_RGB24; fmt.width = cur_tv_width; fmt.height = cur_tv_height; buf = ng_grabber_get_image(&fmt); if (buf) ng_release_video_buf(buf); if (capture_rel_hook) capture_rel_hook(); return 0; } static int movie_handler(char *name, int argc, char **argv) { if (!movie_hook) return 0; movie_hook(argc,argv); return 0; } static int fullscreen_handler(char *name, int argc, char **argv) { if (fullscreen_hook) fullscreen_hook(); return 0; } static int msg_handler(char *name, int argc, char **argv) { if (display_message) display_message(argv[0]); return 0; } static int showtime_handler(char *name, int argc, char **argv) { char timestr[6]; struct tm *times; time_t timet; timet = time(NULL); times = localtime(&timet); strftime(timestr, 6, "%k:%M", times); if (display_message) display_message(timestr); return 0; } static int exit_handler(char *name, int argc, char **argv) { if (exit_hook) exit_hook(); return 0; } /* ----------------------------------------------------------------------- */ static char *strfamily(int family) { switch (family) { case PF_INET6: return "ipv6"; case PF_INET: return "ipv4"; case PF_UNIX: return "unix"; } return "????"; } static int tcp_connect(struct addrinfo *ai, char *host, char *serv) { struct addrinfo *res,*e; char uhost[INET6_ADDRSTRLEN+1]; char userv[33]; int sock,rc,opt=1; ai->ai_flags = AI_CANONNAME; if (debug) fprintf(stderr,"tcp: lookup %s:%s ... ",host,serv); if (0 != (rc = getaddrinfo(host, serv, ai, &res))) { fprintf(stderr,"tcp: getaddrinfo (%s:%s): %s\n", host,serv,gai_strerror(rc)); return -1; } if (debug) fprintf(stderr,"ok\n"); for (e = res; e != NULL; e = e->ai_next) { if (0 != getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen, uhost,INET6_ADDRSTRLEN,userv,32, NI_NUMERICHOST | NI_NUMERICSERV)) { fprintf(stderr,"tcp: getnameinfo (peer): oops\n"); continue; } if (debug) fprintf(stderr,"tcp: trying %s (%s:%s) ... ", strfamily(e->ai_family),uhost,userv); if (-1 == (sock = socket(e->ai_family, e->ai_socktype, e->ai_protocol))) { fprintf(stderr,"tcp: socket: %s\n",strerror(errno)); continue; } setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); if (-1 == connect(sock,e->ai_addr,e->ai_addrlen)) { fprintf(stderr,"tcp: connect: %s\n",strerror(errno)); close(sock); continue; } if (debug) fprintf(stderr,"ok\n"); fcntl(sock,F_SETFL,O_NONBLOCK); fcntl(sock,F_SETFD,FD_CLOEXEC); return sock; } return -1; } static int tcp_readbuf(int sock, int timeout, char *dest, char dlen) { struct timeval tv; fd_set set; int rc; again: FD_ZERO(&set); FD_SET(sock,&set); tv.tv_sec = timeout; tv.tv_usec = 0; rc = select(sock+1,&set,NULL,NULL,&tv); if (-1 == rc && EINTR == errno) goto again; if (-1 == rc) { if (debug) perror("tcp: select"); return -1; } if (0 == rc) { if (debug) fprintf(stderr,"tcp: select timeout\n"); return -1; } rc = read(sock,dest,dlen-1); if (-1 == rc) { if (debug) perror("tcp: read"); return -1; } dest[rc] = 0; return rc; } static int vdr_sock = -1; static int vdr_handler(char *name, int argc, char **argv) { char line[80]; struct addrinfo ask; int i,rc; unsigned int l,len; reconnect: if (-1 == vdr_sock) { memset(&ask,0,sizeof(ask)); ask.ai_family = PF_UNSPEC; ask.ai_socktype = SOCK_STREAM; vdr_sock = tcp_connect(&ask,"localhost","2001"); if (-1 == vdr_sock) return -1; if (debug) fprintf(stderr,"vdr: connected\n"); /* skip greeting line */ if (-1 == tcp_readbuf(vdr_sock,3,line,sizeof(line))) goto oops; if (debug) fprintf(stderr,"vdr: << %s",line); } /* send command */ line[0] = 0; for (i = 0, len = 0; i < argc; i++) { l = strlen(argv[i]); if (len+l+4 > sizeof(line)) break; if (len) { strcpy(line+len," "); len++; } strcpy(line+len,argv[i]); len += l; } strcpy(line+len,"\r\n"); len += 2; if (len != (rc = write(vdr_sock,line,len))) { if (-1 == rc && EPIPE == errno) { if (debug) fprintf(stderr,"tcp: write: broken pipe, trying reconnect\n"); close(vdr_sock); vdr_sock = -1; goto reconnect; } if (debug) perror("tcp: write"); goto oops; } if (debug) fprintf(stderr,"vdr: >> %s",line); /* skip answer */ if (-1 == tcp_readbuf(vdr_sock,3,line,sizeof(line))) goto oops; if (debug) fprintf(stderr,"vdr: << %s",line); #if 0 /* play nicely and close the handle -- vdr can handle only one * connection at the same time. Drawback is that it increases * latencies ... */ close(vdr_sock); vdr_sock = -1; #endif return 0; oops: close(vdr_sock); vdr_sock = -1; return -1; } /* ----------------------------------------------------------------------- */ #if TT static struct TEXTELEM* parse_vtx(int lines, char **text) { static char *names[8] = { "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white" }; static struct TEXTELEM tt[VTX_COUNT]; int i,n,t,ansi; char *ansi_fg,*ansi_bg; /* parse */ t = 0; memset(tt,0,sizeof(tt)); for (i = 0; i < lines; i++) { tt[t].line = i; ansi_fg = NULL; ansi_bg = NULL; for (n = 0; text[i][n] != 0;) { if (text[i][n] == '\033') { if (tt[t].len) { t++; if (VTX_COUNT == t) return tt; } n++; if (text[i][n] == '[') { /* ANSI color tty sequences */ n++; for (ansi=1;ansi;) { switch (text[i][n]) { case '3': n++; if (text[i][n] >= '0' && text[i][n] < '8') { ansi_fg = names[text[i][n]-'0']; n++; } break; case '4': n++; if (text[i][n] >= '0' && text[i][n] < '8') { ansi_bg = names[text[i][n]-'0']; n++; } break; case '1': case ';': n++; break; case 'm': n++; /* ok, commit */ ansi=0; tt[t].fg = ansi_fg; tt[t].bg = ansi_bg; break; default: /* error */ ansi=0; } } } else { /* old way: ESC fg bg */ if (text[i][n] >= '0' && text[i][n] < '8') { tt[t].fg = names[text[i][n]-'0']; n++; } if (text[i][n] >= '0' && text[i][n] < '8') { tt[t].bg = names[text[i][n]-'0']; n++; } } tt[t].line = i; } else { tt[t].str[tt[t].len++] = text[i][n]; n++; if (tt[t].len >= VTX_LEN-1) { t++; if (VTX_COUNT == t) return tt; tt[t].line = i; } } } if (tt[t].len) { t++; if (VTX_COUNT == t) break; } } return tt; } static int vtx_handler(char *name, int argc, char **argv) { struct TEXTELEM *tt; if (vtx_message) { if (argc) { tt = parse_vtx(argc,argv); vtx_message(tt); } else { vtx_message(NULL); } } return 0; } #endif /* ----------------------------------------------------------------------- */ #define CH_MAX (keypad_ntsc ? 99 : count) static int keypad_handler(char *name, int argc, char **argv) { int n = atoi(argv[0])%10; char msg[8],ch[8]; if (debug) fprintf(stderr,"keypad: key %d\n",n); if (-1 == keypad_state) { if ((keypad_partial && n > 0 && n <= CH_MAX) || (!keypad_partial && n > 0 && n <= CH_MAX && 10*n > CH_MAX)) { if (keypad_ntsc) { sprintf(ch,"%d",n); do_va_cmd(2,"setchannel",ch,NULL); } else do_va_cmd(2,"setstation",channels[n-1]->name,NULL); } if (n >= 0 && 10*n <= CH_MAX) { if (debug) fprintf(stderr,"keypad: hang: %d\n",n); keypad_state = n; if (display_message) { sprintf(msg,"%d_",n); display_message(msg); } } } else { if ((n+keypad_state*10) <= CH_MAX) n += keypad_state*10; keypad_state = -1; if (debug) fprintf(stderr,"keypad: ok: %d\n",n); if (n > 0 && n <= CH_MAX) { if (keypad_ntsc) { sprintf(ch,"%d",n); do_va_cmd(2,"setchannel",ch,NULL); } else do_va_cmd(2,"setstation",channels[n-1]->name,NULL); } } return 0; } void keypad_timeout(void) { if (debug) fprintf(stderr,"keypad: timeout\n"); if (keypad_state == cur_sender+1) set_title(); keypad_state = -1; } xawtv-3.106/common/commands.h000066400000000000000000000040631343350355000161420ustar00rootroot00000000000000#include "vbi-data.h" #define TT 0 #if TT #define VTX_COUNT 256 #define VTX_LEN 64 struct TEXTELEM { char str[VTX_LEN]; char *fg; char *bg; int len; int line; int x,y; }; #endif /*------------------------------------------------------------------------*/ /* feedback for the user */ extern void (*update_title)(char *message); extern void (*display_message)(char *message); extern void (*rec_status)(char *message); #if TT extern void (*vtx_message)(struct TEXTELEM *tt); #endif #ifdef HAVE_ZVBI extern void (*vtx_subtitle)(struct vbi_page *pg, struct vbi_rect *rect); #endif /* for updating GUI elements / whatever */ extern void (*attr_notify)(struct ng_attribute *attr, int val); extern void (*mute_notify)(int val); extern void (*volume_notify)(void); extern void (*freqtab_notify)(void); extern void (*setfreqtab_notify)(void); extern void (*setstation_notify)(void); /* gets called _before_ channel switches */ extern void (*channel_switch_hook)(void); /* capture overlay/grab/off */ extern void (*set_capture_hook)(int old, int new, int tmp_switch); /* toggle fullscreen */ extern void (*fullscreen_hook)(void); extern void (*exit_hook)(void); extern void (*capture_get_hook)(void); extern void (*capture_rel_hook)(void); extern void (*movie_hook)(int argc, char **argv); extern int debug; extern int do_overlay; extern char *snapbase; extern int have_shmem; extern unsigned int cur_tv_width,cur_tv_height; extern int cur_movie,cur_attrs[256]; extern struct movie_parm m_parm; extern const struct ng_vid_driver *drv; extern void *h_drv; extern int f_drv; extern struct ng_attribute *attrs; /*------------------------------------------------------------------------*/ void attr_init(void); void audio_init(void); void audio_on(void); void audio_off(void); void set_defaults(void); void add_attrs(struct ng_attribute *new); void init_overlay(void); int do_va_cmd(int argc, ...); int do_command(int argc, char **argv); char** split_cmdline(char *line, int *count); void keypad_timeout(void); xawtv-3.106/common/event.c000066400000000000000000000066661343350355000154700ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include "grab-ng.h" #include "commands.h" #include "event.h" #include "parseconfig.h" /* ----------------------------------------------------------------------- */ static struct event_entry *event_conf_list; static struct event_entry *event_builtin_list; /* ----------------------------------------------------------------------- */ static void parse_action(struct event_entry *entry) { char *token,*h; strcpy(entry->argbuf,entry->action); h = entry->argbuf; for (;;) { while (' ' == *h || '\t' == *h) h++; if ('\0' == *h) break; if ('"' == *h) { /* quoted string */ h++; token = h; while ('\0' != *h && '"' != *h) h++; } else { /* normal string */ token = h; while ('\0' != *h && ' ' != *h && '\t' != *h) h++; } if ('\0' != *h) { *h = 0; h++; } entry->argv[entry->argc++] = token; } } /* ----------------------------------------------------------------------- */ int event_register(char *event, char *action) { struct event_entry *entry; entry = malloc(sizeof(*entry)); memset(entry,0,sizeof(*entry)); strncpy(entry->event,event,127); strncpy(entry->action,action,127); entry->next = event_conf_list; event_conf_list = entry; parse_action(entry); if (debug) fprintf(stderr,"ev: reg conf \"%s\" => \"%s\"\n", entry->event,entry->action); return 0; } int event_register_list(struct event_entry *entry) { for (; NULL != entry && 0 != entry->event[0]; entry++) { entry->next = event_builtin_list; event_builtin_list = entry; parse_action(entry); if (debug) fprintf(stderr,"ev: reg built-in \"%s\" => \"%s\"\n", entry->event,entry->action); } return 0; } void event_readconfig(void) { char **list,*val; list = cfg_list_entries("eventmap"); if (NULL == list) return; for (; *list != NULL; list++) if (NULL != (val = cfg_get_str("eventmap",*list))) event_register(*list,val); } void event_writeconfig(FILE *fp) { struct event_entry *entry; if (NULL == event_conf_list) return; fprintf(fp,"[eventmap]\n"); for (entry = event_conf_list; NULL != entry; entry = entry->next) fprintf(fp,"%s = %s\n",entry->event,entry->action); fprintf(fp,"\n"); } /* ----------------------------------------------------------------------- */ int event_dispatch(char *event) { struct event_entry *entry = NULL; char *name,*arg,*h,*argv[EVENT_ARGV_SIZE]; int argc; /* parse */ if (NULL != (h = strchr(event,'('))) { name = event; arg = h+1; *h = 0; if (NULL != (h = strchr(arg,')'))) *h = 0; if (debug) fprintf(stderr,"ev: dispatch name=%s arg=%s\n",name,arg); } else { name = event; arg = NULL; if (debug) fprintf(stderr,"ev: dispatch name=%s\n",name); } /* search lists */ if (NULL == entry) for (entry = event_conf_list; NULL != entry; entry = entry->next) if (0 == strcasecmp(name,entry->event)) break; if (NULL == entry) for (entry = event_builtin_list; NULL != entry; entry = entry->next) if (0 == strcasecmp(name,entry->event)) break; if (NULL == entry) { if (debug) fprintf(stderr,"ev: 404: %s\n",name); return 0; } /* call action */ memcpy(argv,entry->argv,sizeof(argv)); argc = entry->argc; if (arg) argv[argc++] = arg; do_command(argc,argv); return 0; } xawtv-3.106/common/event.h000066400000000000000000000007401343350355000154600ustar00rootroot00000000000000#define EVENT_ARGV_SIZE 16 struct event_entry { /* the entry */ char event[128]; char action[128]; /* pre-parsed action for do_command */ char argbuf[128]; int argc; char *argv[EVENT_ARGV_SIZE]; /* linked list */ struct event_entry *next; }; int event_register(char *event, char *action); int event_register_list(struct event_entry *entry); void event_readconfig(void); void event_writeconfig(FILE *fp); int event_dispatch(char *event); xawtv-3.106/common/frequencies.c000066400000000000000000000064101343350355000166430ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "grab-ng.h" #include "commands.h" #include "frequencies.h" /* --------------------------------------------------------------------- */ int chantab = -1; struct CHANLISTS *chanlists; struct STRTAB *chanlist_names; /* --------------------------------------------------------------------- */ void freq_init(void) { char line[256],value[256]; FILE *fp; int nr,i,j; if (NULL == (fp = fopen(DATADIR "/Index.map","r"))) { perror("open " DATADIR "/Index.map"); exit(1); } if (debug) fprintf(stderr,"freq: reading " DATADIR "/Index.map\n"); nr = 0; i = 0; while (NULL != fgets(line,255,fp)) { nr++; if (line[0] == '\n' || line[0] == '#' || line[0] == '%') continue; if (1 == sscanf(line,"[%255[^]]]",value)) { /* [section] */ chanlists = realloc(chanlists, (i+2) * sizeof(struct CHANLISTS)); memset(chanlists+i, 0, 2*sizeof(struct CHANLISTS)); chanlists[i].name = strdup(value); i++; continue; } if (NULL == chanlists) { fprintf(stderr,"%s:%d: error: no section\n", DATADIR "/Index.map",nr); continue; } if (1 == sscanf(line," file = %255[^\n]",value)) { /* file = */ chanlists[i-1].filename = strdup(value); continue; } /* Huh ? */ fprintf(stderr,"%s:%d: syntax error\n", DATADIR "/Index.map",nr); } fclose(fp); chanlist_names = malloc((i+1) * sizeof(struct STRTAB)); for (j = 0; j < i; j++) { chanlist_names[j].nr = j; chanlist_names[j].str = chanlists[j].name; } chanlist_names[j].nr = -1; chanlist_names[j].str = NULL; } /* --------------------------------------------------------------------- */ static int freq_readlist(struct CHANLIST **list, int n, char *name) { char line[256],value[256]; char filename[256]; FILE *fp; int nr; sprintf(filename,"%s/%s",DATADIR,name); if (NULL == (fp = fopen(filename,"r"))) { fprintf(stderr,"open %s: %s\n",filename,strerror(errno)); exit(1); } if (debug) fprintf(stderr,"freq: reading %s\n",filename); nr = 0; while (NULL != fgets(line,255,fp)) { nr++; if (1 == sscanf(line,"# include \"%[^\"]\"",value)) { /* includes */ n = freq_readlist(list,n,value); continue; } if (line[0] == '\n' || line[0] == '#' || line[0] == '%') { /* ignore */ continue; } if (1 == sscanf(line,"[%255[^]]]",value)) { /* [section] */ if (0 == (n % 16)) { *list = realloc(*list, (n+16) * sizeof(struct CHANLIST)); memset((*list)+n, 0, 16*sizeof(struct CHANLIST)); } (*list)[n].name = strdup(value); n++; continue; } if (0 == n) { fprintf(stderr,"%s:%d: error: no section\n",filename,nr); continue; } if (1 == sscanf(line," freq = %255[^\n]", value)) { /* freq = */ (*list)[n-1].freq = atoi(value); continue; } /* Huh ? */ fprintf(stderr,"%s:%d: syntax error\n", filename, nr); } fclose(fp); return n; } void freq_newtab(int n) { if (debug) fprintf(stderr,"freq: newtab %d\n",n); if (NULL == chanlists[n].list) chanlists[n].count = freq_readlist(&chanlists[n].list,0,chanlists[n].filename); chantab = n; } xawtv-3.106/common/frequencies.h000066400000000000000000000106331343350355000166520ustar00rootroot00000000000000/* * Worldwide channel/frequency list * * Nathan Laredo (laredo@broked.net) * * Frequencies are given in kHz */ /* 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 */ /* 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, 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 CHANLIST { char *name; unsigned int freq; }; struct CHANLISTS { char *name; char *filename; struct CHANLIST *list; int count; }; /* --------------------------------------------------------------------- */ extern int chantab; extern struct CHANLISTS *chanlists; extern struct STRTAB *chanlist_names; #define chanlist ((-1 != chantab) ? chanlists[chantab].list : NULL) #define chancount ((-1 != chantab) ? chanlists[chantab].count : 0) /* --------------------------------------------------------------------- */ void freq_init(void); void freq_newtab(int n); xawtv-3.106/common/get_media_devices.c000066400000000000000000000341511343350355000177550ustar00rootroot00000000000000/* Copyright © 2011 by Mauro Carvalho Chehab The get_media_devices is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The libv4l2util Library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the libv4l2util Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA. */ #ifdef __linux__ /* This depends on sysfs, so it is linux only */ #include "config.h" #ifdef MAJOR_IN_SYSMACROS # include #endif #ifdef MAJOR_IN_MKDEV # include #endif #include #include #include #include #include #include #include #include #include "get_media_devices.h" #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) /** * struct media_device_entry - Describes one device entry got via sysfs * * @device: sysfs name for a device. * PCI devices are like: pci0000:00/0000:00:1b.0 * USB devices are like: pci0000:00/0000:00:1d.7/usb1/1-8 * @node: Device node, in sysfs or alsa hw identifier * @device_type: Type of the device (V4L_*, DVB_*, SND_*) */ struct media_device_entry { char *device; char *node; enum device_type type; enum bus_type bus; unsigned major, minor; /* Device major/minor */ }; /** * struct media_devices - Describes all devices found * * @device: sysfs name for a device. * PCI devices are like: pci0000:00/0000:00:1b.0 * USB devices are like: pci0000:00/0000:00:1d.7/usb1/1-8 * @node: Device node, in sysfs or alsa hw identifier * @device_type: Type of the device (V4L_*, DVB_*, SND_*) */ struct media_devices { struct media_device_entry *md_entry; unsigned int md_size; }; typedef int (*fill_data_t)(struct media_device_entry *md); #define DEVICE_STR "devices" static void get_uevent_info(struct media_device_entry *md_ptr, char *dname) { FILE *fd; char file[PATH_MAX * 2 + 8], *name, *p; char s[1024]; snprintf(file, sizeof(file), "%s/%s/uevent", dname, md_ptr->node); fd = fopen(file, "r"); if (!fd) return; while (fgets(s, sizeof(s), fd)) { p = strtok(s, "="); if (!p) continue; name = p; p = strtok(NULL, "\n"); if (!p) continue; if (!strcmp(name, "MAJOR")) md_ptr->major = atol(p); else if (!strcmp(name, "MINOR")) md_ptr->minor = atol(p); } fclose(fd); } static enum bus_type get_bus(char *device) { char file[PATH_MAX + 10]; char s[1024]; FILE *f; if (!strcmp(device, "/sys/devices/virtual")) return MEDIA_BUS_VIRTUAL; snprintf(file, sizeof(file), "%s/modalias", device); f = fopen(file, "r"); if (!f) return MEDIA_BUS_UNKNOWN; if (!fgets(s, sizeof(s), f)) return MEDIA_BUS_UNKNOWN; fclose(f); if (!strncmp(s, "pci", 3)) return MEDIA_BUS_PCI; if (!strncmp(s, "usb", 3)) return MEDIA_BUS_USB; return MEDIA_BUS_UNKNOWN; } static int get_class(char *class, struct media_device_entry **md, unsigned int *md_size, fill_data_t fill) { DIR *dir; struct dirent *entry; char dname[PATH_MAX + 1]; char fname[2 * PATH_MAX + 1]; char link[PATH_MAX + 1]; char virt_dev[60]; int err = -2; struct media_device_entry *md_ptr = NULL; char *p, *device; enum bus_type bus; static int virtual = 0; snprintf(dname, sizeof(dname), "/sys/class/%s", class); dir = opendir(dname); if (!dir) { return 0; } for (entry = readdir(dir); entry; entry = readdir(dir)) { /* Skip . and .. */ if (entry->d_name[0] == '.') continue; /* Canonicalize the device name */ snprintf(fname, sizeof(fname), "%s/%s", dname, entry->d_name); if (realpath(fname, link)) { device = link; /* Remove the subsystem/class_name from the string */ p = strstr(device, class); if (!p) continue; *(p - 1) = '\0'; bus = get_bus(device); /* remove the /sys/devices/ from the name */ device += 13; switch (bus) { case MEDIA_BUS_PCI: /* Remove the device function nr */ p = strrchr(device, '.'); if (!p) continue; *p = '\0'; break; case MEDIA_BUS_USB: /* Remove USB interface from the path */ p = strrchr(device, '/'); if (!p) continue; /* In case we have a device where the driver attaches directly to the usb device rather then to an interface */ if (!strchr(p, ':')) break; *p = '\0'; break; case MEDIA_BUS_VIRTUAL: /* Don't group virtual devices */ sprintf(virt_dev, "virtual%d", virtual++); device = virt_dev; break; case MEDIA_BUS_UNKNOWN: break; } /* Add one more element to the devices struct */ *md = realloc(*md, (*md_size + 1) * sizeof(*md_ptr)); if (!*md) goto error; md_ptr = (*md) + *md_size; (*md_size)++; /* Cleans previous data and fills it with device/node */ memset(md_ptr, 0, sizeof(*md_ptr)); md_ptr->type = UNKNOWN; md_ptr->device = strdup(device); md_ptr->node = strdup(entry->d_name); /* Retrieve major and minor information */ get_uevent_info(md_ptr, dname); /* Used to identify the type of node */ fill(md_ptr); } } err = 0; error: closedir(dir); return err; } static int add_v4l_class(struct media_device_entry *md) { if (strstr(md->node, "video")) md->type = MEDIA_V4L_VIDEO; else if (strstr(md->node, "vbi")) md->type = MEDIA_V4L_VBI; else if (strstr(md->node, "radio")) md->type = MEDIA_V4L_RADIO; else if (strstr(md->node, "v4l-subdev")) md->type = MEDIA_V4L_SUBDEV; return 0; } static int add_snd_class(struct media_device_entry *md) { unsigned c = 65535, d = 65535; char node[64]; if (strstr(md->node, "timer")) { md->type = MEDIA_SND_TIMER; return 0; } else if (strstr(md->node, "seq")) { md->type = MEDIA_SND_SEQ; return 0; } if (strstr(md->node, "card")) { sscanf(md->node, "card%u", &c); md->type = MEDIA_SND_CARD; } else if (strstr(md->node, "hw")) { sscanf(md->node, "hwC%uD%u", &c, &d); md->type = MEDIA_SND_HW; } else if (strstr(md->node, "control")) { sscanf(md->node, "controlC%u", &c); md->type = MEDIA_SND_CONTROL; } else if (strstr(md->node, "pcm")) { sscanf(md->node, "pcmC%uD%u", &c, &d); if (md->node[strlen(md->node) - 1] == 'p') md->type = MEDIA_SND_OUT; else if (md->node[strlen(md->node) - 1] == 'c') md->type = MEDIA_SND_CAP; } if (c == 65535) return 0; /* Reformat device to be useful for alsa userspace library */ if (d == 65535) snprintf(node, sizeof(node), "hw:%u", c); else snprintf(node, sizeof(node), "hw:%u,%u", c, d); free(md->node); md->node = strdup(node); return 0; } static int add_dvb_class(struct media_device_entry *md) { if (strstr(md->node, "video")) md->type = MEDIA_DVB_VIDEO; if (strstr(md->node, "audio")) md->type = MEDIA_DVB_AUDIO; if (strstr(md->node, "sec")) md->type = MEDIA_DVB_SEC; if (strstr(md->node, "frontend")) md->type = MEDIA_DVB_FRONTEND; else if (strstr(md->node, "demux")) md->type = MEDIA_DVB_DEMUX; else if (strstr(md->node, "dvr")) md->type = MEDIA_DVB_DVR; else if (strstr(md->node, "net")) md->type = MEDIA_DVB_NET; else if (strstr(md->node, "ca")) md->type = MEDIA_DVB_CA; else if (strstr(md->node, "osd")) md->type = MEDIA_DVB_OSD; return 0; } static int sort_media_device_entry(const void *a, const void *b) { const struct media_device_entry *md_a = a; const struct media_device_entry *md_b = b; int cmp; cmp = strcmp(md_a->device, md_b->device); if (cmp) return cmp; cmp = (int)md_a->type - (int)md_b->type; if (cmp) return cmp; return strcmp(md_a->node, md_b->node); } /* Public functions */ void free_media_devices(void *opaque) { struct media_devices *md = opaque; struct media_device_entry *md_ptr = md->md_entry; int i; for (i = 0; i < md->md_size; i++) { free(md_ptr->node); free(md_ptr->device); md_ptr++; } free(md->md_entry); free(md); } void *discover_media_devices(void) { struct media_devices *md = NULL; struct media_device_entry *md_entry = NULL; md = calloc(1, sizeof(*md)); if (!md) return NULL; md->md_size = 0; if (get_class("video4linux", &md_entry, &md->md_size, add_v4l_class)) goto error; if (get_class("sound", &md_entry, &md->md_size, add_snd_class)) goto error; if (get_class("dvb", &md_entry, &md->md_size, add_dvb_class)) goto error; /* There's no media device */ if (!md_entry) goto error; qsort(md_entry, md->md_size, sizeof(*md_entry), sort_media_device_entry); md->md_entry = md_entry; return md; error: free_media_devices(md); return NULL; } const char *media_device_type(enum device_type type) { switch(type) { /* V4L nodes */ case MEDIA_V4L_VIDEO: return "video"; case MEDIA_V4L_VBI: return "vbi"; case MEDIA_V4L_RADIO: return "radio"; case MEDIA_V4L_SUBDEV: return "v4l subdevice"; /* DVB nodes */ case MEDIA_DVB_VIDEO: return "dvb video"; case MEDIA_DVB_AUDIO: return "dvb audio"; case MEDIA_DVB_SEC: return "dvb sec"; case MEDIA_DVB_FRONTEND: return "dvb frontend"; case MEDIA_DVB_DEMUX: return "dvb demux"; case MEDIA_DVB_DVR: return "dvb dvr"; case MEDIA_DVB_NET: return "dvb net"; case MEDIA_DVB_CA: return "dvb conditional access"; case MEDIA_DVB_OSD: return "dvb OSD"; /* Alsa nodes */ case MEDIA_SND_CARD: return "sound card"; case MEDIA_SND_CAP: return "pcm capture"; case MEDIA_SND_OUT: return "pcm output"; case MEDIA_SND_CONTROL: return "mixer"; case MEDIA_SND_HW: return "sound hardware"; case MEDIA_SND_TIMER: return "sound timer"; case MEDIA_SND_SEQ: return "sound sequencer"; default: return "unknown"; }; } void display_media_devices(void *opaque) { struct media_devices *md = opaque; struct media_device_entry *md_ptr = md->md_entry; int i; char *prev = ""; for (i = 0; i < md->md_size; i++) { if (strcmp(prev, md_ptr->device)) { printf("\nDevice %s:\n\t", md_ptr->device); prev = md_ptr->device; } printf("%s(%s, dev %i:%i) ", md_ptr->node, media_device_type(md_ptr->type), md_ptr->major, md_ptr->minor); md_ptr++; } printf("\n"); } const char *get_associated_device(void *opaque, const char *last_seek, const enum device_type desired_type, const char *seek_device, const enum device_type seek_type) { struct media_devices *md = opaque; struct media_device_entry *md_ptr = md->md_entry; int i, found = 0; char *prev, *p; if (seek_type != NONE && seek_device[0]) { /* Get just the device name */ p = strrchr(seek_device, '/'); if (p) seek_device = p + 1; /* Step 1: Find the seek node */ for (i = 0; i < md->md_size; i++, md_ptr++) { if (last_seek && md_ptr->type == seek_type && !strcmp(md_ptr->node, last_seek)) { found = 1; continue; } if (last_seek && !found) continue; if (md_ptr->type == seek_type && !strcmp(seek_device, md_ptr->node)) break; } if (i == md->md_size) return NULL; i++; prev = md_ptr->device; md_ptr++; /* Step 2: find the associated node */ for (; i < md->md_size && !strcmp(prev, md_ptr->device); i++, md_ptr++) { if (last_seek && md_ptr->type == seek_type && !strcmp(md_ptr->node, last_seek)) { found = 1; continue; } if (last_seek && !found) continue; if (md_ptr->type == desired_type) return md_ptr->node; } } else { for (i = 0; i < md->md_size; i++, md_ptr++) { if (last_seek && !strcmp(md_ptr->node, last_seek)) { found = 1; continue; } if (last_seek && !found) continue; if (md_ptr->type == desired_type) return md_ptr->node; } } return NULL; } const char *fget_associated_device(void *opaque, const char *last_seek, const enum device_type desired_type, const int fd_seek_device, const enum device_type seek_type) { struct media_devices *md = opaque; struct media_device_entry *md_ptr = md->md_entry; struct stat f_status; unsigned int dev_major, dev_minor; int i, found = 0; char *prev; if (fstat(fd_seek_device, &f_status)) { perror("Can't get file status"); return NULL; } if (!S_ISCHR(f_status.st_mode)) { fprintf(stderr, "File descriptor is not a char device\n"); return NULL; } dev_major = major(f_status.st_rdev); dev_minor = minor(f_status.st_rdev); /* Step 1: Find the seek node */ for (i = 0; i < md->md_size; i++, md_ptr++) { if (last_seek && md_ptr->type == seek_type && md_ptr->major == dev_major && md_ptr->minor == dev_minor) { found = 1; continue; } if (last_seek && !found) continue; if (md_ptr->type == seek_type && md_ptr->major == dev_major && md_ptr->minor == dev_minor) break; } if (i == md->md_size) return NULL; i++; prev = md_ptr->device; md_ptr++; /* Step 2: find the associated node */ for (; i < md->md_size && !strcmp(prev, md_ptr->device); i++, md_ptr++) { if (last_seek && md_ptr->type == seek_type && md_ptr->major == dev_major && md_ptr->minor == dev_minor) { found = 1; continue; } if (last_seek && !found) continue; if (md_ptr->type == desired_type) return md_ptr->node; } return NULL; } const char *get_not_associated_device(void *opaque, const char *last_seek, const enum device_type desired_type, const enum device_type not_desired_type) { struct media_devices *md = opaque; struct media_device_entry *md_ptr = md->md_entry; int i, skip = 0, found = 0; char *prev = "", *result = NULL; /* Step 1: Find a device without seek_type node */ for (i = 0; i < md->md_size; i++, md_ptr++) { if (last_seek && !strcmp(md_ptr->node, last_seek)) { found = 1; continue; } if (last_seek && !found) continue; if (strcmp(prev, md_ptr->device)) { if (!skip && result) break; prev = md_ptr->device; skip = 0; result = NULL; } if (md_ptr->type == not_desired_type) skip = 1; else if (!skip && !result && md_ptr->type == desired_type) result = md_ptr->node; } if (skip) result = NULL; return result; } #endif xawtv-3.106/common/get_media_devices.h000066400000000000000000000126331343350355000177630ustar00rootroot00000000000000/* Copyright © 2011 by Mauro Carvalho Chehab The get_media_devices is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The libv4l2util Library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the libv4l2util Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA. */ /* * Version of the API */ #define GET_MEDIA_DEVICES_VERSION 0x0105 /** * enum device_type - Enumerates the type for each device * * The device_type is used to sort the media devices array. * So, the order is relevant. The first device should be * MEDIA_V4L_VIDEO. */ enum device_type { UNKNOWN = 65535, NONE = 65534, MEDIA_V4L_VIDEO = 0, MEDIA_V4L_VBI, MEDIA_V4L_RADIO, MEDIA_V4L_SUBDEV, MEDIA_DVB_VIDEO = 100, MEDIA_DVB_AUDIO, MEDIA_DVB_SEC, MEDIA_DVB_FRONTEND, MEDIA_DVB_DEMUX, MEDIA_DVB_DVR, MEDIA_DVB_CA, MEDIA_DVB_NET, MEDIA_DVB_OSD, MEDIA_SND_CARD = 200, MEDIA_SND_CAP, MEDIA_SND_OUT, MEDIA_SND_CONTROL, MEDIA_SND_HW, MEDIA_SND_TIMER, MEDIA_SND_SEQ, /* * FIXME: not all alsa devices were mapped. missing things like * midi, midiC%iD%i and timer interfaces */ }; enum bus_type { MEDIA_BUS_UNKNOWN, MEDIA_BUS_VIRTUAL, MEDIA_BUS_PCI, MEDIA_BUS_USB, }; /** * discover_media_devices() - Returns a list of the media devices * @md_size: Returns the size of the media devices found * * This function reads the /sys/class nodes for V4L, DVB and sound, * and returns an opaque desciptor that keeps a list of the devices. * The fields on this list is opaque, as they can be changed on newer * releases of this library. So, all access to it should be done via * a function provided by the API. The devices are ordered by device, * type and node. At return, md_size is updated. */ void *discover_media_devices(void); /** * free_media_devices() - Frees the media devices array * * @opaque: media devices opaque descriptor * * As discover_media_devices() dynamically allocate space for the * strings, feeing the list requires also to free those data. So, * the safest and recommended way is to call this function. */ void free_media_devices(void *opaque); /** * media_device_type() - returns a string with the name of a given type * * @type: media device type */ const char *media_device_type(const enum device_type type); /** * display_media_devices() - prints a list of media devices * * @opaque: media devices opaque descriptor */ void display_media_devices(void *opaque); /** * get_associated_device() - Return the next device associated with another one * * @opaque: media devices opaque descriptor * @last_seek: last seek result. Use NULL to get the first result * @desired_type: type of the desired device * @seek_device: name of the device with you want to get an association. *@ seek_type: type of the seek device. Using NONE produces the same * result of using NULL for the seek_device. * * This function seeks inside the media_devices struct for the next device * that it is associated with a seek parameter. * It can be used to get an alsa device associated with a video device. If * the seek_device is NULL or seek_type is NONE, it will just search for * devices of the desired_type. */ const char *get_associated_device(void *opaque, const char *last_seek, const enum device_type desired_type, const char *seek_device, const enum device_type seek_type); /** * fget_associated_device() - Return the next device associated with another one * * @opaque: media devices opaque descriptor * @last_seek: last seek result. Use NULL to get the first result * @desired_type: type of the desired device * @fd_seek_device: file handler for the device where the association will be made *@ seek_type: type of the seek device. Using NONE produces the same * result of using NULL for the seek_device. * * This function seeks inside the media_devices struct for the next device * that it is associated with a seek parameter. * It can be used to get an alsa device associated with an open file descriptor */ const char *fget_associated_device(void *opaque, const char *last_seek, const enum device_type desired_type, const int fd_seek_device, const enum device_type seek_type); /** * get_not_associated_device() - Return the next device not associated with * an specific device type. * * @opaque: media devices opaque descriptor * @last_seek: last seek result. Use NULL to get the first result * @desired_type: type of the desired device * @not_desired_type: type of the seek device * * This function seeks inside the media_devices struct for the next physical * device that doesn't support a non_desired type. * This method is useful for example to return the audio devices that are * provided by the motherboard. */ const char *get_not_associated_device(void *opaque, const char *last_seek, const enum device_type desired_type, const enum device_type not_desired_type); xawtv-3.106/common/joystick.c000066400000000000000000000043671343350355000162020ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #ifdef HAVE_LINUX_JOYSTICK_H # include #endif #include "grab-ng.h" #include "commands.h" #include "joystick.h" #include "event.h" /*-----------------------------------------------------------------------*/ extern int debug; #ifdef HAVE_LINUX_JOYSTICK_H struct JOYTAB { int class; int number; int value; char *event; }; static struct JOYTAB joytab[] = { { JS_EVENT_BUTTON, 0, 1, "joy-button-0" }, { JS_EVENT_BUTTON, 1, 1, "joy-button-1" }, { JS_EVENT_AXIS, 1, -32767, "joy-axis-up" }, { JS_EVENT_AXIS, 1, 32767, "joy-axis-down" }, { JS_EVENT_AXIS, 0, 32767, "joy-axis-left" }, { JS_EVENT_AXIS, 0, -32767, "joy-axis-right" }, }; #define NJOYTAB (sizeof(joytab)/sizeof(struct JOYTAB)) static struct event_entry joy_events[] = { { .event = "joy-button-0", .action = "quit", },{ .event = "joy-button-1", .action = "fullscreen", },{ .event = "joy-axis-up", .action = "volume inc", },{ .event = "joy-axis-down", .action = "volume dec", },{ .event = "joy-axis-left", .action = "setchannel prev", },{ .event = "joy-axis-right", .action = "setchannel next", },{ /* end of list */ } }; #endif int joystick_tv_init(char *dev) { #ifdef HAVE_LINUX_JOYSTICK_H int fd; if (NULL == dev) return -1; if (-1 == (fd = open(dev, O_NONBLOCK))) { fprintf(stderr, "joystick: open %s: %s\n",dev,strerror(errno)); return -1; } fcntl(fd,F_SETFD,FD_CLOEXEC); event_register_list(joy_events); return fd; #else if (debug) fprintf(stderr,"joystick: not enabled at compile time\n"); return -1; #endif } void joystick_tv_havedata(int js) { #ifdef HAVE_LINUX_JOYSTICK_H unsigned int i; struct js_event event; if (debug) fprintf(stderr, "joystick: received input\n"); if (read(js, &event, sizeof(struct js_event))) { for (i = 0; i < NJOYTAB; i++) if (joytab[i].class == (event.type) && joytab[i].number == event.number && joytab[i].value == event.value) break; if (i != NJOYTAB) event_dispatch(joytab[i].event); } #endif } xawtv-3.106/common/joystick.h000066400000000000000000000001041343350355000161700ustar00rootroot00000000000000int joystick_tv_init(char *dev); void joystick_tv_havedata(int js); xawtv-3.106/common/lirc.c000066400000000000000000000062001343350355000152600ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "config.h" #ifdef HAVE_LIBLIRC_CLIENT # include #endif #include "grab-ng.h" #include "commands.h" #include "lirc.h" #include "event.h" /*-----------------------------------------------------------------------*/ extern int debug; #ifdef HAVE_LIBLIRC_CLIENT static struct lirc_config *config = NULL; static struct event_entry lirc_events[] = { { .event = "lirc-key-ch+", .action = "setstation next", },{ .event = "lirc-key-ch-", .action = "setstation prev", },{ .event = "lirc-key-vol+", .action = "volume inc", },{ .event = "lirc-key-vol-", .action = "volume dec", },{ .event = "lirc-key-mute", .action = "volume mute", },{ .event = "lirc-key-full_screen", .action = "fullscreen toggle", },{ .event = "lirc-key-source", .action = "setinput next", },{ .event = "lirc-key-reserved", .action = "quit", },{ .event = "lirc-key-0", .action = "keypad 0", },{ .event = "lirc-key-1", .action = "keypad 1", },{ .event = "lirc-key-2", .action = "keypad 2", },{ .event = "lirc-key-3", .action = "keypad 3", },{ .event = "lirc-key-4", .action = "keypad 4", },{ .event = "lirc-key-5", .action = "keypad 5", },{ .event = "lirc-key-6", .action = "keypad 6", },{ .event = "lirc-key-7", .action = "keypad 7", },{ .event = "lirc-key-8", .action = "keypad 8", },{ .event = "lirc-key-9", .action = "keypad 9", },{ /* end of list */ } }; #endif int lirc_tv_init() { #ifdef HAVE_LIBLIRC_CLIENT int fd; if (-1 == (fd = lirc_init("xawtv",debug))) { if (debug) fprintf(stderr,"lirc: no infrared remote support available\n"); return -1; } if (0 != lirc_readconfig(NULL,&config,NULL)) { config = NULL; } if (debug) fprintf(stderr, "lirc: ~/.lircrc file %sfound\n", config ? "" : "not "); fcntl(fd,F_SETFL,O_NONBLOCK); fcntl(fd,F_SETFD,FD_CLOEXEC); event_register_list(lirc_events); if (debug) fprintf(stderr,"lirc: init ok\n"); return fd; #else if (debug) fprintf(stderr,"lirc: not enabled at compile time\n"); return -1; #endif } int lirc_tv_havedata() { #ifdef HAVE_LIBLIRC_CLIENT char *code,event[32],*cmd,**argv; int dummy,repeat,argc; int ret=-1; strcpy(event,"lirc-key-"); while (lirc_nextcode(&code)==0 && code!=NULL) { ret = 0; if (3 != sscanf(code,"%x %x %20s",&dummy,&repeat,event+9)) { fprintf(stderr,"lirc: oops, parse error: %s",code); continue; } if (debug) fprintf(stderr,"lirc: key=%s repeat=%d\n", event+9, repeat); if (config) { /* use ~/.lircrc */ while (lirc_code2char(config,code,&cmd)==0 && cmd != NULL) { if (debug) fprintf(stderr,"lirc: cmd \"%s\"\n", cmd); if (0 == strcasecmp(cmd,"eventmap")) { event_dispatch(event); } else { argv = split_cmdline(cmd,&argc); do_command(argc,argv); } } } else { /* standalone mode */ if (!repeat) event_dispatch(event); } free(code); } return ret; #else return 0; #endif } xawtv-3.106/common/lirc.h000066400000000000000000000000641343350355000152670ustar00rootroot00000000000000int lirc_tv_init(void); int lirc_tv_havedata(void); xawtv-3.106/common/midictrl.c000066400000000000000000000174551343350355000161540ustar00rootroot00000000000000#include "config.h" #ifdef HAVE_ALSA #include #include #include #include #include #include "grab-ng.h" #include "commands.h" #include "channel.h" #include "midictrl.h" #include "event.h" extern int debug; /* ------------------------------------------------------------------------ */ static char *midi_events[] = { "system", "result", "r2", "r3", "r4", "note", "noteon", "noteoff", "keypress", "r9", "controller", "pgmchange", "chanpress", "pitchbend", "control14", "nonregparam", "regparam", "r17", "r18", "r19", "songpos", "songsel", "qframe", "timesign", "keysign", "r25", "r26", "r27", "r28", "r29", "start", "continue", "stop", "setpos_tick", "setpos_time", "tempo", "clock", "tick", "r38", "r39", "tune_request", "reset", "sensing", "r43", "r44", "r45", "r46", "r47", "r48", "r49", "echo", "oss", "r52", "r53", "r54", "r55", "r56", "r57", "r58", "r59", "client_start", "client_exit", "client_change", "port_start", "port_exit", "port_change", "subscribed", "used", "unsubscribed", "unused", "sample", "sample_cluster", "sample_start", "sample_stop", "sample_freq", "sample_volume", "sample_loop", "sample_position", "sample_private1", "r79", "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87", "r88", "r89", "usr0", "usr1", "usr2", "usr3", "usr4", "usr5", "usr6", "usr7", "usr8", "usr9", "instr_begin", "instr_end", "instr_info", "instr_info_result", "instr_finfo", "instr_finfo_result", "instr_reset", "instr_status", "instr_status_result", "instr_put", "instr_get", "instr_get_result", "instr_free", "instr_list", "instr_list_result", "instr_cluster", "instr_cluster_get", "instr_cluster_result", "instr_change", "r119", "r120", "r121", "r122", "r123", "r124", "r125", "r126", "r127", "r128", "r129", "sysext", "bounce", "r132", "r133", "r134", "usr_var0", "usr_var1", "usr_var2", "usr_var3", "usr_var4", "ipcshm", "r141", "r142", "r143", "r144", "usr_varipc0", "usr_varipc1", "usr_varipc2", "usr_varipc3", "usr_varipc4", "kernel_error", "kernel_quote" }; #define EV_NAME(x) (x < sizeof(midi_events)/sizeof(char*) ? \ midi_events[x] : "UNKNOWN") static void midi_dump_ev(FILE *out, snd_seq_event_t *ev) { fprintf(out,"midi ev:"); if (ev->flags & SND_SEQ_TIME_STAMP_TICK) fprintf(out," tick %d",ev->time.tick); if (ev->flags & SND_SEQ_TIME_STAMP_REAL) { fprintf(out," real %d:%06d", ev->time.time.tv_sec,ev->time.time.tv_nsec); } if (ev->flags & SND_SEQ_TIME_MODE_ABS) fprintf(out," abs"); if (ev->flags & SND_SEQ_TIME_MODE_REL) fprintf(out," rel"); fprintf(out," [%d:%d] %s", ev->source.client,ev->source.port,EV_NAME(ev->type)); switch (ev->type) { case SND_SEQ_EVENT_NOTE: fprintf(out," ch=%d note=%d vel=%d off_vel=%d dur=%d", ev->data.note.channel, ev->data.note.note, ev->data.note.velocity, ev->data.note.off_velocity, ev->data.note.duration); break; case SND_SEQ_EVENT_NOTEON: case SND_SEQ_EVENT_NOTEOFF: case SND_SEQ_EVENT_KEYPRESS: fprintf(out," ch=%d note=%d vel=%d", ev->data.note.channel, ev->data.note.note, ev->data.note.velocity); break; case SND_SEQ_EVENT_CONTROLLER: case SND_SEQ_EVENT_PGMCHANGE: case SND_SEQ_EVENT_CONTROL14: case SND_SEQ_EVENT_NONREGPARAM: case SND_SEQ_EVENT_REGPARAM: fprintf(out," ch=%d par=%d val=%d", ev->data.control.channel, ev->data.control.param, ev->data.control.value); break; case SND_SEQ_EVENT_CHANPRESS: case SND_SEQ_EVENT_PITCHBEND: fprintf(out," ch=%d val=%d", ev->data.control.channel, ev->data.control.value); break; case SND_SEQ_EVENT_SONGPOS: case SND_SEQ_EVENT_SONGSEL: case SND_SEQ_EVENT_QFRAME: case SND_SEQ_EVENT_TIMESIGN: case SND_SEQ_EVENT_KEYSIGN: fprintf(out," val=%d", ev->data.control.value); break; } fprintf(out,"\n"); } /* ------------------------------------------------------------------------ */ int midi_open(struct midi_handle *h, char *name) { char *func; int rc; func = "snd_seq_open"; #if SND_LIB_VERSION >= 0x000900 if ((rc = snd_seq_open(&h->seq, "default", SND_SEQ_OPEN_INPUT, SND_SEQ_NONBLOCK)) < 0) goto err; #else if ((rc = snd_seq_open(&h->seq, SND_SEQ_OPEN_IN)) < 0) goto err; #endif func = "snd_seq_set_client_name"; if ((rc = snd_seq_set_client_name(h->seq, name)) < 0) goto err; func = "snd_seq_create_simple_port"; if ((rc = snd_seq_create_simple_port (h->seq,"name", SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION)) < 0) goto err; h->port = rc; if (debug) fprintf(stderr,"midi: open ok [%d:%d]\n", snd_seq_client_id(h->seq),h->port); #if SND_LIB_VERSION >= 0x000900 { struct pollfd p; snd_seq_poll_descriptors(h->seq, &p, 1, POLLIN); h->fd = p.fd; } #else h->fd = snd_seq_file_descriptor(h->seq); #endif return h->fd; err: fprintf(stderr, "midi: %s: %s\n",func,snd_strerror(rc)); if (h->seq) { snd_seq_close(h->seq); h->seq = NULL; } return -1; } int midi_close(struct midi_handle *h) { if (debug) fprintf(stderr,"midi: close\n"); if (h->ev) { snd_seq_free_event(h->ev); h->ev = NULL; } if (h->seq) { snd_seq_close(h->seq); h->seq = NULL; } return 0; } int midi_connect(struct midi_handle *h, char *arg) { int client, port, rc; snd_seq_port_subscribe_t *psubs; #if SND_LIB_VERSION >= 0x000900 snd_seq_addr_t addr; #else snd_seq_port_subscribe_t subs; #endif if (2 == sscanf(arg,"%d:%d",&client,&port)) { /* nothing */ } else { return -1; } #if SND_LIB_VERSION >= 0x000900 snd_seq_port_subscribe_malloc(&psubs); addr.client = client; addr.port = port; snd_seq_port_subscribe_set_sender(psubs,&addr); addr.client = snd_seq_client_id(h->seq); addr.port = h->port; snd_seq_port_subscribe_set_dest(psubs,&addr); #else psubs = &subs; memset(&subs,0,sizeof(subs)); subs.sender.client = client; subs.sender.port = port; subs.dest.client = snd_seq_client_id(h->seq); subs.dest.port = h->port; #endif if ((rc = snd_seq_subscribe_port(h->seq, psubs)) < 0) { fprintf(stderr, "midi: snd_seq_subscribe_port: %s\n",snd_strerror(rc)); } else if (debug) fprintf(stderr,"midi: subscribe ok [%d:%d]\n",client,port); #if SND_LIB_VERSION >= 0x000900 snd_seq_port_subscribe_free(psubs); #endif return rc; } int midi_read(struct midi_handle *h) { int rc; if (h->ev) { snd_seq_free_event(h->ev); h->ev = NULL; } if ((rc = snd_seq_event_input(h->seq,&h->ev)) < 0) { fprintf(stderr, "midi: snd_seq_event_input: %s\n",snd_strerror(rc)); return -1; } if (debug > 1) midi_dump_ev(stderr,h->ev); return 0; } /* ------------------------------------------------------------------------ */ #ifdef STANDALONE int debug = 2; int main(int argc, char *argv[]) { struct midi_handle h; memset(&h,0,sizeof(h)); if (-1 == midi_open(&h, "midi dump")) exit(1); if (argc > 1) midi_connect(&h,argv[1]); for (;;) midi_read(&h); midi_close(&h); exit(0); } #else /* STANDALONE */ void midi_translate(struct midi_handle *h) { char event[64]; int i; switch (h->ev->type) { case SND_SEQ_EVENT_NOTEON: if (0 == h->ev->data.note.velocity) return; for (i = 0; i < count; i++) { if (channels[i]->midi != 0 && channels[i]->midi == h->ev->data.note.note) { do_va_cmd(2,"setstation",channels[i]->name); return; } } sprintf(event,"midi-note-%d",h->ev->data.note.note); event_dispatch(event); break; case SND_SEQ_EVENT_CONTROLLER: sprintf(event,"midi-ctrl-%d(%d%%)", h->ev->data.control.param, h->ev->data.control.value*100/128); event_dispatch(event); } } #endif /* STANDALONE */ #endif /* HAVE_ALSA */ xawtv-3.106/common/midictrl.h000066400000000000000000000006761343350355000161560ustar00rootroot00000000000000#ifdef HAVE_ALSA #ifdef HAVE_ALSA_ASOUNDLIB_H # include #else # include #endif struct midi_handle { snd_seq_t *seq; int fd; int port; snd_seq_event_t *ev; }; int midi_open(struct midi_handle *h, char *name); int midi_close(struct midi_handle *h); int midi_connect(struct midi_handle *h, char *arg); int midi_read(struct midi_handle *h); void midi_translate(struct midi_handle *h); #endif xawtv-3.106/common/parseconfig.c000066400000000000000000000132361343350355000166360ustar00rootroot00000000000000/* * config file parser * */ #include #include #include #include "parseconfig.h" struct CFG_ENTRIES { int ent_count; char **ent_names; char **ent_values; int **ent_seen; }; struct CFG_SECTIONS { int sec_count; char **sec_names; struct CFG_ENTRIES **sec_entries; }; /* ------------------------------------------------------------------------ */ static struct CFG_SECTIONS *c; /* ------------------------------------------------------------------------ */ #define ALLOC_SIZE 16 static struct CFG_SECTIONS* cfg_init_sections(void) { struct CFG_SECTIONS *c; c = malloc(sizeof(struct CFG_SECTIONS)); memset(c,0,sizeof(struct CFG_SECTIONS)); c->sec_names = malloc(ALLOC_SIZE*sizeof(char*)); c->sec_names[0] = NULL; c->sec_entries = malloc(ALLOC_SIZE*sizeof(struct CFG_ENTRIES*)); c->sec_entries[0] = NULL; return c; } static struct CFG_ENTRIES* cfg_init_entries(void) { struct CFG_ENTRIES *e; e = malloc(sizeof(struct CFG_ENTRIES)); memset(e,0,sizeof(struct CFG_ENTRIES)); e->ent_names = malloc(ALLOC_SIZE*sizeof(char*)); e->ent_names[0] = NULL; e->ent_values = malloc(ALLOC_SIZE*sizeof(char*)); e->ent_values[0] = NULL; e->ent_seen = malloc(ALLOC_SIZE*sizeof(int*)); e->ent_seen[0] = 0; return e; } static struct CFG_ENTRIES* cfg_find_section(struct CFG_SECTIONS *c, char *name) { struct CFG_ENTRIES* e; int i; for (i = 0; i < c->sec_count; i++) if (0 == strcasecmp(c->sec_names[i],name)) return c->sec_entries[i]; /* 404 not found => create a new one */ if ((c->sec_count % ALLOC_SIZE) == (ALLOC_SIZE-2)) { c->sec_names = realloc(c->sec_names,(c->sec_count+2+ALLOC_SIZE)*sizeof(char*)); c->sec_entries = realloc(c->sec_entries,(c->sec_count+2+ALLOC_SIZE)*sizeof(struct CFG_ENTRIES*)); } e = cfg_init_entries(); c->sec_names[c->sec_count] = strdup(name); c->sec_entries[c->sec_count] = e; c->sec_count++; c->sec_names[c->sec_count] = NULL; c->sec_entries[c->sec_count] = NULL; return e; } static void cfg_set_entry(struct CFG_ENTRIES *e, char *name, char *value) { int i; for (i = 0; i < e->ent_count; i++) if (0 == strcasecmp(e->ent_names[i],name)) break; if (i == e->ent_count) { /* 404 not found => create a new one */ if ((e->ent_count % ALLOC_SIZE) == (ALLOC_SIZE-2)) { e->ent_names = realloc(e->ent_names,(e->ent_count+2+ALLOC_SIZE)*sizeof(char*)); e->ent_values = realloc(e->ent_values,(e->ent_count+2+ALLOC_SIZE)*sizeof(char*)); e->ent_seen = realloc(e->ent_seen,(e->ent_count+2+ALLOC_SIZE)*sizeof(int*)); } e->ent_count++; e->ent_names[e->ent_count] = NULL; e->ent_values[e->ent_count] = NULL; e->ent_seen[e->ent_count] = 0; } e->ent_names[i] = strdup(name); e->ent_values[i] = strdup(value); } /* ------------------------------------------------------------------------ */ int cfg_parse_file(char *filename) { struct CFG_ENTRIES *e = NULL; char line[256],tag[64],value[192]; FILE *fp; int nr; if (NULL == c) c = cfg_init_sections(); if (NULL == (fp = fopen(filename,"r"))) return -1; nr = 0; while (NULL != fgets(line,255,fp)) { nr++; if (line[0] == '\n' || line[0] == '#' || line[0] == '%') continue; if (1 == sscanf(line,"[%99[^]]]",value)) { /* [section] */ e = cfg_find_section(c,value); } else if (2 == sscanf(line," %63[^= ] = %191[^\n]",tag,value)) { /* foo = bar */ if (NULL == e) { fprintf(stderr,"%s:%d: error: no section\n",filename,nr); } else { char *c = value + strlen(value)-1; while (c > value && (*c == ' ' || *c == '\t')) *(c--) = 0; cfg_set_entry(e,tag,value); } } else { /* Huh ? */ fprintf(stderr,"%s:%d: syntax error\n",filename,nr); } } fclose(fp); return 0; } /* ------------------------------------------------------------------------ */ void cfg_parse_option(char *section, char *tag, char *value) { struct CFG_ENTRIES *e = NULL; if (NULL == c) c = cfg_init_sections(); e = cfg_find_section(c,section); cfg_set_entry(e,tag,value); } void cfg_parse_options(int *argc, char **argv) { char section[64], tag[64]; int i,j; for (i = 1; i+1 < *argc;) { if (2 == sscanf(argv[i],"-%63[^:]:%63s",section,tag)) { cfg_parse_option(section,tag,argv[i+1]); for (j = i; j < *argc-1; j++) argv[j] = argv[j+2]; (*argc) -= 2; } else { i++; } } } /* ------------------------------------------------------------------------ */ char** cfg_list_sections() { return c->sec_names; } char** cfg_list_entries(char *name) { int i; if (NULL == c) return NULL; for (i = 0; i < c->sec_count; i++) if (0 == strcasecmp(c->sec_names[i],name)) return c->sec_entries[i]->ent_names; return NULL; } char* cfg_get_str(char *sec, char *ent) { struct CFG_ENTRIES* e = NULL; char *v = NULL; int i; for (i = 0; i < c->sec_count; i++) if (0 == strcasecmp(c->sec_names[i],sec)) e = c->sec_entries[i]; if (NULL == e) return NULL; for (i = 0; i < e->ent_count; i++) if (0 == strcasecmp(e->ent_names[i],ent)) { v = e->ent_values[i]; e->ent_seen[i]++; } return v; } int cfg_get_int(char *sec, char *ent) { char *val; val = cfg_get_str(sec,ent); if (NULL == val) return -1; return atoi(val); } int cfg_get_signed_int(char *sec, char *ent) { char *val; val = cfg_get_str(sec,ent); if (NULL == val) return 0; return atoi(val); } float cfg_get_float(char *sec, char *ent) { char *val; val = cfg_get_str(sec,ent); if (NULL == val) return -1; return atof(val); } xawtv-3.106/common/parseconfig.h000066400000000000000000000006201343350355000166340ustar00rootroot00000000000000int cfg_parse_file(char *filename); void cfg_parse_option(char *section, char *tag, char *value); void cfg_parse_options(int *argc, char **argv); char** cfg_list_sections(void); char** cfg_list_entries(char *name); char* cfg_get_str(char *sec, char *ent); int cfg_get_int(char *sec, char *ent); int cfg_get_signed_int(char *sec, char *ent); float cfg_get_float(char *sec, char *ent); xawtv-3.106/common/sound.c000066400000000000000000000025631343350355000154670ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include "grab-ng.h" #include "sound.h" void oss_levels(struct ng_audio_buf *buf, int *left, int *right) { int lmax,rmax,i,level; signed char *s = (signed char*) buf->data; unsigned char *u = (unsigned char*) buf->data; lmax = 0; rmax = 0; switch (buf->fmt.fmtid) { case AUDIO_U8_MONO: i = 0; while (i < buf->size) { level = abs((int)u[i++] - 128); if (lmax < level) lmax = level, rmax = level; } break; case AUDIO_U8_STEREO: i = 0; while (i < buf->size) { level = abs((int)u[i++] - 128); if (lmax < level) lmax = level; level = abs((int)u[i++] - 128); if (rmax < level) rmax = level; } break; case AUDIO_S16_BE_MONO: case AUDIO_S16_LE_MONO: i = (AUDIO_S16_BE_MONO == buf->fmt.fmtid) ? 0 : 1; while (i < buf->size) { level = abs((int)s[i]); i += 2; if (lmax < level) lmax = level, rmax = level; } break; case AUDIO_S16_LE_STEREO: case AUDIO_S16_BE_STEREO: i = (AUDIO_S16_BE_STEREO == buf->fmt.fmtid) ? 0 : 1; while (i < buf->size) { level = abs((int)s[i]); i += 2; if (lmax < level) lmax = level; level = abs((int)s[i]); i += 2; if (rmax < level) rmax = level; } break; } *left = lmax; *right = rmax; } xawtv-3.106/common/sound.h000066400000000000000000000001771343350355000154730ustar00rootroot00000000000000#ifndef _SOUND_H_ #define _SOUND_H_ void oss_levels(struct ng_audio_buf *buf, int *left, int *right); #endif /* _SOUND_H_ */ xawtv-3.106/common/vbi-data.c000066400000000000000000000176731343350355000160360ustar00rootroot00000000000000#include "config.h" #ifdef HAVE_ZVBI #include #include #include #include #include #include #include #include #include #include #include #include #include #include "vbi-data.h" #include "vbi-sim.c" char *vbi_colors[8] = { "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white" }; struct vbi_rect vbi_fullrect = { .x1 = 0, .y1 = 0, .x2 = 41, .y2 = 25, }; /*---------------------------------------------------------------------*/ struct vbi_state* vbi_open(char *dev, int debug, int sim) { struct vbi_state *vbi; int services = VBI_SLICED_VBI_525 | VBI_SLICED_VBI_625 | VBI_SLICED_TELETEXT_B | VBI_SLICED_CAPTION_525 | VBI_SLICED_CAPTION_625 | VBI_SLICED_VPS | VBI_SLICED_WSS_625 | VBI_SLICED_WSS_CPR1204; int p[2]; /* init vbi */ vbi = malloc(sizeof(*vbi)); if (NULL == vbi) goto oops; memset(vbi,0,sizeof(*vbi)); vbi->debug = debug; vbi->sim = sim; vbi->dec = vbi_decoder_new(); if (NULL == vbi->dec) goto oops; /* * Give the user possibility to change default zvbi region (16, West-Europe) * Sometimes the region value just not reported in the stream etc... */ if (1) { char *env = getenv("ALEVTD_REGION"); unsigned int region; if (env && (region = strtoul(env,NULL,0)) != 0) vbi_teletext_set_default_region(vbi->dec,region); } if (vbi->sim) { vbi->par = init_sim(625,services); /* simulation for select */ pipe(p); switch (fork()) { case -1: perror("fork"); exit(1); case 0: close(p[0]); for (;;) { if (1 != write(p[1],"x",1)) exit(0); usleep(100*1000); } default: vbi->fd = p[0]; close(p[1]); }; } else { vbi->cap = vbi_capture_v4l2_new(dev,16,&services,-1,&vbi->err,debug); if (NULL == vbi->cap) { vbi->cap = vbi_capture_v4l_new(dev,16,&services,-1,&vbi->err,debug); if (NULL == vbi->cap) goto oops; } vbi->par = vbi_capture_parameters(vbi->cap); vbi->fd = vbi_capture_fd(vbi->cap); } vbi->lines = (vbi->par->count[0] + vbi->par->count[1]); vbi->raw = malloc(vbi->lines * vbi->par->bytes_per_line); if (NULL == vbi->raw) goto oops; vbi->sliced = malloc(vbi->lines * sizeof(vbi_sliced)); if (NULL == vbi->sliced) goto oops; vbi->tv.tv_sec = 1; vbi->tv.tv_usec = 0; return vbi; oops: if (vbi) { if (vbi->sliced) free(vbi->sliced); if (vbi->raw) free(vbi->raw); if (vbi->cap) vbi_capture_delete(vbi->cap); if (vbi->dec) vbi_decoder_delete(vbi->dec); free(vbi); } fprintf(stderr,"vbi: open failed [%s]\n",dev); return NULL; } int vbi_hasdata(struct vbi_state *vbi) { char buf[1]; int rc; if (vbi->sim) { read(vbi->fd,buf,1); read_sim(vbi->raw, vbi->sliced, &vbi->lines, &vbi->ts); rc = 1; } else { rc = vbi_capture_read(vbi->cap, vbi->raw, vbi->sliced, &vbi->lines, &vbi->ts, &vbi->tv); } vbi_decode(vbi->dec, vbi->sliced, vbi->lines, vbi->ts); return rc; } void vbi_close(struct vbi_state *vbi) { if (vbi) { if (vbi->sliced) free(vbi->sliced); if (vbi->raw) free(vbi->raw); if (vbi->cap) vbi_capture_delete(vbi->cap); if (vbi->dec) vbi_decoder_delete(vbi->dec); free(vbi); } } void vbi_dump_event(struct vbi_event *ev, void *user) { switch (ev->type) { case VBI_EVENT_TTX_PAGE: fprintf(stderr,"vbi ev: ttx page %03x.%02x \r", ev->ev.ttx_page.pgno, ev->ev.ttx_page.subno); break; case VBI_EVENT_CLOSE: fprintf(stderr,"vbi ev: close \n"); break; case VBI_EVENT_CAPTION: fprintf(stderr,"vbi ev: caption \n"); break; case VBI_EVENT_NETWORK: fprintf(stderr,"vbi ev: network id=%d name=\"%s\" call=\"%s\"\n", ev->ev.network.nuid, ev->ev.network.name, ev->ev.network.call); break; case VBI_EVENT_TRIGGER: switch (ev->ev.trigger->type) { case VBI_LINK_NONE: fprintf(stderr,"vbi ev: trigger none \n"); break; case VBI_LINK_MESSAGE: fprintf(stderr,"vbi ev: trigger message \n"); break; case VBI_LINK_PAGE: fprintf(stderr,"vbi ev: trigger page [%03x.%02x]\n", ev->ev.trigger->pgno, ev->ev.trigger->subno); break; case VBI_LINK_SUBPAGE: fprintf(stderr,"vbi ev: trigger subpage \n"); break; case VBI_LINK_HTTP: fprintf(stderr,"vbi ev: trigger http [%s]\n", ev->ev.trigger->url); break; case VBI_LINK_FTP: fprintf(stderr,"vbi ev: trigger ftp \n"); break; case VBI_LINK_EMAIL: fprintf(stderr,"vbi ev: trigger email \n"); break; case VBI_LINK_LID: fprintf(stderr,"vbi ev: trigger lid \n"); break; case VBI_LINK_TELEWEB: fprintf(stderr,"vbi ev: trigger teleweb \n"); break; } break; case VBI_EVENT_ASPECT: fprintf(stderr,"vbi ev: aspect \n"); break; case VBI_EVENT_PROG_INFO: fprintf(stderr,"vbi ev: prog info \n"); break; default: fprintf(stderr,"vbi ev: UNKNOWN[0x%x] \n",ev->type); break; } } int vbi_calc_page(int pagenr, int offset) { int result; result = pagenr + offset; if (offset < 0) { while ((result & 0x0f) > 0x09) result -= 0x01; while ((result & 0xf0) > 0x90) result -= 0x10; if (result < 0x100) result = 0x100; } if (offset > 0) { while ((result & 0x0f) > 0x09) result += 0x01; while ((result & 0xf0) > 0x90) result += 0x10; if (result > 0x899) result = 0x899; } return result; } int vbi_calc_subpage(vbi_decoder *dec, int pgno, int subno, int offset) { vbi_page pg; int newno; for (newno = subno+offset; newno != subno;) { if (vbi_fetch_vt_page(dec,&pg,pgno,newno, VBI_WST_LEVEL_1,0,0)) break; if (offset < 0) { newno--; if (newno < 0) newno += VBI_MAX_SUBPAGES; while ((newno & 0x0f) > 0x09) newno -= 0x01; } if (offset > 0) { newno++; while ((newno & 0x0f) > 0x09) newno += 0x01; if (newno >= VBI_MAX_SUBPAGES) newno = 0; } } return newno; } int vbi_export_txt(char *dest, char *charset, int size, vbi_page *pg, struct vbi_rect *rect, enum vbi_txt_colors color) { int x,y,rc; size_t olen,ilen; int fg,bg,len=0; char *ibuf, *obuf; vbi_char *ch; wchar_t wch; iconv_t ic; ic = iconv_open(charset,"WCHAR_T"); if (NULL == ic) return -1; obuf = dest; olen = size; for (y = rect->y1; y < rect->y2; y++) { ch = pg->text + 41*y; fg = -1; bg = -1; for (x = rect->x1; x <= rect->x2; x++) { if (x < rect->x2) { wch = ch[x].unicode; if (ch[x].size > VBI_DOUBLE_SIZE) wch = ' '; if (ch[x].conceal) wch = ' '; } else { wch = '\n'; } if (fg != ch[x].foreground || bg != ch[x].background) { fg = ch[x].foreground; bg = ch[x].background; switch (color) { case VBI_ANSICOLOR: len = sprintf(obuf,"\033[%d;%dm", 30 + (fg & 7), 40 + (bg & 7)); break; case VBI_NOCOLOR: len = 0; break; } olen -= len; obuf += len; } ibuf = (char*)(&wch); ilen = sizeof(wch); retry: rc = iconv(ic,&ibuf,&ilen,&obuf,&olen); if (-1 == rc && EILSEQ == errno && wch != '?') { if (vbi_is_gfx(wch)) wch = '#'; else wch = '?'; goto retry; } if (-1 == rc) goto done; } switch (color) { case VBI_ANSICOLOR: len = sprintf(obuf,"\033[0m"); break; case VBI_NOCOLOR: len = 0; break; } olen -= len; obuf += len; } done: return obuf - dest; } void vbi_find_subtitle(vbi_page *pg, struct vbi_rect *rect) { int x,y,showline; vbi_char *ch; *rect = vbi_fullrect; for (y = 1; y < 25; y++) { showline = 0; ch = pg->text + 41*y; for (x = 0; x <= 40; x++) if (ch[x].unicode != ' ') showline = 1; if (showline) break; } rect->y1 = y; for (y = 25; y >= rect->y1; y--) { showline = 0; ch = pg->text + 41*y; for (x = 0; x <= 40; x++) if (ch[x].unicode != ' ') showline = 1; if (showline) break; } rect->y2 = y+1; } #endif /* HAVE_ZVBI */ xawtv-3.106/common/vbi-data.h000066400000000000000000000023621343350355000160300ustar00rootroot00000000000000#ifndef _VBI_DATA_H #define _VBI_DATA_H 1 #ifdef HAVE_ZVBI #include #define VBI_MAX_SUBPAGES 64 struct vbi_state { vbi_decoder *dec; vbi_capture *cap; vbi_raw_decoder *par; vbi_sliced *sliced; uint8_t *raw; char *err; int lines,fd,sim,debug; double ts; struct timeval tv; }; struct vbi_rect { int x1,x2,y1,y2; }; enum vbi_txt_colors { VBI_NOCOLOR = 0, VBI_ANSICOLOR = 1, }; extern char *vbi_colors[8]; extern struct vbi_rect vbi_fullrect; struct vbi_state* vbi_open(char *dev, int debug, int sim); int vbi_hasdata(struct vbi_state *vbi); void vbi_close(struct vbi_state *vbi); void vbi_dump_event(struct vbi_event *ev, void *user); int vbi_to_utf8(struct vbi_char *src, unsigned char *dest, int n); int vbi_calc_page(int pagenr, int offset); int vbi_calc_subpage(struct vbi_decoder *dec, int pgno, int subno, int offset); int vbi_export_txt(char *dest, char *charset, int size, struct vbi_page *pg, struct vbi_rect *rect, enum vbi_txt_colors); void vbi_find_subtitle(struct vbi_page *pg, struct vbi_rect *rect); #endif /* HAVE_ZVBI */ #endif /* _VBI_DATA_H */ xawtv-3.106/common/vbi-sim.c000066400000000000000000000257031343350355000157060ustar00rootroot00000000000000#include #define AMP 110 #define DC 60 static vbi_raw_decoder sim; static double sim_time; static inline double shape(double ph) { double x = sin(ph); return x * x; } /* * Closed Caption Signal Simulator */ static inline double cc_sim(double t, double F, unsigned char b1, unsigned char b2) { int bits = (b2 << 10) + (b1 << 2) + 2; /* start bit 0 -> 1 */ double t1 = 10.5e-6 - .25 / F; double t2 = t1 + 7 / F; /* CRI 7 cycles */ double t3 = t2 + 1.5 / F; double t4 = t3 + 18 / F; /* 17 bits + raise and fall time */ double ph; if (t < t1) { return 0.0; } else if (t < t2) { t -= t2; ph = M_PI * 2 * t * F - (M_PI * .5); return sin(ph) / 2 + .5; } else if (t < t3) { return 0.0; } else if (t < t4) { int i, n; t -= t3; i = (t * F - .0); n = (bits >> i) & 3; /* low = 0, up, down, high */ if (n == 0) return 0.0; else if (n == 3) return 1.0; if ((n ^ i) & 1) /* down */ ph = M_PI * 2 * (t - 1 / F) * F / 4; else /* up */ ph = M_PI * 2 * (t - 0 / F) * F / 4; return shape(ph); } else { return 0.0; } } /* * Wide Screen Signalling Simulator */ static inline double wss625_sim(double t, double F, unsigned int bits) { static int twobit[] = { 0xE38, 0xE07, 0x1F8, 0x1C7 }; static char frame[] = "\0" "\1\1\1\1\1\0\0\0\1\1\1\0\0\0" "\1\1\1\0\0\0\1\1\1\0\0\0\1\1\1" "\0\0\0\1\1\1\1\0\0\0\1\1\1\1\0\0\0\0\0\1\1\1\1\1" "x"; double t1 = 11.0e-6 - .5 / F; double t4 = t1 + (29 + 24 + 84) / F; double ph; int i, j, n; frame[1 + 29 + 24] = bits & 1; if (t < t1) { return 0.0; } else if (t < t4) { t -= t1; i = (t * F - .0); if (i < 29 + 24) { n = frame[i] + 2 * frame[i + 1]; } else { j = i - 29 - 24; n = twobit[(bits >> (j / 6)) & 3]; n = (n >> (j % 6)) & 3; } /* low = 0, down, up, high */ if (n == 0) return 0.0; else if (n == 3) return 1.0; if ((n ^ i) & 1) ph = M_PI * 2 * (t - 1 / F) * F / 4; else /* down */ ph = M_PI * 2 * (t - 0 / F) * F / 4; return shape(ph); } else { return 0.0; } } static inline double wss525_sim(double t, double F, unsigned int bits) { double t1 = 11.2e-6 - .5 / F; double t4 = t1 + (2 + 14 + 6 + 1) / F; double ph; int i, n; bits = bits * 2 + (2 << 21); /* start bits 10, stop 0 */ if (t < t1) { return 0.0; } else if (t < t4) { t -= t1; i = (t * F - .0); n = (bits >> (22 - i)) & 3; /* low = 0, up, down, high */ if (n == 0) return 0.0; else if (n == 3) return 1.0; if ((n ^ i) & 1) ph = M_PI * 2 * (t - 0 / F) * F / 4; else /* down */ ph = M_PI * 2 * (t - 1 / F) * F / 4; return shape(ph); } else return 0.0; } /* * Teletext Signal Simulator */ static inline double ttx_sim(double t, double F, const uint8_t *text) { double t1 = 10.3e-6 - .5 / F; double t2 = t1 + (45 * 8 + 1) / F; /* 45 bytes + raise and fall time */ double ph; if (t < t1) { return 0.0; } else if (t < t2) { int i, j, n; t -= t1; i = (t * F); j = i >> 3; i &= 7; if (j == 0) n = ((text[0] * 2) >> i) & 3; else n = (((text[j - 1] >> 7) + text[j] * 2) >> i) & 3; if (n == 0) { return 0.0; } else if (n == 3) { return 1.0; } else if ((n ^ i) & 1) { ph = M_PI * 2 * (t - 1 / F) * F / 4; return shape(ph); } else { /* up */ ph = M_PI * 2 * (t - 0 / F) * F / 4; return shape(ph); } } else { return 0.0; } } static unsigned int caption_i = 0; static const uint8_t caption_text[] = { 0x14, 0x25, 0x14, 0x25, 'L', 'I', 'B', 'Z', 'V', 'B', 'I', ' ', 'C', 'A', 'P', 'T', 'I', 'O', 'N', ' ', 'S', 'I', 'M', 'U', 'L', 'A', 'T', 'I', 'O', 'N', 0x14, 0x2D, 0x14, 0x2D /* even size please, add 0 if neccessary */ }; static inline int odd(int c) { int n; n = c ^ (c >> 4); n = n ^ (n >> 2); n = n ^ (n >> 1); if (!(n & 1)) c |= 0x80; return c; } static uint8_t * ttx_next(void) { static uint8_t s1[2][10] = { { 0x02, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15 }, { 0x02, 0x15, 0x02, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15 } }; static uint8_t s2[32] = "100\2LIBZVBI\7 00:00:00"; static uint8_t s3[40] = " LIBZVBI TELETEXT SIMULATION "; static uint8_t s4[40] = " Page 100 "; static uint8_t s5[10][42] = { { 0x02, 0x2f, 0x97, 0x20, 0x37, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0xb5, 0x20 }, { 0xc7, 0x2f, 0x97, 0x0d, 0xb5, 0x04, 0x20, 0x9d, 0x83, 0x8c, 0x08, 0x2a, 0x2a, 0x2a, 0x89, 0x20, 0x20, 0x0d, 0x54, 0x45, 0xd3, 0x54, 0x20, 0xd0, 0xc1, 0xc7, 0x45, 0x8c, 0x20, 0x20, 0x08, 0x2a, 0x2a, 0x2a, 0x89, 0x0d, 0x20, 0x20, 0x1c, 0x97, 0xb5, 0x20 }, { 0x02, 0xd0, 0x97, 0x20, 0xb5, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xea, 0x20 }, { 0xc7, 0xd0, 0x97, 0x20, 0xb5, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xb5, 0x20 }, { 0x02, 0xc7, 0x97, 0x20, 0xb5, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x15, 0x1a, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x97, 0x19, 0xb5, 0x20 }, { 0xc7, 0xc7, 0x97, 0x20, 0xb5, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xb5, 0x20 }, { 0x02, 0x8c, 0x97, 0x9e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x13, 0x7f, 0x7f, 0x7f, 0x7f, 0x16, 0x7f, 0x7f, 0x7f, 0x7f, 0x92, 0x7f, 0x92, 0x7f, 0x7f, 0x15, 0x7f, 0x7f, 0x15, 0x7f, 0x91, 0x91, 0x7f, 0x7f, 0x91, 0x94, 0x7f, 0x94, 0x7f, 0x94, 0x97, 0xb5, 0x20 }, { 0xc7, 0x8c, 0x97, 0x9e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x13, 0x7f, 0x7f, 0x7f, 0x7f, 0x16, 0x7f, 0x7f, 0x7f, 0x7f, 0x92, 0x7f, 0x7f, 0x7f, 0x7f, 0x15, 0x7f, 0x7f, 0x7f, 0x7f, 0x91, 0x7f, 0x7f, 0x7f, 0x7f, 0x94, 0x7f, 0x7f, 0x7f, 0x7f, 0x97, 0xb5, 0x20 }, { 0x02, 0x9b, 0x97, 0x9e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x13, 0x7f, 0x7f, 0x7f, 0x7f, 0x16, 0x7f, 0x7f, 0x7f, 0x7f, 0x92, 0x7f, 0x7f, 0x7f, 0x7f, 0x15, 0x7f, 0x7f, 0x7f, 0x7f, 0x91, 0x7f, 0x7f, 0x7f, 0x7f, 0x94, 0x7f, 0x7f, 0x7f, 0x7f, 0x97, 0xb5, 0x20 }, { 0xc7, 0x9b, 0x97, 0x20, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0xa1, 0x20 } }; static uint8_t buf[45]; static int row = 0, page = 0; int i; buf[0] = 0x55; buf[1] = 0x55; buf[2] = 0x27; if (row == 0) { memcpy(buf + 3, s1[page], 10); page ^= 1; for (i = 0; i < 32; i++) buf[13 + i] = odd(s2[i]); } else if (row == 1) { buf[3] = 0x02; buf[4] = 0x02; for (i = 0; i < 40; i++) buf[5 + i] = odd(s3[i]); } else if (row == 2) { buf[3] = 0x02; buf[4] = 0x49; for (i = 0; i < 40; i++) buf[5 + i] = odd(s4[i]); } else { memcpy(buf + 3, s5[row - 3], 42); } if (++row >= 13) row = 0; return buf; } static void read_sim(uint8_t *raw_data, vbi_sliced *sliced_data, int *lines, double *timestamp) { uint8_t *buf; double start, inc; int i; memset(raw_data, 0, (sim.count[0] + sim.count[1]) * sim.bytes_per_line); *timestamp = sim_time; if (sim.scanning == 525) sim_time += 1001 / 30000.0; else sim_time += 1 / 25.0; start = sim.offset / (double) sim.sampling_rate; inc = 1 / (double) sim.sampling_rate; if (sim.scanning == 525) { /* Closed Caption */ { buf = raw_data + (21 - sim.start[0]) * sim.bytes_per_line; for (i = 0; i < sim.bytes_per_line; i++) buf[i] = cc_sim(start + i * inc, 15734 * 32, odd(caption_text[caption_i]), odd(caption_text[caption_i + 1])) * AMP + DC; if ((caption_i += 2) > sizeof(caption_text)) caption_i = 0; } /* WSS NTSC-Japan */ { const int poly = (1 << 6) + (1 << 1) + 1; int b0 = 1, b1 = 1; int bits = (b0 << 13) + (b1 << 12); int crc, j; crc = (((1 << 6) - 1) << (14 + 6)) + (bits << 6); for (j = 14 + 6 - 1; j >= 0; j--) { if (crc & ((1 << 6) << j)) crc ^= poly << j; } bits <<= 6; bits |= crc; /* fprintf(stderr, "WSS CPR << %08x\n", bits); */ buf = raw_data + (20 - sim.start[0]) * sim.bytes_per_line; for (i = 0; i < sim.bytes_per_line; i++) buf[i] = wss525_sim(start + i * inc, 447443, bits) * AMP + DC; } } else { /* Closed Caption */ { buf = raw_data + (22 - sim.start[0]) * sim.bytes_per_line; for (i = 0; i < sim.bytes_per_line; i++) buf[i] = cc_sim(start + i * inc, 15625 * 32, odd(caption_text[caption_i]), odd(caption_text[caption_i + 1])) * AMP + DC; if ((caption_i += 2) > sizeof(caption_text)) caption_i = 0; } /* WSS PAL */ { int g0 = 1, g1 = 2, g2 = 3, g3 = 4; int bits = (g3 << 11) + (g2 << 8) + (g1 << 4) + g0; buf = raw_data + (23 - sim.start[0]) * sim.bytes_per_line; for (i = 0; i < sim.bytes_per_line; i++) buf[i] = wss625_sim(start + i * inc, 15625 * 320, bits) * AMP + DC; } /* Teletext */ { int line, count; uint8_t *text; buf = raw_data; for (line = sim.start[0], count = sim.count[0]; count > 0; line++, count--, buf += sim.bytes_per_line) if ((line >= 7 && line <= 15) || (line >= 19 && line <= 21)) { text = ttx_next(); for (i = 0; i < sim.bytes_per_line; i++) { buf[i] = ttx_sim(start + i * inc, 15625 * 444, text) * AMP + DC; } } for (line = sim.start[1], count = sim.count[1]; count > 0; line++, count--, buf += sim.bytes_per_line) if ((line >= 320 && line <= 328) || (line >= 332 && line <= 335)) { text = ttx_next(); for (i = 0; i < sim.bytes_per_line; i++) { buf[i] = ttx_sim(start + i * inc, 15625 * 444, text) * AMP + DC; } } } } *lines = vbi_raw_decode(&sim, raw_data, sliced_data); } static vbi_raw_decoder * init_sim(int scanning, unsigned int services) { vbi_raw_decoder_init(&sim); sim.scanning = scanning; sim.sampling_format = VBI_PIXFMT_YUV420; sim.sampling_rate = 2 * 13500000; sim.bytes_per_line = 1440; sim.offset = 9.7e-6 * sim.sampling_rate; sim.interlaced = FALSE; sim.synchronous = TRUE; if (scanning == 525) { sim.start[0] = 10; sim.count[0] = 21 - 10 + 1; sim.start[1] = 272; sim.count[1] = 285 - 272 + 1; } else if (scanning == 625) { sim.start[0] = 6; sim.count[0] = 23 - 6 + 1; sim.start[1] = 318; sim.count[1] = 335 - 318 + 1; } else assert(!"invalid scanning value"); sim_time = 0.0; vbi_raw_decoder_add_services(&sim, services, 0); return ∼ } xawtv-3.106/common/webcam.c000066400000000000000000000064661343350355000156030ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include #include "grab-ng.h" #include "writefile.h" #include "webcam.h" extern int jpeg_quality; extern int debug; char *webcam; struct WEBCAM { pthread_mutex_t lock; pthread_cond_t wait; char *filename; struct ng_video_buf *buf; }; static void* webcam_writer(void *arg) { struct WEBCAM *web = arg; int rename,fd,old; char tmpfilename[512]; struct ng_video_fmt *fmt; if (debug) fprintf(stderr,"webcam_writer start\n"); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&old); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&old); pthread_mutex_lock(&web->lock); for (;;) { while (web->buf == NULL) { if (debug) fprintf(stderr,"webcam_writer: waiting for data\n"); pthread_cond_wait(&web->wait, &web->lock); } fmt = &web->buf->fmt; if (debug) fprintf(stderr,"webcam_writer: %d %dx%d \n", fmt->fmtid,fmt->width,fmt->height); rename = 1; sprintf(tmpfilename,"%s.$$$",web->filename); switch (fmt->fmtid) { case VIDEO_MJPEG: case VIDEO_JPEG: if (-1 == (fd = open(tmpfilename,O_CREAT|O_WRONLY,0666))) { fprintf(stderr,"open(%s): %s\n",tmpfilename, strerror(errno)); goto done; } write(fd,web->buf->data,web->buf->size); close(fd); break; #if 0 /* FIXME */ case VIDEO_BGR24: data = malloc(web->buf->size); memcpy(data,web->buf->data,web->buf->size); swap_rgb24(data,fmt->width*fmt->height); write_jpeg(tmpfilename,data,jpeg_quality,0); free(data); break; #endif case VIDEO_RGB24: write_jpeg(tmpfilename,web->buf,ng_jpeg_quality,0); break; default: fprintf(stderr,"webcam_writer: can't deal with format=%d\n", fmt->fmtid); rename = 0; } if (rename) { unlink(web->filename); if (-1 == link(tmpfilename,web->filename)) { fprintf(stderr,"link(%s,%s): %s\n", tmpfilename,web->filename,strerror(errno)); goto done; } unlink(tmpfilename); } free(web->filename); ng_release_video_buf(web->buf); web->buf = NULL; } done: pthread_mutex_unlock(&web->lock); if (debug) fprintf(stderr,"webcam_writer done\n"); return NULL; } /* ----------------------------------------------------------------------- */ static struct WEBCAM *web; static pthread_t tweb; void webcam_init() { web = malloc(sizeof(struct WEBCAM)); memset(web,0,sizeof(struct WEBCAM)); pthread_mutex_init(&web->lock, NULL); pthread_create(&tweb,NULL,webcam_writer,web); return; } void webcam_exit() { if (web) { pthread_cancel(tweb); free(web); web = NULL; } } int webcam_put(char *filename, struct ng_video_buf *buf) { int ret = 0; if (NULL == web) webcam_init(); if (-1 == pthread_mutex_trylock(&web->lock)) { if (debug) fprintf(stderr,"webcam_put: locked\n"); return -1; } if (NULL != web->buf) { if (debug) fprintf(stderr,"webcam_put: still has data\n"); ret = -1; goto done; } web->filename = strdup(filename); web->buf = buf; buf->refcount++; if (debug) fprintf(stderr,"webcam_put: ok\n"); pthread_cond_signal(&web->wait); done: pthread_mutex_unlock(&web->lock); return ret; } xawtv-3.106/common/webcam.h000066400000000000000000000001771343350355000156010ustar00rootroot00000000000000extern char *webcam; int webcam_put(char *filename, struct ng_video_buf *buf); void webcam_init(void); void webcam_exit(void); xawtv-3.106/configure.ac000066400000000000000000000246361343350355000151760ustar00rootroot00000000000000dnl --------------------------------------------------------------------- dnl Process this file with autoconf to produce a configure script. AC_INIT(xawtv.spec.in) AC_CONFIG_HEADER(config.h) dnl --------------------------------------------------------------------- dnl Options AC_ARG_ENABLE(xfree-ext, [ --enable-xfree-ext use XFree extentions (DGA,VidMode,DPMS)]) AC_ARG_ENABLE(xvideo, [ --enable-xvideo use the Xvideo extention]) AC_ARG_ENABLE(lirc, [ --enable-lirc lirc support]) AC_ARG_ENABLE(quicktime, [ --enable-quicktime quicktime support]) AC_ARG_ENABLE(motif, [ --enable-motif enable experimental motif support]) AC_ARG_ENABLE(aa, [ --enable-aa enable aalib support]) AC_ARG_ENABLE(alsa, [ --enable-alsa enable alsa support]) AC_ARG_ENABLE(zvbi, [ --enable-zvbi enable vbi support (via libzvbi)]) AC_ARG_ENABLE(gl, [ --enable-gl enable opengl support]) AC_ARG_ENABLE(dv, [ --enable-dv enable dvlib support]) AC_ARG_ENABLE(mmx, [ --enable-mmx enable mmx support]) AC_ARG_ENABLE(xft, [ --enable-xft enable xft support]) dnl --------------------------------------------------------------------- dnl Checks for programs. AC_PROG_CC AC_PROG_CXX AC_PROG_CPP AC_PROG_INSTALL AC_CHECK_PROGS(DEPEND,gccmakedep makedepend,true) dnl --------------------------------------------------------------------- dnl do some OS specific stuff here AC_HEADER_MAJOR AC_SUBST(FOUND_AALIB) AC_SUBST(FOUND_ALSA) AC_SUBST(FOUND_DV) AC_SUBST(FOUND_LQT) AC_SUBST(FOUND_MOTIF) AC_SUBST(FOUND_OS) AC_SUBST(FOUND_X11) AC_SUBST(FOUND_GL) AC_SUBST(FOUND_ZVBI) AC_SUBST(LIBV4L) AC_SUBST(FOUND_EXPLAIN) FOUND_AALIB="no" FOUND_ALSA="no" FOUND_DV="no" FOUND_LQT="no" FOUND_MOTIF="no" FOUND_OS="unknown" FOUND_X11="no" FOUND_GL="no" FOUND_ZVBI="no" FOUND_LIRC="no" LIBV4L="no" FOUND_EXPLAIN="no" case "`uname -s`" in Linux) FOUND_OS="linux" ;; OpenBSD | FreeBSD | NetBSD) # *BSD has important stuff (from ports) # in /usr/local ... CFLAGS="$CFLAGS -I/usr/local/include -L/usr/local/lib" LDLIBS="$LDLIBS -L/usr/local/lib" FOUND_OS="bsd" ;; GNU/kFreeBSD) FOUND_OS="bsd" ;; *) AC_MSG_CHECKING(if xawtv will build on `uname -s`) AC_MSG_RESULT(maybe) FOUND_OS="unknown" ;; esac dnl --------------------------------------------------------------------- dnl Checks for functions AC_EGREP_HEADER(sockaddr_storage,sys/socket.h,AC_DEFINE(HAVE_SOCKADDR_STORAGE,1,"have ipv6")) AC_CHECK_HEADERS(getopt.h soundcard.h unistd.h sys/select.h sys/soundcard.h alsa/asoundlib.h linux/joystick.h dev/ic/bt8xx.h machine/ioctl_bt848.h) AC_CHECK_FUNCS(ftello fseeko getpt getnameinfo getopt_long strcasestr dlopen) AC_SUBST(DLFLAGS) DLFLAGS="" if test "$ac_cv_func_dlopen" = "no"; then AC_CHECK_LIB(dl,dlopen, [ DLFLAGS="-ldl" ] ) fi AC_MSG_CHECKING(for ELF) if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then AC_MSG_RESULT(yes) DLFLAGS="$DLFLAGS -Wl,-E" else AC_MSG_RESULT(no) fi AC_CHECK_LIB(pthread,pthread_create,LIBPTHREAD="-lpthread") if test "$LIBPTHREAD" = ""; then AC_CHECK_LIB(c_r,pthread_create,LIBPTHREAD="-lc_r") fi AC_CHECK_LIB(ossaudio,main,LIBOSS="-lossaudio") AC_CHECK_LIB(ncursesw,initscr,LIBCURSES="-lncursesw") if test "$LIBCURSES" = ""; then AC_CHECK_LIB(ncurses,initscr,LIBCURSES="-lncurses") fi if test "$LIBCURSES" = ""; then AC_CHECK_LIB(curses,initscr,LIBCURSES="-lcurses") fi if test "$LIBCURSES" = ""; then echo "Oops: (n)curses library not found. You need this one, please install." echo "Note: to compile stuff just the library packages are not enougth," echo " you need also the *-devel packages." exit 1 fi if test "$LIBCURSES" = "-lncursesw"; then CFLAGS="$CFLAGS -I/usr/include/ncursesw" fi AC_SUBST(LIBPTHREAD) AC_SUBST(LIBOSS) AC_SUBST(LIBCURSES) dnl --------------------------------------------------------------------- dnl X11 checks AC_PATH_XTRA if test "$no_x" != "yes"; then FOUND_X11="yes" ATHENA="-lXaw -lXmu -lXt $X_PRE_LIBS -lXpm -lXext -lX11 $X_EXTRA_LIBS" XFT_FLAGS="" XFT_LIBS="" if test "$enable_xft" != "no"; then AC_MSG_CHECKING(for Xft) if test -x "`which pkg-config 2>/dev/null`" && pkg-config xft && pkg-config fontconfig; then XFT_FLAGS="`pkg-config --cflags xft fontconfig`" XFT_LIBS="`pkg-config --libs xft fontconfig`" AC_DEFINE(HAVE_XFT,1,"have xft") AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi else ATHENA="" fi AC_SUBST(X_CFLAGS) AC_SUBST(X_PRE_LIBS) AC_SUBST(X_EXTRA_LIBS) AC_SUBST(X_LIBS) AC_SUBST(x_includes) AC_SUBST(ATHENA) AC_SUBST(SUBS) AC_SUBST(TOOLS) AC_SUBST(LDLIBS) AC_SUBST(XFT_FLAGS) AC_SUBST(XFT_LIBS) AC_CHECK_LIB(v4l2, v4l2_fd_open, LIBV4L="yes",,) if test "$LIBV4L" != "yes"; then echo "Oops: libv4l library not found. This is needed to use most webcams." echo "Note: to compile stuff just the library packages are not enough," echo " you need also the *-devel packages." fi AC_CHECK_LIB(explain, explain_open, AC_DEFINE(HAVE_EXPLAIN,1,"have libexplain") FOUND_EXPLAIN="yes",,) AC_CHECK_LIB(jpeg, jpeg_start_compress, JPEG="found",,) if test "$JPEG" != "found"; then echo "Oops: jpeg library not found. You need this one, please install." echo "Note: to compile stuff just the library packages are not enougth," echo " you need also the *-devel packages." exit 1 fi AC_SUBST(LIBALSA) LIBALSA="" if test "$enable_alsa" != "no"; then AC_CHECK_LIB(asound, snd_seq_open, AC_DEFINE(HAVE_ALSA,1,"have alsa") FOUND_ALSA="yes"; LIBALSA="-lasound",,) else echo "*** alsa disabled" fi AC_SUBST(LIRC) LIRC="" if test "$enable_lirc" != "no"; then AC_CHECK_LIB(lirc_client, lirc_init, AC_DEFINE(HAVE_LIBLIRC_CLIENT,1,"have lirc") FOUND_LIRC="yes"; LIRC="-llirc_client",,) else echo "*** lirc disabled" fi AC_SUBST(LIBZVBI) LIBZVBI="" if test "$enable_zvbi" != "no"; then AC_CHECK_LIB(zvbi, vbi_capture_fd, AC_DEFINE(HAVE_ZVBI,1,"have zvbi") FOUND_ZVBI="yes"; LIBZVBI="-lzvbi -lpthread -lm -lpng -lz",,$LIBPTHREAD) else echo "*** zvbi disabled" fi AC_SUBST(AALIBS) AALIBS="" if test "$enable_aa" != "no"; then AC_CHECK_LIB(aa,aa_autoinit, [ FOUND_AALIB="yes" ],,) if test "$FOUND_AALIB" = "yes"; then AALIBS=-laa if test -x "`which aalib-config 2>/dev/null`"; then AALIBS=`aalib-config --libs` fi fi else echo "*** aalib support disabled" fi AC_SUBST(LIBDV) LIBDV="" if test "$enable_dv" != "no"; then AC_CHECK_LIB(dv, dv_decoder_new, AC_DEFINE(HAVE_DV,1,"have dv") FOUND_DV="yes"; LIBDV="-ldv -lm",, -lm $LIBPTHREAD) else echo "*** DV disabled" fi dashlglib=$(pkg-config glib-2.0 --libs 2>/dev/null) if test "$dashlglib" = ""; then dashlglib=$(glib-config --libs 2>/dev/null) fi if test "$enable_quicktime" != "no"; then AC_CHECK_LIB(quicktime, lqt_query_registry, FOUND_LQT="yes"; AC_DEFINE(HAVE_LIBQUICKTIME,1,"have libquicktime"),, $DLFLAGS $dashlglib $LIBPTHREAD) else echo "*** quicktime disabled" fi QTLIBS="" if test "$FOUND_LQT" = "yes"; then QTFLAGS="`pkg-config libquicktime --cflags-only-I`" if test "$QTFLAGS" = ""; then QTFLAGS= "-I/usr/include/quicktime" fi QTLIBS="-lquicktime $DLFLAGS $dashlglib -lm" fi AC_SUBST(QTLIBS) AC_SUBST(QTFLAGS) if test "$enable_xfree_ext" != "no"; then AC_CHECK_LIB(Xxf86dga, XF86DGAQueryExtension,,, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryExtension,,, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) AC_CHECK_LIB(Xdpms, DPMSQueryExtension,,, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) if test "$ac_cv_lib_Xdpms_DPMSQueryExtension" = "no"; then AC_CHECK_LIB(Xext, DPMSQueryExtension,AC_DEFINE(HAVE_LIBXDPMS),, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) fi AC_CHECK_LIB(Xinerama, XineramaQueryExtension,,, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) AC_CHECK_LIB(Xrender, XRenderQueryExtension,,, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) AC_CHECK_LIB(Xrandr, XRRConfigCurrentConfiguration,,, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) else echo "*** XFree extentions disabled" fi if test "$enable_xvideo" != "no"; then AC_CHECK_LIB(Xv, XvQueryExtension,,, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) else echo "*** Xvideo extention disabled" fi if test "$enable_motif" != "no"; then AC_CHECK_LIB(Xm,XmStringGenerate, [ FOUND_MOTIF="yes" ],, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) else echo "*** motif support disabled" fi AC_SUBST(LIBGL) LIBGL="" if test "$enable_gl" != "no"; then AC_CHECK_LIB(GL, glXChooseVisual, AC_DEFINE(HAVE_GL,1,"have opengl") FOUND_GL="yes"; LIBGL="-lGL -lm",, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS -lm) else echo "*** OpenGL disabled" fi VERSION="`head -1 $srcdir/Changes`" AC_SUBST(VERSION) dnl --------------------------------------------------------------------- AC_MSG_CHECKING(for X11 config directory) x11conf=/usr/lib/X11 if test -d /etc/X11; then x11conf=/etc/X11 fi AC_MSG_RESULT($x11conf) AC_SUBST(x11conf) AC_MSG_CHECKING(for X11 app-defaults directory) resdir=/usr/lib/X11 if test -d /usr/share/X11/app-defaults; then resdir=/usr/share/X11 fi if test -d /etc/X11/app-defaults; then resdir=/etc/X11 fi AC_MSG_RESULT($resdir/app-defaults) AC_SUBST(resdir) dnl --------------------------------------------------------------------- dnl for screenlock AC_DEFINE(HAVE_XMU,1,"have xmu") dnl --------------------------------------------------------------------- dnl deinterlace plugins AC_MSG_CHECKING(if mmx should be used) AC_SUBST(USE_MMX) if test "$enable_mmx" = "no" -o "$enable_mmx" = "yes"; then USE_MMX="$enable_mmx" else case "`uname -m`" in i586 | i686) USE_MMX="yes" ;; *) USE_MMX="no" ;; esac fi AC_MSG_RESULT($USE_MMX) dnl --------------------------------------------------------------------- AC_OUTPUT(Makefile xawtv.spec) for dir in \ common console debug fonts jwz libvbi vbistuff x11 structs \ libng libng/plugins libng/contrib-plugins mk do test -d $dir && continue mkdir -p $dir done dnl --------------------------------------------------------------------- dnl compile time options summary cat < * */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SOUNDCARD_H # include #endif #ifdef HAVE_SYS_SOUNDCARD_H # include #endif char *labels[] = SOUND_DEVICE_LABELS; char *names[] = SOUND_DEVICE_NAMES; static int dump_mixer(char *devname) { #ifdef SOUND_MIXER_INFO struct mixer_info info; #endif int mix,i,devmask,recmask,recsrc,stereomask,volume; if (-1 == (mix = open(devname,O_RDONLY))) return -1; printf("%s",devname); #ifdef SOUND_MIXER_INFO if (-1 != ioctl(mix,SOUND_MIXER_INFO,&info)) printf(" = %s (%s)",info.id,info.name); #endif printf("\n"); if (-1 == ioctl(mix,MIXER_READ(SOUND_MIXER_DEVMASK),&devmask) || -1 == ioctl(mix,MIXER_READ(SOUND_MIXER_STEREODEVS),&stereomask) || -1 == ioctl(mix,MIXER_READ(SOUND_MIXER_RECMASK),&recmask) || -1 == ioctl(mix,MIXER_READ(SOUND_MIXER_RECSRC),&recsrc)) { perror("mixer ioctl"); return -1; } for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { if ((1<> 8) & 0xff); else printf(" %d\n",volume & 0xff); } } return 0; } int main(int argc, char *argv[]) { char devname[32]; int i; /* first mixer device. If "mixer0" does'nt work, try "mixer" */ if (-1 == dump_mixer("/dev/mixer0")) dump_mixer("/dev/mixer"); /* other more devices */ for (i = 1; i < 8; i++) { sprintf(devname,"/dev/mixer%d",i); dump_mixer(devname); } return 0; } xawtv-3.106/console/fbtools.c000066400000000000000000000302551343350355000161600ustar00rootroot00000000000000/* * some generic framebuffer device stuff * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fbtools.h" /* -------------------------------------------------------------------- */ /* exported stuff */ struct fb_fix_screeninfo fb_fix; struct fb_var_screeninfo fb_var; unsigned char *fb_mem; int fb_mem_offset = 0; int fb_switch_state = FB_ACTIVE; /* -------------------------------------------------------------------- */ /* internal variables */ static int fb,tty; #if 0 static int bpp,black,white; #endif static int orig_vt_no = 0; static struct vt_mode vt_mode; static int kd_mode; static struct vt_mode vt_omode; static struct termios term; static struct fb_var_screeninfo fb_ovar; static unsigned short ored[256], ogreen[256], oblue[256]; static struct fb_cmap ocmap = { 0, 256, ored, ogreen, oblue }; /* -------------------------------------------------------------------- */ /* devices */ struct DEVS { char *fb0; char *fbnr; char *ttynr; }; struct DEVS devs_default = { .fb0 = "/dev/fb0", .fbnr = "/dev/fb%d", .ttynr = "/dev/tty%d", }; struct DEVS devs_devfs = { .fb0 = "/dev/fb/0", .fbnr = "/dev/fb/%d", .ttynr = "/dev/vc/%d", }; struct DEVS *devices; static void dev_init(void) { struct stat dummy; if (NULL != devices) return; if (0 == stat("/dev/.devfsd",&dummy)) devices = &devs_devfs; else devices = &devs_default; } /* -------------------------------------------------------------------- */ /* console switching */ extern int debug; static void fb_switch_signal(int signal) { if (signal == SIGUSR1) { /* release */ fb_switch_state = FB_REL_REQ; if (debug) write(2,"vt: SIGUSR1\n",12); } if (signal == SIGUSR2) { /* acquisition */ fb_switch_state = FB_ACQ_REQ; if (debug) write(2,"vt: SIGUSR2\n",12); } } void fb_switch_release() { ioctl(tty, VT_RELDISP, 1); fb_switch_state = FB_INACTIVE; if (debug) write(2,"vt: release\n",12); } void fb_switch_acquire() { ioctl(tty, VT_RELDISP, VT_ACKACQ); fb_switch_state = FB_ACTIVE; if (debug) write(2,"vt: acquire\n",12); } int fb_switch_init() { struct sigaction act,old; memset(&act,0,sizeof(act)); act.sa_handler = fb_switch_signal; sigemptyset(&act.sa_mask); sigaction(SIGUSR1,&act,&old); sigaction(SIGUSR2,&act,&old); if (-1 == ioctl(tty,VT_GETMODE, &vt_mode)) { perror("ioctl VT_GETMODE"); exit(1); } vt_mode.mode = VT_PROCESS; vt_mode.waitv = 0; vt_mode.relsig = SIGUSR1; vt_mode.acqsig = SIGUSR2; if (-1 == ioctl(tty,VT_SETMODE, &vt_mode)) { perror("ioctl VT_SETMODE"); exit(1); } return 0; } /* -------------------------------------------------------------------- */ /* initialisation & cleanup */ void fb_memset (void *addr, int c, size_t len) { #if 1 /* defined(__powerpc__) */ unsigned int i, *p; i = (c & 0xff) << 8; i |= i << 16; len >>= 2; for (p = addr; len--; p++) *p = i; #else memset(addr, c, len); #endif } static int fb_setmode(char *name) { FILE *fp; char line[80],label[32],value[16]; int geometry=0, timings=0, err=-1; /* load current values */ if (-1 == ioctl(fb,FBIOGET_VSCREENINFO,&fb_var)) { perror("ioctl FBIOGET_VSCREENINFO"); exit(1); } if (NULL == name) return -1; if (NULL == (fp = fopen("/etc/fb.modes","r"))) return -1; while (NULL != fgets(line,79,fp)) { if (1 == sscanf(line, "mode \"%31[^\"]\"",label) && 0 == strcmp(label,name)) { /* fill in new values */ fb_var.sync = 0; fb_var.vmode = 0; while (NULL != fgets(line,79,fp) && NULL == strstr(line,"endmode")) { if (5 == sscanf(line," geometry %d %d %d %d %d", &fb_var.xres,&fb_var.yres, &fb_var.xres_virtual,&fb_var.yres_virtual, &fb_var.bits_per_pixel)) geometry = 1; if (7 == sscanf(line," timings %d %d %d %d %d %d %d", &fb_var.pixclock, &fb_var.left_margin, &fb_var.right_margin, &fb_var.upper_margin, &fb_var.lower_margin, &fb_var.hsync_len, &fb_var.vsync_len)) timings = 1; if (1 == sscanf(line, " hsync %15s",value) && 0 == strcasecmp(value,"high")) fb_var.sync |= FB_SYNC_HOR_HIGH_ACT; if (1 == sscanf(line, " vsync %15s",value) && 0 == strcasecmp(value,"high")) fb_var.sync |= FB_SYNC_VERT_HIGH_ACT; if (1 == sscanf(line, " csync %15s",value) && 0 == strcasecmp(value,"high")) fb_var.sync |= FB_SYNC_COMP_HIGH_ACT; if (1 == sscanf(line, " extsync %15s",value) && 0 == strcasecmp(value,"true")) fb_var.sync |= FB_SYNC_EXT; if (1 == sscanf(line, " laced %15s",value) && 0 == strcasecmp(value,"true")) fb_var.vmode |= FB_VMODE_INTERLACED; if (1 == sscanf(line, " double %15s",value) && 0 == strcasecmp(value,"true")) fb_var.vmode |= FB_VMODE_DOUBLE; } /* ok ? */ if (!geometry || !timings) goto out; /* set */ fb_var.xoffset = 0; fb_var.yoffset = 0; if (-1 == ioctl(fb,FBIOPUT_VSCREENINFO,&fb_var)) perror("ioctl FBIOPUT_VSCREENINFO"); /* look what we have now ... */ if (-1 == ioctl(fb,FBIOGET_VSCREENINFO,&fb_var)) { perror("ioctl FBIOGET_VSCREENINFO"); exit(1); } err = 0; goto out; } } out: fclose(fp); return err; } static void fb_setvt(int vtno) { struct vt_stat vts; char vtname[12]; if (vtno < 0) { if (-1 == ioctl(tty,VT_OPENQRY, &vtno) || vtno == -1) { perror("ioctl VT_OPENQRY"); exit(1); } } vtno &= 0xff; sprintf(vtname, devices->ttynr, vtno); chown(vtname, getuid(), getgid()); if (-1 == access(vtname, R_OK | W_OK)) { fprintf(stderr,"access %s: %s\n",vtname,strerror(errno)); exit(1); } switch (fork()) { case 0: break; case -1: perror("fork"); exit(1); default: exit(0); } close(tty); close(0); close(1); close(2); setsid(); open(vtname,O_RDWR); dup(0); dup(0); if (-1 == ioctl(tty,VT_GETSTATE, &vts)) { perror("ioctl VT_GETSTATE"); exit(1); } orig_vt_no = vts.v_active; if (-1 == ioctl(tty,VT_ACTIVATE, vtno)) { perror("ioctl VT_ACTIVATE"); exit(1); } if (-1 == ioctl(tty,VT_WAITACTIVE, vtno)) { perror("ioctl VT_WAITACTIVE"); exit(1); } } /* Hmm. radeonfb needs this. matroxfb doesn't. */ static int fb_activate_current(int tty) { struct vt_stat vts; if (-1 == ioctl(tty,VT_GETSTATE, &vts)) { perror("ioctl VT_GETSTATE"); return -1; } if (-1 == ioctl(tty,VT_ACTIVATE, vts.v_active)) { perror("ioctl VT_ACTIVATE"); return -1; } if (-1 == ioctl(tty,VT_WAITACTIVE, vts.v_active)) { perror("ioctl VT_WAITACTIVE"); return -1; } return 0; } int fb_init(char *device, char *mode, int vt) { char fbdev[16]; struct vt_stat vts; dev_init(); tty = 0; if (vt != 0) fb_setvt(vt); if (-1 == ioctl(tty,VT_GETSTATE, &vts)) { fprintf(stderr,"ioctl VT_GETSTATE: %s (not a linux console?)\n", strerror(errno)); exit(1); } if (NULL == device) { device = getenv("FRAMEBUFFER"); if (NULL == device) { struct fb_con2fbmap c2m; if (-1 == (fb = open(devices->fb0,O_WRONLY,0))) { fprintf(stderr,"open %s: %s\n",devices->fb0,strerror(errno)); exit(1); } c2m.console = vts.v_active; if (-1 == ioctl(fb, FBIOGET_CON2FBMAP, &c2m)) { perror("ioctl FBIOGET_CON2FBMAP"); exit(1); } close(fb); fprintf(stderr,"map: vt%02d => fb%d\n", c2m.console,c2m.framebuffer); sprintf(fbdev,devices->fbnr,c2m.framebuffer); device = fbdev; } } /* get current settings (which we have to restore) */ if (-1 == (fb = open(device,O_RDWR /* O_WRONLY */))) { fprintf(stderr,"open %s: %s\n",device,strerror(errno)); exit(1); } if (-1 == ioctl(fb,FBIOGET_VSCREENINFO,&fb_ovar)) { perror("ioctl FBIOGET_VSCREENINFO"); exit(1); } if (-1 == ioctl(fb,FBIOGET_FSCREENINFO,&fb_fix)) { perror("ioctl FBIOGET_FSCREENINFO"); exit(1); } if (fb_ovar.bits_per_pixel == 8 || fb_fix.visual == FB_VISUAL_DIRECTCOLOR) { if (-1 == ioctl(fb,FBIOGETCMAP,&ocmap)) { perror("ioctl FBIOGETCMAP"); exit(1); } } if (-1 == ioctl(tty,KDGETMODE, &kd_mode)) { perror("ioctl KDGETMODE"); exit(1); } if (-1 == ioctl(tty,VT_GETMODE, &vt_omode)) { perror("ioctl VT_GETMODE"); exit(1); } tcgetattr(tty, &term); /* switch mode */ fb_setmode(mode); /* checks & initialisation */ if (-1 == ioctl(fb,FBIOGET_FSCREENINFO,&fb_fix)) { perror("ioctl FBIOGET_FSCREENINFO"); exit(1); } if (fb_fix.type != FB_TYPE_PACKED_PIXELS) { fprintf(stderr,"can handle only packed pixel frame buffers\n"); goto err; } #if 0 switch (fb_var.bits_per_pixel) { case 8: white = 255; black = 0; bpp = 1; break; case 15: case 16: if (fb_var.green.length == 6) white = 0xffff; else white = 0x7fff; black = 0; bpp = 2; break; case 24: white = 0xffffff; black = 0; bpp = fb_var.bits_per_pixel/8; break; case 32: white = 0xffffff; black = 0; bpp = fb_var.bits_per_pixel/8; fb_setpixels = fb_setpixels4; break; default: fprintf(stderr, "Oops: %i bit/pixel ???\n", fb_var.bits_per_pixel); goto err; } #endif fb_mem_offset = (unsigned long)(fb_fix.smem_start) & (getpagesize()-1); fb_mem = mmap(NULL,fb_fix.smem_len+fb_mem_offset, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0); if (-1L == (long)fb_mem) { perror("mmap"); goto err; } /* move viewport to upper left corner */ if (fb_var.xoffset != 0 || fb_var.yoffset != 0) { fb_var.xoffset = 0; fb_var.yoffset = 0; if (-1 == ioctl(fb,FBIOPAN_DISPLAY,&fb_var)) { perror("ioctl FBIOPAN_DISPLAY"); goto err; } } if (-1 == ioctl(tty,KDSETMODE, KD_GRAPHICS)) { perror("ioctl KDSETMODE"); goto err; } fb_activate_current(tty); /* cls */ fb_memset(fb_mem+fb_mem_offset,0,fb_fix.smem_len); return fb; err: fb_cleanup(); exit(1); } void fb_cleanup(void) { /* restore console */ if (-1 == ioctl(fb,FBIOPUT_VSCREENINFO,&fb_ovar)) perror("ioctl FBIOPUT_VSCREENINFO"); if (-1 == ioctl(fb,FBIOGET_FSCREENINFO,&fb_fix)) perror("ioctl FBIOGET_FSCREENINFO"); if (fb_ovar.bits_per_pixel == 8 || fb_fix.visual == FB_VISUAL_DIRECTCOLOR) { if (-1 == ioctl(fb,FBIOPUTCMAP,&ocmap)) perror("ioctl FBIOPUTCMAP"); } close(fb); if (-1 == ioctl(tty,KDSETMODE, kd_mode)) perror("ioctl KDSETMODE"); if (-1 == ioctl(tty,VT_SETMODE, &vt_omode)) perror("ioctl VT_SETMODE"); if (orig_vt_no && -1 == ioctl(tty, VT_ACTIVATE, orig_vt_no)) perror("ioctl VT_ACTIVATE"); if (orig_vt_no && -1 == ioctl(tty, VT_WAITACTIVE, orig_vt_no)) perror("ioctl VT_WAITACTIVE"); tcsetattr(tty, TCSANOW, &term); close(tty); } /* -------------------------------------------------------------------- */ /* handle fatal errors */ static jmp_buf fb_fatal_cleanup; static void fb_catch_exit_signal(int signal) { siglongjmp(fb_fatal_cleanup,signal); } void fb_catch_exit_signals(void) { struct sigaction act,old; int termsig; memset(&act,0,sizeof(act)); act.sa_handler = fb_catch_exit_signal; sigemptyset(&act.sa_mask); sigaction(SIGINT, &act,&old); sigaction(SIGQUIT,&act,&old); sigaction(SIGTERM,&act,&old); sigaction(SIGABRT,&act,&old); sigaction(SIGTSTP,&act,&old); sigaction(SIGBUS, &act,&old); sigaction(SIGILL, &act,&old); sigaction(SIGSEGV,&act,&old); if (0 == (termsig = sigsetjmp(fb_fatal_cleanup,0))) return; /* cleanup */ fb_cleanup(); fprintf(stderr,"Oops: %s\n",sys_siglist[termsig]); exit(42); } xawtv-3.106/console/fbtools.h000066400000000000000000000012301343350355000161540ustar00rootroot00000000000000#define FB_ACTIVE 0 #define FB_REL_REQ 1 #define FB_INACTIVE 2 #define FB_ACQ_REQ 3 /* info about videomode - yes I know, quick & dirty... */ extern struct fb_fix_screeninfo fb_fix; extern struct fb_var_screeninfo fb_var; extern unsigned char *fb_mem; extern int fb_mem_offset; extern int fb_switch_state; /* init + cleanup */ int fb_probe(void); int fb_init(char *device, char *mode, int vt); void fb_cleanup(void); void fb_catch_exit_signals(void); void fb_memset(void *addr, int c, size_t len); /* console switching */ int fb_switch_init(void); void fb_switch_release(void); void fb_switch_acquire(void); xawtv-3.106/console/fbtv.c000066400000000000000000000537561343350355000154640ustar00rootroot00000000000000/* * console TV application. Uses a framebuffer device. * * (c) 1998-2001 Gerd Knorr * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "grab-ng.h" #include "writefile.h" #include "sound.h" #include "channel.h" #include "frequencies.h" #include "commands.h" #include "capture.h" #include "lirc.h" #include "joystick.h" #include "midictrl.h" #include "event.h" #include "fbtools.h" #include "fs.h" #include "matrox.h" #define MAX(x,y) ((x)>(y)?(x):(y)) #define MIN(x,y) ((x)<(y)?(x):(y)) /* ---------------------------------------------------------------------- */ /* framebuffer */ static char *fbdev = NULL; static char *fontfile = NULL; static char *mode = NULL; static char *joydev = NULL; static struct fs_font *f; static unsigned short red[256], green[256], blue[256]; static struct fb_cmap cmap = { 0, 256, red, green, blue }; static int switch_last,fb; static int keep_dma_on = 0; static int sig,quiet,matrox; static int ww,hh; static float fbgamma = 1.0; static struct ng_video_buf *buf; static struct ng_video_fmt fmt,gfmt; static struct ng_video_conv *conv; static struct ng_convert_handle *ch; static int dx,dy; int have_config; int x11_native_format,have_dga=1,debug; /*--- channels ------------------------------------------------------------*/ struct event_entry kbd_events[] = { { .event = "kbd-key-+", .action = "volume inc", },{ .event = "kbd-key--", .action = "volume dec", },{ .event = "kbd-key-enter", .action = "volume mute", },{ .event = "kbd-key-space", .action = "setstation next", },{ .event = "kbd-key-backspace", .action = "setstation back", },{ .event = "kbd-key-pgup", .action = "setstation next", },{ .event = "kbd-key-pgdown", .action = "setstation prev", },{ .event = "kbd-key-right", .action = "setchannel fine_up", },{ .event = "kbd-key-left", .action = "setchannel fine_down", },{ .event = "kbd-key-up", .action = "setchannel next", },{ .event = "kbd-key-down", .action = "setchannel prev", },{ .event = "kbd-key-g", .action = "snap ppm", },{ .event = "kbd-key-j", .action = "snap jpeg", },{ .event = "kbd-key-v", .action = "capture toggle", },{ .event = "kbd-key-f", .action = "fullscreen toggle", },{ .event = "kbd-key-0", .action = "keypad 0", },{ .event = "kbd-key-1", .action = "keypad 1", },{ .event = "kbd-key-2", .action = "keypad 2", },{ .event = "kbd-key-3", .action = "keypad 3", },{ .event = "kbd-key-4", .action = "keypad 4", },{ .event = "kbd-key-5", .action = "keypad 5", },{ .event = "kbd-key-6", .action = "keypad 6", },{ .event = "kbd-key-7", .action = "keypad 7", },{ .event = "kbd-key-8", .action = "keypad 8", },{ .event = "kbd-key-9", .action = "keypad 9", },{ /* end of list */ } }; struct KEYTAB { int key; char *name; }; static struct KEYTAB keytab[] = { { 9, "tab" }, { 10, "enter" }, { 13, "enter" }, { KEY_ENTER, "enter" }, { ' ', "space" }, { KEY_BACKSPACE, "backspace" }, { KEY_RIGHT, "right" }, { KEY_LEFT, "left" }, { KEY_UP, "up" }, { KEY_DOWN, "down" }, { KEY_PPAGE, "pgup" }, { KEY_NPAGE, "pgdown" }, { KEY_HOME, "home" }, { KEY_END, "end" }, }; #define NKEYTAB (sizeof(keytab)/sizeof(struct KEYTAB)) static char default_title[128] = "???"; static char message[128] = ""; /* ---------------------------------------------------------------------- */ /* framebuffer stuff */ static void linear_palette(int r, int g, int b) { int i, size; size = 256 >> (8 - r); for (i = 0; i < size; i++) red[i] = (unsigned short)(65535.0 * pow(i/(size - 1.0), fbgamma)); size = 256 >> (8 - g); for (i = 0; i < size; i++) green[i] = (unsigned short)(65535.0 * pow(i/(size - 1.0), fbgamma)); size = 256 >> (8 - b); for (i = 0; i < size; i++) blue[i] = (unsigned short)(65535.0 * pow(i/(size - 1.0), fbgamma)); } static void dither_palette(int r, int g, int b) { int rs, gs, bs, i; rs = 256 / (r - 1); gs = 256 / (g - 1); bs = 256 / (b - 1); for (i = 0; i < r*g*b; i++) { green[i+16] = (gs * ((i / (r * b)) % g)) * 255; red[i+16] = (rs * ((i / b) % r)) * 255; blue[i+16] = (bs * ((i) % b)) * 255; } } static void fb_initcolors(int fd, int gray) { /* get colormap */ if (fb_var.bits_per_pixel == 8 || fb_fix.visual == FB_VISUAL_DIRECTCOLOR) { if (-1 == ioctl(fd,FBIOGETCMAP,&cmap)) perror("ioctl FBIOGETCMAP"); } switch (fb_var.bits_per_pixel) { case 8: if (gray) { linear_palette(8,8,8); x11_native_format = VIDEO_GRAY; } else { dither_palette(5,9,5); x11_native_format = VIDEO_RGB08; } break; case 15: case 16: if (fb_fix.visual == FB_VISUAL_DIRECTCOLOR) linear_palette(fb_var.red.length, fb_var.green.length, fb_var.blue.length); #if BYTE_ORDER == BIG_ENDIAN x11_native_format = (fb_var.green.length == 6) ? VIDEO_RGB16_BE : VIDEO_RGB15_BE; #else x11_native_format = (fb_var.green.length == 6) ? VIDEO_RGB16_LE : VIDEO_RGB15_LE; #endif break; case 24: if (fb_fix.visual == FB_VISUAL_DIRECTCOLOR) linear_palette(8,8,8); #if BYTE_ORDER == BIG_ENDIAN x11_native_format = VIDEO_RGB24; #else x11_native_format = VIDEO_BGR24; #endif break; case 32: if (fb_fix.visual == FB_VISUAL_DIRECTCOLOR) linear_palette(8,8,8); #if BYTE_ORDER == BIG_ENDIAN x11_native_format = VIDEO_RGB32; #else x11_native_format = VIDEO_BGR32; #endif break; default: fb_cleanup(); fprintf(stderr, "Oops: %i bit/pixel ???\n", fb_var.bits_per_pixel); exit(1); } /* set colormap */ if (fb_var.bits_per_pixel == 8 || fb_fix.visual == FB_VISUAL_DIRECTCOLOR) { if (-1 == ioctl(fd,FBIOPUTCMAP,&cmap)) perror("ioctl FBIOPUTCMAP"); } } static void tty_init(void) { /* we use curses just for kbd input */ initscr(); cbreak(); noecho(); keypad(stdscr,1); } static void tty_cleanup(void) { clear(); refresh(); endwin(); } /* ---------------------------------------------------------------------- */ static void text_init(char *font) { if (NULL == f) f = fs_consolefont(font ? font : NULL); if (NULL == f) { fprintf(stderr,"no font available\n"); exit(1); } } static void text_out(int x, int y, char *str) { y *= f->height; y -= f->fontHeader.max_bounds.descent; fs_puts(f,x,y,str); } static int text_width(char *str) { return fs_textwidth(f,str); } /* ---------------------------------------------------------------------- */ #ifdef HAVE_ALSA static struct midi_handle fb_midi; #endif /* ---------------------------------------------------------------------- */ static void ctrlc(int signal) { sig=1; } #if 0 void change_audio(int mode) { if (grabber->grab_audio) grabber->grab_audio(-1,-1,&mode); } #endif static void do_capture(int from, int to, int tmp_switch) { /* off */ switch (from) { case CAPTURE_GRABDISPLAY: if (f_drv & CAN_CAPTURE) drv->stopvideo(h_drv); break; case CAPTURE_OVERLAY: if (f_drv & CAN_CAPTURE) drv->overlay(h_drv,NULL,0,0,NULL,0,0); if (matrox && !tmp_switch) gfx_scaler_off(); break; } /* Sanity check: don't accept resolution higher than framebuffer */ if (ww && hh) { if (ww > fb_var.xres) ww = fb_var.xres; if (hh > fb_var.yres) hh = fb_var.yres; } /* on */ memset(&buf,0,sizeof(buf)); switch (to) { case CAPTURE_GRABDISPLAY: if (ww && hh) { dx = fb_var.xres-fmt.width; dy = 0; fmt.fmtid = x11_native_format; fmt.width = ww; fmt.height = hh; fmt.bytesperline = fb_fix.line_length; } else { if (quiet) { dx = 0; dy = 0; } else { dx = f->height*3/2; dy = f->height; } fmt.fmtid = x11_native_format; fmt.width = fb_var.xres-dx; fmt.height = fb_var.yres-dy; fmt.bytesperline = fb_fix.line_length; } if (0 != ng_grabber_setformat(&fmt,1)) { gfmt = fmt; if (NULL == (conv = ng_grabber_findconv(&gfmt,0))) { fb_cleanup(); fprintf(stderr,"can't find useful capture format\n"); exit(1); } ch = ng_convert_alloc(conv,&gfmt,&fmt); ng_convert_init(ch); } dx += (fb_var.xres - 24 - fmt.width)/2; dy += (fb_var.yres - 16 - fmt.height)/2; if (f_drv & CAN_CAPTURE) drv->startvideo(h_drv,-1,2); break; case CAPTURE_OVERLAY: fmt.fmtid = x11_native_format; if (ww && hh) { fmt.width = ww; fmt.height = hh; dx = fb_var.xres-fmt.width; dy = 0; } else if (quiet) { fmt.width = fb_var.xres; fmt.height = fb_var.yres; dx = 0; dy = 0; } else { fmt.width = fb_var.xres-24; fmt.height = fb_var.yres-16; dx = f->height*3/2; dy = f->height; } if (matrox) { struct ng_video_fmt off; int starty; #if 1 /* FIXME: need some kind of size negotiation */ /* hardcoded: PAL, half height (want no interleace) */ off.width = 768; off.height = 288; starty = fb_var.yres; #else /* settings for debugging */ off.width = 320; off.height = 240; starty = fb_var.yres-off.height; #endif off.bytesperline = fb_fix.line_length; if (off.width*2 > off.bytesperline) off.width = off.bytesperline/2; off.fmtid = VIDEO_YUYV; drv->overlay(h_drv,&off,0,starty,NULL,0,0); gfx_scaler_on(starty*off.bytesperline,off.bytesperline, off.width,off.height, dx,dx+fmt.width, dy,dy+fmt.height); } else { drv->overlay(h_drv,&fmt,dx,dy,NULL,0,1); } break; } /* Sanity checks: some of the formula above could overflow */ if (dx < 0 || dx > fb_var.xres) dx = 0; if (dy < 0 || dy > fb_var.yres) dy = 0; } static void do_exit(void) { sig = 1; } static void new_title(char *txt) { strcpy(default_title,txt); } static void new_message(char *txt) { strcpy(message,txt); } static void channel_menu(void) { char key[32],ctrl[16],event[64],action[128]; int i; for (i = 0; i < count; i++) { if (channels[i]->key) { if (2 != sscanf(channels[i]->key,"%15[A-Za-z0-9_]+%31[A-Za-z0-9_]", ctrl,key)) strcpy(key,channels[i]->key); sprintf(event,"kbd-key-%s",key); sprintf(action,"setstation \"%s\"",channels[i]->name); event_register(event,action); } } } static void do_fullscreen(void) { do_va_cmd(2,"capture","off"); if (quiet < 0) text_init(fontfile); quiet = quiet ? 0 : 1; fb_memset(fb_mem+fb_mem_offset,0,fb_fix.smem_len); do_va_cmd(2,"capture","on"); } /*--- main ---------------------------------------------------------------*/ static void grabber_init(void) { drv = NULL; struct ng_video_fmt screen; memset(&screen,0,sizeof(screen)); screen.fmtid = x11_native_format, screen.width = fb_var.xres_virtual; screen.height = fb_var.yres_virtual; screen.bytesperline = fb_fix.line_length; drv = ng_vid_open(&ng_dev.video, ng_dev.driver, &screen, 0, &h_drv); if (NULL == drv) { fb_cleanup(); fprintf(stderr,"no grabber device available\n"); exit(1); } f_drv = drv->capabilities(h_drv); add_attrs(drv->list_attrs(h_drv)); } static void console_switch(void) { switch (fb_switch_state) { case FB_REL_REQ: if (!keep_dma_on) do_va_cmd(2,"capture","off"); switch_last = fb_switch_state; fb_switch_release(); break; case FB_ACQ_REQ: switch_last = fb_switch_state; fb_switch_acquire(); fb_memset(fb_mem+fb_mem_offset,0,fb_fix.smem_len); ioctl(fb,FBIOPAN_DISPLAY,&fb_var); do_va_cmd(2,"capture","on"); break; case FB_ACTIVE: case FB_INACTIVE: default: switch_last = fb_switch_state; break; } } #if 0 /* just a hook for some test code */ static void scaler_test(int off) { if (!matrox) { matrox=1; if (-1 == gfx_init(fb)) matrox = 0; } if (matrox) { gfx_scaler_on(0,fb_fix.line_length,320,240, fb_var.xres-320,fb_var.xres,0,240); sleep(2); } } #endif int main(int argc, char *argv[]) { int i,key,c,help=0,gray=0,rc,vt=0,fps=0,t1,t2,lirc,js,err,mute=1,fdmax, linesize; unsigned long ui; unsigned long freq; struct timeval tv; time_t t; char text1[145], text2[145], event[64], *env, *src, *dst; fd_set set; struct sigaction act,old; if (0 == geteuid() && 0 != getuid()) { fprintf(stderr,"fbtv /must not/ be installed suid root\n"); exit(1); } if (NULL != (env = getenv("FBFONT"))) fontfile = env; ng_init(); for (;;) { double val; c = getopt(argc, argv, "hMgvqkd:o:s:c:f:m:z:t:j:D:"); if (c == -1) break; switch (c) { case 'z': if(sscanf(optarg, "%lf", &val) == 1) { if(val < 0.1 || val > 10) fprintf(stderr, "gamma value is out of range. must be " "0.1 <= value <= 10.0\n"); else fbgamma = 1.0 / val; } break; case 'f': fontfile = optarg; break; case 'm': mode = optarg; break; case 'g': gray = 1; break; case 'M': matrox = 1; break; case 'k': keep_dma_on = 1; break; case 'v': debug++; ng_debug++; break; case 'q': quiet = -1; break; case 'd': fbdev = optarg; break; case 'o': snapbase = strdup(optarg); break; case 's': sscanf(optarg,"%dx%d",&ww,&hh); break; case 'c': ng_dev.video = optarg; break; case 'D': ng_dev.driver = optarg; break; case 't': if (optarg) vt = strtoul(optarg, 0, 0); else vt = 0; break; case 'j': joydev = optarg; break; case 'h': help = 1; break; default: fprintf(stderr, "Try '%s -h' for more information.\n", argv[0]); exit(1); } } if (help) { fprintf(stderr, "Usage:\n\t%s [options]\n\nwhere [options] are:\n\n", argv[0]); fprintf(stderr, "\t-h - print this text\n"); fprintf(stderr, "\t-M - enable Matrox mode\n"); fprintf(stderr, "\t-g - sets a gray colormap. Works only on 8 bits per pixel modes (256 color mode)\n"); fprintf(stderr, "\t-v - increase debug level\n"); fprintf(stderr, "\t-q - quiet mode: don't output any text at the framebuffer. Show just the camera stream\n"); fprintf(stderr, "\t-k - keep capture enabled when switching consoles\n"); fprintf(stderr, "\t-d - use as the framebuffer devicen"); fprintf(stderr, "\t-o - base string prefix for snapshot file names. Default: snap\n"); fprintf(stderr, "\t-s - V4L2 capture resolution. The is at x format, e. g. 800x600\n"); fprintf(stderr, "\t-c - use as video4linux device\n"); fprintf(stderr, "\t-f - use as the font console file. Not used on quiet mode. Default: lat1-16\n"); fprintf(stderr, "\t-m - framebuffer mode, as defined at /etc/fb.modes\n"); fprintf(stderr, "\t-z - Sets the Gamma value. It should be between 0.1 and 10.0\n"); fprintf(stderr, "\t-t [] - virtual tty to open\n"); fprintf(stderr, "\t-j - use as a joystick to control the capture\n"); fprintf(stderr, "\t-D - use as video4linux driver. Default: libv4l\n"); exit(1); } do_overlay = 1; if (!quiet) text_init(fontfile); fb = fb_init(fbdev,mode,vt); fb_catch_exit_signals(); fb_initcolors(fb,gray); fb_switch_init(); switch_last = fb_switch_state; fs_init_fb(15); if (matrox) if (-1 == gfx_init(fb)) matrox = 0; if (matrox) strcat(ng_v4l_conf," -y "); grabber_init(); freq_init(); read_config(NULL,NULL,NULL); if (0 != strlen(mixerdev)) { struct ng_attribute *attr; if (NULL != (attr = ng_mix_init(mixerdev,mixerctl))) add_attrs(attr); } /* set hooks (command.c) */ update_title = new_title; display_message = new_message; set_capture_hook = do_capture; exit_hook = do_exit; fullscreen_hook = do_fullscreen; memset(&act,0,sizeof(act)); act.sa_handler = ctrlc; sigemptyset(&act.sa_mask); sigaction(SIGINT,&act,&old); /* init hardware */ attr_init(); audio_on(); audio_init(); /* build channel list */ parse_config(1); channel_menu(); init_overlay(); if (optind+1 == argc) { do_va_cmd(2,"setstation",argv[optind]); } else { if ((f_drv & CAN_TUNE) && 0 != (freq = drv->getfreq(h_drv))) { for (i = 0; i < chancount; i++) if (chanlist[i].freq == freq*1000/16) { do_va_cmd(2,"setchannel",chanlist[i].name); break; } } if (-1 == cur_channel) { if (count > 0) do_va_cmd(2,"setstation","0"); else set_defaults(); } } /* keyboard, lirc + midi + joystick input support */ event_register_list(kbd_events); lirc = lirc_tv_init(); js = joystick_tv_init(joydev); #ifdef HAVE_ALSA fb_midi.fd = -1; if (midi) { if (-1 != midi_open(&fb_midi, "fbtv")) midi_connect(&fb_midi,midi); } #endif tty_init(); fb_memset(fb_mem+fb_mem_offset,0,fb_fix.smem_len); for (;!sig;) { if ((fb_switch_state == FB_ACTIVE || keep_dma_on) && !quiet) { if (message[0] != '\0') { strcpy(text1, message); } else { sprintf(text1, "Framebuffer TV - %s",default_title); } /* debugging + preformance monitoring */ switch (cur_capture) { case CAPTURE_GRABDISPLAY: sprintf(text1 + strlen(text1), " - grab %d.%d fps", fps / 5, (fps * 2) % 10); break; } /* display time */ time(&t); strftime(text2, 16, "%H:%M", localtime(&t)); if (dy >= f->height) { /* clear first lines */ fb_memset(fb_mem+fb_mem_offset,0,f->height*fb_fix.line_length); text_out(0,0,text1); text_out(fb_var.xres - text_width(text2) - f->width, 0, text2); } } if (switch_last != fb_switch_state) console_switch(); t1 = time(NULL); fps = 0; message[0] = '\0'; for (;!sig;) { FD_ZERO(&set); FD_SET(0,&set); fdmax = 1; if (lirc != -1) { FD_SET(lirc,&set); fdmax = MAX(fdmax,lirc+1); } if (js != -1) { FD_SET(js,&set); fdmax = MAX(fdmax,js+1); } #ifdef HAVE_ALSA if (fb_midi.fd != -1) { FD_SET(fb_midi.fd,&set); fdmax = MAX(fdmax,fb_midi.fd+1); } #endif if (cur_capture == CAPTURE_GRABDISPLAY && (fb_switch_state == FB_ACTIVE || keep_dma_on)) { fps++; /* grab + convert frame */ if (NULL == (buf = ng_grabber_grab_image(0))) { do_va_cmd(2,"capture","off"); if (mute) audio_off(); drv->close(h_drv); if (fb_switch_state == FB_ACTIVE) fb_memset(fb_mem+fb_mem_offset,0,fb_fix.smem_len); tty_cleanup(); fb_cleanup(); fprintf(stderr,"capturing image failed\n"); exit(1); } if (ch) buf = ng_convert_frame(ch,NULL,buf); /* blit frame */ src = buf->data; dst = fb_mem + dy * fb_fix.line_length + dx * ((fb_var.bits_per_pixel + 7)/8); linesize = buf->fmt.width * (ng_vfmt_to_depth[fmt.fmtid] / 8); /* Prevent writing at the next line */ if (linesize > fb_fix.line_length) linesize = fb_fix.line_length; for (ui = 0; ui < buf->fmt.height; ui++) { if ((char *)dst + linesize > (char *)fb_mem + fb_mem_offset + fb_fix.smem_len) break; memcpy(dst, src, linesize); src += buf->fmt.bytesperline; dst += fb_fix.line_length; } ng_release_video_buf(buf); tv.tv_sec = 0; tv.tv_usec = 0; rc = select(fdmax,&set,NULL,NULL,&tv); } else { tv.tv_sec = 6; tv.tv_usec = 0; rc = select(fdmax,&set,NULL,NULL,&tv); } /* If space is too short, overlay text at screen */ if ((fb_switch_state == FB_ACTIVE || keep_dma_on) && !quiet && dy < f->height) { text_out(0,0,text1); text_out(fb_var.xres - text_width(text2) - f->width, 0, text2); } err = errno; if (switch_last != fb_switch_state) console_switch(); if (-1 == rc && EINTR == err) { FD_ZERO(&set); continue; } if (rc > 0) break; t2 = time(NULL); if (t2 - t1 >= 5) { keypad_timeout(); break; } } if (FD_ISSET(0,&set)) { /* keyboard input */ switch (key = getch()) { case 27: /* ESC */ case 'q': case 'Q': sig=1; break; case 'x': case 'X': sig=1; mute=0; break; case -1: break; #if 0 /* debug */ case 'y': /* scaler_test(1); */ do_va_cmd(2,"capture","off"); do_va_cmd(2,"capture","grab"); break; #endif default: event[0] = 0; if (key > ' ' && key < 127) { /* as is */ sprintf(event,"kbd-key-%c",key); } else if (key >= KEY_F(0) && key <= KEY_F(12)) { /* function keys */ sprintf(event,"kbd-key-f%d",key - KEY_F(0)); } else { /* other special keys */ for (ui = 0; ui < NKEYTAB; ui++) { if (keytab[ui].key == key) break; } if (ui != NKEYTAB) sprintf(event,"kbd-key-%s",keytab[ui].name); } if (0 != event[0]) { event_dispatch(event); } else { sprintf(message,"unknown key: %d 0x%x ",key,key); } } } /* if (FD_ISSET(0,&set)) */ if (lirc != -1 && FD_ISSET(lirc,&set)) { /* lirc input */ if (-1 == lirc_tv_havedata()) { fprintf(stderr,"lirc: connection lost\n"); close(lirc); lirc = -1; } } if (js != -1 && FD_ISSET(js,&set)) { /* joystick input */ joystick_tv_havedata(js); } #ifdef HAVE_ALSA if (fb_midi.fd != -1 && FD_ISSET(fb_midi.fd,&set)) { /* midi input */ midi_read(&fb_midi); midi_translate(&fb_midi); } #endif } do_va_cmd(2,"capture","off"); if (mute) audio_off(); drv->close(h_drv); if (fb_switch_state == FB_ACTIVE) fb_memset(fb_mem+fb_mem_offset,0,fb_fix.smem_len); tty_cleanup(); fb_cleanup(); exit(0); } xawtv-3.106/console/font-6x11.h000066400000000000000000002045211343350355000161570ustar00rootroot00000000000000/**********************************************/ /* */ /* Font file generated by rthelen */ /* */ /**********************************************/ static unsigned char fontdata[] = { /* 0 0x00 '^A' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 1 0x01 '^B' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 2 0x02 '^C' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 3 0x03 '^D' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 4 0x04 '^E' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 5 0x05 '^F' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 6 0x06 '^G' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 7 0x07 '^H' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 8 0x08 '^I' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 9 0x09 '^J' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 10 0x0a '^K' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 11 0x0b '^L' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 12 0x0c '^M' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 13 0x0d '^N' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 14 0x0e '^O' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 15 0x0f '^P' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 16 0x10 '^Q' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 17 0x11 '^R' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x54, /* 0 0 0 00 */ 0x38, /* 00 000 */ 0x54, /* 0 0 0 00 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 18 0x12 '^S' */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x50, /* 0 0 0000 */ 0x50, /* 0 0 0000 */ 0x20, /* 00 00000 */ 0x20, /* 00 00000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 19 0x13 '^T' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x7c, /* 0 00 */ 0x38, /* 00 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 20 0x14 '^U' */ 0x18, /* 000 000 */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x7c, /* 0 00 */ 0x78, /* 0 000 */ 0x78, /* 0 000 */ 0x7c, /* 0 00 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 21 0x15 '^V' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 22 0x16 '^W' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 23 0x17 '^X' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 24 0x18 '^Y' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 25 0x19 '^Z' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 26 0x1a '^[' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 27 0x1b '^\' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 28 0x1c '^]' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 29 0x1d '^^' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 30 0x1e '^_' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 31 0x1f '^`' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 32 0x20 ' ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 33 0x21 '!' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 34 0x22 '"' */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 35 0x23 '#' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x7c, /* 0 00 */ 0x28, /* 00 0 000 */ 0x7c, /* 0 00 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 36 0x24 '$' */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x54, /* 0 0 0 00 */ 0x50, /* 0 0 0000 */ 0x38, /* 00 000 */ 0x14, /* 000 0 00 */ 0x54, /* 0 0 0 00 */ 0x38, /* 00 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 37 0x25 '%' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x54, /* 0 0 0 00 */ 0x58, /* 0 0 000 */ 0x28, /* 00 0 000 */ 0x34, /* 00 0 00 */ 0x54, /* 0 0 0 00 */ 0x48, /* 0 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 38 0x26 '&' */ 0x00, /* 00000000 */ 0x30, /* 00 0000 */ 0x48, /* 0 00 000 */ 0x50, /* 0 0 0000 */ 0x20, /* 00 00000 */ 0x54, /* 0 0 0 00 */ 0x48, /* 0 00 000 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 39 0x27 ''' */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 40 0x28 '(' */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x04, /* 00000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 41 0x29 ')' */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 42 0x2a '*' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x54, /* 0 0 0 00 */ 0x38, /* 00 000 */ 0x54, /* 0 0 0 00 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 43 0x2b '+' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x7c, /* 0 00 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 44 0x2c ',' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x30, /* 00 0000 */ 0x30, /* 00 0000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x00, /* 00000000 */ /* 45 0x2d '-' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 46 0x2e '.' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x18, /* 000 000 */ 0x18, /* 000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 47 0x2f '/' */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x20, /* 00 00000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x00, /* 00000000 */ /* 48 0x30 '0' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x54, /* 0 0 0 00 */ 0x64, /* 0 00 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 49 0x31 '1' */ 0x00, /* 00000000 */ 0x08, /* 0000 000 */ 0x18, /* 000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x1c, /* 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 50 0x32 '2' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 51 0x33 '3' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x04, /* 00000 00 */ 0x18, /* 000 000 */ 0x04, /* 00000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 52 0x34 '4' */ 0x00, /* 00000000 */ 0x08, /* 0000 000 */ 0x18, /* 000 000 */ 0x28, /* 00 0 000 */ 0x48, /* 0 00 000 */ 0x7c, /* 0 00 */ 0x08, /* 0000 000 */ 0x1c, /* 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 53 0x35 '5' */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x40, /* 0 000000 */ 0x78, /* 0 000 */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 54 0x36 '6' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x40, /* 0 000000 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 55 0x37 '7' */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 56 0x38 '8' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 57 0x39 '9' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x3c, /* 00 00 */ 0x04, /* 00000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 58 0x3a ':' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x18, /* 000 000 */ 0x18, /* 000 000 */ 0x00, /* 00000000 */ 0x18, /* 000 000 */ 0x18, /* 000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 59 0x3b ';' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x30, /* 00 0000 */ 0x30, /* 00 0000 */ 0x00, /* 00000000 */ 0x30, /* 00 0000 */ 0x30, /* 00 0000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x00, /* 00000000 */ /* 60 0x3c '<' */ 0x00, /* 00000000 */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x04, /* 00000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 61 0x3d '=' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 62 0x3e '>' */ 0x00, /* 00000000 */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 63 0x3f '?' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 64 0x40 '@' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x74, /* 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x78, /* 0 000 */ 0x40, /* 0 000000 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 65 0x41 'A' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 66 0x42 'B' */ 0x00, /* 00000000 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x78, /* 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 67 0x43 'C' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 68 0x44 'D' */ 0x00, /* 00000000 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x78, /* 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 69 0x45 'E' */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x78, /* 0 000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 70 0x46 'F' */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x78, /* 0 000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 71 0x47 'G' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x40, /* 0 000000 */ 0x4c, /* 0 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 72 0x48 'H' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 73 0x49 'I' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 74 0x4a 'J' */ 0x00, /* 00000000 */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 75 0x4b 'K' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x48, /* 0 00 000 */ 0x50, /* 0 0 0000 */ 0x60, /* 0 00000 */ 0x50, /* 0 0 0000 */ 0x48, /* 0 00 000 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 76 0x4c 'L' */ 0x00, /* 00000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 77 0x4d 'M' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x6c, /* 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 78 0x4e 'N' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x64, /* 0 00 00 */ 0x54, /* 0 0 0 00 */ 0x4c, /* 0 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 79 0x4f 'O' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 80 0x50 'P' */ 0x00, /* 00000000 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x78, /* 0 000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 81 0x51 'Q' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x54, /* 0 0 0 00 */ 0x38, /* 00 000 */ 0x04, /* 00000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 82 0x52 'R' */ 0x00, /* 00000000 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 83 0x53 'S' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x40, /* 0 000000 */ 0x38, /* 00 000 */ 0x04, /* 00000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 84 0x54 'T' */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 85 0x55 'U' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 86 0x56 'V' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 87 0x57 'W' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x6c, /* 0 0 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 88 0x58 'X' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 89 0x59 'Y' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 90 0x5a 'Z' */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x40, /* 0 000000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 91 0x5b '[' */ 0x0c, /* 0000 00 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x0c, /* 0000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 92 0x5c '\' */ 0x20, /* 00 00000 */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x02, /* 000000 0 */ 0x02, /* 000000 0 */ 0x00, /* 00000000 */ /* 93 0x5d ']' */ 0x30, /* 00 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x30, /* 00 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 94 0x5e '^' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 95 0x5f '_' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x7e, /* 0 0 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 96 0x60 '`' */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 97 0x61 'a' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 98 0x62 'b' */ 0x00, /* 00000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x78, /* 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 99 0x63 'c' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x40, /* 0 000000 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 100 0x64 'd' */ 0x00, /* 00000000 */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 101 0x65 'e' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x40, /* 0 000000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 102 0x66 'f' */ 0x00, /* 00000000 */ 0x0c, /* 0000 00 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 103 0x67 'g' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x3c, /* 00 00 */ 0x04, /* 00000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ /* 104 0x68 'h' */ 0x00, /* 00000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 105 0x69 'i' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x30, /* 00 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 106 0x6a 'j' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x30, /* 00 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x60, /* 0 00000 */ 0x00, /* 00000000 */ /* 107 0x6b 'k' */ 0x00, /* 00000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x48, /* 0 00 000 */ 0x50, /* 0 0 0000 */ 0x70, /* 0 0000 */ 0x48, /* 0 00 000 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 108 0x6c 'l' */ 0x00, /* 00000000 */ 0x30, /* 00 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 109 0x6d 'm' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x78, /* 0 000 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 110 0x6e 'n' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x58, /* 0 0 000 */ 0x64, /* 0 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 111 0x6f 'o' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 112 0x70 'p' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x78, /* 0 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x78, /* 0 000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x00, /* 00000000 */ /* 113 0x71 'q' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x3c, /* 00 00 */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x00, /* 00000000 */ /* 114 0x72 'r' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x58, /* 0 0 000 */ 0x64, /* 0 00 00 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 115 0x73 's' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x40, /* 0 000000 */ 0x38, /* 00 000 */ 0x04, /* 00000 00 */ 0x78, /* 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 116 0x74 't' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x0c, /* 0000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 117 0x75 'u' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 118 0x76 'v' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 119 0x77 'w' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 120 0x78 'x' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 121 0x79 'y' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x3c, /* 00 00 */ 0x04, /* 00000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ /* 122 0x7a 'z' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 123 0x7b '{' */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x04, /* 00000 00 */ 0x00, /* 00000000 */ /* 124 0x7c '|' */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 125 0x7d '}' */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x00, /* 00000000 */ /* 126 0x7e '~' */ 0x00, /* 00000000 */ 0x34, /* 00 0 00 */ 0x58, /* 0 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 127 0x7f '^?' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 128 0x80 '\200' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 129 0x81 '\201' */ 0x28, /* 00 0 000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 130 0x82 '\202' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 131 0x83 '\203' */ 0x10, /* 000 0000 */ 0x7c, /* 0 00 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x78, /* 0 000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 132 0x84 '\204' */ 0x58, /* 0 0 000 */ 0x44, /* 0 000 00 */ 0x64, /* 0 00 00 */ 0x54, /* 0 0 0 00 */ 0x4c, /* 0 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 133 0x85 '\205' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 134 0x86 '\206' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 135 0x87 '\207' */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 136 0x88 '\210' */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 137 0x89 '\211' */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 138 0x8a '\212' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 139 0x8b '\213' */ 0x34, /* 00 0 00 */ 0x58, /* 0 0 000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 140 0x8c '\214' */ 0x18, /* 000 000 */ 0x24, /* 00 00 00 */ 0x18, /* 000 000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 141 0x8d '\215' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x3c, /* 00 00 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x00, /* 00000000 */ /* 142 0x8e '\216' */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x40, /* 0 000000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 143 0x8f '\217' */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x40, /* 0 000000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 144 0x90 '\220' */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x40, /* 0 000000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 145 0x91 '\221' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x40, /* 0 000000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 146 0x92 '\222' */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 147 0x93 '\223' */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 148 0x94 '\224' */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 149 0x95 '\225' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 150 0x96 '\226' */ 0x34, /* 00 0 00 */ 0x58, /* 0 0 000 */ 0x00, /* 00000000 */ 0x58, /* 0 0 000 */ 0x64, /* 0 00 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 151 0x97 '\227' */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 152 0x98 '\230' */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 153 0x99 '\231' */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 154 0x9a '\232' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 155 0x9b '\233' */ 0x34, /* 00 0 00 */ 0x58, /* 0 0 000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 156 0x9c '\234' */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 157 0x9d '\235' */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 158 0x9e '\236' */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 159 0x9f '\237' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 160 0xa0 '\240' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 161 0xa1 '\241' */ 0x18, /* 000 000 */ 0x24, /* 00 00 00 */ 0x24, /* 00 00 00 */ 0x18, /* 000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 162 0xa2 '\242' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x54, /* 0 0 0 00 */ 0x50, /* 0 0 0000 */ 0x54, /* 0 0 0 00 */ 0x38, /* 00 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 163 0xa3 '\243' */ 0x30, /* 00 0000 */ 0x48, /* 0 00 000 */ 0x40, /* 0 000000 */ 0x70, /* 0 0000 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x44, /* 0 000 00 */ 0x78, /* 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 164 0xa4 '\244' */ 0x44, /* 0 000 00 */ 0x24, /* 00 00 00 */ 0x50, /* 0 0 0000 */ 0x48, /* 0 00 000 */ 0x24, /* 00 00 00 */ 0x14, /* 000 0 00 */ 0x48, /* 0 00 000 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 165 0xa5 '\245' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x7c, /* 0 00 */ 0x7c, /* 0 00 */ 0x7c, /* 0 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 166 0xa6 '\246' */ 0x3c, /* 00 00 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x3c, /* 00 00 */ 0x14, /* 000 0 00 */ 0x14, /* 000 0 00 */ 0x14, /* 000 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 167 0xa7 '\247' */ 0x18, /* 000 000 */ 0x24, /* 00 00 00 */ 0x44, /* 0 000 00 */ 0x48, /* 0 00 000 */ 0x48, /* 0 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x58, /* 0 0 000 */ 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 168 0xa8 '\250' */ 0x00, /* 00000000 */ 0x70, /* 0 0000 */ 0x08, /* 0000 000 */ 0x64, /* 0 00 00 */ 0x54, /* 0 0 0 00 */ 0x64, /* 0 00 00 */ 0x58, /* 0 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 169 0xa9 '\251' */ 0x00, /* 00000000 */ 0x70, /* 0 0000 */ 0x08, /* 0000 000 */ 0x34, /* 00 0 00 */ 0x44, /* 0 000 00 */ 0x34, /* 00 0 00 */ 0x08, /* 0000 000 */ 0x70, /* 0 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 170 0xaa '\252' */ 0x00, /* 00000000 */ 0x7a, /* 0 0 0 */ 0x2e, /* 00 0 0 */ 0x2e, /* 00 0 0 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 171 0xab '\253' */ 0x00, /* 00000000 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 172 0xac '\254' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 173 0xad '\255' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x08, /* 0000 000 */ 0x7c, /* 0 00 */ 0x10, /* 000 0000 */ 0x7c, /* 0 00 */ 0x20, /* 00 00000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 174 0xae '\256' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x50, /* 0 0 0000 */ 0x50, /* 0 0 0000 */ 0x78, /* 0 000 */ 0x50, /* 0 0 0000 */ 0x50, /* 0 0 0000 */ 0x5c, /* 0 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 175 0xaf '\257' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x54, /* 0 0 0 00 */ 0x64, /* 0 00 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 176 0xb0 '\260' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x6c, /* 0 0 00 */ 0x54, /* 0 0 0 00 */ 0x6c, /* 0 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 177 0xb1 '\261' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x7c, /* 0 00 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 178 0xb2 '\262' */ 0x00, /* 00000000 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 179 0xb3 '\263' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x1c, /* 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 180 0xb4 '\264' */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ 0x7c, /* 0 00 */ 0x10, /* 000 0000 */ 0x7c, /* 0 00 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 181 0xb5 '\265' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x48, /* 0 00 000 */ 0x48, /* 0 00 000 */ 0x48, /* 0 00 000 */ 0x48, /* 0 00 000 */ 0x74, /* 0 0 00 */ 0x40, /* 0 000000 */ 0x40, /* 0 000000 */ 0x00, /* 00000000 */ /* 182 0xb6 '\266' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x0c, /* 0000 00 */ 0x14, /* 000 0 00 */ 0x24, /* 00 00 00 */ 0x24, /* 00 00 00 */ 0x18, /* 000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 183 0xb7 '\267' */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x24, /* 00 00 00 */ 0x10, /* 000 0000 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x24, /* 00 00 00 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 184 0xb8 '\270' */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 185 0xb9 '\271' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 186 0xba '\272' */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x60, /* 0 00000 */ 0x00, /* 00000000 */ /* 187 0xbb '\273' */ 0x00, /* 00000000 */ 0x1c, /* 000 00 */ 0x24, /* 00 00 00 */ 0x24, /* 00 00 00 */ 0x1c, /* 000 00 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 188 0xbc '\274' */ 0x00, /* 00000000 */ 0x18, /* 000 000 */ 0x24, /* 00 00 00 */ 0x24, /* 00 00 00 */ 0x18, /* 000 000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 189 0xbd '\275' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ 0x6c, /* 0 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 190 0xbe '\276' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x54, /* 0 0 0 00 */ 0x5c, /* 0 0 00 */ 0x50, /* 0 0 0000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 191 0xbf '\277' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x4c, /* 0 00 00 */ 0x54, /* 0 0 0 00 */ 0x64, /* 0 00 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 192 0xc0 '\300' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ 0x40, /* 0 000000 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 193 0xc1 '\301' */ 0x00, /* 00000000 */ 0x08, /* 0000 000 */ 0x00, /* 00000000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 194 0xc2 '\302' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x04, /* 00000 00 */ 0x04, /* 00000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 195 0xc3 '\303' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x0c, /* 0000 00 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x50, /* 0 0 0000 */ 0x20, /* 00 00000 */ 0x20, /* 00 00000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 196 0xc4 '\304' */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x60, /* 0 00000 */ 0x00, /* 00000000 */ /* 197 0xc5 '\305' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x04, /* 00000 00 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 198 0xc6 '\306' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 199 0xc7 '\307' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x24, /* 00 00 00 */ 0x48, /* 0 00 000 */ 0x48, /* 0 00 000 */ 0x24, /* 00 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 200 0xc8 '\310' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x48, /* 0 00 000 */ 0x24, /* 00 00 00 */ 0x24, /* 00 00 00 */ 0x48, /* 0 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 201 0xc9 '\311' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x54, /* 0 0 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 202 0xca '\312' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 203 0xcb '\313' */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 204 0xcc '\314' */ 0x58, /* 0 0 000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 205 0xcd '\315' */ 0x58, /* 0 0 000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 206 0xce '\316' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x50, /* 0 0 0000 */ 0x50, /* 0 0 0000 */ 0x58, /* 0 0 000 */ 0x50, /* 0 0 0000 */ 0x50, /* 0 0 0000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 207 0xcf '\317' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x54, /* 0 0 0 00 */ 0x5c, /* 0 0 00 */ 0x50, /* 0 0 0000 */ 0x2c, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 208 0xd0 '\320' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 209 0xd1 '\321' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x7e, /* 0 0 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 210 0xd2 '\322' */ 0x00, /* 00000000 */ 0x14, /* 000 0 00 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 211 0xd3 '\323' */ 0x00, /* 00000000 */ 0x14, /* 000 0 00 */ 0x14, /* 000 0 00 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 212 0xd4 '\324' */ 0x00, /* 00000000 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x18, /* 000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 213 0xd5 '\325' */ 0x00, /* 00000000 */ 0x18, /* 000 000 */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 214 0xd6 '\326' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 215 0xd7 '\327' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 216 0xd8 '\330' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x3c, /* 00 00 */ 0x04, /* 00000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ /* 217 0xd9 '\331' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x7e, /* 0 0 */ 0x00, /* 00000000 */ 0x7e, /* 0 0 */ 0x00, /* 00000000 */ 0x7e, /* 0 0 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 218 0xda '\332' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 219 0xdb '\333' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 220 0xdc '\334' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 221 0xdd '\335' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 222 0xde '\336' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 223 0xdf '\337' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 224 0xe0 '\340' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 225 0xe1 '\341' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 226 0xe2 '\342' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 227 0xe3 '\343' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 228 0xe4 '\344' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 229 0xe5 '\345' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 230 0xe6 '\346' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 231 0xe7 '\347' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 232 0xe8 '\350' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 233 0xe9 '\351' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 234 0xea '\352' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 235 0xeb '\353' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 236 0xec '\354' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 237 0xed '\355' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 238 0xee '\356' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 239 0xef '\357' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 240 0xf0 '\360' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 241 0xf1 '\361' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 242 0xf2 '\362' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 243 0xf3 '\363' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 244 0xf4 '\364' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 245 0xf5 '\365' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 246 0xf6 '\366' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 247 0xf7 '\367' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 248 0xf8 '\370' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 249 0xf9 '\371' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 250 0xfa '\372' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 251 0xfb '\373' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 252 0xfc '\374' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 253 0xfd '\375' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 254 0xfe '\376' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 255 0xff '\377' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ }; xawtv-3.106/console/fs.c000066400000000000000000000230441343350355000151160ustar00rootroot00000000000000/* * text rendering for the framebuffer console * pick fonts from X11 font server or * use linux consolefont psf files. * (c) 2001 Gerd Knorr */ #include "config.h" #include #include #include #include #include #include #include "fbtools.h" #include "fs.h" /* ------------------------------------------------------------------ */ #define BIT_ORDER BitmapFormatBitOrderMSB #ifdef BYTE_ORDER #undef BYTE_ORDER #endif #define BYTE_ORDER BitmapFormatByteOrderMSB #define SCANLINE_UNIT BitmapFormatScanlineUnit8 #define SCANLINE_PAD BitmapFormatScanlinePad8 #define EXTENTS BitmapFormatImageRectMin #define SCANLINE_PAD_BYTES 1 #define GLWIDTHBYTESPADDED(bits, nBytes) \ ((nBytes) == 1 ? (((bits) + 7) >> 3) /* pad to 1 byte */\ :(nBytes) == 2 ? ((((bits) + 15) >> 3) & ~1) /* pad to 2 bytes */\ :(nBytes) == 4 ? ((((bits) + 31) >> 3) & ~3) /* pad to 4 bytes */\ :(nBytes) == 8 ? ((((bits) + 63) >> 3) & ~7) /* pad to 8 bytes */\ : 0) static const unsigned fs_masktab[] = { (1 << 7), (1 << 6), (1 << 5), (1 << 4), (1 << 3), (1 << 2), (1 << 1), (1 << 0), }; /* ------------------------------------------------------------------ */ static unsigned int bpp,black,white; static void (*setpixel)(void *ptr, unsigned int color); static void setpixel1(void *ptr, unsigned int color) { unsigned char *p = ptr; *p = color; } static void setpixel2(void *ptr, unsigned int color) { unsigned short *p = ptr; *p = color; } static void setpixel3(void *ptr, unsigned int color) { unsigned char *p = ptr; *(p++) = (color >> 16) & 0xff; *(p++) = (color >> 8) & 0xff; *(p++) = color & 0xff; } static void setpixel4(void *ptr, unsigned int color) { unsigned long *p = ptr; *p = color; } int fs_init_fb(int white8) { switch (fb_var.bits_per_pixel) { case 8: white = white8; black = 0; bpp = 1; setpixel = setpixel1; break; case 15: case 16: if (fb_var.green.length == 6) white = 0xffff; else white = 0x7fff; black = 0; bpp = 2; setpixel = setpixel2; break; case 24: white = 0xffffff; black = 0; bpp = fb_var.bits_per_pixel/8; setpixel = setpixel3; break; case 32: white = 0xffffff; black = 0; bpp = fb_var.bits_per_pixel/8; setpixel = setpixel4; break; default: fprintf(stderr, "Oops: %i bit/pixel ???\n", fb_var.bits_per_pixel); return -1; } return 0; } void fs_render_fb(unsigned char *ptr, int pitch, FSXCharInfo *charInfo, unsigned char *data) { int row,bit,bpr,x; bpr = GLWIDTHBYTESPADDED((charInfo->right - charInfo->left), SCANLINE_PAD_BYTES); for (row = 0; row < (charInfo->ascent + charInfo->descent); row++) { for (x = 0, bit = 0; bit < (charInfo->right - charInfo->left); bit++) { if (data[bit>>3] & fs_masktab[bit&7]) setpixel(ptr+x,white); x += bpp; } data += bpr; ptr += pitch; } } int fs_puts(struct fs_font *f, unsigned int x, unsigned int y, unsigned char *str) { unsigned char *pos,*start; int i,c,j,w; pos = fb_mem+fb_mem_offset; pos += fb_fix.line_length * y; for (i = 0; str[i] != '\0'; i++) { c = str[i]; if (NULL == f->eindex[c]) continue; /* clear with bg color */ start = pos + x*bpp + f->fontHeader.max_bounds.descent * fb_fix.line_length; w = (f->eindex[c]->width+1)*bpp; for (j = 0; j < f->height; j++) { memset(start,0,w); start += fb_fix.line_length; } /* draw char */ start = pos + x*bpp + fb_fix.line_length * (f->height-f->eindex[c]->ascent); fs_render_fb(start,fb_fix.line_length,f->eindex[c],f->gindex[c]); x += f->eindex[c]->width; if (x > fb_var.xres - f->width) return -1; } return x; } int fs_textwidth(struct fs_font *f, unsigned char *str) { int width = 0; int i,c; for (i = 0; str[i] != '\0'; i++) { c = str[i]; if (NULL == f->eindex[c]) continue; width += f->eindex[c]->width; } return width; } void fs_render_tty(FSXCharInfo *charInfo, unsigned char *data) { int bpr,row,bit,on; bpr = GLWIDTHBYTESPADDED((charInfo->right - charInfo->left), SCANLINE_PAD_BYTES); for (row = 0; row < (charInfo->ascent + charInfo->descent); row++) { fprintf(stdout,"|"); for (bit = 0; bit < (charInfo->right - charInfo->left); bit++) { on = data[bit>>3] & fs_masktab[bit&7]; fprintf(stdout,"%s",on ? "##" : " "); } fprintf(stdout,"|\n"); data += bpr; } fprintf(stdout,"--\n"); } /* ------------------------------------------------------------------ */ void fs_free(struct fs_font *f) { if (f->gindex) free(f->gindex); #if 0 /* FIXME */ if (f->glyphs) FSFree((char *) f->glyphs); #endif free(f); } /* ------------------------------------------------------------------ */ /* load console font file */ static char *default_font = "lat1-16"; /* * Depending on the distro, the console font could be on different * locations. Also, nowadays, they're typically gzipped to save some space. */ static char *default_path[] = { "/usr/share/consolefonts/%s.psfu.gz", "/usr/share/consolefonts/%s.psf.gz", "/usr/share/consolefonts/%s.psf", "/usr/share/consolefonts/%s", "/usr/share/kbd/consolefonts/%s.psfu.gz", "/usr/share/kbd/consolefonts/%s.psf.gz", "/usr/share/kbd/consolefonts/%s.psf", "/usr/share/kbd/consolefonts/%s", "/usr/lib/kbd/consolefonts/%s.psfu.gz", "/usr/lib/kbd/consolefonts/%s.psf.gz", "/usr/lib/kbd/consolefonts/%s.psf", "/usr/lib/kbd/consolefonts/%s", "/lib/kbd/consolefonts/%s.psfu.gz", "/lib/kbd/consolefonts/%s.psf.gz", "/lib/kbd/consolefonts/%s.psf", "/lib/kbd/consolefonts/%s", NULL }; static u_int32_t get_dword(FILE *fp, u_int32_t *dword) { *dword = fgetc(fp); *dword |= fgetc(fp) << 8; *dword |= fgetc(fp) << 16; if (feof(fp)) return 1; *dword |= fgetc(fp) << 24; return 0; } struct fs_font* fs_consolefont(char *filename) { int i; char *h, command[256], fname[251] = ""; u_int32_t magic, nchars, width, charlen, height, flags; struct fs_font *f = NULL; FILE *fp; if (!filename) filename = default_font; fprintf(stderr, "seeking for console font %s\n", filename); if (!strchr(filename, '/')) { for (i = 0; default_path[i] != NULL; i++) { snprintf(fname, sizeof(fname), default_path[i], filename); if (!access(fname, R_OK)) break; } } else { strcpy(fname, filename); } if (!*fname || access(fname, R_OK)) { fprintf(stderr,"can't find console font file\n"); return NULL; } h = fname + strlen(fname)-3; if (0 == strcmp(h,".gz")) { sprintf(command,"zcat %s", fname); fp = popen(command,"r"); } else { fp = fopen(fname, "r"); } if (NULL == fp) { fprintf(stderr,"can't open %s: %s\n", fname, strerror(errno)); return NULL; } if (get_dword(fp, &magic)) { fprintf(stderr,"Can't use font %s: file truncated\n", fname); return NULL; } if ((magic & 0xffff) == 0x0436) { flags = (magic & 0x020000L) ? 1 : 0; nchars = (magic & 0x010000L) ? 512 : 256; width = 8; charlen = magic >> 24; height = charlen; } else { u_int32_t psf_ver, hsize; if (magic != 0x864ab572L) { fprintf(stderr, "Can't use font %s: unknown psf version\n", fname); return NULL; } if (get_dword(fp, &psf_ver)) { fprintf(stderr, "Can't use font %s: file truncated\n", fname); return NULL; } if (psf_ver > 0) { fprintf(stderr,"Don't know how to handle psf version %d\n", psf_ver); return NULL; } if (get_dword(fp, &hsize)) { fprintf(stderr, "Can't use font %s: file truncated\n", fname); return NULL; } if (get_dword(fp, &flags)) { fprintf(stderr, "Can't use font %s: file truncated\n", fname); return NULL; } if (get_dword(fp, &nchars)) { fprintf(stderr, "Can't use font %s: file truncated\n", fname); return NULL; } if (get_dword(fp, &charlen)) { fprintf(stderr, "Can't use font %s: file truncated\n", fname); return NULL; } if (get_dword(fp, &height)) { fprintf(stderr, "Can't use font %s: file truncated\n", fname); return NULL; } if (get_dword(fp, &width)) { fprintf(stderr, "Can't use font %s: file truncated\n", fname); return NULL; } /* Skip any extra header bits */ while (hsize > 32) { fgetc(fp); --hsize; } } fprintf(stderr, "using linux console font \"%s\": %d gliphs %dx%d, char len %d%s\n", fname, nchars, width, height, charlen, flags & 1 ? " (unicode)" : ""); f = malloc(sizeof(*f)); memset(f,0,sizeof(*f)); f->maxenc = nchars; f->width = width; f->height = height; f->fontHeader.min_bounds.left = 0; f->fontHeader.max_bounds.right = f->width; f->fontHeader.max_bounds.descent = 0; f->fontHeader.max_bounds.ascent = f->height; f->glyphs = malloc(nchars * charlen); f->extents = malloc(sizeof(FSXCharInfo) * nchars); fread(f->glyphs, charlen, nchars, fp); /* * There is an unicode table at the end, for new PSF * format, if flags == 1. For now, just ignore it. */ fclose(fp); f->eindex = malloc(sizeof(FSXCharInfo*) * nchars); f->gindex = malloc(sizeof(unsigned char*) * nchars); for (i = 0; i < nchars; i++) { f->eindex[i] = f->extents + i; f->gindex[i] = f->glyphs + i * charlen; f->eindex[i]->left = 0; f->eindex[i]->right = width - 1; f->eindex[i]->width = width; f->eindex[i]->descent = 0; f->eindex[i]->ascent = f->height; } return f; } xawtv-3.106/console/fs.h000066400000000000000000000025211343350355000151200ustar00rootroot00000000000000typedef struct _FSXCharInfo { short left; short right; short width; short ascent; short descent; //unsigned short attributes; } FSXCharInfo; typedef struct _FSXFontInfoHeader { //int flags; //FSRange char_range; //unsigned draw_direction; //FSChar2b default_char; FSXCharInfo min_bounds; FSXCharInfo max_bounds; short font_ascent; short font_descent; } FSXFontInfoHeader; struct fs_font { FSXFontInfoHeader fontHeader; //unsigned char *propData; FSXCharInfo *extents; unsigned char *glyphs; int maxenc,width,height; FSXCharInfo **eindex; unsigned char **gindex; }; /* ------------------------------------------------------------------ */ int fs_init_fb(int white8); void fs_render_fb(unsigned char *ptr, int pitch, FSXCharInfo *charInfo, unsigned char *data); int fs_puts(struct fs_font *f, unsigned int x, unsigned int y, unsigned char *str); int fs_textwidth(struct fs_font *f, unsigned char *str); void fs_render_tty(FSXCharInfo *charInfo, unsigned char *data); #ifndef X_DISPLAY_MISSING int fs_connect(char *servername); struct fs_font* fs_open(char *pattern); #endif struct fs_font* fs_consolefont(char *filename); void fs_free(struct fs_font *f); xawtv-3.106/console/ftp.c000066400000000000000000000127451343350355000153050ustar00rootroot00000000000000/* * (c) 1998-2002 Gerd Knorr * * functions to handle ftp uploads using the ftp utility * */ #include "config.h" #define _GNU_SOURCE 1 #include #include #include #include #include #include #include #include #include "ftp.h" /* ---------------------------------------------------------------------- */ /* FTP stuff */ struct ftp_state { char *name; int connected; int debug; int pty, pid; char tty_name[32]; }; static int open_pty(struct ftp_state *s) { #ifdef HAVE_GETPT int master; char *slave; if (-1 == (master = getpt())) return -1; if (-1 == grantpt(master) || -1 == unlockpt(master) || NULL == (slave = ptsname(master))) { close(master); return -1; } strcpy(s->tty_name,slave); return master; #else static char pty_name[32]; static char s1[] = "pqrs"; static char s2[] = "0123456789abcdef"; char *p1,*p2; int pty; for (p1 = s1; *p1; p1++) { for (p2 = s2; *p2; p2++) { sprintf(pty_name,"/dev/pty%c%c",*p1,*p2); sprintf(s->tty_name,"/dev/tty%c%c",*p1,*p2); if (-1 == access(s->tty_name,R_OK|W_OK)) continue; if (-1 != (pty = open(pty_name,O_RDWR))) return pty; } } return -1; #endif } struct ftp_state* ftp_init(char *name, int autologin, int passive, int debug) { static char *doauto[] = { "ftp", NULL }; /* allow autologin via ~/.netrc */ static char *noauto[] = { "ftp", "-n", NULL }; struct ftp_state *s; s = malloc(sizeof(*s)); memset(s,0,sizeof(*s)); s->name = name; s->debug = debug; if (-1 == (s->pty = open_pty(s))) { fprintf(stderr,"can't grab pty\n"); exit(1); } switch (s->pid = fork()) { case -1: perror("fork"); exit(1); case 0: /* child */ close(s->pty); close(0); close(1); close(2); setsid(); open(s->tty_name,O_RDWR); dup(0); dup(0); /* need english messages from ftp */ setenv("LC_ALL","C",1); if (autologin) execvp(doauto[0],doauto); else execvp(noauto[0],noauto); perror("execvp"); exit(1); default: /* parent */ break; } ftp_recv(s); /* initialisation */ if (passive) { ftp_send(s,1,"pass"); ftp_recv(s); } return s; } void ftp_send(struct ftp_state *s, int argc, ...) { va_list ap; char line[256],*arg; int length,i; va_start(ap,argc); memset(line,0,256); length = 0; for (i = 0; i < argc; i++) { if (i) line[length++] = ' '; arg = va_arg(ap,char*); length += strlen(arg); strcat(line,arg); } line[length++] = '\n'; va_end (ap); if (s->debug) fprintf(stderr,"[%s]>> %s",s->name,line); if (length != write(s->pty,line,length)) { fprintf(stderr,"ftp: write error\n"); exit(1); } } int ftp_recv(struct ftp_state *s) { char line[512],*p,*n; int length, done, status, ret=0; fd_set set; for (done = 0; !done;) { FD_ZERO(&set); FD_SET(s->pty,&set); select(s->pty+1,&set,NULL,NULL,NULL); switch (length = read(s->pty,line,511)) { case -1: perror("ftp: read error"); exit(1); case 0: fprintf(stderr,"ftp: EOF\n"); exit(1); } line[length] = 0; for (p=line; p && *p; p = n) { /* split into lines */ if (NULL != (n = strchr(p,'\n')) || NULL != (n = strchr(p,'\r'))) *(n++) = 0; else n = NULL; if (s->debug) fprintf(stderr,"[%s]<< %s\n",s->name,p); /* prompt? */ if (NULL != strstr(p,"ftp>")) { done = 1; } /* line dropped ? */ if (NULL != strstr(p,"closed connection")) { fprintf(stderr,"ftp: lost connection\n"); s->connected = 0; } if (NULL != strstr(p,"Not connected")) { if (!ftp_connected(s)) fprintf(stderr,"ftp: lost connection\n"); s->connected = 0; } /* status? */ if (1 == sscanf(p,"%d",&status)) { ret = status; } } } return ret; } void ftp_connect(struct ftp_state *s, char *host, char *user, char *pass, char *dir) { int delay = 0, status; for (;;) { /* Wiederholungsversuche mit wachsendem Intervall, 10 min max. */ if (delay) { fprintf(stderr,"ftp: connect failed, sleeping %d sec\n",delay); sleep(delay); delay *= 2; if (delay > 600) delay = 600; } else { delay = 5; } /* (re-) connect */ ftp_send(s,1,"close"); ftp_recv(s); ftp_send(s,2,"open",host); status = ftp_recv(s); if (230 == status) { fprintf(stderr,"ftp: connected to %s, login ok\n",host); s->connected = 1; goto login_ok; } if (220 != status && 530 != status) continue; fprintf(stderr,"ftp: connected to %s\n",host); s->connected = 1; /* login */ ftp_send(s,3,"user",user,pass); if (230 != ftp_recv(s)) { if (!ftp_connected(s)) continue; fprintf(stderr,"ftp: login incorrect\n"); exit(1); } login_ok: /* set directory */ ftp_send(s,2,"cd",dir); if (250 != ftp_recv(s)) { if (!s->connected) continue; fprintf(stderr,"ftp: cd %s failed\n",dir); exit(1); } /* initialisation */ ftp_send(s,1,"bin"); ftp_recv(s); ftp_send(s,1,"umask 022"); ftp_recv(s); /* ok */ break; } } int ftp_connected(struct ftp_state *s) { return s->connected; } void ftp_upload(struct ftp_state *s, char *local, char *remote, char *tmp) { ftp_send(s,3,"put",local,tmp); ftp_recv(s); ftp_send(s,3,"rename",tmp,remote); ftp_recv(s); } void ftp_fini(struct ftp_state *s) { ftp_send(s,1,"bye"); ftp_recv(s); kill(s->pid,SIGTERM); close(s->pty); free(s); } xawtv-3.106/console/ftp.h000066400000000000000000000006571343350355000153110ustar00rootroot00000000000000extern int ftp_debug; struct ftp_state* ftp_init(char *name, int autologin, int passive, int debug); void ftp_send(struct ftp_state* s, int argc, ...); int ftp_recv(struct ftp_state* s); void ftp_connect(struct ftp_state* s, char *host, char *user, char *pass, char *dir); int ftp_connected(struct ftp_state *s); void ftp_upload(struct ftp_state* s, char *local, char *remote, char *tmp); void ftp_fini(struct ftp_state *s); xawtv-3.106/console/matrox.c000066400000000000000000000147431343350355000160260ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include "byteswap.h" #include "fbtools.h" #include "matrox.h" /* ---------------------------------------------------------------------- */ /* generic */ void (*gfx_scaler_on)(int offscreen, int pitch, int width, int height, int left, int right, int top, int bottom); void (*gfx_scaler_off)(void); static unsigned char *bmmio; static uint32_t *mmio; static void wrio4(int adr, unsigned long val) { #if BYTE_ORDER == LITTLE_ENDIAN mmio[adr] = val; #else mmio[adr] = SWAP4(val); #endif /* usleep(10); */ } /* ---------------------------------------------------------------------- */ /* Matrox G200/G400 */ #define BES_BASE 0x3d00 #define BESA1ORG ((BES_BASE+0x00)>>2) #define BESA2ORG ((BES_BASE+0x04)>>2) #define BESB1ORG ((BES_BASE+0x08)>>2) #define BESB2ORG ((BES_BASE+0x0c)>>2) #define BESA1CORG ((BES_BASE+0x10)>>2) #define BESA2CORG ((BES_BASE+0x14)>>2) #define BESB1CORG ((BES_BASE+0x18)>>2) #define BESB2CORG ((BES_BASE+0x1c)>>2) #define BESCTL ((BES_BASE+0x20)>>2) #define BESPITCH ((BES_BASE+0x24)>>2) #define BESHCOORD ((BES_BASE+0x28)>>2) #define BESVCOORD ((BES_BASE+0x2c)>>2) #define BESHISCAL ((BES_BASE+0x30)>>2) #define BESVISCAL ((BES_BASE+0x34)>>2) #define BESHSRCST ((BES_BASE+0x38)>>2) #define BESHSRCEND ((BES_BASE+0x3c)>>2) #define BESV1WGHT ((BES_BASE+0x48)>>2) #define BESV2WGHT ((BES_BASE+0x4c)>>2) #define BESHSRCLST ((BES_BASE+0x50)>>2) #define BESV1SRCLST ((BES_BASE+0x54)>>2) #define BESV2SRCLST ((BES_BASE+0x58)>>2) #define BESGLOBCTL ((BES_BASE+0xc0)>>2) #define BESSTATUS ((BES_BASE+0xc4)>>2) #define PALWTADD 0x3c00 #define X_DATAREG 0x3c0a #define XKEYOPMODE 0x51 static void matrox_scaler_on(int offscreen, int pitch, int width, int height, int left, int right, int top, int bottom) { /* color keying (turn it off) */ bmmio[PALWTADD] = XKEYOPMODE; bmmio[X_DATAREG] = 0; /* src */ wrio4(BESA1ORG, offscreen); wrio4(BESA2ORG, offscreen); wrio4(BESB1ORG, offscreen); wrio4(BESB2ORG, offscreen); wrio4(BESPITCH, pitch/2); /* dest */ wrio4(BESHCOORD, (left << 16) | right); wrio4(BESVCOORD, (top << 16) | bottom); /* scale horiz */ wrio4(BESHISCAL, width*65536/(right-left) & 0x001ffffc); wrio4(BESHSRCST, 0 << 16); wrio4(BESHSRCEND, width << 16); wrio4(BESHSRCLST, (width-1) << 16); /* scale vert */ wrio4(BESVISCAL, height*65536/(bottom-top) & 0x001ffffc); wrio4(BESV1WGHT, 0); wrio4(BESV2WGHT, 0); wrio4(BESV1SRCLST, height-1); wrio4(BESV2SRCLST, height-1); /* turn on (enable, horizontal+vertical interpolation filters */ wrio4(BESCTL, (1 << 0) | (1 << 10) | (1 << 11)); wrio4(BESGLOBCTL, 0); } static void matrox_scaler_off(void) { /* turn off */ wrio4(BESCTL, 0); } /* ---------------------------------------------------------------------- */ /* ATI Mach64 VT+GT */ #define OVERLAY_X_Y_START 0x0000 #define OVERLAY_X_Y_END 0x0001 #define OVERLAY_VIDEO_KEY_CLR 0x0002 #define OVERLAY_VIDEO_KEY_MSK 0x0003 #define OVERLAY_GRAPHICS_KEY_CLR 0x0004 #define OVERLAY_GRAPHICS_KEY_MSK 0x0005 #define OVERLAY_KEY_CNTL 0x0006 #define OVERLAY_SCALE_INC 0x0008 #define OVERLAY_SCALE_CNTL 0x0009 #define SCALER_HEIGHT_WIDTH 0x000a #define SCALER_TEST 0x000b #define SCALER_BUF0_OFFSET 0x000d #define SCALER_BUF1_OFFSET 0x000e #define SCALER_BUF_PITCH 0x000f #define VIDEO_FORMAT 0x0012 #define CAPTURE_CONFIG 0x0014 #define SCALER_COLOR_CNTL 0x0054 #define SCALER_H_COEFF0 0x0055 #define SCALER_H_COEFF1 0x0056 #define SCALER_H_COEFF2 0x0057 #define SCALER_H_COEFF3 0x0058 #define SCALER_H_COEFF4 0x0059 /* does'nt work for all color depth yet... */ static void mach64_scaler_on(int offscreen, int pitch, int width, int height, int left, int right, int top, int bottom) { int v,h; v = (height << 12) / (bottom-top); h = (width << 12) / (right-left); wrio4(OVERLAY_SCALE_CNTL, 0); wrio4(OVERLAY_SCALE_INC, (h << 16) | v); wrio4(VIDEO_FORMAT, (12 << 16)); wrio4(SCALER_BUF0_OFFSET, offscreen); wrio4(SCALER_BUF1_OFFSET, offscreen); wrio4(SCALER_BUF_PITCH, pitch/2); wrio4(SCALER_HEIGHT_WIDTH, (width << 16) | height); wrio4(CAPTURE_CONFIG, 0); #if 1 /* from gatos, don't know what this does, have no specs :-( */ wrio4(SCALER_COLOR_CNTL, 0x00101000); wrio4(SCALER_H_COEFF0, 0x00002000); wrio4(SCALER_H_COEFF1, 0x0D06200D); wrio4(SCALER_H_COEFF2, 0x0D0A1C0D); wrio4(SCALER_H_COEFF3, 0x0C0E1A0C); wrio4(SCALER_H_COEFF4, 0x0C14140C); #endif wrio4(OVERLAY_X_Y_START, (left << 16) | top); wrio4(OVERLAY_X_Y_END, ((right-1) << 16) | (bottom-1)); wrio4(OVERLAY_VIDEO_KEY_MSK, 0); wrio4(OVERLAY_VIDEO_KEY_CLR, 0); wrio4(OVERLAY_KEY_CNTL, 1); wrio4(SCALER_TEST, 0); /* 2 == test mode */ wrio4(OVERLAY_SCALE_CNTL, (1<<31) | (1<<30)); } static void mach64_scaler_off(void) { /* off */ wrio4(OVERLAY_SCALE_CNTL, 0); } /* ---------------------------------------------------------------------- */ /* generic */ int gfx_init(int fd) { int off; switch (fb_fix.accel) { case FB_ACCEL_MATROX_MGAG200: #ifdef FB_ACCEL_MATROX_MGAG400 case FB_ACCEL_MATROX_MGAG400: #endif gfx_scaler_on = matrox_scaler_on; gfx_scaler_off = matrox_scaler_off; break; case FB_ACCEL_ATI_MACH64VT: case FB_ACCEL_ATI_MACH64GT: gfx_scaler_on = mach64_scaler_on; gfx_scaler_off = mach64_scaler_off; break; default: return -1; } fb_var.accel_flags = 0; if (0 != ioctl(fd,FBIOPUT_VSCREENINFO,&fb_var)) { perror("FBIOPUT_VSCREENINFO"); return -1; } bmmio = mmap(NULL, fb_fix.mmio_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, fb_fix.smem_len); if ((void*)-1 == bmmio) { perror("mmap"); return -1; } off = (unsigned long)fb_fix.mmio_start - ((unsigned long)fb_fix.mmio_start & ~(getpagesize()-1)); bmmio += off; mmio = (uint32_t*)bmmio; return 0; } xawtv-3.106/console/matrox.h000066400000000000000000000003041343350355000160170ustar00rootroot00000000000000extern int gfx_init(int fd); extern void (*gfx_scaler_on)(int offscreen, int pitch, int width, int height, int left, int right, int top, int bottom); extern void (*gfx_scaler_off)(void); xawtv-3.106/console/radio.c000066400000000000000000000733441343350355000156140ustar00rootroot00000000000000/* * radio.c - (c) 1998-2001 Gerd Knorr * (c) 2012 Hans de Goede * * test tool for bttv + WinTV/Radio * */ /* Changes: * 20 Jun 99 - Juli Merino (JMMV) - Added some features: * visual menu, manual 'go to' function, negative symbol and a * good interface. See code for more details. * 30 Aug 2001 - Gunther Mayer * Scan for Stations, ad-hoc algorithm for signal strength * analysis. My Temic 4009FR5 finds all 19 stations here, * a Samsung TPI8PSB02P misses two stations below 90MHz, * which are received fine, but the tuner doesn't indicate * signal strength. * 19 May 2012 - Hans de Goede - Add support for looping back sound using alsa * 28 May 2012 - Hans de Goede - Various UI improvements * 8 Jul 2012 - Hans de Goede - Add support for multi-band tuners */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "videodev2.h" #include "alsa_stream.h" #include "get_media_devices.h" #define FREQ_MIN (bands[band].rangelow * (1e6 / freqfact)) #define FREQ_MAX (bands[band].rangehigh * (1e6 / freqfact)) #define FREQ_STEP ((bands[band].rangelow > (50 * freqfact)) ? \ 50000 : ((bands[band].rangelow > (10 * freqfact)) ? \ 10000 : 1000)) #define FREQ_MIN_KHZ (bands[band].rangelow * (1e3 / freqfact)) #define FREQ_MAX_KHZ (bands[band].rangehigh * (1e3 / freqfact)) #define FREQ_STEP_KHZ ((FREQ_STEP) / 1e3) #define FREQ_MIN_MHZ ((float)bands[band].rangelow / freqfact) #define FREQ_MAX_MHZ ((float)bands[band].rangehigh / freqfact) #define FREQ_STEP_MHZ ((FREQ_STEP) / 1e6) #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX_STATIONS 100 #define MAX_BANDS 32 /* Latency is not a big problem for radio (no video to sync with), and USB radio devices benefit from a larger default latency */ #define DEFAULT_LATENCY 500 int alsa_loopback = 1; #if defined(HAVE_ALSA) char *alsa_playback = NULL; char *alsa_capture = NULL; int alsa_latency = DEFAULT_LATENCY; #endif /* JMMV: WINDOWS for radio */ int ncurses = 0; int debug = 0; char *device = "/dev/radio0"; WINDOW *wfreq, *woptions, *wstations, *wcommand, *whelp, *wbands; struct v4l2_tuner tuner; struct v4l2_frequency_band bands[MAX_BANDS]; int band = -1; int no_bands; int freqfact = 16; /* ffreq-in-Mhz * freqfact == v4l2-freq */ static int radio_getfreq(int fd, int *ifreq) { struct v4l2_frequency frequency; memset (&frequency, 0, sizeof(frequency)); frequency.type = V4L2_TUNER_RADIO; if (-1 == ioctl(fd, VIDIOC_G_FREQUENCY, &frequency)) { perror("VIDIOC_G_FREQUENCY"); return errno; } *ifreq = frequency.frequency * (1e6 / freqfact); return 0; } static int radio_setfreq(int fd, int *ifreq) { struct v4l2_frequency frequency; memset (&frequency, 0, sizeof(frequency)); frequency.type = V4L2_TUNER_RADIO; frequency.frequency = *ifreq * (freqfact / 1e6); if (ioctl(fd, VIDIOC_S_FREQUENCY, &frequency) == -1) { perror("VIDIOC_S_FREQUENCY"); return errno; } radio_getfreq(fd, ifreq); return 0; } /* * Perform a hw_seek, dir = 0 = down, 1 = up, Returns 0 and the new freq * in ifreq on a successful seek. Returns non 0 and leaves ifreq untouched * if the seek fails. */ static int radio_seek(int fd, int dir, int *ifreq) { struct v4l2_hw_freq_seek seek; memset(&seek, 0, sizeof(seek)); seek.type = V4L2_TUNER_RADIO; seek.seek_upward = dir; seek.rangelow = bands[band].rangelow; seek.rangehigh = bands[band].rangehigh; if (tuner.capability & V4L2_TUNER_CAP_HWSEEK_WRAP) seek.wrap_around = 1; seek.spacing = FREQ_STEP_MHZ * freqfact; if (seek.spacing < 1) seek.spacing = 1; if (-1 == ioctl(fd, VIDIOC_S_HW_FREQ_SEEK, &seek)) { if (errno != ENODATA) perror("VIDIOC_G_FREQUENCY"); return errno; } return radio_getfreq(fd, ifreq); } static void radio_mute(int fd, int mute, int alsa_loopback) { struct v4l2_control ctrl; int res; memset (&ctrl, 0, sizeof(ctrl)); ctrl.id = V4L2_CID_AUDIO_MUTE; ctrl.value = mute; res = ioctl(fd, VIDIOC_S_CTRL, &ctrl); if (res == -1 && errno != EINVAL && errno != ENOTTY) perror("VIDIOC_S_CTRL"); #if defined(HAVE_ALSA) if (alsa_loopback) { if (mute) alsa_thread_stop(); else alsa_thread_startup(alsa_playback, alsa_capture, alsa_latency, stderr, debug); } #endif } static int radio_getsignal_n_stereo(int fd) { struct v4l2_tuner tuner; int i, asterisks; memset (&tuner, 0, sizeof(tuner)); if (ioctl (fd, VIDIOC_G_TUNER, &tuner) == -1) { if (ncurses) { mvwprintw(wfreq, 2, 1, " "); mvwprintw(wfreq, 3, 1, " "); } perror("VIDIOC_G_TUNER"); return 0; } if (ncurses) { mvwprintw(wfreq, 2, 1, (tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? "STEREO" : " MONO "); /* Draw 0 - 6 asterisks for signal strength */ asterisks = (tuner.signal * 6 + 32767) / 65535; for (i = 0; i < 6; i++) mvwprintw(wfreq, 3, i + 1, "%s", i < asterisks ? "*" : " "); } return tuner.signal; } static int select_wait(int sec) { struct timeval tv; fd_set se; FD_ZERO(&se); FD_SET(0,&se); tv.tv_sec = sec; tv.tv_usec = 0; return select(1,&se,NULL,NULL,&tv); } /* ---------------------------------------------------------------------- */ int fkeys[8]; /* Hotkey preset frequencies in Hz! */ int fkeybands[8]; /* Hotkey preset bands */ int p_bands[MAX_STATIONS];/* Preset stations bands */ int p_freqs[MAX_STATIONS];/* Preset frequencies in Hz! */ char *labels[MAX_STATIONS]; /* Preset labels */ int stations; /* Number of valid presets */ static int find_station(int ifreq) { int i; for (i = 0; i < stations; i++) { if (ifreq == p_freqs[i]) return i; } return -1; } static char *find_label(int ifreq) { int i = find_station(ifreq); return (i == -1) ? NULL : labels[i]; } static char *make_label(int band, int ifreq) { static char text[20]; /* We show bands < 2 MHz in kHz */ if (bands[band].rangehigh < (2 * freqfact)) sprintf(text, "%6.1f", ifreq / 1e3); else sprintf(text, "%6.2f", ifreq / 1e6); return text; } static char *modulation_label(int band) { static char buf[20]; buf[0] = 0; if (bands[band].modulation & V4L2_BAND_MODULATION_VSB) strcat(buf, " VSB"); /* Note this would be really funky for radio */ if (bands[band].modulation & V4L2_BAND_MODULATION_FM) strcat(buf, " FM"); if (bands[band].modulation & V4L2_BAND_MODULATION_AM) strcat(buf, " AM"); return buf; } char *digit[3][10] = { { " _ ", " ", " _ ", " _ ", " ", " _ ", " _ ", " _ ", " _ ", " _ " }, { "| |", " | ", " _|", " _|", "|_|", "|_ ", "|_ ", " |", "|_|", "|_|" }, { "|_|", " | ", "|_ ", " _|", " |", " _|", "|_|", " |", "|_|", " _|" } }; static void print_freq(int band, int ifreq, int muted) { int x,y,i; char *name, *text, status[20] = ""; text = make_label(band, ifreq); for (i = 0, x = 8; i < 6; i++, x+=4) { if (text[i] >= '0' && text[i] <= '9') { for (y = 0; y < 3; y++) mvwprintw(wfreq, y + 1, x, "%s", digit[y][text[i] - '0']); } else if (text[i] == '.') { x--; for (y = 0; y < 3; y++) mvwprintw(wfreq, y + 1, x, (y == 2) ? " . " : " "); x--; } else { for (y = 0; y < 3; y++) mvwprintw(wfreq, y + 1, x, " "); } } if (muted) snprintf(status, sizeof(status), "muted%s", modulation_label(band)); else snprintf(status, sizeof(status), "%s", modulation_label(band)); mvwprintw(wfreq, 4, 2, "%28.28s", status); if (NULL != (name = find_label(ifreq))) mvwprintw(wfreq, 5, 2, "%-20.20s", name); else mvwprintw(wfreq, 5, 2, "%-20.20s", ""); wrefresh(wfreq); } /* ---------------------------------------------------------------------- */ static int check_band_n_freq(int *band, int ifreq, const char *extra_msg) { unsigned int v4l2_f = ifreq * (freqfact / 1e6); int i, largest_band = 0; if (*band == -1) { *band = 0; for (i = 0; i < no_bands; i++) { if (v4l2_f >= bands[i].rangelow && v4l2_f <= bands[i].rangehigh) { if ((bands[i].rangehigh - bands[i].rangelow) > largest_band) { largest_band = bands[i].rangehigh - bands[i].rangelow; *band = i; } } } } else if (*band < 0 || *band >= no_bands) { fprintf(stderr, "Invalid band '%d'%s\n", *band, extra_msg); return -1; } if (v4l2_f < bands[*band].rangelow || v4l2_f > bands[*band].rangehigh) { fprintf(stderr, "Invalid freq '%d'%s\n", ifreq, extra_msg); return -1; } return 0; } static void add_fkey(int band, int ifreq, char n) { if (check_band_n_freq(&band, ifreq, " in config file, ignoring")) return; if (n < '1' || n > '8') { fprintf(stderr, "Invalid function key char '%c' in config file, ignoring\n", n); return; } fkeys[n - '1'] = ifreq; fkeybands[n - '1'] = band; } static void add_station(int band, int ifreq, const char *name) { if (check_band_n_freq(&band, ifreq, " in config file, ignoring")) return; if (stations < MAX_STATIONS) { p_bands[stations] = band; p_freqs[stations] = ifreq; labels[stations] = strdup(name); stations++; } else { fprintf(stderr, "Station limit (%d) exceeded, ignoring station '%s'\n", MAX_STATIONS, name); } } static void read_kradioconfig(void) { char name[80], file[256], n; int i, band, ifreq; FILE *fp; sprintf(file, "%.225s/.kde/share/config/kradiorc", getenv("HOME")); if (NULL == (fp = fopen(file,"r"))) { sprintf(file, "%.225s/.radio", getenv("HOME")); if (NULL == (fp = fopen(file,"r"))) return; } while (fgets(file, sizeof(file), fp) != NULL) { if (sscanf(file,"%c=%d:%d", &n, &band, &ifreq) == 3) add_fkey(band - 1, ifreq, n); else if (sscanf(file,"%c=%d", &n, &ifreq) == 2) add_fkey(-1, ifreq, n); else if (sscanf(file,"%d:%d=%30[^\n]", &band, &ifreq, name) == 3) add_station(band - 1, ifreq, name); else if (sscanf(file,"%d=%30[^\n]", &ifreq, name) == 2) add_station(-1, ifreq, name); } fclose(fp); /* If no hotkeys were specified, bind the first 8 presets to 1 - 8 */ for (i = 0; i < 8; i++) if (fkeys[i]) break; if (i == 8) { for (i = 0; i < 8 && i < stations; i++) { fkeys[i] = p_freqs[i]; fkeybands[i] = p_bands[i]; } } } /* ---------------------------------------------------------------------- */ /* autoscan */ float *g, baseline; int g_len, astation[MAX_STATIONS]; static void foundone(int m) { float freq = FREQ_MIN_MHZ + m * FREQ_STEP_MHZ; int i; for (i = 0; i < stations; i++) { /* Assume stations less then 5 steps apart are the same station */ if (abs(astation[i] - m) < 5) break; } if (i == MAX_STATIONS) { fprintf(stderr, "Station limit (%d) exceeded, ignoring station at %6.2f MHz\n", MAX_STATIONS, freq); return; } /* If new or bigger signal add the found station */ if (i == stations || g[m] > g[astation[i]]) { if (i == stations) stations = i + 1; astation[i] = m; fprintf(stderr, "Station %2d: %6.2f MHz - %.2f\n", i, freq, g[m]); } } static void maxi(int m) { int i, l, r; float freq, halbwert; if (debug) { freq = FREQ_MIN_MHZ + m * FREQ_STEP_MHZ; fprintf(stderr,"maxi i %d %f %f\n", m, freq, g[m]); } if (g[m] < baseline) return; halbwert = (g[m] - baseline) / 2 + baseline; for(i = m; i > 0; i--) if (g[i] < halbwert) break; l = i; if (debug) { freq = FREQ_MIN_MHZ + i * FREQ_STEP_MHZ; fprintf(stderr, "Left i %d %f %f\n", i, freq, g[i]); } for(i = m; i < g_len; i++) if (g[i] < halbwert) break; if (debug) { freq = FREQ_MIN_MHZ + i * FREQ_STEP_MHZ; fprintf(stderr, "Right i %d %f %f\n", i, freq, g[i]); } r = i; m = (l + r) / 2; if (debug) { freq = FREQ_MIN_MHZ + m * FREQ_STEP_MHZ; fprintf(stderr, "Middle m %d %f %f\n", m, freq, g[m]); } foundone(m); } static void findmax(void) { int i; for (i = 0; i < g_len - 1; i++) { if (g[i + 1] < g[i]) maxi(i); } } // find the baseline for this tuners signal strength static float get_baseline(float ming, float maxg) { int unt, i; float nullinie = 0, u; if (debug) fprintf(stderr, "get_baseline: min=%f max=%f\n", ming, maxg); for (u = ming; u < maxg; u += 0.1) { unt = 0; for (i = 0; i < g_len; i++) if (g[i] < u) { unt++; } if (unt > (g_len * 7 / 8)) { fprintf(stderr, "baseline at %.2f\n", u); nullinie = u; break; } if (debug) fprintf(stderr, "%f %d\n", u, unt); } return nullinie; } static void findstations(void) { float maxg = 0, ming = 65536; int i; for (i = 0; i < g_len; i++) { if (g[i] < ming) ming = g[i]; if (g[i] > maxg) maxg = g[i]; } baseline = get_baseline(ming, maxg); findmax(); } static void do_scan(int fd, int scan, int write_config) { FILE * fmap=NULL; int i, j, s, ifreq; char name[80]; if (scan > 1) fmap = fopen("radio.fmmap","w"); g_len = (FREQ_MAX - FREQ_MIN) / FREQ_STEP + 1; g = malloc(g_len * sizeof(float)); for (i = 0; i < g_len; i++) { ifreq = FREQ_MIN + i * FREQ_STEP; s = 0; radio_setfreq(fd, &ifreq); usleep(10000); /* give the tuner some time to settle */ for(j = 0; j < 5; j++) { s += radio_getsignal_n_stereo(fd); usleep(1000); } g[i] = s / 5.0; // average if (scan > 1) fprintf(fmap, "%f %d\n", ifreq / 1e6, s); fprintf(stderr, "scanning: %6.2f MHz - %6d\r", ifreq / 1e6, s); } fprintf(stderr, "%40s\r", ""); if (scan > 1) fclose(fmap); findstations(); if (write_config) printf("[Stations]\n"); for (i = 0; i < stations; i++) { ifreq = FREQ_MIN + astation[i] * FREQ_STEP; p_bands[i] = band; p_freqs[i] = ifreq; snprintf(name, sizeof(name), "scan-%d", i + 1); labels[i] = strdup(name); if (i < 8) { fkeybands[i] = band; fkeys[i] = ifreq; } if (write_config) printf("%d:%d=scan-%d\n", band + 1, ifreq, i + 1); } } /* ---------------------------------------------------------------------- */ static void usage(FILE *out) { fprintf(out, "radio -- interactive ncurses radio application\n" "usage:\n" " radio [ options ]\n" "\n" "options:\n" " -h print this text\n" " -d enable debug output\n" " -m mute radio\n" " -b 1-# select tuner band (? lists available bands)\n" " -f freq tune given frequency (also unmutes)\n" " -c dev use given device [default: %s]\n" " -s scan\n" " -S scan + write radio.fmmap\n" " -i scan, write initial ~/.radio config file to\n" " stdout and quit\n" #if defined(HAVE_ALSA) " -l 0/1 loopback digital audio from radio [default: 1]\n" " -r dev record/capture device for loopback [default: auto]\n" " -p dev playback device for loopback [default: default]\n" " -L ms latency for loopback in ms [default: %d]\n" #endif " -q quit. Useful with other options to control the\n" " radio device without entering interactive mode,\n" " i.e. \"radio -qf 91.4\"\n" "\n" "(c) 1998-2001 Gerd Knorr \n" "(c) 2012 Hans de Goede \n" "interface by Juli Merino \n" "channel scan by Gunther Mayer \n", device #if defined(HAVE_ALSA) , DEFAULT_LATENCY #endif ); } static void redraw(void) { redrawwin(stdscr); redrawwin(wfreq); redrawwin(woptions); redrawwin(wstations); redrawwin(wcommand); wrefresh(stdscr); wrefresh(wfreq); wrefresh(woptions); wrefresh(wstations); wrefresh(wcommand); } /* ---------------------------------------------------------------------- */ static void draw_wbands(void) { int i; wbands = newwin(12, 40, (LINES - 12) / 2, (COLS - 40) / 2); box(wbands, 0, 0); mvwprintw(wbands, 0, 1, " Select Tuner Band "); for (i = 0; i < no_bands; i++) { if (bands[i].rangehigh < (2 * freqfact)) mvwprintw(wbands, i + 1, 2, "%d.%10.10s %6.1f - %6.1f kHz%s", i + 1, modulation_label(i), bands[i].rangelow * (1e3 / freqfact), bands[i].rangehigh * (1e3 / freqfact), (i == band) ? " (*)" : ""); else mvwprintw(wbands, i + 1, 2, "%d.%10.10s %6.2f - %6.2f MHz%s", i + 1, modulation_label(i), (float)bands[i].rangelow / freqfact, (float)bands[i].rangehigh / freqfact, (i == band) ? " (*)" : ""); } mvwprintw(wbands, i + 2, 2, "(*) Current band"); wrefresh(wbands); } static void handle_wbands_keypress(int c) { switch (c) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case KEY_F(1): case KEY_F(2): case KEY_F(3): case KEY_F(4): case KEY_F(5): case KEY_F(6): case KEY_F(7): case KEY_F(8): band = (c >= '1' && c <= '8') ? c - '1' : c - KEY_F(1); /* fall through */ case 27: /* ESC */ case EOF: case 'b': case 'B': case 'e': case 'E': case 'q': case 'Q': case 'x': case 'X': delwin(wbands); wbands = NULL; redraw(); break; } } /* ---------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int lastband = -1, ifreq = -1, lastfreq = -1, mute = 0; int i, c, fd, quit = 0, scan = 0, write_config = 0; float newfreq = 0; setlocale(LC_ALL,""); /* parse args */ for (;;) { #if defined(HAVE_ALSA) c = getopt(argc, argv, "mhiqdsSb:f:c:l:r:p:L:"); #else c = getopt(argc, argv, "mhiqdsSb:f:c:"); #endif if (c == -1) break; switch (c) { case 'm': mute = 1; break; case 'q': quit = 1; break; case 'd': debug= 1; break; case 'S': scan = 2; break; case 's': scan = 1; break; case 'i': write_config = 1; scan = 1; quit = 1; break; case 'b': if (!strcmp(optarg, "?")) { band = -2; break; } sscanf(optarg, "%d", &band); if (band >= 1) { band--; /* user 1-# => array index 0-#*/ } else { fprintf(stderr, "Invalid band: '%s'\n", optarg); band = -3; } break; case 'f': sscanf(optarg, "%f", &newfreq); break; case 'c': device = optarg; break; case 'h': usage(stdout); exit(0); #if defined(HAVE_ALSA) case 'l': alsa_loopback = atoi(optarg); break; case 'r': alsa_capture = optarg; break; case 'p': alsa_playback = optarg; break; case 'L': alsa_latency = atoi(optarg); break; #endif default: usage(stderr); exit(1); } } if (-1 == (fd = open(device, O_RDONLY))) { fprintf(stderr,"open %s: %s\n",device,strerror(errno)); exit(1); } #if defined(HAVE_ALSA) if (alsa_loopback && alsa_capture == NULL) { void *md = discover_media_devices(); const char *p = strrchr(device, '/'); if (p) p++; else p = device; p = get_associated_device(md, NULL, MEDIA_SND_CAP, p, MEDIA_V4L_RADIO); if (p) alsa_capture = strdup(p); else alsa_loopback = 0; free_media_devices(md); } if (alsa_playback == NULL) alsa_playback = "default"; #endif memset(&tuner, 0, sizeof(tuner)); if (ioctl(fd, VIDIOC_G_TUNER, &tuner) != 0) { perror("G_TUNER"); return 1; } if (tuner.capability & V4L2_TUNER_CAP_LOW) freqfact = 16000; if (tuner.capability & V4L2_TUNER_CAP_FREQ_BANDS) { for (i = 0; i < MAX_BANDS; i++) { bands[i].tuner = 0; bands[i].type = V4L2_TUNER_RADIO; bands[i].index = i; if (ioctl(fd, VIDIOC_ENUM_FREQ_BANDS, &bands[i]) != 0) { if (i > 0 && errno == EINVAL) break; perror("ENUM_FREQ_BANDS"); return 1; } } no_bands = i; } else { bands[0].tuner = 0; bands[0].type = V4L2_TUNER_RADIO; bands[0].index = 0; bands[0].capability = tuner.capability; bands[0].rangelow = tuner.rangelow; bands[0].rangehigh = tuner.rangehigh; bands[0].modulation = V4L2_BAND_MODULATION_FM; no_bands = 1; } if (band >= no_bands) { fprintf(stderr, "Invalid band: '%d'\n", band); band = -3; } if (band <= -2) { fprintf(stderr, "Possible band values:\n"); for (i = 0; i < no_bands; i++) { if (bands[i].rangehigh < (2 * freqfact)) fprintf(stderr, "%d.%10.10s %6.1f - %6.1f kHz\n", i + 1, modulation_label(i), bands[i].rangelow * (1e3 / freqfact), bands[i].rangehigh * (1e3 / freqfact)); else fprintf(stderr, "%d.%10.10s %6.2f - %6.2f MHz\n", i + 1, modulation_label(i), (float)bands[i].rangelow / freqfact, (float)bands[i].rangehigh / freqfact); } return (band == -2) ? 0 : 1; } /* non-interactive stuff */ if (scan) { if (band == -1) { if (no_bands > 1) fprintf(stderr, "Warning no band specified, scanning band 1.\n"); band = 0; } do_scan(fd, scan, write_config); } if (newfreq) { if (band >= 0 && bands[band].rangehigh < (2 * freqfact)) { fprintf(stderr, "Tuning to %.2f kHz\n", newfreq); ifreq = newfreq * 1e3; } else { fprintf(stderr, "Tuning to %.2f MHz\n", newfreq); ifreq = newfreq * 1e6; } if (radio_setfreq(fd, &ifreq) != 0) return 1; lastfreq = ifreq; } if (mute) fprintf(stderr, "Muting radio\n"); radio_mute(fd, mute, alsa_loopback && !quit); if (quit) return 0; if (!scan) read_kradioconfig(); /* If not specified, get current freq/band from device and/or presets */ if (ifreq == -1) { if (radio_getfreq(fd, &ifreq)) return 1; lastfreq = ifreq; } if (band == -1) { if ((i = find_station(ifreq)) != -1) band = p_bands[i]; } if (band == -1 && !newfreq && fkeys[0]) { band = fkeybands[0]; ifreq = fkeys[0]; lastfreq = -1; } if (band == -1) { if (check_band_n_freq(&band, ifreq, ". Current freq out of range?")) return 1; } #if defined(HAVE_ALSA) if (alsa_loopback) fprintf(stderr, "Using alsa loopback: cap: %s (%s), out: %s\n", alsa_capture, device, alsa_playback); #endif /* enter interactive mode -- init ncurses */ ncurses=1; initscr(); start_color(); cbreak(); noecho(); keypad(stdscr,1); curs_set(0); /* JMMV: Set colors and windows */ /* XXX: Color definitions are wrong! BLUE is RED, CYAN is YELLOW and * viceversa */ init_pair(1,COLOR_WHITE,COLOR_BLACK); init_pair(2,COLOR_CYAN,COLOR_BLUE); init_pair(3,COLOR_WHITE,COLOR_RED); bkgd(A_BOLD | COLOR_PAIR(1)); refresh(); wfreq = newwin(7,32,1,2); wbkgd(wfreq,A_BOLD | COLOR_PAIR(2)); werase(wfreq); box(wfreq, 0, 0); mvwprintw(wfreq, 0, 1, " Tuner "); woptions = newwin(7,COLS-38,1,36); wbkgd(woptions,A_BOLD | COLOR_PAIR(3)); werase(woptions); box(woptions, 0, 0); mvwprintw(woptions, 0, 1, " Main menu "); wstations = newwin(LINES-14,COLS-4,9,2); wbkgd(wstations,A_BOLD | COLOR_PAIR(3)); werase(wstations); box(wstations, 0, 0); mvwprintw(wstations, 0, 1, " Preset stations "); wcommand = newwin(3,COLS-4,LINES-4,2); wbkgd(wcommand,A_BOLD | COLOR_PAIR(3)); werase(wcommand); box(wcommand,0,0); mvwprintw(wcommand, 0, 1, " Command window "); wrefresh(wcommand); /* JMMV: Added key information and windows division */ i = 1; mvwprintw(woptions, i++, 1, "Up/Down - inc/dec frequency"); if (tuner.capability & (V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP)) mvwprintw(woptions, i++, 1, "Right/Left - seek up/down"); if (stations) mvwprintw(woptions, i++, 1, "PgUp/PgDown - next/prev preset"); mvwprintw(woptions, i++, 1, "g - go to frequency..."); if (i <= 4) mvwprintw(woptions, i++, 1, "ESC, q, e - mute and exit"); if (i <= 4) mvwprintw(woptions, i++, 1, "x - exit (no mute)"); mvwprintw(woptions, i++, 1, "h, ? - help (more options)"); wrefresh(woptions); for (i = 0, c = 1; i < 8; i++) { if (fkeys[i]) { char *l = find_label(fkeys[i]); if (l) mvwprintw(wstations, c, 2, "F%d: %s", i + 1, l); else mvwprintw(wstations, c, 2, "F%d: %s", i + 1, make_label(fkeybands[i], fkeys[i])); c++; } } if (c == 1) mvwprintw(wstations, 1, 1, "[none]"); wrefresh(wstations); if (lastfreq != -1) print_freq(band, lastfreq, mute); for (quit = 0; quit == 0;) { if (band != lastband) { if (ifreq < (bands[band].rangelow * (1e6 / freqfact)) || ifreq > (bands[band].rangehigh * (1e6 / freqfact))) ifreq = bands[band].rangelow * (1e6 / freqfact); } if (ifreq != lastfreq) { if (!radio_setfreq(fd, &ifreq)) { print_freq(band, ifreq, mute); lastfreq = ifreq; } else ifreq = lastfreq; } radio_getsignal_n_stereo(fd); wrefresh(wfreq); wrefresh(wcommand); if (0 == select_wait(1)) { mvwprintw(wcommand,1,1,"%50.50s",""); wrefresh(wcommand); continue; } c = getch(); if (wbands) { handle_wbands_keypress(c); continue; } if (whelp) { delwin(whelp); whelp = NULL; redraw(); continue; } switch (c) { case 27: /* ESC */ case 'q': case 'Q': case 'e': case 'E': if (!mute) radio_mute(fd, 1, alsa_loopback); /* fall through */ case EOF: case 'x': case 'X': quit = 1; break; case 'g': case 'G': mvwprintw(wcommand, 1, 2, "GO: Enter frequency (%s): ", (bands[band].rangehigh < (2*freqfact)) ? "kHz" : "MHz"); curs_set(1); echo(); wrefresh(wcommand); wscanw(wcommand, "%f", &newfreq); cbreak(); noecho(); keypad(stdscr, 1); curs_set(0); wrefresh(wcommand); if (bands[band].rangehigh < (2 * freqfact)) { if (newfreq >= FREQ_MIN_KHZ && newfreq <= FREQ_MAX_KHZ) ifreq = newfreq * 1e3; else mvwprintw(wcommand, 1, 2, "Frequency out of range (%.1f-%.1f kHz)", FREQ_MIN_KHZ, FREQ_MAX_KHZ); } else { if (newfreq >= FREQ_MIN_MHZ && newfreq <= FREQ_MAX_MHZ) ifreq = newfreq * 1e6; else mvwprintw(wcommand, 1, 2, "Frequency out of range (%.2f-%.2f MHz)", FREQ_MIN_MHZ, FREQ_MAX_MHZ); } break; case KEY_UP: ifreq += FREQ_STEP; if (ifreq > FREQ_MAX) ifreq = FREQ_MIN; mvwprintw(wcommand, 1, 2, "Increment frequency"); break; case KEY_DOWN: ifreq -= FREQ_STEP; if (ifreq < FREQ_MIN) ifreq = FREQ_MAX; mvwprintw(wcommand, 1, 2, "Decrease frequency"); break; case KEY_LEFT: if (!(tuner.capability & (V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP))) break; mvwprintw(wcommand, 1, 2, "Seek down"); wrefresh(wcommand); if (!radio_seek(fd, 0, &ifreq)) { print_freq(band, ifreq, mute); lastfreq = ifreq; } break; case KEY_RIGHT: if (!(tuner.capability & (V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP))) break; mvwprintw(wcommand, 1, 2, "Seek up"); wrefresh(wcommand); if (!radio_seek(fd, 1, &ifreq)) { print_freq(band, ifreq, mute); lastfreq = ifreq; } break; case KEY_PPAGE: case KEY_NPAGE: case ' ': i = find_station(ifreq); if (i != -1) { i += (c == KEY_NPAGE) ? -1 : 1; if (i < 0) i = stations - 1; if (i == stations) i = 0; band = p_bands[i]; ifreq = p_freqs[i]; } else if (stations) { band = p_bands[0]; ifreq = p_freqs[0]; } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case KEY_F(1): case KEY_F(2): case KEY_F(3): case KEY_F(4): case KEY_F(5): case KEY_F(6): case KEY_F(7): case KEY_F(8): i = (c >= '1' && c <= '8') ? c - '1' : c - KEY_F(1); if (fkeys[i]) { band = fkeybands[i]; ifreq = fkeys[i]; mvwprintw(wcommand, 1, 2, "Go to preset station %d", i+1); } break; case 'L' & 0x1f: /* Ctrl-L */ redraw(); break; case 'm': mute ^= 1; radio_mute(fd, mute, alsa_loopback); print_freq(band, ifreq, mute); break; case 'b': case 'B': draw_wbands(); break; case 'h': case 'H': case '?': whelp = newwin(12, 40, (LINES-12)/2, (COLS-40)/2); box(whelp, 0, 0); i = 0; mvwprintw(whelp, i++, 1, " Help "); mvwprintw(whelp, i++, 1, "Up/Down - inc/dec frequency"); if (tuner.capability & (V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP)) mvwprintw(whelp, i++, 1, "Right/Left - seek up/down"); mvwprintw(whelp, i++, 1, "PgUp/PgDown - next/prev station"); mvwprintw(whelp, i++, 1, "F1-F8, 1-8 - select preset 1 - 8"); mvwprintw(whelp, i++, 1, "g - go to frequency..."); mvwprintw(whelp, i++, 1, "b - select tuner band"); mvwprintw(whelp, i++, 1, "m - toggle mute on/off"); mvwprintw(whelp, i++, 1, "ESC, q, e - mute and exit"); mvwprintw(whelp, i++, 1, "x - exit (no mute)"); mvwprintw(whelp, i++, 1, "h, ? - this help screen"); wrefresh(whelp); break; } } close(fd); bkgd(0); clear(); refresh(); endwin(); return 0; } xawtv-3.106/console/record.c000066400000000000000000000467031343350355000157730ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SOUNDCARD_H # include #endif #ifdef HAVE_SYS_SOUNDCARD_H # include #endif /* -------------------------------------------------------------------- */ static void tty_raw(void) { initscr(); cbreak(); noecho(); keypad(stdscr,1); refresh(); } static void tty_restore(void) { endwin(); } /* -------------------------------------------------------------------- */ static int sound_fd; static int sound_rcount; static unsigned int sound_blksize; static int16_t *sound_buffer; static int maxl,maxr; static int secl,secr; static int *histl,*histr,histn,histi; static float peak_seconds = 1.5; static char *audio_dev = "/dev/dsp"; static int sound_open(int rate) { int frag,afmt,channels,trigger,srate; if (-1 == (sound_fd = open(audio_dev, O_RDONLY))) { fprintf(stderr,"open %s: %s\n",audio_dev,strerror(errno)); exit(1); } frag = 0x7fff000d; /* 8k */ if (-1 == ioctl(sound_fd, SNDCTL_DSP_SETFRAGMENT, &frag)) perror("ioctl SNDCTL_DSP_SETFRAGMENT"); /* format */ afmt = AFMT_S16_LE; if (-1 == ioctl(sound_fd, SNDCTL_DSP_SETFMT, &afmt)) { perror("ioctl SNDCTL_DSP_SETFMT"); exit(1); } if (afmt != AFMT_S16_LE) { fprintf(stderr,"can't set sound format to 16 bit (le)\n"); exit(1); } /* channels */ channels = 2; if (-1 == ioctl(sound_fd, SNDCTL_DSP_CHANNELS, &channels)) { perror("ioctl SNDCTL_DSP_CHANNELS"); exit(1); } if (channels != 2) { fprintf(stderr,"can't record in stereo\n"); exit(1); } /* rate */ srate = rate; if (-1 == ioctl(sound_fd, SNDCTL_DSP_SPEED, &srate)) { perror("ioctl SNDCTL_DSP_SPEED"); exit(1); } /* accept +/- 1% */ if (srate < rate * 99 / 100 || srate > rate * 101 / 100) { fprintf(stderr,"can't set sample rate to %d (got %d)\n", rate,srate); exit(1); } /* get block size */ if (-1 == ioctl(sound_fd, SNDCTL_DSP_GETBLKSIZE, &sound_blksize)) { perror("ioctl SNDCTL_DSP_GETBLKSIZE"); exit(1); } if (0 == sound_blksize) sound_blksize = 4096; sound_buffer = malloc(sound_blksize); /* peak level history */ histn = peak_seconds * rate * 4 / sound_blksize; histl = malloc(histn * sizeof(int)); histr = malloc(histn * sizeof(int)); memset(histl,0,histn * sizeof(int)); memset(histr,0,histn * sizeof(int)); /* trigger record */ trigger = ~PCM_ENABLE_INPUT; ioctl(sound_fd,SNDCTL_DSP_SETTRIGGER,&trigger); trigger = PCM_ENABLE_INPUT; ioctl(sound_fd,SNDCTL_DSP_SETTRIGGER,&trigger); return sound_fd; } static int sound_read(void) { unsigned int have; int i,rc; int16_t *v; /* read */ for (have = 0;have < sound_blksize;) { rc = read(sound_fd,sound_buffer+have,sound_blksize-have); switch (rc) { case -1: if (EINTR != errno) { perror("read sound"); exit(1); } break; case 0: fprintf(stderr,"Huh? got 0 bytes from sound device?\n"); exit(1); default: have += rc; } } /* look for peaks */ maxl = 0; maxr = 0; for (i = sound_blksize>>2, v=sound_buffer; i > 0; i--) { if (abs(*v) > maxl) maxl = abs(*v); v++; if (abs(*v) > maxr) maxr = abs(*v); v++; } /* max for the last second */ histl[histi] = maxl; histr[histi] = maxr; histi++; if (histn == histi) histi = 0; for (secl = 0, secr = 0, i = 0; i < histn; i++) { if (secl < histl[i]) secl = histl[i]; if (secr < histr[i]) secr = histr[i]; } sound_rcount++; return 0; } /* -------------------------------------------------------------------- */ char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; char *config_names[SOUND_MIXER_NRDEVICES][4]; static int mix; static int dev = -1; static int volume; static char *mixer_dev = "/dev/mixer"; static int mixer_open(char *filename, char *device) { int i, devmask; if (-1 == (mix = open(filename,O_RDONLY))) { fprintf(stderr,"open %s: %s\n",filename,strerror(errno)); exit(1); } if (-1 == ioctl(mix,MIXER_READ(SOUND_MIXER_DEVMASK),&devmask)) { perror("mixer read devmask"); exit(1); } for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { if ((1< (1 << 30)) { value = (value * 10) >> 30; sprintf(buf,"%d.%d GB",(int)(value/10),(int)(value%10)); return buf; } if (value > (1 << 20)) { value = (value * 10) >> 20; sprintf(buf,"%d.%d MB",(int)(value/10),(int)(value%10)); return buf; } value >>= 10; sprintf(buf,"%3d kB",(int)value); return buf; } /* -------------------------------------------------------------------- */ char *progname; char *input = "line"; char *str_maxsize = "2GB"; int level_trigger; static void usage(FILE *fp) { fprintf(fp, "\n" "%s records sound in CD-Quality (44100/16bit/stereo).\n" "It has a nice ascii-art input-level meter. It is a\n" "interactive curses application. You'll need a fast\n" "terminal, don't try this on a 9600 bps vt100...\n" "\n" "%s has several options:\n" " -h this text\n" " -o file output file basename [%s], a number and the .wav\n" " extention are added by %s.\n" " -i ctrl mixer control [%s]. This should be the one\n" " where you can adjust the record level for\n" " your audio source, \"line\", \"mic\" and \"igain\"\n" " are good candidates.\n" " -m dev set mixer device [%s]\n" " -d dev set dsp device [%s]\n" " -r rate set sample rate [%d]\n" " -p sec peak seconds [%.1f]\n" "\n" "for non-interactive usage only:\n" " -c enable console (non-interactive) mode\n" " -v be verbose (show progress)\n" " -t mm:ss limit the time to record. By default it records\n" " until stopped by a signal (^C)\n" " -s size set max file size [%s]. You have to give number\n" " and unit without space inbetween, i.e. \"100mb\".\n" " -n num limit amount of files recorded, quits when\n" " reached.\n" " -l signal level triggered recording.\n" " -L level same as above + specify trigger level [%d]\n" "\n", progname,progname,filename,progname, input,mixer_dev,audio_dev, rate,peak_seconds,str_maxsize, level_trigger ? level_trigger : 1000); } int main(int argc, char *argv[]) { int c,key,vol,delay,auto_adjust; int record,nr,wav=0; char *outfile; fd_set s; int sec,maxhour,maxmin,maxsec; int maxfiles = 0; size_t maxsize; /* init some vars */ progname = strrchr(argv[0],'/'); progname = progname ? progname+1 : argv[0]; maxsec = 0; delay = 0; auto_adjust = 1; record = 0; nr = 0; setlocale(LC_ALL,""); /* parse options */ for (;;) { if (-1 == (c = getopt(argc, argv, "vhlci:o:d:m:r:t:s:L:p:n:"))) break; switch (c) { case 'v': verbose = 1; break; case 'l': level_trigger = 1000; break; case 'L': level_trigger = atoi(optarg); break; case 'i': input = optarg; break; case 'o': filename = optarg; break; case 'd': audio_dev = optarg; break; case 'm': mixer_dev = optarg; break; case 'c': mode = CONSOLE; break; case 'r': rate = atoi(optarg); break; case 'p': peak_seconds = atof(optarg); break; case 't': if (3 != sscanf(optarg,"%d:%d:%d",&maxhour,&maxmin,&maxsec)) { maxhour = 0; if (2 != sscanf(optarg,"%d:%d",&maxmin,&maxsec)) { fprintf(stderr,"time parse error\n"); exit(1); } } maxsec += maxmin * 60; maxsec += maxhour * 60 * 60; break; case 's': str_maxsize = optarg; break; case 'n': maxfiles = atoi(optarg); break; case 'h': usage(stdout); exit(0); default: usage(stderr); exit(1); } } maxsize = parse_size(str_maxsize); if (0 == maxsize) { fprintf(stderr,"maxsize parse error [%s]\n",str_maxsize); exit(1); } mixer_open(mixer_dev,input); sound_open(rate); outfile = malloc(strlen(filename)+16); if (mode == NCURSES) { tty_raw(); atexit(tty_restore); } signal(SIGINT,ctrlc); signal(SIGQUIT,ctrlc); signal(SIGTERM,ctrlc); signal(SIGHUP,ctrlc); if (mode == NCURSES) { mvprintw( 5,0,"record to %s*.wav",filename); mvprintw( 7,0,"left/right adjust mixer level for \"%s\"",input); mvprintw( 8,0,"space starts/stops recording"); /* line 9 is printed later */ mvprintw(10,0," auto-adjust reduces the record level on overruns"); mvprintw(11,0,"'N' next file (same as space twice, but without break)"); mvprintw(12,0,"'Q' quit"); mvprintw(LINES-3,0,"--"); mvprintw(LINES-2,0,"(c) 1999-2003 Gerd Knorr "); for (;!stop;) { refresh(); FD_ZERO(&s); FD_SET(0,&s); FD_SET(sound_fd,&s); if (-1 == select(sound_fd+1,&s,NULL,NULL,NULL)) { if (EINTR == errno) continue; perror("select"); break; } if (FD_ISSET(sound_fd,&s)) { /* sound */ if (-1 == sound_read()) break; if (delay) delay--; if (auto_adjust && (0 == delay) && (maxl >= 32767 || maxr >= 32767)) { /* auto-adjust */ vol = mixer_get_volume(); vol--; if (vol < 0) vol = 0; mixer_set_volume(vol); delay = 3; } print_bar(0,input,mixer_get_volume(),-1,100); print_bar(1,"left",maxl,secl,32768); print_bar(2,"right",maxr,secr,32768); mvprintw(9,0,"'A' toggle auto-adjust [%s] ", auto_adjust ? "on" : "off"); if (record) { wav_write_audio(wav,sound_buffer,sound_blksize); sec = wav_size / (rate*4); mvprintw(3,0,"%s: %3d:%02d (%s) ",outfile, sec/60,sec%60,str_mb(wav_size)); } else { mvprintw(3,0,"%c",ALIVE(sound_rcount)); } } if (FD_ISSET(0,&s)) { /* tty in */ switch (key = getch()) { case 'Q': case 'q': stop = 1; break; case 'A': case 'a': auto_adjust = !auto_adjust; break; case 'N': case 'n': if (record) { record_stop(wav); wav = record_start(outfile,&nr); } break; case ' ': if (!filename) break; if (!record) { /* start */ wav = record_start(outfile,&nr); record=1; auto_adjust=0; } else { /* stop */ record_stop(wav); record=0; } break; case KEY_RIGHT: vol = mixer_get_volume(); vol++; if (vol > 100) vol = 100; mixer_set_volume(vol); break; case KEY_LEFT: vol = mixer_get_volume(); vol--; if (vol < 0) vol = 0; mixer_set_volume(vol); break; } } } } if (mode == CONSOLE) { if (!level_trigger) { wav = record_start(outfile,&nr); record=1; } for (;!stop;) { if (-1 == sound_read()) break; if (level_trigger) { if (!record && (maxl > level_trigger || maxr > level_trigger)) { wav = record_start(outfile,&nr); record=1; } if (record && secl < level_trigger && secr < level_trigger) { record_stop(wav); record=0; if (maxfiles && nr == maxfiles) break; } } if (!record) { printf("waiting for signal %c [%d/%d]... \r", ALIVE(sound_rcount), maxl,maxr); fflush(stdout); continue; } sec = (done_size + wav_size) / (rate*4); if (maxsec && sec >= maxsec) break; if (wav_size + sound_blksize + sizeof(WAVEHDR) > maxsize) { record_stop(wav); wav = record_start(outfile,&nr); } wav_write_audio(wav,sound_buffer,sound_blksize); if (verbose) { int total = 10; int len = (maxl+maxr)*total/32768/2; printf("|%*.*s%*.*s| %s %d:%02d", len,len,full, total-len,total-len,empty, outfile,sec/60,sec%60); if (maxsec) printf("/%d:%02d",maxsec/60,maxsec%60); printf(" (%s",str_mb(wav_size)); if (done_size) printf(", %s total",str_mb(done_size + wav_size)); printf(") \r"); fflush(stdout); } } } if (record) record_stop(wav); mixer_close(); exit(0); } xawtv-3.106/console/scantv.c000066400000000000000000000175561343350355000160170ustar00rootroot00000000000000/* * (c) 2000-2002 Gerd Knorr * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include /* xawtv */ #include "frequencies.h" #include "grab-ng.h" #include "commands.h" #include "channel.h" #include "vbi-data.h" int debug = 0; int have_dga = 0; int timeout = 3; char *tvname; /*---------------------------------------------------------------------*/ static void grabber_init(void) { drv = ng_vid_open(&ng_dev.video,ng_dev.driver,NULL,0,&h_drv); if (NULL == drv) { fprintf(stderr,"no analog TV device available\n"); exit(1); } f_drv = drv->capabilities(h_drv); add_attrs(drv->list_attrs(h_drv)); } static void event(struct vbi_event *ev, void *user) { switch (ev->type) { case VBI_EVENT_NETWORK: if (NULL != tvname) free(tvname); if (strlen(ev->ev.network.name) > 0) tvname = strdup(ev->ev.network.name); break; } } static char* get_vbi_name(struct vbi_state *vbi) { int start; if (!vbi) return NULL; vbi_hasdata(vbi); if (NULL != tvname) free(tvname); tvname = NULL; start = time(NULL); for (;;) { vbi_hasdata(vbi); if (time(NULL) > start+timeout) break; if (tvname) break; } return tvname; } static int menu(char *intro, struct STRTAB *tab, char *opt) { int i,ret; char line[80]; if (NULL != opt) { /* cmd line option -- non-interactive mode */ for (i = 0; tab[i].str != NULL; i++) if (0 == strcasecmp(tab[i].str,opt)) return tab[i].nr; fprintf(stderr,"%s: not found\n",opt); exit(1); } fprintf(stderr,"\n%s\n",intro); for (i = 0; tab[i].str != NULL; i++) fprintf(stderr," %2ld: %s\n",tab[i].nr,tab[i].str); for (;;) { fprintf(stderr,"nr ? "); fgets(line,79,stdin); ret = atoi(line); for (i = 0; tab[i].str != NULL; i++) if (ret == tab[i].nr) return ret; fprintf(stderr,"invalid choice\n"); } } static void usage(FILE *out, char *prog, char *outfile) { fprintf(out, "This tool scan for tv stations and writes " "a initial xawtv config file.\n" "usage: %s [ options ]\n" "options:\n" " -h print this text\n" " -o outfile set output file. [%s]\n" " -i input set input.\n" " -n norm set tv norm.\n" " -f table set frequency table.\n" " -c device set video device file. [%s]\n" " -C device set vbi device file. [%s]\n" " -D driver set video driver. [%s]\n" " -s skip channel scan\n" " -a full scan (all frequencies, not just\n" " the ones from the frequency table)\n", prog, outfile ? outfile : "stdout", ng_dev.video, ng_dev.vbi, ng_dev.driver); } int main(int argc, char **argv) { struct vbi_state *vbi; struct ng_attribute *attr; int c,fi,on,tuned,i,j,scan=1,fullscan=0; unsigned int f,f1,f2,fc; char *name,dummy[32]; char *tvnorm = NULL; char *tvinput = NULL; char *freqtab = NULL; char *outfile = NULL; FILE *conf = stdout; /* parse options */ ng_init(); /* Autodetect devices */ ng_dev.video = "auto_tv"; for (;;) { if (-1 == (c = getopt(argc, argv, "hsadi:n:f:o:c:C:D:"))) break; switch (c) { case 'd': debug++; break; case 's': scan=0; break; case 'a': fullscan=1; break; case 'i': tvinput = optarg; break; case 'n': tvnorm = optarg; break; case 'f': freqtab = optarg; break; case 'o': outfile = optarg; break; case 'c': ng_dev.video = optarg; break; case 'C': ng_dev.vbi = optarg; break; case 'D': ng_dev.driver = optarg; break; case 'h': usage(stdout,argv[0],outfile); exit(0); default: usage(stderr,argv[0],outfile); exit(1); } } if (outfile) { if (NULL == (conf = fopen(outfile,"w"))) { fprintf(stderr,"open %s: %s\n",argv[1],strerror(errno)); exit(1); } } /* video */ if (NULL == drv) grabber_init(); if (NULL == drv) { fprintf(stderr,"can't open video device\n"); exit(1); } attr_init(); audio_init(); freq_init(); /* ask the user some questions ... */ attr = ng_attr_byid(attrs,ATTR_ID_NORM); i = menu("please select your TV norm",attr->choices,tvnorm); j = menu("please select a frequency table",chanlist_names,freqtab); if (tvinput == NULL) { tvinput = "Television"; } fprintf(conf,"[global]\n"); fprintf(conf,"freqtab = %s\n",chanlist_names[j].str); fprintf(conf,"\n"); fprintf(conf,"[defaults]\n"); fprintf(conf,"input = %s\n", tvinput); fprintf(conf,"norm = %s\n",ng_attr_getstr(attr,i)); fprintf(conf,"\n"); fflush(conf); if (!scan) exit(0); if (!(f_drv & CAN_TUNE)) { fprintf(stderr,"device has no tuner, exiting\n"); exit(0); } set_defaults(); do_va_cmd(2,"setinput",tvinput); do_va_cmd(2,"setnorm",ng_attr_getstr(attr,i)); do_va_cmd(2,"setfreqtab",chanlist_names[j].str); /* vbi */ vbi = vbi_open(ng_dev.vbi,debug,0); if (NULL == vbi) fprintf(stderr,"open %s: %s\n",ng_dev.vbi,strerror(errno)); else vbi_event_handler_add(vbi->dec,~0,event,vbi); if (!fullscan) { /* scan channels */ fprintf(stderr,"\nscanning channel list %s...\n", chanlist_names[j].str); for (i = 0; i < chancount; i++) { fprintf(stderr,"%-4s (%6.2f MHz): ",chanlist[i].name, (float)chanlist[i].freq/1000); do_va_cmd(2,"setchannel",chanlist[i].name); usleep(200000); /* 0.2 sec */ if (0 == drv->is_tuned(h_drv)) { fprintf(stderr,"no station\n"); continue; } name = get_vbi_name(vbi); fprintf(stderr, "%s\n", name ? name : "???"); if (NULL == name) { sprintf(dummy,"unknown (%s)",chanlist[i].name); name = dummy; } fprintf(conf,"[%s]\nchannel = %s\n\n",name,chanlist[i].name); fflush(conf); } } else { /* scan freqnencies */ fprintf(stderr,"\nscanning freqencies...\n"); on = 0; fc = 0; f1 = 0; f2 = 0; fi = -1; for (f = 44*16; f <= 958*16; f += 4) { for (i = 0; i < chancount; i++) if (chanlist[i].freq * 16 == f * 1000) break; fprintf(stderr,"?? %6.2f MHz (%-4s): ",f/16.0, (i == chancount) ? "-" : chanlist[i].name); drv->setfreq(h_drv,f); usleep(200000); /* 0.2 sec */ tuned = drv->is_tuned(h_drv); /* state machine */ if (0 == on && 0 == tuned) { fprintf(stderr,"| no\n"); continue; } if (0 == on && 0 != tuned) { fprintf(stderr," \\ raise\n"); f1 = f; if (i != chancount) { fi = i; fc = f; } on = 1; continue; } if (0 != on && 0 != tuned) { fprintf(stderr," | yes\n"); if (i != chancount) { fi = i; fc = f; } continue; } /* if (on != 0 && 0 == tuned) -- found one, read name from vbi */ fprintf(stderr," / fall\n"); f2 = f; if (0 == fc) fc = (f1+f2)/2; fprintf(stderr,"=> %6.2f MHz (%-4s): ", fc/16.0, (-1 != fi) ? chanlist[fi].name : "-"); drv->setfreq(h_drv,fc); name = get_vbi_name(vbi); fprintf(stderr,"%s\n",name ? name : "???"); if (NULL == name) { if (-1 == fi) sprintf(dummy,"unknown (%s)",chanlist[fi].name); else sprintf(dummy,"unknown (%.2f)",fc/16.0); name = dummy; } if (-1 != fi) { if (NULL == name) { sprintf(dummy,"unknown (%s)",chanlist[fi].name); name = dummy; } fprintf(conf,"[%s]\nchannel = %s\n\n",name,chanlist[fi].name); } else { if (NULL == name) { sprintf(dummy,"unknown (%.3f)", fc/16.0); name = dummy; } fprintf(conf,"[%s]\nfreq = %.3f\n\n", name, fc/16.0); } fflush(conf); on = 0; fc = 0; f1 = 0; f2 = 0; fi = -1; } } /* cleanup */ audio_off(); drv->close(h_drv); exit(0); } xawtv-3.106/console/showqt.c000066400000000000000000000415771343350355000160460ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include #ifndef PRId64 # define PRId64 "lld" # define PRIx64 "llx" #endif #if BYTE_ORDER == LITTLE_ENDIAN # define SWAP2(x) ((((uint16_t)x>>8) & (uint16_t)0x00ff) |\ (((uint16_t)x<<8) & (uint16_t)0xff00)) # define SWAP4(x) ((((uint32_t)x>>24) & (uint32_t)0x000000ff) |\ (((uint32_t)x>>8) & (uint32_t)0x0000ff00) |\ (((uint32_t)x<<8) & (uint32_t)0x00ff0000) |\ (((uint32_t)x<<24) & (uint32_t)0xff000000)) # define SWAP8(x) ((((uint64_t)x>>56) & (uint64_t)0x00000000000000ffULL) |\ (((uint64_t)x>>40) & (uint64_t)0x000000000000ff00ULL) |\ (((uint64_t)x>>24) & (uint64_t)0x0000000000ff0000ULL) |\ (((uint64_t)x>> 8) & (uint64_t)0x00000000ff000000ULL) |\ (((uint64_t)x<< 8) & (uint64_t)0x000000ff00000000ULL) |\ (((uint64_t)x<<24) & (uint64_t)0x0000ff0000000000ULL) |\ (((uint64_t)x<<40) & (uint64_t)0x00ff000000000000ULL) |\ (((uint64_t)x<<56) & (uint64_t)0xff00000000000000ULL)) #else # define SWAP2(a) (a) # define SWAP4(a) (a) # define SWAP8(a) (a) #endif #define MAKEFOURCC(a,b,c,d) ((((uint32_t)a)<<24) | (((uint32_t)b)<<16) | \ (((uint32_t)c)<< 8) | ( (uint32_t)d) ) #define a_clip MAKEFOURCC('c','l','i','p') #define a_co64 MAKEFOURCC('c','o','6','4') #define a_dinf MAKEFOURCC('d','i','n','f') #define a_dref MAKEFOURCC('d','r','e','f') #define a_free MAKEFOURCC('f','r','e','e') #define a_edts MAKEFOURCC('e','d','t','s') #define a_elst MAKEFOURCC('e','l','s','t') #define a_hdlr MAKEFOURCC('h','d','l','r') #define a_mdat MAKEFOURCC('m','d','a','t') #define a_mdhd MAKEFOURCC('m','d','h','d') #define a_mdia MAKEFOURCC('m','d','i','a') #define a_minf MAKEFOURCC('m','i','n','f') #define a_moov MAKEFOURCC('m','o','o','v') #define a_mvhd MAKEFOURCC('m','v','h','d') #define a_skip MAKEFOURCC('s','k','i','p') #define a_smhd MAKEFOURCC('s','m','h','d') #define a_stbl MAKEFOURCC('s','t','b','l') #define a_stco MAKEFOURCC('s','t','c','o') #define a_stsc MAKEFOURCC('s','t','s','c') #define a_stsd MAKEFOURCC('s','t','s','d') #define a_stsh MAKEFOURCC('s','t','s','h') #define a_stss MAKEFOURCC('s','t','s','s') #define a_stsz MAKEFOURCC('s','t','s','z') #define a_stts MAKEFOURCC('s','t','t','s') #define a_tkhd MAKEFOURCC('t','k','h','d') #define a_trak MAKEFOURCC('t','r','a','k') #define a_udta MAKEFOURCC('u','d','t','a') #define a_vmhd MAKEFOURCC('v','m','h','d') #define a_wide MAKEFOURCC('w','i','d','e') /* ------------------------------------------------------------------ */ struct classic_atom { uint32_t size; uint32_t type; uint64_t extsize; }; struct qt_atom { uint32_t size; uint32_t type; uint64_t extsize; }; enum field_type { END_OF_LIST = 0, INT16, INT32, INT64, FIX16, FIX32, FOURCC, VER, FLAGS3, TIME, LANG, COLOR, COUNT, RES2, RES4, RES6, RES8, RES10, MATRIX, }; struct field_list { enum field_type type; char *name; }; struct atom_list { uint32_t type; struct field_list *fields; }; struct fcc_names { uint32_t type; char *name; }; static int handle_classic_atom(int fh, off_t pos, off_t size, int depth); #if 0 static int handle_qt_atom(int fh, off_t pos, off_t size, int depth); #endif /* ------------------------------------------------------------------ */ static struct field_list l_co64[] = { { VER, "version" }, { FLAGS3, "flags" }, { COUNT, "number of entries" }, /* FIXME: loop */ { INT64, "offset64" }, { END_OF_LIST } }; static struct field_list l_dref[] = { { VER, "version" }, { FLAGS3, "flags" }, { INT32, "number of entries" }, /* FIXME: loop */ { INT32, "size" }, { FOURCC, "type" }, { VER, "version" }, { FLAGS3, "flags" }, { END_OF_LIST } }; static struct field_list l_elst[] = { { VER, "version" }, { FLAGS3, "flags" }, { COUNT, "number of entries" }, /* FIXME: loop */ { INT32, "track duration" }, { INT32, "media time" }, { FIX32, "media rate" }, { END_OF_LIST } }; static struct field_list l_hdlr[] = { { VER, "version" }, { FLAGS3, "flags" }, { FOURCC, "component type" }, { FOURCC, "component subtype" }, { RES4, "component manufacturer" }, { RES4, "component flags" }, { RES4, "component flags mask" }, /* FIXME: name */ { END_OF_LIST } }; static struct field_list l_mdhd[] = { { VER, "version" }, { FLAGS3, "flags" }, { TIME, "ctime" }, { TIME, "mtime" }, { INT32, "time scale" }, { INT32, "duration" }, { LANG, "language" }, { INT16, "quality" }, { END_OF_LIST } }; static struct field_list l_mvhd[] = { { VER, "version" }, { FLAGS3, "flags" }, { TIME, "ctime" }, { TIME, "mtime" }, { INT32, "time scale" }, { INT32, "duration" }, { FIX32, "preferred rate" }, { FIX16, "preferred volume" }, { RES10, "reserved" }, { MATRIX, "matrix" }, { INT32, "preview time" }, { INT32, "preview duration" }, { INT32, "poster time" }, { INT32, "selection time" }, { INT32, "selection duration" }, { INT32, "current time" }, { INT32, "next track id" }, { END_OF_LIST } }; static struct field_list l_smhd[] = { { VER, "version" }, { FLAGS3, "flags" }, { INT16, "balance" }, { RES2, "reserved" }, { END_OF_LIST } }; static struct field_list l_stco[] = { { VER, "version" }, { FLAGS3, "flags" }, { COUNT, "number of entries" }, /* FIXME: loop */ { INT32, "offset" }, { END_OF_LIST } }; static struct field_list l_stsc[] = { { VER, "version" }, { FLAGS3, "flags" }, { COUNT, "number of entries" }, /* FIXME: loop */ { INT32, "first chunk" }, { INT32, "samples per chunk" }, { INT32, "sample description id" }, { END_OF_LIST } }; static struct field_list l_stsd[] = { { VER, "version" }, { FLAGS3, "flags" }, { COUNT, "number of entries" }, /* FIXME: loop */ { INT32, "size" }, { FOURCC, "format" }, { RES6, "reserved" }, { INT16, "data reference index" }, { END_OF_LIST } }; static struct field_list l_stts[] = { { VER, "version" }, { FLAGS3, "flags" }, { COUNT, "number of entries" }, /* FIXME: loop */ { INT32, "sample count" }, { INT32, "sample duration" }, { END_OF_LIST } }; static struct field_list l_stsz[] = { { VER, "version" }, { FLAGS3, "flags" }, { INT32, "sample size" }, { COUNT, "number of entries" }, /* FIXME: loop if "sample size is 0" */ #if 0 { INT32, "sample size" }, #endif { END_OF_LIST } }; static struct field_list l_tkhd[] = { { VER, "version" }, { FLAGS3, "flags" }, { TIME, "ctime" }, { TIME, "mtime" }, { INT32, "track id" }, { RES4, "reserved" }, { INT32, "duration" }, { RES8, "reserved" }, { INT16, "layer" }, { INT16, "alternate group" }, { INT16, "volume" }, { RES2, "reserved" }, { MATRIX, "matrix" }, { FIX32, "width" }, { FIX32, "height" }, { END_OF_LIST } }; static struct field_list l_vmhd[] = { { VER, "version" }, { FLAGS3, "flags" }, { INT16, "graphics mode" }, { COLOR, "opcolor" }, { END_OF_LIST } }; static struct atom_list alist[] = { { a_co64, l_co64 }, { a_dref, l_dref }, { a_elst, l_elst }, { a_hdlr, l_hdlr }, { a_mdhd, l_mdhd }, { a_mvhd, l_mvhd }, { a_smhd, l_smhd }, { a_stco, l_stco }, { a_stsc, l_stsc }, { a_stsd, l_stsd }, { a_stsz, l_stsz }, { a_stts, l_stts }, { a_tkhd, l_tkhd }, { a_vmhd, l_vmhd }, { /* end of list */} }; /* ------------------------------------------------------------------ */ static struct fcc_names flist[] = { { a_co64, "chunk offset64 atom" }, { a_clip, "movie clipping atom" }, { a_dinf, "data information atom" }, { a_dref, "data reference atom" }, { a_edts, "edit atom" }, { a_elst, "edit list atom" }, { a_free, "unused space" }, { a_hdlr, "handler reference atom" }, { a_mdat, "movie data atom" }, { a_mdhd, "media header atom" }, { a_mdia, "media atom" }, { a_minf, "media information atom" }, { a_moov, "movie atom" }, { a_mvhd, "movie header atom" }, { a_skip, "unused space" }, { a_smhd, "sound media information header atom" }, { a_stbl, "sample table atom" }, { a_stco, "chunk offset atom" }, { a_stsc, "sample-to-chunk atom" }, { a_stsd, "sample description atom" }, { a_stsz, "sample size atom" }, { a_stts, "time-to-sample atom" }, { a_tkhd, "track header atom" }, { a_trak, "track atom" }, { a_udta, "user data atom" }, { a_vmhd, "video media information header atom" }, { a_wide, "reserved space for extsize field" }, { /* end of list */} }; /* ------------------------------------------------------------------ */ static int verbose=0; static void swap_classic_atom(struct classic_atom *a) { a->size = SWAP4(a->size); a->type = SWAP4(a->type); a->extsize = SWAP8(a->extsize); } #if 0 static void swap_qt_atom(struct qt_atom *a) { } #endif static int xisprint(int c) { switch (c) { case 169: /* copyright */ return 1; default: return isprint(c); } } static char* strfcc(uint32_t type) { static char retval[64]; int i,l; if (xisprint((type >> 24) & 0xff) && xisprint((type >> 16) & 0xff) && xisprint((type >> 8) & 0xff) && xisprint( type & 0xff)) { l = sprintf(retval,"%c%c%c%c", (type >> 24) & 0xff, (type >> 16) & 0xff, (type >> 8) & 0xff, type & 0xff); } else { l = sprintf(retval,"0x%08x",type); } for (i = 0; flist[i].type != 0; i++) if (flist[i].type == type) break; if (flist[i].type != 0) sprintf(retval+l," [%s]",flist[i].name); return retval; } #define FIELD_NAME "\t%s%-20s = " static void dump_fields(int fh, off_t pos, struct field_list *list) { char dummy[64],si[15]; int i,loop,cpos; int8_t int8; int16_t int16; int32_t int32, fcc, count; int64_t int64; uint16_t color[3]; uint32_t uint32; time_t t; if (0 == verbose) return; if (-1 == lseek(fh,pos,SEEK_SET)) { perror("lseek"); exit(1); } si[0] = 0; count = 0; cpos = 0; loop = 0; for (i = 0; list[i].type != END_OF_LIST || loop < count-1; i++) { switch (list[i].type) { case FOURCC: read(fh,&fcc,sizeof(fcc)); printf(FIELD_NAME "%s\n",si,list[i].name,strfcc(SWAP4(fcc))); break; case VER: read(fh,&int8,sizeof(int8)); if (verbose > 1 || int8 > 0) printf(FIELD_NAME "%d\n",si,list[i].name,(int)int8); break; case LANG: case INT16: read(fh,&int16,sizeof(int16)); printf(FIELD_NAME "%d\n",si,list[i].name,(int)SWAP2(int16)); break; case INT32: read(fh,&int32,sizeof(int32)); printf(FIELD_NAME "%d\n",si,list[i].name,SWAP4(int32)); break; case INT64: read(fh,&int64,sizeof(int64)); printf(FIELD_NAME "%" PRId64 "\n",si,list[i].name,SWAP8(int64)); break; case FIX16: read(fh,&int16,sizeof(int16)); printf(FIELD_NAME "%f\n",si,list[i].name, SWAP2(int16) / 256.0); break; case FIX32: read(fh,&int32,sizeof(int32)); printf(FIELD_NAME "%f\n",si,list[i].name, SWAP4(int32) / 65536.0); break; case FLAGS3: read(fh,dummy,3); int32 = dummy[0] << 16 | dummy[1] << 8 | dummy[2]; if (verbose > 1 || int32 > 0) printf(FIELD_NAME "0x%06x\n",si,list[i].name,int32); break; case TIME: read(fh,&uint32,sizeof(uint32)); t = SWAP4(uint32) - 2082848400; strftime(dummy,sizeof(dummy),"%d. %b %Y - %H:%M:%S",localtime(&t)); printf(FIELD_NAME "%s\n",si,list[i].name,dummy); break; case COLOR: read(fh,&color,sizeof(color)); printf(FIELD_NAME "%d/%d/%d (rgb)\n",si,list[i].name, (int)SWAP2(color[0]), (int)SWAP2(color[0]), (int)SWAP2(color[0])); break; case RES2: read(fh,dummy,2); break; case RES4: read(fh,dummy,4); break; case RES6: read(fh,dummy,6); break; case RES8: read(fh,dummy,8); break; case RES10: read(fh,dummy,10); break; case MATRIX: read(fh,dummy,36); break; case COUNT: read(fh,&count,sizeof(count)); count = SWAP4(count); cpos = i; if (verbose < 2) { printf("\t[list follows]\n"); return; } printf(FIELD_NAME "%d\n",si,list[i].name,count); sprintf(si,"[%d] ",loop); break; case END_OF_LIST: i = cpos; loop++; sprintf(si,"[%d] ",loop); break; } } } static void dump_string(int fh, off_t pos, off_t size) { off_t off; uint16_t ssize,stype; char *str; if (0 == verbose) return; if (-1 == lseek(fh,pos,SEEK_SET)) { perror("lseek"); exit(1); } /* FIXME: specs say size is _including_ size+type */ for (off = 0; off < size; off += ssize+4) { read(fh,&ssize,sizeof(ssize)); read(fh,&stype,sizeof(stype)); ssize = SWAP2(ssize); stype = SWAP2(stype); str = malloc(ssize+1); read(fh,str,ssize); str[ssize] = 0; printf("\t%d[%d] = %s\n",(int)stype,(int)ssize,str); free(str); } if (off != size) { fprintf(stderr,"Huh? string size mismatch!\n"); exit(1); } } static int handle_classic_atom(int fh, off_t pos, off_t size, int depth) { struct classic_atom a; uint64_t asize; size_t off; int i; if (-1 == lseek(fh,pos,SEEK_SET)) { perror("lseek"); exit(1); } if (sizeof(a) != read(fh,&a,sizeof(a))) { perror("read"); exit(1); } swap_classic_atom(&a); switch (a.size) { case 0: asize = size; off = 8; break; case 1: asize = a.extsize; off = 16; break; default: asize = a.size; off = 8; } printf("0x%08" PRIx64 " 0x%08" PRIx64 " %*s%s\n", (int64_t)pos,(int64_t)asize,depth,"",strfcc(a.type)); switch (a.type) { case a_dinf: case a_edts: case a_mdia: case a_minf: case a_moov: case a_stbl: case a_trak: case a_udta: while (off < asize) off += handle_classic_atom(fh,pos+off,asize-off,depth+3); if (off != asize) { fprintf(stderr,"Huh? atom size mismatch!\n"); exit(1); } break; default: if (169 == ((a.type >> 24) & 0xff)) { dump_string(fh,pos+off,asize-off); } else { for (i = 0; alist[i].type != 0; i++) if (alist[i].type == a.type) break; if (alist[i].type != 0) dump_fields(fh,pos+off,alist[i].fields); } } return asize; } #if 0 static int handle_qt_atom(int fh, off_t pos, off_t size, int depth) { return 0; } #endif /* ------------------------------------------------------------------ */ static void usage(char *prog) { char *h; if (NULL != (h = strrchr(prog,'/'))) prog = h+1; fprintf(stderr, "%s - dump structure of quicktime files\n" "\n" "usage: %s [ -j ] [ -e ] filename\n" "options:\n" " -h this text\n" " -v increase verbose level\n" "\n", prog,prog); } int main(int argc, char *argv[]) { int fh; off_t off,size; int c; /* parse options */ for (;;) { if (-1 == (c = getopt(argc, argv, "hv"))) break; switch (c) { case 'v': verbose++; break; case 'h': default: usage(argv[0]); exit(1); } } if (optind == argc) { usage(argv[0]); exit(1); } setlocale(LC_ALL,NULL); fh = open(argv[optind],O_RDONLY); if (-1 == fh) { fprintf(stderr,"open %s: %s\n",argv[optind],strerror(errno)); exit(1); } size = lseek(fh,0,SEEK_END); for (off = 0; off < size;) off += handle_classic_atom(fh,off,size,0); if (off != size) { fprintf(stderr,"Huh? File size mismatch!\n"); exit(1); } return 0; } xawtv-3.106/console/showriff.c000066400000000000000000000353301343350355000163360ustar00rootroot00000000000000/* SHOWRIFF.c * Extracts some infos from RIFF files * (c)94 UP-Vision Computergrafik for c't * Written in ANSI-C. No special header files needed to compile. * * modified by Gerd Knorr: * - dos2unix :-) * - fixed warnings * - added some tags (checked xanim sources for info) * - LFS + OpenDML + mjpeg * - bytesex fixes */ #include "config.h" #include #include #include #include #include #include #include #include #include #if BYTE_ORDER == BIG_ENDIAN # define SWAP2(x) (((x>>8) & 0x00ff) |\ ((x<<8) & 0xff00)) # define SWAP4(x) (((x>>24) & 0x000000ff) |\ ((x>>8) & 0x0000ff00) |\ ((x<<8) & 0x00ff0000) |\ ((x<<24) & 0xff000000)) #else # define SWAP2(a) (a) # define SWAP4(a) (a) #endif #ifndef HAVE_FTELLO # define ftello ftell #endif #ifndef HAVE_FSEEKO # define fseeko fseek #endif typedef uint32_t DWORD; typedef uint16_t WORD; typedef DWORD FOURCC; /* Type of FOUR Character Codes */ typedef uint8_t boolean; #define TRUE 1 #define FALSE 0 #define BUFSIZE 4096 /* Macro to convert expressions of form 'F','O','U','R' to numbers of type FOURCC: */ #if BYTE_ORDER == BIG_ENDIAN # define MAKEFOURCC(a,b,c,d) ((((DWORD)a)<<24) | (((DWORD)b)<<16) | \ (((DWORD)c)<< 8) | ( (DWORD)d) ) #else # define MAKEFOURCC(a,b,c,d) ( ((DWORD)a) | (((DWORD)b)<< 8) | \ (((DWORD)c)<<16) | (((DWORD)d)<<24) ) #endif /* The only FOURCCs interpreted by this program: */ #define RIFFtag MAKEFOURCC('R','I','F','F') #define LISTtag MAKEFOURCC('L','I','S','T') #define avihtag MAKEFOURCC('a','v','i','h') #define strhtag MAKEFOURCC('s','t','r','h') #define strftag MAKEFOURCC('s','t','r','f') #define vidstag MAKEFOURCC('v','i','d','s') #define audstag MAKEFOURCC('a','u','d','s') #define dmlhtag MAKEFOURCC('d','m','l','h') #define avi_tag MAKEFOURCC('A','V','I',' ') #define wavetag MAKEFOURCC('W','A','V','E') #define fmt_tag MAKEFOURCC('f','m','t',' ') #define MJPGtag MAKEFOURCC('M','J','P','G') #define _00dbtag MAKEFOURCC('0','0','d','b') #define _00dctag MAKEFOURCC('0','0','d','c') /* Build a string from a FOURCC number (s must have room for at least 5 chars) */ static void FOURCC2Str(FOURCC fcc, char* s) { #if BYTE_ORDER == BIG_ENDIAN s[0]=(fcc >> 24) & 0xFF; s[1]=(fcc >> 16) & 0xFF; s[2]=(fcc >> 8) & 0xFF; s[3]=(fcc ) & 0xFF; #else s[0]=(fcc ) & 0xFF; s[1]=(fcc >> 8) & 0xFF; s[2]=(fcc >> 16) & 0xFF; s[3]=(fcc >> 24) & 0xFF; #endif s[4]=0; } static DWORD fcc_type; static DWORD riff_type; static int stop_on_errors = 1; static int print_mjpeg = 0; #define EoLST 0 #define INT32 1 #define INT16 2 #define FLAGS 3 #define CCODE 4 struct FLAGLIST { int bit; char *name; }; struct VAL { int type; char *name; struct FLAGLIST *flags; }; struct FLAGLIST flags_avih[] = { { 0x00000010, "hasindex" }, { 0x00000020, "useindex" }, { 0x00000100, "interleaved" }, { 0x00010000, "for_capture" }, { 0x00020000, "copyrighted" }, { 0, NULL } }; struct VAL names_avih[] = { { INT32, "us_frame" }, { INT32, "max_bps" }, { INT32, "pad_gran" }, { FLAGS, "flags", flags_avih }, { INT32, "tot_frames" }, { INT32, "init_frames" }, { INT32, "streams" }, { INT32, "sug_bsize" }, { INT32, "width" }, { INT32, "height" }, { INT32, "scale" }, { INT32, "rate" }, { INT32, "start" }, { INT32, "length" }, { EoLST, NULL } }; struct VAL names_strh[] = { { CCODE, "fcc_handler" }, { FLAGS, "flags" }, { INT32, "priority" }, { INT32, "init_frames" }, { INT32, "scale" }, { INT32, "rate" }, { INT32, "start" }, { INT32, "length" }, { INT32, "sug_bsize" }, { INT32, "quality" }, { INT32, "samp_size" }, { EoLST, NULL } }; struct VAL names_strf_vids[] = { { INT32, "size" }, { INT32, "width" }, { INT32, "height" }, { INT16, "planes" }, { INT16, "bit_cnt" }, { CCODE, "compression" }, { INT32, "image_size" }, { INT32, "xpels_meter" }, { INT32, "ypels_meter" }, { INT32, "num_colors" }, { INT32, "imp_colors" }, { EoLST, NULL } }; struct VAL names_strf_auds[] = { { INT16, "format" }, { INT16, "channels" }, { INT32, "rate" }, { INT32, "av_bps" }, { INT16, "blockalign" }, { INT16, "size" }, { EoLST, NULL } }; struct VAL names_dmlh[] = { { INT32, "frames" }, { EoLST, NULL } }; static void dump_vals(FILE *f, int count, struct VAL *names) { DWORD i,j,val32; WORD val16; for (i = 0; names[i].type != EoLST; i++) { switch (names[i].type) { case INT32: fread(&val32,4,1,f); val32 = SWAP4(val32); printf("\t%-12s = %d\n",names[i].name,val32); break; case CCODE: fread(&val32,4,1,f); val32 = SWAP4(val32); if (val32) { printf("\t%-12s = %c%c%c%c (0x%x)\n",names[i].name, (int)( val32 & 0xff), (int)((val32 >> 8) & 0xff), (int)((val32 >> 16) & 0xff), (int)((val32 >> 24) & 0xff), val32); } else { printf("\t%-12s = unset (0)\n",names[i].name); } break; case FLAGS: fread(&val32,4,1,f); val32 = SWAP4(val32); printf("\t%-12s = 0x%x\n",names[i].name,val32); if (names[i].flags) { for (j = 0; names[i].flags[j].bit != 0; j++) if (names[i].flags[j].bit & val32) printf("\t\t0x%x: %s\n", names[i].flags[j].bit,names[i].flags[j].name); } break; case INT16: fread(&val16,2,1,f); val16 = SWAP2(val16); printf("\t%-12s = %ld\n",names[i].name,(long)val16); break; } } } struct JPEG_MARKER { unsigned char val; char *name; char *desc; } mark[] = { { 0xc0, "SOF0 ", "start of frame 0" }, { 0xc4, "DHT ", "huffmann table(?)" }, { 0xd8, "SOI ", "start of image" }, { 0xda, "SOS ", "start of scan" }, { 0xdb, "DQT ", "quantization table" }, { 0xe0, "APP0 ", NULL }, { 0xfe, "COM ", "comment" }, { 0, NULL, NULL } }; static void hexlog(unsigned char *buf, int count) { int l,i; for (l = 0; l < count; l+= 16) { printf("\t "); for (i = l; i < l+16; i++) { if (i < count) printf("%02x ",buf[i]); else printf(" "); if ((i%4) == 3) printf(" "); } for (i = l; i < l+16; i++) { if (i < count) printf("%c",isprint(buf[i]) ? buf[i] : '.'); } printf("\n"); } } static void dump_jpeg(unsigned char *buf, int len) { int i,j,type,skip; if (!print_mjpeg) return; for (i = 0; i < len;) { if (buf[i] != 0xff) { printf("\tjpeg @ 0x%04x: oops 0x%02x 0x%02x 0x%02x 0x%02x\n", i,buf[i],buf[i+1],buf[i+2],buf[i+3]); return; } type = buf[i+1]; for (j = 0; 0 != mark[j].val; j++) if (mark[j].val == type) break; printf("\tjpeg @ 0x%04x: %s (0x%x) %s\n",i, mark[j].name ? mark[j].name : "???", type, mark[j].desc ? mark[j].desc : "???"); i+=2; skip = buf[i] << 8 | buf[i+1]; switch (type) { case 0xd8: skip=0; break; case 0xc0: /* SOF0 */ printf("\t\tsize: %dx%d prec=%d comp=%d\n", buf[i+6] | (buf[i+5] << 8), buf[i+4] | (buf[i+3] << 8), buf[i+2], buf[i+7]); for (j = 0; j < buf[i+7]; j++) { printf("\t\tcomp%d: id=%d h=%d v=%d qt=%d\n",j, buf[i+3*j+8], (buf[i+3*j+9] >> 4) & 0x0f, buf[i+3*j+9] & 0x0f, buf[i+3*j+10]); } break; case 0xc4: /* DHT */ printf("\t\tindex=%d\n",buf[i+2]); break; case 0xdb: /* DQT */ printf("\t\tprec=%d, nr=%d\n", (buf[i+2] >> 4) & 0x0f, buf[i+2] & 0x0f); break; case 0xda: return; } hexlog(buf+i+2,skip-2); i += skip; } } static unsigned char* off_t_to_char(off_t val, int base, int len) { static const unsigned char digit[] = "0123456789abcdef"; static unsigned char outbuf[32]; unsigned char *p = outbuf + sizeof(outbuf); int i; *(--p) = 0; for (i = 0; i < len || val > 0; i++) { *(--p) = digit[ val % base ]; val = val / base; } return p; } /* Reads a chunk ID and the chunk's size from file f at actual file position : */ static boolean ReadChunkHead(FILE* f, FOURCC* ID, DWORD* size) { if (!fread(ID,sizeof(FOURCC),1,f)) return(FALSE); if (!fread(size,sizeof(DWORD),1,f)) return(FALSE); *size = SWAP4(*size); return(TRUE); } /* Processing of a chunk. (Will be called recursively!). Processes file f starting at position filepos. f contains filesize bytes. If DesiredTag!=0, ProcessChunk tests, whether the chunk begins with the DesiredTag. If the read chunk is not identical to DesiredTag, an error message is printed. RekDepth determines the recursion depth of the chunk. chunksize is set to the length of the chunk's data (excluding header and padding byte). ProcessChunk prints out information of the chunk to stdout and returns FALSE, if an error occured. */ static boolean ProcessChunk(FILE* f, size_t filepos, size_t filesize, FOURCC DesiredTag, int RekDepth, DWORD* chunksize) { unsigned char buf[BUFSIZE]; int buflen; char tagstr[5]; /* FOURCC of chunk converted to string */ FOURCC chunkid; /* read FOURCC of chunk */ size_t datapos; /* position of data in file to process */ if (filepos>filesize-1) { /* Oops. Must be something wrong! */ printf(" ***** Error: Data would be behind end of file!\n"); if (stop_on_errors) return(FALSE); } fseeko(f,filepos,SEEK_SET); /* Go to desired file position! */ if (!ReadChunkHead(f,&chunkid,chunksize)) { /* read chunk header */ printf(" ***** Error reading chunk at filepos 0x%s\n", off_t_to_char(filepos,16,1)); return(FALSE); } FOURCC2Str(chunkid,tagstr); /* now we can PRINT the chunkid */ if (DesiredTag) { /* do we have to test identity? */ if (DesiredTag!=chunkid) { char ds[5]; FOURCC2Str(DesiredTag,ds); printf("\n\n *** Error: Expected chunk '%s', found '%s'\n", ds,tagstr); return(FALSE); } } datapos=filepos+sizeof(FOURCC)+sizeof(DWORD); /* here is the data */ /* print out header: */ printf("(0x%s) %*c ID:<%s> Size: 0x%08x\n", off_t_to_char(filepos,16,8),(RekDepth+1)*4,' ',tagstr,*chunksize); if (datapos + ((*chunksize+1)&~1) > filesize) { /* too long? */ printf(" ***** Error: Chunk exceeds file\n"); if (stop_on_errors) return(FALSE); } switch (chunkid) { /* Depending on the ID of the chunk and the internal state, the different IDs can be interpreted. At the moment the only interpreted chunks are RIFF- and LIST-chunks. For all other chunks only their header is printed out. */ case RIFFtag: case LISTtag: { DWORD datashowed; FOURCC formtype; /* format of chunk */ char formstr[5]; /* format of chunk converted to string */ DWORD subchunksize; /* size of a read subchunk */ fread(&formtype,sizeof(FOURCC),1,f); /* read the form type */ FOURCC2Str(formtype,formstr); /* make it printable */ /* print out the indented form of the chunk: */ if (chunkid==RIFFtag) { printf("%12c %*c Form Type = <%s>\n", ' ',(RekDepth+1)*4,' ',formstr); riff_type = formtype; } else printf("%12c %*c List Type = <%s>\n", ' ',(RekDepth+1)*4,' ',formstr); datashowed=sizeof(FOURCC); /* we showed the form type */ datapos+=datashowed; /* for the rest of the routine */ while (datashowed<*chunksize) { /* while not showed all: */ long subchunklen; /* complete size of a subchunk */ /* recurse for subchunks of RIFF and LIST chunks: */ if (!ProcessChunk(f,datapos,filesize,0, RekDepth+1,&subchunksize)) return(FALSE); subchunklen = sizeof(FOURCC) + /* this is the complete.. */ sizeof(DWORD) + /* .. size of the subchunk */ ((subchunksize+1) & ~1); datashowed += subchunklen; /* we showed the subchunk */ datapos += subchunklen; /* for the rest of the loop */ } } break; /* Feel free to put your extensions here! */ case avihtag: dump_vals(f,sizeof(names_avih)/sizeof(struct VAL),names_avih); break; case strhtag: { char typestr[5]; fread(&fcc_type,sizeof(FOURCC),1,f); FOURCC2Str(fcc_type,typestr); printf("\tfcc_type = %s\n",typestr); dump_vals(f,sizeof(names_strh)/sizeof(struct VAL),names_strh); break; } case strftag: switch (fcc_type) { case vidstag: dump_vals(f,sizeof(names_strf_vids)/sizeof(struct VAL),names_strf_vids); break; case audstag: dump_vals(f,sizeof(names_strf_auds)/sizeof(char*),names_strf_auds); break; default: printf("unknown\n"); break; } break; case fmt_tag: if (riff_type == wavetag) dump_vals(f,sizeof(names_strf_auds)/sizeof(char*),names_strf_auds); break; case dmlhtag: dump_vals(f,sizeof(names_dmlh)/sizeof(struct VAL),names_dmlh); break; case _00dbtag: case _00dctag: buflen = (*chunksize > BUFSIZE) ? BUFSIZE : *chunksize; fread(buf, buflen, 1, f); dump_jpeg(buf,buflen); break; } return(TRUE); } static void usage(char *prog) { char *h; if (NULL != (h = strrchr(prog,'/'))) prog = h+1; fprintf(stderr, "\n" "%s shows contents of RIFF files (AVI,WAVE...).\n" "(c) 1994 UP-Vision Computergrafik for c't\n" "unix port and some extentions (for avi) by Gerd Knorr\n" "\n" "usage: %s [ -j ] [ -e ] filename\n" "options:\n" " -j try to decode some mjpeg headers\n" " -e don't stop on errors\n" "\n", prog,prog); } int main (int argc, char **argv) { FILE* f; /* the input file */ off_t filesize; /* its size */ off_t filepos; DWORD chunksize; /* size of the RIFF chunk data */ int c; /* parse options */ for (;;) { if (-1 == (c = getopt(argc, argv, "jeh"))) break; switch (c) { case 'j': print_mjpeg = 1; break; case 'e': stop_on_errors = 0; break; case 'h': default: usage(argv[0]); exit(1); } } if (optind == argc) { usage(argv[0]); exit(1); } if (!(f=fopen(argv[optind],"rb"))) { printf("\n\n *** Error opening file %s. Program aborted!\n", argv[optind]); return(1); } fseeko(f, 0, SEEK_END); filesize = ftello(f); fseeko(f, 0, SEEK_SET); printf("Contents of file %s (%s/0x%s bytes):\n\n",argv[optind], off_t_to_char(filesize,10,1), off_t_to_char(filesize,16,1)); for (filepos = 0; filepos < filesize;) { chunksize = 0; if (!ProcessChunk(f,filepos,filesize,RIFFtag,0,&chunksize)) break; filepos += chunksize + 8; printf("\n"); } return(0); } xawtv-3.106/console/streamer.c000066400000000000000000000310571343350355000163330ustar00rootroot00000000000000/* * (c) 1997-2001 Gerd Knorr * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "grab-ng.h" #include "writefile.h" #include "channel.h" #include "sound.h" #include "capture.h" #include "commands.h" /* ---------------------------------------------------------------------- */ static int bufcount = 16; static int parallel = 1; static char* tvnorm = NULL; static char* input = NULL; static char* moviename = NULL; static char* audioname = NULL; static char* vfmt_name; static char* afmt_name; static const struct ng_writer *writer; static const void *video_priv; static const void *audio_priv; static struct ng_video_fmt video = { .width = 320, .height = 240, }; static struct ng_audio_fmt audio = { .rate = 44100, }; static void *movie_state; static int absframes = 1; static int quiet = 0, fps = 10000; static int signaled = 0, wait_seconds = 0; int debug = 0, have_dga = 0; /* ---------------------------------------------------------------------- */ static void list_formats(FILE *out) { struct list_head *item; const struct ng_writer *wr; int j; fprintf(out,"\nmovie writers:\n"); list_for_each(item,&ng_writers) { wr = list_entry(item, struct ng_writer, list); fprintf(out," %s - %s\n",wr->name, wr->desc ? wr->desc : "-"); if (NULL != wr->video) { fprintf(out," video formats:\n"); for (j = 0; NULL != wr->video[j].name; j++) { fprintf(out," %-7s %-28s [%s]\n",wr->video[j].name, wr->video[j].desc ? wr->video[j].desc : ng_vfmt_to_desc[wr->video[j].fmtid], wr->video[j].ext); } } if (NULL != wr->audio) { fprintf(out," audio formats:\n"); for (j = 0; NULL != wr->audio[j].name; j++) { fprintf(out," %-7s %-28s [%s]\n",wr->audio[j].name, wr->audio[j].desc ? wr->audio[j].desc : ng_afmt_to_desc[wr->audio[j].fmtid], wr->audio[j].ext ? wr->audio[j].ext : "-"); } } fprintf(out,"\n"); } } static void usage(FILE *out) { fprintf(out, "streamer grabs image(s), records movies and sound\n" "\n" "usage: streamer [ options ]\n" "\n" "general options:\n" " -h print this help text\n" " -q quiet operation\n" " -d enable debug output\n" " -p n use n compression threads [%d]\n" " -w seconds wait before grabbing [%d]\n" "\n" "video options:\n" " -o file video/movie file name\n" " -f format specify video format\n" " -c device specify video4linux device [%s]\n" " -D driver specify video4linux driver [%s]\n" " -r fps frame rate [%d.%03d]\n" " -s size specify size [%dx%d]\n" "\n" " -t times number of frames or hh:mm:ss [%d]\n" " -b buffers specify # of buffers [%d]\n" " -j quality quality for mjpeg or jpeg [%d]\n" " -n tvnorm set pal/ntsc/secam\n" " -i input set video source\n" " -a don't unmute/mute v4l device.\n" "\n" "audio options:\n" " -O file wav file name\n" " -F format specify audio format\n" " -C device specify dsp device [%s]\n" " -R rate sample rate [%d]\n" "\n", parallel,wait_seconds, ng_dev.video, ng_dev.driver, fps/1000, fps%1000, video.width, video.height, absframes, bufcount, ng_jpeg_quality, ng_dev.dsp, audio.rate ); list_formats(out); fprintf(out, "If you want to capture to multiple image files you should include some\n" "digits into the movie filename (foo0000.jpeg for example), streamer will\n" "use the digit block to enumerate the image files.\n" "\n" "For file formats which can hold *both* audio and video (like AVI and\n" "QuickTime) the -O option has no effect.\n" "\n" "streamer will use the file extention of the output file name to figure\n" "which format to use. You need the -f/-F options only if the extention\n" "allows more than one format.\n" "\n" "Examples:\n" " capture a single frame:\n" " streamer -o foobar.ppm\n" "\n" " capture ten frames, two per second:\n" " streamer -t 10 -r 2 -o foobar00.jpeg\n" "\n" " record 30 seconds stereo sound:\n" " streamer -t 0:30 -O soundtrack.wav -F stereo\n" "\n" " record a quicktime movie with sound:\n" " streamer -t 0:30 -o movie.mov -f jpeg -F mono16\n" "\n" " build mpeg movies using mjpegtools + compressed avi file:\n" " streamer -t 0:30 -s 352x240 -r 24 -o movie.avi -f mjpeg -F stereo\n" " lav2wav +p movie.avi | mp2enc -o audio.mp2\n" " lav2yuv +p movie.avi | mpeg2enc -o video.m1v\n" " mplex audio.mp2 video.m1v -o movie.mpg\n" "\n" " build mpeg movies using mjpegtools + raw, uncompressed video:\n" " streamer -t 0:30 -s 352x240 -r 24 -o video.yuv -O audio.wav -F stereo\n" " mp2enc -o audio.mp2 < audio.wav\n" " mpeg2enc -o video.m1v < video.yuv\n" " mplex audio.mp2 video.m1v -o movie.mpg\n" "\n" "-- \n" "(c) 1998-2001 Gerd Knorr \n"); } /* ---------------------------------------------------------------------- */ static void find_formats(void) { struct list_head *item; const struct ng_writer *wr = NULL; char *mext = NULL; char *aext = NULL; int v=-1,a=-1; if (moviename) { mext = strrchr(moviename,'.'); if (mext) mext++; } if (audioname) { aext = strrchr(audioname,'.'); if (aext) aext++; } list_for_each(item,&ng_writers) { wr = list_entry(item, struct ng_writer, list); if (debug) fprintf(stderr,"checking writer %s [%s] ...\n",wr->name,wr->desc); if ((/*!wr->combined && */mext) || NULL != vfmt_name) { if (NULL == wr->video) { if (debug) fprintf(stderr," no video, skipping\n"); continue; } for (v = 0; NULL != wr->video[v].name; v++) { if (debug) fprintf(stderr," video name=%s ext=%s: ", wr->video[v].name,wr->video[v].ext); if (mext && 0 != strcasecmp(wr->video[v].ext,mext)) { if (debug) fprintf(stderr,"ext mismatch [need %s]\n",mext); continue; } if (vfmt_name && 0 != strcasecmp(wr->video[v].name,vfmt_name)) { if (debug) fprintf(stderr,"name mismatch [need %s]\n",vfmt_name); continue; } if (debug) fprintf(stderr,"OK\n"); break; } if (NULL == wr->video[v].name) continue; } if ((!wr->combined && aext) || NULL != afmt_name) { if (NULL == wr->audio) { if (debug) fprintf(stderr," no audio, skipping\n"); continue; } for (a = 0; NULL != wr->audio[a].name; a++) { if (debug) fprintf(stderr," audio name=%s ext=%s: ", wr->audio[a].name,wr->audio[a].ext); if (!wr->combined && aext && 0 != strcasecmp(wr->audio[a].ext,aext)) { if (debug) fprintf(stderr,"ext mismatch [need %s]\n",aext); continue; } if (wr->combined && mext && 0 != strcasecmp(wr->audio[a].ext,mext)) { if (debug) fprintf(stderr,"ext mismatch [need %s]\n",mext); continue; } if (afmt_name && 0 != strcasecmp(wr->audio[a].name,afmt_name)) { if (debug) fprintf(stderr,"name mismatch [need %s]\n",afmt_name); continue; } if (debug) fprintf(stderr,"OK\n"); break; } if (NULL == wr->audio[a].name) continue; } break; } if (item != &ng_writers) { writer = wr; if (-1 != v) { video.fmtid = wr->video[v].fmtid; video_priv = wr->video[v].priv; } if (-1 != a) { audio.fmtid = wr->audio[a].fmtid; audio_priv = wr->audio[a].priv; } } else { if (debug) fprintf(stderr,"no match found\n"); } } static int parse_time(char *time) { int hours, minutes, seconds, total=0; if (3 == sscanf(time,"%d:%d:%d",&hours,&minutes,&seconds)) total = hours * 60*60 + minutes * 60 + seconds; else if (2 == sscanf(time,"%d:%d",&minutes,&seconds)) total = minutes * 60 + seconds; if (0 != total) { /* hh:mm:ss => framecount */ return total * fps / 1000; } return atoi(time); } /* ---------------------------------------------------------------------- */ static void do_rec_status(char *message) { if (!quiet) fprintf(stderr,"%s \r",message); } static void ctrlc(int signal) { static char text[] = "^C - one moment please\n"; if (!quiet) write(2,text,strlen(text)); signaled=1; } int main(int argc, char **argv) { int c,queued=0,noaudio=0; char *raw_length=NULL; /* parse options */ ng_init(); for (;;) { if (-1 == (c = getopt(argc, argv, "haqdp:w:" "o:c:f:r:s:t:n:i:b:j:D:" "O:C:F:R:"))) break; switch (c) { /* general options */ case 'q': quiet = 1; break; case 'a': noaudio = 1; break; case 'd': debug++; ng_debug++; break; case 'w': wait_seconds = atoi(optarg); break; case 'p': parallel = atoi(optarg); break; /* video options */ case 'o': moviename = optarg; break; case 'f': vfmt_name = optarg; break; case 'c': ng_dev.video = optarg; break; case 'D': ng_dev.driver = optarg; break; case 'r': fps = (int)(atof(optarg) * 1000 + 0.5); break; case 's': if (2 != sscanf(optarg,"%dx%d",&video.width,&video.height)) video.width = video.height = 0; break; case 't': raw_length = optarg; break; case 'b': bufcount = atoi(optarg); break; case 'j': ng_jpeg_quality = atoi(optarg); break; case 'n': tvnorm = optarg; break; case 'i': input = optarg; break; /* audio options */ case 'O': audioname = optarg; break; case 'F': afmt_name = optarg; break; case 'C': ng_dev.dsp = optarg; break; case 'R': audio.rate = atoi(optarg); break; /* errors / help */ case 'h': usage(stdout); exit(0); default: usage(stderr); exit(1); } } if (raw_length) absframes = parse_time(raw_length); find_formats(); /* sanity checks */ if (video.fmtid == VIDEO_NONE && audio.fmtid == AUDIO_NONE) { fprintf(stderr,"neither audio nor video format specified/found\n"); exit(1); } if (NULL == writer) { fprintf(stderr,"no output driver found\n"); exit(1); } if (audio.fmtid != AUDIO_NONE && !writer->combined && NULL == audioname) { fprintf(stderr,"no audio file name specified\n"); exit(1); } /* set hooks */ rec_status = do_rec_status; /* open */ if (writer && !quiet) fprintf(stderr,"%s / video: %s / audio: %s\n",writer->name, ng_vfmt_to_desc[video.fmtid],ng_afmt_to_desc[audio.fmtid]); if (video.fmtid != VIDEO_NONE) { drv = ng_vid_open(&ng_dev.video,ng_dev.driver,NULL,0,&h_drv); if (NULL == drv) { fprintf(stderr,"no grabber device available\n"); exit(1); } f_drv = drv->capabilities(h_drv); add_attrs(drv->list_attrs(h_drv)); if (!(f_drv & CAN_CAPTURE)) { fprintf(stderr,"%s: capture not supported\n",drv->name); exit(1); } if (!noaudio) audio_on(); audio_init(); /* modify settings */ if (input != NULL) do_va_cmd(2,"setinput",input); if (tvnorm != NULL) do_va_cmd(2,"setnorm",tvnorm); } /* init movie writer */ ng_ratio_x = video.width; ng_ratio_y = video.height; movie_state = movie_writer_init (moviename, audioname, writer, &video, video_priv, fps, &audio, audio_priv, ng_dev.dsp, bufcount, parallel); if (NULL == movie_state) { fprintf(stderr,"movie writer initialisation failed\n"); if (video.fmtid != VIDEO_NONE) { audio_off(); drv->close(h_drv); } exit(1); } /* catch ^C */ signal(SIGINT,ctrlc); /* wait for some cameras to wake up and adjust light and all that */ if (wait_seconds) sleep(wait_seconds); /* main loop */ movie_writer_start(movie_state); for (;queued < absframes && !signaled;) { if (video.fmtid != VIDEO_NONE) { /* video */ queued = movie_grab_put_video(movie_state,NULL); } else { sleep(1); queued += fps / 1000; } } movie_writer_stop(movie_state); /* done */ if (video.fmtid != VIDEO_NONE) { if (!noaudio) audio_off(); drv->close(h_drv); } return 0; } xawtv-3.106/console/ttv.c000066400000000000000000000170431343350355000153250ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include "grab-ng.h" #include "capture.h" #include "channel.h" #include "commands.h" #include "frequencies.h" #include "parseconfig.h" #include "sound.h" /* ---------------------------------------------------------------------- */ /* capture stuff */ static struct aa_hardware_params params; static aa_renderparams render; static aa_context *context; char *framebuffer; static int signaled; static char title[256]; static char message[256]; static time_t mtime; static struct ng_video_fmt fmt,gfmt; static struct ng_video_conv *conv; static struct ng_convert_handle *ch; static int fast; static void grabber_init(void) { drv = ng_vid_open(&ng_dev.video,ng_dev.driver,NULL,0,&h_drv); if (NULL == drv) { fprintf(stderr,"no grabber device available\n"); exit(1); } f_drv = drv->capabilities(h_drv); add_attrs(drv->list_attrs(h_drv)); } static void new_title(char *txt) { strcpy(title,txt); } static void new_message(char *txt) { mtime = time(NULL); strcpy(message,txt); } static void do_capture(int from, int to, int tmp_switch) { /* off */ switch (from) { case CAPTURE_GRABDISPLAY: if (f_drv & CAN_CAPTURE) drv->stopvideo(h_drv); break; } /* on */ switch (to) { case CAPTURE_GRABDISPLAY: /* try native */ fmt.fmtid = VIDEO_GRAY; fmt.width = aa_imgwidth(context); fmt.height = aa_imgheight(context); if (0 != ng_grabber_setformat(&fmt,1)) { gfmt = fmt; if (NULL == (conv = ng_grabber_findconv(&gfmt,0))) { fprintf(stderr,"can't capture gray data\n"); exit(1); } ch = ng_convert_alloc(conv,&gfmt,&fmt); ng_convert_init(ch); } if (f_drv & CAN_CAPTURE) drv->startvideo(h_drv,-1,2); break; } } static void blitframe(struct ng_video_buf *buf) { int w,h,y; char *s,*d; #if 0 /* debug */ fprintf(stdout,"P5\n%d %d\n255\n",buf->fmt.width,buf->fmt.height); fwrite(buf->data,buf->fmt.width,buf->fmt.height,stdout); exit(1); #endif if (buf->fmt.width == aa_imgwidth(context) && buf->fmt.height == aa_imgheight(context)) { memcpy(framebuffer,buf->data,buf->fmt.width*buf->fmt.height); } else { s = buf->data; d = framebuffer; if (buf->fmt.height < aa_imgheight(context)) { h = buf->fmt.height; d += (aa_imgheight(context)-buf->fmt.height)/2 * aa_imgwidth(context); } else { h = aa_imgheight(context); s += (buf->fmt.height-aa_imgheight(context))/2 * buf->fmt.width; } if (buf->fmt.width < aa_imgwidth(context)) { w = buf->fmt.width; d += (aa_imgwidth(context)-buf->fmt.width)/2; } else { w = aa_imgwidth(context); s += (buf->fmt.width-aa_imgwidth(context))/2; } for (y = 0; y < h; y++) { memcpy(d,s,w); s += buf->fmt.width; d += aa_imgwidth(context); } } } /* ----------------------------------------------------------------------- */ static void aa_cleanup(void) { aa_uninitkbd(context); aa_close(context); } static void ctrlc(int signal) { signaled++; } static void usage(void) { printf("ttv -- watch tv on a ascii terminal using aalib\n" "\n" "ttv options:\n" " -h print this text\n" " -f use fast aalib render function\n" " -c video device [%s]\n" " -D video driver [%s]\n" "\n" "aalib options:\n" "%s", ng_dev.video,ng_dev.driver,aa_help); exit(1); } int main(int argc, char **argv) { struct ng_video_buf *buf; unsigned long freq; int c,i,key,frames,fps; time_t now,last; struct tm *t; ng_init(); params = aa_defparams; render = aa_defrenderparams; if (!aa_parseoptions (¶ms, &render, &argc, argv)) usage(); for (;;) { c = getopt(argc, argv, "vfhc:D:"); if (c == -1) break; switch (c) { case 'v': debug++; ng_debug++; break; case 'f': fast++; break; case 'c': ng_dev.video = optarg; break; case 'D': ng_dev.driver = optarg; break; case 'h': default: usage(); break; } } /* init aalib */ context = aa_autoinit(¶ms); if (context == NULL) { printf("Failed to initialize aalib\n"); exit (1); } aa_autoinitkbd(context,0); atexit(aa_cleanup); framebuffer = aa_image(context); /* init v4l */ grabber_init(); freq_init(); read_config(NULL,NULL,NULL); ng_ratio_x = 0; ng_ratio_y = 0; /* init mixer */ if (0 != strlen(mixerdev)) { struct ng_attribute *attr; if (NULL != (attr = ng_mix_init(mixerdev,mixerctl))) add_attrs(attr); } /* set hooks (command.c) */ update_title = new_title; display_message = new_message; set_capture_hook = do_capture; /* init hardware */ attr_init(); audio_on(); audio_init(); /* build channel list */ parse_config(1); do_va_cmd(2,"setfreqtab",(-1 != chantab) ? chanlist_names[chantab].str : "europe-west"); cur_capture = 0; do_va_cmd(2,"capture","grabdisplay"); if (optind+1 == argc) { do_va_cmd(2,"setstation",argv[optind]); } else { if ((f_drv & CAN_TUNE) && 0 != (freq = drv->getfreq(h_drv))) { for (i = 0; i < chancount; i++) if (chanlist[i].freq == freq*1000/16) { do_va_cmd(2,"setchannel",chanlist[i].name); break; } } if (-1 == cur_channel) { if (count > 0) do_va_cmd(2,"setstation","0"); else set_defaults(); } } /* catch ^C */ signal(SIGINT,ctrlc); signal(SIGTERM,ctrlc); signal(SIGQUIT,ctrlc); /* main loop */ last = now = time(NULL); frames = fps = 0; for (;!signaled;) { /* time + performance */ now = time(NULL); t = localtime(&now); frames++; if (now - last >= 5) { fps = frames * 10 / (now-last); last = now; frames = 0; } /* grab + convert frame */ if (NULL == (buf = ng_grabber_grab_image(0))) { fprintf(stderr,"capturing image failed\n"); exit(1); } if (ch) buf = ng_convert_frame(ch,NULL,buf); /* blit frame */ blitframe(buf); ng_release_video_buf(buf); if (fast) aa_fastrender(context, 0, 0, aa_scrwidth (context), aa_scrheight (context)); else aa_render(context, &render, 0, 0, aa_scrwidth (context), aa_scrheight (context)); if (now - mtime < 6) { aa_printf(context,0,0,AA_NORMAL,"[ %s ] ", message); } else { aa_printf(context,0,0,AA_NORMAL,"[ %s - %d.%d fps - %02d:%02d ] ", title,fps/10,fps%10,t->tm_hour,t->tm_min); } aa_flush(context); /* check for keys */ key = aa_getkey(context,0); switch (key) { case 'q': case 'Q': case 'e': case 'E': case 'x': case 'X': audio_off(); signaled++; break; case 'd': case 'D': mtime = time(NULL); sprintf(message,"debug: scr=%dx%d / img=%dx%d / cap=%dx%d", aa_scrwidth(context),aa_scrheight(context), aa_imgwidth(context),aa_imgheight(context), fmt.width,fmt.height); break; case '+': do_va_cmd(2,"volume","inc"); break; case '-': do_va_cmd(2,"volume","dec"); break; case 10: case 13: do_va_cmd(2,"volume","mute"); break; case AA_UP: do_va_cmd(2,"setchannel","next"); break; case AA_DOWN: do_va_cmd(2,"setchannel","prev"); break; case AA_RIGHT: do_va_cmd(2,"setchannel","fine_up"); break; case AA_LEFT: do_va_cmd(2,"setchannel","fine_down"); break; case ' ': do_va_cmd(2,"setstation","next"); break; default: /* nothing */ break; } } exit(0); } xawtv-3.106/console/v4l-conf.c000066400000000000000000000365661343350355000161530ustar00rootroot00000000000000/* * Set the framebuffer parameters for bttv. * tries to ask the X-Server if $DISPLAY is set, * otherwise it checks /dev/fb0 * * (c) 1998-2001 Gerd Knorr * * Security checks by okir@caldera.de */ #include "config.h" #ifdef MAJOR_IN_SYSMACROS # include #endif #ifdef MAJOR_IN_MKDEV # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_GETOPT_H # include #endif #ifndef X_DISPLAY_MISSING # include # include # ifdef HAVE_LIBXXF86DGA # include # endif #endif #include #include "videodev2.h" struct DISPLAYINFO { int width; /* visible display width (pixels) */ int height; /* visible display height (pixels) */ int depth; /* color depth */ int bpp; /* bit per pixel */ int bpl; /* bytes per scanline */ unsigned char *base; }; int verbose = 1; int yuv = 0; int user_bpp = 0; int user_shift = 0; int user_bpl = 0; void *user_base = NULL; char *display = NULL; char *fbdev = NULL; char *videodev = "/dev/video0"; /* ---------------------------------------------------------------- */ /* this is required for MkLinux */ #ifdef __powerpc__ struct vc_mode { int height; int width; int depth; int pitch; int mode; char name[32]; unsigned long fb_address; unsigned long cmap_adr_address; unsigned long cmap_data_address; unsigned long disp_reg_address; }; #define VC_GETMODE 0x7667 #define VC_SETMODE 0x7668 #define VC_INQMODE 0x7669 #define VC_SETCMAP 0x766a #define VC_GETCMAP 0x766b static int is_mklinux(void) { int fd; if(-1 == (fd = open("/proc/osfmach3", O_RDONLY))) return 0; close(fd); return 1; } static void displayinfo_mklinux(struct DISPLAYINFO *d) { struct vc_mode mode; int fd; if (verbose) fprintf(stderr,"v4l-conf: using mklinux console driver\n"); if (-1 == (fd = open("/dev/console",O_RDWR|O_NDELAY))) { fprintf(stderr,"open console: %s\n",strerror(errno)); exit(1); } if (-1 == ioctl(fd, VC_GETMODE, (unsigned long)&mode)) { perror("ioctl VC_GETMODE"); exit(1); } close(fd); d->width = mode.width; d->height = mode.height; d->bpp = mode.depth; d->bpl = mode.pitch; d->base = (void*)mode.fb_address; } #endif /* ---------------------------------------------------------------- */ #ifndef major # define major(dev) (((dev) >> 8) & 0xff) #endif static int dev_open(const char *device, int major) { struct stat stb; int fd; if (strncmp(device, "/dev/", 5)) { fprintf(stderr, "error: %s is not a /dev file\n", device); exit(1); } /* open & check v4l device */ if (-1 == (fd = open(device,O_RDWR))) { fprintf(stderr, "can't open %s: %s\n", device, strerror(errno)); exit(1); } if (-1 == fstat(fd,&stb)) { fprintf(stderr, "fstat(%s): %s\n", device, strerror(errno)); exit(1); } if (!S_ISCHR(stb.st_mode) || (major(stb.st_rdev) != major)) { fprintf(stderr, "%s: wrong device\n", device); exit(1); } return fd; } static void real_user(void) { if (-1 == seteuid(getuid())) { perror("seteuid(user)"); exit(1); } } static void root_user(void) { if (-1 == seteuid(0)) { perror("seteuid(root)"); exit(1); } } /* ---------------------------------------------------------------- */ /* get mode info */ #ifndef X_DISPLAY_MISSING static void displayinfo_x11(Display *dpy, struct DISPLAYINFO *d) { Window root; XVisualInfo *info, template; XPixmapFormatValues *pf; XWindowAttributes wts; int found,v,i,n; if (verbose) fprintf(stderr,"v4l-conf: using X11 display %s\n",display); /* take size from root window */ root = DefaultRootWindow(dpy); XGetWindowAttributes(dpy, root, &wts); d->width = wts.width; d->height = wts.height; /* look for a usable visual */ template.screen = XDefaultScreen(dpy); info = XGetVisualInfo(dpy, VisualScreenMask,&template,&found); v = -1; for (i = 0; v == -1 && i < found; i++) if (info[i].class == TrueColor && info[i].depth >= 15) v = i; for (i = 0; v == -1 && i < found; i++) if (info[i].class == StaticGray && info[i].depth == 8) v = i; if (-1 == v) { fprintf(stderr,"x11: no approximate visual available\n"); exit(1); } /* get depth + bpp (heuristic) */ pf = XListPixmapFormats(dpy,&n); for (i = 0; i < n; i++) { if (pf[i].depth == info[v].depth) { d->depth = pf[i].depth; d->bpp = pf[i].bits_per_pixel; d->bpl = d->bpp * d->width / 8; break; } } if (0 == d->bpp) { fprintf(stderr,"x11: can't detect framebuffer depth\n"); exit(1); } } #ifdef HAVE_LIBXXF86DGA static int dga_error = 0; static int dga_error_base; static int (*orig_xfree_error_handler)(Display *, XErrorEvent *); static int dga_error_handler(Display *d, XErrorEvent *e) { if (e->error_code == (dga_error_base + XF86DGANoDirectVideoMode)) { dga_error = 1; return 0; } return orig_xfree_error_handler(d, e); } #endif static void displayinfo_dga(Display *dpy, struct DISPLAYINFO *d) { #ifdef HAVE_LIBXXF86DGA int width,bar,foo,major,minor,flags=0; void *base = NULL; if (!XF86DGAQueryExtension(dpy,&foo,&dga_error_base)) { fprintf(stderr,"WARNING: Your X-Server has no DGA support.\n"); return; } XF86DGAQueryVersion(dpy,&major,&minor); if (verbose) fprintf(stderr,"dga: version %d.%d\n",major,minor); XF86DGAQueryDirectVideo(dpy,XDefaultScreen(dpy),&flags); if (!(flags & XF86DGADirectPresent)) { fprintf(stderr,"WARNING: No DGA support available for this display.\n"); return; } orig_xfree_error_handler = XSetErrorHandler(dga_error_handler); if (!XF86DGAGetVideoLL(dpy,XDefaultScreen(dpy),(void*)&base,&width,&foo,&bar)) dga_error = 1; XSync(dpy, 0); XSetErrorHandler(orig_xfree_error_handler); if (dga_error) { fprintf(stderr,"WARNING: No DGA direct video mode for this display.\n"); return; } d->bpl = width * d->bpp/8; d->base = base; #else fprintf(stderr,"WARNING: v4l-conf is compiled without DGA support.\n"); #endif } #endif static void displayinfo_fbdev(struct DISPLAYINFO *d) { struct fb_fix_screeninfo fix; struct fb_var_screeninfo var; struct fb_con2fbmap c2m; struct vt_stat vstat; int fd; if (NULL == fbdev) { if (-1 == (fd = open("/dev/tty",O_RDWR,0))) { fprintf(stderr,"open /dev/tty: %s\n",strerror(errno)); exit(1); } if (-1 == ioctl(fd, VT_GETSTATE, &vstat)) { perror("VT_GETSTATE is not supported"); return; } close(fd); c2m.console = vstat.v_active; if (-1 == (fd = open("/dev/fb0",O_RDWR,0))) { fprintf(stderr,"open /dev/fb0: %s\n",strerror(errno)); exit(1); } if (-1 == ioctl(fd, FBIOGET_CON2FBMAP, &c2m)) { perror("ioctl FBIOGET_CON2FBMAP"); c2m.framebuffer = 0; } close(fd); fprintf(stderr,"map: vt%02d => fb%d\n",c2m.console,c2m.framebuffer); sprintf(fbdev=malloc(16),"/dev/fb%d",c2m.framebuffer); } if (verbose) fprintf(stderr,"v4l-conf: using framebuffer device %s\n",fbdev); /* Open frame buffer device, with security checks */ fd = dev_open(fbdev, 29 /* VIDEO_MAJOR */); if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,&fix)) { perror("ioctl FBIOGET_FSCREENINFO"); exit(1); } if (-1 == ioctl(fd,FBIOGET_VSCREENINFO,&var)) { perror("ioctl FBIOGET_VSCREENINFO"); exit(1); } if (fix.type != FB_TYPE_PACKED_PIXELS) { fprintf(stderr,"can handle only packed pixel frame buffers\n"); exit(1); } close(fd); d->width = var.xres_virtual; d->height = var.yres_virtual; d->bpp = var.bits_per_pixel; d->bpl = fix.line_length; d->base = (unsigned char*)fix.smem_start; d->depth = d->bpp; if (var.green.length == 5) d->depth = 15; } /* ---------------------------------------------------------------- */ /* set mode info */ static int displayinfo_v4l2(int fd, struct DISPLAYINFO *d) { struct v4l2_capability cap; struct v4l2_framebuffer fb; if (-1 == ioctl(fd,VIDIOC_QUERYCAP,&cap)) { if (verbose) fprintf(stderr,"%s [v4l2]: ioctl VIDIOC_QUERYCAP: %s\n", videodev,strerror(errno)); return -1; } if (!(cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)) { fprintf(stderr,"%s [v4l2]: no overlay support\n",videodev); exit(1); } /* read-modify-write v4l screen parameters */ if (-1 == ioctl(fd,VIDIOC_G_FBUF,&fb)) { fprintf(stderr,"%s [v4l2]: ioctl VIDIOC_G_FBUF: %s\n", videodev,strerror(errno)); exit(1); } /* set values */ fb.fmt.width = d->width; fb.fmt.height = d->height; switch (d->bpp) { case 8: fb.fmt.pixelformat = V4L2_PIX_FMT_HI240; break; #if BYTE_ORDER == BIG_ENDIAN case 15: fb.fmt.pixelformat = V4L2_PIX_FMT_RGB555X; break; case 16: fb.fmt.pixelformat = V4L2_PIX_FMT_RGB565X; break; case 24: fb.fmt.pixelformat = V4L2_PIX_FMT_RGB24; break; case 32: fb.fmt.pixelformat = V4L2_PIX_FMT_RGB32; break; #else case 15: fb.fmt.pixelformat = V4L2_PIX_FMT_RGB555; break; case 16: fb.fmt.pixelformat = V4L2_PIX_FMT_RGB565; break; case 24: fb.fmt.pixelformat = V4L2_PIX_FMT_BGR24; break; case 32: fb.fmt.pixelformat = V4L2_PIX_FMT_BGR32; break; #endif } if (yuv) fb.fmt.pixelformat = V4L2_PIX_FMT_YUYV; /* Prefer an already configured bpl (if it makes sense) over our found bpl if we did not find a base as our bpl is not very reliable when we did not find a base */ if (user_bpl || d->base || fb.fmt.bytesperline < (fb.fmt.width * ((d->bpp + 7) / 8))) fb.fmt.bytesperline = d->bpl; else fprintf(stderr,"WARNING: keeping fbuf pitch at: %d, as no base addr was detected\n", (int)fb.fmt.bytesperline); fb.fmt.sizeimage = fb.fmt.height * fb.fmt.bytesperline; if (NULL != d->base) fb.base = d->base; if (NULL == fb.base) fprintf(stderr, "WARNING: couldn't find framebuffer base address, try manual\n" " configuration (\"v4l-conf -a \")\n"); if (-1 == ioctl(fd,VIDIOC_S_FBUF,&fb)) { fprintf(stderr,"%s [v4l2]: ioctl VIDIOC_S_FBUF: %s\n", videodev,strerror(errno)); if (EPERM == errno && 0 != geteuid()) fprintf(stderr, "v4l-conf: You should install me suid root, I need\n" " root priviliges for the VIDIOC_S_FBUF ioctl.\n"); exit(1); } if (verbose) fprintf(stderr,"%s [v4l2]: configuration done\n",videodev); return 0; } /* ---------------------------------------------------------------- */ int main(int argc, char *argv[]) { struct DISPLAYINFO d; int fd,c,i,n; char *h; #ifndef X_DISPLAY_MISSING Display *dpy; #endif /* we don't need root proviliges for now ... */ real_user(); /* Make sure fd's 0 1 2 are open, otherwise * we might end up sending perror() messages to * the `device' file */ for (i = 0; i < 3; i++) { if (-1 == fcntl(i, F_GETFL, &n)) exit(1); } /* take defaults from environment */ if (NULL != (h = getenv("DISPLAY"))) display = h; if (NULL != (h = getenv("FRAMEBUFFER"))) fbdev = h; /* parse options */ for (;;) { if (-1 == (c = getopt(argc, argv, "hyq12d:c:b:s:fa:p:"))) break; switch (c) { case 'q': verbose = 0; break; case 'y': yuv = 1; break; case 'd': display = optarg; break; case 'c': videodev = optarg; break; case 'b': user_bpp = atoi(optarg); break; case 's': user_shift = atoi(optarg); if (user_shift < 0 || user_shift > 8192) user_shift = 0; break; case 'f': display = NULL; break; case 'a': if (0 == getuid()) { /* only root is allowed to set this, and it will work only * if v4l-conf can't figure out the correct address itself. * Useful for "post-install bttv ..." */ sscanf(optarg,"%p",&user_base); } else { fprintf(stderr,"only root is allowed to use the -a option\n"); exit(1); } break; case 'p': if (0 == getuid()) { sscanf(optarg,"%d",&user_bpl); } else { fprintf(stderr,"only root is allowed to use the -p option\n"); exit(1); } break; case 'h': default: fprintf(stderr, "usage: %s [ options ] \n" "\n" "options:\n" " -q quiet\n" #ifndef X_DISPLAY_MISSING " -d X11 Display [%s]\n" #endif " -c video device [%s]\n" " -b displays color depth is bpp\n" " -s shift display by bytes\n" " -f query frame buffer device for info\n" " -a set framebuffer address to \n" " (in hex, root only, successful autodetect\n" " will overwrite this address)\n" " -p set framebuffer pitch to bytes\n" " (decimal, root only)\n" " -1 force v4l API\n" " -2 force v4l2 API\n", argv[0], #ifndef X_DISPLAY_MISSING display ? display : "none", #endif videodev); exit(1); } } /* figure out display parameters */ memset(&d,0,sizeof(struct DISPLAYINFO)); #ifdef __powerpc__ if (is_mklinux()) { displayinfo_mklinux(&d); } else #endif #ifndef X_DISPLAY_MISSING if (NULL != display) { /* using X11 */ if (display[0] != ':') { fprintf(stderr,"WARNING: remote display `%s' not allowed, ", display); display = strchr(display,':'); if (NULL == display) { fprintf(stderr,"exiting"); exit(1); } else { fprintf(stderr,"using `%s' instead\n",display); } } if (NULL == (dpy = XOpenDisplay(display))) { fprintf(stderr,"can't open x11 display %s\n",display); exit(1); } displayinfo_x11(dpy,&d); displayinfo_dga(dpy,&d); } else #endif { /* try framebuffer device */ displayinfo_fbdev(&d); } /* fixup struct displayinfo according to the given command line options */ if (user_base) { if (NULL == d.base) { fprintf(stderr,"using user provided base address %p\n",user_base); d.base = user_base; } else { fprintf(stderr,"user provided base address %p ignored.\n", user_base); } } if (d.base) d.base += user_shift; if ((user_bpp == 24 || user_bpp == 32) && (d.bpp == 24 || d.bpp == 32)) { d.bpp = user_bpp; d.bpl = d.width * d.bpp/8; } if ((user_bpp == 15 || user_bpp == 16) && (d.depth == 15 || d.depth == 16)) d.depth = user_bpp; if (user_bpl) d.bpl = user_bpl; if (verbose) { fprintf(stderr,"mode: %dx%d, depth=%d, bpp=%d, bpl=%d, ", d.width,d.height,d.depth,d.bpp,d.bpl); if (NULL != d.base) fprintf(stderr,"base=%p\n",d.base); else fprintf(stderr,"base=unknown\n"); } /* Set the parameters (needs root) */ root_user(); fd = dev_open(videodev, 81 /* VIDEO_MAJOR */); displayinfo_v4l2(fd,&d); close(fd); return 0; } xawtv-3.106/console/v4l-info.c000066400000000000000000000127621343350355000161510ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include "videodev2.h" #include "struct-dump.h" #include "struct-v4l2.h" /* --------------------------------------------------------------------- */ /* v4l2 */ static int dump_v4l2(int fd, int tab) { struct v4l2_capability capability; struct v4l2_standard standard; struct v4l2_input input; struct v4l2_tuner tuner; struct v4l2_fmtdesc fmtdesc; struct v4l2_format format; struct v4l2_framebuffer fbuf; struct v4l2_queryctrl qctrl; int i; printf("general info\n"); memset(&capability,0,sizeof(capability)); if (-1 == ioctl(fd,VIDIOC_QUERYCAP,&capability)) return -1; printf(" VIDIOC_QUERYCAP\n"); print_struct(stdout,desc_v4l2_capability,&capability,"",tab); printf("\n"); printf("standards\n"); for (i = 0;; i++) { memset(&standard,0,sizeof(standard)); standard.index = i; if (-1 == ioctl(fd,VIDIOC_ENUMSTD,&standard)) break; printf(" VIDIOC_ENUMSTD(%d)\n",i); print_struct(stdout,desc_v4l2_standard,&standard,"",tab); } printf("\n"); printf("inputs\n"); for (i = 0;; i++) { memset(&input,0,sizeof(input)); input.index = i; if (-1 == ioctl(fd,VIDIOC_ENUMINPUT,&input)) break; printf(" VIDIOC_ENUMINPUT(%d)\n",i); print_struct(stdout,desc_v4l2_input,&input,"",tab); } printf("\n"); if (capability.capabilities & V4L2_CAP_TUNER) { printf("tuners\n"); for (i = 0;; i++) { memset(&tuner,0,sizeof(tuner)); tuner.index = i; if (-1 == ioctl(fd,VIDIOC_G_TUNER,&tuner)) break; printf(" VIDIOC_G_TUNER(%d)\n",i); print_struct(stdout,desc_v4l2_tuner,&tuner,"",tab); } printf("\n"); } if (capability.capabilities & V4L2_CAP_VIDEO_CAPTURE) { printf("video capture\n"); for (i = 0;; i++) { memset(&fmtdesc,0,sizeof(fmtdesc)); fmtdesc.index = i; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)) break; printf(" VIDIOC_ENUM_FMT(%d,VIDEO_CAPTURE)\n",i); print_struct(stdout,desc_v4l2_fmtdesc,&fmtdesc,"",tab); } memset(&format,0,sizeof(format)); format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl(fd,VIDIOC_G_FMT,&format)) { perror("VIDIOC_G_FMT(VIDEO_CAPTURE)"); } else { printf(" VIDIOC_G_FMT(VIDEO_CAPTURE)\n"); print_struct(stdout,desc_v4l2_format,&format,"",tab); } printf("\n"); } if (capability.capabilities & V4L2_CAP_VIDEO_OVERLAY) { printf("video overlay\n"); for (i = 0;; i++) { memset(&fmtdesc,0,sizeof(fmtdesc)); fmtdesc.index = i; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; if (-1 == ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)) break; printf(" VIDIOC_ENUM_FMT(%d,VIDEO_OVERLAY)\n",i); print_struct(stdout,desc_v4l2_fmtdesc,&fmtdesc,"",tab); } memset(&format,0,sizeof(format)); format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; if (-1 == ioctl(fd,VIDIOC_G_FMT,&format)) { perror("VIDIOC_G_FMT(VIDEO_OVERLAY)"); } else { printf(" VIDIOC_G_FMT(VIDEO_OVERLAY)\n"); print_struct(stdout,desc_v4l2_format,&format,"",tab); } memset(&fbuf,0,sizeof(fbuf)); if (-1 == ioctl(fd,VIDIOC_G_FBUF,&fbuf)) { perror("VIDIOC_G_FBUF"); } else { printf(" VIDIOC_G_FBUF\n"); print_struct(stdout,desc_v4l2_framebuffer,&fbuf,"",tab); } printf("\n"); } if (capability.capabilities & V4L2_CAP_VBI_CAPTURE) { printf("vbi capture\n"); for (i = 0;; i++) { memset(&fmtdesc,0,sizeof(fmtdesc)); fmtdesc.index = i; fmtdesc.type = V4L2_BUF_TYPE_VBI_CAPTURE; if (-1 == ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)) break; printf(" VIDIOC_ENUM_FMT(%d,VBI_CAPTURE)\n",i); print_struct(stdout,desc_v4l2_fmtdesc,&fmtdesc,"",tab); } memset(&format,0,sizeof(format)); format.type = V4L2_BUF_TYPE_VBI_CAPTURE; if (-1 == ioctl(fd,VIDIOC_G_FMT,&format)) { perror("VIDIOC_G_FMT(VBI_CAPTURE)"); } else { printf(" VIDIOC_G_FMT(VBI_CAPTURE)\n"); print_struct(stdout,desc_v4l2_format,&format,"",tab); } printf("\n"); } printf("controls\n"); for (i = 0; i < V4L2_CID_LASTP1 - V4L2_CID_USER_BASE; i++) { memset(&qctrl,0,sizeof(qctrl)); qctrl.id = V4L2_CID_BASE+i; if (-1 == ioctl(fd,VIDIOC_QUERYCTRL,&qctrl)) continue; if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) continue; printf(" VIDIOC_QUERYCTRL(BASE+%d)\n",i); print_struct(stdout,desc_v4l2_queryctrl,&qctrl,"",tab); } for (i = 0;; i++) { memset(&qctrl,0,sizeof(qctrl)); qctrl.id = V4L2_CID_PRIVATE_BASE+i; if (-1 == ioctl(fd,VIDIOC_QUERYCTRL,&qctrl)) break; if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) continue; printf(" VIDIOC_QUERYCTRL(PRIVATE_BASE+%d)\n",i); print_struct(stdout,desc_v4l2_queryctrl,&qctrl,"",tab); } return 0; } /* --------------------------------------------------------------------- */ /* main */ int main(int argc, char *argv[]) { char dummy[256]; char *device = "/dev/video0"; int tab = 1; int fd; if (argc > 1) device = argv[1]; fd = open(device,O_RDONLY); if (-1 == fd) { fprintf(stderr,"open %s: %s\n",device,strerror(errno)); exit(1); }; if (-1 != ioctl(fd,VIDIOC_QUERYCAP,dummy)) { printf("\n### v4l2 device info [%s] ###\n",device); dump_v4l2(fd,tab); } else { fprintf(stderr,"%s: not an video4linux device\n",device); exit(1); } return 0; } /* * Local variables: * c-basic-offset: 8 * End: */ xawtv-3.106/console/vbi-tty.c000066400000000000000000000170141343350355000161040ustar00rootroot00000000000000/* * vbi-tty -- terminal videotext browser * * (c) 2002 Gerd Knorr */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "vbi-data.h" #include "vbi-tty.h" #include "fbtools.h" /* --------------------------------------------------------------------- */ struct termios saved_attributes; int saved_fl; static void tty_raw(void) { struct termios tattr; fcntl(0,F_GETFL,&saved_fl); tcgetattr (0, &saved_attributes); fcntl(0,F_SETFL,O_NONBLOCK); memcpy(&tattr,&saved_attributes,sizeof(struct termios)); tattr.c_lflag &= ~(ICANON|ECHO); tattr.c_cc[VMIN] = 1; tattr.c_cc[VTIME] = 0; tcsetattr (0, TCSAFLUSH, &tattr); } static void tty_restore(void) { fcntl(0,F_SETFL,saved_fl); tcsetattr (0, TCSANOW, &saved_attributes); } /* FIXME: Yes, I know, hardcoding ANSI sequences is bad. ncurses * can't handle multibyte locales like UTF-8 not yet, that's why that * dirty hack for now ... */ static void tty_clear(void) { fprintf(stderr,"\033[H\033[2J"); } static void tty_goto(int x, int y) { fprintf(stderr,"\033[%d;%dH",y,x); } /* --------------------------------------------------------------------- */ static int have_fb = 0; static int fb_fmt = VBI_PIXFMT_RGBA32_LE; static int switch_last; static void fb_clear(void) { fb_memset(fb_mem+fb_mem_offset,0,fb_fix.smem_len); } /* --------------------------------------------------------------------- */ struct vbi_tty { struct vbi_state *vbi; struct vbi_page pg; int pgno,subno; int newpage; }; static void vbi_fix_head(struct vbi_tty *tty, struct vbi_char *ch) { int showno,showsub,red,i; showno = tty->pg.pgno; showsub = tty->pg.subno; red = 0; if (0 == showno) { showno = tty->pgno; showsub = 0; red = 1; } if (tty->newpage) { showno = tty->newpage; showsub = 0; red = 1; } for (i = 1; i <= 6; i++) ch[i].unicode = ' '; if (showno >= 0x100) ch[1].unicode = '0' + ((showno >> 8) & 0xf); if (showno >= 0x10) ch[2].unicode = '0' + ((showno >> 4) & 0xf); if (showno >= 0x1) ch[3].unicode = '0' + ((showno >> 0) & 0xf); if (showsub) { ch[4].unicode = '/'; ch[5].unicode = '0' + ((showsub >> 4) & 0xf); ch[6].unicode = '0' + ((showsub >> 0) & 0xf); } if (red) { ch[1].foreground = VBI_RED; ch[2].foreground = VBI_RED; ch[3].foreground = VBI_RED; } } static void vbi_render_page(struct vbi_tty *tty) { char *data; int len; data = malloc(25*41*24); vbi_fetch_vt_page(tty->vbi->dec,&tty->pg,tty->pgno,tty->subno, VBI_WST_LEVEL_1p5,25,1); vbi_fix_head(tty,tty->pg.text); if (have_fb) { vbi_draw_vt_page_region(&tty->pg, fb_fmt, fb_mem + fb_mem_offset, fb_fix.line_length, 0,0, tty->pg.columns, tty->pg.rows, 0,1); } else { len = vbi_export_txt(data,nl_langinfo(CODESET),25*41*8, &tty->pg,&vbi_fullrect,VBI_ANSICOLOR); tty_goto(0,0); fwrite(data,len,1,stderr); tty_goto(42,0); free(data); } } static void vbi_render_head(struct vbi_tty *tty, int pgno, int subno) { static struct vbi_rect head = { .x1 = 0, .y1 = 0, .x2 = 41, .y2 = 1, }; struct vbi_page pg; char *data; int len; data = malloc(41*24); memset(&pg,0,sizeof(pg)); vbi_fetch_vt_page(tty->vbi->dec,&pg,pgno,subno, VBI_WST_LEVEL_1p5,1,1); vbi_fix_head(tty,pg.text); if (have_fb) { vbi_draw_vt_page_region(&pg, fb_fmt, fb_mem + fb_mem_offset, fb_fix.line_length, 0,0, pg.columns, 1, 0,1); } else { len = vbi_export_txt(data,nl_langinfo(CODESET),41*8, &pg,&head,VBI_ANSICOLOR); tty_goto(0,0); fwrite(data,len,1,stderr); tty_goto(42,0); free(data); } } static void vbi_newdata(struct vbi_event *ev, void *user) { struct vbi_tty *tty = user; switch (ev->type) { case VBI_EVENT_TTX_PAGE: if (tty->pgno == ev->ev.ttx_page.pgno && (tty->subno == ev->ev.ttx_page.subno || tty->subno == VBI_ANY_SUBNO)) { vbi_render_page(tty); } else { vbi_render_head(tty, ev->ev.ttx_page.pgno, ev->ev.ttx_page.subno); } break; } } static void vbi_setpage(struct vbi_tty *tty, int pgno, int subno) { tty->pgno = pgno; tty->subno = subno; tty->newpage = 0; memset(&tty->pg,0,sizeof(struct vbi_page)); vbi_fetch_vt_page(tty->vbi->dec,&tty->pg,tty->pgno,tty->subno, VBI_WST_LEVEL_1p5,25,1); vbi_render_page(tty); } /* --------------------------------------------------------------------- */ void vbi_tty(char *device, int debug, int sim) { struct vbi_state *vbi; struct vbi_tty *tty; fd_set set; struct winsize win; struct timeval tv; char key[11]; int rc,subno,last; setlocale(LC_ALL,""); vbi = vbi_open(device,debug,sim); if (NULL == vbi) exit(1); if (0 /* 0 == fb_probe() */ ) { have_fb = 1; fb_init(NULL,NULL,0); fb_catch_exit_signals(); fb_switch_init(); switch_last = fb_switch_state; } else { if (-1 != ioctl(0,TIOCGWINSZ,&win) && win.ws_row < 26) { fprintf(stderr,"Terminal too small (need 26 rows, have %d)\n", win.ws_row); exit(1); } } tty_raw(); have_fb ? fb_clear() : tty_clear(); tty = malloc(sizeof(*tty)); memset(tty,0,sizeof(*tty)); tty->vbi = vbi; vbi_event_handler_add(vbi->dec,~0,vbi_newdata,tty); vbi_setpage(tty,0x100,VBI_ANY_SUBNO); for (last = 0; !last;) { FD_ZERO(&set); FD_SET(0,&set); FD_SET(vbi->fd,&set); tv.tv_sec = 1; tv.tv_usec = 0; rc = select(vbi->fd+1,&set,NULL,NULL,&tv); if (-1 == rc) { tty_restore(); if (have_fb) fb_cleanup(); perror("select"); exit(1); } if (0 == rc) { if (have_fb) fb_cleanup(); tty_restore(); fprintf(stderr,"oops: timeout\n"); exit(1); } if (FD_ISSET(0,&set)) { /* tty input */ rc = read(0, key, 10); key[rc] = 0; if (1 == rc) { switch (key[0]) { case 'q': case 'Q': /* quit */ last = 1; break; case 'L' & 0x1f: /* refresh */ have_fb ? fb_clear() : tty_clear(); vbi_render_page(tty); break; case 'i': case 'I': /* index */ vbi_setpage(tty,0x100,VBI_ANY_SUBNO); break; case ' ': case 'l': case 'L': /* next page */ vbi_setpage(tty,vbi_calc_page(tty->pgno,+1),VBI_ANY_SUBNO); break; case '\x7f': case 'h': case 'H': /* prev page */ vbi_setpage(tty,vbi_calc_page(tty->pgno,-1),VBI_ANY_SUBNO); break; case 'k': case 'K': /* next subpage */ subno = (tty->subno != VBI_ANY_SUBNO) ? tty->subno : tty->pg.subno; subno = vbi_calc_subpage(tty->vbi->dec,tty->pgno,subno,+1); vbi_setpage(tty,tty->pgno,subno); break; case 'j': case 'J': /* prev subpage */ subno = (tty->subno != VBI_ANY_SUBNO) ? tty->subno : tty->pg.subno; subno = vbi_calc_subpage(tty->vbi->dec,tty->pgno,subno,-1); vbi_setpage(tty,tty->pgno,subno); break; default: if (key[0] >= '0' && key[0] <= '9') { tty->newpage *= 16; tty->newpage += key[0] - '0'; if (tty->newpage >= 0x100) vbi_setpage(tty,tty->newpage,VBI_ANY_SUBNO); } } } } if (FD_ISSET(vbi->fd,&set)) { vbi_hasdata(vbi); } } if (have_fb) fb_cleanup(); tty_goto(0,0); tty_restore(); } xawtv-3.106/console/vbi-tty.h000066400000000000000000000000671343350355000161110ustar00rootroot00000000000000extern void vbi_tty(char *device, int debug, int sim); xawtv-3.106/console/webcam.c000066400000000000000000000551321343350355000157470ustar00rootroot00000000000000/* * (c) 1998-2002 Gerd Knorr * * capture a image, compress as jpeg and upload to the webserver * using the ftp utility or ssh * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "grab-ng.h" #include "jpeglib.h" #include "ftp.h" #include "parseconfig.h" #include "list.h" /* ---------------------------------------------------------------------- */ /* configuration */ int daemonize = 0; char *archive = NULL; char *tmpdir; struct list_head connections; char *grab_text = "webcam %Y-%m-%d %H:%M:%S"; /* strftime */ char *grab_infofile = NULL; int grab_width = 320; int grab_height = 240; int grab_delay = 3; int grab_wait = 0; int grab_rotate = 0; int grab_top = -1; int grab_left = -1; int grab_bottom = -1; int grab_right = -1; int grab_quality= 75; int grab_trigger= 0; int grab_times = -1; int grab_fg_r = 255; int grab_fg_g = 255; int grab_fg_b = 255; int grab_bg_r = -1; int grab_bg_g = -1; int grab_bg_b = -1; char *grab_input = NULL; char *grab_norm = NULL; /* ---------------------------------------------------------------------- */ /* jpeg stuff */ static int write_file(int fd, unsigned char *data, int width, int height) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE *fp; int i; unsigned char *line; fp = fdopen(fd,"w"); cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, fp); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, grab_quality, TRUE); jpeg_start_compress(&cinfo, TRUE); for (i = 0, line = data; i < height; i++, line += width*3) jpeg_write_scanlines(&cinfo, &line, 1); jpeg_finish_compress(&(cinfo)); jpeg_destroy_compress(&(cinfo)); fclose(fp); return 0; } /* ---------------------------------------------------------------------- */ /* image transfer */ struct xfer_ops; struct xfer_state { char *name; struct list_head list; /* xfer options */ char *host; char *user; char *pass; char *dir; char *file; char *tmpfile; int debug; /* ftp options */ int passive,autologin; /* function pointers + private date */ struct xfer_ops *ops; void *data; }; struct xfer_ops { int (*open)(struct xfer_state*); void (*info)(struct xfer_state*); int (*xfer)(struct xfer_state*, char *image, int width, int height); void (*close)(struct xfer_state*); }; static int ftp_open(struct xfer_state *s) { s->data = ftp_init(s->name,s->autologin,s->passive,s->debug); ftp_connect(s->data,s->host,s->user,s->pass,s->dir); return 0; } static void ftp_info(struct xfer_state *s) { fprintf(stderr,"ftp config [%s]:\n %s@%s:%s\n %s => %s\n", s->name,s->user,s->host,s->dir,s->tmpfile,s->file); } static int ftp_xfer(struct xfer_state *s, char *image, int width, int height) { char filename[1024]; int fh; sprintf(filename,"%s/webcamXXXXXX",tmpdir); if (-1 == (fh = mkstemp(filename))) { perror("mkstemp"); exit(1); } write_file(fh, image, width, height); if (ftp_connected(s->data)) ftp_connect(s->data,s->host,s->user,s->pass,s->dir); ftp_upload(s->data,filename,s->file,s->tmpfile); unlink(filename); return 0; } static void ftp_close(struct xfer_state *s) { ftp_fini(s->data); } static struct xfer_ops ftp_ops = { .open = ftp_open, .info = ftp_info, .xfer = ftp_xfer, .close = ftp_close, }; static int ssh_open(struct xfer_state *s) { s->data = malloc(strlen(s->user)+strlen(s->host)+strlen(s->tmpfile)*2+ strlen(s->dir)+strlen(s->file)+32); sprintf(s->data, "ssh %s@%s \"cat >%s && mv %s %s/%s\"", s->user,s->host,s->tmpfile,s->tmpfile,s->dir,s->file); return 0; } static void ssh_info(struct xfer_state *s) { fprintf(stderr,"ssh config [%s]:\n %s@%s:%s\n %s => %s\n", s->name,s->user,s->host,s->dir,s->tmpfile,s->file); } static int ssh_xfer(struct xfer_state *s, char *image, int width, int height) { char filename[1024]; char *cmd = s->data; unsigned char buf[4096]; FILE *sshp, *imgdata; int len,fh; sprintf(filename,"%s/webcamXXXXXX",tmpdir); if (-1 == (fh = mkstemp(filename))) { perror("mkstemp"); exit(1); } write_file(fh, image, width, height); if ((sshp=popen(cmd, "w")) == NULL) { perror("popen"); exit(1); } if ((imgdata = fopen(filename,"rb"))==NULL) { perror("fopen"); exit(1); } for (;;) { len = fread(buf,1,sizeof(buf),imgdata); if (len <= 0) break; fwrite(buf,1,len,sshp); } fclose(imgdata); pclose(sshp); unlink(filename); return 0; } static void ssh_close(struct xfer_state *s) { char *cmd = s->data; free(cmd); } static struct xfer_ops ssh_ops = { .open = ssh_open, .info = ssh_info, .xfer = ssh_xfer, .close = ssh_close, }; static int local_open(struct xfer_state *s) { char *t; if (s->dir != NULL && s->dir[0] != '\0' ) { t = malloc(strlen(s->tmpfile)+strlen(s->dir)+2); sprintf(t, "%s/%s", s->dir, s->tmpfile); s->tmpfile = t; t = malloc(strlen(s->file)+strlen(s->dir)+2); sprintf(t, "%s/%s", s->dir, s->file); s->file = t; } return 0; } static void local_info(struct xfer_state *s) { fprintf(stderr,"write config [%s]:\n local transfer %s => %s\n", s->name,s->tmpfile,s->file); } static int local_xfer(struct xfer_state *s, char *image, int width, int height) { int fh; if (-1 == (fh = open(s->tmpfile,O_CREAT|O_WRONLY|O_TRUNC,0666))) { fprintf(stderr,"open %s: %s\n",s->tmpfile,strerror(errno)); exit(1); } write_file(fh, image, width, height); if (rename(s->tmpfile, s->file) ) { fprintf(stderr, "can't move %s -> %s\n", s->tmpfile, s->file); exit(1); } return 0; } static void local_close(struct xfer_state *s) { /* nothing */ } static struct xfer_ops local_ops = { .open = local_open, .info = local_info, .xfer = local_xfer, .close = local_close, }; /* ---------------------------------------------------------------------- */ /* capture stuff */ const struct ng_vid_driver *drv; void *h_drv; struct ng_video_fmt fmt,gfmt; struct ng_video_conv *conv; void *hconv; static void grab_init(void) { struct ng_attribute *attr; int val,i; drv = ng_vid_open(&ng_dev.video,ng_dev.driver,NULL,0,&h_drv); if (NULL == drv) { fprintf(stderr,"no grabber device available\n"); exit(1); } if (!(drv->capabilities(h_drv) & CAN_CAPTURE)) { fprintf(stderr,"device does'nt support capture\n"); exit(1); } if (grab_input) { attr = ng_attr_byid(drv->list_attrs(h_drv),ATTR_ID_INPUT); val = ng_attr_getint(attr,grab_input); if (-1 == val) { fprintf(stderr,"invalid input: %s\n",grab_input); exit(1); } attr->write(attr,val); } if (grab_norm) { attr = ng_attr_byid(drv->list_attrs(h_drv),ATTR_ID_NORM); val = ng_attr_getint(attr,grab_norm); if (-1 == val) { fprintf(stderr,"invalid norm: %s\n",grab_norm); exit(1); } attr->write(attr,val); } /* try native */ fmt.fmtid = VIDEO_RGB24; fmt.width = grab_width; fmt.height = grab_height; if (0 == drv->setformat(h_drv,&fmt)) return; /* check all available conversion functions */ fmt.bytesperline = fmt.width*ng_vfmt_to_depth[fmt.fmtid]/8; for (i = 0;;) { conv = ng_conv_find_to(fmt.fmtid, &i); if (NULL == conv) break; gfmt = fmt; gfmt.fmtid = conv->fmtid_in; gfmt.bytesperline = 0; if (0 == drv->setformat(h_drv,&gfmt)) { fmt.width = gfmt.width; fmt.height = gfmt.height; hconv = conv->init(&fmt,conv->priv); return; } } fprintf(stderr,"can't get rgb24 data\n"); exit(1); } static unsigned char* grab_one(int *width, int *height) { static struct ng_video_buf *cap,*buf; if (NULL != buf) ng_release_video_buf(buf); if (NULL == (cap = drv->getimage(h_drv))) { fprintf(stderr,"capturing image failed\n"); exit(1); } if (NULL != conv) { buf = ng_malloc_video_buf(&fmt,3*fmt.width*fmt.height); conv->frame(hconv,buf,cap); buf->info = cap->info; ng_release_video_buf(cap); } else { buf = cap; } *width = buf->fmt.width; *height = buf->fmt.height; return buf->data; } /* ---------------------------------------------------------------------- */ #define MSG_MAXLEN 256 #define CHAR_HEIGHT 11 #define CHAR_WIDTH 6 #define CHAR_START 4 #include "font-6x11.h" static char* get_message(void) { static char buffer[MSG_MAXLEN+1]; FILE *fp; char *p; if (NULL == grab_infofile) return grab_text; if (NULL == (fp = fopen(grab_infofile, "r"))) { fprintf(stderr,"open %s: %s\n",grab_infofile,strerror(errno)); return grab_text; } fgets(buffer, MSG_MAXLEN, fp); fclose(fp); if (NULL != (p = strchr(buffer,'\n'))) *p = '\0'; return buffer; } static void add_text(char *image, int width, int height) { time_t t; struct tm *tm; char line[MSG_MAXLEN+1],*ptr; int i,x,y,f,len; time(&t); tm = localtime(&t); len = strftime(line,MSG_MAXLEN,get_message(),tm); // fprintf(stderr,"%s\n",line); for (y = 0; y < CHAR_HEIGHT; y++) { ptr = image + 3 * width * (height-CHAR_HEIGHT-2+y) + 12; for (x = 0; x < len; x++) { f = fontdata[line[x] * CHAR_HEIGHT + y]; for (i = CHAR_WIDTH-1; i >= 0; i--) { if (f & (CHAR_START << i)) { ptr[0] = grab_fg_r; ptr[1] = grab_fg_g; ptr[2] = grab_fg_b; } else if (grab_bg_r != -1) { ptr[0] = grab_bg_r; ptr[1] = grab_bg_g; ptr[2] = grab_bg_b; } ptr += 3; } } } } /* ---------------------------------------------------------------------- */ /* Frederic Helin - 15/07/2002 */ /* Correction fonction of stereographic radial distortion */ int grab_dist_on = 0; int grab_dist_k = 700; int grab_dist_cx = -1; int grab_dist_cy = -1; int grab_dist_zoom = 50; int grab_dist_sensorw = 640; int grab_dist_sensorh = 480; static unsigned char * correct_distor(unsigned char * in, int width, int height, int grab_zoom, int grap_k, int cx, int cy, int grab_sensorw, int grab_sensorh) { static unsigned char * corrimg = NULL; int i, j, di, dj; float dr, cr,ca, sensor_w, sensor_h, sx, zoom, k; sensor_w = grab_dist_sensorw/100.0; sensor_h = grab_dist_sensorh/100.0; zoom = grab_zoom / 100.0; k = grap_k / 100.0; if (corrimg == NULL && (corrimg = malloc(width*height*3)) == NULL ) { fprintf(stderr, "out of memory\n"); exit(1); } sensor_w = 6.4; sensor_h = 4.8; // calc ratio x/y sx = width * sensor_h / (height * sensor_w); // calc new value of k in the coordonates systeme of computer k = k * height / sensor_h; // Clear image for (i = 0; i < height*width*3; i++) corrimg[i] = 255; for (j = 0; j < height ; j++) { for (i = 0; i < width ; i++) { // compute radial distortion / parameters of center of image cr = sqrt((i-cx)/sx*(i-cx)/sx+(j-cy)*(j-cy)); ca = atan(cr/k/zoom); dr = k * tan(ca/2); if (i == cx && j == cy) {di = cx; dj = cy;} else { di = (i-cx) * dr / cr + cx; dj = (j-cy) * dr / cr + cy; } if (dj= 0 && dj >= 0 && j= 0 && j >= 0 ) { corrimg[3*(j*width + i) ] = in[3*(dj*width + di) ]; corrimg[3*(j*width + i)+1] = in[3*(dj*width + di)+1]; corrimg[3*(j*width + i)+2] = in[3*(dj*width + di)+2]; } } } return corrimg; } /* ---------------------------------------------------------------------- */ static unsigned int compare_images(unsigned char *last, unsigned char *current, int width, int height) { unsigned char *p1 = last; unsigned char *p2 = current; int avg, diff, max, i = width*height*3; for (max = 0, avg = 0; --i; p1++,p2++) { diff = (*p1 < *p2) ? (*p2 - *p1) : (*p1 - *p2); avg += diff; if (diff > max) max = diff; } avg = avg / width / height; fprintf(stderr,"compare: max=%d,avg=%d\n",max,avg); /* return avg */ return max; } static unsigned char * rotate_image(unsigned char * in, int *wp, int *hp, int rot, int top, int left, int bottom, int right) { static unsigned char * rotimg = NULL; int i, j; int w = *wp; int ow = (right-left); int oh = (bottom-top); if (rotimg == NULL && (rotimg = malloc(ow*oh*3)) == NULL ) { fprintf(stderr, "out of memory\n"); exit(1); } switch (rot) { default: case 0: for (j = 0; j < oh; j++) { int ir = (j+top)*w+left; int or = j*ow; for (i = 0; i < ow; i++) { rotimg[3*(or + i)] = in[3*(ir+i)]; rotimg[3*(or + i)+1] = in[3*(ir+i)+1]; rotimg[3*(or + i)+2] = in[3*(ir+i)+2]; } } *wp = ow; *hp = oh; break; case 1: for (i = 0; i < ow; i++) { int rr = (ow-1-i)*oh; int ic = i+left; for (j = 0; j < oh; j++) { rotimg[3*(rr+j)] = in[3*((j+top)*w+ic)]; rotimg[3*(rr+j)+1] = in[3*((j+top)*w+ic)+1]; rotimg[3*(rr+j)+2] = in[3*((j+top)*w+ic)+2]; } } *wp = oh; *hp = ow; break; case 2: for (j = 0; j < oh; j++) { int ir = (j+top)*w; for (i = 0; i < ow; i++) { rotimg[3*((oh-1-j)*ow + (ow-1-i))] = in[3*(ir+i+left)]; rotimg[3*((oh-1-j)*ow + (ow-1-i))+1] = in[3*(ir+i+left)+1]; rotimg[3*((oh-1-j)*ow + (ow-1-i))+2] = in[3*(ir+i+left)+2]; } } *wp = ow; *hp = oh; break; case 3: for (i = 0; i < ow; i++) { int rr = i*oh; int ic = i+left; rr += oh-1; for (j = 0; j < oh; j++) { rotimg[3*(rr-j)] = in[3*((j+top)*w+ic)]; rotimg[3*(rr-j)+1] = in[3*((j+top)*w+ic)+1]; rotimg[3*(rr-j)+2] = in[3*((j+top)*w+ic)+2]; } } *wp = oh; *hp = ow; break; } return rotimg; } /* ---------------------------------------------------------------------- */ static int make_dirs(char *filename) { char *dirname,*h; int retval = -1; dirname = strdup(filename); if (NULL == dirname) goto done; h = strrchr(dirname,'/'); if (NULL == h) goto done; *h = 0; if (-1 == (retval = mkdir(dirname,0777))) if (ENOENT == errno) if (0 == make_dirs(dirname)) retval = mkdir(dirname,0777); done: free(dirname); return retval; } int main(int argc, char *argv[]) { unsigned char *image,*val,*gimg,*lastimg = NULL; int width, height, i, fh; char filename[1024]; char **sections; struct list_head *item; struct xfer_state *s; /* read config */ if (argc > 1) { strcpy(filename,argv[1]); } else { sprintf(filename,"%s/%s",getenv("HOME"),".webcamrc"); } fprintf(stderr,"reading config file: %s\n",filename); cfg_parse_file(filename); ng_init(); if (NULL != (val = cfg_get_str("grab","device"))) ng_dev.video = val; if (NULL != (val = cfg_get_str("grab","driver"))) ng_dev.driver = val; if (NULL != (val = cfg_get_str("grab","text"))) grab_text = val; if (NULL != (val = cfg_get_str("grab","infofile"))) grab_infofile = val; if (NULL != (val = cfg_get_str("grab","input"))) grab_input = val; if (NULL != (val = cfg_get_str("grab","norm"))) grab_norm = val; if (-1 != (i = cfg_get_int("grab","width"))) grab_width = i; if (-1 != (i = cfg_get_int("grab","height"))) grab_height = i; if (-1 != (i = cfg_get_int("grab","delay"))) grab_delay = i; if (-1 != (i = cfg_get_int("grab","wait"))) grab_wait = i; if (-1 != (i = cfg_get_int("grab","rotate"))) grab_rotate = i; if (-1 != (i = cfg_get_int("grab","top"))) grab_top = i; if (-1 != (i = cfg_get_int("grab","left"))) grab_left = i; grab_bottom = cfg_get_int("grab","bottom"); grab_right = cfg_get_int("grab","right"); if (-1 != (i = cfg_get_int("grab","quality"))) grab_quality = i; if (-1 != (i = cfg_get_int("grab","trigger"))) grab_trigger = i; if (-1 != (i = cfg_get_int("grab","once"))) if (i > 0) grab_times = 1; if (-1 != (i = cfg_get_int("grab","times"))) grab_times = i; if (NULL != (val = cfg_get_str("grab","archive"))) archive = val; if (-1 != (i = cfg_get_int("grab","fg_red"))) if (i >= 0 && i <= 255) grab_fg_r = i; if (-1 != (i = cfg_get_int("grab","fg_green"))) if (i >= 0 && i <= 255) grab_fg_g = i; if (-1 != (i = cfg_get_int("grab","fg_blue"))) if (i >= 0 && i <= 255) grab_fg_b = i; if (-1 != (i = cfg_get_int("grab","bg_red"))) if (i >= 0 && i <= 255) grab_bg_r = i; if (-1 != (i = cfg_get_int("grab","bg_green"))) if (i >= 0 && i <= 255) grab_bg_g = i; if (-1 != (i = cfg_get_int("grab","bg_blue"))) if (i >= 0 && i <= 255) grab_bg_b = i; if (-1 != (i = cfg_get_int("grab","distor"))) grab_dist_on = i; if (-1 != (i = cfg_get_int("grab","distor_k"))) grab_dist_k = i; if (-1 != (i = cfg_get_int("grab","distor_cx"))) grab_dist_cx = i; if (-1 != (i = cfg_get_int("grab","distor_cy"))) grab_dist_cy = i; if (-1 != (i = cfg_get_int("grab","distor_zoom"))) grab_dist_zoom =i; if (-1 != (i = cfg_get_int("grab","distor_sensorw"))) grab_dist_sensorw = i; if (-1 != (i = cfg_get_int("grab","distor_sensorh"))) grab_dist_sensorh = i; /* defaults */ if (grab_top < 0) grab_top = 0; if (grab_left < 0) grab_left = 0; if (grab_bottom < 0) grab_bottom = grab_height; if (grab_right < 0) grab_right = grab_width; if (grab_bottom > grab_height) grab_bottom = grab_height; if (grab_right > grab_width) grab_right = grab_width; if (grab_top >= grab_bottom) { fprintf(stderr, "config error: top must be smaller than bottom\n"); exit(1); } if (grab_left >= grab_right) { fprintf(stderr, "config error: left must be smaller than right\n"); exit(1); } if (grab_dist_k < 1 || grab_dist_k > 10000) grab_dist_k = 700; if (grab_dist_cx < 0 || grab_dist_cx > grab_width) grab_dist_cx = grab_width / 2; if (grab_dist_cy < 0 || grab_dist_cy > grab_height) grab_dist_cy = grab_height / 2; if (grab_dist_zoom < 1 || grab_dist_zoom > 1000) grab_dist_zoom = 100; if (grab_dist_sensorw < 1 || grab_dist_sensorw >9999) grab_dist_sensorw = 640; if (grab_dist_sensorh < 1 || grab_dist_sensorh >9999) grab_dist_sensorh = 480; INIT_LIST_HEAD(&connections); for (sections = cfg_list_sections(); *sections != NULL; sections++) { if (0 == strcasecmp(*sections,"grab")) continue; /* init + set defaults */ s = malloc(sizeof(*s)); memset(s,0,sizeof(*s)); s->name = *sections; s->host = "www"; s->user = "webcam"; s->pass = "xxxxxx"; s->dir = "public_html/images"; s->file = "webcam.jpeg"; s->tmpfile = "uploading.jpeg"; s->passive = 1; s->autologin = 0; s->ops = &ftp_ops; /* from config */ if (NULL != (val = cfg_get_str(*sections,"host"))) s->host = val; if (NULL != (val = cfg_get_str(*sections,"user"))) s->user = val; if (NULL != (val = cfg_get_str(*sections,"pass"))) s->pass = val; if (NULL != (val = cfg_get_str(*sections,"dir"))) s->dir = val; if (NULL != (val = cfg_get_str(*sections,"file"))) s->file = val; if (NULL != (val = cfg_get_str(*sections,"tmp"))) s->tmpfile = val; if (-1 != (i = cfg_get_int(*sections,"passive"))) s->passive = i; if (-1 != (i = cfg_get_int(*sections,"auto"))) s->autologin = i; if (-1 != (i = cfg_get_int(*sections,"debug"))) s->debug = i; if (-1 != (i = cfg_get_int(*sections,"local"))) if (i) s->ops = &local_ops; if (-1 != (i = cfg_get_int(*sections,"ssh"))) if (i) s->ops = &ssh_ops; /* all done */ list_add_tail(&s->list,&connections); } /* init everything */ grab_init(); sleep(grab_wait); tmpdir = (NULL != getenv("TMPDIR")) ? getenv("TMPDIR") : "/tmp"; list_for_each(item,&connections) { s = list_entry(item, struct xfer_state, list); (s->ops->open)(s); } /* print config */ fprintf(stderr,"video4linux webcam v1.5 - (c) 1998-2002 Gerd Knorr\n"); fprintf(stderr,"grabber config:\n size %dx%d [%s]\n", fmt.width,fmt.height,ng_vfmt_to_desc[gfmt.fmtid]); fprintf(stderr," input %s, norm %s, jpeg quality %d\n", grab_input,grab_norm, grab_quality); fprintf(stderr," rotate=%d, top=%d, left=%d, bottom=%d, right=%d\n", grab_rotate, grab_top, grab_left, grab_bottom, grab_right); list_for_each(item,&connections) { s = list_entry(item, struct xfer_state, list); s->ops->info(s); } /* run as daemon - detach from terminal */ if (daemonize) { switch (fork()) { case -1: perror("fork"); exit(1); case 0: close(0); close(1); close(2); setsid(); break; default: exit(0); } } /* main loop */ for (;;) { /* grab a new one */ gimg = grab_one(&width,&height); if (grab_dist_on) gimg = correct_distor(gimg, width, height, grab_dist_zoom, grab_dist_k, grab_dist_cx, grab_dist_cy, grab_dist_sensorw, grab_dist_sensorh); image = rotate_image(gimg, &width, &height, grab_rotate, grab_top, grab_left, grab_bottom, grab_right); if (grab_trigger) { /* look if it has changed */ if (NULL != lastimg) { i = compare_images(lastimg,image,width,height); if (i < grab_trigger) continue; } else { lastimg = malloc(width*height*3); } memcpy(lastimg,image,width*height*3); } /* ok, label it and upload */ add_text(image,width,height); list_for_each(item,&connections) { s = list_entry(item, struct xfer_state, list); s->ops->xfer(s,image,width,height); } if (archive) { time_t t; struct tm *tm; time(&t); tm = localtime(&t); strftime(filename,sizeof(filename)-1,archive,tm); again: if (-1 == (fh = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666))) { if (ENOENT == errno) { if (0 == make_dirs(filename)) goto again; } fprintf(stderr,"open %s: %s\n",filename,strerror(errno)); exit(1); } write_file(fh, image, width, height); } if (-1 != grab_times && --grab_times == 0) break; if (grab_delay > 0) sleep(grab_delay); } list_for_each(item,&connections) { s = list_entry(item, struct xfer_state, list); s->ops->close(s); } return 0; } xawtv-3.106/contrib/000077500000000000000000000000001343350355000143355ustar00rootroot00000000000000xawtv-3.106/contrib/frequencies-europe000066400000000000000000000210721343350355000200700ustar00rootroot00000000000000From: Filip Streibl To: Gerd Knorr Subject: Re: Freqs +------+----------------------------+----------------------------+ | | OIRT | CCIR | | Band +----+---------+------+------+----+---------+------+------+ | |Cha-| Range |Vision|Sound |Cha-| Range |Vision|Sound | | |nnel| | | |nnel| | | | +------+----+---------+------+------+----+---------+------+------+ | I | R1 |48.5-56.5| 49.75| 56.25| E2 | 47-54 | 48.25| 53.75| | | R2 | 58-66 | 59.25| 65.75| E3 | 54-61 | 55.25| 60.75| | | | | | | E4 | 61-68 | 62.25| 67.75| +------+----+---------+------+------+----+---------+------+------+ | II | R3 | 76-84 | 77.25| 83.75|S01 | 68-75 | 69.25| 74.75| | | R4 | 84-92 | 85.25| 91.75|S02 | 75-82 | 76.25| 81.75| | | R5 | 92-100 | 93.25| 99.75|S03 | 82-89 | 83.25| 88.75| +------+----+---------+------+------+----+---------+------+------+ | S |SR1 | 110-118 |111.25|117.75|SE2 | 111-118 |112.25|117.75| | (low)|SR2 | 118-126 |119.25|125.75|SE3 | 118-125 |119.25|124.75| | |SR3 | 126-134 |127.25|133.75|SE4 | 125-132 |126.25|131.75| | |SR4 | 134-142 |135.25|141.75|SE5 | 132-139 |133.25|138.75| | |SR5 | 142-150 |143.25|149.75|SE6 | 139-146 |140.25|145.75| | |SR6 | 150-158 |151.25|157.75|SE7 | 146-153 |147.25|152.75| | |SR7 | 158-166 |159.25|165.75|SE8 | 153-160 |154.25|159.75| | |SR8 | 166-174 |167.25|173.75|SE9 | 160-167 |161.25|166.75| | | | | | |SE10| 167-174 |168.25|173.75| +------+----+---------+------+------+----+---------+------+------+ | III | R6 | 174-182 |175.25|181.75| E5 | 174-181 |175.25|180.75| | | R7 | 182-190 |183.25|189.75| E6 | 181-188 |182.25|187.75| | | R8 | 190-198 |191.25|197.75| E7 | 188-195 |189.25|194.75| | | R9 | 198-206 |199.25|205.75| E8 | 195-202 |196.25|201.75| | | R10| 206-214 |207.25|213.75| E9 | 202-209 |203.25|208.75| | | R11| 214-222 |215.25|221.75| E10| 209-216 |210.25|215.75| | | R12| 222-230 |223.25|229.75| E11| 216-223 |217.25|222.75| | | | | | | E12| 223-230 |224.25|229.75| +------+----+---------+------+------+----+---------+------+------+ | S |SR11| 230-238 |231.25|237.75|SE11| 230-237 |231.25|236.75| |(high)|SR12| 238-246 |239.25|245.75|SE12| 237-244 |238.25|243.75| | |SR13| 246-254 |247.25|253.75|SE13| 244-251 |245.25|250.75| | |SR14| 254-262 |255.25|261.75|SE14| 251-258 |252.25|257.75| | |SR15| 262-270 |263.25|269.75|SE15| 258-265 |259.25|264.75| | |SR16| 270-278 |271.25|277.75|SE16| 265-272 |266.25|271.75| | |SR17| 278-286 |279.25|285.75|SE17| 272-279 |273.25|278.75| | |SR18| 286-294 |287.25|293.75|SE18| 279-286 |280.25|285.75| | | | | | |SE19| 286-293 |287.25|292.75| | | | | | |SE20| 293-300 |294.25|299.75| +------+----+---------+------+------+----+---------+------+------+ | H | | | | |S21 | 302-310 |303.25|308.75| | | | | | |S22 | 310-318 |311.25|316.75| | | | | | |S23 | 318-326 |319.25|324.75| | | | | | |S24 | 326-334 |327.25|332.75| | | | | | |S25 | 334-342 |335.25|340.75| | | | | | |S26 | 342-350 |343.25|348.75| | | | | | |S27 | 350-358 |351.25|356.75| | | | | | |S28 | 358-366 |359.25|364.75| | | | | | |S29 | 366-374 |367.25|372.75| | | | | | |S30 | 374-382 |375.25|380.75| | | | | | |S31 | 382-390 |383.25|388.75| | | | | | |S32 | 390-398 |391.25|396.75| | | | | | |S33 | 398-406 |399.25|404.75| | | | | | |S34 | 406-414 |407.25|412.75| | | | | | |S35 | 414-422 |415.25|420.75| | | | | | |S36 | 422-430 |423.25|428.75| | | | | | |S37 | 430-438 |431.25|436.75| | | | | | |S38 | 438-446 |439.25|444.75| | | | | | |S39 | 446-454 |447.25|452.75| | | | | | |S40 | 454-462 |455.25|460.75| | | | | | |S41 | 462-470 |463.25|468.75| +------+----+---------+------+------+----+---------+------+------+ | IV | 21 | 470-478 |471.25|477.75| 21 | 470-478 |471.25|476.75| | | 22 | 478-486 |479.25|485.75| 22 | 478-486 |479.25|484.75| | | 23 | 486-494 |487.25|493.75| 23 | 486-494 |487.25|492.75| | | 24 | 494-502 |495.25|501.75| 24 | 494-502 |495.25|500.75| | | 25 | 502-510 |503.25|509.75| 25 | 502-510 |503.25|508.75| | | 26 | 510-518 |511.25|517.75| 26 | 510-518 |511.25|516.75| | | 27 | 518-526 |519.25|525.75| 27 | 518-526 |519.25|524.75| | | 28 | 526-534 |527.25|533.75| 28 | 526-534 |527.25|532.75| | | 29 | 534-542 |535.25|541.75| 29 | 534-542 |535.25|540.75| | | 30 | 542-550 |543.25|549.75| 30 | 542-550 |543.25|548.75| | | 31 | 550-558 |551.25|557.75| 31 | 550-558 |551.25|556.75| | | 32 | 558-566 |559.25|565.75| 32 | 558-566 |559.25|564.75| | | 33 | 566-574 |567.25|573.75| 33 | 566-574 |567.25|572.75| | | 34 | 574-582 |575.25|581.75| 34 | 574-582 |575.25|580.75| | | 35 | 582-590 |583.25|589.75| 35 | 582-590 |583.25|588.75| | | 36 | 590-598 |591.25|597.75| 36 | 590-598 |591.25|596.75| | | 37 | 598-606 |599.25|605.75| 37 | 598-606 |599.25|604.75| +------+----+---------+------+------+----+---------+------+------+ | V | 38 | 606-614 |607.25|613.75| 38 | 606-614 |607.25|612.75| | | 39 | 614-622 |615.25|621.75| 39 | 614-622 |615.25|620.75| | | 40 | 622-630 |623.25|629.75| 40 | 622-630 |623.25|628.75| | | 41 | 630-638 |631.25|637.75| 41 | 630-638 |631.25|636.75| | | 42 | 638-646 |639.25|645.75| 42 | 638-646 |639.25|644.75| | | 43 | 646-654 |647.25|653.75| 43 | 646-654 |647.25|652.75| | | 44 | 654-662 |655.25|661.75| 44 | 654-662 |655.25|660.75| | | 45 | 662-670 |663.25|669.75| 45 | 662-670 |663.25|668.75| | | 46 | 670-678 |671.25|677.75| 46 | 670-678 |671.25|676.75| | | 47 | 678-686 |679.25|685.75| 47 | 678-686 |679.25|684.75| | | 48 | 686-694 |687.25|693.75| 48 | 686-694 |687.25|692.75| | | 49 | 694-702 |695.25|701.75| 49 | 694-702 |695.25|700.75| | | 50 | 702-710 |703.25|709.75| 50 | 702-710 |703.25|708.75| | | 51 | 710-718 |711.25|717.75| 51 | 710-718 |711.25|716.75| | | 52 | 718-726 |719.25|725.75| 52 | 718-726 |719.25|724.75| | | 53 | 726-734 |727.25|733.75| 53 | 726-734 |727.25|732.75| | | 54 | 734-742 |735.25|741.75| 54 | 734-742 |735.25|740.75| | | 55 | 742-750 |743.25|749.75| 55 | 742-750 |743.25|748.75| | | 56 | 750-758 |751.25|757.75| 56 | 750-758 |751.25|756.75| | | 57 | 758-766 |759.25|765.75| 57 | 758-766 |759.25|764.75| | | 58 | 766-774 |767.25|773.75| 58 | 766-774 |767.25|772.75| | | 59 | 774-782 |775.25|781.75| 59 | 774-782 |775.25|780.75| | | 60 | 782-790 |783.25|789.75| 60 | 782-790 |783.25|788.75| | | 61 | 790-798 |791.25|797.75| 61 | 790-798 |791.25|796.75| | | 62 | 798-806 |799.25|805.75| 62 | 798-806 |799.25|804.75| | | 63 | 806-814 |807.25|813.75| 63 | 806-814 |807.25|812.75| | | 64 | 814-822 |815.25|821.75| 64 | 814-822 |815.25|820.75| | | 65 | 822-830 |823.25|829.75| 65 | 822-830 |823.25|828.75| | | 66 | 830-838 |831.25|837.75| 66 | 830-838 |831.25|836.75| | | 67 | 838-846 |839.25|845.75| 67 | 838-846 |839.25|844.75| | | 68 | 846-854 |847.25|853.75| 68 | 846-854 |847.25|852.75| | | 69 | 854-862 |855.25|861.75| | | | | | | 70 | 862-870 |863.25|869.75| | | | | | | 71 | 870-878 |871.25|877.75| | | | | | | 72 | 878-886 |879.25|885.75| | | | | | | 73 | 886-894 |887.25|893.75| | | | | | | 74 | 894-902 |895.25|901.75| | | | | | | 75 | 902-910 |903.25|909.75| | | | | | | 76 | 910-918 |911.25|917.75| | | | | | | 77 | 918-926 |919.25|925.75| | | | | | | 78 | 926-934 |927.25|933.75| | | | | | | 79 | 934-942 |935.25|941.75| | | | | | | 80 | 942-950 |943.25|949.75| | | | | | | 81 | 950-958 |951.25|957.75| | | | | +------+----+---------+------+------+----+---------+------+------+ xawtv-3.106/contrib/frequencies-japan000066400000000000000000000040731343350355000176640ustar00rootroot00000000000000From: Seizo Mikami < ntsc-bcast-jp > +------+----+-------+-------+ | Band |Cha-| Vision| Sound | | |nnel| | | +------+----+-------+-------+ | VHF | 1 | 91.25| 95.75| | | 2 | 97.25| 101.75| | | 3 | 103.25| 107.75| | | 4 | 171.25| 175.75| | | 5 | 177.25| 181.75| | | 6 | 183.25| 187.75| | | 7 | 189.25| 193.75| | | 8 | 193.25| 197.75| | | 9 | 199.25| 203.75| | | 10 | 205.25| 209.75| | | 11 | 211.25| 215.75| | | 12 | 217.25| 221.75| +------+----+-------+-------+ | UHF | 13 | 417.25| 421.75| | | 14 | 477.25| 481.75| | | 15 | 483.25| 487.75| | | 16 | 489.25| 493.75| | | 17 | 495.25| 499.75| | | 18 | 501.25| 505.75| | | 19 | 507.25| 511.75| | | 20 | 513.25| 517.75| | | 21 | 519.25| 523.75| | | 22 | 525.25| 529.75| | | 23 | 531.25| 535.75| | | 24 | 537.25| 541.75| | | 25 | 543.25| 547.75| | | 26 | 549.25| 553.75| | | 27 | 555.25| 559.75| | | 28 | 561.25| 565.75| | | 29 | 567.25| 571.75| | | 30 | 573.25| 577.75| | | 31 | 579.25| 583.75| | | 32 | 585.25| 589.75| | | 33 | 591.25| 595.75| | | 34 | 597.25| 601.75| | | 35 | 603.25| 607.75| | | 36 | 609.25| 613.75| | | 37 | 615.25| 619.75| | | 38 | 621.25| 625.75| | | 39 | 627.25| 631.75| | | 40 | 633.25| 637.75| | | 41 | 639.25| 643.75| | | 42 | 645.25| 649.75| | | 43 | 651.25| 655.75| | | 44 | 657.25| 661.75| | | 45 | 663.25| 667.75| | | 46 | 669.25| 673.75| | | 47 | 675.25| 679.75| | | 48 | 681.25| 685.75| | | 49 | 687.25| 691.75| | | 50 | 693.25| 697.75| | | 51 | 699.25| 703.75| | | 52 | 705.25| 709.75| | | 53 | 711.25| 715.75| | | 54 | 717.25| 721.75| | | 55 | 723.25| 727.75| | | 56 | 729.25| 733.75| | | 57 | 735.25| 739.75| | | 58 | 741.25| 745.75| | | 59 | 747.25| 751.75| | | 60 | 753.25| 757.75| | | 61 | 759.25| 763.75| | | 62 | 765.25| 769.75| +------+----+-------+-------+ xawtv-3.106/contrib/hauppauge-eeprom000066400000000000000000000062501343350355000175270ustar00rootroot00000000000000From roger@cs.strath.ac.uk Mon Nov 30 22:45:25 1998 Date: Mon, 30 Nov 1998 16:47:15 +0000 From: Roger Hardiman To: olivier.lahaye@cea.fr, roger@cs.strath.ac.uk Cc: kraxel@goldbach.in-berlin.de, video4linux@phunk.org Subject: Roger's complete Hauppauge EEPROM info Olivier, Gerd and V4L developers. Here is my list of the Hauppauge EEPROM contents which I built up for the FreeBSD bt848 driver. If you want further details, I can provide about 20 EEPROM contents dumps from different USA and European cards. I also have email contacts inside Hauppauge who can supply info when we require it. Special thanks to Steve Passe, Amancio Hasty and Randall Hopper and all the others who send in EEPROM contents to me or to the FreeBSD multimedia list. There are 5 datablocks, each can vary in size. Block 1 ======= This is of the format 84 11 00 00 04 followed by 15 bytes or 84 12 00 00 05 followed by 16 bytes In this block, byte 6 is the chipset type (see below) byte 9 is the tuner type (see below) byte 11 and 12 are the model number I'm sure byte 13 is the revision but I cannot decode it. There is also a byte which reports the ability to get Radio but I've forgotten it. Block 2 ======= 84 0a 00 01 01 20 77 00 40 This seems to be common for all cards Block 3 ======= 84 then 3 bytes Bytes 1,2 and 3 are the serial number Block 4 ======= This varies if you have No Stereo decoder, TDA decoder or MSP decoder Within this block, byte 3 tells us the stereo decoder chip type (or no stereo decoder) If byte 3 is 00 == No stereo decoder chip. The block is 5 bytes. EG. 74 02 01 00 03 If byte 3 indicates a MSP chip, the block is 5 bytes, EG 74 02 01 06 02 If byte 3 indicates a TDA chip, the block is 8 bytes, EG 77 02 01 03 03 43 17 12 byte 5, 6 and 7 are used in programming the TDA (the TDA dbx alignment bytes). Each TDA chip needs different values found during card calibration at Hauppage. Block 5 ======= This is 79 followed by a one byte checksum Free Space ========== the remainer of the eeprom is either filled with 00 or with ff. Missing Info ------------ I cannot work out the bits which tell me a) presence of SVIDEO b) presence of Teletext decoder The decode table you need for the chip type, tuner type and steroe chip are Chipset byte 0 Reserved 1 BT815 2 BT817 3 BT819 4 BT815A 5 BT817A 6 BT819A 7 BT827 8 BT829 9 BT848 a BT848A b BT849A c BT829A d BT827A e BT878 f BT879 10 BT880 BUT only 0x09 and 0x0e have been used. Tuner Byte 1 External 2 Unspecified 3 Phillips FI1216 4 Phillips FI1216MF 5 Phillips FI1236 6 Phillips FI1246 7 Phillips FI1256 8 Phillips FI1216 MK2 9 Phillips FI1216MF MK2 a Phillips FI1236 MK2 b Phillips FI1246 MK2 c Phillips FI1256 MK2 d Temic 4032FY5 e Temic 4002FH5 f Temic 4062FY5 10 Phillips FR1216 MK2 11 Phillips FR1216MF MK2 12 Phillips FR1236 MK2 13 Phillips FR1246 MK2 14 Phillips FR1256 MK2 15 Phillips FM1216 16 Phillips FM1216MF 17 Phillips FM1236 18 Temic ??? Stereo Decoder byte 0 None 1 TEA6300 2 TEA6320 3 TDA9850 4 MSP3400C 5 MSP3410D 6 MSP3415 7 MSP3430 xawtv-3.106/contrib/mash/000077500000000000000000000000001343350355000152655ustar00rootroot00000000000000xawtv-3.106/contrib/mash/README000066400000000000000000000017511343350355000161510ustar00rootroot00000000000000From hankm@netvideo.com Tue Aug 4 22:29:52 1998 Date: Thu, 30 Jul 1998 16:47:28 -0700 From: hankm@netvideo.com, Hank Magnuski To: mash-developers@mash.cs.berkeley.edu, rowe@bmrc.berkeley.edu Cc: kraxel@cs.tu-berlin.de, alan@cymru.net Subject: Video4Linux BTTV(Bt848) Driver for Mash I've taken the video-grabber code developed by Gerd Knorr and have Mashified it so that there is now a new Video-4-Linux BTTV (Bt848) video capture driver available for the Mash development environment. See http://user.cs.tu-berlin.de/~kraxel/linux/ under the section "Xawtv" for the low level BTTV driver that this package calls. You can, for example, construct a Mash version of Vic using this new code. More information on Mash is at http://www-mash.cs.berkeley.edu/mash/ Since I'm not a regular Mash developer (which is to say once step above clueless) any feedback or error reports would be appreciated. Hank [Part 2, Application/X-GZIP 7.7KB] [Unable to print this part] xawtv-3.106/contrib/mjpeg.html000066400000000000000000001042011343350355000163230ustar00rootroot00000000000000 WWW.PROG.CZ - Graphics File Formats /

Graphics File Formats /
Microsoft Windows Bitmap Format

(c) 1993 Microsoft Corporation. All rights reserved.


Multimedia Technical Note: JPEG DIB
Format

Created: May 26, 1993

Goals for this DIB Format Extension

The purpose of this specification is twofold:

1.        To define a standard DIB extension for storing JPEG-encoded
still images.

2.        To define a standard DIB extension for storing JPEG-encoded
motion images.

A standard DIB extension is one in which the data format is clearly
defined so that any codec that claims to understand the standard will
be able to process the image data correctly. In addition, the image
data created by any codec must be readable by any other codec. In
other words, it must conform to the standard.

These standards are extensions to the standard DIB format defined by
Microsoftr Windows version 3.0 and extended by the technical note
entitled "DIB Format Extensions."

This standard will provide:

*        Immediate support for partial implementation of the full scope of
JPEG Baseline Sequential DCT process as defined in ISO 10918 for SOF0
(marker Code 0xFFC0). The implemented subset of the full scope shall
maximize cross-platform interchange between the known universe of
existing JPEG codecs.

*        Provision for transparent (or nearly so) implementation of the
full scope of JPEG Baseline Sequential DCT process as defined in ISO
10918 for SOF0 (marker Code 0xFFC0).

*        Provision for subsequent inclusion of additional non-hierarchical
JPEG processes on a singular and individual basis. The additional
JPEG processes identified by JPEG Markers SOF1, SOF2, SOF3, SOF9,
SOF10, and SOF11 shall be capable of being implemented in whole or in
part by codecs with no constraint on the number or combination of
processes implemented. Provision for hierarchical processes is deemed
inappropriate to the DIB context.

*        Maximal conformance to existing implications of the
BITMAPINFOHEADER structure and its use at application level and
system level. Adaptive redefinition of the BITMAPINFOHEADER shall
provide that members of the basic BITMAPINFOHEADER shall be
identically defined as the preliminary (and primary) members of each
re-definition of the BITMAPINFOHEADER. As a result, a pointer to a
re-defined BITMAPINFOHEADER structure shall always be capable of
being recast as a pointer to the basic BITMAPINFOHEADER from which it
is derived.

*        Consideration of the usage of the revised BITMAPINFOHEADER within
enclosing structures of type BITMAPINFO, or analogous substitutes for
BITMAPINFO.

*        Define JPEG DIBs in a manner "suitable" for AVI incorporation,
but unconstrained by AVI specific usage. A standalone JPEG DIB image
file shall not include conventions adopted solely for the convenience
of AVI file construction. The off-line process of creating AVI files
should not bring AVI peculiar design requirements into the arena of
still image files.

It is assumed that the reader is familiar with JPEG as defined in the
ISO 10918 document. For additional information on JPEG see the ISO
10918 document.  For additional information about RIFF files, see the
Microsoft Windows Software Development Kit (SDK) Multimedia
Programmer's Guide and Multimedia Programmer's Reference.  For
additional information on installable compressors and decompressors,
see the "Video Compression/Decompression Drivers" technical note from
Microsoft.

General Specifications

This specification will define two standards for use in Windows:

1.        JPEG still-image format
2.        JPEG motion format (a.k.a. motion-JPEG)

Type 1: Still Image JPEG

All JPEG DIB still image formats (e.g., DIB files) shall embed a
complete "Interchange Format" JPEG data stream as a contiguous whole.
This provision shall eliminate inadvertent introduction of platform-,
system-, or application-specific conditions that may cause some
JPEG-compliant codecs to be incapable of processing the embedded JPEG
data of a DIB. Provision for indexed access to tables and other data
within the JPEG portion of a DIB shall be accommodated solely by the
introduction of new offset and length members in the body of the
revised BITMAPINFOHEADER structure (none are yet defined). This
provision permits any application or codec to construct a JPEG DIB
file simply by prepending the defined structures to JPEG data, then
perform a single pass through the JPEG data to calculate and set the
associated offset and length members which correlate to JPEG data
items.

Type 2: Motion JPEG

Motion JPEG DIBs shall accommodate interchange formats that satisfy
the "General sequential and progressive syntax" (ISO 10918 Part 1,
Annex B, Para. B.2). A set of images of this type with compatible
parameters can be placed in an AVI file to describe a motion
sequence. Frame headers for these DIBs shall be limited to those
specified in Para B.2.2 of the cited Annex B. These types are SOF0,
SOF1, SOF2, SOF3, SOF9, SOF10, and SOF11. Of the types accommodated,
this specification provides implementation only for the Baseline
Sequential DCT.

BITMAPINFOHEADER for JPEG



typedef struct tagEXBMINFOHEADER {
     BITMAPINFOHEADER     bmi;
     /* extended BITMAPINFOHEADER fields */
     DWORD  biExtDataOffset;
     /* Other stuff will go here */

     /* Format-specific information */
     /* biExtDataOffset points here */
} EXBMINFOHEADER;

typedef struct tagJPEGINFOHEADER {
     /* compress-specific fields */
     DWORD  JPEGSize;
     DWORD  JPEGProcess;

     /* Process specific fields */
     DWORD  JPEGColorSpaceID;
     DWORD  JPEGBitsPerSample;

     DWORD  JPEGHSubSampling;
     DWORD  JPEGVSubSampling;
} JPEGINFOHEADER

Field        Description

Standard BITMAPINFOHEADER fields


These fields are valid for all DIBs, regardless of compression format.


biSize        Size of entire set of structures for header data. Image offset
in DIB file or '"packed" DIB is: biSize + biColorUsed*sizeof
(RGBQUAD)

biWidth        Width of decompressed image in pixels.

biHeight        Height of decompressed image in pixels.

biPlanes        1

biBitCount        24 for RGB or YCbCr, 8 for Y only images (8 bit mono). The
values and their meanings are as follows.1: The bitmap is monochrome,
and the color table contains two entries. Each bit in the bitmap
array represents a pixel. If the bit is clear, the pixel is displayed
with the color of the first entry in the color table. If the bit is
set, the pixel has the color of the second entry in the table.4: The
bitmap has a maximum of 16 colors. Each pixel in the bitmap is
represented by a four-bit index into the color table. For example,
the first byte in the (uncompressed) bitmap is 0x1F and the byte
represents two pixels. The first pixel contains the color in the
second table entry, and the second pixel contains the color in the
16th color table entry.8: The bitmap has a maximum of 256 colors.
Each pixel in the (uncompressed) bitmap is represented by a
byte-sized index into the color table. For example, if the first byte
in the (uncompressed) bitmap is 0x1F, then the first pixel has the
color of the thirty-second table entry.24: The bitmap has a maximum
of 224 colors. The biClrUsed and biClrImportant fields can optionally
be used (by setting biClrUsed to non-zero) to store an optimized
palette for the image.N (for N > 8): The bitmap has a maximum of 2N
colors. The biClrUsed and biClrImportant fields can optionally be used
(by setting biClrUsed to non-zero) to store an optimized palette for
the image.

biCompression        Specifies the type of compression for a compressed
bitmap. See the technical note entitled "DIB Format Extensions" for a
complete list. Values and their meanings are as
follows.mmioFOURCC('J','P','E','G'): Still image JPEG
DIB.mmioFOURCC('M','J','P','G'): Motion image JPEG DIB.

biSizeImage        Specifies the size of the compressed image data in bytes.
For JPEG data, this is the length of the data including the EOI
marker.

biXPelsPerMeter        0. Specifies the horizontal resolution in pixels per
meter of the target device for the bitmap. An application can use
this value to select from a resource group that best matches the
characteristics of the current device.

biYPelsPerMeter        0. Specifies the vertical resolution in pixels per
meter of the target device for the bitmap.

biClrUsed        0 to 256. Specifies the number of color values in the
color table actually used by the bitmap. See also the biBitCount
field description.

biClrImportant        0. Specifies the number of color indexes that are
considered important for displaying the bitmap. If this value is 0
and biClrUsed is non-zero, all used colors are important.


Extended BITMAPINFOHEADER fields


biExtDataOffset        Specifies the offset to the start of the JPEG-specific
data. This field allows for an expanding BITMAPINFOHEADER structure.


JPEG DIB Specific fields


	These fields start at the offset specified by biExtDataOffset.

JPEGSize        Size of the JPEG DIB specific fields. This field allows
for expanding the JPEG DIB specific fields.

JPEGProcess        Specifies the various format types. In this extension,
only 0 (Baseline DCT sequential) is allowed.


Process Specific fields


JPEGColorSpaceID        Specifies the color space used for the compressed
JPEG data.JPEG_Y. The Y only component of YCbCr, as described below.
Implies 1 component.JPEG_YCbCr. YCbCr as defined by CCIR 601 (256
levels). The RGB components calculated by linear conversion from YC C
shall not be gamma corrected (gamma = 1.0). Implies 3 components.
This is the only option defined for motion JPEG images.JPEG_RGB. 24
bit RGB. (3 components).

JPEGBitsPerSample        Specifies the number of bits per sample per
component for the defined color space. For this extension, this value
will be 8. The subsequent frame header shall have its sample
precision parameter set to 8.


JPEGHSubSampling        Specifies the horizontal sampling factors used for
the chrominance components of a YCbCr image. Applicable only to
images with JPEGColorSpaceID == 2 (YCbCr). Specifies the horizontal
sampling factor for the chrominance components (jointly) with respect
to the luminance component. Non-zero values must correlate to the
"Hi" values for both chrominance components in the JPEG frame header
(see ISO 10918). The values and their meanings are as follows.0:
Subsampling is not- applicable (JPEGColorSpaceID != 2).1: For every
luminance sample in the horizontal dimension, the chrominance
components are sampled in a 1:1 ratio.2: For every luminance sample in
the horizontal dimension, the chrominance components are sampled in a
1:2 ratio, with chrominance samples (Cb and Cr separately) sampled at
half the horizontal spatial resolution as for luminance.4: For every
luminance sample in the horizontal dimension, the chrominance
components are sampled in a 1:4 ratio, with chrominance samples (Cb
and Cr separately) sampled at one-fourth the horizontal spatial
resolution as for luminance.

JPEGVSubSampling        Applicable only to images with JPEGColorSpaceID =2
(YCbCr). Specifies the vertical sampling factor for the chrominance
components (jointly) with respect to the luminance component.
Non-zero values must correlate to the "Vi" values for both chrominance
components in the JPEG frame header (see ISO 10918). The values and
their meanings are as follows.0: Subsampling is not- applicable
(JPEGColorSpaceID != 2).1: For every luminance sample in the vertical
dimension, the chrominance components are sampled in a 1:1 ratio.2:
For every luminance sample in the vertical dimension, the chrominance
components are sampled in a 1:2 ratio, with chrominance samples (Cb
and Cr separately) sampled at half the vertical spatial resolution as
for luminance.4: For every luminance sample in the vertical
dimension, the chrominance components are sampled in a 1:4 ratio, with
chrominance samples (Cb and Cr separately) sampled at one-fourth the
vertical spatial resolution as for luminance.

This specification affirms that the member biSize of structure
type BITMAPINFOHEADER and all JPEG derivative
redefinitions of BITMAPINFOHEADER shall be identically
defined. The member biSize shall always contain the count of
all bytes within the header information.
This specification affirms that the structure format and member
definition shall be correlated uniquely to the value of the
member biCompression. Further additions to the structure
definition shall not break any previous definitions, just as this
definition's use of the predefined fields (biSize especially) does
not break the BITMAPINFOHEADER definition. By virtue of this
provision, any application or system function given a pointer to
a BITMAPINFOHEADER structure (or derivative thereof) shall
be capable of determining the appropriate "recast" typedef by
examination of biCompression alone, with biSize serving only
as a cross-check. biSize can increase (but it should not
decrease) from the known definition.

This specification affirms that each redefinition of BITMAPINFOHEADER
for any value of biCompression shall contain the identical initial
members as defined for BITMAPINFOHEADER under Windows 3.1. This shall
apply equally to future redefinition of BITMAPINFOHEADER for those
biCompression values already incorporated (e.g., BI_RGB, BI_RLE8, and
BI_RLE4).

The offset to the start of the compression specific data is specified
by the biExtDataOffset field. This is the offset from the beginning
of the BITMAPINFOHEADER for JPEG structure.

For JPEG DIB compression structure, the second field is always the
JPEG process used to compress the image. The process-specific fields
may change depending on the process ID in the JPEGProcess field.

Image Data

Image data should not contain any thumbnail or other optional data as
this will greatly increase the size of the image data. If thumbnail,
copyright, creator, etc. information is desired, the appropriate RIFF
chunks should be used to store this data (see the RDIB definition in
the RIFF references).  The inclusion of optional data (e.g.,
comments, application-specific data, etc.) is strongly discouraged as
this will greatly increase the size of the image data.

Type 1: Still-image JPEG

Complete JPEG interchange format stream from SOI-EOI including all
tables and compressed data IAW ISO 10918 para 3.9.1"Interchange
Format". The size of the data shall be defined by the field
biSizeImage in the BITMAPINFOHEADER for JPEG structure.

Type 2: Motion JPEG

This DIB type contains incomplete JPEG data (abbreviated format per
ISO 10918) and is not intended for stand-alone single image frame
disk files. It may be used within RIFF files and other contexts where
it is appropriate to:

*        Decode an image without supplying the associated JPEG Huffman
tables. This presumes the codec has been properly pre-initialized
prior to image decode.

*        Request encoder output of compressed image data absent embedded
Huffman Tables.

All motion JPEG data will use YCrCb encoding.  In an AVI sequence,
all JPEG frames will be key frames as this ensures that within the
AVI and Video for Windows architecture all frames will be directly
and independently addressable.

For optimal size and speed during playback of an AVI file, the
Huffman data used by motion JPEG will be fixed and defined by this
document. This will make the individual frames of every motion
sequence smaller and more efficient to play back. Also, because all
sequences of motion images use the same Huffman data and color space,
it is much more likely that motion data can be directly exchanged
without re-compression. A definition of the Huffman data will be
provided in MMREG.H (which is listed at the end of this document) as
a byte string which can be concatenated onto the start of a motion
JPEG image to form a valid still JPEG image.



MJPGDHTSeg = { X'FF', DHT, length, JPEG Huffman table parameters }

Q-table data is present and may vary in every frame of a motion
sequence to permit control over the bandwidth of sequences that
contain bursts of frames of varying levels of complexity. The restart
interval used during the compression process may also vary for every
frame.

Only the interleaved form of YCrCb images is supported for motion
JPEG data. This implies that only one SOS segment will be present in
any particular motion JPEG image.  Following the Tables segment is
the compressed image data. The data is in JPEG stream syntax and
includes the SOI, DRI, DQT, SOF0, SOS, and EOI markers. For
JPEG_YCbCr, JPEG_RGB, and JPEG_Y color space IDs, these markers are
shown in the typical order with typical values.

As with all DIB files and functions that take "packed" DIBs,
regardless of compression, the offset to the image data can be
calculated as follows:



ImageOffset = biSize + biColorUsed*sizeof (RGBQUAD)

Sample table segment for baseline process:



X'FF', SOI

  X'FF', DHT, length, Huffman table parameters (only in still JPEG)
  X'FF', DRI, length, restart interval
  X'FF', DOT,
       length                Lq = 67 for JPEG_Y or
				  132 for JPEG_RGB or JPEG_YCbCr
       Precision, Table ID,  Pq = 0, Tq = 0
       DQT data [64]
       [If 3 Components
	  Precision, Table ID,    Pq = 0, Tq = 1
	  DQT data [64]
       ]
  X'FF', SOF0, length,

       Sample Precision      P = 8
       Number of lines       Y = biHeight
       Sample per line       X = biWidth
       Number of components  Nc = 1 or 3 (must match information from
	 JPEGColorSpaceID)

					  YCbCr     RGB
       1st Component parameters   C1=     1 =Y      4 =R
       2nd Component parameters   C2=     2 =Cb     5 =G
       3rd Component parameters   C3=     3 =Cr     6 =B
       *
       *]
  X'FF', SOS, length,

       Number of components  Ns = 1 or 3 (must match information from
	 JPEGColorSpaceID)

					  YCbCr     RGB
       1st Component parameters   C1=     1 =Y      4 =R
       2nd Component parameters   C2=     2 =Cb     5 =G
       3rd Component parameters   C3=     3 =Cr     6 =B
       *
       *
       *

X'FF', EOI

Note that the order in which the internal JPEG data segments
shown above can actually occur is not restricted by this
definition; see ISO 10918 for any ordering restrictions that are
defined.

JPEG DIB File Format

Support for JPEG under Windows is fast becoming a
requirement due to the increased number of 16-bit and 24-bit
adapters on the market. The introduction of JPEG as a
Windows support file format will allow users to dramatically
decrease the storage requirement for their 16- and 24-bit
images.
Every DIB (including JPEG DIB) file has the following format:

1.        DIB file header
2.        Bitmap information header
3.        Optional color table
4.        Image data

The DIB file header is defined in the DIB documentation. The
JPEG DIB bitmap information header is defined in this
document. The (optional) color table must be RGBQUADs and
is defined in the DIB documentation. The JPEG DIB image
data is defined in this document.

JPEG AVI File Format

JPEG AVI files use the AVI RIFF form as described in the
Microsoft Multimedia technical note "AVI Files." The JPEG AVI
file format has the same mandatory LIST chunks as any other
AVI files. The following example shows the JPEG AVI RIFF
form expanded with the chunks needed to complete the LIST
"hdr1" and LIST "movi" chunks:
As defined in the AVI file format, key frames have the key
frame bit set in the index flags. Since all JPEG frames are key
frames, this flag will always be set for all the frames in a
motion JPEG AVI file.



RIFF   ('AVI'
       LIST    ('hdr1'
	       'avih'   (
0 LIST ('str1' 'strh' () 'strf () 'strd () . . . ) LIST ('movi' { '##dc' Byte abJPEGdata[ ]; } . . . LIST ('rec' '##dc' Byte abJPEGdata [ ]; . . . ) ) . . . ) ['idx' ] ) ) The strh chunk contains the stream header chunk that describes the type of data the stream contains. The strf chunk describes the format of the data in the stream. For the JPEG AVI case, the information in this chunk is a BMINFOHEADER FOR JPEG. The strd chunk contains the FOURCC ID and associated state structure containing any specific state data for initializing the identified codec. All frames in the AVI file are key-frames and have a form similar to that defined for JPEG "abbreviated format for compressed image data" as specified in ISO 10918 para. B.4. The LIST "movi" Chunk Following the header information is a LIST "movi" chunk that contains chunks of the actual data in the streams, that is, the pictures and sounds themselves. The data chunks can reside directly in the LIST "movi" chunk or they might be grouped into "rec" chunks, as described in the AVI file format technical note. As in any RIFF chunk, a four-character code is used to identify the chunk. As in the JPEG DIB format, the JPEG stream syntax is used for the image data with the following constraints. The JPEG marker codes SOI, DRI, DQT, SOF0, SOS, and EOI are expected (mandatory) in the image data chunk, and the constrained values shown in the example below are mandatory for the image data within the AVI stream. Any parameters in the SOF0 (frame) and SOS (start of scan) headers that are duplicated in the BITMAPINFOHEADER for JPEG must be the same. This would include Sample Precision, subsampling, and number of components (as implied by JPEGColorSpaceID). The number of lines and samples per lines in the SOF0 segment and the width and height defined in the format chunk must match the main AVI header width and height values. All of these values are expected to remain the same for every image data chunk in the AVI sequence. Within the image data chunk, two JPEG segments beginning with the SOI marker and ending with the EOI marker are allowed to accommodate field interleaved streams. There is an APP0 marker immediately following the SOI marker that contains information about the video image. Specifically, this allows the identification of the ODD and EVEN fields of an image for images stored in field interleaved fashion. This APP0 marker is expected to have the first 4 bytes following the length bytes set to the characters 'A', 'V', 'I', '1'. The next byte indicates which field the JPEG data was compressed from and has an expected value of one for the first JPEG data segment and two for the second segment, indicating the ODD and EVEN fields respectively. If the stream is not field interleaved, this value will be 0 and there will only be one JPEG segment. The remaining seven bytes are expected to be set to 0 and will be ignored by the codec. If a codec cannot handle the interleaved fields, the codec will use only the first (ODD) field and will replicate the lines as necessary to provide an image that conforms to the image size defined in the main AVI header. Conversely, if a capture system only accesses a single field of each source frame, only a single (ODD) field image may be present in a JPEG stream. This implies that the single (ODD) field data should be used as the source of both fields by a decompressor that wishes to process full interlaced data. It is an advantage to keep the interlace structure of all the frames in a particular motion JPEG AVI file consistent. To this end, the following convention can be followed concerning the relationship of interlace structure to the biHeight parameter of each motion JPEG image, and hence the entire AVI sequence. biHeight Interlace structure suggested <= 240 Single JPEG data block describing entire frame. > 240 A pair of half-height JPEG data blocks describing ODD and EVEN fields of the frame (EVEN field data is optional if these blocks would be identical). Note that interlace structure and individual fields of data should be treated as an internal feature of the image data representation. The entire frame remains an indivisible unit on which editors etc. should operate. The following is an example of what the image data chunk would look like for a non-interleaved stream. X'FF', SOI X'FF', APP0' 14, "AVI1", 0, 0, 0, 0, 0, 0, 0, 0 X'FF', DRI, length, restart interval length Lq = 67 for JPEG_Y or 132 for JPEG_YCbCr or JPEG_RGB Precision, Table ID, Pq = 0, Tq = 0 DQT data [64] [If 3 components Precision, Table ID, Pq = 0, Tq = 1 DQT data [64] ] X'FF', SOF0, length, Sample Precision P = 8 Number of lines Y = biHeight Sample per line X = biWidth Number of components Nc = 1 or 3 YCbCr RGB 1st Component parameters C1= 1 =Y 4 =R 2nd Component parameters C2= 2 =Cb 5 =G 3rd Component parameters C3= 3 =Cr 6 =B X'FF', SOS, length, Number of components Ns = 1 or 3 YCbCr RGB 1st Component parameters C1= 1 =Y 4 =R 2nd Component parameters C2= 2 =Cb 5 =G 3rd Component parameters C3= 3 =Cr 6 =B * * * X'FF', EOI Note that the order in which the internal JPEG data segments (other than APP0) shown above can actually occur is not restricted by this definition; see ISO 10918 for any ordering restrictions that are defined. To identify motion JPEG frames in an AVI "movi'" segment, the stream ID plus the two-character code for a compressed DIB is used and would have the following format: DIB Bits '##dc' BYTE abJPEGImageData [ ]; JPEG DIB Definitions The following have been added to MMREG.H: #define JPEG_DIB mmioFOURCC('J','P','E','G'); /* Still image JPEG DIB biCompression */ #define MJPG_DIB mmioFOURCC('M','J','P','G'); /* Motion JPEG DIB biCompression */ /* JPEGProcess Definitions */ #define JPEG_PROCESS_BASELINE 0 /* Baseline DCT */ /* JIF Marker byte pairs in JPEG Interchange Format sequence */ #define JIFMK_SOF0 0xFFC0 /* SOF Huff - Baseline DCT*/ #define JIFMK_SOF1 0xFFC1 /* SOF Huff - Extended sequential DCT*/ #define JIFMK_SOF2 0xFFC2 /* SOF Huff - Progressive DCT*/ #define JIFMK_SOF3 0xFFC3 /* SOF Huff - Spatial (sequential) lossless*/ #define JIFMK_SOF5 0xFFC5 /* SOF Huff - Differential sequential DCT*/ #define JIFMK_SOF6 0xFFC6 /* SOF Huff - Differential progressive DCT*/ #define JIFMK_SOF7 0xFFC7 /* SOF Huff - Differential spatial*/ #define JIFMK_JPG 0xFFC8 /* SOF Arith - Reserved for JPEG extensions*/ #define JIFMK_SOF9 0xFFC9 /* SOF Arith - Extended sequential DCT*/ #define JIFMK_SOF10 0xFFCA /* SOF Arith - Progressive DCT*/ #define JIFMK_SOF11 0xFFCB /* SOF Arith - Spatial (sequential) lossless*/ #define JIFMK_SOF13 0xFFCD /* SOF Arith - Differential sequential DCT*/ #define JIFMK_SOF14 0xFFCE /* SOF Arith - Differential progressive DCT*/ #define JIFMK_SOF15 0xFFCF /* SOF Arith - Differential spatial*/ #define JIFMK_DHT 0xFFC4 /* Define Huffman Table(s) */ #define JIFMK_DAC 0xFFCC /* Define Arithmetic coding conditioning(s) */ #define JIFMK_RST0 0xFFD0 /* Restart with modulo 8 count 0 */ #define JIFMK_RST1 0xFFD1 /* Restart with modulo 8 count 1 */ #define JIFMK_RST2 0xFFD2 /* Restart with modulo 8 count 2 */ #define JIFMK_RST3 0xFFD3 /* Restart with modulo 8 count 3 */ #define JIFMK_RST4 0xFFD4 /* Restart with modulo 8 count 4 */ #define JIFMK_RST5 0xFFD5 /* Restart with modulo 8 count 5 */ #define JIFMK_RST6 0xFFD6 /* Restart with modulo 8 count 6 */ #define JIFMK_RST7 0xFFD7 /* Restart with modulo 8 count 7 */ #define JIFMK_SOI 0xFFD8 /* Start of Image */ #define JIFMK_EOI 0xFFD9 /* End of Image */ #define JIFMK_SOS 0xFFDA /* Start of Scan */ #define JIFMK_DQT 0xFFDB /* Define quantization Table(s) */ #define JIFMK_DNL 0xFFDC /* Define Number of Lines */ #define JIFMK_DRI 0xFFDD /* Define Restart Interval */ #define JIFMK_DHP 0xFFDE /* Define Hierarchical progression */ #define JIFMK_EXP 0xFFDF /* Expand Reference Component(s) */ #define JIFMK_APP0 0xFFE0 /* Application Field 0*/ #define JIFMK_APP1 0xFFE1 /* Application Field 1*/ #define JIFMK_APP2 0xFFE2 /* Application Field 2*/ #define JIFMK_APP3 0xFFE3 /* Application Field 3*/ #define JIFMK_APP4 0xFFE4 /* Application Field 4*/ #define JIFMK_APP5 0xFFE5 /* Application Field 5*/ #define JIFMK_APP6 0xFFE6 /* Application Field 6*/ #define JIFMK_APP7 0xFFE7 /* Application Field 7*/ #define JIFMK_JPG0 0xFFF0 /* Reserved for JPEG extensions */ #define JIFMK_JPG1 0xFFF1 /* Reserved for JPEG extensions */ #define JIFMK_JPG2 0xFFF2 /* Reserved for JPEG extensions */ #define JIFMK_JPG3 0xFFF3 /* Reserved for JPEG extensions */ #define JIFMK_JPG4 0xFFF4 /* Reserved for JPEG extensions */ #define JIFMK_JPG5 0xFFF5 /* Reserved for JPEG extensions */ #define JIFMK_JPG6 0xFFF6 /* Reserved for JPEG extensions */ #define JIFMK_JPG7 0xFFF7 /* Reserved for JPEG extensions */ #define JIFMK_JPG8 0xFFF8 /* Reserved for JPEG extensions */ #define JIFMK_JPG9 0xFFF9 /* Reserved for JPEG extensions */ #define JIFMK_JPG10 0xFFFA /* Reserved for JPEG extensions */ #define JIFMK_JPG11 0xFFFB /* Reserved for JPEG extensions */ #define JIFMK_JPG12 0xFFFC /* Reserved for JPEG extensions */ #define JIFMK_JPG13 0xFFFD /* Reserved for JPEG extensions */ #define JIFMK_COM 0xFFFE /* Comment */ #define JIFMK_TEM 0xFF01 /* for temp private use arith code */ #define JIFMK_RES 0xFF02 /* Reserved */ #define JIFMK_00 0xFF00 /* Zero stuffed byte - entropy data */ #define JIFMK_FF 0xFFFF /* Fill byte */ /* JPEGColorSpaceID Definitions */ #define JPEG_Y 1 /* Y only component of YCbCr */ #define JPEG_YCbCr 2 /* YCbCr as define by CCIR 601 */ #define JPEG_RGB 3 /* 3 component RGB */ /* Structure definitions */ typedef struct tagEXBMINFOHEADER { BITMAPINFOHEADER bmi; /* extended BITMAPINFOHEADER fields */ DWORD biExtDataOffset; /* Other stuff will go here */ /* Format-specific information */ /* biExtDataOffset points here */ } EXBMINFOHEADER; typedef struct tagJPEGINFOHEADER { /* compression-specific fields */ /* these fields are defined for 'JPEG' and 'MJPG' */ DWORD JPEGSize; DWORD JPEGProcess; /* Process specific fields */ DWORD JPEGColorSpaceID; DWORD JPEGBitsPerSample; DWORD JPEGHSubSampling; DWORD JPEGVSubSampling; } JPEGINFOHEADER #ifdef MJPGDHTSEG_STORAGE /* Default DHT Segment */ MJPGHDTSEG_STORAGE BYTE MJPGDHTSeg[0x1A0] = { /* JPEG DHT Segment for YCrCb omitted from MJPG data */ 0xFF,0xC4,0x01,0xA2, 0x00,0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x01, 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00, 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x10,0x00, 0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D, 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61, 0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52, 0xD1,0xF0,0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25, 0x26,0x27,0x28,0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45, 0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64, 0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83, 0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99, 0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6, 0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3, 0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8, 0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0x11,0x00,0x02, 0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77,0x00, 0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71, 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52, 0xF0,0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19, 0x1A,0x26,0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45, 0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64, 0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82, 0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98, 0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5, 0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2, 0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8, 0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA }; #endif



ProgNET-CZ is member of system BillBoard.cz - banner exchange xawtv-3.106/contrib/motv.desktop000066400000000000000000000003471343350355000167210ustar00rootroot00000000000000[Desktop Entry] Comment=Analog TV viewing application Icon=xawtv Exec=motv Name=MoTV Television Viewer Terminal=false StartupNotify=false Type=Application Categories=AudioVideo;Video; Keywords=video;tv;viewer;v4l;v4l2;video4linux; xawtv-3.106/contrib/motv.metainfo.xml000066400000000000000000000007001343350355000176420ustar00rootroot00000000000000 motv.desktop xawtv.desktop CC0-1.0 GPL-2.0+ MoTV Television Viewer Motif UI version of xawtv http://linuxtv.org/wiki/index.php/Xawtv jwrdegoede_at_fedoraproject.org xawtv-3.106/contrib/mtt.desktop000066400000000000000000000003651343350355000165400ustar00rootroot00000000000000[Desktop Entry] Comment=Analog TV Teletext viewing application Icon=xawtv Exec=mtt Name=MTT Teletext Viewer Terminal=false StartupNotify=false Type=Application Categories=AudioVideo;Video; Keywords=video;tv;viewer;v4l;v4l2;video4linux;teletext; xawtv-3.106/contrib/mtt.metainfo.xml000066400000000000000000000006731343350355000174720ustar00rootroot00000000000000 mtt.desktop xawtv.desktop CC0-1.0 GPL-2.0+ MTT Teletext Viewer Easy to use Teletext GUI http://linuxtv.org/wiki/index.php/Xawtv jwrdegoede_at_fedoraproject.org xawtv-3.106/contrib/r@dio.mp3000066400000000000000000000000651343350355000160140ustar00rootroot00000000000000see http://www.nbc-vbi.de.vu for up-to-date versions xawtv-3.106/contrib/vdr.config000066400000000000000000000026361343350355000163260ustar00rootroot00000000000000# eventmap config for using xawtv with vdr # contributed by Gregoire Favre [eventmap] kbd-key-Return = vdr "HITK" "Ok" kbd-key-Up = vdr "HITK" "Up" kbd-key-Down = vdr "HITK" "Down" kbd-key-M = vdr "HITK" "Menu" kbd-key-Return = vdr "HITK" "Ok" kbd-key-BackSpace = vdr "HITK" "Back" kbd-key-Left = vdr "HITK" "Left" kbd-key-Right = vdr "HITK" "Right" kbd-key-F1 = vdr "HITK" "Red" kbd-key-F2 = vdr "HITK" "Green" kbd-key-F3 = vdr "HITK" "Yellow" kbd-key-F4 = vdr "HITK" "Blue" kbd-key-KP_0 = vdr "HITK" "0" kbd-key-KP_1 = vdr "HITK" "1" kbd-key-KP_2 = vdr "HITK" "2" kbd-key-KP_3 = vdr "HITK" "3" kbd-key-KP_4 = vdr "HITK" "4" kbd-key-KP_5 = vdr "HITK" "5" kbd-key-KP_6 = vdr "HITK" "6" kbd-key-KP_7 = vdr "HITK" "7" kbd-key-KP_8 = vdr "HITK" "8" kbd-key-KP_9 = vdr "HITK" "9" kbd-key-F5 = vdr "HITK" "Play" kbd-key-F6 = vdr "HITK" "Pause" kbd-key-F7 = vdr "HITK" "Stop" kbd-key-R = vdr "HITK" "Record" kbd-key-F12 = vdr "HITK" "FastFwd" kbd-key-F11 = vdr "HITK" "FastRew" kbd-key-P = vdr "HITK" "Power" kbd-key-F9 = vdr "HITK" "Channel+" kbd-key-F10 = vdr "HITK" "Channel-" kbd-key-KP_Add = vdr "HITK" "Volume+" kbd-key-KP_Subtract = vdr "HITK" "Volume-" kbd-key-$ = vdr "HITK" "Mute" kbd-key-S = vdr "HITK" "Schedule" kbd-key-C = vdr "HITK" "Channels" kbd-key-T = vdr "HITK" "Timers" kbd-key-G = vdr "HITK" "Recordings" kbd-key-X = vdr "HITK" "Setup" kbd-key-V = vdr "HITK" "Commands" kbd-key-N = vdr "HITK" "None" xawtv-3.106/contrib/vtx2xawtv/000077500000000000000000000000001343350355000163325ustar00rootroot00000000000000xawtv-3.106/contrib/vtx2xawtv/README.vtx2xawtv000066400000000000000000000016551343350355000212150ustar00rootroot00000000000000 vtx2xawtv Public Domain, von Kai Fett K@i-Fett.de Schonmal drüber geärgert, daß das Erfassen der Sendernamen ewgig lange dauert und noch dazu nervenaufreibend ist? Insbesondere bei den "Privaten", die die Hälfte der Zeit Werbung und damit kein Senderlogo zeigen? Das geht auch einfacher: Kabel 1 bietet ab Videotextseite 600 eine Kanalübersicht der Telekom, die sich herrlich zur Weiterverarbeitung mit Perl eignet: - Zunächst packt man die für seinen Ort passenden Seiten in Text- dateien, z.B. in alevt mit Taste 's', oder mit vbidecode und vtx2ascii -a. Bitte die Seiten als ASCII abspeichern! - Dann piped man diese Textdateien durch das beiliegende Script vtx2xawtv, und fügt den Output an seine Konfigurationsdatei an: cat vtx*.txt | ./vtx2xawtv >> ~/.xawtv Schon hat man alle Sender mit der offiziellen Senderbezeichnung in xawtv zur Verfügung. Über Feedback würde ich mich freuen! Viel Spaß Kaixawtv-3.106/contrib/vtx2xawtv/vtx2xawtv000066400000000000000000000030321343350355000202500ustar00rootroot00000000000000#!/usr/bin/perl # # vtx2xawtv - Konvertiert Kabel1-Kanalliste ins .xawtv-Format # # 1) Mit Videotext-Tool aus dem Kabel1-Text die Seiten mit # den Kanal-Listen aufrufen und abspeichern, z.B. als # vtx1.txt bis vtx3.txt # # 2) Diese Seiten durch vtx2xawtv pipen: # # cat vtx?.txt | vtx2xawtv >> ~/.xawtv # # # Have Fun, # Kai (K@i-Fett.de) # # PS: Dieses Scriptchen ist natürlich Public Domain, es wäre aber schön, # wenn mein Name in weiteren Versionen drinbleibt. # ############################################################################# # while(){ # if (/\*/) { # # # Zeile in 3 Teile zerlegen, jeweils feste Breite # # /(.........................)(..)(...)/; # $name=$1; $typ=$2; $chan=$3; $name=~s/\(.*\)//; # Bemerkungen in Klammern löschen $name=~s/(\ )*$//; # Leerzeichen am Ende... $name=~s/^(\ )//; # ...und am Anfang löschen if ($typ=~/K/){$typ='E'} # Die Kabel1-Liste notiert if ($typ=~/S/ and $chan<21){$typ='SE'} # die Kanäle etwas if ($typ=~/S/ and $chan>20){$typ='S'} # anders als xawtv $chan=~s/(\ )*$//; # Auch wieder füllende $chan=~s/^(\ )*//; # und führende Leerzeichen abschneiden print "[$name]\nchannel=$typ$chan\n\n"; # Und im xawtv-Format ausgeben. } }xawtv-3.106/contrib/xawtv-bayer.diff000066400000000000000000000301211343350355000174350ustar00rootroot00000000000000Ok..This is the patch for xawtv-3.92.. diff -uprN xawtv-3.92/libng/color_bayer2rgb.c xawtv-3.92-devel/libng/color_bayer2rgb.c --- xawtv-3.92/libng/color_bayer2rgb.c 1970-01-01 01:00:00.000000000 +0100 +++ xawtv-3.92-devel/libng/color_bayer2rgb.c 2004-05-31 10:37:11.000000000 +0200 @@ -0,0 +1,257 @@ +/* + * colorspace conversion functions + * -- bayer to rgb colorspace conversions + * + * (c) 2004 Luca Risolia + * Heavily based on color_yuv2rgb.c by Gerd Knorr + * sbggr8_to_rgb24 written by Christopher Cramer + */ + +#define NG_PRIVATE +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "grab-ng.h" + +#define RED 0 +#define GREEN 1 +#define BLUE 2 + +#define avg2(x,y) ((((int)(x)) + ((int)(y))) / 2) +#define avg3(x,y,z) ((((int)(x)) + ((int)(y)) + ((int)(z))) / 3) +#define avg4(w,x,y,z) ((((int)(w)) + ((int)(x)) + ((int)(y)) + ((int)(z))) / 4) + +/* ------------------------------------------------------------------- */ +/* bayer bgbg...grgr...to rgb24 */ + +/* + bgbgbg + grgrgr + bgbgbg + grgrgr +*/ + +static void +sbggr8_to_rgb24(void *h, struct ng_video_buf *out, struct ng_video_buf *in) +{ + unsigned char *restrict s, *restrict d; + unsigned long x, y, i, j; + + d = out->data; + s = in->data; + x = in->fmt.width; + y = in->fmt.height; + + /* upper left corner */ + d[0 + RED] = s[x + 1]; + d[0 + BLUE] = s[0]; + d[0 + GREEN] = ((int)s[1] + (int)s[x]) / 2; + + /* top line (minus corners) */ + i = 1; + while (i < x - 2) { + d[i * 3 + RED] = s[x + i]; + d[i * 3 + GREEN] = s[i]; + d[i * 3 + BLUE] = avg2(s[i - 1], s[i + 1]); + + i++; + + d[i * 3 + RED] = avg2(s[x + i - 1], s[x + i + 1]); + d[i * 3 + GREEN] = avg3(s[i - 1], s[i + 1], s[x + 1]); + d[i * 3 + BLUE] = s[i]; + + i++; + } + + /* upper right corner */ + d[i * 3 + RED] = s[x + i]; + d[i * 3 + GREEN] = s[i]; + d[i * 3 + BLUE] = s[i - 1]; + + /* middle lines */ + j = 1; + while (j < y - 2) { + d[j * x * 3 + RED] = s[j * x + 1]; + d[j * x * 3 + GREEN] = s[j * x]; + d[j * x * 3 + BLUE] = avg2(s[(j - 1) * x], s[(j + 1) * x]); + + i = 1; + while (i < x - 2) { + d[(j * x + i) * 3 + RED] = s[j * x + i]; + d[(j * x + i) * 3 + GREEN] = avg4(s[(j - 1) * x + i], + s[j * x + i - 1], + s[j * x + i + 1], + s[(j + 1) * x + i]); + d[(j * x + i) * 3 + BLUE] = avg4(s[(j - 1) * x + i - 1], + s[(j - 1) * x + i + 1], + s[(j + 1) * x + i - 1], + s[(j + 1) * x + i + 1]); + + i++; + + d[(j * x + i) * 3 + RED] = avg2(s[j * x + i - 1], + s[j * x + i + 1]); + d[(j * x + i) * 3 + GREEN] = s[j * x + i]; + d[(j * x + i) * 3 + BLUE] = avg2(s[(j - 1) * x + i], + s[(j + 1) * x + i]); + + i++; + } + + d[(j * x + i) * 3 + RED] = s[j * x + i]; + d[(j * x + i) * 3 + BLUE] = avg2(s[(j - 1) * x + i - 1], + s[(j + 1) * x + i - 1]); + d[(j * x + i) * 3 + GREEN] = avg2(s[(j - 1) * x + i], + s[(j + 1) * x + i]); + + j++; + + d[(j * x + i) * 3 + RED] = avg2(s[(j - 1) * x + i + 1], + s[(j + 1) * x + i + 1]); + d[(j * x + i) * 3 + BLUE] = s[j * x + i]; + d[(j * x + i) * 3 + GREEN] = avg3(s[(j - 1) * x + i], + s[j * x + i + 1], + s[(j + 1) * x + i]); + + i = 1; + while (i < x - 2) { + d[(j * x + i) * 3 + RED] = avg2(s[(j - 1) * x + i], + s[(j + 1) * x + i]); + d[(j * x + i) * 3 + GREEN] = s[j * x + i]; + d[(j * x + i) * 3 + BLUE] = avg2(s[j * x + i - 1], + s[j * x + i + 1]); + + i++; + + d[(j * x + i) * 3 + RED] = avg4(s[(j - 1) * x + i - 1], + s[(j - 1) * x + i + 1], + s[(j + 1) * x + i - 1], + s[(j + 1) * x + i + 1]); + d[(j * x + i) * 3 + GREEN] = avg4(s[(j - 1) * x + i], + s[j * x + i - 1], + s[j * x + i + 1], + s[(j + 1) * x + i]); + d[(j * x + i) * 3 + BLUE] = s[j * x + i]; + + i++; + } + + j++; + } + + /* lower left corner */ + d[(j * x) * 3 + RED] = s[j * x + 1]; + d[(j * x) * 3 + GREEN] = s[j * x]; + d[(j * x) * 3 + BLUE] = s[(j - 1) * x]; + + /* bottom line */ + i = 1; + while (i < x - 2) { + d[(j * x + i) * 3 + RED] = s[j * x + i]; + d[(j * x + i) * 3 + GREEN] = avg2(s[j * x + i - 1], s[j * x + i + 1]); + d[(j * x + i) * 3 + BLUE] = avg2(s[(j - 1) * x + i - 1], + s[(j - 1) * x + i + 1]); + + i++; + + d[(j * x + i) * 3 + RED] = avg2(s[j * x + i - 1], s[j * x + i + 1]); + d[(j * x + i) * 3 + GREEN] = s[j * x + i]; + d[(j * x + i) * 3 + BLUE] = s[(j - 1) * x + i]; + + i++; + } + + /* lower right corner */ + d[(j * x + i) * 3 + RED] = s[j * x + i]; + d[(j * x + i) * 3 + GREEN] = avg2(s[(j - 1) * x + i], s[j * x + i - 1]); + d[(j * x + i) * 3 + BLUE] = s[(j - 1) * x + i - 1]; +} + +/* ------------------------------------------------------------------- */ +/* bayer bgbg...grgr...to rgb16 */ + +static void +sbggr8_to_rgb16(void *p, struct ng_video_buf *out, struct ng_video_buf *in) +{ + unsigned char *restrict s1, *restrict s2, *restrict d; + unsigned long i, j, x, y, w, h; + unsigned char r, g1, g2, b, g; + + w = in->fmt.width; + h = in->fmt.height; + d = out->data; + s1 = in->data; + s2 = s1 + w; + i = 0; + j = w; + + for (y = 0; y < h; y += 2, i += w * 2, j += w * 2) { + for (x = 0; x < w; x += 2) { + + b = d[i + x] ; + g1 = d[i + 1 + x]; + g2 = d[j + x]; + r = d[j + 1 + x]; + g = (g1 >> 1) + (g2 >> 1); + + *s1 = ( ((r & 0xF8) >> 3) | + ((g1 & 0xFC) << 3) | + ((b & 0xF8) << 8) ); + + s1 += 2; + + *s1 = ( ((r & 0xF8) >> 3) | + ((g & 0xFC) << 3) | + ((b & 0xF8) << 8) ); + + s1 += 2; + + *s2 = ( ((r & 0xF8) >> 3) | + ((g & 0xFC) << 3) | + ((b & 0xF8) << 8) ); + + s2 += 2; + + *s2 = ( ((r & 0xF8) >> 3) | + ((g2 & 0xFC) << 3) | + ((b & 0xF8) << 8) ); + + s2 += 2; + } + } +} + +/* ------------------------------------------------------------------- */ + +static struct ng_video_conv conv_list[] = { + { + init: ng_conv_nop_init, + fini: ng_conv_nop_fini, + frame: sbggr8_to_rgb24, + fmtid_in: VIDEO_SBGGR8, + fmtid_out: VIDEO_RGB24, + }, + { + init: ng_conv_nop_init, + fini: ng_conv_nop_fini, + frame: sbggr8_to_rgb16, + fmtid_in: VIDEO_SBGGR8, + fmtid_out: VIDEO_RGB16_LE, + } + +}; +static const int nconv = sizeof(conv_list)/sizeof(struct ng_video_conv); + +/* ------------------------------------------------------------------- */ + +void ng_color_bayer2rgb_init(void) +{ + /* register stuff */ + ng_conv_register(NG_PLUGIN_MAGIC,"built-in",conv_list,nconv); +} diff -uprN xawtv-3.92/libng/grab-ng.c xawtv-3.92-devel/libng/grab-ng.c --- xawtv-3.92/libng/grab-ng.c 2003-03-28 13:19:28.000000000 +0100 +++ xawtv-3.92-devel/libng/grab-ng.c 2004-05-30 23:59:15.000000000 +0200 @@ -42,6 +42,7 @@ const unsigned int ng_vfmt_to_depth[] = 0, /* unused */ 8, /* RGB8 */ 8, /* GRAY8 */ + 8, /* SBGGR8 */ 16, /* RGB15 LE */ 16, /* RGB16 LE */ 16, /* RGB15 BE */ @@ -64,6 +65,7 @@ const char* ng_vfmt_to_desc[] = { "none", "8 bit PseudoColor (dithering)", "8 bit StaticGray", + "8 bit Sequential Bayer BGGR", "15 bit TrueColor (LE)", "16 bit TrueColor (LE)", "15 bit TrueColor (BE)", @@ -865,6 +867,7 @@ ng_init(void) ng_device_init(); ng_color_packed_init(); ng_color_yuv2rgb_init(); + ng_color_bayer2rgb_init(); ng_writefile_init(); count += ng_plugins(LIBDIR); diff -uprN xawtv-3.92/libng/grab-ng.h xawtv-3.92-devel/libng/grab-ng.h --- xawtv-3.92/libng/grab-ng.h 2003-02-14 15:14:07.000000000 +0100 +++ xawtv-3.92-devel/libng/grab-ng.h 2004-05-30 21:44:23.000000000 +0200 @@ -41,23 +41,24 @@ extern char ng_v4l_conf[256]; #define VIDEO_NONE 0 #define VIDEO_RGB08 1 /* bt848 dithered */ #define VIDEO_GRAY 2 -#define VIDEO_RGB15_LE 3 /* 15 bpp little endian */ -#define VIDEO_RGB16_LE 4 /* 16 bpp little endian */ -#define VIDEO_RGB15_BE 5 /* 15 bpp big endian */ -#define VIDEO_RGB16_BE 6 /* 16 bpp big endian */ -#define VIDEO_BGR24 7 /* bgrbgrbgrbgr (LE) */ -#define VIDEO_BGR32 8 /* bgr-bgr-bgr- (LE) */ -#define VIDEO_RGB24 9 /* rgbrgbrgbrgb (BE) */ -#define VIDEO_RGB32 10 /* -rgb-rgb-rgb (BE) */ -#define VIDEO_LUT2 11 /* lookup-table 2 byte depth */ -#define VIDEO_LUT4 12 /* lookup-table 4 byte depth */ -#define VIDEO_YUYV 13 /* 4:2:2 */ -#define VIDEO_YUV422P 14 /* YUV 4:2:2 (planar) */ -#define VIDEO_YUV420P 15 /* YUV 4:2:0 (planar) */ -#define VIDEO_MJPEG 16 /* MJPEG (AVI) */ -#define VIDEO_JPEG 17 /* JPEG (JFIF) */ -#define VIDEO_UYVY 18 /* 4:2:2 */ -#define VIDEO_FMT_COUNT 19 +#define VIDEO_SBGGR8 3 /* 8 bpp lines: bgbgbgbg...grgrgrgr... */ +#define VIDEO_RGB15_LE 4 /* 15 bpp little endian */ +#define VIDEO_RGB16_LE 5 /* 16 bpp little endian */ +#define VIDEO_RGB15_BE 6 /* 15 bpp big endian */ +#define VIDEO_RGB16_BE 7 /* 16 bpp big endian */ +#define VIDEO_BGR24 8 /* bgrbgrbgrbgr (LE) */ +#define VIDEO_BGR32 9 /* bgr-bgr-bgr- (LE) */ +#define VIDEO_RGB24 10 /* rgbrgbrgbrgb (BE) */ +#define VIDEO_RGB32 11 /* -rgb-rgb-rgb (BE) */ +#define VIDEO_LUT2 12 /* lookup-table 2 byte depth */ +#define VIDEO_LUT4 13 /* lookup-table 4 byte depth */ +#define VIDEO_YUYV 14 /* 4:2:2 */ +#define VIDEO_YUV422P 15 /* YUV 4:2:2 (planar) */ +#define VIDEO_YUV420P 16 /* YUV 4:2:0 (planar) */ +#define VIDEO_MJPEG 17 /* MJPEG (AVI) */ +#define VIDEO_JPEG 18 /* JPEG (JFIF) */ +#define VIDEO_UYVY 19 /* 4:2:2 */ +#define VIDEO_FMT_COUNT 20 #define AUDIO_NONE 0 #define AUDIO_U8_MONO 1 @@ -478,6 +479,7 @@ void ng_rgb24_to_lut4(unsigned char *des /* init functions */ void ng_color_packed_init(void); void ng_color_yuv2rgb_init(void); +void ng_color_bayer2rgb_init(void); void ng_writefile_init(void); /* for yuv2rgb using lookup tables (color_lut.c, color_yuv2rgb.c) */ diff -uprN xawtv-3.92/libng/plugins/drv0-v4l2.c xawtv-3.92-devel/libng/plugins/drv0-v4l2.c --- xawtv-3.92/libng/plugins/drv0-v4l2.c 2003-04-09 20:15:07.000000000 +0200 +++ xawtv-3.92-devel/libng/plugins/drv0-v4l2.c 2004-05-30 18:35:20.000000000 +0200 @@ -134,6 +134,7 @@ struct ng_vid_driver v4l2_driver = { static __u32 xawtv_pixelformat[VIDEO_FMT_COUNT] = { [ VIDEO_RGB08 ] = V4L2_PIX_FMT_HI240, [ VIDEO_GRAY ] = V4L2_PIX_FMT_GREY, + [ VIDEO_SBGGR8] = V4L2_PIX_FMT_SBGGR8, [ VIDEO_RGB15_LE ] = V4L2_PIX_FMT_RGB555, [ VIDEO_RGB16_LE ] = V4L2_PIX_FMT_RGB565, [ VIDEO_RGB15_BE ] = V4L2_PIX_FMT_RGB555X, diff -uprN xawtv-3.92/libng/Subdir.mk xawtv-3.92-devel/libng/Subdir.mk --- xawtv-3.92/libng/Subdir.mk 2003-02-14 15:14:07.000000000 +0100 +++ xawtv-3.92-devel/libng/Subdir.mk 2004-05-30 20:23:41.000000000 +0200 @@ -6,6 +6,7 @@ OBJS-libng := \ libng/color_packed.o \ libng/color_lut.o \ libng/color_yuv2rgb.o \ + libng/color_bayer2rgb.o \ libng/convert.o libng/libng.a: $(OBJS-libng) diff -uprN xawtv-3.92/libng/videodev2.h xawtv-3.92-devel/libng/videodev2.h --- xawtv-3.92/libng/videodev2.h 2003-02-14 15:14:07.000000000 +0100 +++ xawtv-3.92-devel/libng/videodev2.h 2004-05-30 22:18:01.000000000 +0200 @@ -177,6 +177,7 @@ struct v4l2_pix_format #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ #define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG..GRGR.. */ #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ #define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */ xawtv-3.106/contrib/xawtv.appdata.xml000066400000000000000000000026131343350355000176430ustar00rootroot00000000000000 xawtv.desktop CC0-1.0 GPL-2.0+ xawtv Analog TV viewing application

xawtv was originally just an analog TV viewing application for Bttv devices (bt848, bt878) using the Athena widgets, but evolved into a small suite of X11 applications for V4L devices.

The xawtv package includes a number of useful console commandline utilities:

  • alevtd - a http deamon for use with analogue TV teletext
  • radio -- a console radio listening app
  • scantv -- an analogue TV frequency scanner
  • v4l-conf -- current video mode (size and color depth)
  • v4lctl -- used to control a v4l device and set varying image parameters
  • webcam -- capture images from a webcam
http://linuxtv.org/wiki/index.php/Xawtv http://www.easylinux.de/Artikel/ausgabe/2004/01/036-xawtv/tv_8.png http://www.easylinux.de/Artikel/ausgabe/2004/01/036-xawtv/xawtv1.png jwrdegoede_at_fedoraproject.org
xawtv-3.106/contrib/xawtv.desktop000066400000000000000000000003511343350355000171000ustar00rootroot00000000000000[Desktop Entry] Comment=Analog TV viewing application Icon=xawtv Exec=xawtv Name=XawTV Television Viewer Terminal=false StartupNotify=false Type=Application Categories=AudioVideo;Video; Keywords=video;tv;viewer;v4l;v4l2;video4linux; xawtv-3.106/contrib/xawtv16x16.xpm000066400000000000000000000067061343350355000167530ustar00rootroot00000000000000/* XPM */ static char * xawtv16x16[] = { "16 16 181 2", " c None", ". c #8F8E91", "+ c #969397", "@ c #979499", "# c #979497", "$ c #918E92", "% c #949196", "& c #949195", "* c #939094", "= c #979498", "- c #979599", "; c #959296", "> c #928F91", ", c #8F8C8F", "' c #858487", ") c #818184", "! c #878789", "~ c #8A898C", "{ c #232228", "] c #16161A", "^ c #151519", "/ c #16151A", "( c #161519", "_ c #15141A", ": c #14141A", "< c #14131A", "[ c #141319", "} c #24242D", "| c #767478", "1 c #8D8B90", "2 c #0E0D10", "3 c #000000", "4 c #000101", "5 c #020204", "6 c #101011", "7 c #19181C", "8 c #7A777B", "9 c #8F8E93", "0 c #0C0C10", "a c #1F1F20", "b c #252526", "c c #282829", "d c #000001", "e c #1A1A1C", "f c #7B797C", "g c #88878C", "h c #0C0C0F", "i c #3B331F", "j c #B09830", "k c #554D2D", "l c #19181A", "m c #7B787B", "n c #848287", "o c #0B0B0E", "p c #4D4228", "q c #CAA734", "r c #867A5C", "s c #0A0A0B", "t c #171619", "u c #767476", "v c #7B7A80", "w c #0A0A0D", "x c #ACACAC", "y c #EEEDEC", "z c #E6E6E5", "A c #060608", "B c #141416", "C c #6E6C70", "D c #77767C", "E c #1B1B1C", "F c #EFEFED", "G c #FCFCFA", "H c #F5F5F4", "I c #676767", "J c #040405", "K c #121214", "L c #6A6A6E", "M c #76767A", "N c #0A0A0C", "O c #707070", "P c #FAFAF8", "Q c #FDFDFB", "R c #9A9A9A", "S c #070708", "T c #101113", "U c #66666A", "V c #747377", "W c #020100", "X c #3D2D04", "Y c #A08E58", "Z c #F7F7F6", "` c #9A8D64", " . c #1E1A0B", ".. c #151413", "+. c #626266", "@. c #727177", "#. c #0C0B0E", "$. c #362703", "%. c #F2B90C", "&. c #E1AE0C", "*. c #817E72", "=. c #F4F4F3", "-. c #C8981D", ";. c #CC9A0A", ">. c #5F4C15", ",. c #605F63", "'. c #6E6E72", "). c #433003", "!. c #EFB60C", "~. c #F5BC0C", "{. c #BFA24C", "]. c #A4A4A3", "^. c #4A494A", "/. c #D29E0A", "(. c #EAB30C", "_. c #7A6016", ":. c #5E5D62", "<. c #55AC4D", "[. c #1A5919", "}. c #1A8410", "|. c #204222", "1. c #1A1A20", "2. c #18181F", "3. c #121419", "4. c #342819", "5. c #6E541A", "6. c #4A391A", "7. c #23761C", "8. c #24CE12", "9. c #44C118", "0. c #3C571C", "a. c #1D461F", "b. c #479C40", "c. c #6A6E6B", "d. c #30C620", "e. c #38AA2C", "f. c #4F684C", "g. c #31C621", "h. c #32C422", "i. c #149914", "j. c #0F7812", "k. c #18B410", "l. c #117E0C", "m. c #435B3F", "n. c #35B826", "o. c #4C6648", "p. c #3BA22E", "q. c #3AA42E", "r. c #50684F", "s. c #5B5E5C", "t. c #2AC01A", "u. c #2FA023", "v. c #34822C", "w. c #427A3C", "x. c #487D43", "y. c #428E3A", "z. c #30C61F", "A. c #2FCB1E", "B. c #32BB24", "C. c #514F52", "D. c #30B421", "E. c #3E3C3E", "F. c #2DAA1F", "G. c #2DAB1F", "H. c #494849", "I. c #41C033", "J. c #3C7A35", "K. c #3DA831", "L. c #41793A", "M. c #32C521", "N. c #33C124", "O. c #408439", "P. c #34A028", "Q. c #3F6D3A", "R. c #37942D", "S. c #4A494B", "T. c #35AC27", "U. c #464445", "V. c #409036", "W. c #409038", "X. c #565555", ". + @ # $ % & * = - ; > , ' ) ! ", "~ { ] ] ] ] ] ^ / ( _ : < [ } | ", "1 2 3 3 3 3 3 3 3 4 5 6 3 3 7 8 ", "9 0 3 3 3 3 3 3 3 a b c d 3 e f ", "g h 3 3 3 3 3 3 3 i j k d 3 l m ", "n o 3 3 3 3 3 3 3 p q r s 3 t u ", "v w 3 3 3 3 3 3 3 x y z A 3 B C ", "D w 3 3 3 3 3 3 E F G H I J K L ", "M N 3 3 3 3 3 3 O P G Q R S T U ", "V w 3 3 3 3 W X Y Z G Q ` ...+.", "@.#.3 3 3 3 $.%.&.*.Q =.-.;.>.,.", "'.N 3 3 3 3 ).!.~.{.].^./.(._.:.", "<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.", "c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.", "s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.", "I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X."}; xawtv-3.106/contrib/xawtv32x32.xpm000066400000000000000000000266461343350355000167540ustar00rootroot00000000000000/* XPM */ static char * xawtv32x32[] = { "32 32 591 2", " c None", ". c #A4A4A6", "+ c #9D9C9E", "@ c #A09EA1", "# c #9F9D9F", "$ c #9A999C", "% c #9C9A9D", "& c #939194", "* c #969597", "= c #989798", "- c #9A999A", "; c #979598", "> c #9E9D9F", ", c #A1A0A1", "' c #A1A0A2", ") c #9F9EA0", "! c #9C9B9D", "~ c #A09FA2", "{ c #A09EA0", "] c #9E9D9E", "^ c #9C9B9C", "/ c #9A999B", "( c #969497", "_ c #8F8F91", ": c #969698", "< c #959597", "[ c #979798", "} c #878789", "| c #828084", "1 c #8F8A90", "2 c #918C92", "3 c #928D94", "4 c #908C92", "5 c #938E93", "6 c #928E92", "7 c #918C91", "8 c #8E8A8F", "9 c #8E8A90", "0 c #8F8A91", "a c #8F8B91", "b c #8F8A8F", "c c #8D888D", "d c #8E898F", "e c #8B878C", "f c #878386", "g c #878385", "h c #858184", "i c #837F83", "j c #7E7B7F", "k c #77777A", "l c #737376", "m c #727176", "n c #727276", "o c #838384", "p c #878689", "q c #888689", "r c #42414B", "s c #2D2C33", "t c #2D2C34", "u c #2D2C35", "v c #2D2B35", "w c #2C2B34", "x c #2C2B32", "y c #2B2B31", "z c #2A2A30", "A c #2B2A31", "B c #2B2A30", "C c #2A2932", "D c #292831", "E c #282730", "F c #282630", "G c #26252E", "H c #25242D", "I c #3E3E4B", "J c #78757B", "K c #706E74", "L c #909092", "M c #8A898B", "N c #1E1D23", "O c #000000", "P c #000001", "Q c #000002", "R c #000003", "S c #000103", "T c #2E2F38", "U c #7B7A7B", "V c #757377", "W c #8A898C", "X c #8C8A90", "Y c #1C1C23", "Z c #000101", "` c #020204", " . c #0B0B0C", ".. c #030304", "+. c #323138", "@. c #817D82", "#. c #706F72", "$. c #8E8D90", "%. c #8E8C92", "&. c #1A191F", "*. c #020203", "=. c #262626", "-. c #0D0D0E", ";. c #333137", ">. c #848086", ",. c #717072", "'. c #929194", "). c #908E94", "!. c #19181F", "~. c #010101", "{. c #0A0A0B", "]. c #050506", "^. c #08080A", "/. c #131315", "(. c #040406", "_. c #010102", ":. c #343338", "<. c #868287", "[. c #717071", "}. c #8D8D8F", "|. c #8E8C93", "1. c #19181E", "2. c #0B0B0B", "3. c #676767", "4. c #2A2A2A", "5. c #5D5D5E", "6. c #747474", "7. c #151516", "8. c #343337", "9. c #706F70", "0. c #18181D", "a. c #1A1A1B", "b. c #43403A", "c. c #817240", "d. c #81774D", "e. c #54524C", "f. c #303031", "g. c #323136", "h. c #868286", "i. c #868689", "j. c #88868D", "k. c #17161C", "l. c #100E09", "m. c #80631E", "n. c #E0B613", "o. c #E0C122", "p. c #A68E23", "q. c #2B2514", "r. c #010103", "s. c #312F34", "t. c #848085", "u. c #706F71", "v. c #868588", "w. c #85838A", "x. c #16161C", "y. c #0D0A03", "z. c #8F6E1B", "A. c #E0B711", "B. c #D8AE11", "C. c #B18D31", "D. c #373020", "E. c #2F2E33", "F. c #6F6F70", "G. c #838285", "H. c #807E85", "I. c #16151B", "J. c #0D0D0D", "K. c #8A8377", "L. c #B6974D", "M. c #BC9F63", "N. c #D7D2C6", "O. c #5A5959", "P. c #131314", "Q. c #2C2C30", "R. c #79767A", "S. c #6F6D6E", "T. c #808083", "U. c #78777E", "V. c #14141A", "W. c #4E4D4E", "X. c #E4E4E3", "Y. c #D8D7D6", "Z. c #EDECEB", "`. c #FEFEFC", " + c #C7C7C5", ".+ c #29292D", "++ c #716F73", "@+ c #6D6B6C", "#+ c #74737A", "$+ c #131319", "%+ c #858585", "&+ c #F9F9F8", "*+ c #F5F5F4", "=+ c #FCFCFA", "-+ c #F3F3F2", ";+ c #E2E2E1", ">+ c #121213", ",+ c #28282D", "'+ c #706E73", ")+ c #6C6A6D", "!+ c #807F82", "~+ c #706F76", "{+ c #0F0F10", "]+ c #C8C8C7", "^+ c #FBFBF9", "/+ c #FAFAF8", "(+ c #FDFDFB", "_+ c #F6F6F4", ":+ c #E5E5E4", "<+ c #848484", "[+ c #171718", "}+ c #030305", "|+ c #010000", "1+ c #242429", "2+ c #6D6D71", "3+ c #6A696D", "4+ c #7F7F82", "5+ c #6E6D74", "6+ c #060607", "7+ c #555555", "8+ c #C9C9C8", "9+ c #383838", "0+ c #0B0B0D", "a+ c #222227", "b+ c #68686C", "c+ c #69686C", "d+ c #7E7E80", "e+ c #6E6D73", "f+ c #131318", "g+ c #161617", "h+ c #B0B0AF", "i+ c #F9F9F7", "j+ c #EAEAE8", "k+ c #434344", "l+ c #202226", "m+ c #65666B", "n+ c #68676B", "o+ c #818183", "p+ c #6D6C72", "q+ c #333333", "r+ c #F7F7F5", "s+ c #F2F2F0", "t+ c #4B4B4B", "u+ c #0A0A0C", "v+ c #202225", "w+ c #626368", "x+ c #67666A", "y+ c #6B6A70", "z+ c #241B04", "A+ c #5D522E", "B+ c #CCCBC8", "C+ c #F6F6F5", "D+ c #FBFBFA", "E+ c #EDE8D6", "F+ c #4B4942", "G+ c #0C0C0D", "H+ c #0C0B0B", "I+ c #202125", "J+ c #606165", "K+ c #666569", "L+ c #6B6A6F", "M+ c #141319", "N+ c #060400", "O+ c #2F2103", "P+ c #A07709", "Q+ c #CEA011", "R+ c #877C5A", "S+ c #F2F2F1", "T+ c #F8F8F6", "U+ c #E6C767", "V+ c #493D12", "W+ c #060507", "X+ c #5A4B0D", "Y+ c #141001", "Z+ c #5E5F63", "`+ c #656468", " @ c #7D7D80", ".@ c #6A6970", "+@ c #705107", "@@ c #EDB30C", "#@ c #F2BA0C", "$@ c #F5BD0C", "%@ c #AD870A", "&@ c #494846", "*@ c #D8D8D6", "=@ c #F0F0EF", "-@ c #D7AC3C", ";@ c #A07308", ">@ c #7D5A07", ",@ c #D7A40A", "'@ c #4C3A05", ")@ c #1D1D21", "!@ c #5D5C61", "~@ c #646367", "{@ c #7C7B7F", "]@ c #69676F", "^@ c #17171C", "/@ c #6A4C06", "(@ c #F4BB0C", "_@ c #EDB90C", ":@ c #43370C", "<@ c #9F9F9E", "[@ c #E8E8E6", "}@ c #C09525", "|@ c #E7AE0A", "1@ c #E8B00B", "2@ c #C0930A", "3@ c #534523", "4@ c #5C5A5F", "5@ c #636266", "6@ c #7A7A7D", "7@ c #65646B", "8@ c #010100", "9@ c #755405", "0@ c #DDB531", "a@ c #DCD5C3", "b@ c #F1F1EF", "c@ c #BDBDBC", "d@ c #454546", "e@ c #AE8009", "f@ c #F3BB0C", "g@ c #E4AE0C", "h@ c #8A6E25", "i@ c #5B585E", "j@ c #636265", "k@ c #7A7A7C", "l@ c #636268", "m@ c #090601", "n@ c #8D6406", "o@ c #E6AD0B", "p@ c #EEB50C", "q@ c #F5BC0C", "r@ c #D8A30D", "s@ c #6C5931", "t@ c #585859", "u@ c #4D4D4E", "v@ c #1E1E20", "w@ c #060505", "x@ c #B58208", "y@ c #F2B90C", "z@ c #F1B80C", "A@ c #CF9B0A", "B@ c #513C05", "C@ c #2A2623", "D@ c #5A585F", "E@ c #626165", "F@ c #6E9C6A", "G@ c #34C925", "H@ c #10530D", "I@ c #020408", "J@ c #051805", "K@ c #169608", "L@ c #12720A", "M@ c #030806", "N@ c #020206", "O@ c #090707", "P@ c #332308", "Q@ c #5F410A", "R@ c #91660B", "S@ c #B8850A", "T@ c #966708", "U@ c #2B1D08", "V@ c #0A3608", "W@ c #1BB50A", "X@ c #1CC30A", "Y@ c #1DC30A", "Z@ c #49CA0B", "`@ c #54D90B", " # c #727E0A", ".# c #1E1507", "+# c #030307", "@# c #124313", "## c #34C326", "$# c #5A7959", "%# c #818C82", "&# c #3AB72D", "*# c #23C215", "=# c #324B3A", "-# c #277D25", ";# c #24E30F", "># c #385B3C", ",# c #34343E", "'# c #32323C", ")# c #303339", "!# c #2F3139", "~# c #2D2C37", "{# c #20222B", "]# c #1F232C", "^# c #1F1F28", "/# c #201F29", "(# c #2D2829", "_# c #443F2C", ":# c #40382A", "<# c #27282E", "[# c #2B482F", "}# c #3BA331", "|# c #25EE0F", "1# c #33C623", "2# c #429832", "3# c #31C91A", "4# c #2E9521", "5# c #34353E", "6# c #373840", "7# c #299821", "8# c #32C822", "9# c #5D6A5D", "0# c #848486", "a# c #566557", "b# c #2ADF16", "c# c #36BA28", "d# c #28E414", "e# c #419E36", "f# c #595858", "g# c #556153", "h# c #37BA28", "i# c #27E712", "j# c #2BDC17", "k# c #32C122", "l# c #16A913", "m# c #129C18", "n# c #169F0D", "o# c #02200F", "p# c #159A0A", "q# c #11961A", "r# c #032C0E", "s# c #18B812", "t# c #347E2A", "u# c #595456", "v# c #28E513", "w# c #458E3C", "x# c #575455", "y# c #429637", "z# c #2FCF1D", "A# c #52654D", "B# c #51664D", "C# c #2ED11C", "D# c #42923B", "E# c #5D5D60", "F# c #828284", "G# c #525154", "H# c #3B9332", "I# c #25EC0F", "J# c #2DC91C", "K# c #4B5F49", "L# c #504E51", "M# c #3F9736", "N# c #29E014", "O# c #3E9635", "P# c #419638", "Q# c #19B20E", "R# c #0D6D17", "S# c #1DD513", "T# c #074E1B", "U# c #1FDE0D", "V# c #1AC00E", "W# c #093B06", "X# c #1FDB0C", "Y# c #2A4728", "Z# c #545255", "`# c #27E513", " $ c #408A38", ".$ c #4F4D4F", "+$ c #485F46", "@$ c #28E113", "#$ c #43753D", "$$ c #41773B", "%$ c #27E313", "&$ c #485A45", "*$ c #59595B", "=$ c #7D7D7F", "-$ c #434244", ";$ c #34872B", ">$ c #24EB0F", ",$ c #2BC41A", "'$ c #3C4F3A", ")$ c #3E473E", "!$ c #2BBF1B", "~$ c #36A72A", "{$ c #565457", "]$ c #3CA830", "^$ c #32C222", "/$ c #515D51", "($ c #29DE15", "_$ c #38A12D", ":$ c #29DF15", "<$ c #2ADC16", "[$ c #39A12E", "}$ c #2CCC1B", "|$ c #4D4C4E", "1$ c #535254", "2$ c #27E512", "3$ c #3A8431", "4$ c #403E41", "5$ c #3D3B3E", "6$ c #2ABB1B", "7$ c #309C23", "8$ c #2FA021", "9$ c #2BB81C", "0$ c #414041", "a$ c #545455", "b$ c #7B7B7D", "c$ c #3F4B3F", "d$ c #27DA13", "e$ c #2BB31C", "f$ c #25E310", "g$ c #318C28", "h$ c #3C443B", "i$ c #2BBE1B", "j$ c #35A728", "k$ c #4C4B4D", "l$ c #545256", "m$ c #3AA72F", "n$ c #31C222", "o$ c #525753", "p$ c #35BA26", "q$ c #29E114", "r$ c #37B12A", "s$ c #32C123", "t$ c #28E014", "u$ c #3C9F31", "v$ c #514F52", "w$ c #525052", "x$ c #38822F", "y$ c #3E3C3E", "z$ c #3B393B", "A$ c #318328", "B$ c #28CD16", "C$ c #27D115", "D$ c #328229", "E$ c #3F3D3E", "F$ c #505051", "G$ c #34B127", "H$ c #29C818", "I$ c #374F34", "J$ c #318927", "K$ c #26E310", "L$ c #375833", "M$ c #34862A", "N$ c #27E212", "O$ c #359A2A", "P$ c #3A9931", "Q$ c #28DF14", "R$ c #30C121", "S$ c #4C514C", "T$ c #3F8138", "U$ c #43763D", "V$ c #3B9232", "W$ c #27E113", "X$ c #43703F", "Y$ c #4C4A4D", "Z$ c #27E412", "`$ c #36802C", " % c #3D3B3C", ".% c #3C3A3B", "+% c #385733", "@% c #28D414", "#% c #28D315", "$% c #3A5836", "%% c #434142", "&% c #535353", "*% c #36EB22", "=% c #43863C", "-% c #4D4D4D", ";% c #5A6C57", ">% c #44C635", ",% c #46A73B", "'% c #52604F", ")% c #3DB330", "!% c #2DE418", "~% c #31D51F", "{% c #39B72B", "]% c #39AE2D", "^% c #4A4E49", "/% c #405C3D", "(% c #2DB71E", "_% c #414B41", ":% c #3D6039", "<% c #2EAE20", "[% c #435242", "}% c #484648", "|% c #4A494A", "1% c #33CD23", "2% c #437E3B", "3% c #4E4C4D", "4% c #504F50", "5% c #585D56", "6% c #47B73A", "7% c #4AB93E", "8% c #565B55", "9% c #545353", "0% c #757575", ". + @ + # # $ % & & * # = - % ; > , ' ) ! ~ { ] ^ / ( _ : < [ ", "} | 1 2 3 4 5 6 7 8 9 0 a 1 b c d 1 a a b e f g h i j k l m n o ", "p q r s t u u u v w x x x y z z A A A B C C D E F E E G H I J K ", "L M N O O O O O O P Q Q Q Q Q Q Q Q Q Q Q R R R R R S R R T U V ", "W X Y O O O O O O O O O O O O O O O O Z ` ` ...O O O O P +.@.#.", "$.%.&.O O O O O O O O O O O O O O O P *.` ` =.-.O O O O O ;.>.,.", "'.).!.O O O O O O O O O O O O O O O ~.{.].^./.(._.O O O O :.<.[.", "}.|.1.P O O O O O O O O O O O O O O 2.3.4.5.6.7._.O O O P 8.<.9.", "p X 0.P O O O O O O O O O O O O O O a.b.c.d.e.f._.O O O O g.h.[.", "i.j.k.P O O O O O O O O O O O O O O l.m.n.o.p.q.r.O O O O s.t.u.", "v.w.x.P O O O O O O O O O O O O O O y.z.A.B.C.D.7.P O O O E.@.F.", "G.H.I.P O O O O O O O O O O O O O O J.K.L.M.N.O.P._.O O O Q.R.S.", "T.U.V.P O O O O O O O O O O O O O O W.X.Y.Z.`. +` ` O O O .+++@+", "T.#+$+P O O O O O O O O O O O O O _.%+&+*+=+-+;+>+` _.O O ,+'+)+", "!+~+$+P O O O O O O O O O O O O *.{+]+^+/+(+_+:+<+[+}+P |+1+2+3+", "4+5+$+P O O O O O O O O O O O O 6+7+^+(+=+(+(+(+8+9+0+_.O a+b+c+", "d+e+f+P O O O O O O O O O O O O g+h+(+i+/+(+(+(+j+k+-.` P l+m+n+", "o+p+f+P O O O O O O O O O O O Q q+8+(+r+/+(+(+(+s+t+u+` O v+w+x+", "d+y+$+P O O O O O O O O O O O z+A+B+(+C+D+(+(+(+E+F+G+H+O I+J+K+", "d+L+M+P O O O O O O O O O N+O+P+Q+R+S+T+=+(+(+(+U+V+W+X+Y+I+Z+`+", " @.@k.P O O O O O O O O O +@@@#@$@%@&@*@(+(+(+=@-@;@>@,@'@)@!@~@", "{@]@^@P O O O O O O O O O /@(@$@$@_@:@<@(+(+(+[@}@|@1@(@2@3@4@5@", "6@7@f+P O O O O O O O O 8@9@(@$@$@$@0@a@T+b@c@d@e@f@$@$@g@h@i@j@", "k@l@f+P O O O O O O O O m@n@o@p@(@q@r@s@t@u@v@w@x@y@z@A@B@C@D@E@", "F@G@H@I@J@K@L@M@N@N@N@N@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #.#+#@###$#", "%#&#*#=#-#;#>#,#'#)#!#~#{#]#^#/#(#_#:#<#[#}#|#1#2#3#4#5#6#7#8#9#", "0#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#w#x#y#z#A#B#C#D#E#", "F#G#H#I#J#K#L#M#N#O#P#b#Q#R#S#T#U#V#W#X#Y#Z#`# $.$+$@$#$$$%$&$*$", "=$-$;$>$,$'$)$!$~$L#{$]$^$/$($_$:$<$[$}$|$1$2$3$4$5$6$7$8$9$0$a$", "b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$s$t$u$v$w$2$x$y$z$A$B$C$D$E$F$", " G$H$I$J$K$L$M$N$O$P$Q$R$S$T$I#U$V$W$X$Y$k$Z$`$ %.%+%@%#%$%%%&%", " *%=%-%;%>%,%'%)%!%~%{%]%^%/%(%_%:%<%[%}%|%1%2%3%4%5%6%7%8%9%0%"}; xawtv-3.106/contrib/xawtv48x48.xpm000066400000000000000000000504261343350355000167630ustar00rootroot00000000000000/* XPM */ static char * xawtv48x48[] = { "48 48 994 2", " c None", ". c #B9B9BB", "+ c #B8B7B8", "@ c #B7B6B7", "# c #AAAAAA", "$ c #ACABAC", "% c #ACACAC", "& c #ACABAD", "* c #A0A0A2", "= c #A7A7A9", "- c #A2A1A4", "; c #959496", "> c #9D9C9E", ", c #969597", "' c #989798", ") c #A4A3A4", "! c #AAA9AA", "~ c #A0A0A0", "{ c #999999", "] c #A5A5A5", "^ c #A5A4A6", "/ c #A3A2A4", "( c #9B9A9C", "_ c #A7A7A7", ": c #ABABAB", "< c #A7A7A8", "[ c #A1A1A2", "} c #AEAEB0", "| c #B0B0B2", "1 c #B1B0B2", "2 c #B0B0B0", "3 c #AFAFAF", "4 c #ADADAD", "5 c #ADADAF", "6 c #ACABAE", "7 c #A8A8AA", "8 c #A4A4A6", "9 c #B7B7B9", "0 c #B7B7B8", "a c #B9B9B9", "b c #B8B8B9", "c c #98989A", "d c #7C7C7E", "e c #807E81", "f c #858286", "g c #888589", "h c #89868A", "i c #8B888C", "j c #8A878B", "k c #898689", "l c #8C898D", "m c #8C898C", "n c #8B888B", "o c #8D8A8E", "p c #8E8B8F", "q c #8C8A8D", "r c #8E8B8E", "s c #8D8A8D", "t c #8B898C", "u c #868386", "v c #848182", "w c #827F80", "x c #7E7B7E", "y c #7B787B", "z c #777478", "A c #737274", "B c #717173", "C c #707072", "D c #6F6F72", "E c #787879", "F c #BABABA", "G c #88888A", "H c #7F7F81", "I c #878288", "J c #938D94", "K c #948E95", "L c #959097", "M c #969098", "N c #948F97", "O c #948F95", "P c #969196", "Q c #969096", "R c #959095", "S c #948E94", "T c #918C91", "U c #908A90", "V c #8F8A91", "W c #908A92", "X c #908B92", "Y c #918B93", "Z c #908B90", "` c #8D888D", " . c #8E888D", ".. c #908A91", "+. c #8F8991", "@. c #8F8A8F", "#. c #8B868B", "$. c #878287", "%. c #898487", "&. c #898486", "*. c #888486", "=. c #868186", "-. c #858085", ";. c #7D7C80", ">. c #79797C", ",. c #767579", "'. c #747378", "). c #737278", "!. c #717076", "~. c #767679", "{. c #7E7E7E", "]. c #858587", "^. c #817E81", "/. c #8A888C", "(. c #5C5A69", "_. c #434249", ":. c #44424E", "<. c #44414E", "[. c #43414E", "}. c #43414F", "|. c #434150", "1. c #43404F", "2. c #423F4D", "3. c #42404B", "4. c #413F4A", "5. c #41404A", "6. c #3F3E48", "7. c #403E49", "8. c #3F3D4A", "9. c #3F3D4B", "0. c #3E3C4A", "a. c #3D3B49", "b. c #3D3B4A", "c. c #3C3948", "d. c #3C3A48", "e. c #3C3A49", "f. c #3A3846", "g. c #393745", "h. c #373644", "i. c #373640", "j. c #4F4F61", "k. c #76747B", "l. c #7A767F", "m. c #68676B", "n. c #949496", "o. c #827F83", "p. c #8D8D8D", "q. c #2D2C35", "r. c #010101", "s. c #010100", "t. c #000100", "u. c #010200", "v. c #010203", "w. c #434450", "x. c #777775", "y. c #7B777D", "z. c #727175", "A. c #99999B", "B. c #838184", "C. c #8E8D90", "D. c #2C2B35", "E. c #000000", "F. c #000002", "G. c #000003", "H. c #000004", "I. c #464753", "J. c #7D7C7B", "K. c #7D797F", "L. c #706F73", "M. c #909092", "N. c #858386", "O. c #8E8C94", "P. c #2C2B36", "Q. c #000101", "R. c #020203", "S. c #020204", "T. c #010103", "U. c #4A4954", "V. c #807D82", "W. c #7F7C80", "X. c #68686B", "Y. c #868688", "Z. c #868487", "`. c #918F97", " + c #282730", ".+ c #000001", "++ c #212122", "@+ c #1B1B1C", "#+ c #4C4A52", "$+ c #847F86", "%+ c #817F81", "&+ c #68686A", "*+ c #979799", "=+ c #888588", "-+ c #929098", ";+ c #26242E", ">+ c #2B2B2B", ",+ c #262626", "'+ c #030305", ")+ c #4C4A51", "!+ c #868188", "~+ c #838183", "{+ c #89878A", "]+ c #94929A", "^+ c #26252F", "/+ c #040406", "(+ c #010102", "_+ c #4E4C53", ":+ c #878389", "<+ c #848284", "[+ c #686869", "}+ c #919294", "|+ c #888689", "1+ c #939199", "2+ c #242425", "3+ c #0E0E0F", "4+ c #1C1C1E", "5+ c #424243", "6+ c #131314", "7+ c #4D4C53", "8+ c #88838A", "9+ c #838081", "0+ c #666666", "a+ c #878588", "b+ c #25242D", "c+ c #303031", "d+ c #BDBDBC", "e+ c #505050", "f+ c #0C0C0E", "g+ c #B8B8B8", "h+ c #4D4D4D", "i+ c #4D4B52", "j+ c #878289", "k+ c #838182", "l+ c #676767", "m+ c #878789", "n+ c #8F8D95", "o+ c #545455", "p+ c #2C2B2C", "q+ c #787773", "r+ c #2A2721", "s+ c #858585", "t+ c #282828", "u+ c #939393", "v+ c #868288", "w+ c #858283", "x+ c #686868", "y+ c #868387", "z+ c #8D8B93", "A+ c #22212A", "B+ c #414142", "C+ c #615439", "D+ c #C69913", "E+ c #CBA40D", "F+ c #AD9329", "G+ c #574F35", "H+ c #7F7F7E", "I+ c #4B4950", "J+ c #848283", "K+ c #666668", "L+ c #88898B", "M+ c #838084", "N+ c #898890", "O+ c #281D09", "P+ c #CB9611", "Q+ c #EBBB0B", "R+ c #F0D124", "S+ c #F6D822", "T+ c #EBC70E", "U+ c #7E630E", "V+ c #48464D", "W+ c #858087", "X+ c #827F81", "Y+ c #676769", "Z+ c #838083", "`+ c #87868E", " @ c #322305", ".@ c #D19C0A", "+@ c #EDC410", "@@ c #F1D21D", "#@ c #DBB60D", "$@ c #CF9909", "%@ c #75560D", "&@ c #141415", "*@ c #09090B", "=@ c #47464D", "-@ c #837F85", ";@ c #817E80", ">@ c #7F7D80", ",@ c #86848C", "'@ c #21212A", ")@ c #151515", "!@ c #A48A54", "~@ c #C2960B", "{@ c #C48E09", "]@ c #C18A12", "^@ c #C3AD7B", "/@ c #8C8A88", "(@ c #4B4B4C", "_@ c #45434A", ":@ c #7E7A81", "<@ c #7B797A", "[@ c #69696B", "}@ c #79787E", "|@ c #807E87", "1@ c #201F28", "2@ c #2C2C2D", "3@ c #C9C7C6", "4@ c #AF9C76", "5@ c #AF925F", "6@ c #BFB5A4", "7@ c #E6E6E5", "8@ c #F3F3F1", "9@ c #232324", "0@ c #020202", "a@ c #414147", "b@ c #76747A", "c@ c #777475", "d@ c #6A6869", "e@ c #76757A", "f@ c #7C7A83", "g@ c #1F1E27", "h@ c #070607", "i@ c #A6A6A6", "j@ c #F0F0EF", "k@ c #C4C3C2", "l@ c #CCCBCA", "m@ c #FEFEFC", "n@ c #919190", "o@ c #3D3D44", "p@ c #706E74", "q@ c #757273", "r@ c #76757D", "s@ c #1D1C26", "t@ c #2D2D2E", "u@ c #F9F9F7", "v@ c #F9F9F8", "w@ c #FDFDFB", "x@ c #DFDFDE", "y@ c #040405", "z@ c #3D3C43", "A@ c #6F6D73", "B@ c #737072", "C@ c #696768", "D@ c #74727B", "E@ c #1D1C25", "F@ c #5E5E5E", "G@ c #FBFBFA", "H@ c #F8F8F7", "I@ c #FCFCFA", "J@ c #F1F1F0", "K@ c #DBDBDA", "L@ c #262526", "M@ c #010001", "N@ c #3A3B42", "O@ c #6E6E73", "P@ c #737074", "Q@ c #69686B", "R@ c #706F75", "S@ c #716F78", "T@ c #060607", "U@ c #8F8F8F", "V@ c #F2F2F1", "W@ c #F6F6F5", "X@ c #F8F8F6", "Y@ c #E8E8E7", "Z@ c #D2D2D2", "`@ c #111112", " # c #0F0F10", ".# c #020001", "+# c #36383E", "@# c #6D6E73", "## c #706E72", "$# c #89898A", "%# c #706F74", "&# c #6F6E76", "*# c #0F0F11", "=# c #2E2E2F", "-# c #F5F5F4", ";# c #E2E2E2", "># c #3B3B3C", ",# c #1B1A1B", "'# c #080809", ")# c #33343B", "!# c #69696E", "~# c #6D6B6F", "{# c #6E6D72", "]# c #6E6D75", "^# c #9B9B9A", "/# c #FBFBF9", "(# c #1A1A1A", "_# c #141315", ":# c #313339", "<# c #65666A", "[# c #6B696D", "}# c #67676B", "|# c #6E6E70", "1# c #6D6B73", "2# c #1C1B24", "3# c #09090A", "4# c #EEEEEC", "5# c #FDFDFC", "6# c #BBBBBA", "7# c #2F3238", "8# c #64666B", "9# c #69686C", "0# c #6F6F71", "a# c #121213", "b# c #4B4B4B", "c# c #F5F5F3", "d# c #D6D6D5", "e# c #101011", "f# c #303338", "g# c #626469", "h# c #67666A", "i# c #8C8C8E", "j# c #6B6A71", "k# c #202020", "l# c #6D6D6E", "m# c #F3F3F2", "n# c #DFDFDD", "o# c #2F3237", "p# c #5F6266", "q# c #656468", "r# c #696870", "s# c #030204", "t# c #141413", "u# c #818181", "v# c #FAFAF9", "w# c #D5D5D4", "x# c #0A0A0C", "y# c #101010", "z# c #0A090B", "A# c #646266", "B# c #68686C", "C# c #020200", "D# c #9A7309", "E# c #CC9D0B", "F# c #5A523E", "G# c #EEEEED", "H# c #F8ECC4", "I# c #C4B069", "J# c #1E1C15", "K# c #5D6064", "L# c #636165", "M# c #68676E", "N# c #1E1D26", "O# c #0E0A01", "P# c #372704", "Q# c #634606", "R# c #E8AE0C", "S# c #F5BD0C", "T# c #BB910A", "U# c #454340", "V# c #E5E5E4", "W# c #EECA66", "X# c #D4A90B", "Y# c #050505", "Z# c #090807", "`# c #B3920B", " $ c #2C2402", ".$ c #5B5E62", "+$ c #626064", "@$ c #6F6E72", "#$ c #68666F", "$$ c #201E28", "%$ c #A17409", "&$ c #EBB20C", "*$ c #F4BC0C", "=$ c #F3BD0C", "-$ c #634E07", ";$ c #29292A", ">$ c #D6D6D4", ",$ c #ECECEB", "'$ c #D8B456", ")$ c #DAA109", "!$ c #573C06", "~$ c #342405", "{$ c #845F07", "]$ c #EDB60B", "^$ c #493804", "/$ c #292B31", "($ c #5C5C61", "_$ c #5F5E62", ":$ c #6D6C72", "<$ c #68676F", "[$ c #B5840C", "}$ c #F4BB0C", "|$ c #D7AA0B", "1$ c #110D05", "2$ c #1C1C1D", "3$ c #CBA753", "4$ c #E6AC0A", "5$ c #D39808", "6$ c #D19708", "7$ c #EAB10B", "8$ c #BD900A", "9$ c #0A0802", "0$ c #29282F", "a$ c #5C5A60", "b$ c #5F5D61", "c$ c #666669", "d$ c #6C6B70", "e$ c #66646D", "f$ c #936A07", "g$ c #F3BA0D", "h$ c #F3BE0C", "i$ c #7F6508", "j$ c #121214", "k$ c #D9D9D7", "l$ c #9B7622", "m$ c #EDB40B", "n$ c #EFB60B", "o$ c #EEB60B", "p$ c #B78B0A", "q$ c #484032", "r$ c #5A585E", "s$ c #68676C", "t$ c #64636B", "u$ c #9C6F07", "v$ c #F3B90C", "w$ c #E5B60B", "x$ c #D3C8AB", "y$ c #D7D7D6", "z$ c #2B2A2C", "A$ c #8B6307", "B$ c #F2B90C", "C$ c #856D32", "D$ c #58565C", "E$ c #636169", "F$ c #0D0901", "G$ c #D09709", "H$ c #EFB90B", "I$ c #AD8524", "J$ c #BCBBBA", "K$ c #EDEDEC", "L$ c #EDEDEB", "M$ c #D1D0CF", "N$ c #7C7C7C", "O$ c #0D0D0F", "P$ c #040304", "Q$ c #946808", "R$ c #F0B60B", "S$ c #E4AC0C", "T$ c #856009", "U$ c #2F2E32", "V$ c #595760", "W$ c #605C60", "X$ c #646467", "Y$ c #656567", "Z$ c #615F67", "`$ c #211702", " % c #C18808", ".% c #DCA20A", "+% c #E6AB0C", "@% c #EDB30C", "#% c #F5BC0C", "$% c #EEB50B", "%% c #AC7707", "&% c #140E05", "*% c #080604", "=% c #9C6B06", "-% c #EBB20B", ";% c #F3BA0C", ">% c #E6AC0C", ",% c #A77908", "'% c #221803", ")% c #262732", "!% c #58565F", "~% c #5E5A5E", "{% c #646468", "]% c #878C88", "^% c #3BBD2E", "/% c #35C627", "(% c #144D13", "_% c #031701", ":% c #18A508", "<% c #18A608", "[% c #041B01", "}% c #0F0A01", "|% c #382602", "1% c #6C4904", "2% c #9B6906", "3% c #B88007", "4% c #D49A0A", "5% c #E1A70B", "6% c #CB9108", "7% c #825505", "8% c #100B03", "9% c #148708", "0% c #19AA09", "a% c #1BAB09", "b% c #47C20A", "c% c #6FCB0B", "d% c #61E10C", "e% c #ADA609", "f% c #704D05", "g% c #060400", "h% c #1A4A1D", "i% c #32C324", "j% c #43A939", "k% c #939395", "l% c #489940", "m% c #23F40C", "n% c #1ED30B", "o% c #081313", "p% c #070715", "q% c #060612", "r% c #179B0B", "s% c #189611", "t% c #060611", "u% c #070712", "v% c #070713", "w% c #080712", "x% c #1F1613", "y% c #523710", "z% c #7C5107", "A% c #714905", "B% c #322211", "C% c #1DC20D", "D% c #26ED0C", "E% c #4FA209", "F% c #319B0E", "G% c #080812", "H% c #060712", "I% c #080814", "J% c #090917", "K% c #179310", "L% c #43973B", "M% c #A1A1A3", "N% c #5C5F5E", "O% c #30CC20", "P% c #37A431", "Q% c #504F5B", "R% c #3E7641", "S% c #23F20C", "T% c #28E414", "U% c #4A5A50", "V% c #4B4B54", "W% c #4A4A53", "X% c #494952", "Y% c #474850", "Z% c #444B4C", "`% c #43484C", " & c #44434D", ".& c #3E3E47", "+& c #2C3138", "@& c #2D2E36", "#& c #2B3239", "$& c #2A2A33", "%& c #2C2C34", "&& c #2C2B34", "*& c #2C2A34", "=& c #2B2F37", "-& c #303F3F", ";& c #32383A", ">& c #30343C", ",& c #30353C", "'& c #33313B", ")& c #487945", "!& c #488743", "~& c #28E713", "{& c #24F10D", "]& c #468E40", "^& c #488544", "/& c #4A6349", "(& c #24F00E", "_& c #27DA15", ":& c #4A4C52", "<& c #4C4B55", "[& c #4F4E57", "}& c #4E5253", "|& c #27E213", "1& c #546552", "2& c #636365", "3& c #9E9EA0", "4& c #5B5B5D", "5& c #50714F", "6& c #25EF0F", "7& c #25EF0E", "8& c #4C7848", "9& c #2BDD18", "0& c #468D3D", "a& c #595957", "b& c #595857", "c& c #585856", "d& c #4A8342", "e& c #2FD31D", "f& c #26EA11", "g& c #3AAF2C", "h& c #38A72B", "i& c #1DCF0F", "j& c #04431B", "k& c #1BD016", "l& c #1CC20A", "m& c #021707", "n& c #000906", "o& c #0D5D05", "p& c #1DD10F", "q& c #076525", "r& c #00130D", "s& c #07591C", "t& c #1DD310", "u& c #25A316", "v& c #595354", "w& c #5B5555", "x& c #2AE015", "y& c #575E52", "z& c #595554", "A& c #595555", "B& c #31CA1F", "C& c #23F30C", "D& c #4D7445", "E& c #585454", "F& c #497A43", "G& c #57565B", "H& c #616163", "I& c #5C5A5D", "J& c #3EA433", "K& c #26EC10", "L& c #33C424", "M& c #5A575B", "N& c #59565A", "O& c #59565B", "P& c #4A8144", "Q& c #29E314", "R& c #29E215", "S& c #25EE0F", "T& c #23F10C", "U& c #044F24", "V& c #17B313", "W& c #0A7725", "X& c #002D1E", "Y& c #18B20E", "Z& c #108F18", "`& c #118F14", " * c #1E7714", ".* c #555156", "+* c #575558", "@* c #29E016", "#* c #535D54", "$* c #545356", "%* c #555357", "&* c #42913B", "** c #3BA730", "=* c #39AE2D", "-* c #448A3B", ";* c #575657", ">* c #606062", ",* c #4F4F51", "'* c #4D4B4E", ")* c #494F49", "!* c #28D814", "~* c #25EB0F", "{* c #445E42", "]* c #4C4A4D", "^* c #4B494C", "/* c #4E4D4F", "(* c #2CD719", "_* c #3BA030", ":* c #515452", "<* c #565756", "[* c #3F9B36", "}* c #062509", "|* c #0E751C", "1* c #14A81E", "2* c #032716", "3* c #20E40E", "4* c #19B10A", "5* c #1BBE0A", "6* c #132A11", "7* c #504E51", "8* c #545355", "9* c #29E015", "0* c #4B5449", "a* c #4D4B4C", "b* c #465345", "c* c #24EB0E", "d* c #2AD816", "e* c #484947", "f* c #464745", "g* c #28DF14", "h* c #25E90F", "i* c #454D42", "j* c #49484A", "k* c #5F5F61", "l* c #48484A", "m* c #413F42", "n* c #3F423F", "o* c #28D116", "p* c #25E810", "q* c #3D523B", "r* c #3F3D40", "s* c #403E41", "t* c #3C543A", "u* c #23F20D", "v* c #28DC14", "w* c #4E4E4E", "x* c #525053", "y* c #565457", "z* c #595759", "A* c #2CD919", "B* c #24F20D", "C* c #50654F", "D* c #535E53", "E* c #25EC0F", "F* c #2AD518", "G* c #456E41", "H* c #2CD419", "I* c #26E910", "J* c #4B6149", "K* c #24EF0E", "L* c #2CCD1B", "M* c #4B4A4C", "N* c #535154", "O* c #24F00D", "P* c #454F43", "Q* c #434143", "R* c #3E3C3F", "S* c #3D3B3E", "T* c #2BB61C", "U* c #395C34", "V* c #376331", "W* c #2DB11E", "X* c #403E3F", "Y* c #464546", "Z* c #5C5C5E", "`* c #9F9FA1", " = c #474749", ".= c #403F41", "+= c #329228", "@= c #24ED0E", "#= c #2CB91C", "$= c #3D3C3E", "%= c #396135", "&= c #2EC31E", "*= c #4F4D50", "== c #555356", "-= c #32C123", ";= c #4A5E48", ">= c #33C023", ",= c #38AD2B", "'= c #43853C", ")= c #37A82B", "!= c #38932F", "~= c #4A484B", "{= c #535153", "]= c #444D42", "^= c #3F3D3F", "/= c #3C3A3D", "(= c #34722E", "_= c #309724", ":= c #2F9F22", "<= c #356E2E", "[= c #3E3C3D", "}= c #454445", "|= c #5A5A5C", "1= c #A9A9AB", "2= c #434345", "3= c #3A5538", "4= c #24EC0E", "5= c #23EF0D", "6= c #34672E", "7= c #26DC12", "8= c #34762D", "9= c #3D3B3D", "0= c #3A4F37", "a= c #23F10D", "b= c #28DD14", "c= c #494B49", "d= c #525055", "e= c #545256", "f= c #2ADA17", "g= c #4E624E", "h= c #555258", "i= c #438C3B", "j= c #25ED0F", "k= c #30CA1F", "l= c #525A52", "m= c #26EB10", "n= c #50674E", "o= c #545255", "p= c #514F52", "q= c #515052", "r= c #424B40", "s= c #3F3D3E", "t= c #3B393B", "u= c #3A383A", "v= c #3A4038", "w= c #25E310", "x= c #27D314", "y= c #26D912", "z= c #25E111", "A= c #3B3F39", "B= c #3B393A", "C= c #434343", "D= c #555556", "E= c #4B4D4D", "F= c #29BF18", "G= c #2E9C22", "H= c #353334", "I= c #316E2A", "J= c #26DF11", "K= c #374435", "L= c #3A3839", "M= c #28CC15", "N= c #31A923", "O= c #455143", "P= c #4C544D", "Q= c #38A22E", "R= c #4C614C", "S= c #504E52", "T= c #4C594C", "U= c #3B9C30", "V= c #2FC61F", "W= c #2DCD1B", "X= c #4E4C4F", "Y= c #24EF0D", "Z= c #3D463A", "`= c #383637", " - c #373536", ".- c #363435", "+- c #2CA71D", "@- c #2EA421", "#- c #454444", "$- c #515151", "%- c #5FBC56", "&- c #27DD13", "*- c #3D463D", "=- c #403E40", "-- c #424041", ";- c #2EB51F", ">- c #2FAC21", ",- c #434242", "'- c #3D6A37", ")- c #24EE0E", "!- c #26E710", "~- c #435841", "{- c #474547", "]- c #474548", "^- c #2EBE1E", "/- c #41693D", "(- c #49474A", "_- c #36952C", ":- c #36932D", "<- c #484649", "[- c #434142", "}- c #454344", "|- c #3D6D36", "1- c #3B6835", "2- c #464445", "3- c #474546", "4- c #4A4949", "5- c #6C6C6C", "6- c #3EED2B", "7- c #4F8A49", "8- c #484749", "9- c #5A595A", "0- c #6B696A", "a- c #667A63", "b- c #48D938", "c- c #47D836", "d- c #5D735A", "e- c #5A5959", "f- c #517A4C", "g- c #3CCC2C", "h- c #2CE817", "i- c #31DF1E", "j- c #459A3C", "k- c #439F38", "l- c #38CB28", "m- c #4E5C4B", "n- c #4B494A", "o- c #444345", "p- c #387532", "q- c #2CB71D", "r- c #404340", "s- c #3B5C38", "t- c #29BE19", "u- c #3E553C", "v- c #474648", "w- c #484648", "x- c #3ABC2C", "y- c #39CA29", "z- c #50564E", "A- c #525051", "B- c #555354", "C- c #626061", "D- c #666764", "E- c #4CD23D", "F- c #51D642", "G- c #6C6E6B", "H- c #525151", "I- c #696969", " . + @ @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : : : : < [ } | 1 2 3 4 5 5 6 7 8 9 0 0 a b ", "c d e f g h i j k l m l m n j l o o o p q r s l i t p p p p r m g u v v w x y z A B C D D D E F ", "G H I J K L M N O P Q R S T U V W X X Y V Z ` ...+.W W X W ..@.#.$.%.&.*.$.=.-.;.>.,.'.).!.~.{.", "].^./.(._.:.<.[.}.|.|.|.|.1.2.3.3.3.3.4.5.6.6.6.7.7.7.4.4.6.8.9.0.a.b.c.c.c.d.e.f.g.h.i.j.k.l.m.", "n.o.p.q.r.r.r.r.s.s.s.s.s.t.s.s.s.s.s.s.t.s.s.s.s.s.s.t.s.s.s.s.s.s.t.s.t.t.s.u.t.t.t.v.w.x.y.z.", "A.B.C.D.E.E.E.E.E.E.E.E.E.E.F.G.G.G.G.G.G.G.G.G.G.G.G.G.G.G.G.H.H.H.H.H.H.H.H.H.H.H.H.G.I.J.K.L.", "M.N.O.P.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.Q.R.S.S.T.r.E.E.E.E.E.E.E.E.F.U.V.W.X.", "Y.Z.`. +E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E..+S.S.S.S.++@+T.E.E.E.E.E.E.E..+#+$+%+&+", "*+=+-+;+E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.T.S.S.S.S.>+,+'+.+E.E.E.E.E.E..+)+!+~+&+", "A.{+]+^+E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.S.S.S.S.S./+S.S.(+E.E.E.E.E.E.r._+:+<+[+", "}+|+1+;+E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.'+2+3+S.4+5+6+S.T.E.E.E.E.E.E.r.7+8+9+0+", "M.a+`.b+t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.c+d+e+f+d+g+h+S.R.E.E.E.E.E.E.(+i+j+k+l+", "m+=+n+b+t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E..+o+p+q+r+s+t+u+S.R.E.E.E.E.E.E..+)+v+w+x+", "m+y+z+A+t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.B+C+D+E+F+G+H+S.S.E.E.E.E.E.E..+I+!+J+K+", "L+M+N+A+t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.O+P+Q+R+S+T+U+S.S.E.E.E.E.E.E..+V+W+X+Y+", "L+Z+`+A+t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E. @.@+@@@#@$@%@&@*@.+E.E.E.E.E.r.=@-@;@Y+", "m+>@,@'@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.)@!@~@{@]@^@/@&@(@T.E.E.E.E.E..+_@:@<@[@", "Y.}@|@1@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.r.2@3@4@5@6@7@8@9@'+S.0@E.E.E.E.Q.a@b@c@d@", "Y.e@f@g@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.h@i@j@k@l@j@m@m@n@S.S.R.E.E.E.E.Q.o@p@q@d@", "Y.'.r@s@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.(+t@u@m@v@w@m@m@m@x@y@S.S.(+E.E.E.Q.z@A@B@C@", "m+'.D@E@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.r.S.F@j@G@j@H@I@J@7@K@L@S.S.S..+E.E.M@N@O@P@Q@", "m+R@S@E@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.S.T@U@V@w@W@w@w@X@Y@Z@~ `@ #S.T.E.E..#+#@###m.", "$#%#&#E@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.*#=#-#w@w@w@w@w@w@w@I@;#>#,#'#S..+E..#)#!#~#m.", "m+{#]#E@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.(+6+^#w@w@w@/#w@w@w@w@w@w@U@(#_#S.(+E.M@:#<#[#}#", "Y.|#1#2#t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.3#@+4#5#w@H@u@w@w@w@w@w@w@6#S.&@S.T.E.(+7#8#9#m.", "m+0#]#E@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E..+a#b#w@w@w@c#H@w@w@w@w@w@w@d#S.e#S.S.E.M@f#g#h#m.", "i#0#j#2#t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.T.k#l#w@w@w@m#u@w@w@w@w@w@w@n#S.3+S.S.E.M@o#p#q#m.", "G 0#r#E@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.s#t#u#w@w@w@8@v#w@w@w@w@w@w@w#x#y#z#S.E.M@o#p#A#B#", "G 0#r#E@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.C#D#E#F#G#w@w@m#G@w@w@w@w@w@H#I#'#S.&@J#E.M@o#K#L#h#", "m+0#M#N#t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.O#P#Q#R#S#T#U#V#w@W@/#w@w@w@w@w@W#X#Y#S.Z#`# $M@7#.$+$h#", "m+@$#$$$t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.%$R#&$*$S#=$-$;$>$w@w@w@w@w@w@,$'$)$!$~${$]$^$(+/$($_$h#", "Y.:$<$ +t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.[$}$S#S#S#S#|$1$2$,$w@w@w@w@w@7@3$4$5$6$7$S#8$9$0$a$b$c$", "].d$e$1@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.f$g$S#S#S#S#h$i$j$n#w@w@w@w@w@k$l$m$n$o$}$S#*$p$q$r$b$q#", "Y.s$t$E@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.E.u$v$S#S#S#S#S#w$x$w@w@w@w@w@y$z$A$n$S#S#S#S#S#B$C$D$b$q#", "Y.Y+E$2#t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.F$G$}$S#S#S#S#S#H$I$J$K$L$M$N$O$P$Q$R$S#S#S#}$S$T$U$V$W$X$", "G Y$Z$E@t.F.E.E.E.E.E.E.E.E.E.E.E.E.E.`$ %.%+%@%B$#%#%$%%%&%O$O$'+S.S.*%=%-%#%;%>%,%'%(+)%!%~%{%", "]%^%/%(%t.F.E._%:%<%[%E.E.E.E.E.E.E.E.E.}%|%1%2%3%4%5%6%7%8%(+9%0%0%0%a%b%c%d%e%f%g%E.(+h%i%j%q#", "k%l%m%n%o%p%q%r%m%s%q%q%q%q%t%q%t%q%u%q%v%u%q%w%x%y%z%A%B%u%u%C%m%m%m%m%D%E%m%F%G%H%I%J%K%m%L%K+", "M%N%O%m%P%Q%R%S%T%U%V%W%X%Y%Z%`% &.&+&@&#&$&%&&&*&=&-&;&>&,&'&)&!&~&{&]&^&/&(&_&:&<&[&}&|&(&1&2&", "3&4&5&6&7&8&9&m%0&a&b&c&d&e&(&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&(&y&z&A&B&C&D&z&E&F&m%i%G&H&", "* 4&I&J&m%K&m%L&M&N&O&P&(&m%Q&R&m%S&T&U&V&m%W&X&Y&m%Z&Q.`&m% *.*+*@*(&#*$*%*&*m%**%*%*=*m%-*;*>*", "* ,*'*)*!*m%~*{*]*^*/*(*m%_*:*<*[*m%T&}*|*m%1*2*3*m%4*0@5*T&6*7*8*9*(&0*a*^*b*c*d*e*f*g*h*i*j*k*", "* l*m*n*o*m%p*q*r*s*t*u*v*w*x*y*z*A*B*C*D*E*F*G*m%H*I*J*K*L*M*N*8*9*O*P*Q*R*S*T*C&U*V*C&W*X*Y*Z*", "`* =.=+=m%@=m%#=$=r*%=m%&='**===y*-=u*;=N*>={&,=E*'=m%)=m%!=~=N*{=9*O*]=^=R*/=(=m%_=:=m%<=[=}=|=", "1=2=3=4=5=6=7=C&8=9=0=a=b=c=]*d=e=f=u*g=h=i=m%j=k=l=m=j=u*n=o=p=q=9*O*r=s=t=u=v=w=x=y=z=A=B=C=D=", " E=F=m%G=H=I=C&J=K=L=M=m%N=O=P=Q=m%B*R=S=T=j=m%U=7*V=m%W=7*X=X=/*g*Y=Z=L=`= -.-+-m%m%@-L=[=#-$-", " %-m%&-*-=---;-m%>-,-'-E*m%)-j=C&!-u*~-{-]-^-m%/-(-_-m%:-]-<-<-j*g*O*r=[-[-}-}-|-m%m%1-2-3-4-5-", " m%6-7-8-9-0-a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-.=s-t-u-v-v-w-(@x-y-z-A-B-;*C-D-E-F-G-9-H-I- "}; xawtv-3.106/contrib/xawtvsort.pl000066400000000000000000000321701343350355000167560ustar00rootroot00000000000000#!/usr/bin/perl # Autor : D. Landolt # Date : 26.8.2002 # Version : 0.9 # Name : xawtvsort.pl # Description : Utility to sort the xawtv frequency table # Changers : # 27.8.2002 # Marks works now. Some correction to handel correct. # 30.8.2002 # Version 0.10 made # Tool is now with menu and supports keystrokens for sortings. # 30.8.2002 # Version 0.11 made # You cann now chose tv canels with return key it needs v4lctl program # 31.8.2002 # Version 0.12 made # Scrolling when moving down is now working use Tk; use Tk::Table; use Tk::Frame; use Tk::FileSelect; use Tk::Dialog; $maxentry=0; $minentry=3; # Marks the first entry witch is a station $version = "0.12"; $xawtvfile=$ENV{HOME}."/.xawtv"; @stations = (); $top= new MainWindow; # Menu erstellen $Menuleiste = $top->Frame()->pack(-side => top, -fill => x); $DateiMenu = $Menuleiste->Menubutton(-text => "File", -underline => 0)->pack(-side => left, -padx => 2); $HelpMenu = $Menuleiste->Menubutton(-text => "Help", -underline => 0)->pack(-side => right, -padx => 2); $DateiMenu->command(-label => "Open", -underline => 1, -command => sub{ &OpenFile(); }); $DateiMenu->command(-label => "Save", -underline => 1, -command => sub{ SaveXawtv($xawtvfile) }); $DateiMenu->command(-label => "Save as", -underline => 6, -command => sub { $top->Dialog(-text => "Sorry Save as not jet implemented", -title => "Sorry")->Show; } ); $DateiMenu->separator(); $DateiMenu->command(-label => "Exit", -underline => 1, -command => [ $top => 'destroy' ] ); $HelpMenu->command(-label => "keyboard", -underline => 0, -command => sub { $top->Dialog(-text => "up\t\t= go up\n". "down\t\t= go down\n". "shift-up\t\t= move up\n". "shift-down\t= move down\n". "ctrl-up\t\t= move at top\n". "ctrl-down\t= move to bottom\n". "home\t\t= go to first entry\n". "end\t\t= go to last entry\n". "ctrl-l\t\t= (un)locks entry\n". "ctrl-m\t\t= (un)marks entry\n". "ctrl-u\t\t= unmarks all\n". "ctrl-s\t\t= sorts stations\n". "ctrl-n\t\t= sorts numbers\n". "return\t\t= sets the sender\n", -buttons => [qw/Close/] , -title => "Keyboard Help" )->Show; } ) ; $HelpMenu->separator(); $HelpMenu->command(-label => "about", -underline => 0, -command => sub { $hd = $top->Dialog(-text => "Autor D. Landolt\n". "Version $version\n\n". "perl/tk programm for sorting .xawtv file", -buttons => [qw/Close/] , -title => "Help about" ); $hd->Show; } ) ; # Add a Table for Sorting $hframe = $top->Frame->pack; $table = $top->Table(-rows => 15, -columns => 8, -fixedrows => 1, -takefocus => 0, -scrollbars => e ); $Statusleiste = $top->Frame()->pack(-side => bottom, -fill => x)->pack; $StatusLabel = $Statusleiste->Label(-text => "File : ")->pack(side => left, padx => 2); $StatusText = $Statusleiste->Label(-text => $xawtvfile )->pack(side => left, padx => 2); $StatusVersion = $Statusleiste->Label(-text => $version )->pack(side => right, padx => 2); ReadXawtv($xawtvfile); $table->pack; MainLoop; sub OpenFile { my $FileDialog = $top->FileSelect(-directory => "."); my $file = $FileDialog->Show; if ($file ne "" ) { foreach $x ( 1..$table->totalRows ) { foreach $y ( 1..$table->totalColumns) { $table->put($x,$y,""); } } $StatusText->configure(-text => "Reading : ".$xawtvfile ); $top->update; ReadXawtv($file); $xawtvfile = $file; } } sub ReadXawtv { ($filename) = @_; my $nr=1; @stations = (); $maxentry = 0; $table->put(0,1,$table->Button(-text => "Station", -underline => 0, -command => sub{ tablesortstation() } )); $table->bind(Tk::Entry, '', sub { tablesortstation() } ); $table->put(0,2,$table->Button(-text => "Nr", -underline => 0, -command => sub{ tablesortnr() } )); $table->bind(Tk::Entry, '', sub { tablesortnr() } ); $table->put(0,3,$table->Button(-text => "UnMark", -underline => 0, -command => sub{ unmarkall() } )); $table->bind(Tk::Entry, '', sub { unmarkall() } ); $table->put(0,4,"Lock\nmove"); $table->put(0,5,"1\nUp"); $table->put(0,6,"1\nDown"); $table->put(0,7,"all\nUp"); $table->put(0,8,"all\nDown"); open(XA,"$filename") || die ".xawtv nicht gefunden"; while () { chomp; if(/^\[(.*)\]/) { $StationName = $1; push(@stations,$StationName); # In den Zwischenspeicher mit dem Originalname $table->put($nr,1, $table->Entry()); $widget = $table->get($nr,1); $widget->insert(0,$StationName); $table->put($nr,2,$nr); my $nr_nr=$nr; my @command = (); if($StationName ne "global" && $StationName ne "defaults") { $table->put($nr,3, $table->Checkbutton()); $table->get($nr,3)->deselect(); $table->put($nr,4, $table->Checkbutton()); $table->get($nr,4)->deselect(); $table->put($nr,5, $table->Button(-text => "^", -command => sub{ movecolumn($nr_nr,"up")} )); $table->put($nr,6, $table->Button(-text => "v", -command => sub{ movecolumn($nr_nr,"down")} )); $table->put($nr,7, $table->Button(-text => "^^", -command => sub{ moveallcolumn($nr_nr,"up")} )); $table->put($nr,8, $table->Button(-text => "vv", -command => sub{ moveallcolumn($nr_nr,"down")} )); $table->get($nr,1)->bind(Tk::Entry , '', sub{ settablefocus('down') } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ settablefocus('up') } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ settablefocus('left') } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ settablefocus('right') } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ invokebutton(5); } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ invokebutton(6); } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ invokebutton(7); } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ invokebutton(8); } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ invokebutton(3); } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ invokebutton(4); } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ choseTv(); } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ settablefocus('home'); } ); $table->get($nr,1)->bind(Tk::Entry , '', sub{ settablefocus('end');} ); } else { $widget->configure(-state => "disabled"); $table->put($nr,3, $table->Checkbutton()); $table->get($nr,3)->deselect(); $table->get($nr,3)->configure(-state => "disabled"); $table->put($nr,4, $table->Checkbutton()); $table->get($nr,4)->deselect(); $table->get($nr,4)->configure(-state => "disabled"); $table->get($nr,1)->configure(-bg => "gray"); } $nr++; } else { $Stations{$nr -1} .= $_."\n"; } } close XA; $StatusText->configure(-text => $xawtvfile); $table->get($minentry,1)->focus(); $maxentry=$nr -1; } sub choseTv { my ($x, $y) = $table->Posn($top->focusCurrent); my $sn = $table->get($x,2)->cget(-text); system("v4lctl setstation \"".$stations[$sn - 1].'"'); print "v4lctl setstation ".$stations[$sn - 1]."\n"; } sub invokebutton { my ($bnr) = @_; ($x, $y) = $table->Posn($top->focusCurrent); # print "Invokebutton\n"; my $entry = $table->get($x,2)->cget(-text); $table->get($x,$bnr)->invoke; if ( $bnr > 4) { settablefocus("up",$entry) if($bnr == 5); settablefocus("down",$entry) if($bnr == 6); settablefocus("up",$entry) if($bnr == 7); settablefocus("down",$entry) if($bnr == 8); } } sub settablefocus { my ($direct,$entry) = @_; my ($x, $y) = $table->Posn($top->focusCurrent); if ( $entry ne '' ) { my $loop = $x; my $pm = 0; $pm = 1 if($direct eq 'down'); $pm = -1 if($direct eq 'up'); while( $entry ne $table->get($loop, 2)->cget(-text) ) { # print "x = $x Loop = $loop pm = $pm\n"; $loop += $pm; $loop = $minentry if($loop > $maxentry); $loop = $maxentry if($loop > $maxentry); break if($loop eq $x); # Notbremse } # print "Found : x = $x Loop = $loop pm = $pm\n"; # $loop -= $pm; $pm = ( $loop > $x) ? 1 : -1; # Neue Richtung festlegen für Scrolling my $loop2 = $x; while ($loop2 != $loop) { # print "Visible : x = $x Loop = $loop pm = $pm \$_ = $_\n"; $loop2 += $pm; $table->yview(scroll,$pm) if (! $table->get($loop2, $y)->viewable); } $table->get($loop, $y)->focus; } else { if ($direct eq 'down') { if ( $x >= $maxentry) { settablefocus("home"); } else { $table->yview(scroll,1) if (! $table->get($x+1, $y)->viewable); $table->get($x +1 , $y)->focus; } } if ($direct eq 'up') { if ( $x == $minentry) { settablefocus("end"); } else { $table->yview(scroll,-1) if (! $table->get($x-1, $y)->viewable); $table->get($x -1 , $y)->focus; } } if ($direct eq 'end') { $table->yview(moveto, 1); $table->get($maxentry, $y)->focus; } if ($direct eq 'home') { $table->yview(moveto, 0); $table->get($minentry, $y)->focus; } } } sub SaveXawtv { my ($filename) = @_; open(XA,">$filename"); # XA= STDOUT; my $oldtext = $StatusText->cget(-text); $StatusText->configure(-text => "Saveing : ".$filename ); $top->update; @stations = (); # Initialize Aerea print XA "[".$table->get(1,1)->get."]\n".$Stations{1}; push(@stations,$table->get(1,1)->get); print XA "[".$table->get(2,1)->get."]\n".$Stations{2}; push(@stations,$table->get(2,1)->get); for $i ($minentry..$maxentry) { print XA "[".$table->get($i,1)->get."]\n".$Stations{$table->get($i,2)->cget(-text)}; push(@stations,$table->get($i,1)->get); } close XA; $StatusText->configure(-text => $oldtext ); } sub moveallcolumn() { my ($nr,$direct) = @_; my $laufnr=$nr; my ( $marks, @allMarks ) = getmarked(); if ($marks < 1) { while ( $laufnr > 2 && $laufnr <= $maxentry ) { $laufnr = movecolumn($laufnr,$direct); } } else { if($direct eq "down" ) { @allMarks = sort { $b cmp $a } @allMarks; } my $mnr=0; foreach(@allMarks) { # print "Move $_ nach $direct\n"; $laufnr = $_; $mnr++; while ( ( $laufnr > 2 + $mnr && $direct eq "up" ) || ( $laufnr <= ( $maxentry - $mnr) && $direct eq "down") ) { $laufnr = movesinglecolumn($laufnr,$direct); } } } } sub movecolumn { my ($nr,$direct) = @_; my $dest; my ( $marks, @allMarks ) = getmarked(); # print "$#allMarks -> Anzahl im Array\n"; if ($marks < 1) { return movesinglecolumn($nr,$direct); } else { # print "Marked sind $marks Nr\n"; if($direct eq "down" ) { @allMarks = sort { $b cmp $a } @allMarks; } foreach(@allMarks) { # print "Move $_ nach $direct\n"; $dest = movesinglecolumn($_,$direct); } return $dest; } } sub movesinglecolumn { my ($nr,$direct) = @_; my $plmi=0; # verschiebeindex -1 = auf +1 = ab; my $spreiz=1; # Spreizung bei gesperrten Einträgen; my $dest=$nr; # Startindex if($direct eq "up") { $plmi=-1; } else { $plmi=+1; } # Sperrung überspringen while(($dest = $nr + $plmi * $spreiz) <= $maxentry && $table->get($dest = $nr + $plmi * $spreiz,4)->{'Value'} == 1) { $spreiz++; } if ( $dest > 2 && $dest <= $maxentry ) { exchangevalue($nr,$dest); } return $dest; } sub getmarked { # Zurückbringen der Markierten Einträge my $i ; @nrArray = (); my $hasmarks=0; # print "getmarkde\n"; for $i ( $minentry..$maxentry ) { if($table->get($i, 3)->{'Value'} == 1) { push(@nrArray,$i); $hasmarks++; } } return($hasmarks, @nrArray ); } sub exchangevalue { my ($source,$dest) = @_; my $indexex = $index = $table->get($source,2)->cget(-text); my $stringex = $string = $table->get($source,1)->get; my $markex = $mark = $table->get($source,3)->{'Value'}; # Zielnummer und String holen my $indexex = $table->get($dest ,2)->cget(-text); my $stringex = $table->get($dest, 1)->get; my $markex = $table->get($dest, 3)->{'Value'}; # print "$nr / $dest / $indexex / $stringex \n"; # String Verschieben $table->get($source, 1)->delete(0,length($string)); $table->get($source, 1)->insert(0,$stringex); $table->get($dest,1)->delete(0,length($stringex)); $table->get($dest,1)->insert(0,$string); # Nummer verschieben $table->get($source, 2)->configure(-text => $indexex); $table->get($dest,2)->configure(-text => $index); # Marker Verschieben if($markex == 1) { $table->get($source, 3)->select; } else { $table->get($source, 3)->deselect; } if($mark == 1) { $table->get($dest,3)->select; } else { $table->get($dest,3)->deselect; } } sub tablesortstation { my $i; # print "Tablesort\n"; my $oldtext = $StatusText->cget(-text); $StatusText->configure(-text => "sorting Stations"); $top->update; foreach $i ($minentry .. $maxentry-1) { # print " Sort $i\n"; if ( $table->get($i,1)->get gt $table->get($i+1 ,1)->get ) { exchangevalue($i,$i + 1); tablesortstation(); } } $StatusText->configure(-text => $oldtext); } sub tablesortnr { # print "Tablesort Nr\n"; my $oldtext = $StatusText->cget(-text); $StatusText->configure(-text => "sorting Nr"); $top->update; foreach $i ($minentry .. $maxentry-1) { # print " Sort $i\n"; if ( $table->get($i,2)->cget(-text) > $table->get($i+1 ,2)->cget(-text) ) { exchangevalue($i,$i + 1); tablesortnr(); } } $StatusText->configure(-text => $oldtext); } sub unmarkall { foreach $i ( 3..$maxentry) { $table->get($i,3)->deselect; } } xawtv-3.106/debian/000077500000000000000000000000001343350355000141175ustar00rootroot00000000000000xawtv-3.106/debian/alevtd.install000066400000000000000000000001011343350355000167560ustar00rootroot00000000000000debian/tmp/usr/bin/alevtd debian/tmp/usr/share/man/man1/alevtd.1 xawtv-3.106/debian/changelog000066400000000000000000000672631343350355000160070ustar00rootroot00000000000000xawtv (3.104-1) sid; urgency=medium * Update Vcs fields * Update watch file * New upstream release (3.104). * Drop upstream released patches * Migrate to dh using compat 11 * Bump to Standards-Version 4.1.3 * Drop dh-autoreconf build dep * Release to sid -- Maximiliano Curia Tue, 06 Mar 2018 10:20:14 +0100 xawtv (3.103-4) unstable; urgency=medium * Import upstream patches. (Closes: #805830) Thanks to Philippe Waroquiers for reporting * Recommend ssh-client instead of simply ssh. (Closes: #605607) * Bump Standards-Version to 3.9.6, no changes needed. * Drop obsolete README.xfree4 doc file. (Closes: #559234) * Fix synopsis typo (Closes: #654279) Thanks to Vincent Blut for reporting * Add patch to update v4l2 api. (Closes: #658726) Thanks to Philipp Matthias Hahn for the patch and pointers -- Maximiliano Curia Fri, 19 Feb 2016 17:25:07 +0100 xawtv (3.103-3) unstable; urgency=low * Replace lesstif with motif. * Remove libexplain build-dep. * Remove libxp-dev as build-dep, thanks to Graham Inggs. (Closes: #733137) * Import 3.103-2.1 nmu, thanks to Luk Claes. * Bump Standards-Version to 3.9.5, no changes needed. * Add vcs fields. -- Maximiliano Curia Tue, 14 Jan 2014 18:59:17 +0100 xawtv (3.103-2.1) unstable; urgency=low * Non-maintainer upload. * Transition from lesstif2 to motif (Closes: #714682). -- Luk Claes Sat, 14 Sep 2013 18:50:16 +0200 xawtv (3.103-2) unstable; urgency=low * New patch: mayhem_showriff.diff. * New patch: mayhem_rootv.diff. -- Maximiliano Curia Thu, 27 Jun 2013 17:59:08 +0200 xawtv (3.103-1) unstable; urgency=low * New upstream release. * Bump debhelper build-dep and compat to 9. * Bump Standards-Version to 3.9.4. * Change libpng12-dev build-dep to libpng-dev (Closes: #662555). * Update Maintainer field (Closes: #678879). * Add explicit build-dep of libxp-dev (Closes: #707944). * [remove_dl_motif] Remove applied patch. * [fix_libjpeg_segfault] Remove applied patch. * [mtt_only_in_linux] Remove applied patch. * [fbtv_manpage_typo] Remove applied patch. * Update debian rules. * Add build-dep to dh-autoreconf. * Update install files for multi-arch. * Add hardening-includes as build-dep. * [honour_ldflags.diff] new patch. * Disable HARDENING_PIE. * [manpages_minor_changes.diff] new patch. * [minor_spelling_change.diff] new patch. * Add ${misc:Pre-Depends} to packages with multi-arch installed files. * New debug package xawtv-dbg. -- Maximiliano Curia Thu, 16 May 2013 11:26:36 +0200 xawtv (3.102-3) unstable; urgency=low * Missing dollar sign in xawtv postinst script. (Closes: #657935) -- Maximiliano Curia Mon, 30 Jan 2012 08:02:51 -0300 xawtv (3.102-2) unstable; urgency=low * Fix kfreebsd-i386 build (Closes: #654736) * [mtt_only_in_linux] mtt is linux dependent (uses linux/fb.h). * [fbtv_manpage_typo] upstream patch, manpage typo fix. -- Maximiliano Curia Sat, 28 Jan 2012 17:11:05 -0300 xawtv (3.102-1) unstable; urgency=low * Add myself as uploader. * Add changelog missing entries. * Fix postinst script so it continues even if scantv can't create the configuration file, which is the behaviour it had before the usage of the -e shell option. (Closes: #656570, #657182) * Change default for scantv, so it doesn't search for channels in installation time. * Fix dependencies architecture information. kfreebsd-i386 build should work if #656947 gets fixed. -- Maximiliano Curia Fri, 20 Jan 2012 09:02:02 -0300 xawtv (3.102-0.1) unstable; urgency=low * Non-maintainer upload. * New upstream release (Closes: #650849) (Closes: #627435) (Closes: #299460) (Closes: #654302) (Closes: #634984) (Closes: #639500) (Closes: #638440) (Closes: #638439) (Closes: #513818) (Closes: #644761) (Closes: #584090) (Closes: #454186) (Closes: #444449) (Closes: #390312) (Closes: #366144) (Closes: #200248) (Closes: #636909) (Closes: #643652) (Closes: #227590) * Migration to debian format 3.0 (quilt) * Remove all patches, upstream have already applied them. * [remove_dl_motif] upstream patch imported from git, removes dl option to motif libraries. * [fix_libjpeg_segfault] upstream patch imported from git, fixes libjpeg8 segfaults * Fix typographic errors in package descrition (Closes: #639248), thanks to Simon Kainz for the fix. * Update xawtv menu (Closes: #564229) * Update dependencies (Closes: #633387) (Closes: #578974) * Updated Standards-Version to 3.9.2 (No changes). -- Maximiliano Curia Sun, 15 Jan 2012 16:53:21 -0300 xawtv (3.95.dfsg.1-8.3) unstable; urgency=low * Non-maintainer upload. * Touch configure between patch and build rules so make doesn't decide to run autoconf (closes: #617710). -- Julien Cristau Sat, 31 Dec 2011 19:10:46 +0100 xawtv (3.95.dfsg.1-8.2) unstable; urgency=low * Non-maintainer upload. * Fix FTBFS with binutils-fold (Closes: #556689); patch from Felix Geyer. * Replace x-dev with x11proto-core-dev in the Build-Depends field; report and patch come from Julien Cristau (Closes:# 515517). * Also rebuild with newest libquicktime in sid. -- Alessio Treglia Thu, 26 May 2011 12:05:53 +0200 xawtv (3.95.dfsg.1-8.1) unstable; urgency=low * Non-maintainer upload. * Fix pending l10n issues. Debconf translations: - Swedish. Closes: #491427 - Danish. Closes: #500410 - Dutch. Closes: #500515 -- Christian Perrier Tue, 30 Sep 2008 07:23:03 +0200 xawtv (3.95.dfsg.1-8) unstable; urgency=low * Updated Standards-Version to 3.7.3. * Switched from glib 1.2 to glib 2.0. * Aplied A. Costa's patch for scantv manual page typo (Closes: #448578) * Debconf templates and debian/control reviewed by the debian-l10n- english team as part of the Smith review project. (Closes: #447430) * [Debconf translation updates] * Basque. (Closes: #447995) * Vietnamese. (Closes: #448026) * Galician. (Closes: #448069) * Finnish. (Closes: #448075) * Spanish. (Closes: #448744) * Japanese. (Closes: #448750) * German. (Closes: #449030) * Czech. (Closes: #449262) * Italian. (Closes: #449443) * French. (Closes: #449579) * Russian. (Closes: #450503) * Portuguese. (Closes: #450669) -- Krzysztof Burghardt Fri, 14 Dec 2007 16:32:12 +0100 xawtv (3.95.dfsg.1-7) unstable; urgency=low * Applied Tim Connors's patch for xawtv wrapper (Closes: #444447) * Applied patch for uvcvideo driver submited by Tim Connors (Closes: #444449) * Add Russian debconf translation updated by Yuri Kozlov (Closes: #446283) -- Krzysztof Burghardt Wed, 17 Oct 2007 08:25:38 +0200 xawtv (3.95.dfsg.1-6) unstable; urgency=low * Applied Martin Denn's patch for 11_plugins_memory_leaks.dpatch fixes free()ing invalid pointer (Closes: #438135, #440706) * Moved xawtv binary to xawtv.bin and add wrapper to detect and work around graphic cards / drivers without DGA support (idea by Jorge S. de Lis) * Updated Portuguese translation for debconf messages (Closes: #439694) * File xawtv.desktop modified to adhere to freedesktop standards (incorporated changes from Ubuntu patch by Luca Falavigna) -- Krzysztof Burghardt Wed, 26 Sep 2007 00:12:47 +0200 xawtv (3.95.dfsg.1-5) unstable; urgency=low * Add desktop file provided by Luca Falavigna (Closes: #414261) * Applied quicktime patch from Alexis Ballier and re-enabled quicktime feature (Closes: #394001) * Applied patch for scantv provided by Adrian Phillips that allow card's input to be specified (overriding default "Television" input) (Closes: #231557) * Add streamer-wrapper.pl provided by John Goerzen (Closes: #55016) (can be found in streamer package in /usr/share/doc/streamer/contrib) * Add German debconf translation updated by Helge Kreutzmann (Closes: #436953) * Add French debconf translation updated by Michel Grentzinger (Closes: #437843) * Add Spanish debconf translation updated by Carlos Valdivia Yagüe (Closes: #436513) * Updated debian/copyright to cover copyright statements found in sources * Updated debian/*.menu to use "Applications" instead of "Apps". -- Krzysztof Burghardt Wed, 15 Aug 2007 20:36:57 +0200 xawtv (3.95.dfsg.1-4) unstable; urgency=low * Applied Kristof Koehler's patch for problems with recording oss audio using streamer (Closes: #374626) * Applied Romain FRANCOISE's patch for unmute sound on xavtv exit (Closes: #199570) * Applied Steven Barker's patches for radio application. This fixes multiple issues listed in bug report (Closes: #202133) * Applied Bjoern Erik Nilsen's patch that fixes some memory leaks in the v4l plugins (Closes: #369803) * Applied Petr Vandrovec's patch that fixes 4 problems with fbtv observed with radeonfb. Fixes to support 15bpp depth in v4l-conf, reload palette when switching terminals, clear only visible area of videoram instead of clearing 256MB and problem with FBIOGETCMAP. (Closes: #383194) * Changed ${Source-Version} substvar to ${binary:Version} * Adjust debconf-templates. * New maintainer (Closes: #379251) -- Krzysztof Burghardt Sun, 29 Jul 2007 15:00:06 +0200 xawtv (3.95.dfsg.1-3) unstable; urgency=low * QA upload. * Add armel support. Closes: #408796. * Fix manpages permissions. Closes: #391951. -- Aurelien Jarno Wed, 30 May 2007 16:04:23 +0200 xawtv (3.95.dfsg.1-2) unstable; urgency=low * QA upload. * Debconf translations: - Galician. Closes: #407953 -- Christian Perrier Sat, 3 Mar 2007 14:02:57 +0100 xawtv (3.95.dfsg.1-1) unstable; urgency=medium * QA upload. * Removed GPL-incompatible code from Open Motif (Closes: #402786). -- Nelson A. de Oliveira Wed, 13 Dec 2006 02:41:20 -0200 xawtv (3.95-6) unstable; urgency=low * QA upload * Disable quicktime-support and removing xawtv-qt-plugin - adding a conflict on xawtv-plugin-qt to remove old broken binaries. Fixing ftbfs. Please enable again when quicktime in debian is fixed (Closes: #392576) * adds libdv-dev to build-dep instead of libquicktime -- Sune Vuorela Sat, 14 Oct 2006 01:18:00 +0200 xawtv (3.95-5) unstable; urgency=medium * QA upload * Add a Replaces: xawtv (<=3.95-3) for v4l-conf, as /usr/bin/v4l-conf was moved from xawtv to v4l-conf (closes: #384782) -- Bas Zoetekouw Fri, 29 Sep 2006 19:44:38 +0000 xawtv (3.95-4) unstable; urgency=low * QA upload. * Fix 07_page_size.dpatch. Closes: #384312. -- Aurelien Jarno Sun, 27 Aug 2006 12:55:35 +0200 xawtv (3.95-3) unstable; urgency=low * QA upload. * 07_page_size.dpatch: fix build against newer kernel-headers which do not define PAGE_MASK anymore. Closes: #384312. -- Aurelien Jarno Wed, 23 Aug 2006 21:27:22 +0200 xawtv (3.95-2) unstable; urgency=low * QA upload. * debian/po/ru.po: Add translation by Yuri Kozlov. Closes: #383038. * Added support for GNU/kFreeBSD. Closes: #372701. -- Aurelien Jarno Mon, 21 Aug 2006 23:58:28 +0200 xawtv (3.95-1) unstable; urgency=low * QA upload. * Package is orphaned (#379251); set maintainer to Debian QA Group. * New upstream release. Closes: #331125. * Acknowledge NMUs. Closes: #325597. * Update dependencies to allow for cdebconf. Closes: #332154. * Update build dependencies. Closes: #333889. - Replace libjpeg-dev with libjpeg62-dev. - Replace xlibmesa-gl-dev with libgl1-mesa-dev. - Replace libxft2-dev with libxft-dev. - Replace libpng-dev with libpng12-dev. * man/fbtv.1, man/pia.1, man/record.1, man/rootv.1, man/subtitles.1, man/v4l-conf.8, man/xawtv-remote.1, man/xawtv.1, man/webcam.1: Fix typos. Thanks to A Costa. Closes: #302758, #302764, #302766, #302767, #302772, #302773, #305648, #311230. * man/v4l-conf.8, man/es/v4l-conf.8: Fix section header. * contrib/xawtv16x16.xpm, contrib/xawtv32x32.xpm: Use as menu icons. * Switch to debhelper 5. * Replace ad-hoc patch system with dpatch. * Makefile: Previous maintainer's private rules; remove. * debian/copyright: Update upstream information. * debian/rules: Add support for DEB_BUILD_OPTIONS=noopt. * debian/watch: Add. * debian/xawtv.postrm: Remove call to mkfontdir (fonts were moved to tv-fonts around version 3.78). * debian/po/sv.po: Add translation by Daniel Nylander. Closes: #332398. * debian/po/nl.po: Add translation by Kurt De Bree. Closes: #363036. * debian/po/pt.po: Add translation by Rui Branco. Closes: #372475. * debian/po/pt_BR.po: Add translation by Herbert Parentes Fortes Neto. Closes: #380408. * Conforms to Standards version 3.7.2. -- Matej Vela Sun, 13 Aug 2006 04:27:51 +0200 xawtv (3.94-1.2) unstable; urgency=high * Non-maintainer upload. * High-urgency upload for RC bugfix. * Fix FTBFS using Steve Langasek patch to make xawtv build against Xorg 7.0. + Fix header/library path handling issues during build, due to Xorg 7.0. Closes: #364259. -- Pierre Habouzit Wed, 24 May 2006 22:59:05 +0200 xawtv (3.94-1.1) unstable; urgency=low * Non-maintainer upload. * xlibs-dev transition patch. Closes: #346757 -- Victor Seva Tue, 10 Jan 2006 13:20:12 +0100 xawtv (3.94-1.0) unstable; urgency=low * NMU. * Fix FTBFS with gcc 4.0 with patches from Andreas Jochens. Closes: #300363, #298171 * Build depend on libaa1-dev. Closes: #325044 * Rebuilt with slang2 and libaa. Closes: #317579 * Add Czech translation of debconf messages, by Miroslav Kure. Closes: #314790 * Add Vietnamese translation of debconf messages, by Clytie Siddall. Closes: #324235 * Add build dependency on libfs-dev due to X reorg. * Update includes to work with current libquicktime-dev, which has moved them to lqt/ -- Joey Hess Mon, 29 Aug 2005 10:02:16 -0400 xawtv (3.94-1) unstable; urgency=low * new release (closes: #191044, #256860). -- Gerd Knorr Wed, 18 Aug 2004 18:03:26 +0200 xawtv (3.93-1) unstable; urgency=low * new release. -- Gerd Knorr Tue, 8 Jun 2004 14:40:50 +0200 xawtv (3.92-3) unstable; urgency=low * update German po-debconf translation (closes: #251746). -- Gerd Knorr Mon, 7 Jun 2004 14:36:16 +0200 xawtv (3.92-2) unstable; urgency=low * add Turkish po-debconf translation (closes: #249124). -- Gerd Knorr Wed, 26 May 2004 15:37:35 +0200 xawtv (3.92-1) unstable; urgency=low * bugfix release (closes: #243423). * split distribution tarball + debian package info. * update + rename japanese debconf file (closes: #234068). * trigger rebuild for new libdv4 (closes: #245225). * fixup build dependencies (closes: #234664). * add icon to xawtv menu file (closes: #244485). -- Gerd Knorr Thu, 22 Apr 2004 17:08:56 +0200 xawtv (3.91) unstable; urgency=low * bugfix release. * fix dependencies (closes: #217451). * added Japanese po-debconf template (closes: #227811). -- Gerd Knorr Thu, 29 Jan 2004 14:23:49 +0100 xawtv (3.90) unstable; urgency=low * bugfix release (closes: #204990). * added spanish template file (closes: #215652). * fix webcam description (closes: #216061). * fix build dependencies (closes: #216164). * rebuild with new libquicktime likely closes: #193712. -- Gerd Knorr Fri, 17 Oct 2003 12:55:22 +0200 xawtv (3.88.1) unstable; urgency=low * bugfix release (closes: #214120). * updated debconf (closes: #198780, #199982). -- Gerd Knorr Tue, 7 Oct 2003 17:26:57 +0200 xawtv (3.88) unstable; urgency=low * new release. -- Gerd Knorr Wed, 16 Apr 2003 12:19:46 +0200 xawtv (3.87) unstable; urgency=low * new release. * postinst fixes (closes: #179319,#188652). * rebuild with new, fixed libquicktime-dev (closes: #186332). -- Gerd Knorr Tue, 15 Apr 2003 12:39:21 +0200 xawtv (3.86) unstable; urgency=low * new release (closes: #175886, #171884, #178691, #171354) (closes: #178940, #179371, #175886). * added danish template (closes: #175424). * fixed radio description text (closes: #175115). * splitted quicktime plugin into separate sub-package. * rebuild seems to fix #183567 - not sure how this happened in the first place as shared libary dependencies are autogenerated by debhelper ... (closes: #183567). * rebuild should also fixup the vorbis mess (closes: #179379, #178851). * fixed dependencies (closes: #179372, #184956, #184959, #144403). -- Gerd Knorr Tue, 18 Mar 2003 10:12:33 +0100 xawtv (3.82) unstable; urgency=low * new release (closes: #173791). -- Gerd Knorr Sat, 28 Dec 2002 13:38:59 +0100 xawtv (3.81) unstable; urgency=low * new release (closes: #171346, #171812, #171470). -- Gerd Knorr Tue, 10 Dec 2002 16:23:26 +0100 xawtv (3.80) unstable; urgency=low * new release. * fixed build dependencies (closes: #169570). -- Gerd Knorr Wed, 27 Nov 2002 13:07:56 +0100 xawtv (3.79) unstable; urgency=low * new release (closes: #168896, #168694) -- Gerd Knorr Fri, 15 Nov 2002 11:02:59 +0100 xawtv (3.78) unstable; urgency=low * new release (closes: #132366,#135393,#138792,#144699,#159689). * fixed copyright file (closes: #143371). * fixed control file (closes: #153046). -- Gerd Knorr Wed, 30 Oct 2002 13:04:45 +0100 xawtv (3.72) unstable; urgency=low * new release (closes: #134444). -- Gerd Knorr Tue, 19 Feb 2002 15:18:45 +0100 xawtv (3.71) unstable; urgency=low * new release (closes: #133120). * fixed dependences (closes: #132619,#132987). -- Gerd Knorr Mon, 11 Feb 2002 13:21:05 +0100 xawtv (3.70) unstable; urgency=low * new release. -- Gerd Knorr Tue, 5 Feb 2002 11:03:48 +0100 xawtv (3.69) unstable; urgency=low * new release (closes: #112892) * various bugs are fixed in other releases but I forgot to mention them in the changelog (closes: #122672, #116477, #119935, #116476). -- Gerd Knorr Thu, 31 Jan 2002 12:05:43 +0100 xawtv (3.68) unstable; urgency=low * new release. -- Gerd Knorr Thu, 17 Jan 2002 19:08:55 +0100 xawtv (3.67) unstable; urgency=low * new release (closes: #124275). -- Gerd Knorr Fri, 14 Dec 2001 13:00:56 +0100 xawtv (3.66) unstable; urgency=low * new release. -- Gerd Knorr Wed, 12 Dec 2001 15:51:37 +0100 xawtv (3.65) unstable; urgency=low * new release (closes: #119935). -- Gerd Knorr Tue, 4 Dec 2001 13:13:01 +0100 xawtv (3.64) unstable; urgency=low * new release (closes: #113633,#112169). * fixed build dependences (closes: #115111). -- Gerd Knorr Wed, 10 Oct 2001 12:51:39 +0200 xawtv (3.63) unstable; urgency=low * new release. -- Gerd Knorr Mon, 8 Oct 2001 15:17:11 +0200 xawtv (3.62) unstable; urgency=low * new release (closes: #111105, #111267, #111296). -- Gerd Knorr Fri, 14 Sep 2001 19:39:38 +0200 xawtv (3.61) unstable; urgency=low * new release. -- Gerd Knorr Thu, 23 Aug 2001 21:32:42 +0200 xawtv (3.60) unstable; urgency=low * new release. -- Gerd Knorr Tue, 14 Aug 2001 16:39:51 +0200 xawtv (3.59) unstable; urgency=low * new release. -- Gerd Knorr Mon, 13 Aug 2001 20:12:52 +0200 xawtv (3.58) unstable; urgency=low * new release. -- Gerd Knorr Thu, 2 Aug 2001 14:22:14 +0200 xawtv (3.57) unstable; urgency=low * new release. -- Gerd Knorr Mon, 23 Jul 2001 13:44:03 +0200 xawtv (3.56) unstable; urgency=low * new release. -- Gerd Knorr Mon, 16 Jul 2001 16:17:18 +0200 xawtv (3.55) unstable; urgency=low * new release. * spell fix in control file (s/Replace/Replaces/, closes: #103418). -- Gerd Knorr Wed, 4 Jul 2001 09:38:14 +0200 xawtv (3.54) unstable; urgency=low * new release (closes: #102096). -- Gerd Knorr Mon, 2 Jul 2001 11:36:09 +0200 xawtv (3.53.1) unstable; urgency=low * fixed dependences for new scantv package (closes: #101971). -- Gerd Knorr Sat, 23 Jun 2001 10:42:57 +0200 xawtv (3.53) unstable; urgency=low * new release. * splitted scantv into a sepatate package (closes: #101353). * updated ttv description (closes: #101682) -- Gerd Knorr Wed, 20 Jun 2001 12:18:06 +0200 xawtv (3.52) unstable; urgency=low * new release. -- Gerd Knorr Mon, 18 Jun 2001 10:20:03 +0200 xawtv (3.51) unstable; urgency=low * new release. -- Gerd Knorr Mon, 11 Jun 2001 12:58:33 +0200 xawtv (3.50) unstable; urgency=low * new release (closes: #99858). -- Gerd Knorr Wed, 6 Jun 2001 11:28:14 +0200 xawtv (3.49) unstable; urgency=low * new release. -- Gerd Knorr Thu, 31 May 2001 11:45:34 +0200 xawtv (3.48) unstable; urgency=low * new release (closes: #97772). * updated template file (closes: #92402). -- Gerd Knorr Mon, 21 May 2001 14:19:33 +0200 xawtv (3.47) unstable; urgency=low * new release. * tweak postinst (closes: #97187). -- Gerd Knorr Wed, 16 May 2001 11:04:53 +0200 xawtv (3.46) unstable; urgency=low * new release. -- Gerd Knorr Mon, 7 May 2001 17:30:03 +0200 xawtv (3.45) unstable; urgency=low * new release. -- Gerd Knorr Sun, 6 May 2001 11:02:52 +0200 xawtv (3.44) unstable; urgency=low * new release (closes: #87136). * deleted some magic from xawtv config/postinst scripts to avoid dependency on pciutils. -- Gerd Knorr Sat, 5 May 2001 18:02:34 +0200 xawtv (3.43) unstable; urgency=low * new release. -- Gerd Knorr Mon, 9 Apr 2001 09:03:17 +0000 xawtv (3.42) unstable; urgency=low * new release. -- Gerd Knorr Fri, 6 Apr 2001 08:04:27 +0000 xawtv (3.41) unstable; urgency=low * new release. -- Gerd Knorr Fri, 23 Mar 2001 22:49:04 +0100 xawtv (3.40) unstable; urgency=high * new release (closes: #90003). * new scantv manpage (closes: #87120). Ok, that was fixed in 3.39 already, but I forgot to add it to the changelog... -- Gerd Knorr Sun, 18 Mar 2001 17:41:56 +0100 xawtv (3.39) unstable; urgency=low * new release. * added xbase-clients to build-depends (closes: #89522). -- Gerd Knorr Tue, 13 Mar 2001 21:30:12 +0100 xawtv (3.38) unstable; urgency=low * new release (closes: #88396). * fixed a number of lintian warnings. -- Gerd Knorr Sun, 11 Mar 2001 10:18:20 +0100 xawtv (3.37) unstable; urgency=low * new release. -- Gerd Knorr Wed, 28 Feb 2001 19:56:30 +0100 xawtv (3.36) unstable; urgency=low * new release (closes: #87429). -- Gerd Knorr Sun, 25 Feb 2001 16:52:43 +0100 xawtv (3.35) unstable; urgency=low * new release (closes: #85648, #86065). -- Gerd Knorr Thu, 15 Feb 2001 21:21:30 +0100 xawtv (3.34) unstable; urgency=low * new release. * rm'ed libXv.so libXxf86dga.so on my system (closes: #85555). -- Gerd Knorr Sun, 11 Feb 2001 10:05:25 +0100 xawtv (3.33) unstable; urgency=low * new release. * debconf changes (only dpkg-reconfigure will overwrite a existing config file, a normal upgrade should never ever do that). * german translations for the template file (Eduard Bloch , closes: #83772) * enabled quicktime4linux support. -- Gerd Knorr Sun, 28 Jan 2001 14:25:15 +0100 xawtv (3.30) unstable; urgency=low * new release. -- Gerd Knorr Sun, 14 Jan 2001 09:38:03 +0100 xawtv (3.29) unstable; urgency=low * new release (closes: #74458) * updated v4l-conf package for the new dpkg-statoverride -- Gerd Knorr Sat, 13 Jan 2001 22:02:05 +0100 xawtv (3.28) unstable; urgency=low * new release (closes: #80933) -- Gerd Knorr Sat, 6 Jan 2001 13:09:31 +0100 xawtv (3.27) unstable; urgency=low * new release. * xawtv postinst script fixes (closes: #80611, #80578) -- Gerd Knorr Sat, 30 Dec 2000 15:07:25 +0100 xawtv (3.26) unstable; urgency=low * new release * added debconf support -- Gerd Knorr Thu, 21 Dec 2000 22:58:42 +0100 xawtv (3.24) unstable; urgency=low * new release * updated (build) dependences to require xfree4 libraries + xutils (mkfontdir+bdftopcf have been moved) * build binary packages with Xvideo support [i386 only, powerpc has no xfree4 packages yet] -- Gerd Knorr Sat, 4 Nov 2000 15:56:55 +0100 xawtv (3.23) unstable; urgency=low * new release * fixed (build) dependences (closes: #69918, #74428) -- Gerd Knorr Sat, 21 Oct 2000 22:41:37 +0200 xawtv (3.22) unstable; urgency=low * new release * added liblircclient-dev to build-depends, compiled packages with lirc support -- Gerd Knorr Sun, 1 Oct 2000 17:40:52 +0200 xawtv (3.21) unstable; urgency=low * new release -- Gerd Knorr Wed, 6 Sep 2000 00:04:21 +0200 xawtv (3.20) unstable; urgency=low * new release * packaging bug fixed: v4l-conf was not installed suid-root because dh_fixperm killed my suid bit... -- Gerd Knorr Wed, 6 Sep 2000 00:04:11 +0200 xawtv (3.19) unstable; urgency=low * new release. Starting with this release /me maintains debian package, i.e. xawtv is a native debian package now. Going to close a number of bugs... * closes: #48118 - not xawtv's fault, it is a driver problem. * closes: #52538 - This can be changed with keypad-ntsc in ~/.xawtv, see man-page. Don't remember which version introduces this, seems I forgot this one in the Changes file... * closes: #54906 - It's not a bug, it's a feature. xawtv uses the maximun size supported by the driver which is 844x576 with bttv. If one needs a fixed 4:3 aspect ratio, this can be set in the config file (>= version 3.14) * closes: #55956 - same as 54906 ... * closes: #57161, #52351 (packaging is completely different) * closes: #61590 - was fixed in 3.11 * closes: #61698, #65802 - bug in the 2.2.x kernel bttv driver * closes: #64064 - this is newer than 3.14 :-) -- Gerd Knorr Sun, 20 Aug 2000 23:47:15 +0200 xawtv (3.18) unstable; urgency=low * new release. -- Gerd Knorr Wed, 16 Aug 2000 21:39:03 +0200 xawtv (3.17) unstable; urgency=low * new release. -- Gerd Knorr Thu, 22 Jun 2000 23:43:00 +0200 xawtv (3.16) unstable; urgency=low * new release. -- Gerd Knorr Mon, 5 Jun 2000 21:35:30 +0200 xawtv (3.15) unstable; urgency=low * new release. -- Gerd Knorr Thu, 1 Jun 2000 22:58:00 +0200 xawtv (3.14) unstable; urgency=low * new release. -- Gerd Knorr Mon, 8 May 2000 23:13:03 +0200 xawtv (3.13) unstable; urgency=low * deianized. -- Gerd Knorr Sun, 16 Apr 2000 15:57:04 +0200 xawtv-3.106/debian/compat000066400000000000000000000000031343350355000153160ustar00rootroot0000000000000011 xawtv-3.106/debian/contrib/000077500000000000000000000000001343350355000155575ustar00rootroot00000000000000xawtv-3.106/debian/contrib/streamer-wrapper.pl000066400000000000000000000041141343350355000214140ustar00rootroot00000000000000#!/usr/bin/perl -w use Getopt::Long; # $FAKE = 1; $FRAMESIZE = "320x240"; $HIGHRESVAL = "720x480"; $FPS = 30; $ENCODING = "mjpeg"; GetOptions("minutes=i" => \$MINUTES, "fps=i" => \$FPS, "outfile=s" => \$OUTFILE, "framesize=s" => \$FRAMESIZE, "channel=i" => \$CHANNEL, "mute" => \$MUTE, "highres" => \$HIGHRES, "encoding" => \$ENCODING); validateOpts(); runProgram(); sub validateOpts { synerror() unless $MINUTES; synerror() unless $FPS; synerror() unless $OUTFILE; synerror() unless $CHANNEL; if ($HIGHRES) { $FRAMESIZE = $HIGHRESVAL; } } sub synerror { print <= 11), libaa1-dev, libasound2-dev [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386], libdv-dev, libfs-dev, libgl1-mesa-dev, libglib2.0-dev, libjpeg-dev, liblircclient-dev, libmotif-dev, libncurses5-dev, libpng-dev, libquicktime-dev (>= 0.9.9), libv4l-dev [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386], libx11-dev, libxaw7-dev, libxext-dev, libxft-dev, libxinerama-dev, libxmu-dev, libxpm-dev, libxrandr-dev, libxt-dev, libxv-dev, libxxf86dga-dev, libxxf86vm-dev, libzvbi-dev (>= 0.2.1), po-debconf, x11-xserver-utils, x11proto-core-dev Maintainer: Maximiliano Curia Standards-Version: 4.1.3 Vcs-Browser: https://salsa.debian.org/debian/xawtv Vcs-Git: https://salsa.debian.org/debian/xawtv.git Package: xawtv Architecture: any Depends: pia, scantv, v4l-conf [linux-any], x11-utils, xawtv-plugins (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Suggests: tv-fonts, xawtv-plugin-qt (=${binary:Version}) Description: television viewer - X11 application XawTV is an X11 application which displays television channels. It supports video4linux devices and the Xvideo extension. Package: pia Architecture: any Depends: xawtv-plugins (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Description: movie player for xawtv This package provides a simple movie player used by xawtv and motv to play back movie files which are recorded from TV. Package: fbtv Architecture: linux-any Depends: v4l-conf, xawtv-plugins (=${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Suggests: xawtv Description: television viewer - Linux framebuffer application FbTV is a Linux framebuffer application which displays television channels. It supports video4linux devices and requires a framebuffer device (vesafb, matroxfb, atyfb, etc.). Package: ttv Architecture: any Depends: xawtv-plugins (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Suggests: xawtv Description: television viewer - console application TTV is a console application, based on aalib, which displays television channels. It supports video4linux devices. Package: scantv Architecture: any Depends: xawtv-plugins (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Replaces: xawtv (<< 3.53) Description: television channel-scanner This package provides a utility that can scan a channel set for TV stations and write the ones found in an xawtv configuration file (which is also read by some other utilities such as fbtv). It attempts to extract the station names from inter-frame (VBI) data as well. Package: streamer Architecture: any Depends: xawtv-plugins (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Suggests: xawtv Description: television capture tool (images/movies) This package provides a tool to capture single/multiple images or record movies from a video4linux device. Package: radio Section: sound Architecture: linux-any Depends: ${misc:Depends}, ${shlibs:Depends} Description: ncurses-based radio application This package provides a ncurses-based radio application. It supports the video4linux API. Package: v4l-conf Architecture: linux-any Depends: ${misc:Depends}, ${shlibs:Depends} Conflicts: suidmanager (<< 0.50) Replaces: xawtv (<=3.95-3) Description: tool to configure video4linux drivers This package provides a small tool to configure a video4linux device driver. It is required to make the video overlay work in fbtv and xawtv. Package: xawtv-tools Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} Description: television viewer - tools This package provides some tools that may be useful with xawtv: - propwatch: monitors properties of X11 windows. Helps to keep track of xawtv's _XAWTV_STATION property; - dump-mixers: dumps mixer settings to stdout; - record: console sound recorder. It has a simple input level meter which might be useful for troubleshooting sound problems; - showriff: display the structure of RIFF files (avi, wav). Package: xawtv-plugin-qt Architecture: any Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends} Description: television viewer - QuickTime plugin This package provides a plugin to record QuickTime movies with xawtv and motv. Package: xawtv-plugins Architecture: any Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends} Description: television viewer - plugins This package provides plugins for xawtv and motv: driver interfaces for hardware access (video4linux API, etc.), plugins for reading/writing movie files and some image processing filters. Package: webcam Section: net Architecture: any Depends: xawtv-plugins (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Recommends: ftp, ssh-client Description: image grabber and uploader This package provides an utility that captures images from a video4linux device such as bttv, annotates them and uploads them to a webserver in an endless loop using FTP or SSH. Package: alevtd Section: net Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} Description: HTTP daemon for teletext pages This package provides an HTTP daemon which serves teletext pages as HTML. xawtv-3.106/debian/copyright000066400000000000000000000034471343350355000160620ustar00rootroot00000000000000This package is maintained by Krzysztof Burghardt Previously it was maintained by Gerd Knorr It was downloaded from http://git.linuxtv.org/xawtv3.git Upstream Author: Gerd Knorr Includes code developed by: Mauro Carvalho Chehab Devin Heitmueller Jaroslav Kysela Marcus Metzler Jamie Zawinski Malte Starostik Andreas Stolcke Heiko Eissfeldt Copyright: Copyright (C) 2011 Mauro Carvalho Chehab Copyright (C) 1997-2005 Gerd Knorr Copyright (C) 2002 Malte Starostik Copyright (C) 1996,1997 Marcus Metzler Copyright (C) 1991-1998 Jamie Zawinski Copyright (C) 1991 Andreas Stolcke Copyright (C) 1990 Solbourne Computer Inc. Copyright (C) Heiko Eissfeldt Copyright (C) Devin Heitmueller Copyright (C) Jaroslav Kysela License: This package 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 package 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 package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA On Debian systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL'. xawtv-3.106/debian/fbtv.install000066400000000000000000000001441343350355000164470ustar00rootroot00000000000000debian/tmp/usr/bin/fbtv debian/tmp/usr/share/man/*/man1/fbtv.1 debian/tmp/usr/share/man/man1/fbtv.1 xawtv-3.106/debian/fbtv.menu000066400000000000000000000001461343350355000157470ustar00rootroot00000000000000?package(fbtv):needs="vc" section="Applications/TV and Radio" \ title="fbtv" command="/usr/bin/fbtv" xawtv-3.106/debian/not-installed000066400000000000000000000002241343350355000166150ustar00rootroot00000000000000# False positives usr/share/man # Not including motv etc/X11/app-defaults/MoTV etc/X11/*/app-defaults/MoTV usr/bin/motv # Nor showqt usr/bin/showqt xawtv-3.106/debian/pia.install000066400000000000000000000000731343350355000162600ustar00rootroot00000000000000debian/tmp/usr/bin/pia debian/tmp/usr/share/man/man1/pia.1 xawtv-3.106/debian/po/000077500000000000000000000000001343350355000145355ustar00rootroot00000000000000xawtv-3.106/debian/po/POTFILES.in000066400000000000000000000000521343350355000163070ustar00rootroot00000000000000[type: gettext/rfc822deb] xawtv.templates xawtv-3.106/debian/po/cs.po000066400000000000000000000115211343350355000155020ustar00rootroot00000000000000# # Translators, if you are not familiar with the PO format, gettext # documentation is worth reading, especially sections dedicated to # this format, e.g. by running: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # # Some information specific to po-debconf are available at # /usr/share/doc/po-debconf/README-trans # or http://www.debian.org/intl/l10n/po-debconf/README-trans # # Developers do not need to manually edit POT or PO files. # msgid "" msgstr "" "Project-Id-Version: xawtv\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-11-04 14:51+0100\n" "Last-Translator: Miroslav Kure \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "VytvoÅ™it speciální soubory pro video4linux (/dev/video*)?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Hledat TV stanice?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "Seznam nalezených televizních stanic můžete pÅ™idat do konfiguraÄního souboru." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "To vyžaduje funkÄní ovladaÄ bttv. Pokud bttv není nastaven správnÄ›, nejspíš " "se žádné televizní stanice nenaleznou." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Názvy kanálů se zjistí z teletextu, což funguje pouze u kanálů dle normy PAL." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "Televizní norma:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "VytvoÅ™it poÄáteÄní konfiguraci xawtv?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Můžete si nechat vytvoÅ™it systémový konfiguraÄní soubor xawtv, který bude " "obsahovat rozumné hodnoty pro vaÅ¡i zemi." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "Tento soubor není vyžadován, ovÅ¡em uživatelům zjednoduší nastavení." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "USA - vysílání" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "USA - kabel" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "USA - kabel-hrc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "Japonsko - vysílání" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "Japonsko - kabel" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "Evropa - západ" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "Evropa - východ" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "Itálie" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "Nový Zéland" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "Austrálie" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "Irsko" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "Francie" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "Čína - vysílání" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Tabulka frekvencí, která se má použít:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Tabulka frekvencí je seznam jmen a Äísel televizních kanálů a odpovídajících " "vysílacích frekvencí." #~ msgid "" #~ "It is not required to have a global configuration file, but it will be " #~ "more comfortable for your users if they find a working default " #~ "configuration." #~ msgstr "" #~ "Není nutné mít systémový konfiguraÄní soubor, avÅ¡ak je to pohodlnÄ›jší pro " #~ "vaÅ¡e uživatele, kteří tak nemusí nic nastavovat." xawtv-3.106/debian/po/da.po000066400000000000000000000136631343350355000154720ustar00rootroot00000000000000# Danish translation of xawtv templates, debconf # Last update Frank Damgaard , 2008. # This file is distributed under the same license as the xawtv package. # # # Translators, if you are not familiar with the PO format, gettext # documentation is worth reading, especially sections dedicated to # this format, e.g. by running: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # # Some information specific to po-debconf are available at # /usr/share/doc/po-debconf/README-trans # or http://www.debian.org/intl/l10n/po-debconf/README-trans # # Developers do not need to manually edit POT or PO files. # msgid "" msgstr "" "Project-Id-Version: xawtv\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2008-09-28 15:46+0200\n" "Last-Translator: Frank Damgaard \n" "Language-Team: Danish \n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Opret video4linux (/dev/video*) enhedsfiler?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Skan efter TV stationer?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "En liste over fundne TV stationer kan tilføjes konfigurationsfilen." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Dette kræver en fungerende bttv driver. Hvis bttv ikke er korrekt " "konfigureret, sÃ¥ vil TV stationerne ikke blive fundet." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Kanalnavne vil blive hentet fra tekst-tv. Dette vil kun fungere for PAL " "kanaler." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "TV standard:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Opret en standard konfigurationsfil til xawtv?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "En hovedkonfigurationsfil til xawtv kan oprettes med fornuftige " "standardværdier for det aktuelle land." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "Denne fil er ikke pÃ¥krævet, men vil forenkle opsætningen for brugerne." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "us-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "us-kabel" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "us-kabel-hrc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "japan-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "japan-kabel" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "europa-vest" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "europa-øst" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "italien" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "newzealand" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "australien" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "irland" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "frankrig" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "kina-bcast" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Frekvenstabel der skal bruges:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "En frekvenstabel er en liste af kanalnavne og tal med de tilhørende " "frekvenser. " #, fuzzy #~ msgid "" #~ "This can do a scan of all channels and put a list of the TV stations I've " #~ "found into the config file." #~ msgstr "" #~ "Jeg kan lave en skanning efter alle kanaler og putte dem i en liste af de " #~ "TV stationer jeg har fundet, ind i en konfigurations fil." #~ msgid "" #~ "I'll try to pick up the channel names from videotext. This will work with " #~ "PAL only." #~ msgstr "" #~ "Jeg vil prøve at finde kanal navne fra videotext. Dette vil kun virke med " #~ "PAL." #~ msgid "PAL, SECAM, NTSC" #~ msgstr "PAL, SECAM, NTSC" #, fuzzy #~ msgid "TV norm is used in your country:" #~ msgstr "Hvilken TV norm er brugt i dit land?" #~ msgid "" #~ "It is not required to have a global configuration file, but it will be " #~ "more comfortable for your users if they find a working default " #~ "configuration." #~ msgstr "" #~ "Det er ikke krævet at have en global konfigurations fil, men det vil gøre " #~ "det mere behageligt for dine brugere, hvis de finder en standard virkende " #~ "konfiguration." #~ msgid "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" #~ msgstr "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" xawtv-3.106/debian/po/de.po000066400000000000000000000133201343350355000154640ustar00rootroot00000000000000# German translation of xawtv templates # Helge Kreutzmann , 2004, 2007. # This file is distributed under the same license as the xawtv package. # msgid "" msgstr "" "Project-Id-Version: xawtv 3.95.dfsg.1-4\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-10-26 19:17+0200\n" "Last-Translator: Helge Kreutzmann \n" "Language-Team: de \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Sollen Gerätedateien (/dev/video*) für video4linux erstellt werden?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Soll nach Fernsehsendern gesucht werden?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "Es kann eine Liste von Fernsehstationen in die Konfiguration aufgenommen " "werden, die durch automatisches Durchsuchen ermittelt wird." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Dafür ist ein funktionierender BTTV-Treiber erforderlich. Falls BTTV nicht " "richtig eingerichtet ist, könnte kein Sender gefunden werden." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Die Kanalnamen werden aus den Videotextinformationen entnommen. Dies " "funktioniert nur für PAL-Kanäle." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "Fernsehstandard:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Soll eine Standard-Konfiguration für Xawtv erstellt werden?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Es kann eine systemweite Konfigurationsdatei für Xawtv erstellt werden, die " "vernünftige Voreinstellungen für das eigene Land enthält." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Diese Datei muss nicht zwingend vorhanden sein, erleichtert aber den " "Benutzern die Software-Konfiguration." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "US-Rundfunk" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "US-Kabel" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "US-Kabel-HRC" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "Japan-Rundfunk" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "Japan-Kabel" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "West-Europa" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "Ost-Europa" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "Italien" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "Neuseeland" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "Australien" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "Irland" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "Frankreich" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "China-Rundfunk" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Frequenz-Tabelle, die verwendet werden soll:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Eine Frequenz-Tabelle ist eine Liste der Fernsehsender (Namen und Nummern) " "mit dazugehörigen Sendefrequenzen." #~ msgid "" #~ "This can do a scan of all channels and put a list of the TV stations I've " #~ "found into the config file." #~ msgstr "" #~ "Es kann eine Suche nach Kanälen durchgeführt und eine Liste der " #~ "gefundenen Fernsehsender in die Konfigurationsdatei geschrieben werden." #~ msgid "" #~ "I'll try to pick up the channel names from videotext. This will work with " #~ "PAL only." #~ msgstr "" #~ "Ich werde versuchen, die Namen der Kanäle aus dem Videotext " #~ "herauszulesen. Dies funktioniert nur mit PAL." #~ msgid "PAL, SECAM, NTSC" #~ msgstr "PAL, SECAM, NTSC" #~ msgid "TV norm is used in your country:" #~ msgstr "TV-Norm, die in Ihrem Land benutzt wird:" #~ msgid "" #~ "It is not required to have a global configuration file, but it will be " #~ "more comfortable for your users if they find a working default " #~ "configuration." #~ msgstr "" #~ "Eine globale Konfigurationsdatei ist nicht unbedingt erforderlich, aber " #~ "es ist für die Benutzer sicherlich angenehm, gleich eine funktionierende " #~ "Konfiguration vorzufinden." #~ msgid "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" #~ msgstr "" #~ "US-bcast, US-Kabel, US-Kabel-hrc, Japan-bcast, Japan-Kabel, Europa-West, " #~ "Europa-Ost, Italien, Neuseeland, Australien, Irland, Frankreich, China-" #~ "bcast" xawtv-3.106/debian/po/es.po000066400000000000000000000117671343350355000155200ustar00rootroot00000000000000# xawtv debconf translation to spanish # Copyright (C) 2003, 2007 Software in the Public Interest # This file is distributed under the same license as the xawtv package # # Changes: # - Initial translation # Carlos Valdivia Yagüe , 2003 # - Revisions # Carlos Valdivia Yagüe , 2007 # # Translators, if you are not familiar with the PO format, gettext # documentation is worth reading, especially sections dedicated to # this format, e.g. by running: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # # Some information specific to po-debconf are available at # /usr/share/doc/po-debconf/README-trans # or http://www.debian.org/intl/l10n/po-debconf/README-trans # # Developers do not need to manually edit POT or PO files. # msgid "" msgstr "" "Project-Id-Version: xawtv 3.95.dfsg.1-8\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-10-26 04:20+0200\n" "Last-Translator: Carlos Valdivia Yagüe \n" "Language-Team: Debian L10n Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "¿Crear los ficheros especiales video4linux (/dev/video*)?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "¿Buscar cadenas de televisión?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "Se puede añadir en el fichero de configuración una lista de las cadenas de " "televisión encontradas durante la búsqueda." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Esto requiere un controlador bttv que funcione. Si éste no se ha configurado " "correctamente puede que no se encuentren las cadenas de televisión." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Los nombres de los canales se obtendrán a partir de la información de " "teletexto, lo cual sólo funciona con el sistema PAL." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "Sistema de televisión:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "¿Crear una configuración predeterminada para xawtv?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Puede crearse un fichero de configuración global de xawtv con valores " "razonables para su país." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Este fichero no es necesario pero simplificará la configuración del sofware " "por parte de los usuarios." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "EE.UU. (broadcast)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "EE.UU. (cable)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "EE.UU. (cable HRC)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "Japón (broadcast)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "Japón (cable)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "Europa Occidental" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "Europa Oriental" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "Italia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "Nueva Zelanda" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "Australia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "Irlanda" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "Francia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "China (broadcast)" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Tabla de frecuencias a utilizar:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Una tabla de frecuencias es una lista de canales de televisión con sus " "frecuencias de emisión." xawtv-3.106/debian/po/eu.po000066400000000000000000000103551343350355000155120ustar00rootroot00000000000000# translation of xawtv-templates-eu.po to Euskara # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Piarres Beobide , 2007. msgid "" msgstr "" "Project-Id-Version: xawtv-templates-eu\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-10-25 09:56+0200\n" "Last-Translator: Piarres Beobide \n" "Language-Team: Euskara \n" "Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "video4linux gailu bereziak (dev/video*) sortu?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "TV kateak bilatu?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "Bilaketan aurkitutako telebista kateen zerrenda konfigurazio fitxategian " "gordeko dira." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Hobek egoki instalaturik dagoen bbtv kontragailu behar du. bttv ez badago " "behar bezala konfiguraturik telebista kateak ez dira aurkituko." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Kate izenak teletestu argibideetatik artzen dira, honek PAL kanaletan " "bakarrik funtzionatuko du." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "TV estandarra:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "xawtv-rentzat lehenetsiriko konfigurazio bat sortu?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Estatu lokalarentzat lehenetsiriko balio erabilgarriez sistema osorako " "konfigurazio fitxategi bat sortu daiteke." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Fitxategi hau ez da beharrezkoa baina erabiltzaileentzat software " "konfigurazioa erraztu dezake." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "us-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "us-cable" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "us-cable-hrc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "japonia-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "japonia-cable" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "europa-medebaldea" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "europa-ekialdea" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "italia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "zelandaberria" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "australia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "irlanda" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "frantzia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "txina-bcast" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Erabiliko den frekuentzia taula:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Frekuentzia taula telebista kate izen eta kanal zenbaki eta haien difusio " "frekuentzien zerrenda bat da." xawtv-3.106/debian/po/fi.po000066400000000000000000000077231343350355000155040ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: xawtv\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-10-25 21:25+0200\n" "Last-Translator: Esko Arajärvi \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Finnish\n" "X-Poedit-Country: FINLAND\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Luodaanko video4linux-laitetiedostot (/dev/video*)?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Etsitäänkö tv-kanavia?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "Lista löydetyistä tv-kanavista voidaan sisällyttää asetustiedostoon." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Tämä vaatii toimivaa bttv-ajuria. Jos bttv:tä ei ole asetettu oikein, tv-" "kanavia ei löydetä." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Kanavien nimet haetaan teletext-tiedoista, jotka toimivat vain PAL-kanavilla." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "tv-standardi:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Luodaanko xawtv:lle oletusasetukset?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Ohjelmalle xawtv voidaan luoda järjestelmän laajuinen asetustiedosto " "järkevillä oletusarvoilla tähän maahan." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Tiedosto ei ole välttämätön, mutta se helpottaa ohjelman käyttäjäasetusten " "tekemistä." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "USA-antenni" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "USA-kaapeli" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "USA-kaapeli-hrc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "Japani-antenni" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "Japani-kaapeli" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "Eurooppa-länsi" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "Eurooppa-itä" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "Italia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "Uusi-Seelanti" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "Australia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "Irlanti" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "Ranska" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "Kiina-antenni" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Käytettävä taajuustaulukko:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Taajuustaulukko on lista tv-kanavien nimistä ja numeroista yhdistettyinä " "lähetystaajuuksiin." xawtv-3.106/debian/po/fr.po000066400000000000000000000121201343350355000155000ustar00rootroot00000000000000# # Translators, if you are not familiar with the PO format, gettext # documentation is worth reading, especially sections dedicated to # this format, e.g. by running: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # Some information specific to po-debconf are available at # /usr/share/doc/po-debconf/README-trans # or http://www.debian.org/intl/l10n/po-debconf/README-trans# # Developers do not need to manually edit POT or PO files. # msgid "" msgstr "" "Project-Id-Version: xawtv_3.95.dfsg.1-4\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-10-30 22:30+0100\n" "Last-Translator: Michel Grentzinger \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Faut-il créer les fichiers spéciaux video4linux (/dev/video*) ?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Faut-il rechercher des chaînes de télévision ?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "Une liste des chaînes de télévision détectées lors de la recherche peut être " "incluse dans le fichier de configuration." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Cela nécessite un pilote fonctionnel pour bttv. Si bttv n'est pas encore " "configuré correctement, les chaînes de télévision ne seront sans doute pas " "trouvées." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Les noms des chaînes seront déterminés d'après le télétexte, ce qui ne " "fonctionnera qu'avec les chaînes à la norme PAL." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "Standard TV :" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Créer une configuration par défaut pour xawtv ?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Un fichier de configuration générique pour xawtv peut être créé avec des " "valeurs par défaut adaptées au pays dans lequel vous résidez." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Ce fichier n'est pas nécessaire mais simplifiera les configurations pour les " "utilisateurs." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "USA hertzien" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "USA câble" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "USA câble HRC" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "Japon hertzien" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "Japon câble" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "europe occidentale" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "europe orientale" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "Italie" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "Nouvelle-Zélande" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "Australie" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "Irlande" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "France" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "Chine hertzien" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Table des fréquences à utiliser :" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Une table de fréquences consiste simplement en une liste de numéros ou de " "noms de chaînes, associés aux fréquences de diffusion correspondantes." #~ msgid "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" #~ msgstr "" #~ "us-bcast, us-cable, us-cable-hrc, japon-bcast, japon-cable, europe-ouest, " #~ "europe-est, italie, nouvelle-zélande, australie, irlande, france, chine-" #~ "bcast" xawtv-3.106/debian/po/gl.po000066400000000000000000000102701343350355000154770ustar00rootroot00000000000000# Galician translation of xawtv's debconf templates # This file is distributed under the same license as the xawtv package. # Jacobo Tarrio , 2007. # msgid "" msgstr "" "Project-Id-Version: xawtv\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-10-25 19:00+0100\n" "Last-Translator: Jacobo Tarrio \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "¿Crear os ficheiros especiais de video4linux (/dev/video*)?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "¿Buscar canles de TV?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "Pódese incluír unha lista de canles de televisión atopadas tras unha busca " "automática." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Isto precisa dun controlador bttv que funcione. Se bttv non está configurado " "correctamente, non se ha atopar ningunha canle de televisión." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Os nomes das canles hanse extraer da información do teletexto, que só ha " "funcionar coas canles PAL." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "Norma de TV:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "¿Crear unha configuración por defecto para xawtv?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Pódese crear un ficheiro de configuración global para xawtv con valores por " "defecto razoables para o país." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Ese ficheiro non é necesario, pero ha simplificar a configuración do " "software para os usuarios." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "EEUU-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "EEUU-cable" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "EEUU-cable-hrc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "Xapón-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "Xapón-cable" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "Europa-oeste" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "Europa-leste" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "Italia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "Nova Celandia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "Australia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "Irlanda" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "Francia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "China-bcast" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Táboa de frecuencias a empregar:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Unha táboa de frecuencias é unha lista de nomes e números de canles de " "televisión coas súas frecuencias de emisión." xawtv-3.106/debian/po/it.po000066400000000000000000000106151343350355000155140ustar00rootroot00000000000000# Italian translation of the xawtv debconf template # This file is distributed under the same license as the xawtv package # Copyright (C) 2007 Free Software Foundation, Inc. # Luca Monducci , 2007. # msgid "" msgstr "" "Project-Id-Version: xawtv debconf templates\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-01-05 20:05+0100\n" "Last-Translator: Luca Monducci \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Creare i file speciali video4linux (/dev/video*)?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Ricerca dei canali TV?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "L'elenco dei canali TV trovati con la ricerca può essere inserito nel file " "di configurazione." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Per effettuare la ricerca è necessario che il driver bttv sia funzionante. " "Se bttv non è configurato correttamente, i canali TV non possono essere " "trovati." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "I nomi dei canali verranno recuperati dalle informazioni del teletext, " "disponibile solo per i canali PAL." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "Standard TV:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Creare un file di configurazione predefinito per xawtv?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "È possibile creare un file di configurazione per xawtv valido per l'intero " "sistema utilizzando i valori predefiniti per il proprio paese." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Non è necessario usare questo file però semplifica la configurazione del " "programma da parte degli utenti." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "stati uniti-radiodiffusione" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "stati uniti-via cavo" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "stati uniti-via cavo hrc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "giappone-radiodiffusione" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "giappone-via cavo" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "europa occidentale" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "europa orientale" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "italia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "nuova zelanda" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "australia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "irlanda" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "francia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "cina-radiodiffusione" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Tabella delle frequenze da usare:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Una tabella delle frequenze è un elenco di nomi e numeri dei canali TV " "associati alle frequenze su cui trasmettono." xawtv-3.106/debian/po/ja.po000066400000000000000000000106051343350355000154710ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: xawtv 3.95.dfsg.1-7\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-10-30 22:04+0900\n" "Last-Translator: Hideki Yamane (Debian-JP) \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "video4linux (/dev/video*) ã®ç‰¹æ®Šãƒ•ァイルを作æˆã—ã¾ã™ã‹?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "TV å±€ã®ä¸€è¦§ã‚’スキャンã—ã¾ã™ã‹?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "スキャンã—㟠TV 局一覧情報を設定ファイルã«å«ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "bttv ドライãƒãŒæ—¢ã«å‹•作ã—ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ã¾ã  bttv ãŒãã¡ã‚“ã¨è¨­å®šã•れã¦" "ã„ãªã„å ´åˆã€TV 局を見ã¤ã‘る事ãŒã§ããªã„ã‹ã‚‚ã—れã¾ã›ã‚“。" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "videotext 情報ã‹ã‚‰ãƒãƒ£ãƒ³ãƒãƒ«åã‚’å–り出ã—ã¾ã™ã€‚ã“れ㯠PAL ã§ã®ã¿å‹•作ã—ã¾ã™ (æ—¥" "本ã§ã¯ NTSC を利用ã—ã¦ã„ã‚‹ã®ã§å‹•作ã—ã¾ã›ã‚“)。" #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "TV 放é€è¦æ ¼:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "xawtv ã®æ¨™æº–設定を作æˆã—ã¾ã™ã‹?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "システム全体ã§åˆ©ç”¨ã™ã‚‹ xawtv 用設定ファイルをã€ã‚ãªãŸãŒä½ã‚“ã§ã„る国ã«ã‚ã‚ã›ã¦" "é©åˆ‡ãªåˆæœŸå€¤ã§ä½œæˆã—ã¾ã™ã€‚" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "ã“ã®ãƒ•ァイルã¯å¿…è¦ã§ã¯ã‚りã¾ã›ã‚“ãŒã€ãƒ¦ãƒ¼ã‚¶è¨­å®šã‚’ç°¡å˜ã«ã—ã¦ãれã¾ã™ã€‚" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "アメリカ (地上波)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "アメリカ (ケーブルTV)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "アメリカ (å…‰åŒè»¸ã‚±ãƒ¼ãƒ–ルTV)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "日本 (地上波)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "日本 (ケーブルTV)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "ヨーロッパ西部" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "ヨーロッパæ±éƒ¨" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "イタリア" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "ニュージーランド" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "オーストラリア" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "アイルランド" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "フランス" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "中国 (地上波)" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "利用周波数テーブル:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "周波数テーブル㯠TV ãƒãƒ£ãƒ³ãƒãƒ«ã®åå‰ãƒ»æ•°å­—ã¨ãƒãƒ£ãƒ³ãƒãƒ«ã«å¯¾å¿œã™ã‚‹æ”¾é€å‘¨æ³¢æ•°ã®" "リストã§ã™ã€‚" xawtv-3.106/debian/po/nl.po000066400000000000000000000115551343350355000155150ustar00rootroot00000000000000# translation of xawtv_3.95.dfsg.1-8_nl.po to Dutch # This file is distributed under the same license as the xawtv package. # # Please see debian/copyright. # # Translators, if you are not familiar with the PO format, gettext # documentation is worth reading, especially sections dedicated to # this format, e.g. by running: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # Some information specific to po-debconf are available at # /usr/share/doc/po-debconf/README-trans # or http://www.debian.org/intl/l10n/po-debconf/README-trans# # Developers do not need to manually edit POT or PO files. # # Paul Gevers , 2008. msgid "" msgstr "" "Project-Id-Version: xawtv_3.95.dfsg.1-8_nl\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2008-09-24 21:36-0500\n" "Last-Translator: Paul Gevers \n" "Language-Team: Dutch \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Wilt u de 'video4linux' (/dev/video*) apparaatbestanden aanmaken?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "TV-zenders zoeken?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "Als er TV-zenders gevonden worden tijdens het zoeken, dan kunnen die " "opgenomen worden in het configuratiebestand." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Dit vereist een werkend 'bttv'-stuurprogramma. Als 'bttv' niet correct is " "geconfigureerd zullen de zenders niet gevonden worden." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Er wordt gebruik gemaakt van teletekstinformatie om de zendernamen te " "achterhalen, maar dit werkt alleen voor PAL zenders." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "TV standaard:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Wilt u een standaardconfiguratie voor 'xawtv' aanmaken?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "U kunt een systeemomvattend 'xawtv' configuratiebestand laten aanmaken met " "redelijke standaardwaarden voor het land waarin u verblijft." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Dit bestand in niet noodzakelijk, maar vergemakkelijkt het instellen van de " "programmatuur voor gebruikers." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "VS-ether" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "VS-kabel" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "VS-kabel-hdtv" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "Japan-ether" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "Japan-kabel" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "West-Europa" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "Oost-Europa" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "Italië" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "Nieuw-Zeeland" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "Australië" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "Ierland" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "Frankrijk" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "China-ether" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Welke frequentietabel wilt u dat er gebruikt wordt?" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Een frequentietabel is een lijst met zendernamen en nummers, en de " "bijbehorende frequenties." xawtv-3.106/debian/po/pt.po000066400000000000000000000133501343350355000155220ustar00rootroot00000000000000# Portuguese translation of xawtv (debconf). # Copyright (C) 2006 THE xawtv'S COPYRIGHT HOLDER # This file is distributed under the same license as the xawtv package. # Rui Branco , 2006. # 2007-08-26 - Rui Branco - 3f # 2007-11-08 - Rui Branco - 17u5f # # msgid "" msgstr "" "Project-Id-Version: xawtv 3.95.dfsg.1-5\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-11-09 00:00+0000\n" "Last-Translator: Rui Branco \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Criar ficheiros especiais para o video4linux·(/dev/video*)?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Procurar estações de TV?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "Uma lista de estações de TV pode ser encontrada pela procura pode ser " "incluída no ficheiro de configuração." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Esta operação requer um controlador bttv funcional. Se o bttv não estiver " "correctamente configurado não irá encontrar estações de TV." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Os nomes dos canais podem ser obtidos pela informação do teletexto, o que " "apenas funciona para canais PAL." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "Standard TV:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Criar uma configuração por omissão para o xawtv?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Pode criar um ficheiro de configuração xawtv para todo o sistema com valores " "por omissão razoáveis para o país onde habita ." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Este ficheiro não é necessário, mas pode simplificar a configuração do " "software" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "us-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "us-cable" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "us-cable-hrc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "japan-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "japan-cable" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "europe-west" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "europe-east" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "itália" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "nova zelândia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "austrália" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "irlanda" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "frança" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "china-bcast" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Tabela de frequências a ser utilizada:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Uma tabela de frequências é uma lista de nomes e numeros de canais de TV e " "correspondentes frequências de emissão." #~ msgid "" #~ "This can do a scan of all channels and put a list of the TV stations I've " #~ "found into the config file." #~ msgstr "" #~ "Posso efectuar uma procura por todos os canais e colocá-los numa lista de " #~ "estações de TV que encontrar num ficheiro de configuração." #~ msgid "" #~ "I'll try to pick up the channel names from videotext. This will work with " #~ "PAL only." #~ msgstr "" #~ "Tentarei encontrar o nome dos canais a partir do videotext. Apenas " #~ "funciona para o sistema PAL." #~ msgid "PAL, SECAM, NTSC" #~ msgstr "PAL, SECAM, NTSC" #~ msgid "TV norm is used in your country:" #~ msgstr "Norma de TV utilizada no seu país:" #~ msgid "" #~ "It is not required to have a global configuration file, but it will be " #~ "more comfortable for your users if they find a working default " #~ "configuration." #~ msgstr "" #~ "Não é requisito ter um ficheiro de configuração global, mas será mais " #~ "confortável para os seus utilizadores se descobrirem uma configuração por " #~ "omissão funcional." #~ msgid "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" #~ msgstr "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" xawtv-3.106/debian/po/pt_BR.po000066400000000000000000000143571343350355000161150ustar00rootroot00000000000000# # Translators, if you are not familiar with the PO format, gettext # documentation is worth reading, especially sections dedicated to # this format, e.g. by running: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # # Some information specific to po-debconf are available at # /usr/share/doc/po-debconf/README-trans # or http://www.debian.org/intl/l10n/po-debconf/README-trans # # Developers do not need to manually edit POT or PO files. # msgid "" msgstr "" "Project-Id-Version: xawtv_3.94-1.2\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2006-07-27 23:25-0300\n" "Last-Translator: Herbert Parentes Fortes Neto \n" "Language-Team: l10n portuguese \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "pt_BR utf-8\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Criar arquivos especiais video4linux (/dev/video*)?" #. Type: boolean #. Description #: ../xawtv.templates:3001 #, fuzzy #| msgid "scan for TV stations?" msgid "Scan for TV stations?" msgstr "Fazer uma busca por estações de TV?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:3001 #, fuzzy #| msgid "" #| "This requires a working bttv driver. If bttv isn't configured correctly " #| "I might not find the TV stations." msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Isso requer um driver bttv funcional. Se o bttv não estiver configurado " "corretamente eu talvez não encontre as estações de TV." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Criar uma configuração padrão para o xawtv?" #. Type: boolean #. Description #: ../xawtv.templates:5001 #, fuzzy #| msgid "" #| "You can create a system-wide configuration file for xawtv with reasonable " #| "default values for the country you live in (which TV norm is used for " #| "example)." msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Você pode criar um arquivo de configuração global para o xawtv com valores " "padrões razoáveis para o país em que você vive (com o TV \"norm\" que é " "usado por exemplo)." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "" #. Type: select #. Description #: ../xawtv.templates:6002 #, fuzzy msgid "Frequency table to use:" msgstr "Qual tabela de freqüência deve ser usada?" #. Type: select #. Description #: ../xawtv.templates:6002 #, fuzzy #| msgid "" #| "A frequency table is just a list of TV channel names/numbers and the " #| "corresponding broadcast frequencies for these channels. Different " #| "regions use different standards here..." msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Uma tabela de freqüência é apenas uma lista de nomes/números de canais de TV " "e sua correspondente freqüência de broadcast para esses canais. Regiões " "diferentes usam diferentes padrões aqui..." #, fuzzy #~ msgid "" #~ "This can do a scan of all channels and put a list of the TV stations I've " #~ "found into the config file." #~ msgstr "" #~ "Eu posso fazer uma busca por todos os canais e colocar uma lista de " #~ "estações de TV que encontrei em um arquivo de configuração." #~ msgid "" #~ "I'll try to pick up the channel names from videotext. This will work with " #~ "PAL only." #~ msgstr "" #~ "Eu tentarei pegar os nomes dos canais a partir do \"videotext\". Isso só " #~ "funcionará com PAL." #~ msgid "PAL, SECAM, NTSC" #~ msgstr "PAL, SECAM, NTSC" #, fuzzy #~ msgid "TV norm is used in your country:" #~ msgstr "Qual TV \"norm\" é usado em seu país?" #~ msgid "" #~ "It is not required to have a global configuration file, but it will be " #~ "more comfortable for your users if they find a working default " #~ "configuration." #~ msgstr "" #~ "Não é necessário ter um arquivo de configuração global, mas será mais " #~ "confortável para seus usuários se eles encontrarem uma configuração " #~ "padrão que funcione." #~ msgid "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" #~ msgstr "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzeal and, australia, ireland, france, china-bcast" xawtv-3.106/debian/po/ru.po000066400000000000000000000125321343350355000155260ustar00rootroot00000000000000# translation of ru.po to Russian # This file is distributed under the same license as the PACKAGE package. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. # # Yuri Kozlov , 2006, 2007. msgid "" msgstr "" "Project-Id-Version: 3.95.dfsg.1-7\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-11-07 20:40+0300\n" "Last-Translator: Yuri Kozlov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Создать Ñпециальные файлы video4linux (/dev/video*)?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Ðайти ТВ-каналы?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "СпиÑок найденных телевизионных каналов можно включить в файл конфигурации." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Ð”Ð»Ñ Ñтого требуетÑÑ Ñ€Ð°Ð±Ð¾Ñ‚Ð°ÑŽÑ‰Ð¸Ð¹ драйвер bttv. ЕÑли bttv наÑтроен неправильно, " "то ТВ-каналы найдены не будут." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² будут получены из информации телетекÑта, но Ñто работает " "только Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² в кодировке PAL." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "Телевизионный Ñтандарт:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Создать конфигурацию по умолчанию Ð´Ð»Ñ xawtv?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Можно Ñоздать общеÑиÑтемный конфигурационный файл Ð´Ð»Ñ xawtv Ñ Ð¿Ñ€Ð¸ÐµÐ¼Ð»ÐµÐ¼Ñ‹Ð¼Ð¸ " "значениÑми по умолчанию Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ Ñтраны." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Этот файл необÑзателен, но упроÑтил бы наÑтройку программного обеÑÐ¿ÐµÑ‡ÐµÐ½Ð¸Ñ " "Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "американÑÐºÐ°Ñ ÑÑ„Ð¸Ñ€Ð½Ð°Ñ (us-bcast)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "американÑÐºÐ°Ñ ÐºÐ°Ð±ÐµÐ»ÑŒÐ½Ð°Ñ (us-cable)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "американÑÐºÐ°Ñ ÐºÐ°Ð±ÐµÐ»ÑŒÐ½Ð°Ñ hrc (us-cable-hrc)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "ÑпонÑÐºÐ°Ñ ÑÑ„Ð¸Ñ€Ð½Ð°Ñ (japan-bcast)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "ÑпонÑÐºÐ°Ñ ÐºÐ°Ð±ÐµÐ»ÑŒÐ½Ð°Ñ (japan-cable)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "западно-европейÑÐºÐ°Ñ (europe-west)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "воÑточно-европейÑÐºÐ°Ñ (europe-east)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "итальÑнÑÐºÐ°Ñ (italy)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "новозеландÑÐºÐ°Ñ (newzealand)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "авÑтралийÑÐºÐ°Ñ (australia)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "ирландÑÐºÐ°Ñ (ireland)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "французÑÐºÐ°Ñ (france)" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "китайÑÐºÐ°Ñ ÑÑ„Ð¸Ñ€Ð½Ð°Ñ (china-bcast)" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "ИÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÐ¼Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° чаÑтот:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Таблица чаÑтот -- Ñто проÑто ÑпиÑок имён/номеров ТВ-каналов и " "ÑоответÑтвующих им Ñфирных чаÑтот." xawtv-3.106/debian/po/sv.po000066400000000000000000000111011343350355000155170ustar00rootroot00000000000000# translation of xawtv_3.95.dfsg.1-8_sv.po to Swedish # Translators, if you are not familiar with the PO format, gettext # documentation is worth reading, especially sections dedicated to # this format, e.g. by running: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # Some information specific to po-debconf are available at # /usr/share/doc/po-debconf/README-trans # or http://www.debian.org/intl/l10n/po-debconf/README-trans # Developers do not need to manually edit POT or PO files. # # Martin Ã…gren , 2008. msgid "" msgstr "" "Project-Id-Version: xawtv_3.95.dfsg.1-8_sv\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2008-07-19 11:48+0200\n" "Last-Translator: Martin Ã…gren \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Skapa video4linux (/dev/video*) specialfiler?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Sök efter TV-stationer?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" "En lista över TV-stationer funna genom sökning kan inkluderas i " "konfigurationsfilen." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Detta kräver en fungerande bttv-drivrutin. Om inte bttv är konfigurerad " "korrekt kan inga TV-stationer hittas." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Kanalnamn kommer hämtas frÃ¥n texttvinformationen, som bara kommer fungera " "för PAL-kanaler." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "TV-standard:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Skapa en standardkonfiguration för xawtv?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Du kan skapa en systembred konfigurationsfil för xawtv med rimliga " "standardvärden för det land du bor i." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Den filen är inte nödvändig men kommer förenkla programvarukonfiguration för " "användare." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "us-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "us-cable" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "us-cable-hrc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "japan-bcast" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "japan-cable" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "europe-west" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "europe-east" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "italy" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "newzealand" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "australia" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "ireland" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "france" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "china-bcast" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Frekvenstabell att använda:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "En frekvenstabell är en lista över namn/nummer pÃ¥ TV-kanaler och dess " "respektive sändarfrekvenser." xawtv-3.106/debian/po/templates.pot000066400000000000000000000063201343350355000172600ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" xawtv-3.106/debian/po/tr.po000066400000000000000000000135461343350355000155330ustar00rootroot00000000000000# Turkish translation of xawtv. # This file is distributed under the same license as the xawtv package. # Recai OktaÅŸ, 2004. # msgid "" msgstr "" "Project-Id-Version: xawtv\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2004-05-15 11:11+0300\n" "Last-Translator: Recai OktaÅŸ \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "\"video4linux\" ozel dosyaları (/dev/video*) oluÅŸturulsun mu?" #. Type: boolean #. Description #: ../xawtv.templates:3001 #, fuzzy #| msgid "scan for TV stations?" msgid "Scan for TV stations?" msgstr "TV kanalları taransın mı?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:3001 #, fuzzy #| msgid "" #| "This requires a working bttv driver. If bttv isn't configured correctly " #| "I might not find the TV stations." msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Bu iÅŸlem çalışır durumda bir bttv sürücüsü gerektiriyor. EÄŸer bttv doÄŸru " "ÅŸekilde yapılandırılmamışsa, TV kanallarını bulamayabilirim." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Xawtv için bir öntanımlı yapılandırma oluÅŸturulsun mu?" #. Type: boolean #. Description #: ../xawtv.templates:5001 #, fuzzy #| msgid "" #| "You can create a system-wide configuration file for xawtv with reasonable " #| "default values for the country you live in (which TV norm is used for " #| "example)." msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "YaÅŸadığınız ülkeye özgü (ülkenizde kullanılan TV standartı gibi) öntanımlı " "deÄŸerlerle sistem genelinde etkin bir xawtv yapılandırma dosyası " "oluÅŸturabilirsiniz." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "" #. Type: select #. Description #: ../xawtv.templates:6002 #, fuzzy msgid "Frequency table to use:" msgstr "Hangi frekans tablosu kullanılsın?" #. Type: select #. Description #: ../xawtv.templates:6002 #, fuzzy #| msgid "" #| "A frequency table is just a list of TV channel names/numbers and the " #| "corresponding broadcast frequencies for these channels. Different " #| "regions use different standards here..." msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Frekans tablosu, bir dizi TV kanal ismi/numarası ve bunlara karşı düşen " "yayın frekanslarından oluÅŸan basit bir listedir. Farklı bölgeler farklı " "standartlar kullanır." #, fuzzy #~ msgid "" #~ "This can do a scan of all channels and put a list of the TV stations I've " #~ "found into the config file." #~ msgstr "" #~ "Bütün kanalları tarayarak, bulduklarımı yapılandırma dosyasına " #~ "kaydedebilirim." #~ msgid "" #~ "I'll try to pick up the channel names from videotext. This will work with " #~ "PAL only." #~ msgstr "" #~ "Kanal isimlerini videotext'ten seçmeye çalışacağım. Bu iÅŸlem, sadece PAL " #~ "için geçerlidir." #~ msgid "PAL, SECAM, NTSC" #~ msgstr "PAL, SECAM, NTSC" #, fuzzy #~ msgid "TV norm is used in your country:" #~ msgstr "Ülkenizde hangi TV standartı kullanılıyor?" #~ msgid "" #~ "It is not required to have a global configuration file, but it will be " #~ "more comfortable for your users if they find a working default " #~ "configuration." #~ msgstr "" #~ "Sistem genelinde etkin bir yapılandırma dosyasına sahip olmanız ÅŸart " #~ "deÄŸil, fakat kullanıcıların çalışır durumda bir öntanımlı yapılandırma " #~ "bulmaları faydalı olacaktır." #~ msgid "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" #~ msgstr "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" xawtv-3.106/debian/po/vi.po000066400000000000000000000132351343350355000155170ustar00rootroot00000000000000# Vietnamese translation for XawTV. # Copyright © 2007 Free Software Foundation, Inc. # Clytie Siddall , 2005-2007. # msgid "" msgstr "" "Project-Id-Version: xawtv 3.95.dfsg.1-7\n" "Report-Msgid-Bugs-To: xawtv@packages.debian.org\n" "POT-Creation-Date: 2007-10-25 07:29+0200\n" "PO-Revision-Date: 2007-10-25 22:47+0930\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n" "Language: vi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: LocFactoryEditor 1.7b1\n" #. Type: boolean #. Description #: ../xawtv.templates:2001 msgid "Create video4linux (/dev/video*) special files?" msgstr "Có tạo tập tin video4linux (/dev/video*) đặc biệt không?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "Scan for TV stations?" msgstr "Có quét tìm các kênh TV không?" #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "A list of TV stations found by scanning can be included in the configuration " "file." msgstr "Tìm được thì danh sách các kênh TV nằm trong tập tin cấu hình." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "This requires a working bttv driver. If bttv isn't configured correctly, TV " "stations will not be found." msgstr "" "Việc này cần thiết trình Ä‘iá»u khiển bttv hoạt động. Chưa cấu hình đúng bttv " "thì không tìm thấy kênh TV." #. Type: boolean #. Description #: ../xawtv.templates:3001 msgid "" "Channel names will be retrieved from teletext information, which will only " "work for PAL channels." msgstr "" "Lấy các tên kênh từ thông tin teletext: chỉ hoạt động cho kệnh kiểu PAL." #. Type: select #. Description #: ../xawtv.templates:4001 msgid "TV standard:" msgstr "Tiêu chuẩn TV:" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "Create a default configuration for xawtv?" msgstr "Có tạo cấu hình mặc định cho xawtv không?" #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "A system-wide configuration file for xawtv can be created with reasonable " "default values for the local country." msgstr "" "Có thể tạo cho xawtv má»™t tập tin cấu hình toàn hệ thống chứa các giá trị hÆ¡i " "thích hợp vá»›i quốc gia đó." #. Type: boolean #. Description #: ../xawtv.templates:5001 msgid "" "That file is not required but will simplify software configuration for users." msgstr "" "Tập tin này không phải bắt buá»™c phải dùng, nhưng vẫn còn đơn giản hoá tiến " "trình cấu hình phần má»m cho ngưá»i dùng." #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-bcast" msgstr "Mỹ-phát_thanh" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable" msgstr "Mỹ-cáp" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "us-cable-hrc" msgstr "Mỹ-cáp-hrc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-bcast" msgstr "Nhật-phát_thanh" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "japan-cable" msgstr "Nhật-cáp" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-west" msgstr "Tây-Âu" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "europe-east" msgstr "Äông-Âu" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "italy" msgstr "Ã" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "newzealand" msgstr "Niu-Xi-Lan" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "australia" msgstr "Úc" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "ireland" msgstr "Ai-len" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "france" msgstr "Pháp" #. Type: select #. Choices #: ../xawtv.templates:6001 msgid "china-bcast" msgstr "Trung-phát_thanh" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "Frequency table to use:" msgstr "Bảng tần số cần dùng:" #. Type: select #. Description #: ../xawtv.templates:6002 msgid "" "A frequency table is a list of TV channel names and numbers with their " "broadcast frequencies." msgstr "" "Bảng tần số là danh sách các tên/số kênh TV và tần số phát hành tương ứng." #~ msgid "" #~ "This can do a scan of all channels and put a list of the TV stations I've " #~ "found into the config file." #~ msgstr "" #~ "Trình này có thể quét má»i kênh rồi ghi vào tập tin cấu hình má»™t danh sách " #~ "các kênh TV đã tìm." #~ msgid "" #~ "I'll try to pick up the channel names from videotext. This will work with " #~ "PAL only." #~ msgstr "" #~ "Trình này sẽ cố lấy tên kênh từ videotext (chữ ảnh động). Sẽ hoạt động " #~ "chỉ vá»›i giao thức PAL." #~ msgid "PAL, SECAM, NTSC" #~ msgstr "PAL, SECAM, NTSC" #~ msgid "TV norm is used in your country:" #~ msgstr "Tiêu chuẩn TV dùng ở chá»— bạn:" #~ msgid "" #~ "It is not required to have a global configuration file, but it will be " #~ "more comfortable for your users if they find a working default " #~ "configuration." #~ msgstr "" #~ "Không cần tập tin cấu hình toàn cục, nhưng nó tiện hÆ¡n cho ngưá»i dùng nếu " #~ "há» tìm cấu hình hoạt động." #~ msgid "" #~ "us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, " #~ "europe-east, italy, newzealand, australia, ireland, france, china-bcast" #~ msgstr "" #~ "phát_thanh_Mỹ, cáp_Mỹ, cáp_Mỹ_hrc, phát_thanh_Nhật_bản, cáp_Nhật_bản, " #~ "Tây_Âu, Äông_Âu, Ã, Niu_Di-lan, Úc, Ãi-nhÄ©-lan, Pháp, " #~ "phát_thanh_Quốc_Trung" xawtv-3.106/debian/radio.install000066400000000000000000000000771343350355000166110ustar00rootroot00000000000000debian/tmp/usr/bin/radio debian/tmp/usr/share/man/man1/radio.1 xawtv-3.106/debian/radio.menu000066400000000000000000000001531343350355000161020ustar00rootroot00000000000000?package(radio):needs="text" section="Applications/TV and Radio" \ title="radio" command="/usr/bin/radio" xawtv-3.106/debian/rules000077500000000000000000000005551343350355000152040ustar00rootroot00000000000000#!/usr/bin/make -f export DEB_BUILD_MAINT_OPTIONS = hardening=+all export verbose = yes %: dh $@ --buildsystem=autoconf --with autoreconf override_dh_fixperms: dh_fixperms -chmod 4755 $(CURDIR)/debian/v4l-conf/usr/bin/v4l-conf override_dh_strip: dh_strip --ddeb-migration='xawtv-dbg (<= 3.103-4~~)' override_dh_installdocs: dh_installdocs -XREADME.xfree4 xawtv-3.106/debian/scantv.install000066400000000000000000000001521343350355000170030ustar00rootroot00000000000000debian/tmp/usr/bin/scantv debian/tmp/usr/share/man/*/man1/scantv.1 debian/tmp/usr/share/man/man1/scantv.1 xawtv-3.106/debian/source/000077500000000000000000000000001343350355000154175ustar00rootroot00000000000000xawtv-3.106/debian/source/format000066400000000000000000000000141343350355000166250ustar00rootroot000000000000003.0 (quilt) xawtv-3.106/debian/streamer.install000066400000000000000000000002631343350355000173320ustar00rootroot00000000000000debian/contrib/streamer-wrapper.pl usr/share/doc/streamer/contrib debian/tmp/usr/bin/streamer debian/tmp/usr/share/man/*/man1/streamer.1 debian/tmp/usr/share/man/man1/streamer.1 xawtv-3.106/debian/ttv.install000066400000000000000000000001411343350355000163200ustar00rootroot00000000000000debian/tmp/usr/bin/ttv debian/tmp/usr/share/man/*/man1/ttv.1 debian/tmp/usr/share/man/man1/ttv.1 xawtv-3.106/debian/ttv.menu000066400000000000000000000001451343350355000156220ustar00rootroot00000000000000?package(ttv):needs="text" section="Applications/TV and Radio" \ title="ttv" command="/usr/bin/ttv" xawtv-3.106/debian/v4l-conf.install000066400000000000000000000002651343350355000171420ustar00rootroot00000000000000debian/tmp/usr/bin/v4l-conf debian/tmp/usr/bin/v4l-info debian/tmp/usr/share/man/*/man8/v4l-conf.8 debian/tmp/usr/share/man/man1/v4l-info.1 debian/tmp/usr/share/man/man8/v4l-conf.8 xawtv-3.106/debian/v4l-conf.lintian-overrides000066400000000000000000000000161343350355000211240ustar00rootroot00000000000000setuid-binary xawtv-3.106/debian/watch000066400000000000000000000002711343350355000151500ustar00rootroot00000000000000version=3 opts=filenamemangle=s!.*/\?id=([^/]*)$!$1\.tar\.gz!,downloadurlmangle=s!tag/\?id=([^/]*)!snapshot/$1\.tar\.gz! \ http://git.linuxtv.org/xawtv3.git/refs/ .*=xawtv-([\d.]+) xawtv-3.106/debian/webcam.docs000066400000000000000000000000231343350355000162220ustar00rootroot00000000000000scripts/webcam.cgi xawtv-3.106/debian/webcam.install000066400000000000000000000001011343350355000167350ustar00rootroot00000000000000debian/tmp/usr/bin/webcam debian/tmp/usr/share/man/man1/webcam.1 xawtv-3.106/debian/xawtv-plugin-qt.install000066400000000000000000000000421343350355000205720ustar00rootroot00000000000000debian/tmp/usr/lib/*/xawtv/*qt.so xawtv-3.106/debian/xawtv-plugin-qt.lintian-overrides000066400000000000000000000002001343350355000225560ustar00rootroot00000000000000pkg-has-shlibs-control-file-but-no-actual-shared-libs postinst-has-useless-call-to-ldconfig postrm-has-useless-call-to-ldconfig xawtv-3.106/debian/xawtv-plugins.install000066400000000000000000000012321343350355000203350ustar00rootroot00000000000000debian/tmp/usr/lib/*/xawtv/bilinear.so debian/tmp/usr/lib/*/xawtv/conv-mjpeg.so debian/tmp/usr/lib/*/xawtv/cubic.so debian/tmp/usr/lib/*/xawtv/drv0-libv4l.so debian/tmp/usr/lib/*/xawtv/drv0-v4l2.so debian/tmp/usr/lib/*/xawtv/flt-disor.so debian/tmp/usr/lib/*/xawtv/flt-gamma.so debian/tmp/usr/lib/*/xawtv/flt-invert.so debian/tmp/usr/lib/*/xawtv/flt-smooth.so debian/tmp/usr/lib/*/xawtv/linear-blend.so debian/tmp/usr/lib/*/xawtv/linedoubler.so debian/tmp/usr/lib/*/xawtv/read-avi.so debian/tmp/usr/lib/*/xawtv/read-dv.so debian/tmp/usr/lib/*/xawtv/snd-oss.so debian/tmp/usr/lib/*/xawtv/write-avi.so debian/tmp/usr/lib/*/xawtv/write-dv.so debian/tmp/usr/share/xawtv xawtv-3.106/debian/xawtv-plugins.install.kfreebsd-amd64000066400000000000000000000011571343350355000230400ustar00rootroot00000000000000debian/tmp/usr/lib/*/xawtv/bilinear.so debian/tmp/usr/lib/*/xawtv/conv-mjpeg.so debian/tmp/usr/lib/*/xawtv/cubic.so debian/tmp/usr/lib/*/xawtv/drv0-bsd.so debian/tmp/usr/lib/*/xawtv/flt-disor.so debian/tmp/usr/lib/*/xawtv/flt-gamma.so debian/tmp/usr/lib/*/xawtv/flt-invert.so debian/tmp/usr/lib/*/xawtv/flt-smooth.so debian/tmp/usr/lib/*/xawtv/linear-blend.so debian/tmp/usr/lib/*/xawtv/linedoubler.so debian/tmp/usr/lib/*/xawtv/read-avi.so debian/tmp/usr/lib/*/xawtv/read-dv.so debian/tmp/usr/lib/*/xawtv/snd-oss.so debian/tmp/usr/lib/*/xawtv/write-avi.so debian/tmp/usr/lib/*/xawtv/write-dv.so debian/tmp/usr/share/xawtv xawtv-3.106/debian/xawtv-plugins.install.kfreebsd-i386000066400000000000000000000011571343350355000226160ustar00rootroot00000000000000debian/tmp/usr/lib/*/xawtv/bilinear.so debian/tmp/usr/lib/*/xawtv/conv-mjpeg.so debian/tmp/usr/lib/*/xawtv/cubic.so debian/tmp/usr/lib/*/xawtv/drv0-bsd.so debian/tmp/usr/lib/*/xawtv/flt-disor.so debian/tmp/usr/lib/*/xawtv/flt-gamma.so debian/tmp/usr/lib/*/xawtv/flt-invert.so debian/tmp/usr/lib/*/xawtv/flt-smooth.so debian/tmp/usr/lib/*/xawtv/linear-blend.so debian/tmp/usr/lib/*/xawtv/linedoubler.so debian/tmp/usr/lib/*/xawtv/read-avi.so debian/tmp/usr/lib/*/xawtv/read-dv.so debian/tmp/usr/lib/*/xawtv/snd-oss.so debian/tmp/usr/lib/*/xawtv/write-avi.so debian/tmp/usr/lib/*/xawtv/write-dv.so debian/tmp/usr/share/xawtv xawtv-3.106/debian/xawtv-plugins.lintian-overrides000066400000000000000000000002001343350355000223170ustar00rootroot00000000000000pkg-has-shlibs-control-file-but-no-actual-shared-libs postinst-has-useless-call-to-ldconfig postrm-has-useless-call-to-ldconfig xawtv-3.106/debian/xawtv-tools.install000066400000000000000000000004301343350355000200130ustar00rootroot00000000000000debian/tmp/usr/bin/dump-mixers debian/tmp/usr/bin/propwatch debian/tmp/usr/bin/record debian/tmp/usr/bin/showriff debian/tmp/usr/share/man/man1/dump-mixers.1 debian/tmp/usr/share/man/man1/propwatch.1 debian/tmp/usr/share/man/man1/record.1 debian/tmp/usr/share/man/man1/showriff.1 xawtv-3.106/debian/xawtv.NEWS000066400000000000000000000010721343350355000157660ustar00rootroot00000000000000xawtv (3.95.dfsg.1-6) unstable; urgency=low Moved xawtv binary to xawtv.bin and add wrapper to detect and work around graphic cards / drivers without DGA support (idea by Jorge S. de Lis). From now xawtv wrapper try to detect faulty card / driver and if one is found adds -nodga to parameters list. Set XAWTV_USE_DGA to force use of DGA. For (ba)sh: export XAWTV_USE_DGA=yes For (t)csh: set XAWTV_USE_DGA=yes Or use: XAWTV_USE_DGA=yes xawtv -- Krzysztof Burghardt Wed, 26 Sep 2007 00:12:47 +0200 xawtv-3.106/debian/xawtv.config000066400000000000000000000013351343350355000164610ustar00rootroot00000000000000#!/bin/sh -e # debconf lib . /usr/share/debconf/confmodule # init variables mode="$1" mkcfg="true" tvnorm="" freqtab="" doscan="" # build xawtv config? if test -s /etc/X11/xawtvrc; then mkcfg="false" fi if test "$mode" = "reconfigure"; then mkcfg="true" fi if test "$mkcfg" = "true"; then db_input medium xawtv/build-config || true db_go || true db_get xawtv/build-config mkcfg="$RET" fi if test "$mkcfg" = "true"; then # configuration db_input medium xawtv/tvnorm || true db_go || true db_get xawtv/tvnorm tvnorm="$RET" db_input medium xawtv/freqtab || true db_go || true db_get xawtv/freqtab freqtab="$RET" db_input medium xawtv/channel-scan || true db_go || true db_get xawtv/channel-scan doscan="$RET" fi xawtv-3.106/debian/xawtv.desktop000066400000000000000000000002311343350355000166570ustar00rootroot00000000000000[Desktop Entry] Comment=TV viewer for X11 Name=XawTV Exec=xawtv Terminal=false GenericName=XawTV Type=Application Categories=AudioVideo; Icon=xawtv48x48 xawtv-3.106/debian/xawtv.docs000066400000000000000000000000351343350355000161400ustar00rootroot00000000000000README* contrib/frequencies* xawtv-3.106/debian/xawtv.install000066400000000000000000000015511343350355000166620ustar00rootroot00000000000000contrib/xawtv*.xpm usr/share/pixmaps debian/tmp/etc/X11/app-defaults/Xawtv debian/tmp/etc/X11/app-defaults/mtt debian/tmp/usr/bin/mtt debian/tmp/usr/bin/ntsc-cc debian/tmp/usr/bin/rootv debian/tmp/usr/bin/subtitles debian/tmp/usr/bin/v4lctl debian/tmp/usr/bin/xawtv debian/tmp/usr/bin/xawtv-remote debian/tmp/usr/share/man/*/man1/rootv.1 debian/tmp/usr/share/man/*/man1/subtitles.1 debian/tmp/usr/share/man/*/man1/v4lctl.1 debian/tmp/usr/share/man/*/man1/xawtv-remote.1 debian/tmp/usr/share/man/*/man1/xawtv.1 debian/tmp/usr/share/man/*/man5/xawtvrc.5 debian/tmp/usr/share/man/man1/mtt.1 debian/tmp/usr/share/man/man1/ntsc-cc.1 debian/tmp/usr/share/man/man1/rootv.1 debian/tmp/usr/share/man/man1/subtitles.1 debian/tmp/usr/share/man/man1/v4lctl.1 debian/tmp/usr/share/man/man1/xawtv-remote.1 debian/tmp/usr/share/man/man1/xawtv.1 debian/tmp/usr/share/man/man5/xawtvrc.5 xawtv-3.106/debian/xawtv.install.kfreebsd-amd64000066400000000000000000000014121343350355000213530ustar00rootroot00000000000000debian/tmp/usr/bin/xawtv debian/tmp/usr/bin/xawtv-remote debian/tmp/usr/bin/v4lctl debian/tmp/usr/bin/rootv debian/tmp/usr/bin/ntsc-cc debian/tmp/usr/bin/subtitles debian/tmp/usr/share/man/man1/v4lctl.1 debian/tmp/usr/share/man/*/man1/v4lctl.1 debian/tmp/usr/share/man/man1/xawtv.1 debian/tmp/usr/share/man/*/man1/xawtv.1 debian/tmp/usr/share/man/man1/rootv.1 debian/tmp/usr/share/man/*/man1/rootv.1 debian/tmp/usr/share/man/man1/xawtv-remote.1 debian/tmp/usr/share/man/*/man1/xawtv-remote.1 debian/tmp/usr/share/man/man1/ntsc-cc.1 debian/tmp/usr/share/man/man1/subtitles.1 debian/tmp/usr/share/man/*/man1/subtitles.1 debian/tmp/usr/share/man/man5/xawtvrc.5 debian/tmp/usr/share/man/*/man5/xawtvrc.5 debian/tmp/etc/X11/app-defaults/Xawtv contrib/xawtv*.xpm usr/share/pixmaps xawtv-3.106/debian/xawtv.install.kfreebsd-i386000066400000000000000000000014121343350355000211310ustar00rootroot00000000000000debian/tmp/usr/bin/xawtv debian/tmp/usr/bin/xawtv-remote debian/tmp/usr/bin/v4lctl debian/tmp/usr/bin/rootv debian/tmp/usr/bin/ntsc-cc debian/tmp/usr/bin/subtitles debian/tmp/usr/share/man/man1/v4lctl.1 debian/tmp/usr/share/man/*/man1/v4lctl.1 debian/tmp/usr/share/man/man1/xawtv.1 debian/tmp/usr/share/man/*/man1/xawtv.1 debian/tmp/usr/share/man/man1/rootv.1 debian/tmp/usr/share/man/*/man1/rootv.1 debian/tmp/usr/share/man/man1/xawtv-remote.1 debian/tmp/usr/share/man/*/man1/xawtv-remote.1 debian/tmp/usr/share/man/man1/ntsc-cc.1 debian/tmp/usr/share/man/man1/subtitles.1 debian/tmp/usr/share/man/*/man1/subtitles.1 debian/tmp/usr/share/man/man5/xawtvrc.5 debian/tmp/usr/share/man/*/man5/xawtvrc.5 debian/tmp/etc/X11/app-defaults/Xawtv contrib/xawtv*.xpm usr/share/pixmaps xawtv-3.106/debian/xawtv.menu000066400000000000000000000003141343350355000161540ustar00rootroot00000000000000?package(xawtv):needs="x11" section="Applications/TV and Radio" \ title="xawtv" command="/usr/bin/xawtv" \ icon16x16="/usr/share/pixmaps/xawtv16x16.xpm" \ icon32x32="/usr/share/pixmaps/xawtv32x32.xpm" xawtv-3.106/debian/xawtv.postinst000066400000000000000000000016231343350355000170770ustar00rootroot00000000000000#!/bin/sh -e # debconf lib . /usr/share/debconf/confmodule # init variables mode="$1" mkcfg="true" tvnorm="" freqtab="" doscan="" # build xawtv config? if test -s /etc/X11/xawtvrc; then mkcfg="false" fi if test "$mode" = "reconfigure"; then mkcfg="true" fi if test "$mkcfg" = "true"; then db_get xawtv/build-config mkcfg="$RET" fi if test "$mkcfg" = "true"; then # configuration db_get xawtv/tvnorm tvnorm="$RET" db_get xawtv/freqtab freqtab="$RET" db_get xawtv/channel-scan doscan="$RET" # create default config cmd="scantv -n $tvnorm -f $freqtab -o /etc/X11/xawtvrc" if test "$doscan" = "false"; then cmd="$cmd -s" fi # finally, run scantv, catching the error if ! $cmd; then true # TODO: create a new debconf template to show the error fi fi ######################################################### db_stop ######################################################### #DEBHELPER# xawtv-3.106/debian/xawtv.reset000066400000000000000000000002421343350355000163320ustar00rootroot00000000000000#!/bin/sh # debconf lib . /usr/share/debconf/confmodule questions=`grep "^Template:" xawtv.templates | cut -d" " -f2` for q in $questions; do db_reset $q done xawtv-3.106/debian/xawtv.templates000066400000000000000000000030211343350355000172040ustar00rootroot00000000000000# These templates have been reviewed by the debian-l10n-english # team # # If modifications/additions/rewording are needed, please ask # debian-l10n-english@lists.debian.org for advice. # # Even minor modifications require translation updates and such # changes should be coordinated with translators and reviewers. Template: xawtv/makedev Type: boolean Default: true _Description: Create video4linux (/dev/video*) special files? Template: xawtv/channel-scan Type: boolean Default: false _Description: Scan for TV stations? A list of TV stations found by scanning can be included in the configuration file. . This requires a working bttv driver. If bttv isn't configured correctly, TV stations will not be found. . Channel names will be retrieved from teletext information, which will only work for PAL channels. Template: xawtv/tvnorm Type: select Choices: PAL, SECAM, NTSC _Description: TV standard: Template: xawtv/build-config Type: boolean Default: false _Description: Create a default configuration for xawtv? A system-wide configuration file for xawtv can be created with reasonable default values for the local country. . That file is not required but will simplify software configuration for users. Template: xawtv/freqtab Type: select __Choices: us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, europe-east, italy, newzealand, australia, ireland, france, china-bcast _Description: Frequency table to use: A frequency table is a list of TV channel names and numbers with their broadcast frequencies. xawtv-3.106/debug/000077500000000000000000000000001343350355000137635ustar00rootroot00000000000000xawtv-3.106/debug/Subdir.mk000066400000000000000000000003661343350355000155510ustar00rootroot00000000000000 # variables TARGETS-debug := ifeq ($(FOUND_X11),yes) TARGETS-debug += \ debug/xvideo endif debug/xvideo: debug/xvideo.o debug/xvideo : LDLIBS += $(ATHENA_LIBS) # global targets all:: $(TARGETS-debug) distclean:: rm -f $(TARGETS-debug) xawtv-3.106/debug/xvideo.c000066400000000000000000000231471343350355000154340ustar00rootroot00000000000000#include "config.h" #ifndef HAVE_LIBXV #include "stdio.h" int main(void) {puts("Compiled without Xvideo extention support, sorry.");exit(0);} #else /* * this is a simple test app for playing around with the xvideo extention */ #include "config.h" #include #include #include #ifdef HAVE_GETOPT_H # include #endif #include #include #include #include #include #include #include #include #include #define WIDTH_INC 64 #define HEIGHT_INC 48 void CloseMainAction(Widget, XEvent*, String*, Cardinal*); static XtActionsRec actionTable[] = { { "CloseMain", CloseMainAction }, }; int port=-1; GC gc; Atom wm; Widget app_shell,video; /*-------------------------------------------------------------------------*/ void CloseMainAction(Widget widget, XEvent *event, String *params, Cardinal *num_params) { exit(0); } static char *events[] = { "0", "1", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut", "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify", "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest", "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify", "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify", "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify", "ClientMessage", "MappingNotify" }; static void resize_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d) { static int width,height; int wwidth,wheight; Display *dpy = XtDisplay(video); #if 0 Screen *scr = DefaultScreenOfDisplay(dpy); Pixmap pix; #endif switch(event->type) { case ConfigureNotify: wwidth = event->xconfigure.width; wheight = event->xconfigure.height; #if 0 fprintf(stderr,"ConfigureNotify: %dx%d+%d+%d\n", wwidth,wheight,wx,wy); #endif if (width != wwidth || height != wheight) { width = wwidth; height = wheight; fprintf(stderr,"resize: %dx%d\n", width,height); #if 1 XvPutVideo(dpy,port,XtWindow(video),gc, 0,0,width,height,0,0,width,height); #else pix = XCreatePixmap(dpy, RootWindowOfScreen(scr), width, height,DefaultDepthOfScreen(scr)); XvPutStill(dpy,port,pix,gc,0,0,width,height,0,0,width,height); #endif } break; default: fprintf(stderr,"got event: %s (%d)\n", events[event->type],event->type); break; } } /*-------------------------------------------------------------------------*/ XvAdaptorInfo *ai; XvEncodingInfo *ei; XvAttribute *at; XvImageFormatValues *fo; static char *reasons[] = { "XvStarted", "XvStopped", "XvBusy", "XvPreempted", "XvHardError", }; int main(int argc, char *argv[]) { #ifdef HAVE_GETOPT_LONG static struct option long_opts[] = { {"port", 1, 0, 'p'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; #endif XtAppContext app_context; Display *dpy; Atom attr; XVisualInfo *info, template; int found,v; char *class; int ver, rel, req, ev, err, val, c; unsigned int adaptors,encodings,attributes,formats; unsigned int i,ui,p; /* init X11 */ app_shell = XtAppInitialize(&app_context, "xvideo", NULL, 0, &argc, argv, NULL, NULL, 0); dpy = XtDisplay(app_shell); XtAppAddActions(app_context,actionTable, sizeof(actionTable)/sizeof(XtActionsRec)); XtOverrideTranslations(app_shell,XtParseTranslationTable ("WM_PROTOCOLS: CloseMain()")); XtAddEventHandler(app_shell, StructureNotifyMask, True, resize_event, NULL); wm = XInternAtom(XtDisplay(app_shell), "WM_DELETE_WINDOW", False); /* parse options */ for (;;) { #ifdef HAVE_GETOPT_LONG if (-1 == (c = getopt_long(argc, argv, "hp:", long_opts,NULL))) break; #else if (-1 == (c = getopt(argc, argv, "hp:"))) break; #endif switch (c) { case 0: /* long option */ break; case 'p': port = atoi(optarg); break; case 'h': default: fprintf(stderr, "This is a xvideo test application.\n" "Options:\n" " -h | --help this text\n" " -p | --port n create a window and call XvPutVideo\n" " with port >n<\n"); exit(1); } } /* query visuals */ memset(&template,0,sizeof(template)); template.screen = XDefaultScreen(dpy); info = XGetVisualInfo(dpy, VisualScreenMask,&template,&found); /* query+print Xvideo properties */ if (Success != XvQueryExtension(dpy,&ver,&rel,&req,&ev,&err)) { puts("Server does'nt support Xvideo"); exit(1); } if (Success != XvQueryAdaptors(dpy,DefaultRootWindow(dpy),&adaptors,&ai)) { puts("Oops: XvQueryAdaptors failed"); exit(1); } printf("%d adaptors available.\n",adaptors); for (i = 0; i < adaptors; i++) { printf(" name: %s\n" " type: %s%s%s%s%s\n" " ports: %ld\n" " first: %ld\n", ai[i].name, (ai[i].type & XvInputMask) ? "input " : "", (ai[i].type & XvOutputMask) ? "output " : "", (ai[i].type & XvVideoMask) ? "video " : "", (ai[i].type & XvStillMask) ? "still " : "", (ai[i].type & XvImageMask) ? "image " : "", ai[i].num_ports, ai[i].base_id); printf(" format list (n=%ld)\n",ai[i].num_formats); for (ui = 0; ui < ai[i].num_formats; ui++) { printf(" depth=%d, visual: id=0x%lx", ai[i].formats[ui].depth, ai[i].formats[ui].visual_id); for (v = 0; v < found; v++) { if (ai[i].formats[ui].visual_id != info[v].visualid) continue; switch (info[v].class) { case StaticGray: class = "StaticGray"; break; case GrayScale: class = "GrayScale"; break; case StaticColor: class = "StaticColor"; break; case PseudoColor: class = "PseudoColor"; break; case TrueColor: class = "TrueColor"; break; case DirectColor: class = "DirectColor"; break; default: class = "UNKNOWN"; break; } printf(", class=%d (%s)",info[v].class,class); } printf("\n"); } for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) { if (Success != XvQueryEncodings(dpy, p, &encodings, &ei)) { puts("Oops: XvQueryEncodings failed"); continue; } printf(" encoding list for port %d (n=%d)\n",p,encodings); for (ui = 0; ui < encodings; ui++) { printf(" id=%ld, name=%s, size=%ldx%ld\n", ei[ui].encoding_id, ei[ui].name, ei[ui].width, ei[ui].height); } XvFreeEncodingInfo(ei); at = XvQueryPortAttributes(dpy,p,&attributes); printf(" attribute list for port %d (n=%d)\n",p,attributes); for (ui = 0; ui < attributes; ui++) { printf(" %s%s%s, %i -> %i", at[ui].name, (at[ui].flags & XvGettable) ? " get" : "", (at[ui].flags & XvSettable) ? " set" : "", at[ui].min_value,at[ui].max_value); attr = XInternAtom(dpy, at[ui].name, False); if (at[ui].flags & XvGettable) { XvGetPortAttribute(dpy, p, attr, &val); printf(", val=%d",val); } printf("\n"); } if (at) XFree(at); fo = XvListImageFormats(dpy, p, &formats); printf(" image format list for port %d (n=%d)\n",p,formats); for(ui = 0; ui < formats; ui++) { fprintf(stderr, " 0x%x (%c%c%c%c) %s", fo[ui].id, (fo[ui].id) & 0xff, (fo[ui].id >> 8) & 0xff, (fo[ui].id >> 16) & 0xff, (fo[ui].id >> 24) & 0xff, (fo[ui].format == XvPacked) ? "packed" : "planar"); if (fo[ui].type == XvRGB) fprintf(stderr," rgb: depth=%d masks=0x%x/0x%x/0x%x", fo[ui].depth,fo[ui].red_mask,fo[ui].green_mask, fo[ui].blue_mask); if (fo[ui].type == XvYUV) fprintf(stderr," yuv: bits=%d/%d/%d horiz=%d/%d/%d " "vert=%d/%d/%d", fo[ui].y_sample_bits, fo[ui].u_sample_bits, fo[ui].v_sample_bits, fo[ui].horz_y_period, fo[ui].horz_u_period, fo[ui].horz_v_period, fo[ui].vert_y_period, fo[ui].vert_u_period, fo[ui].vert_v_period); fprintf(stderr,"\n"); } if (fo) XFree(fo); } printf("\n"); } if (adaptors > 0) XvFreeAdaptorInfo(ai); if (-1 == port) exit(0); /* open test window */ video = XtVaCreateManagedWidget("video",simpleWidgetClass,app_shell, XtNwidth, 4*WIDTH_INC, XtNheight, 4*HEIGHT_INC, NULL); XtRealizeWidget(app_shell); XtVaSetValues(app_shell, XtNtitle, "Xv test application", XtNwidthInc, WIDTH_INC, XtNheightInc, HEIGHT_INC, XtNminWidth, WIDTH_INC, XtNminHeight, HEIGHT_INC, NULL); XSetWMProtocols(XtDisplay(app_shell), XtWindow(app_shell), &wm, 1); gc = XCreateGC(dpy,XtWindow(video),0,NULL); /* receive events */ XvSelectPortNotify(dpy, port, 1); XvSelectVideoNotify(dpy, XtWindow(video), 1); /* main loop */ for (;;) { XEvent event; XtAppNextEvent(app_context,&event); if (XtDispatchEvent(&event)) continue; switch (event.type-ev) { case XvVideoNotify: { XvVideoNotifyEvent *xve = (XvVideoNotifyEvent*)&event; fprintf(stderr,"XvVideoNotify, reason=%s\n", reasons[xve->reason]); break; } case XvPortNotify: { XvPortNotifyEvent *xpe = (XvPortNotifyEvent*)&event; fprintf(stderr,"XvPortNotify: %s=%ld\n", XGetAtomName(dpy,xpe->attribute),xpe->value); break; } } } /* keep compiler happy */ exit(0); } #endif xawtv-3.106/frequencies/000077500000000000000000000000001343350355000152065ustar00rootroot00000000000000xawtv-3.106/frequencies/Index.map000066400000000000000000000014301343350355000167520ustar00rootroot00000000000000[us-bcast] file = ntsc-bcast.list [us-cable] file = ntsc-cable.list [us-cable-hrc] file = ntsc-hrc.list [japan-bcast] file = ntsc-bcast-jp.list [japan-cable] file = ntsc-cable-jp.list [europe-west] file = europe-west.list [europe-east] file = europe-east.list [italy] file = pal-italy.list [newzealand] file = pal-newzealand.list [australia] file = pal-australia.list [ireland] file = pal-ireland.list [france] file = secam-france.list [china-bcast] file = pal-bcast-cn.list [southafrica] file = pal-bcast-za.list [argentina] file = argentina.list # canada + us use the same tables, likely this just works due # to a broken tuner configuration ... #[canada-cable] #file = ntsc-cable-ca.list [australia-optus] file = pal-australia-optus.list [russia] file = secam-russia.list xawtv-3.106/frequencies/README000066400000000000000000000016101343350355000160640ustar00rootroot00000000000000 About adding new lists here ... (1) Check that there isn't already a list which works for you. Often the same frequency lists are used in multiple countries, so you can try if one of some other country near to you works. (2) A reason for tuning not working (or not fully working, i.e. fails for some frequency ranges) also might be that the tuner configuration of the device driver isn't correct. Try to fix your setup first instead of trying to create a new list which is bug-compatible to your broken setup. (3) There are some lists for common stuff. The UHF channels are in uhf.list for example. You can simply #include these. That will save you some typing work and also makes the lists more readable. (4) Giving some reference (URL to your cable provider for example) for the new list highly increases the chance of getting this included. xawtv-3.106/frequencies/Subdir.mk000066400000000000000000000003221343350355000167640ustar00rootroot00000000000000 FILES-frequencies := \ $(srcdir)/frequencies/Index.map \ $(wildcard $(srcdir)/frequencies/*.list) install:: $(FILES-frequencies) $(INSTALL_DIR) $(datadir) $(INSTALL_DATA) $(FILES-frequencies) $(datadir) xawtv-3.106/frequencies/argentina.list000066400000000000000000000036341343350355000200610ustar00rootroot00000000000000[001] freq = 56250 [002] freq = 62250 [003] freq = 68250 [004] freq = 78250 [005] freq = 84250 [006] freq = 176250 [007] freq = 182250 [008] freq = 188250 [009] freq = 194250 [010] freq = 200250 [011] freq = 206250 [012] freq = 212250 [013] freq = 122250 [014] freq = 128250 [015] freq = 134250 [016] freq = 140250 [017] freq = 146250 [018] freq = 152250 [019] freq = 158250 [020] freq = 164250 [021] freq = 170250 [022] freq = 218250 [023] freq = 224250 [024] freq = 230250 [025] freq = 236250 [026] freq = 242250 [027] freq = 248250 [028] freq = 254250 [029] freq = 260250 [030] freq = 266250 [031] freq = 272250 [032] freq = 278250 [033] freq = 284250 [034] freq = 290250 [035] freq = 296250 [036] freq = 302250 [037] freq = 308250 [038] freq = 314250 [039] freq = 320250 [040] freq = 326250 [041] freq = 332250 [042] freq = 338250 [043] freq = 344250 [044] freq = 350250 [045] freq = 356250 [046] freq = 362250 [047] freq = 368250 [048] freq = 374250 [049] freq = 380250 [050] freq = 386250 [051] freq = 392250 [052] freq = 398250 [053] freq = 404250 [054] freq = 410250 [055] freq = 416250 [056] freq = 422250 [057] freq = 428250 [058] freq = 434250 [059] freq = 440250 [060] freq = 446250 [061] freq = 452250 [062] freq = 458250 [063] freq = 464250 [064] freq = 470250 [065] freq = 476250 [066] freq = 482250 [067] freq = 488250 [068] freq = 494250 [069] freq = 500250 [070] freq = 506250 [071] freq = 512250 [072] freq = 518250 [073] freq = 524250 [074] freq = 530250 [075] freq = 536250 [076] freq = 542250 [077] freq = 548250 [078] freq = 554250 [079] freq = 560250 [080] freq = 566250 [081] freq = 572250 [082] freq = 578250 [083] freq = 584250 [084] freq = 590250 [085] freq = 596250 [086] freq = 602250 [087] freq = 608250 [088] freq = 614250 [089] freq = 620250 [090] freq = 626250 [091] freq = 632250 [092] freq = 638250 [093] freq = 644250 xawtv-3.106/frequencies/backup/000077500000000000000000000000001343350355000164535ustar00rootroot00000000000000xawtv-3.106/frequencies/backup/pal-bcast-cn.list000066400000000000000000000035121343350355000216150ustar00rootroot00000000000000[1] freq = 49750 [2] freq = 57750 [3] freq = 65750 [4] freq = 77250 [5] freq = 85250 [6] freq = 112250 [7] freq = 120250 [8] freq = 128250 [9] freq = 136250 [10] freq = 144250 [11] freq = 152250 [12] freq = 160250 [13] freq = 168250 [14] freq = 176250 [15] freq = 184250 [16] freq = 192250 [17] freq = 200250 [18] freq = 208250 [19] freq = 216250 [20] freq = 224250 [21] freq = 232250 [22] freq = 240250 [23] freq = 248250 [24] freq = 256250 [25] freq = 264250 [26] freq = 272250 [27] freq = 280250 [28] freq = 288250 [29] freq = 296250 [30] freq = 304250 [31] freq = 312250 [32] freq = 320250 [33] freq = 328250 [34] freq = 336250 [35] freq = 344250 [36] freq = 352250 [37] freq = 360250 [38] freq = 368250 [39] freq = 376250 [40] freq = 384250 [41] freq = 392250 [42] freq = 400250 [43] freq = 408250 [44] freq = 416250 [45] freq = 424250 [46] freq = 432250 [47] freq = 440250 [48] freq = 448250 [49] freq = 456250 [50] freq = 463250 [51] freq = 471250 [52] freq = 479250 [53] freq = 487250 [54] freq = 495250 [55] freq = 503250 [56] freq = 511250 [57] freq = 519250 [58] freq = 527250 [59] freq = 535250 [60] freq = 543250 [61] freq = 551250 [62] freq = 559250 [63] freq = 607250 [64] freq = 615250 [65] freq = 623250 [66] freq = 631250 [67] freq = 639250 [68] freq = 647250 [69] freq = 655250 [70] freq = 663250 [71] freq = 671250 [72] freq = 679250 [73] freq = 687250 [74] freq = 695250 [75] freq = 703250 [76] freq = 711250 [77] freq = 719250 [78] freq = 727250 [79] freq = 735250 [80] freq = 743250 [81] freq = 751250 [82] freq = 759250 [83] freq = 767250 [84] freq = 775250 [85] freq = 783250 [86] freq = 791250 [87] freq = 799250 [88] freq = 807250 [89] freq = 815250 [90] freq = 823250 [91] freq = 831250 [92] freq = 839250 [93] freq = 847250 [94] freq = 855250 xawtv-3.106/frequencies/ccir-h.list000066400000000000000000000006711343350355000172540ustar00rootroot00000000000000[S21] freq = 303250 [S22] freq = 311250 [S23] freq = 319250 [S24] freq = 327250 [S25] freq = 335250 [S26] freq = 343250 [S27] freq = 351250 [S28] freq = 359250 [S29] freq = 367250 [S30] freq = 375250 [S31] freq = 383250 [S32] freq = 391250 [S33] freq = 399250 [S34] freq = 407250 [S35] freq = 415250 [S36] freq = 423250 [S37] freq = 431250 [S38] freq = 439250 [S39] freq = 447250 [S40] freq = 455250 [S41] freq = 463250 xawtv-3.106/frequencies/ccir-i-iii.list000066400000000000000000000004301343350355000200160ustar00rootroot00000000000000[E2] freq = 48250 [E3] freq = 55250 [E4] freq = 62250 [S01] freq = 69250 [S02] freq = 76250 [S03] freq = 83250 [E5] freq = 175250 [E6] freq = 182250 [E7] freq = 189250 [E8] freq = 196250 [E9] freq = 203250 [E10] freq = 210250 [E11] freq = 217250 [E12] freq = 224250 xawtv-3.106/frequencies/ccir-sl-sh.list000066400000000000000000000006571343350355000200570ustar00rootroot00000000000000[SE1] freq = 105250 [SE2] freq = 112250 [SE3] freq = 119250 [SE4] freq = 126250 [SE5] freq = 133250 [SE6] freq = 140250 [SE7] freq = 147250 [SE8] freq = 154250 [SE9] freq = 161250 [SE10] freq = 168250 [SE11] freq = 231250 [SE12] freq = 238250 [SE13] freq = 245250 [SE14] freq = 252250 [SE15] freq = 259250 [SE16] freq = 266250 [SE17] freq = 273250 [SE18] freq = 280250 [SE19] freq = 287250 [SE20] freq = 294250 xawtv-3.106/frequencies/europe-east.list000066400000000000000000000002271343350355000203350ustar00rootroot00000000000000#include "oirt-i-iii.list" #include "oirt-sl-sh.list" #include "ccir-i-iii.list" #include "ccir-sl-sh.list" #include "ccir-h.list" #include "uhf.list" xawtv-3.106/frequencies/europe-west.list000066400000000000000000000001411343350355000203560ustar00rootroot00000000000000#include "ccir-i-iii.list" #include "ccir-sl-sh.list" #include "ccir-h.list" #include "uhf.list" xawtv-3.106/frequencies/init.pl000066400000000000000000000022421343350355000165060ustar00rootroot00000000000000#!/usr/bin/perl use strict; sub fix_filename ($) { my $name = shift @_; $name =~ tr/_A-Z/-a-z/; $name =~ s/^freq-//; $name .= ".list"; return $name; } my ($name,$filename); while (<>) { # channel lists if (m/\{\s*\"(\w+)\",\s*(\w+)\s*\}/) { print FILE "[$1]\n"; print FILE "freq = $2\n"; print FILE "\n"; next; } if (m/static struct CHANLIST (\w+)/) { $filename = fix_filename($1); close FILE; open FILE, "> $filename" or die "open $filename: $!"; next; } if (m/\#define (FREQ_\w+)/) { $filename = fix_filename($1); close FILE; open FILE, "> $filename" or die "open $filename: $!"; next; } if (m/^\s+(FREQ_\w+)/) { $filename = fix_filename($1); print FILE "#include \"$filename\"\n"; next; } # index file if (m/struct CHANLISTS chanlists/) { close FILE; open FILE, "> Index.map" or die "open Index.map: $!"; } if (m/\{\s*\"([-a-zA-Z]+)\",\s+(\w+)/) { $name = $1; $filename = fix_filename($2); print FILE "[$name]\n"; print FILE "file = $filename\n"; print FILE "\n"; next; } next if m/\#include/; next if m/^\/\*/; next if m/^\s*};/; next if m/^\s*$/; next if m/^\s*\\\s*$/; print "Oops: $_"; } close FILE; xawtv-3.106/frequencies/ntsc-bcast-jp.list000066400000000000000000000023151343350355000205540ustar00rootroot00000000000000[1] freq = 91250 [2] freq = 97250 [3] freq = 103250 [4] freq = 171250 [5] freq = 177250 [6] freq = 183250 [7] freq = 189250 [8] freq = 193250 [9] freq = 199250 [10] freq = 205250 [11] freq = 211250 [12] freq = 217250 [13] freq = 471250 [14] freq = 477250 [15] freq = 483250 [16] freq = 489250 [17] freq = 495250 [18] freq = 501250 [19] freq = 507250 [20] freq = 513250 [21] freq = 519250 [22] freq = 525250 [23] freq = 531250 [24] freq = 537250 [25] freq = 543250 [26] freq = 549250 [27] freq = 555250 [28] freq = 561250 [29] freq = 567250 [30] freq = 573250 [31] freq = 579250 [32] freq = 585250 [33] freq = 591250 [34] freq = 597250 [35] freq = 603250 [36] freq = 609250 [37] freq = 615250 [38] freq = 621250 [39] freq = 627250 [40] freq = 633250 [41] freq = 639250 [42] freq = 645250 [43] freq = 651250 [44] freq = 657250 [45] freq = 663250 [46] freq = 669250 [47] freq = 675250 [48] freq = 681250 [49] freq = 687250 [50] freq = 693250 [51] freq = 699250 [52] freq = 705250 [53] freq = 711250 [54] freq = 717250 [55] freq = 723250 [56] freq = 729250 [57] freq = 735250 [58] freq = 741250 [59] freq = 747250 [60] freq = 753250 [61] freq = 759250 [62] freq = 765250 xawtv-3.106/frequencies/ntsc-bcast.list000066400000000000000000000031331343350355000201440ustar00rootroot00000000000000[2] freq = 55250 [3] freq = 61250 [4] freq = 67250 [5] freq = 77250 [6] freq = 83250 [7] freq = 175250 [8] freq = 181250 [9] freq = 187250 [10] freq = 193250 [11] freq = 199250 [12] freq = 205250 [13] freq = 211250 [14] freq = 471250 [15] freq = 477250 [16] freq = 483250 [17] freq = 489250 [18] freq = 495250 [19] freq = 501250 [20] freq = 507250 [21] freq = 513250 [22] freq = 519250 [23] freq = 525250 [24] freq = 531250 [25] freq = 537250 [26] freq = 543250 [27] freq = 549250 [28] freq = 555250 [29] freq = 561250 [30] freq = 567250 [31] freq = 573250 [32] freq = 579250 [33] freq = 585250 [34] freq = 591250 [35] freq = 597250 [36] freq = 603250 [37] freq = 609250 [38] freq = 615250 [39] freq = 621250 [40] freq = 627250 [41] freq = 633250 [42] freq = 639250 [43] freq = 645250 [44] freq = 651250 [45] freq = 657250 [46] freq = 663250 [47] freq = 669250 [48] freq = 675250 [49] freq = 681250 [50] freq = 687250 [51] freq = 693250 [52] freq = 699250 [53] freq = 705250 [54] freq = 711250 [55] freq = 717250 [56] freq = 723250 [57] freq = 729250 [58] freq = 735250 [59] freq = 741250 [60] freq = 747250 [61] freq = 753250 [62] freq = 759250 [63] freq = 765250 [64] freq = 771250 [65] freq = 777250 [66] freq = 783250 [67] freq = 789250 [68] freq = 795250 [69] freq = 801250 [70] freq = 807250 [71] freq = 813250 [72] freq = 819250 [73] freq = 825250 [74] freq = 831250 [75] freq = 837250 [76] freq = 843250 [77] freq = 849250 [78] freq = 855250 [79] freq = 861250 [80] freq = 867250 [81] freq = 873250 [82] freq = 879250 [83] freq = 885250 xawtv-3.106/frequencies/ntsc-cable-ca.list000066400000000000000000000046741343350355000205120ustar00rootroot00000000000000[2] freq = 61750 [3] freq = 67750 [4] freq = 73750 [5] freq = 83750 [6] freq = 89750 [7] freq = 181750 [8] freq = 187750 [9] freq = 193750 [10] freq = 199750 [11] freq = 205750 [12] freq = 211750 [13] freq = 217750 [14] freq = 127750 [15] freq = 133750 [16] freq = 139750 [17] freq = 145750 [18] freq = 151750 [19] freq = 157750 [20] freq = 163750 [21] freq = 169750 [22] freq = 175750 [23] freq = 223750 [24] freq = 229750 [25] freq = 235750 [26] freq = 241750 [27] freq = 247750 [28] freq = 253750 [29] freq = 259750 [30] freq = 265750 [31] freq = 271750 [32] freq = 277750 [33] freq = 283750 [34] freq = 289750 [35] freq = 295750 [36] freq = 301750 [37] freq = 307750 [38] freq = 313750 [39] freq = 319750 [40] freq = 325750 [41] freq = 331750 [42] freq = 337750 [43] freq = 343750 [44] freq = 349750 [45] freq = 355750 [46] freq = 361750 [47] freq = 367750 [48] freq = 373750 [49] freq = 379750 [50] freq = 385750 [51] freq = 391750 [52] freq = 397750 [53] freq = 403750 [54] freq = 409750 [55] freq = 415750 [56] freq = 421750 [57] freq = 427750 [58] freq = 433750 [59] freq = 439750 [60] freq = 445750 [61] freq = 451750 [62] freq = 457750 [63] freq = 463750 [64] freq = 469750 [65] freq = 475750 [66] freq = 481750 [67] freq = 487750 [68] freq = 493750 [69] freq = 499750 [70] freq = 505750 [71] freq = 511750 [72] freq = 517750 [73] freq = 523750 [74] freq = 529750 [75] freq = 535750 [76] freq = 541750 [77] freq = 547750 [78] freq = 553750 [79] freq = 559750 [80] freq = 565750 [81] freq = 571750 [82] freq = 577750 [83] freq = 583750 [84] freq = 589750 [85] freq = 595750 [86] freq = 601750 [87] freq = 607750 [88] freq = 613750 [89] freq = 619750 [90] freq = 625750 [91] freq = 631750 [92] freq = 637750 [93] freq = 643750 [94] freq = 649750 [95] freq = 97750 [96] freq = 103750 [97] freq = 109750 [98] freq = 115750 [99] freq = 121750 [100] freq = 655750 [101] freq = 661750 [102] freq = 667750 [103] freq = 673750 [104] freq = 679750 [105] freq = 685750 [106] freq = 691750 [107] freq = 697750 [108] freq = 703750 [109] freq = 709750 [110] freq = 715750 [111] freq = 721750 [112] freq = 727750 [113] freq = 733750 [114] freq = 739750 [115] freq = 745750 [116] freq = 751750 [117] freq = 757750 [118] freq = 763750 [119] freq = 769750 [120] freq = 775750 [121] freq = 781750 [122] freq = 787750 [123] freq = 793750 [124] freq = 799750 [125] freq = 805750 xawtv-3.106/frequencies/ntsc-cable-jp.list000066400000000000000000000017741343350355000205360ustar00rootroot00000000000000[13] freq = 109250 [14] freq = 115250 [15] freq = 121250 [16] freq = 127250 [17] freq = 133250 [18] freq = 139250 [19] freq = 145250 [20] freq = 151250 [21] freq = 157250 [22] freq = 165250 [23] freq = 223250 [24] freq = 231250 [25] freq = 237250 [26] freq = 243250 [27] freq = 249250 [28] freq = 253250 [29] freq = 259250 [30] freq = 265250 [31] freq = 271250 [32] freq = 277250 [33] freq = 283250 [34] freq = 289250 [35] freq = 295250 [36] freq = 301250 [37] freq = 307250 [38] freq = 313250 [39] freq = 319250 [40] freq = 325250 [41] freq = 331250 [42] freq = 337250 [43] freq = 343250 [44] freq = 349250 [45] freq = 355250 [46] freq = 361250 [47] freq = 367250 [48] freq = 373250 [49] freq = 379250 [50] freq = 385250 [51] freq = 391250 [52] freq = 397250 [53] freq = 403250 [54] freq = 409250 [55] freq = 415250 [56] freq = 421250 [57] freq = 427250 [58] freq = 433250 [59] freq = 439250 [60] freq = 445250 [61] freq = 451250 [62] freq = 457250 [63] freq = 463250 xawtv-3.106/frequencies/ntsc-cable.list000066400000000000000000000051511343350355000201200ustar00rootroot00000000000000[1] freq = 73250 [2] freq = 55250 [3] freq = 61250 [4] freq = 67250 [5] freq = 77250 [6] freq = 83250 [7] freq = 175250 [8] freq = 181250 [9] freq = 187250 [10] freq = 193250 [11] freq = 199250 [12] freq = 205250 [13] freq = 211250 [14] freq = 121250 [15] freq = 127250 [16] freq = 133250 [17] freq = 139250 [18] freq = 145250 [19] freq = 151250 [20] freq = 157250 [21] freq = 163250 [22] freq = 169250 [23] freq = 217250 [24] freq = 223250 [25] freq = 229250 [26] freq = 235250 [27] freq = 241250 [28] freq = 247250 [29] freq = 253250 [30] freq = 259250 [31] freq = 265250 [32] freq = 271250 [33] freq = 277250 [34] freq = 283250 [35] freq = 289250 [36] freq = 295250 [37] freq = 301250 [38] freq = 307250 [39] freq = 313250 [40] freq = 319250 [41] freq = 325250 [42] freq = 331250 [43] freq = 337250 [44] freq = 343250 [45] freq = 349250 [46] freq = 355250 [47] freq = 361250 [48] freq = 367250 [49] freq = 373250 [50] freq = 379250 [51] freq = 385250 [52] freq = 391250 [53] freq = 397250 [54] freq = 403250 [55] freq = 409250 [56] freq = 415250 [57] freq = 421250 [58] freq = 427250 [59] freq = 433250 [60] freq = 439250 [61] freq = 445250 [62] freq = 451250 [63] freq = 457250 [64] freq = 463250 [65] freq = 469250 [66] freq = 475250 [67] freq = 481250 [68] freq = 487250 [69] freq = 493250 [70] freq = 499250 [71] freq = 505250 [72] freq = 511250 [73] freq = 517250 [74] freq = 523250 [75] freq = 529250 [76] freq = 535250 [77] freq = 541250 [78] freq = 547250 [79] freq = 553250 [80] freq = 559250 [81] freq = 565250 [82] freq = 571250 [83] freq = 577250 [84] freq = 583250 [85] freq = 589250 [86] freq = 595250 [87] freq = 601250 [88] freq = 607250 [89] freq = 613250 [90] freq = 619250 [91] freq = 625250 [92] freq = 631250 [93] freq = 637250 [94] freq = 643250 [95] freq = 91250 [96] freq = 97250 [97] freq = 103250 [98] freq = 109250 [99] freq = 115250 [100] freq = 649250 [101] freq = 655250 [102] freq = 661250 [103] freq = 667250 [104] freq = 673250 [105] freq = 679250 [106] freq = 685250 [107] freq = 691250 [108] freq = 697250 [109] freq = 703250 [110] freq = 709250 [111] freq = 715250 [112] freq = 721250 [113] freq = 727250 [114] freq = 733250 [115] freq = 739250 [116] freq = 745250 [117] freq = 751250 [118] freq = 757250 [119] freq = 763250 [120] freq = 769250 [121] freq = 775250 [122] freq = 781250 [123] freq = 787250 [124] freq = 793250 [125] freq = 799250 [T7] freq = 8250 [T8] freq = 14250 [T9] freq = 20250 [T10] freq = 26250 [T11] freq = 32250 [T12] freq = 38250 [T13] freq = 44250 [T14] freq = 50250 xawtv-3.106/frequencies/ntsc-hrc.list000066400000000000000000000051531343350355000176300ustar00rootroot00000000000000[1] freq = 72000 [2] freq = 54000 [3] freq = 60000 [4] freq = 66000 [5] freq = 78000 [6] freq = 84000 [7] freq = 174000 [8] freq = 180000 [9] freq = 186000 [10] freq = 192000 [11] freq = 198000 [12] freq = 204000 [13] freq = 210000 [14] freq = 120000 [15] freq = 126000 [16] freq = 132000 [17] freq = 138000 [18] freq = 144000 [19] freq = 150000 [20] freq = 156000 [21] freq = 162000 [22] freq = 168000 [23] freq = 216000 [24] freq = 222000 [25] freq = 228000 [26] freq = 234000 [27] freq = 240000 [28] freq = 246000 [29] freq = 252000 [30] freq = 258000 [31] freq = 264000 [32] freq = 270000 [33] freq = 276000 [34] freq = 282000 [35] freq = 288000 [36] freq = 294000 [37] freq = 300000 [38] freq = 306000 [39] freq = 312000 [40] freq = 318000 [41] freq = 324000 [42] freq = 330000 [43] freq = 336000 [44] freq = 342000 [45] freq = 348000 [46] freq = 354000 [47] freq = 360000 [48] freq = 366000 [49] freq = 372000 [50] freq = 378000 [51] freq = 384000 [52] freq = 390000 [53] freq = 396000 [54] freq = 402000 [55] freq = 408000 [56] freq = 414000 [57] freq = 420000 [58] freq = 426000 [59] freq = 432000 [60] freq = 438000 [61] freq = 444000 [62] freq = 450000 [63] freq = 456000 [64] freq = 462000 [65] freq = 468000 [66] freq = 474000 [67] freq = 480000 [68] freq = 486000 [69] freq = 492000 [70] freq = 498000 [71] freq = 504000 [72] freq = 510000 [73] freq = 516000 [74] freq = 522000 [75] freq = 528000 [76] freq = 534000 [77] freq = 540000 [78] freq = 546000 [79] freq = 552000 [80] freq = 558000 [81] freq = 564000 [82] freq = 570000 [83] freq = 576000 [84] freq = 582000 [85] freq = 588000 [86] freq = 594000 [87] freq = 600000 [88] freq = 606000 [89] freq = 612000 [90] freq = 618000 [91] freq = 624000 [92] freq = 630000 [93] freq = 636000 [94] freq = 642000 [95] freq = 900000 [96] freq = 960000 [97] freq = 102000 [98] freq = 108000 [99] freq = 114000 [100] freq = 648000 [101] freq = 654000 [102] freq = 660000 [103] freq = 666000 [104] freq = 672000 [105] freq = 678000 [106] freq = 684000 [107] freq = 690000 [108] freq = 696000 [109] freq = 702000 [110] freq = 708000 [111] freq = 714000 [112] freq = 720000 [113] freq = 726000 [114] freq = 732000 [115] freq = 738000 [116] freq = 744000 [117] freq = 750000 [118] freq = 756000 [119] freq = 762000 [120] freq = 768000 [121] freq = 774000 [122] freq = 780000 [123] freq = 786000 [124] freq = 792000 [125] freq = 798000 [T7] freq = 7000 [T8] freq = 13000 [T9] freq = 19000 [T10] freq = 25000 [T11] freq = 31000 [T12] freq = 37000 [T13] freq = 43000 [T14] freq = 49000 xawtv-3.106/frequencies/oirt-h.list000066400000000000000000000007151343350355000173100ustar00rootroot00000000000000[S19] freq = 295250 [S20] freq = 303250 [S21] freq = 311250 [S22] freq = 319250 [S23] freq = 327250 [S24] freq = 335250 [S25] freq = 343250 [S26] freq = 351250 [S27] freq = 359250 [S28] freq = 367250 [S29] freq = 375250 [S30] freq = 383250 [S31] freq = 391250 [S32] freq = 399250 [S33] freq = 407250 [S34] freq = 415250 [S35] freq = 423250 [S36] freq = 431250 [S37] freq = 439250 [S38] freq = 447250 [S39] freq = 455250 [S40] freq = 463250 xawtv-3.106/frequencies/oirt-i-iii.list000066400000000000000000000003561343350355000200620ustar00rootroot00000000000000[R1] freq = 49750 [R2] freq = 59250 [R3] freq = 77250 [R4] freq = 85250 [R5] freq = 93250 [R6] freq = 175250 [R7] freq = 183250 [R8] freq = 191250 [R9] freq = 199250 [R10] freq = 207250 [R11] freq = 215250 [R12] freq = 223250 xawtv-3.106/frequencies/oirt-sl-sh.list000066400000000000000000000005271343350355000201100ustar00rootroot00000000000000[SR1] freq = 111250 [SR2] freq = 119250 [SR3] freq = 127250 [SR4] freq = 135250 [SR5] freq = 143250 [SR6] freq = 151250 [SR7] freq = 159250 [SR8] freq = 167250 [SR11] freq = 231250 [SR12] freq = 239250 [SR13] freq = 247250 [SR14] freq = 255250 [SR15] freq = 263250 [SR16] freq = 271250 [SR17] freq = 279250 [SR18] freq = 287250 xawtv-3.106/frequencies/pal-australia-optus.list000066400000000000000000000016671343350355000220240ustar00rootroot00000000000000[1] freq = 138250 [2] freq = 147250 [3] freq = 154250 [4] freq = 161250 [5] freq = 168250 [6] freq = 175250 [7] freq = 182250 [8] freq = 189250 [9] freq = 196250 [10] freq = 209250 [11] freq = 216250 [12] freq = 224250 [13] freq = 231250 [14] freq = 238250 [15] freq = 245250 [16] freq = 252250 [17] freq = 259250 [18] freq = 266250 [19] freq = 273250 [20] freq = 280250 [21] freq = 287250 [22] freq = 294250 [23] freq = 303250 [24] freq = 310250 [25] freq = 317250 [26] freq = 324250 [27] freq = 338250 [28] freq = 345250 [29] freq = 352250 [30] freq = 359250 [31] freq = 366250 [32] freq = 373250 [33] freq = 380250 [34] freq = 387250 [35] freq = 394250 [36] freq = 401250 [37] freq = 408250 [38] freq = 415250 [39] freq = 422250 [40] freq = 429250 [41] freq = 436250 [42] freq = 443250 [43] freq = 450250 [44] freq = 457250 [45] freq = 464250 [46] freq = 471250 [47] freq = 478250 [48] freq = 485250 xawtv-3.106/frequencies/pal-australia.list000066400000000000000000000020751343350355000206460ustar00rootroot00000000000000[0] freq = 46250 [1] freq = 57250 [2] freq = 64250 [3] freq = 86250 [4] freq = 95250 [5] freq = 102250 [5A] freq = 138250 [6] freq = 175250 [7] freq = 182250 [8] freq = 189250 [9] freq = 196250 [10] freq = 209250 [11] freq = 216250 [28] freq = 527250 [29] freq = 534250 [30] freq = 541250 [31] freq = 548250 [32] freq = 555250 [33] freq = 562250 [34] freq = 569250 [35] freq = 576250 [36] freq = 583250 [37] freq = 590250 [38] freq = 597250 [39] freq = 604250 [40] freq = 611250 [41] freq = 618250 [42] freq = 625250 [43] freq = 632250 [44] freq = 639250 [45] freq = 646250 [46] freq = 653250 [47] freq = 660250 [48] freq = 667250 [49] freq = 674250 [50] freq = 681250 [51] freq = 688250 [52] freq = 695250 [53] freq = 702250 [54] freq = 709250 [55] freq = 716250 [56] freq = 723250 [57] freq = 730250 [58] freq = 737250 [59] freq = 744250 [60] freq = 751250 [61] freq = 758250 [62] freq = 765250 [63] freq = 772250 [64] freq = 779250 [65] freq = 786250 [66] freq = 793250 [67] freq = 800250 [68] freq = 807250 [69] freq = 814250 xawtv-3.106/frequencies/pal-bcast-cn.list000066400000000000000000000042641343350355000203550ustar00rootroot00000000000000[1] freq = 49750 [2] freq = 57750 [3] freq = 65750 [4] freq = 77250 [5] freq = 85250 [6] freq = 168250 [7] freq = 176250 [8] freq = 184250 [9] freq = 192250 [10] freq = 200250 [11] freq = 208250 [12] freq = 216250 [13] freq = 471250 [14] freq = 479250 [15] freq = 487250 [16] freq = 495250 [17] freq = 503250 [18] freq = 511250 [19] freq = 519250 [20] freq = 527250 [21] freq = 535250 [22] freq = 543250 [23] freq = 551250 [24] freq = 559250 [25] freq = 607250 [26] freq = 615250 [27] freq = 623250 [28] freq = 631250 [29] freq = 639250 [30] freq = 647250 [31] freq = 655250 [32] freq = 663250 [33] freq = 671250 [34] freq = 679250 [35] freq = 687250 [36] freq = 695250 [37] freq = 703250 [38] freq = 711250 [39] freq = 719250 [40] freq = 727250 [41] freq = 735250 [42] freq = 743250 [43] freq = 751250 [44] freq = 759250 [45] freq = 767250 [46] freq = 775250 [47] freq = 783250 [48] freq = 791250 [49] freq = 799250 [50] freq = 807250 [51] freq = 815250 [52] freq = 823250 [53] freq = 831250 [54] freq = 839250 [55] freq = 847250 [56] freq = 855250 [57] freq = 863250 [58] freq = 871250 [59] freq = 879250 [60] freq = 887250 [61] freq = 895250 [62] freq = 903250 [63] freq = 911250 [64] freq = 919250 [65] freq = 927250 [66] freq = 935250 [67] freq = 943250 [68] freq = 951250 [A1] freq = 112250 [A2] freq = 120250 [A3] freq = 128250 [A4] freq = 136250 [A5] freq = 144250 [A6] freq = 152250 [A7] freq = 160250 [B1] freq = 224250 [B2] freq = 232250 [B3] freq = 240250 [B4] freq = 248250 [B5] freq = 256250 [B6] freq = 264250 [B7] freq = 272250 [B8] freq = 280250 [B9] freq = 288250 [B10] freq = 296250 [B11] freq = 304250 [B12] freq = 312250 [B13] freq = 320250 [B14] freq = 328250 [B15] freq = 336250 [B16] freq = 344250 [B17] freq = 352250 [B18] freq = 360250 [B19] freq = 368250 [B20] freq = 376250 [B21] freq = 384250 [B22] freq = 392250 [B23] freq = 400250 [B24] freq = 408250 [B25] freq = 416250 [B26] freq = 424250 [B27] freq = 432250 [B28] freq = 440250 [B29] freq = 448250 [B30] freq = 456250 [B31] freq = 463250 [C1] freq = 567250 [C2] freq = 575250 [C3] freq = 583250 [C4] freq = 591250 [C5] freq = 599250 xawtv-3.106/frequencies/pal-bcast-za.list000066400000000000000000000004171343350355000203630ustar00rootroot00000000000000[1] freq = 175250 [2] freq = 183250 [3] freq = 191250 [4] freq = 199250 [5] freq = 207250 [6] freq = 215250 [7] freq = 223250 [8] freq = 231250 [9] freq = 239250 [10] freq = 247250 [11] freq = 255250 [12] freq = 263250 [13] freq = 271250 #include "uhf.list" xawtv-3.106/frequencies/pal-ireland.list000066400000000000000000000014151343350355000202740ustar00rootroot00000000000000[A0] freq = 45750 [A1] freq = 48000 [A2] freq = 53750 [A3] freq = 56000 [A4] freq = 61750 [A5] freq = 64000 [A6] freq = 175250 [A7] freq = 176000 [A8] freq = 183250 [A9] freq = 184000 [A10] freq = 191250 [A11] freq = 192000 [A12] freq = 199250 [A13] freq = 200000 [A14] freq = 207250 [A15] freq = 208000 [A16] freq = 215250 [A17] freq = 216000 [A18] freq = 224000 [A19] freq = 232000 [A20] freq = 248000 [A21] freq = 256000 [A22] freq = 264000 [A23] freq = 272000 [A24] freq = 280000 [A25] freq = 288000 [A26] freq = 296000 [A27] freq = 304000 [A28] freq = 312000 [A29] freq = 320000 [A30] freq = 344000 [A31] freq = 352000 [A32] freq = 408000 [A33] freq = 416000 [A34] freq = 448000 [A35] freq = 480000 [A36] freq = 520000 #include "uhf.list" xawtv-3.106/frequencies/pal-italy.list000066400000000000000000000003211343350355000177730ustar00rootroot00000000000000[A] freq = 53750 [B] freq = 62250 [C] freq = 82250 [D] freq = 175250 [E] freq = 183750 [F] freq = 192250 [G] freq = 201250 [H] freq = 210250 [H1] freq = 217250 [H2] freq = 224250 #include "uhf.list" xawtv-3.106/frequencies/pal-newzealand.list000066400000000000000000000003441343350355000210060ustar00rootroot00000000000000[1] freq = 45250 [2] freq = 55250 [3] freq = 62250 [4] freq = 175250 [5] freq = 182250 [6] freq = 189250 [7] freq = 196250 [8] freq = 203250 [9] freq = 210250 [10] freq = 217250 [11] freq = 224250 #include "uhf.list" xawtv-3.106/frequencies/secam-france.list000066400000000000000000000016611343350355000204330ustar00rootroot00000000000000[K01] freq = 47750 [K02] freq = 55750 [K03] freq = 60500 [K04] freq = 63750 [K05] freq = 176000 [K06] freq = 184000 [K07] freq = 192000 [K08] freq = 200000 [K09] freq = 208000 [K10] freq = 216000 [KB] freq = 116750 [KC] freq = 128750 [KD] freq = 140750 [KE] freq = 159750 [KF] freq = 164750 [KG] freq = 176750 [KH] freq = 188750 [KI] freq = 200750 [KJ] freq = 212750 [KK] freq = 224750 [KL] freq = 236750 [KM] freq = 248750 [KN] freq = 260750 [KO] freq = 272750 [KP] freq = 284750 [KQ] freq = 296750 [H01] freq = 303250 [H02] freq = 311250 [H03] freq = 319250 [H04] freq = 327250 [H05] freq = 335250 [H06] freq = 343250 [H07] freq = 351250 [H08] freq = 359250 [H09] freq = 367250 [H10] freq = 375250 [H11] freq = 383250 [H12] freq = 391250 [H13] freq = 399250 [H14] freq = 407250 [H15] freq = 415250 [H16] freq = 423250 [H17] freq = 431250 [H18] freq = 439250 [H19] freq = 447250 #include "uhf.list" xawtv-3.106/frequencies/secam-russia.list000066400000000000000000000001411343350355000204730ustar00rootroot00000000000000#include "oirt-i-iii.list" #include "oirt-sl-sh.list" #include "oirt-h.list" #include "uhf.list" xawtv-3.106/frequencies/uhf.list000066400000000000000000000017241343350355000166710ustar00rootroot00000000000000[21] freq = 471250 [22] freq = 479250 [23] freq = 487250 [24] freq = 495250 [25] freq = 503250 [26] freq = 511250 [27] freq = 519250 [28] freq = 527250 [29] freq = 535250 [30] freq = 543250 [31] freq = 551250 [32] freq = 559250 [33] freq = 567250 [34] freq = 575250 [35] freq = 583250 [36] freq = 591250 [37] freq = 599250 [38] freq = 607250 [39] freq = 615250 [40] freq = 623250 [41] freq = 631250 [42] freq = 639250 [43] freq = 647250 [44] freq = 655250 [45] freq = 663250 [46] freq = 671250 [47] freq = 679250 [48] freq = 687250 [49] freq = 695250 [50] freq = 703250 [51] freq = 711250 [52] freq = 719250 [53] freq = 727250 [54] freq = 735250 [55] freq = 743250 [56] freq = 751250 [57] freq = 759250 [58] freq = 767250 [59] freq = 775250 [60] freq = 783250 [61] freq = 791250 [62] freq = 799250 [63] freq = 807250 [64] freq = 815250 [65] freq = 823250 [66] freq = 831250 [67] freq = 839250 [68] freq = 847250 [69] freq = 855250 xawtv-3.106/install-sh000077500000000000000000000112251343350355000147020ustar00rootroot00000000000000#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" tranformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 xawtv-3.106/jwz/000077500000000000000000000000001343350355000135075ustar00rootroot00000000000000xawtv-3.106/jwz/remote.c000066400000000000000000000330721343350355000151530ustar00rootroot00000000000000/* xscreensaver-command, Copyright (c) 1991-1998 * by Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #ifdef HAVE_SYS_SELECT_H # include #endif /* HAVE_SYS_SELECT_H */ #ifdef HAVE_UNISTD_H # include #endif #include /* for CARD32 */ #include #include #include /* for XGetClassHint() */ #include /* for xawtv */ #include extern XtAppContext app_context; #include "remote.h" #ifdef _VROOT_H_ ERROR! you must not include vroot.h in this file #endif static char *progname = "fixme"; static Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_RESPONSE; static Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_EXIT; static Atom XA_VROOT, XA_SELECT, XA_DEMO, XA_BLANK, XA_LOCK; static XErrorHandler old_handler = 0; static Bool got_badwindow = False; static int BadWindow_ehandler (Display *dpy, XErrorEvent *error) { if (error->error_code == BadWindow) { got_badwindow = True; return 0; } else { fprintf (stderr, "%s: ", progname); if (!old_handler) abort(); return (*old_handler) (dpy, error); } } static Window find_screensaver_window (Display *dpy, char **version) { unsigned int i; Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy)); Window root2, parent, *kids; unsigned int nkids; if (version) *version = 0; if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids)) abort (); if (root != root2) abort (); if (parent) abort (); if (! (kids && nkids)) return 0; for (i = 0; i < nkids; i++) { Atom type; int format; unsigned long nitems, bytesafter; char *v; int status; /* We're walking the list of root-level windows and trying to find the one that has a particular property on it. We need to trap BadWindows errors while doing this, because it's possible that some random window might get deleted in the meantime. (That window won't have been the one we're looking for.) */ XSync (dpy, False); if (old_handler) abort(); got_badwindow = False; old_handler = XSetErrorHandler (BadWindow_ehandler); status = XGetWindowProperty (dpy, kids[i], XA_SCREENSAVER_VERSION, 0, 200, False, XA_STRING, &type, &format, &nitems, &bytesafter, (unsigned char **) &v); XSync (dpy, False); XSetErrorHandler (old_handler); old_handler = 0; if (got_badwindow) { status = BadWindow; got_badwindow = False; } if (status == Success && type != None) { if (version) *version = v; return kids[i]; } } return 0; } static int send_xscreensaver_command (Display *dpy, Atom command, long arg, Window *window_ret, char **error_ret) { char *v = 0; Window window = find_screensaver_window (dpy, &v); XWindowAttributes xgwa; char err[2048]; if (window_ret) *window_ret = window; if (!window) { sprintf (err, "no screensaver is running on display %s", DisplayString (dpy)); if (error_ret) { *error_ret = strdup (err); return -1; } if (command == XA_EXIT) /* Don't print an error if xscreensaver is already dead. */ return 1; fprintf (stderr, "%s: %s\n", progname, err); return -1; } /* Select for property change events, so that we can read the response. */ XGetWindowAttributes (dpy, window, &xgwa); XSelectInput (dpy, window, xgwa.your_event_mask | PropertyChangeMask); if (command == XA_SCREENSAVER_STATUS || command == XA_SCREENSAVER_VERSION) { XClassHint hint; memset (&hint, 0, sizeof(hint)); if (!v || !*v) { sprintf (err, "version property not set on window 0x%x?", (unsigned int) window); if (error_ret) *error_ret = strdup (err); else fprintf (stderr, "%s: %s\n", progname, err); return -1; } XGetClassHint(dpy, window, &hint); if (!hint.res_class) { sprintf (err, "class hints not set on window 0x%x?", (unsigned int) window); if (error_ret) *error_ret = strdup (err); else fprintf (stderr, "%s: %s\n", progname, err); return -1; } fprintf (stdout, "%s %s", hint.res_class, v); if (command != XA_SCREENSAVER_STATUS) { fprintf (stdout, "\n"); } else { Atom type; int format; unsigned long nitems, bytesafter; CARD32 *data = 0; if (XGetWindowProperty (dpy, RootWindow (dpy, 0), XA_SCREENSAVER_STATUS, 0, 999, False, XA_INTEGER, &type, &format, &nitems, &bytesafter, (unsigned char **) &data) == Success && type && data) { Atom blanked; time_t tt; char *s; if (type != XA_INTEGER || nitems < 3) { STATUS_LOSE: if (data) free (data); fprintf (stdout, "\n"); fflush (stdout); fprintf (stderr, "bad status format on root window.\n"); return -1; } blanked = (Atom) data[0]; tt = (time_t) data[1]; if (tt <= (time_t) 666000000L) /* early 1991 */ goto STATUS_LOSE; if (blanked == XA_BLANK) fputs (": screen blanked since ", stdout); else if (blanked == XA_LOCK) fputs (": screen locked since ", stdout); else if (blanked == 0) /* suggestions for a better way to phrase this are welcome. */ fputs (": screen non-blanked since ", stdout); else /* `blanked' has an unknown value - fail. */ goto STATUS_LOSE; s = ctime(&tt); if (s[strlen(s)-1] == '\n') s[strlen(s)-1] = 0; fputs (s, stdout); { int nhacks = nitems - 2; Bool any = False; int i; for (i = 0; i < nhacks; i++) if (data[i + 2] > 0) { any = True; break; } if (any && nhacks == 1) fprintf (stdout, " (hack #%ld)\n", (long)data[2]); else if (any) { fprintf (stdout, " (hacks: "); for (i = 0; i < nhacks; i++) { fprintf (stdout, "#%ld", (long)data[2 + i]); if (i != nhacks-1) fputs (", ", stdout); } fputs (")\n", stdout); } else fputs ("\n", stdout); } if (data) free (data); } else { if (data) free (data); fprintf (stdout, "\n"); fflush (stdout); fprintf (stderr, "no saver status on root window.\n"); return -1; } } /* No need to read a response for these commands. */ return 1; } else { XEvent event; long arg1 = arg; long arg2 = 0; if (arg < 0) abort(); else if (arg == 0 && command == XA_SELECT) abort(); else if (arg != 0 && command == XA_DEMO) { arg1 = 300; /* version number of the XA_DEMO protocol, */ arg2 = arg; /* since it didn't use to take an argument. */ } event.xany.type = ClientMessage; event.xclient.display = dpy; event.xclient.window = window; event.xclient.message_type = XA_SCREENSAVER; event.xclient.format = 32; memset (&event.xclient.data, 0, sizeof(event.xclient.data)); event.xclient.data.l[0] = (long) command; event.xclient.data.l[1] = arg1; event.xclient.data.l[2] = arg2; if (! XSendEvent (dpy, window, False, 0L, &event)) { sprintf (err, "XSendEvent(dpy, 0x%x ...) failed.\n", (unsigned int) window); if (error_ret) *error_ret = strdup (err); else fprintf (stderr, "%s: %s\n", progname, err); return -1; } } XSync (dpy, 0); return 0; } static int xscreensaver_command_response (Display *dpy, Window window, Bool verbose_p, Bool exiting_p, char **error_ret) { int fd = ConnectionNumber (dpy); int timeout = 10; int status; fd_set fds, fds_except; struct timeval tv; char err[2048]; while (1) { FD_ZERO(&fds); FD_SET(fd, &fds); fds_except = fds; memset(&tv, 0, sizeof(tv)); tv.tv_sec = timeout; status = select (fd+1, &fds, 0, &fds_except, &tv); if (status < 0) { char buf[1024]; if (error_ret) { sprintf (buf, "error waiting for reply"); *error_ret = strdup (buf); } else { sprintf (buf, "%s: error waiting for reply", progname); perror (buf); } return status; } else if (status == 0) { sprintf (err, "no response to command."); if (error_ret) *error_ret = strdup (err); else fprintf (stderr, "%s: %s\n", progname, err); return -1; } else { XEvent event; XtAppNextEvent(app_context,&event); if (event.xany.type == PropertyNotify && event.xproperty.state == PropertyNewValue && event.xproperty.atom == XA_SCREENSAVER_RESPONSE) { Status st2; Atom type; int format; unsigned long nitems, bytesafter; char *msg = 0; XSync (dpy, False); if (old_handler) abort(); old_handler = XSetErrorHandler (BadWindow_ehandler); st2 = XGetWindowProperty (dpy, window, XA_SCREENSAVER_RESPONSE, 0, 1024, True, AnyPropertyType, &type, &format, &nitems, &bytesafter, (unsigned char **) &msg); XSync (dpy, False); XSetErrorHandler (old_handler); old_handler = 0; if (got_badwindow) { if (exiting_p) return 0; sprintf (err, "xscreensaver window unexpectedly deleted."); if (error_ret) *error_ret = strdup (err); else fprintf (stderr, "%s: %s\n", progname, err); return -1; } if (st2 == Success && type != None) { if (type != XA_STRING || format != 8) { sprintf (err, "unrecognized response property."); if (error_ret) *error_ret = strdup (err); else fprintf (stderr, "%s: %s\n", progname, err); if (msg) XFree (msg); return -1; } else if (!msg || (msg[0] != '+' && msg[0] != '-')) { sprintf (err, "unrecognized response message."); if (error_ret) *error_ret = strdup (err); else fprintf (stderr, "%s: %s\n", progname, err); if (msg) XFree (msg); return -1; } else { int ret = (msg[0] == '+' ? 0 : -1); sprintf (err, "%s: %s\n", progname, msg+1); if (error_ret) *error_ret = strdup (err); else if (verbose_p || ret != 0) fprintf ((ret < 0 ? stderr : stdout), "%s\n", err); XFree (msg); return ret; } } } else { XtDispatchEvent(&event); } } } } int xscreensaver_command (Display *dpy, Atom command, long arg, Bool verbose_p, char **error_ret) { Window w = 0; int status = send_xscreensaver_command (dpy, command, arg, &w, error_ret); if (status == 0) status = xscreensaver_command_response (dpy, w, verbose_p, (command == XA_EXIT), error_ret); fflush (stdout); fflush (stderr); return (status < 0 ? status : 0); } void server_xscreensaver_version (Display *dpy, char **version_ret, char **user_ret, char **host_ret) { Window window = find_screensaver_window (dpy, 0); Atom type; int format; unsigned long nitems, bytesafter; if (version_ret) *version_ret = 0; if (user_ret) *user_ret = 0; if (host_ret) *host_ret = 0; if (!window) return; if (version_ret) { char *v = 0; XGetWindowProperty (dpy, window, XA_SCREENSAVER_VERSION, 0, 1, False, XA_STRING, &type, &format, &nitems, &bytesafter, (unsigned char **) &v); if (v) { *version_ret = strdup (v); XFree (v); } } if (user_ret || host_ret) { char *id = 0; const char *user = 0; const char *host = 0; XGetWindowProperty (dpy, window, XA_SCREENSAVER_ID, 0, 512, False, XA_STRING, &type, &format, &nitems, &bytesafter, (unsigned char **) &id); if (id && *id) { const char *old_tag = " on host "; const char *s = strstr (id, old_tag); if (s) { /* found ID of the form "1234 on host xyz". */ user = 0; host = s + strlen (old_tag); } else { char *o = 0, *p = 0, *c = 0; o = strchr (id, '('); if (o) p = strchr (o, '@'); if (p) c = strchr (p, ')'); if (c) { /* found ID of the form "1234 (user@host)". */ user = o+1; host = p+1; *p = 0; *c = 0; } } } if (user && *user && *user != '?') *user_ret = strdup (user); else *user_ret = 0; if (host && *host && *host != '?') *host_ret = strdup (host); else *host_ret = 0; if (id) XFree (id); } } void xscreensaver_init(Display *dpy) { XA_VROOT = XInternAtom (dpy, "__SWM_VROOT", False); XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False); XA_SCREENSAVER_ID = XInternAtom (dpy, "_SCREENSAVER_ID", False); XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False); XA_SCREENSAVER_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", False); XA_SCREENSAVER_RESPONSE = XInternAtom (dpy, "_SCREENSAVER_RESPONSE", False); XA_SELECT = XInternAtom (dpy, "SELECT", False); XA_EXIT = XInternAtom (dpy, "EXIT", False); XA_DEMO = XInternAtom (dpy, "DEMO", False); XA_LOCK = XInternAtom (dpy, "LOCK", False); XA_BLANK = XInternAtom (dpy, "BLANK", False); } xawtv-3.106/jwz/remote.diff000066400000000000000000000056211343350355000156400ustar00rootroot00000000000000--- xscreensaver-4.00/driver/remote.h Sun Nov 14 01:15:07 1999 +++ remote.h Tue Mar 26 11:01:34 2002 @@ -21,4 +21,6 @@ char **user_ret, char **host_ret); +extern void xscreensaver_init(Display *dpy); + #endif /* _XSCREENSAVER_REMOTE_H_ */ --- xscreensaver-4.00/driver/remote.c Mon Dec 20 12:24:19 1999 +++ remote.c Tue Mar 26 11:31:14 2002 @@ -33,16 +33,20 @@ #include /* for XGetClassHint() */ #include +/* for xawtv */ +#include +extern XtAppContext app_context; + #include "remote.h" #ifdef _VROOT_H_ ERROR! you must not include vroot.h in this file #endif -extern char *progname; -extern Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_RESPONSE; -extern Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_EXIT; -extern Atom XA_VROOT, XA_SELECT, XA_DEMO, XA_BLANK, XA_LOCK; +static char *progname = "fixme"; +static Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_RESPONSE; +static Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_EXIT; +static Atom XA_VROOT, XA_SELECT, XA_DEMO, XA_BLANK, XA_LOCK; static XErrorHandler old_handler = 0; @@ -261,13 +265,13 @@ } if (any && nhacks == 1) - fprintf (stdout, " (hack #%d)\n", data[2]); + fprintf (stdout, " (hack #%ld)\n", data[2]); else if (any) { fprintf (stdout, " (hacks: "); for (i = 0; i < nhacks; i++) { - fprintf (stdout, "#%d", data[2 + i]); + fprintf (stdout, "#%ld", data[2 + i]); if (i != nhacks-1) fputs (", ", stdout); } @@ -380,7 +384,7 @@ else { XEvent event; - XNextEvent (dpy, &event); + XtAppNextEvent(app_context,&event); if (event.xany.type == PropertyNotify && event.xproperty.state == PropertyNewValue && event.xproperty.atom == XA_SCREENSAVER_RESPONSE) @@ -459,6 +463,8 @@ return ret; } } + } else { + XtDispatchEvent(&event); } } } @@ -568,3 +574,18 @@ XFree (id); } } + +void xscreensaver_init(Display *dpy) +{ + XA_VROOT = XInternAtom (dpy, "__SWM_VROOT", False); + XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False); + XA_SCREENSAVER_ID = XInternAtom (dpy, "_SCREENSAVER_ID", False); + XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False); + XA_SCREENSAVER_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", False); + XA_SCREENSAVER_RESPONSE = XInternAtom (dpy, "_SCREENSAVER_RESPONSE", False); + XA_SELECT = XInternAtom (dpy, "SELECT", False); + XA_EXIT = XInternAtom (dpy, "EXIT", False); + XA_DEMO = XInternAtom (dpy, "DEMO", False); + XA_LOCK = XInternAtom (dpy, "LOCK", False); + XA_BLANK = XInternAtom (dpy, "BLANK", False); +} xawtv-3.106/jwz/remote.h000066400000000000000000000016631343350355000151610ustar00rootroot00000000000000/* xscreensaver-command, Copyright (c) 1991-1998 * by Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. */ #ifndef _XSCREENSAVER_REMOTE_H_ #define _XSCREENSAVER_REMOTE_H_ extern int xscreensaver_command (Display *dpy, Atom command, long arg, Bool verbose_p, char **error_ret); extern void server_xscreensaver_version (Display *dpy, char **version_ret, char **user_ret, char **host_ret); extern void xscreensaver_init(Display *dpy); #endif /* _XSCREENSAVER_REMOTE_H_ */ xawtv-3.106/jwz/vroot.h000066400000000000000000000122001343350355000150240ustar00rootroot00000000000000/*****************************************************************************/ /** Copyright 1991 by Andreas Stolcke **/ /** Copyright 1990 by Solbourne Computer Inc. **/ /** Longmont, Colorado **/ /** **/ /** All Rights Reserved **/ /** **/ /** Permission to use, copy, modify, and distribute this software and **/ /** its documentation for any purpose and without fee is hereby **/ /** granted, provided that the above copyright notice appear in all **/ /** copies and that both that copyright notice and this permis- **/ /** sion notice appear in supporting documentation, and that the **/ /** name of Solbourne not be used in advertising **/ /** in publicity pertaining to distribution of the software without **/ /** specific, written prior permission. **/ /** **/ /** ANDREAS STOLCKE AND SOLBOURNE COMPUTER INC. DISCLAIMS ALL WARRANTIES **/ /** WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF **/ /** MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ANDREAS STOLCKE **/ /** OR SOLBOURNE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL **/ /** DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ /** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ /** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ /** OR PERFORMANCE OF THIS SOFTWARE. **/ /*****************************************************************************/ /* * vroot.h -- Virtual Root Window handling header file * * This header file redefines the X11 macros RootWindow and DefaultRootWindow, * making them look for a virtual root window as provided by certain `virtual' * window managers like swm and tvtwm. If none is found, the ordinary root * window is returned, thus retaining backward compatibility with standard * window managers. * The function implementing the virtual root lookup remembers the result of * its last invocation to avoid overhead in the case of repeated calls * on the same display and screen arguments. * The lookup code itself is taken from Tom LaStrange's ssetroot program. * * Most simple root window changing X programs can be converted to using * virtual roots by just including * * #include * * after all the X11 header files. It has been tested on such popular * X clients as xphoon, xfroot, xloadimage, and xaqua. * It also works with the core clients xprop, xwininfo, xwd, and editres * (and is necessary to get those clients working under tvtwm). * It does NOT work with xsetroot; get the xsetroot replacement included in * the tvtwm distribution instead. * * Andreas Stolcke , 9/7/90 * - replaced all NULL's with properly cast 0's, 5/6/91 * - free children list (suggested by Mark Martin ), 5/16/91 * - include X11/Xlib.h and support RootWindowOfScreen, too 9/17/91 */ #ifndef _VROOT_H_ #define _VROOT_H_ #if !defined(lint) && !defined(SABER) static const char vroot_rcsid[] = "#Id: vroot.h,v 1.4 1991/09/30 19:23:16 stolcke Exp stolcke #"; #endif #include #include #include static Window #ifdef __STDC__ /* ANSIfication added by jwz, to avoid superfluous warnings. */ VirtualRootWindowOfScreen(Screen *screen) #else /* !__STDC__ */ VirtualRootWindowOfScreen(screen) Screen *screen; #endif /* !__STDC__ */ { static Screen *save_screen = (Screen *)0; static Window root = (Window)0; if (screen != save_screen) { Display *dpy = DisplayOfScreen(screen); Atom __SWM_VROOT = None; unsigned int i; Window rootReturn, parentReturn, *children; unsigned int numChildren; root = RootWindowOfScreen(screen); /* go look for a virtual root */ __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False); if (XQueryTree(dpy, root, &rootReturn, &parentReturn, &children, &numChildren)) { for (i = 0; i < numChildren; i++) { Atom actual_type; int actual_format; unsigned long nitems, bytesafter; Window *newRoot = (Window *)0; if (XGetWindowProperty(dpy, children[i], __SWM_VROOT, 0, 1, False, XA_WINDOW, &actual_type, &actual_format, &nitems, &bytesafter, (unsigned char **) &newRoot) == Success && newRoot) { root = *newRoot; break; } } if (children) XFree((char *)children); } save_screen = screen; } return root; } #undef RootWindowOfScreen #define RootWindowOfScreen(s) VirtualRootWindowOfScreen(s) #undef RootWindow #define RootWindow(dpy,screen) VirtualRootWindowOfScreen(ScreenOfDisplay(dpy,screen)) #undef DefaultRootWindow #define DefaultRootWindow(dpy) VirtualRootWindowOfScreen(DefaultScreenOfDisplay(dpy)) #endif /* _VROOT_H_ */ xawtv-3.106/libng/000077500000000000000000000000001343350355000137705ustar00rootroot00000000000000xawtv-3.106/libng/OVERVIEW000066400000000000000000000156631343350355000151740ustar00rootroot00000000000000 libng overview ============== some general notes ------------------ The text below is not a complete reference (yet?), it just tries to give a overview and explain the design of the library. Have a look at grab-ng.h, this is the header file where everything is defined. If you are looking for some simple sample code check out console/webcam.c. More complex usages of libng can be found everythere in the xawtv source code: In common/capture.c for example, where most of the threaded movie recording code for xawtv+streamer is. There are two types of structs: Those which carrying some data (like ng_video_fmt or ng_video_buf) and those which define a interface (like ng_driver). The interfaces all have a initialization function which returns a void pointer as handle. All other interface functions expect getting that handle passed in. The complete state information is kept there. Global variables are a no-no, the interfaces need to be reentrant (so you can use multiple instances of them at the same time). video buffers (struct ng_video_buf) ----------------------------------- One video buffer holds one frame. There are some rules for video frames: (1) Multiple instances (threads for example) may hold a pointer to the buffer. The refcount variable is used to keep track of the number of references. If you hand out a pointer to the buffer to someone else *and* keep a pointer to the buffer yourself to use it later refcount must be increased by one. If you don't need the buffer any more, just free it with ng_release_video_buf(). That function will take care about count down the reference counter and freeing the buffer if refcount is zero. (2) The above implies you should not write to ng_video_buf->data because another thread might use the image data while you are modifying it. Allocate a new buffer and put the new data in there instead if you want process the image data. You can use ng_malloc_video_buf() to get a buffer. Don't forget to copy the frame meta data to the new buffer (ng_video_buf->info). Within the current implementation two types of buffers exist: Those malloc()ed ones which are returned by ng_malloc_video_buf() and buffers provided by the hardware drivers, where ng_video_buf->data is a pointer directly to the mmap()ed buffer(s). video capture / overlay drivers (struct ng_vid_driver) ------------------------------------------------------ This is a interface to a capture driver. Right now three different ones exist: (1) video4linux (current linux API, see plugins/drv1-v4l.c). (2) video4linux two (work in progress - new API for linux, see plugins/drv0-v4l2.c). (3) bktr (bt848/878 driver for FreeBSD + OpenBSD, see plugins/drv0-bsd.c). xawtv uses struct ng_vid_driver for Xvideo support too (see x11/xv.c). open()/close() should be clear. The capabilities() function returns a bitfield which specifies the capabilities of the driver. The *attr* functions can be used to control several (hardware) settings (see below for more on attributes). To for a overlay use setupfb() and overlay(). For linux setupfb() just verifies the driver parameters, it expects the setup is done with a extern utility like v4l-conf (because one needs root priviliges for that). To capture frames you have to configure the format with setformat() first. Be aware that the image size might have changed on return, depending on the capabilities of the underlying hardware. For video recording use startvideo(), multiple nextframe() calls and stopvideo(), for single frames use getimage(). output drivers (struct ng_writer) --------------------------------- This is a interface for movie writer code. Four different ones exist: (1) Microsoft's AVI (2) Apple Quicktime (using the libquicktime library). (3) raw, uncompressed data (one big file). (4) one image file/frame (jpeg or ppm). The first two write audio and video data into the same stream, the last two can write audio data to a separate wav file. The audio/video args hold a list of supported formats. Usage should be pretty straight forward: wr_open(), write data with wr_video() + wr_audio(), then wr_close(). You can write both audio-only and video-only streams if you want. attributes (struct ng_attribute) -------------------------------- Attributes can be used to control properties attributes. Right now they are only used for video drivers (struct ng_driver), but that might change in the future. There are a number of standard attributes defined (tv norm, volume and the like), but it is also possible to specify non-standard attributes. struct ng_attribute also has functions to list/read/modify the given attribute. A number of helper functions to search a attribute list by id / name and for multiple choice attribute handling are available too. audio recording + mixer control ------------------------------- There are only some structs for audio formats and audio data chunks. The movie writers use these. There are also interfaces for sound recording and mixer control (struct ng_dsp_driver + struct ng_mix_driver) and a implementation for the OSS API (in plugins/snd-oss.c). I'm not that happy with the current design of the mixer stuff, it likely will change in the future. color space conversion and compression -------------------------------------- struct ng_video_conv describes a converter. There are plenty built-in into libng, but it is also possible to add more using plugins. These converters handle (a) color space conversion (yuv -> rgb), (b) convert rgb with different color depths, (c) handle compression. image filtering --------------- I've recently added a interfaces for image filtering (i.e. on-the-fly image processing). struct ng_filter is it, in plugins/flt-*.c is some sample code. There is no complex stuff yet. For now filters are limited: They work on a frame-by-frame base, i.e. for one frame which gets passed in one is expected to come out. Read: you can't (yet?) merge multiple frames into one. The input and output format is expected to be the same. Filters should be able to handle as much formats as possible, neither xawtv nor libng attempt to do any conversions (i.e. do yuv->rgb -> filter -> rgb->yuv for you because the filter works in RGB space only). ng_filter->fmts lists the supported formats of a given filter, and if the required format isn't supported by some filter it is simply skipped and no filtering takes place. Most frequently formats are: * RGB (various depts), to display images on the X11 screen, for ppm capture, ... * packed pixel yuv (If xawtv/motv blits images using the Xvideo extention instead of normal X11 ximages). * planar yuv (for recording compressed video, libjpeg can be feeded directly with planar yuv to save some CPU cycles for rgb->yuv color space conversion). misc ---- There are some helper functions for various stuff, see grab-ng.[ch]. There are also some arrays with text descriptions and other informations about audio/video formats: ng_[va]fmt_to_*. xawtv-3.106/libng/README000066400000000000000000000011241343350355000146460ustar00rootroot00000000000000 WARNING: This is work-in-progress. In the long run I plan to turn this into a v4l capture library. But that isn't finished yet and probably will not for some time. Some documentation can be found in OVERVIEW. Complete reference is not available. I don't care (yet) about backward compatibility. I neither can nor will stop you from using the code. But if you do don't complain if I break your applications with incompatible changes. You have been warned. Please don't distribute this code as shared library. This is just asking for trouble. Gerd -- Gerd Knorr xawtv-3.106/libng/Subdir.mk000066400000000000000000000004531343350355000155530ustar00rootroot00000000000000OBJS-libng := \ libng/grab-ng.o \ libng/devices.o \ libng/writefile.o \ libng/color_common.o \ libng/color_packed.o \ libng/color_lut.o \ libng/color_yuv2rgb.o \ libng/convert.o \ common/get_media_devices.o libng/libng.a: $(OBJS-libng) @$(echo_ar_lib) @$(ar_lib) clean:: rm -f libng.a xawtv-3.106/libng/byteswap.h000066400000000000000000000005431343350355000160010ustar00rootroot00000000000000#ifndef BYTEORDER_H #define BYTEORDER_H #include #ifndef BYTE_ORDER # error "Aiee: BYTE_ORDER not defined\n"; #endif #define SWAP2(x) (((x>>8) & 0x00ff) |\ ((x<<8) & 0xff00)) #define SWAP4(x) (((x>>24) & 0x000000ff) |\ ((x>>8) & 0x0000ff00) |\ ((x<<8) & 0x00ff0000) |\ ((x<<24) & 0xff000000)) #endif /* BYTEORDER_H */ xawtv-3.106/libng/color_common.c000066400000000000000000000024431343350355000166250ustar00rootroot00000000000000#define NG_PRIVATE #include "config.h" #include #include #include #include #include #include #include "grab-ng.h" /* ------------------------------------------------------------------- */ void* ng_packed_init(struct ng_video_fmt *out, void *priv) { return priv; } void ng_packed_frame(void *handle, struct ng_video_buf *out, struct ng_video_buf *in) { int (*func)(unsigned char *dest, unsigned char *src, int p) = handle; unsigned char *sp,*dp; unsigned int i,sw,dw; dw = (out->fmt.width * ng_vfmt_to_depth[out->fmt.fmtid]) >> 3; sw = (in->fmt.width * ng_vfmt_to_depth[in->fmt.fmtid]) >> 3; if (in->fmt.bytesperline == sw && out->fmt.bytesperline == dw) { /* can convert in one go */ func(out->data, in->data, in->fmt.width * in->fmt.height); } else { /* convert line by line */ dp = out->data; sp = in->data; for (i = 0; i < in->fmt.height; i++) { func(dp,sp,in->fmt.width); dp += out->fmt.bytesperline; sp += in->fmt.bytesperline; } } } /* ------------------------------------------------------------------- */ void* ng_conv_nop_init(struct ng_video_fmt *out, void *priv) { /* nothing */ return NULL; } void ng_conv_nop_fini(void *handle) { /* nothing */ } xawtv-3.106/libng/color_lut.c000066400000000000000000000166601343350355000161470ustar00rootroot00000000000000/* * colorspace conversion functions * -- translate RGB using lookup tables * * (c) 1998-2001 Gerd Knorr * */ #define NG_PRIVATE #include "config.h" #include #include #include #include #include #include #include #include "grab-ng.h" #include "byteswap.h" unsigned long ng_lut_red[256]; unsigned long ng_lut_green[256]; unsigned long ng_lut_blue[256]; /* ------------------------------------------------------------------- */ void ng_rgb24_to_lut2(unsigned char* restrict dest, unsigned char* restrict src, int p) { uint16_t* restrict d = (uint16_t*)dest; while (p-- > 0) { *(d++) = ng_lut_red[src[0]] | ng_lut_green[src[1]] | ng_lut_blue[src[2]]; src += 3; } } static void bgr24_to_lut2(unsigned char* restrict dest, unsigned char* restrict src, int p) { uint16_t* restrict d = (uint16_t*)dest; while (p-- > 0) { *(d++) = ng_lut_red[src[2]] | ng_lut_green[src[1]] | ng_lut_blue[src[0]]; src += 3; } } static void rgb32_to_lut2(unsigned char* restrict dest, unsigned char* restrict src, int p) { uint16_t* restrict d = (uint16_t*)dest; while (p-- > 0) { *(d++) = ng_lut_red[src[1]] | ng_lut_green[src[2]] | ng_lut_blue[src[3]]; src += 4; } } static void bgr32_to_lut2(unsigned char* restrict dest, unsigned char* restrict src, int p) { uint16_t* restrict d = (uint16_t*)dest; while (p-- > 0) { *(d++) = ng_lut_red[src[2]] | ng_lut_green[src[1]] | ng_lut_blue[src[0]]; src += 4; } } static void gray_to_lut2(unsigned char* restrict dest, unsigned char* restrict src, int p) { uint16_t* restrict d = (uint16_t*)dest; while (p-- > 0) { *(d++) = ng_lut_red[*src] | ng_lut_green[*src] | ng_lut_blue[*src]; src++; } } /* ------------------------------------------------------------------- */ void ng_rgb24_to_lut4(unsigned char* restrict dest, unsigned char* restrict src, int p) { unsigned int* restrict d = (unsigned int*)dest; while (p-- > 0) { *(d++) = ng_lut_red[src[0]] | ng_lut_green[src[1]] | ng_lut_blue[src[2]]; src += 3; } } static void bgr24_to_lut4(unsigned char* restrict dest, unsigned char* restrict src, int p) { unsigned int* restrict d = (unsigned int*)dest; while (p-- > 0) { *(d++) = ng_lut_red[src[2]] | ng_lut_green[src[1]] | ng_lut_blue[src[0]]; src += 3; } } static void rgb32_to_lut4(unsigned char* restrict dest, unsigned char* restrict src, int p) { unsigned int* restrict d = (unsigned int*)dest; while (p-- > 0) { *(d++) = ng_lut_red[src[1]] | ng_lut_green[src[2]] | ng_lut_blue[src[3]]; src += 4; } } static void bgr32_to_lut4(unsigned char* restrict dest, unsigned char* restrict src, int p) { unsigned int* restrict d = (unsigned int*)dest; while (p-- > 0) { *(d++) = ng_lut_red[src[2]] | ng_lut_green[src[1]] | ng_lut_blue[src[0]]; src += 4; } } static void gray_to_lut4(unsigned char* restrict dest, unsigned char* restrict src, int p) { unsigned int* restrict d = (unsigned int*)dest; while (p-- > 0) { *(d++) = ng_lut_red[*src] | ng_lut_green[*src] | ng_lut_blue[*src]; src++; } } /* ------------------------------------------------------------------- */ static struct ng_video_conv lut2_list[] = { { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB24, .priv = ng_rgb24_to_lut2, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_BGR24, .priv = bgr24_to_lut2, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB32, .priv = rgb32_to_lut2, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_BGR32, .priv = bgr32_to_lut2, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_GRAY, .priv = gray_to_lut2, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_YUYV, .priv = ng_yuv422_to_lut2, },{ .init = ng_conv_nop_init, .fini = ng_conv_nop_fini, .frame = ng_yuv422p_to_lut2, .fmtid_in = VIDEO_YUV422P, },{ .init = ng_conv_nop_init, .fini = ng_conv_nop_fini, .frame = ng_yuv420p_to_lut2, .fmtid_in = VIDEO_YUV420P, } }; static struct ng_video_conv lut4_list[] = { { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB24, .priv = ng_rgb24_to_lut4, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_BGR24, .priv = bgr24_to_lut4, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB32, .priv = rgb32_to_lut4, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_BGR32, .priv = bgr32_to_lut4, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_GRAY, .priv = gray_to_lut4, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_YUYV, .priv = ng_yuv422_to_lut4, },{ .init = ng_conv_nop_init, .fini = ng_conv_nop_fini, .frame = ng_yuv422p_to_lut4, .fmtid_in = VIDEO_YUV422P, },{ .init = ng_conv_nop_init, .fini = ng_conv_nop_fini, .frame = ng_yuv420p_to_lut4, .fmtid_in = VIDEO_YUV420P, } }; static const unsigned int nconv2 = sizeof(lut2_list)/sizeof(lut2_list[0]); static const unsigned int nconv4 = sizeof(lut4_list)/sizeof(lut4_list[0]); void ng_lut_init(unsigned long red_mask, unsigned long green_mask, unsigned long blue_mask, unsigned int fmtid, int swap) { static int once=0; int rgb_red_bits = 0; int rgb_red_shift = 0; int rgb_green_bits = 0; int rgb_green_shift = 0; int rgb_blue_bits = 0; int rgb_blue_shift = 0; unsigned int i; unsigned int mask; if (once++) { fprintf(stderr,"panic: ng_lut_init called twice\n"); exit(1); } for (i = 0; i < 32; i++) { mask = (1 << i); if (red_mask & mask) rgb_red_bits++; else if (!rgb_red_bits) rgb_red_shift++; if (green_mask & mask) rgb_green_bits++; else if (!rgb_green_bits) rgb_green_shift++; if (blue_mask & mask) rgb_blue_bits++; else if (!rgb_blue_bits) rgb_blue_shift++; } #if 0 printf("color: bits shift\n"); printf("red : %04i %05i\n", rgb_red_bits, rgb_red_shift); printf("green: %04i %05i\n", rgb_green_bits, rgb_green_shift); printf("blue : %04i %05i\n", rgb_blue_bits, rgb_blue_shift); #endif if (rgb_red_bits > 8) for (i = 0; i < 256; i++) ng_lut_red[i] = (i << (rgb_red_bits + rgb_red_shift - 8)); else for (i = 0; i < 256; i++) ng_lut_red[i] = (i >> (8 - rgb_red_bits)) << rgb_red_shift; if (rgb_green_bits > 8) for (i = 0; i < 256; i++) ng_lut_green[i] = (i << (rgb_green_bits + rgb_green_shift - 8)); else for (i = 0; i < 256; i++) ng_lut_green[i] = (i >> (8 - rgb_green_bits)) << rgb_green_shift; if (rgb_blue_bits > 8) for (i = 0; i < 256; i++) ng_lut_blue[i] = (i << (rgb_blue_bits + rgb_blue_shift - 8)); else for (i = 0; i < 256; i++) ng_lut_blue[i] = (i >> (8 - rgb_blue_bits)) << rgb_blue_shift; switch (ng_vfmt_to_depth[fmtid]) { case 16: if (swap) { for (i = 0; i < 256; i++) { ng_lut_red[i] = SWAP2(ng_lut_red[i]); ng_lut_green[i] = SWAP2(ng_lut_green[i]); ng_lut_blue[i] = SWAP2(ng_lut_blue[i]); } } for (i = 0; i < nconv2; i++) lut2_list[i].fmtid_out = fmtid; ng_conv_register(NG_PLUGIN_MAGIC,"built-in",lut2_list,nconv2); break; case 32: if (swap) { for (i = 0; i < 256; i++) { ng_lut_red[i] = SWAP4(ng_lut_red[i]); ng_lut_green[i] = SWAP4(ng_lut_green[i]); ng_lut_blue[i] = SWAP4(ng_lut_blue[i]); } } for (i = 0; i < nconv4; i++) lut4_list[i].fmtid_out = fmtid; ng_conv_register(NG_PLUGIN_MAGIC,"built-in",lut4_list,nconv4); break; } } xawtv-3.106/libng/color_packed.c000066400000000000000000000127771343350355000165770ustar00rootroot00000000000000/* * colorspace conversion functions * -- packed pixel formats (rgb/gray right now) * * (c) 1998-2001 Gerd Knorr * */ #define NG_PRIVATE #include "config.h" #include #include #include #include #include #include #include "grab-ng.h" /* ------------------------------------------------------------------- */ /* RGB conversions */ static void redblue_swap(unsigned char *dest, unsigned char *src, int p) { register unsigned char *s = src; register unsigned char *d = dest; while (p--) { *(d++) = s[2]; *(d++) = s[1]; *(d++) = s[0]; s += 3; } } static void bgr24_to_bgr32(unsigned char* restrict dest, unsigned char* restrict src, int p) { register unsigned char* restrict s = src; register unsigned char* restrict d = dest; while (p--) { *(d++) = *(s++); *(d++) = *(s++); *(d++) = *(s++); *(d++) = 0; } } static void bgr24_to_rgb32(unsigned char* restrict dest, unsigned char* restrict src, int p) { register unsigned char* restrict s = src; register unsigned char* restrict d = dest; while (p--) { *(d++) = 0; *(d++) = s[2]; *(d++) = s[1]; *(d++) = s[0]; s +=3; } } static void rgb32_to_rgb24(unsigned char* restrict dest, unsigned char* restrict src, int p) { register unsigned char* restrict s = src; register unsigned char* restrict d = dest; while (p--) { s++; *(d++) = *(s++); *(d++) = *(s++); *(d++) = *(s++); } } static void rgb32_to_bgr24(unsigned char* restrict dest, unsigned char* restrict src, int p) { register unsigned char* restrict s = src; register unsigned char* restrict d = dest; while (p--) { s++; d[2] = *(s++); d[1] = *(s++); d[0] = *(s++); d += 3; } } /* 15+16 bpp LE <=> BE */ static void byteswap_short(unsigned char* restrict dest, unsigned char* restrict src, int p) { register unsigned char* restrict s = src; register unsigned char* restrict d = dest; while (--p) { *(d++) = s[1]; *(d++) = s[0]; s += 2; } } /* ------------------------------------------------------------------- */ /* color => grayscale */ static void rgb15_native_gray(unsigned char* restrict dest, unsigned char *s, int p) { int r,g,b; unsigned short* restrict src = (unsigned short*)s; while (p--) { r = (src[0] & 0x7c00) >> 10; g = (src[0] & 0x03e0) >> 5; b = src[0] & 0x001f; *(dest++) = ((3*r + 6*g + b)/10) << 3; src++; } } #if BYTE_ORDER == LITTLE_ENDIAN static void rgb15_be_gray(unsigned char* restrict dest, unsigned char* restrict src, int p) { int r,g,b; register unsigned char* restrict d = dest; while (p--) { r = (src[0] & 0x7c) >> 2; g = (src[0] & 0x03) << 3 | (src[1] & 0xe0) >> 5; b = src[1] & 0x1f; *(d++) = ((3*r + 6*g + b)/10) << 3; src += 2; } } #endif #if BYTE_ORDER == BIG_ENDIAN static void rgb15_le_gray(unsigned char* restrict dest, unsigned char* restrict src, int p) { int r,g,b; register unsigned char* restrict d = dest; while (p--) { r = (src[1] & 0x7c) >> 2; g = (src[1] & 0x03) << 3 | (src[0] & 0xe0) >> 5; b = src[0] & 0x1f; *(d++) = ((3*r + 6*g + b)/10) << 3; src += 2; } } #endif /* ------------------------------------------------------------------- */ static struct ng_video_conv conv_list[] = { { /* ----------------------------------- write GRAY -- */ #if BYTE_ORDER == BIG_ENDIAN NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB15_BE, .fmtid_out = VIDEO_GRAY, .priv = rgb15_native_gray, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB15_LE, .fmtid_out = VIDEO_GRAY, .priv = rgb15_le_gray, }, { #else NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB15_BE, .fmtid_out = VIDEO_GRAY, .priv = rgb15_be_gray, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB15_LE, .fmtid_out = VIDEO_GRAY, .priv = rgb15_native_gray, }, { #endif /* ----------------------------------- write RGB15 -- */ NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB15_LE, .fmtid_out = VIDEO_RGB15_BE, .priv = byteswap_short, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB15_BE, .fmtid_out = VIDEO_RGB15_LE, .priv = byteswap_short, }, { /* ----------------------------------- write RGB16 -- */ NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB16_LE, .fmtid_out = VIDEO_RGB16_BE, .priv = byteswap_short, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB16_BE, .fmtid_out = VIDEO_RGB16_LE, .priv = byteswap_short, }, { /* ----------------------------------- write RGB24 -- */ NG_GENERIC_PACKED, .fmtid_in = VIDEO_BGR24, .fmtid_out = VIDEO_RGB24, .priv = redblue_swap, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB24, .fmtid_out = VIDEO_BGR24, .priv = redblue_swap, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB32, .fmtid_out = VIDEO_RGB24, .priv = rgb32_to_rgb24, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_RGB32, .fmtid_out = VIDEO_BGR24, .priv = rgb32_to_bgr24, }, { /* ----------------------------------- write RGB32 -- */ NG_GENERIC_PACKED, .fmtid_in = VIDEO_BGR24, .fmtid_out = VIDEO_BGR32, .priv = bgr24_to_bgr32, }, { NG_GENERIC_PACKED, .fmtid_in = VIDEO_BGR24, .fmtid_out = VIDEO_RGB32, .priv = bgr24_to_rgb32, } }; static const int nconv = sizeof(conv_list)/sizeof(struct ng_video_conv); /* ------------------------------------------------------------------- */ void ng_color_packed_init(void) { ng_conv_register(NG_PLUGIN_MAGIC,"built-in",conv_list,nconv); } xawtv-3.106/libng/color_unused.c000066400000000000000000000021561343350355000166410ustar00rootroot00000000000000/* ------------------------------------------------------------------- */ /* YUV conversions */ int packed422_to_planar422(unsigned char *d, unsigned char *s, int p) { int i; unsigned char *y,*u,*v; i = p/2; y = d; u = y + p; v = u + p / 2; while (--i) { *(y++) = *(s++); *(u++) = *(s++); *(y++) = *(s++); *(v++) = *(s++); } return p*2; } /* y only, no chroma */ int packed422_to_planar420(unsigned char *d, unsigned char *s, int p) { int i; unsigned char *y; i = p/2; y = d; while (--i) { *(y++) = *(s++); s++; *(y++) = *(s++); s++; } return p*3/2; } #if 0 void x_packed422_to_planar420(unsigned char *d, unsigned char *s, int w, int h) { int a,b; unsigned char *y,*u,*v; y = d; u = y + w * h; v = u + w * h / 4; for (a = h; a > 0; a -= 2) { for (b = w; b > 0; b -= 2) { *(y++) = *(s++); *(u++) = *(s++); *(y++) = *(s++); *(v++) = *(s++); } for (b = w; b > 0; b -= 2) { *(y++) = *(s++); s++; *(y++) = *(s++); s++; } } } #endif xawtv-3.106/libng/color_yuv2rgb.c000066400000000000000000000243321343350355000167360ustar00rootroot00000000000000/* * colorspace conversion functions * -- yuv to rgb colorspace conversions * * (c) 2001 Gerd Knorr * */ #define NG_PRIVATE #include "config.h" #include #include #include #include #include #include #include "grab-ng.h" /* ------------------------------------------------------------------- */ #define CLIP 320 #if 0 # define RED_NULL 137 # define BLUE_NULL 156 # define LUN_MUL 360 # define RED_MUL 512 # define BLUE_MUL 512 #else # define RED_NULL 128 # define BLUE_NULL 128 # define LUN_MUL 256 # define RED_MUL 512 # define BLUE_MUL 512 #endif #define GREEN1_MUL (-RED_MUL/2) #define GREEN2_MUL (-BLUE_MUL/6) #define RED_ADD (-RED_NULL * RED_MUL) #define BLUE_ADD (-BLUE_NULL * BLUE_MUL) #define GREEN1_ADD (-RED_ADD/2) #define GREEN2_ADD (-BLUE_ADD/6) /* lookup tables */ static unsigned int ng_yuv_gray[256]; static unsigned int ng_yuv_red[256]; static unsigned int ng_yuv_blue[256]; static unsigned int ng_yuv_g1[256]; static unsigned int ng_yuv_g2[256]; static unsigned int ng_clip[256 + 2 * CLIP]; #define GRAY(val) ng_yuv_gray[val] #define RED(gray,red) ng_clip[ CLIP + gray + ng_yuv_red[red] ] #define GREEN(gray,red,blue) ng_clip[ CLIP + gray + ng_yuv_g1[red] + \ ng_yuv_g2[blue] ] #define BLUE(gray,blue) ng_clip[ CLIP + gray + ng_yuv_blue[blue] ] /* ------------------------------------------------------------------- */ /* packed pixel yuv to gray / rgb */ static void yuv422_to_gray(unsigned char* restrict dest, unsigned char* restrict s, int p) { unsigned char* restrict d = dest; while (p) { d[0] = GRAY(s[0]); p--; d++; s+=2; } } static void yuv422_to_rgb24(unsigned char* restrict dest, unsigned char* restrict s, int p) { unsigned char* restrict d = dest; int gray; while (p) { gray = GRAY(s[0]); d[0] = RED(gray,s[3]); d[1] = GREEN(gray,s[3],s[1]); d[2] = BLUE(gray,s[1]); gray = GRAY(s[2]); d[3] = RED(gray,s[3]); d[4] = GREEN(gray,s[3],s[1]); d[5] = BLUE(gray,s[1]); d += 6; s += 4; p -= 2; } } void ng_yuv422_to_lut2(unsigned char* restrict dest, unsigned char* restrict s, int p) { unsigned short* restrict d = (unsigned short*)dest; int gray; while (p) { gray = GRAY(s[0]); *(d++) = ng_lut_red[RED(gray,s[3])] | ng_lut_green[GREEN(gray,s[3],s[1])] | ng_lut_blue[BLUE(gray,s[1])]; gray = GRAY(s[2]); *(d++) = ng_lut_red[RED(gray,s[3])] | ng_lut_green[GREEN(gray,s[3],s[1])] | ng_lut_blue[BLUE(gray,s[1])]; s += 4; p -= 2; } } void ng_yuv422_to_lut4(unsigned char* restrict dest, unsigned char* restrict s, int p) { unsigned int* restrict d = (unsigned int*)dest; int gray; while (p) { gray = GRAY(s[0]); *(d++) = ng_lut_red[RED(gray,s[3])] | ng_lut_green[GREEN(gray,s[3],s[1])] | ng_lut_blue[BLUE(gray,s[1])]; gray = GRAY(s[2]); *(d++) = ng_lut_red[RED(gray,s[3])] | ng_lut_green[GREEN(gray,s[3],s[1])] | ng_lut_blue[BLUE(gray,s[1])]; s += 4; p -= 2; } } /* ------------------------------------------------------------------- */ /* planar yuv to gray / rgb */ static void yuv42xp_to_gray(void *h, struct ng_video_buf *out, struct ng_video_buf *in) { unsigned char* restrict y; unsigned char* restrict d; unsigned char* dp; unsigned int i,j; dp = out->data; y = in->data; for (i = 0; i < in->fmt.height; i++) { d = dp; for (j = 0; j < in->fmt.width; j++) { *d = GRAY(*y); d++,y++; } dp += out->fmt.bytesperline; } } static void yuv420p_to_rgb24(void *h, struct ng_video_buf *out, struct ng_video_buf *in) { unsigned char *restrict y, *restrict u, *restrict v, *restrict d; unsigned char *us,*vs; unsigned char *dp; unsigned int i,j; int gray; dp = out->data; y = in->data; u = y + in->fmt.width * in->fmt.height; v = u + in->fmt.width * in->fmt.height / 4; for (i = 0; i < in->fmt.height; i++) { d = dp; us = u; vs = v; for (j = 0; j < in->fmt.width; j+= 2) { gray = GRAY(*y); *(d++) = RED(gray,*v); *(d++) = GREEN(gray,*v,*u); *(d++) = BLUE(gray,*u); y++; gray = GRAY(*y); *(d++) = RED(gray,*v); *(d++) = GREEN(gray,*v,*u); *(d++) = BLUE(gray,*u); y++; u++; v++; } if (0 == (i % 2)) { u = us; v = vs; } dp += out->fmt.bytesperline; } } static void yuv422p_to_rgb24(void *h, struct ng_video_buf *out, struct ng_video_buf *in) { unsigned char *restrict y, *restrict u, *restrict v, *restrict d; unsigned char *dp; unsigned int i,j; int gray; dp = out->data; y = in->data; u = y + in->fmt.width * in->fmt.height; v = u + in->fmt.width * in->fmt.height / 2; for (i = 0; i < in->fmt.height; i++) { d = dp; for (j = 0; j < in->fmt.width; j+= 2) { gray = GRAY(*y); *(d++) = RED(gray,*v); *(d++) = GREEN(gray,*v,*u); *(d++) = BLUE(gray,*u); y++; gray = GRAY(*y); *(d++) = RED(gray,*v); *(d++) = GREEN(gray,*v,*u); *(d++) = BLUE(gray,*u); y++; u++; v++; } dp += out->fmt.bytesperline; } } void ng_yuv420p_to_lut2(void *h, struct ng_video_buf *out, struct ng_video_buf *in) { unsigned char *restrict y, *restrict u, *restrict v; unsigned char *us,*vs; unsigned char *dp; unsigned short *restrict d; unsigned int i,j; int gray; dp = out->data; y = in->data; u = y + in->fmt.width * in->fmt.height; v = u + in->fmt.width * in->fmt.height / 4; for (i = 0; i < in->fmt.height; i++) { d = (unsigned short*) dp; us = u; vs = v; for (j = 0; j < in->fmt.width; j+= 2) { gray = GRAY(*y); *(d++) = ng_lut_red[RED(gray,*v)] | ng_lut_green[GREEN(gray,*v,*u)] | ng_lut_blue[BLUE(gray,*u)]; y++; gray = GRAY(*y); *(d++) = ng_lut_red[RED(gray,*v)] | ng_lut_green[GREEN(gray,*v,*u)] | ng_lut_blue[BLUE(gray,*u)]; y++; u++; v++; } if (0 == (i % 2)) { u = us; v = vs; } dp += out->fmt.bytesperline; } } void ng_yuv422p_to_lut2(void *h, struct ng_video_buf *out, struct ng_video_buf *in) { unsigned char *restrict y, *restrict u, *restrict v; unsigned char *dp; unsigned short *restrict d; unsigned int i,j; int gray; dp = out->data; y = in->data; u = y + in->fmt.width * in->fmt.height; v = u + in->fmt.width * in->fmt.height / 2; for (i = 0; i < in->fmt.height; i++) { d = (unsigned short*) dp; for (j = 0; j < in->fmt.width; j+= 2) { gray = GRAY(*y); *(d++) = ng_lut_red[RED(gray,*v)] | ng_lut_green[GREEN(gray,*v,*u)] | ng_lut_blue[BLUE(gray,*u)]; y++; gray = GRAY(*y); *(d++) = ng_lut_red[RED(gray,*v)] | ng_lut_green[GREEN(gray,*v,*u)] | ng_lut_blue[BLUE(gray,*u)]; y++; u++; v++; } dp += out->fmt.bytesperline; } } void ng_yuv420p_to_lut4(void *h, struct ng_video_buf *out, struct ng_video_buf *in) { unsigned char *restrict y, *restrict u, *restrict v; unsigned char *us,*vs; unsigned char *dp; unsigned int *restrict d; unsigned int i,j; int gray; dp = out->data; y = in->data; u = y + in->fmt.width * in->fmt.height; v = u + in->fmt.width * in->fmt.height / 4; for (i = 0; i < in->fmt.height; i++) { d = (unsigned int*) dp; us = u; vs = v; for (j = 0; j < in->fmt.width; j+= 2) { gray = GRAY(*y); *(d++) = ng_lut_red[RED(gray,*v)] | ng_lut_green[GREEN(gray,*v,*u)] | ng_lut_blue[BLUE(gray,*u)]; y++; gray = GRAY(*y); *(d++) = ng_lut_red[RED(gray,*v)] | ng_lut_green[GREEN(gray,*v,*u)] | ng_lut_blue[BLUE(gray,*u)]; y++; u++; v++; } if (0 == (i % 2)) { u = us; v = vs; } dp += out->fmt.bytesperline; } } void ng_yuv422p_to_lut4(void *h, struct ng_video_buf *out, struct ng_video_buf *in) { unsigned char *restrict y, *restrict u, *restrict v; unsigned char *dp; unsigned int *restrict d; unsigned int i,j; int gray; dp = out->data; y = in->data; u = y + in->fmt.width * in->fmt.height; v = u + in->fmt.width * in->fmt.height / 2; for (i = 0; i < in->fmt.height; i++) { d = (unsigned int*) dp; for (j = 0; j < in->fmt.width; j+= 2) { gray = GRAY(*y); *(d++) = ng_lut_red[RED(gray,*v)] | ng_lut_green[GREEN(gray,*v,*u)] | ng_lut_blue[BLUE(gray,*u)]; y++; gray = GRAY(*y); *(d++) = ng_lut_red[RED(gray,*v)] | ng_lut_green[GREEN(gray,*v,*u)] | ng_lut_blue[BLUE(gray,*u)]; y++; u++; v++; } dp += out->fmt.bytesperline; } } /* ------------------------------------------------------------------- */ static struct ng_video_conv conv_list[] = { { NG_GENERIC_PACKED, .fmtid_in = VIDEO_YUYV, .fmtid_out = VIDEO_RGB24, .priv = yuv422_to_rgb24, },{ NG_GENERIC_PACKED, .fmtid_in = VIDEO_YUYV, .fmtid_out = VIDEO_GRAY, .priv = yuv422_to_gray, },{ .init = ng_conv_nop_init, .fini = ng_conv_nop_fini, .frame = yuv422p_to_rgb24, .fmtid_in = VIDEO_YUV422P, .fmtid_out = VIDEO_RGB24, },{ .init = ng_conv_nop_init, .fini = ng_conv_nop_fini, .frame = yuv420p_to_rgb24, .fmtid_in = VIDEO_YUV420P, .fmtid_out = VIDEO_RGB24, },{ .init = ng_conv_nop_init, .fini = ng_conv_nop_fini, .frame = yuv42xp_to_gray, .fmtid_in = VIDEO_YUV422P, .fmtid_out = VIDEO_GRAY, },{ .init = ng_conv_nop_init, .fini = ng_conv_nop_fini, .frame = yuv42xp_to_gray, .fmtid_in = VIDEO_YUV420P, .fmtid_out = VIDEO_GRAY, } }; static const int nconv = sizeof(conv_list)/sizeof(struct ng_video_conv); /* ------------------------------------------------------------------- */ void ng_color_yuv2rgb_init(void) { int i; /* init Lookup tables */ for (i = 0; i < 256; i++) { ng_yuv_gray[i] = i * LUN_MUL >> 8; ng_yuv_red[i] = (RED_ADD + i * RED_MUL) >> 8; ng_yuv_blue[i] = (BLUE_ADD + i * BLUE_MUL) >> 8; ng_yuv_g1[i] = (GREEN1_ADD + i * GREEN1_MUL) >> 8; ng_yuv_g2[i] = (GREEN2_ADD + i * GREEN2_MUL) >> 8; } for (i = 0; i < CLIP; i++) ng_clip[i] = 0; for (; i < CLIP + 256; i++) ng_clip[i] = i - CLIP; for (; i < 2 * CLIP + 256; i++) ng_clip[i] = 255; /* register stuff */ ng_conv_register(NG_PLUGIN_MAGIC,"built-in",conv_list,nconv); } xawtv-3.106/libng/contrib-plugins/000077500000000000000000000000001343350355000171075ustar00rootroot00000000000000xawtv-3.106/libng/contrib-plugins/Subdir.mk000066400000000000000000000023661343350355000206770ustar00rootroot00000000000000 # targets to build TARGETS-contrib-plugins := \ libng/contrib-plugins/flt-smooth.so \ libng/contrib-plugins/bilinear.so \ libng/contrib-plugins/cubic.so \ libng/contrib-plugins/linear-blend.so \ libng/contrib-plugins/linedoubler.so ifeq ($(FOUND_ALSA),yes) #TARGETS-contrib-plugins += \ # libng/contrib-plugins/snd-alsa.so endif # alsa is c++ and thus we should call g++ for linking ... libng/contrib-plugins/snd-alsa.so : CC := $(CXX) libng/contrib-plugins/snd-alsa.so : LDLIBS := $(ALSA_LIBS) # linear-blend has mmx support ... ifeq ($(USE_MMX),yes) libng/contrib-plugins/linear-blend.so : CFLAGS += -DMMX=1 endif # global targets all:: $(TARGETS-contrib-plugins) install:: $(INSTALL_DIR) $(libdir) $(INSTALL_PROGRAM) $(STRIP_FLAG) $(TARGETS-contrib-plugins) $(libdir) clean:: rm -f $(TARGETS-contrib-plugins) libng/contrib-plugins/flt-smooth.so: libng/contrib-plugins/flt-smooth.o libng/contrib-plugins/snd-alsa.so: libng/contrib-plugins/snd-alsa.o libng/contrib-plugins/bilinear.so: libng/contrib-plugins/bilinear.o libng/contrib-pluginsa/cubic.so: libng/contrib-plugins/cubic.o libng/contrib-plugins/linear-blend.so: libng/contrib-plugins/linear-blend.o libng/contrib-plugins/linedoubler.so: libng/contrib-plugins/linedoubler.o xawtv-3.106/libng/contrib-plugins/bilinear.c000066400000000000000000000043501343350355000210420ustar00rootroot00000000000000/* * Simple xawtv deinterlacing plugin - bilinear interpolation * * CAVEATS: Effectively halves framerate, (working on it) * May cause some general slowness (uses more cpu) but the framerate is smooth * on my athlon 700, running the -mjc branch of 2.4 kernel (preempt and other * patches for desktop performance) * Text (in console games for example) looks really ugly * * BENEFITS: It's no longer interlaced ;) * Looks a metric shitton better than line doubling * * AUTHORS: * Conrad Kreyling * Patrick Barrett * * This is licenced under the GNU GPL until someone tells me I'm stealing code * and can't do that ;) www.gnu.org for any version of the license. * * Based on xawtv-3.66/libng/plugins/flt-nop.c (also GPL) */ #include "config.h" #include #include #include #include "grab-ng.h" static void inline deinterlace (struct ng_video_buf *frame) { unsigned int x, y; for (y = 1; y < frame->fmt.height - 1; y += 2) for (x = 0; x < frame->fmt.bytesperline + 1; x++) (frame->data[y * (frame->fmt.bytesperline) + x]) = ((frame->data[((y - 1) * (frame->fmt.bytesperline)) + x]) + (frame->data[((y + 1) * (frame->fmt.bytesperline)) + x])) >> 1; } static void * init (struct ng_video_fmt *out) { /* don't have to carry around status info */ static int dummy; return &dummy; } static struct ng_video_buf * frame (void *handle, struct ng_video_buf *frame) { deinterlace (frame); // In hindsight, we may not have needed the function ;) // Added clarity when we make it more complicated. return frame; } static void fini (void *handle) { /* nothing to clean up */ } /* ------------------------------------------------------------------- */ static struct ng_filter filter = { .name = "bilinear deinterlace", .fmts = (1 << VIDEO_GRAY) | (1 << VIDEO_RGB15_NATIVE) | (1 << VIDEO_RGB16_NATIVE) | (1 << VIDEO_BGR24) | (1 << VIDEO_RGB24) | (1 << VIDEO_BGR32) | (1 << VIDEO_RGB32) | (1 << VIDEO_YUYV) | (1 << VIDEO_UYVY), .init = init, .frame = frame, .fini = fini, }; extern void ng_plugin_init (void); void ng_plugin_init (void) { ng_filter_register (NG_PLUGIN_MAGIC,__FILE__,&filter); } xawtv-3.106/libng/contrib-plugins/cubic.c000066400000000000000000000061551343350355000203470ustar00rootroot00000000000000/* * Simple xawtv deinterlacing plugin - cubic interpolation * * CAVEATS: Effectively halves framerate, (working on it) * May cause some general slowness (uses more cpu) but the framerate is smooth * on my athlon 700, running the -mjc branch of 2.4 kernel (preempt and other * patches for desktop performance) * * BENEFITS: It's no longer interlaced ;) * Looks a metric shitton better than line doubling & bilinear interpolation * around text, but these nasty white specks occur on the border of pure black * (0) and pure white (255). My original theory was that it had something to * do with 0 messing up our multiplication, but that does not appear to be the * case based on preliminary fiddling around. * * AUTHORS: * Conrad Kreyling * Patrick Barrett * * This is licenced under the GNU GPL until someone tells me I'm stealing code * and can't do that ;) www.gnu.org for any version of the license. * * Based on xawtv-3.66/libng/plugins/flt-nop.c (also GPL) * Cubic deinterlacing algorithm adapted from mplayer's libpostproc */ #include "config.h" #include #include #include #include "grab-ng.h" /*static int isOdd; // Global variable so we can tell if a frame uses even or //odd scanlines, not implemented properly yet */ static void inline deinterlace (struct ng_video_buf *frame) { unsigned int x, y, bytes = frame->fmt.bytesperline; /* * if(isOdd){ * isOdd=0; * y=3; * } * else * { * isOdd=1; * y=4; * } //Set y based on scanline evenness/oddness, not implemented yet */ /* for (x=0; x < strlen(frame->data); x++){ switch (frame->data[x]) { case 0: frame->data[x]++; break; case 255: frame->data[x]--; break; } }*/ // This doesn't work to fix the problem with the specks for (y = 3; y < frame->fmt.height - 3; y += 2) { for (x = 0; x < bytes; x++) { frame->data[(y * bytes + x)] = ((-frame->data[((y - 3) * bytes + x)]) + (9 * frame->data[((y - 1) * bytes + x)]) + (9 * frame->data[((y + 1) * bytes + x)]) + (-frame->data[((y + 3) * bytes + x)])) >> 4; } // Basic algorithm borrowed from mplayer's libpostproc } // Angry math } static void * init (struct ng_video_fmt *out) { /* we will be using this variable soon enough */ static int isOdd = 0; return &isOdd; } static struct ng_video_buf * frame (void *handle, struct ng_video_buf *frame) { deinterlace (frame); return frame; } static void fini (void *handle) { /* nothing to clean up */ } /* ------------------------------------------------------------------- */ static struct ng_filter filter = { .name ="cubic interpolation", .fmts = (1 << VIDEO_GRAY) | (1 << VIDEO_RGB15_NATIVE) | (1 << VIDEO_RGB16_NATIVE) | (1 << VIDEO_BGR24) | (1 << VIDEO_RGB24) | (1 << VIDEO_BGR32) | (1 << VIDEO_RGB32) | (1 << VIDEO_YUYV) | (1 << VIDEO_UYVY), .init = init, .frame = frame, .fini = fini, }; extern void ng_plugin_init (void); void ng_plugin_init (void) { ng_filter_register (NG_PLUGIN_MAGIC,__FILE__,&filter); } xawtv-3.106/libng/contrib-plugins/flt-smooth.c000066400000000000000000000307551343350355000213610ustar00rootroot00000000000000/* * libng filter -- Smooth the image to reduce snow at bad TV receiption * * * Filter options * -------------- * * There are 2 options available that can be turned on and off separately. * * Smooth over time: Calculate average of previous and current frame. * Longer filter lengths could improve static * images but would be unusable for movies and * require high CPU power. I found averaging of * 2 frames the most useful filter. * * Smooth horizontally: For every pixel, the average of the actual colour * and the colour of the pixel to the left is displayed. * * * (c) 2002 Klaus Peichl (smoothing filter), * Gerd Knorr (framework) * */ #include "config.h" #include #include #include #include "grab-ng.h" /* ------------------------------------------------------------------- */ typedef struct { struct ng_video_buf * pLastFrame; } SMOOTH_BUFFER; static int smoothTime = 1; static int smoothHorizontal = 1; #if 1 /* Fast 32-bit smoothing */ static void inline smooth_native_32bit(unsigned int *last, unsigned int *dst, unsigned int *src, int pixels) { unsigned int old,new, old2,new2; if (smoothTime && smoothHorizontal) { /* Smoothing in time and horizontally */ old2 = *last; new2 = *src; while (pixels--) { old = *last; new = *src++; *last++ = new; /* Fast averaging: All 4 bytes (of which only 3 are used) can be averaged in one 32bit-word. The lowest 2 bits of every colour are thrown away to avoid influences between the colours. */ *dst++ = ((new >> 2) & 0x3F3F3F3F) + ((new2 >> 2) & 0x3F3F3F3F) + ((old >> 2) & 0x3F3F3F3F) + ((old2 >> 2) & 0x3F3F3F3F); old2 = old; new2 = new; } } else if (smoothTime) { /* Smoothing in time only */ while (pixels--) { old = *last; new = *src++; *last++ = new; /* Fast averaging: All 4 bytes (of which only 3 are used) can be averaged in one 32bit-word. The lowest bit of every colour is thrown away to avoid influences between the colours. */ *dst++ = ((new >> 1) & 0x7F7F7F7F) + ((old >> 1) & 0x7F7F7F7F); } } else if (smoothHorizontal) { /* Smooth horizontally only */ new2 = *src; while (pixels--) { new = *src++; *last++ = new; /* Fast averaging: All 4 bytes (of which only 3 are used) can be averaged in one 32bit-word. The lowest bit of every colour is thrown away to avoid influences between the colours. */ *dst++ = ((new >> 1) & 0x7F7F7F7F) + ((new2 >> 1) & 0x7F7F7F7F); new2 = new; } } else { /* No smoothing at all */ while (pixels--) { new = *src++; *last++ = new; *dst++ = new; } } } #else /* This is an alternative implementation of the above function which does not throw away the lowest bits before addition. It is derived from the byte-based 24-bit-function below but processes 4 bytes for every pixel instead of 3. */ static void inline smooth_native_32bit(unsigned char *last, unsigned char *dst, unsigned char *src, int pixels) { unsigned char oldR,newR, oldR2,newR2; unsigned char oldG,newG, oldG2,newG2; unsigned char oldB,newB, oldB2,newB2; unsigned char oldP,newP, oldP2,newP2; if (smoothTime && smoothHorizontal) { /* Smoothing in time and horizontally */ oldR2 = last[0]; oldG2 = last[1]; oldB2 = last[2]; oldP2 = last[3]; newR2 = src[0]; newG2 = src[1]; newB2 = src[2]; newP2 = src[3]; while (pixels--) { oldR = *last; newR = *src++; *last++ = newR; oldG = *last; newG = *src++; *last++ = newG; oldB = *last; newB = *src++; *last++ = newB; oldP = *last; newP = *src++; *last++ = newP; *dst++ = (newR + oldR + newR2 + oldR2) / 4; *dst++ = (newG + oldG + newG2 + oldG2) / 4; *dst++ = (newB + oldB + newB2 + oldB2) / 4; *dst++ = (newP + oldP + newP2 + oldP2) / 4; oldR2 = oldR; oldG2 = oldG; oldB2 = oldB; oldP2 = oldP; newR2 = newR; newG2 = newG; newB2 = newB; newP2 = newP; } } else if (smoothTime) { /* Smoothing in time only */ while (pixels--) { oldR = *last; newR = *src++; *last++ = newR; oldG = *last; newG = *src++; *last++ = newG; oldB = *last; newB = *src++; *last++ = newB; oldP = *last; newP = *src++; *last++ = newP; *dst++ = (newR + oldR) / 2; *dst++ = (newG + oldG) / 2; *dst++ = (newB + oldB) / 2; *dst++ = (newP + oldP) / 2; } } else if (smoothHorizontal) { /* Smooth horizontally only */ newR2 = src[0]; newG2 = src[1]; newB2 = src[2]; newP2 = src[3]; while (pixels--) { newR = *src++; *last++ = newR; newG = *src++; *last++ = newG; newB = *src++; *last++ = newB; newP = *src++; *last++ = newP; *dst++ = (newR + newR2) / 2; *dst++ = (newG + newG2) / 2; *dst++ = (newB + newB2) / 2; *dst++ = (newP + newP2) / 2; newR2 = newR; newG2 = newG; newB2 = newB; newP2 = newP; } } else { /* No smoothing at all */ while (pixels--) { newR = *src++; *last++ = newR; *dst++ = newR; newG = *src++; *last++ = newG; *dst++ = newG; newB = *src++; *last++ = newB; *dst++ = newB; newP = *src++; *last++ = newP; *dst++ = newP; } } } #endif static void inline smooth_native_24bit(unsigned char *last, unsigned char *dst, unsigned char *src, int pixels) { unsigned char oldR,newR, oldR2,newR2; unsigned char oldG,newG, oldG2,newG2; unsigned char oldB,newB, oldB2,newB2; if (smoothTime && smoothHorizontal) { /* Smoothing in time and horizontally */ oldR2 = last[0]; oldG2 = last[1]; oldB2 = last[2]; newR2 = src[0]; newG2 = src[1]; newB2 = src[2]; while (pixels--) { oldR = *last; newR = *src++; *last++ = newR; oldG = *last; newG = *src++; *last++ = newG; oldB = *last; newB = *src++; *last++ = newB; *dst++ = (newR + oldR + newR2 + oldR2) / 4; *dst++ = (newG + oldG + newG2 + oldG2) / 4; *dst++ = (newB + oldB + newB2 + oldB2) / 4; oldR2 = oldR; oldG2 = oldG; oldB2 = oldB; newR2 = newR; newG2 = newG; newB2 = newB; } } else if (smoothTime) { /* Smoothing in time only */ while (pixels--) { oldR = *last; newR = *src++; *last++ = newR; oldG = *last; newG = *src++; *last++ = newG; oldB = *last; newB = *src++; *last++ = newB; *dst++ = (newR + oldR) / 2; *dst++ = (newG + oldG) / 2; *dst++ = (newB + oldB) / 2; } } else if (smoothHorizontal) { /* Smooth horizontally only */ newR2 = src[0]; newG2 = src[1]; newB2 = src[2]; while (pixels--) { newR = *src++; *last++ = newR; newG = *src++; *last++ = newG; newB = *src++; *last++ = newB; *dst++ = (newR + newR2) / 2; *dst++ = (newG + newG2) / 2; *dst++ = (newB + newB2) / 2; newR2 = newR; newG2 = newG; newB2 = newB; } } else { /* No smoothing at all */ while (pixels--) { newR = *src++; *last++ = newR; *dst++ = newR; newG = *src++; *last++ = newG; *dst++ = newG; newB = *src++; *last++ = newB; *dst++ = newB; } } } static void inline smooth_native_16bit(unsigned short *last, unsigned short *dst, unsigned short *src, unsigned short maskR, unsigned short maskG, unsigned short maskB, int pixels) { unsigned short old,new, old2,new2; unsigned short red,green,blue; if (smoothTime && smoothHorizontal) { /* Smoothing in time and horizontally */ old2 = *last; new2 = *src; while (pixels--) { old = *last; new = *src++; *last++ = new; red = ( ((new & maskR) + (old & maskR) + (new2 & maskR) + (old2 & maskR))/4 ) & maskR; green = ( ((new & maskG) + (old & maskG) + (new2 & maskG) + (old2 & maskG))/4 ) & maskG; blue = ( ((new & maskB) + (old & maskB) + (new2 & maskB) + (old2 & maskB))/4 ) & maskB; *dst++ = red | green | blue; old2 = old; new2 = new; } } else if (smoothTime) { /* Smoothing in time only */ while (pixels--) { old = *last; new = *src++; *last++ = new; red = ( ((new & maskR) + (old & maskR))/2 ) & maskR; green = ( ((new & maskG) + (old & maskG))/2 ) & maskG; blue = ( ((new & maskB) + (old & maskB))/2 ) & maskB; *dst++ = red | green | blue; } } else if (smoothHorizontal) { /* Smooth horizontally only */ new2 = *src; while (pixels--) { new = *src++; *last++ = new; red = ( ((new & maskR) + (new2 & maskR))/2 ) & maskR; green = ( ((new & maskG) + (new2 & maskG))/2 ) & maskG; blue = ( ((new & maskB) + (new2 & maskB))/2 ) & maskB; *dst++ = red | green | blue; new2 = new; } } else { /* No smoothing at all */ while (pixels--) { new = *src++; *last++ = new; *dst++ = new; } } } /* ------------------------------------------------------------------- */ static void *init(struct ng_video_fmt *out) { /* don't have to carry around status info */ static SMOOTH_BUFFER smooth_buffer; smooth_buffer.pLastFrame = ng_malloc_video_buf(out, out->height * out->bytesperline); return &smooth_buffer; } static struct ng_video_buf* frame(void *h, struct ng_video_buf *in) { SMOOTH_BUFFER *handle = h; struct ng_video_buf *out; unsigned char *dst; unsigned char *src; unsigned char *last; unsigned int y; out = ng_malloc_video_buf(&in->fmt, in->fmt.height * in->fmt.bytesperline); out->info = in->info; dst = out->data; src = in->data; last = handle->pLastFrame->data; for (y = 0; y < in->fmt.height; y++) { switch (in->fmt.fmtid) { case VIDEO_GRAY: case VIDEO_BGR24: case VIDEO_RGB24: smooth_native_24bit((unsigned char*)last, (unsigned char*)dst, (unsigned char*)src, in->fmt.width); break; case VIDEO_BGR32: case VIDEO_RGB32: case VIDEO_YUYV: case VIDEO_UYVY: smooth_native_32bit((unsigned int*)last, (unsigned int*)dst, (unsigned int*)src, in->fmt.width); break; case VIDEO_RGB15_NATIVE: smooth_native_16bit((unsigned short*)last, (unsigned short*)dst, (unsigned short*)src, 0x7C00, /* mask for red */ 0x03E0, /* mask for green */ 0x001F, /* mask for blue */ in->fmt.width); break; case VIDEO_RGB16_NATIVE: smooth_native_16bit((unsigned short*)last, (unsigned short*)dst, (unsigned short*)src, 0xF800, /* mask for red */ 0x07E0, /* mask for green */ 0x001F, /* mask for blue */ in->fmt.width); break; } dst += out->fmt.bytesperline; src += in->fmt.bytesperline; last += in->fmt.bytesperline; } ng_release_video_buf(in); return out; } static void fini(void *handle) { ng_release_video_buf(handle); } static int read_attr(struct ng_attribute *attr) { int value; switch (attr->id) { case 0: value = smoothTime; break; case 1: value = smoothHorizontal; break; default: value = 0; } return value; } static void write_attr(struct ng_attribute *attr, int value) { switch (attr->id) { case 0: smoothTime = value; break; case 1: smoothHorizontal = value; break; } } /* ------------------------------------------------------------------- */ static struct ng_attribute attrs[] = { { .id = 0, .name = "smooth over time", .type = ATTR_TYPE_BOOL, .defval = 1, .read = read_attr, .write = write_attr, },{ .id = 1, .name = "smooth horizontally", .type = ATTR_TYPE_BOOL, .defval = 1, .read = read_attr, .write = write_attr, },{ /* end of list */ } }; static struct ng_filter filter = { .name = "smooth", .attrs = attrs, .fmts = (1 << VIDEO_GRAY) | (1 << VIDEO_RGB15_NATIVE) | (1 << VIDEO_RGB16_NATIVE) | (1 << VIDEO_BGR24) | (1 << VIDEO_RGB24) | (1 << VIDEO_BGR32) | (1 << VIDEO_RGB32) | (1 << VIDEO_YUYV) | (1 << VIDEO_UYVY), .init = init, .frame = frame, .fini = fini, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_filter_register(NG_PLUGIN_MAGIC,__FILE__,&filter); } xawtv-3.106/libng/contrib-plugins/linear-blend.c000066400000000000000000000125501343350355000216120ustar00rootroot00000000000000/* * Simple xawtv deinterlacing plugin - linear blend * * CAVEATS: Still some interlacing effects in high motion perhaps * Some ghosting in instant transitions, slightly noticeable * * BENEFITS: NO DROP IN FRAMERATE =] * Looks absolutely beautiful * Doesn't lower framerate * Oh and did I mention it doesn't lower framerate? * Plus, its MMX'itized now, so it really doesn't lower framerate. * * AUTHORS: * Conrad Kreyling * Patrick Barrett * * This is licenced under the GNU GPL until someone tells me I'm stealing code * and can't do that ;) www.gnu.org for any version of the license. * * Based on xawtv-3.72/libng/plugins/flt-nop.c (also GPL) * Linear blend deinterlacing algorithm adapted from mplayer's libpostproc */ #include "config.h" #include #include #include #include "grab-ng.h" #define PAVGB(a,b) "pavgb " #a ", " #b " \n\t" #ifdef MMX #define emms() __asm__ __volatile__ ("emms") #else #define emms() #endif static inline void linearBlend(unsigned char *src, int stride) { #ifdef MMX asm volatile( "leal (%0, %1), %%eax \n\t" "leal (%%eax, %1, 4), %%edx \n\t" "movq (%0), %%mm0 \n\t" // L0 "movq (%%eax, %1), %%mm1 \n\t" // L2 PAVGB(%%mm1, %%mm0) // L0+L2 "movq (%%eax), %%mm2 \n\t" // L1 PAVGB(%%mm2, %%mm0) "movq %%mm0, (%0) \n\t" "movq (%%eax, %1, 2), %%mm0 \n\t" // L3 PAVGB(%%mm0, %%mm2) // L1+L3 PAVGB(%%mm1, %%mm2) // 2L2 + L1 + L3 "movq %%mm2, (%%eax) \n\t" "movq (%0, %1, 4), %%mm2 \n\t" // L4 PAVGB(%%mm2, %%mm1) // L2+L4 PAVGB(%%mm0, %%mm1) // 2L3 + L2 + L4 "movq %%mm1, (%%eax, %1) \n\t" "movq (%%edx), %%mm1 \n\t" // L5 PAVGB(%%mm1, %%mm0) // L3+L5 PAVGB(%%mm2, %%mm0) // 2L4 + L3 + L5 "movq %%mm0, (%%eax, %1, 2) \n\t" "movq (%%edx, %1), %%mm0 \n\t" // L6 PAVGB(%%mm0, %%mm2) // L4+L6 PAVGB(%%mm1, %%mm2) // 2L5 + L4 + L6 "movq %%mm2, (%0, %1, 4) \n\t" "movq (%%edx, %1, 2), %%mm2 \n\t" // L7 PAVGB(%%mm2, %%mm1) // L5+L7 PAVGB(%%mm0, %%mm1) // 2L6 + L5 + L7 "movq %%mm1, (%%edx) \n\t" "movq (%0, %1, 8), %%mm1 \n\t" // L8 PAVGB(%%mm1, %%mm0) // L6+L8 PAVGB(%%mm2, %%mm0) // 2L7 + L6 + L8 "movq %%mm0, (%%edx, %1) \n\t" "movq (%%edx, %1, 4), %%mm0 \n\t" // L9 PAVGB(%%mm0, %%mm2) // L7+L9 PAVGB(%%mm1, %%mm2) // 2L8 + L7 + L9 "movq %%mm2, (%%edx, %1, 2) \n\t" : : "r" (src), "r" (stride) : "%eax", "%edx" ); emms(); #else int x; for (x=0; x<8; x++) { src[0 ] = (src[0 ] + 2*src[stride ] + src[stride*2])>>2; src[stride ] = (src[stride ] + 2*src[stride*2] + src[stride*3])>>2; src[stride*2] = (src[stride*2] + 2*src[stride*3] + src[stride*4])>>2; src[stride*3] = (src[stride*3] + 2*src[stride*4] + src[stride*5])>>2; src[stride*4] = (src[stride*4] + 2*src[stride*5] + src[stride*6])>>2; src[stride*5] = (src[stride*5] + 2*src[stride*6] + src[stride*7])>>2; src[stride*6] = (src[stride*6] + 2*src[stride*7] + src[stride*8])>>2; src[stride*7] = (src[stride*7] + 2*src[stride*8] + src[stride*9])>>2; src++; } #endif } static void inline deinterlace (struct ng_video_buf *frame) { unsigned int x, y, bytes = frame->fmt.bytesperline; unsigned char *src; for (y = 1; y < frame->fmt.height - 8; y+=8) { for (x = 0; x < bytes; x+=8) { src = frame->data + x + y * bytes; linearBlend(src, bytes); } } emms(); } static void * init (struct ng_video_fmt *out) { /* no status info needed */ static int dummy; return &dummy; } static struct ng_video_buf * frame (void *handle, struct ng_video_buf *frame) { deinterlace (frame); return frame; } static void fini (void *handle) { /* nothing to clean up */ } /* ------------------------------------------------------------------- */ static struct ng_filter filter = { .name = "linear blend", .fmts = (1 << VIDEO_GRAY) | (1 << VIDEO_RGB15_NATIVE) | (1 << VIDEO_RGB16_NATIVE) | (1 << VIDEO_BGR24) | (1 << VIDEO_RGB24) | (1 << VIDEO_BGR32) | (1 << VIDEO_RGB32) | (1 << VIDEO_YUYV) | (1 << VIDEO_UYVY), .init = init, .frame = frame, .fini = fini, }; extern void ng_plugin_init (void); void ng_plugin_init (void) { ng_filter_register (NG_PLUGIN_MAGIC,__FILE__,&filter); } xawtv-3.106/libng/contrib-plugins/linedoubler.c000066400000000000000000000041561343350355000215650ustar00rootroot00000000000000/* * Simple xawtv deinterlacing plugin - line doubling * * CAVEATS: Effectively halves framerate and vertical resolution * Framerate problem is to be addressed, vertical resolution problem is * inherent in line doubling. Use one of the interpolating (or blending, when * we write them) filters. * * BENEFITS: It's no longer interlaced ;) thats about it. * * AUTHORS: * Conrad Kreyling * Patrick Barrett * * This is licenced under the GNU GPL until someone tells me I'm stealing code * and can't do that ;) www.gnu.org for any version of the license. * * Based on xawtv-3.67/libng/plugins/flt-nop.c (also GPL) */ #include "config.h" #include #include #include #include "grab-ng.h" static void inline deinterlace(struct ng_video_buf *frame) { unsigned int x,y; for (y = 1; y < frame->fmt.height; y += 2) for (x = 0; x < frame->fmt.bytesperline + 1; x++) frame->data[(y * frame->fmt.bytesperline) + x] = frame->data[((y - 1) * frame->fmt.bytesperline) + x]; } static void *init(struct ng_video_fmt *out) { /* don't have to carry around status info */ static int dummy; return &dummy; } static struct ng_video_buf* frame(void *handle, struct ng_video_buf *frame) { deinterlace(frame); // In hindsight, we may not have needed the function ;) // Added clarity when we make it more complicated. return frame; } static void fini(void *handle) { /* nothing to clean up */ } /* ------------------------------------------------------------------- */ static struct ng_filter filter = { .name = "line doubler deinterlace", .fmts = (1 << VIDEO_GRAY) | (1 << VIDEO_RGB15_NATIVE) | (1 << VIDEO_RGB16_NATIVE) | (1 << VIDEO_BGR24) | (1 << VIDEO_RGB24) | (1 << VIDEO_BGR32) | (1 << VIDEO_RGB32) | (1 << VIDEO_YUYV) | (1 << VIDEO_UYVY), .init = init, .frame = frame, .fini = fini, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_filter_register(NG_PLUGIN_MAGIC,__FILE__,&filter); } xawtv-3.106/libng/contrib-plugins/snd-alsa.cc000066400000000000000000000131501343350355000211200ustar00rootroot00000000000000/* Copyright (c) 2002 Malte Starostik 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include extern "C" { # include "grab-ng.h" } class alsa_mixer; class attr_proxy : public ng_attribute { public: typedef int ( alsa_mixer::*accessor )(); typedef void ( alsa_mixer::*mutator )( int ); attr_proxy() { std::memset( this, 0, sizeof( ng_attribute ) ); } attr_proxy( int type, int id, const char* name, alsa_mixer* instance, accessor read, mutator write ) { this->id = id; this->name = name; this->type = type; this->read = &read_proxy; this->write = &write_proxy; handle_data* d = new handle_data; d->instance = instance; d->read = read; d->write = write; this->handle = d; } attr_proxy( const attr_proxy& other ) { handle = 0; *this = other; } attr_proxy& operator =( const attr_proxy& rhs ) { if ( &rhs != this ) { deref(); std::memcpy( this, &rhs, sizeof( ng_attribute ) ); ref(); } return *this; } ~attr_proxy() { deref(); } private: struct handle_data { handle_data() : ref_count( 1 ) {} alsa_mixer* instance; accessor read; mutator write; int ref_count; }; handle_data* data() const { return reinterpret_cast< handle_data* >( handle ); } void ref() { if ( data() ) data()->ref_count++; } void deref() { if ( data() && !--data()->ref_count ) { delete data(); handle = 0; } } static int read_proxy( ng_attribute* attr ) { handle_data* d = reinterpret_cast< handle_data* >( attr->handle ); return ( d->instance->*d->read )(); } static void write_proxy( ng_attribute* attr, int val ) { handle_data* d = reinterpret_cast< handle_data* >( attr->handle ); ( d->instance->*d->write )( val ); } }; class alsa_mixer { public: alsa_mixer(); ~alsa_mixer(); bool init( const char* channel ); int mute(); void mute( int val ); int volume(); void volume( int val ); static void* open( char* ); static void close( void* inst ); static ng_devinfo* probe(); static ng_devinfo* channels( char* device ); static ng_attribute* volctl( void* inst, char* channel ); private: std::vector< attr_proxy > attrs; snd_mixer_t* handle; snd_mixer_elem_t* elem; bool muted; }; alsa_mixer::alsa_mixer() : attrs( 3 ) { snd_mixer_open( &handle, 0 ); snd_mixer_attach( handle, "default" ); snd_mixer_selem_register( handle, 0, 0 ); snd_mixer_load( handle ); attrs[ 0 ] = attr_proxy( ATTR_TYPE_BOOL, ATTR_ID_MUTE, "mute", this, &alsa_mixer::mute, &alsa_mixer::mute ); attrs[ 1 ] = attr_proxy( ATTR_TYPE_INTEGER, ATTR_ID_VOLUME, "volume", this, &alsa_mixer::volume, &alsa_mixer::volume ); } alsa_mixer::~alsa_mixer() { if ( handle ) snd_mixer_close( handle ); } bool alsa_mixer::init( const char* channel ) { for ( elem = snd_mixer_first_elem( handle ); elem; elem = snd_mixer_elem_next( elem ) ) if ( strcasecmp( channel, snd_mixer_selem_get_name( elem ) ) == 0 ) { long min, max; snd_mixer_selem_get_playback_volume_range( elem, &min, &max ); attrs[ 1 ].min = min; attrs[ 1 ].max = max; return true; } return false; } int alsa_mixer::mute() { int left, right; snd_mixer_selem_get_playback_switch( elem, SND_MIXER_SCHN_FRONT_LEFT, &left ); snd_mixer_selem_get_playback_switch( elem, SND_MIXER_SCHN_FRONT_RIGHT, &right ); return !left && !right; } void alsa_mixer::mute( int val ) { snd_mixer_selem_set_playback_switch( elem, SND_MIXER_SCHN_FRONT_LEFT, !val ); snd_mixer_selem_set_playback_switch( elem, SND_MIXER_SCHN_FRONT_RIGHT, !val ); } int alsa_mixer::volume() { long left, right; snd_mixer_selem_get_playback_volume( elem, SND_MIXER_SCHN_FRONT_LEFT, &left ); snd_mixer_selem_get_playback_volume( elem, SND_MIXER_SCHN_FRONT_RIGHT, &right ); return ( left + right ) / 2; } void alsa_mixer::volume( int val ) { snd_mixer_selem_set_playback_volume( elem, SND_MIXER_SCHN_FRONT_LEFT, val ); snd_mixer_selem_set_playback_volume( elem, SND_MIXER_SCHN_FRONT_RIGHT, val ); } void* alsa_mixer::open( char* ) { return new alsa_mixer(); } void alsa_mixer::close( void* inst ) { delete reinterpret_cast< alsa_mixer* >( inst ); } ng_devinfo* alsa_mixer::probe() { std::cerr << "alsa_mixer::probe not implemented" << std::endl; return 0; } ng_devinfo* alsa_mixer::channels( char* device ) { std::cerr << "alsa_mixer::channels not implemented" << std::endl; return 0; } ng_attribute* alsa_mixer::volctl( void* instance, char* channel ) { alsa_mixer* mixer = reinterpret_cast< alsa_mixer* >( instance ); return mixer->init( channel ) ? &mixer->attrs[ 0 ] : 0; } extern "C" void ng_plugin_init( void ) { static struct ng_mix_driver mixer_info = { /* name */ "alsa", /* probe */ alsa_mixer::probe, /* channels */ alsa_mixer::channels, /* open */ alsa_mixer::open, /* volctl */ alsa_mixer::volctl, /* close */ alsa_mixer::close, }; ng_mix_driver_register( NG_PLUGIN_MAGIC, __FILE__, &mixer_info ); } // vim: ts=4 sw=4 noet xawtv-3.106/libng/convert.c000066400000000000000000000062761343350355000156270ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include "grab-ng.h" /*-------------------------------------------------------------------------*/ /* color space conversion / compression helper functions */ struct ng_convert_handle* ng_convert_alloc(struct ng_video_conv *conv, struct ng_video_fmt *i, struct ng_video_fmt *o) { struct ng_convert_handle *h; h = malloc(sizeof(*h)); if (NULL == h) return 0; memset(h,0,sizeof(*h)); /* fixup output image size to match incoming */ o->width = i->width; o->height = i->height; if (0 == o->bytesperline) o->bytesperline = o->width * ng_vfmt_to_depth[o->fmtid] / 8; h->ifmt = *i; h->ofmt = *o; if (conv) h->conv = conv; return h; } void ng_convert_init(struct ng_convert_handle *h) { if (0 == h->ifmt.bytesperline) h->ifmt.bytesperline = h->ifmt.width * ng_vfmt_to_depth[h->ifmt.fmtid] / 8; if (0 == h->ofmt.bytesperline) h->ofmt.bytesperline = h->ofmt.width * ng_vfmt_to_depth[h->ofmt.fmtid] / 8; h->isize = h->ifmt.height * h->ifmt.bytesperline; if (0 == h->isize) h->isize = h->ifmt.width * h->ifmt.height * 3; h->osize = h->ofmt.height * h->ofmt.bytesperline; if (0 == h->osize) h->osize = h->ofmt.width * h->ofmt.height * 3; if (h->conv) h->chandle = h->conv->init(&h->ofmt,h->conv->priv); if (ng_debug) { fprintf(stderr,"convert-in : %dx%d %s (size=%d)\n", h->ifmt.width, h->ifmt.height, ng_vfmt_to_desc[h->ifmt.fmtid], h->isize); fprintf(stderr,"convert-out: %dx%d %s (size=%d)\n", h->ofmt.width, h->ofmt.height, ng_vfmt_to_desc[h->ofmt.fmtid], h->osize); } } static void ng_convert_copyframe(struct ng_video_buf *dest, struct ng_video_buf *src) { unsigned int i,sw,dw; unsigned char *sp,*dp; dw = dest->fmt.width * ng_vfmt_to_depth[dest->fmt.fmtid] / 8; sw = src->fmt.width * ng_vfmt_to_depth[src->fmt.fmtid] / 8; if (src->fmt.bytesperline == sw && dest->fmt.bytesperline == dw) { /* can copy in one go */ memcpy(dest->data, src->data, src->fmt.bytesperline * src->fmt.height); } else { /* copy line by line */ dp = dest->data; sp = src->data; for (i = 0; i < src->fmt.height; i++) { memcpy(dp,sp,dw); dp += dest->fmt.bytesperline; sp += src->fmt.bytesperline; } } } struct ng_video_buf* ng_convert_frame(struct ng_convert_handle *h, struct ng_video_buf *dest, struct ng_video_buf *buf) { if (NULL == buf) return NULL; if (NULL == dest && NULL != h->conv) dest = ng_malloc_video_buf(&h->ofmt,h->osize); if (NULL != dest) { dest->fmt = h->ofmt; dest->size = h->osize; if (NULL != h->conv) { h->conv->frame(h->chandle,dest,buf); } else { ng_convert_copyframe(dest,buf); } dest->info = buf->info; ng_release_video_buf(buf); buf = dest; } return buf; } void ng_convert_fini(struct ng_convert_handle *h) { if (h->conv) h->conv->fini(h->chandle); free(h); } struct ng_video_buf* ng_convert_single(struct ng_convert_handle *h, struct ng_video_buf *in) { struct ng_video_buf *out; ng_convert_init(h); out = ng_convert_frame(h,NULL,in); ng_convert_fini(h); return out; } xawtv-3.106/libng/devices.c000066400000000000000000000033271343350355000155630ustar00rootroot00000000000000#include #include #include #include #include #include #include "devices.h" /* * default devices names */ #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) struct ng_device_config ng_dev = { .video = "/dev/bktr0", .driver = "bktr", .radio = NULL, .vbi = "/dev/vbi0", .dsp = "/dev/dsp", .mixer = "/dev/mixer", .video_scan = { "/dev/bktr0", "/dev/bktr1", "/dev/cxm0", "/dev/cxm1", NULL }, .mixer_scan = { "/dev/mixer", "/dev/mixer1", "/dev/mixer2", "/dev/mixer3", NULL } }; #endif #if defined(__linux__) struct ng_device_config ng_dev = { .video = "/dev/video0", .driver = "libv4l", .radio = "/dev/radio0", .vbi = "/dev/vbi0", .dsp = "/dev/dsp", .mixer = "/dev/mixer", .video_scan = { "/dev/video0", "/dev/video1", "/dev/video2", "/dev/video3", NULL }, .mixer_scan = { "/dev/mixer", "/dev/mixer1", "/dev/mixer2", "/dev/mixer3", NULL } }; struct ng_device_config ng_dev_devfs = { .video = "/dev/v4l/video0", .driver = "libv4l", .radio = "/dev/v4l/radio0", .vbi = "/dev/v4l/vbi0", .dsp = "/dev/sound/dsp", .mixer = "/dev/sound/mixer", .video_scan = { "/dev/v4l/video0", "/dev/v4l/video1", "/dev/v4l/video2", "/dev/v4l/video3", NULL }, .mixer_scan = { "/dev/sound/mixer", "/dev/sound/mixer1", "/dev/sound/mixer2", "/dev/sound/mixer3", NULL } }; #endif void ng_device_init(void) { #if defined(__linux__) struct stat st; if (-1 == lstat("/dev/.devfsd",&st)) return; if (!S_ISCHR(st.st_mode)) return; ng_dev = ng_dev_devfs; #endif } xawtv-3.106/libng/devices.h000066400000000000000000000003711343350355000155640ustar00rootroot00000000000000 struct ng_device_config { char *video; char *driver; char *radio; char *vbi; char *dsp; char *mixer; char *video_scan[32]; char *mixer_scan[32]; }; extern struct ng_device_config ng_dev; void ng_device_init(void); xawtv-3.106/libng/grab-ng.c000066400000000000000000000552171343350355000154630ustar00rootroot00000000000000/* * next generation[tm] xawtv capture interfaces * * (c) 2001 Gerd Knorr * */ #define NG_PRIVATE #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef RTLD_NOW # define RTLD_NOW RTLD_LAZY #endif #include "get_media_devices.h" #include "grab-ng.h" int ng_debug = 0; int ng_chromakey = 0x00ff00ff; int ng_jpeg_quality = 75; int ng_ratio_x = 4; int ng_ratio_y = 3; char ng_v4l_conf[256] = "v4l-conf"; /* --------------------------------------------------------------------- */ const unsigned int ng_vfmt_to_depth[] = { 0, /* unused */ 8, /* RGB8 */ 8, /* GRAY8 */ 16, /* RGB15 LE */ 16, /* RGB16 LE */ 16, /* RGB15 BE */ 16, /* RGB16 BE */ 24, /* BGR24 */ 32, /* BGR32 */ 24, /* RGB24 */ 32, /* RGB32 */ 16, /* LUT2 */ 32, /* LUT4 */ 16, /* YUYV */ 16, /* YUV422P */ 12, /* YUV420P */ 0, /* MJPEG */ 0, /* JPEG */ 16, /* UYVY */ }; const char* ng_vfmt_to_desc[] = { "none", "8 bit PseudoColor (dithering)", "8 bit StaticGray", "15 bit TrueColor (LE)", "16 bit TrueColor (LE)", "15 bit TrueColor (BE)", "16 bit TrueColor (BE)", "24 bit TrueColor (LE: bgr)", "32 bit TrueColor (LE: bgr-)", "24 bit TrueColor (BE: rgb)", "32 bit TrueColor (BE: -rgb)", "16 bit TrueColor (lut)", "32 bit TrueColor (lut)", "16 bit YUV 4:2:2 (packed, YUYV)", "16 bit YUV 4:2:2 (planar)", "12 bit YUV 4:2:0 (planar)", "MJPEG (AVI)", "JPEG (JFIF)", "16 bit YUV 4:2:2 (packed, UYVY)", }; /* --------------------------------------------------------------------- */ const unsigned int ng_afmt_to_channels[] = { 0, 1, 2, 1, 2, 1, 2, 0 }; const unsigned int ng_afmt_to_bits[] = { 0, 8, 8, 16, 16, 16, 16, 0 }; const char* ng_afmt_to_desc[] = { "none", "8bit mono", "8bit stereo", "16bit mono (LE)", "16bit stereo (LE)", "16bit mono (BE)", "16bit stereo (BE)", "mp3 compressed audio", }; /* --------------------------------------------------------------------- */ const char* ng_attr_to_desc[] = { "none", "norm", "input", "volume", "mute", "audio mode", "color", "bright", "hue", "contrast", }; /* --------------------------------------------------------------------- */ void ng_init_video_buf(struct ng_video_buf *buf) { memset(buf,0,sizeof(*buf)); pthread_mutex_init(&buf->lock,NULL); pthread_cond_init(&buf->cond,NULL); } void ng_release_video_buf(struct ng_video_buf *buf) { int release; pthread_mutex_lock(&buf->lock); buf->refcount--; release = (buf->refcount == 0); pthread_mutex_unlock(&buf->lock); if (release && NULL != buf->release) buf->release(buf); } void ng_wakeup_video_buf(struct ng_video_buf *buf) { pthread_cond_signal(&buf->cond); } void ng_waiton_video_buf(struct ng_video_buf *buf) { pthread_mutex_lock(&buf->lock); while (buf->refcount) pthread_cond_wait(&buf->cond, &buf->lock); pthread_mutex_unlock(&buf->lock); } static void ng_free_video_buf(struct ng_video_buf *buf) { free(buf->data); free(buf); } struct ng_video_buf* ng_malloc_video_buf(struct ng_video_fmt *fmt, int size) { struct ng_video_buf *buf; buf = malloc(sizeof(*buf)); if (NULL == buf) return NULL; ng_init_video_buf(buf); buf->fmt = *fmt; buf->size = size; buf->data = malloc(size); if (NULL == buf->data) { free(buf); return NULL; } buf->refcount = 1; buf->release = ng_free_video_buf; return buf; } /* --------------------------------------------------------------------- */ struct ng_audio_buf* ng_malloc_audio_buf(struct ng_audio_fmt *fmt, int size) { struct ng_audio_buf *buf; buf = malloc(sizeof(*buf)+size); memset(buf,0,sizeof(*buf)); buf->fmt = *fmt; buf->size = size; buf->data = (char*)buf + sizeof(*buf); return buf; } /* --------------------------------------------------------------------- */ struct ng_attribute* ng_attr_byid(struct ng_attribute *attrs, int id) { if (NULL == attrs) return NULL; for (;;) { if (NULL == attrs->name) return NULL; if (attrs->id == id) return attrs; attrs++; } } struct ng_attribute* ng_attr_byname(struct ng_attribute *attrs, char *name) { if (NULL == attrs) return NULL; for (;;) { if (NULL == attrs->name) return NULL; if (0 == strcasecmp(attrs->name,name)) return attrs; attrs++; } } const char* ng_attr_getstr(struct ng_attribute *attr, int value) { int i; if (NULL == attr) return NULL; if (attr->type != ATTR_TYPE_CHOICE) return NULL; for (i = 0; attr->choices[i].str != NULL; i++) if (attr->choices[i].nr == value) return attr->choices[i].str; return NULL; } int ng_attr_getint(struct ng_attribute *attr, char *value) { int i,val; if (NULL == attr) return -1; if (attr->type != ATTR_TYPE_CHOICE) return -1; for (i = 0; attr->choices[i].str != NULL; i++) { if (0 == strcasecmp(attr->choices[i].str,value)) return attr->choices[i].nr; } if (isdigit(value[0])) { /* Hmm. String not found, but starts with a digit. Check if this is a valid number ... */ val = atoi(value); for (i = 0; attr->choices[i].str != NULL; i++) if (val == attr->choices[i].nr) return attr->choices[i].nr; } return -1; } void ng_attr_listchoices(struct ng_attribute *attr) { int i; fprintf(stderr,"valid choices for \"%s\": ",attr->name); for (i = 0; attr->choices[i].str != NULL; i++) fprintf(stderr,"%s\"%s\"", i ? ", " : "", attr->choices[i].str); fprintf(stderr,"\n"); } int ng_attr_int2percent(struct ng_attribute *attr, int value) { int range,percent; range = attr->max - attr->min; percent = (value - attr->min) * 100 / range; if (percent < 0) percent = 0; if (percent > 100) percent = 100; return percent; } int ng_attr_percent2int(struct ng_attribute *attr, int percent) { int range,value; range = attr->max - attr->min; value = percent * range / 100 + attr->min; if (value < attr->min) value = attr->min; if (value > attr->max) value = attr->max; return value; } int ng_attr_parse_int(struct ng_attribute *attr, char *str) { int value,n; if (0 == sscanf(str,"%d%n",&value,&n)) /* parse error */ return attr->defval; if (str[n] == '%') value = ng_attr_percent2int(attr,value); if (value < attr->min) value = attr->min; if (value > attr->max) value = attr->max; return value; } /* --------------------------------------------------------------------- */ void ng_ratio_fixup(int *width, int *height, int *xoff, int *yoff) { int h = *height; int w = *width; if (0 == ng_ratio_x || 0 == ng_ratio_y) return; if (w * ng_ratio_y < h * ng_ratio_x) { *height = *width * ng_ratio_y / ng_ratio_x; if (yoff) *yoff += (h-*height)/2; } else if (w * ng_ratio_y > h * ng_ratio_x) { *width = *height * ng_ratio_x / ng_ratio_y; if (yoff) *xoff += (w-*width)/2; } } void ng_ratio_fixup2(int *width, int *height, int *xoff, int *yoff, int ratio_x, int ratio_y, int up) { int h = *height; int w = *width; if (0 == ratio_x || 0 == ratio_y) return; if ((!up && w * ratio_y < h * ratio_x) || (up && w * ratio_y > h * ratio_x)) { *height = *width * ratio_y / ratio_x; if (yoff) *yoff += (h-*height)/2; } else if ((!up && w * ratio_y > h * ratio_x) || (up && w * ratio_y < h * ratio_x)) { *width = *height * ratio_x / ratio_y; if (yoff) *xoff += (w-*width)/2; } } /* --------------------------------------------------------------------- */ LIST_HEAD(ng_conv); LIST_HEAD(ng_aconv); LIST_HEAD(ng_filters); LIST_HEAD(ng_writers); LIST_HEAD(ng_readers); LIST_HEAD(ng_vid_drivers); LIST_HEAD(ng_dsp_drivers); LIST_HEAD(ng_mix_drivers); static int ng_check_magic(int magic, char *plugname, char *type) { if (magic != NG_PLUGIN_MAGIC) { fprintf(stderr, "ERROR: plugin magic mismatch [xawtv=%d,%s=%d]\n", NG_PLUGIN_MAGIC,plugname,magic); return -1; } #if 0 if (ng_debug) fprintf(stderr,"plugins: %s registered by %s\n",type,plugname); #endif return 0; } int ng_conv_register(int magic, char *plugname, struct ng_video_conv *list, int count) { int n; if (0 != ng_check_magic(magic,plugname,"video converters")) return -1; for (n = 0; n < count; n++) list_add_tail(&(list[n].list),&ng_conv); return 0; } int ng_aconv_register(int magic, char *plugname, struct ng_audio_conv *list, int count) { int n; if (0 != ng_check_magic(magic,plugname,"audio converters")) return -1; for (n = 0; n < count; n++) list_add_tail(&(list[n].list),&ng_aconv); return 0; } int ng_filter_register(int magic, char *plugname, struct ng_filter *filter) { if (0 != ng_check_magic(magic,plugname,"filter")) return -1; list_add_tail(&filter->list,&ng_filters); return 0; } int ng_writer_register(int magic, char *plugname, struct ng_writer *writer) { if (0 != ng_check_magic(magic,plugname,"writer")) return -1; list_add_tail(&writer->list,&ng_writers); return 0; } int ng_reader_register(int magic, char *plugname, struct ng_reader *reader) { if (0 != ng_check_magic(magic,plugname,"reader")) return -1; list_add_tail(&reader->list,&ng_readers); return 0; } int ng_vid_driver_register(int magic, char *plugname, struct ng_vid_driver *driver) { if (0 != ng_check_magic(magic,plugname,"video drv")) return -1; list_add_tail(&driver->list,&ng_vid_drivers); return 0; } int ng_dsp_driver_register(int magic, char *plugname, struct ng_dsp_driver *driver) { if (0 != ng_check_magic(magic,plugname,"dsp drv")) return -1; list_add_tail(&driver->list,&ng_dsp_drivers); return 0; } int ng_mix_driver_register(int magic, char *plugname, struct ng_mix_driver *driver) { if (0 != ng_check_magic(magic,plugname,"mixer drv")) return -1; list_add_tail(&driver->list,&ng_mix_drivers); return 0; } struct ng_video_conv* ng_conv_find_to(unsigned int out, int *i) { struct list_head *item; struct ng_video_conv *ret; int j = 0; list_for_each(item,&ng_conv) { if (j < *i) { j++; continue; } ret = list_entry(item, struct ng_video_conv, list); #if 0 fprintf(stderr,"\tconv to: %-28s => %s\n", ng_vfmt_to_desc[ret->fmtid_in], ng_vfmt_to_desc[ret->fmtid_out]); #endif if (ret->fmtid_out == out) { (*i)++; return ret; } (*i)++; j++; } return NULL; } struct ng_video_conv* ng_conv_find_from(unsigned int in, int *i) { struct list_head *item; struct ng_video_conv *ret; int j = 0; list_for_each(item,&ng_conv) { if (j < *i) { j++; continue; } ret = list_entry(item, struct ng_video_conv, list); #if 0 fprintf(stderr,"\tconv from: %-28s => %s\n", ng_vfmt_to_desc[ret->fmtid_in], ng_vfmt_to_desc[ret->fmtid_out]); #endif if (ret->fmtid_in == in) { (*i)++; return ret; } } return NULL; } struct ng_video_conv* ng_conv_find_match(unsigned int in, unsigned int out) { struct list_head *item; struct ng_video_conv *ret = NULL; list_for_each(item,&ng_conv) { ret = list_entry(item, struct ng_video_conv, list); if (ret->fmtid_in == in && ret->fmtid_out == out) return ret; } return NULL; } /* --------------------------------------------------------------------- */ #ifdef __linux__ /* Because this depends on get_media_devices.c */ static void *ng_vid_open_auto(struct ng_vid_driver *drv, char *devpath, int allow_grabber) { void *md, *handle = NULL; const char *device = NULL; const char *scan_type = "an analog TV"; *devpath = 0; md = discover_media_devices(); if (!md) goto error; /* Step 1: try TV cards first */ while (1) { device = get_associated_device(md, device, MEDIA_V4L_VIDEO, NULL, NONE); if (!device) break; /* No more video devices to try */ snprintf(devpath, PATH_MAX, "/dev/%s", device); if (ng_debug) fprintf(stderr,"vid-open-auto: trying: %s... \n", devpath); handle = (drv->open)(devpath, CAN_CAPTURE | CAN_TUNE); if (handle) { fprintf(stderr,"vid-open-auto: using analog TV device %s\n", devpath); break; } } /* Step 2: try grabber devices and webcams */ if (!handle) { if (!allow_grabber) goto error; scan_type = "a capture"; device = NULL; while (1) { device = get_associated_device(md, device, MEDIA_V4L_VIDEO, NULL, NONE); if (!device) break; /* No more video devices to try */ snprintf(devpath, PATH_MAX, "/dev/%s", device); if (ng_debug) fprintf(stderr,"vid-open-auto: trying: %s... \n", devpath); handle = (drv->open)(devpath, CAN_CAPTURE); if (handle) { fprintf(stderr,"vid-open-auto: using grabber/webcam device %s\n", devpath); break; } } } free_media_devices(md); error: if (!handle) { fprintf(stderr, "vid-open-auto: failed to open %s device", scan_type); if (*devpath) fprintf(stderr, " at %s\n", devpath); else fprintf(stderr, "\n"); return NULL; } if (handle && ng_debug) fprintf(stderr,"vid-open-auto: success, using: %s\n", devpath); return handle; } #endif const struct ng_vid_driver* ng_vid_open(char **device, char *driver, struct ng_video_fmt *screen, void *base, void **handle) { struct list_head *item; struct ng_vid_driver *drv; if (!driver) { fprintf (stderr, "Video4linux driver is not specified\n"); return NULL; } /* check all grabber drivers */ list_for_each(item,&ng_vid_drivers) { drv = list_entry(item, struct ng_vid_driver, list); if (strcasecmp(driver, drv->name) == 0) break; } if (item == &ng_vid_drivers) { if (strcasecmp(driver, "help") != 0) fprintf (stderr, "Cannot find %s video driver\n", driver); fprintf (stderr, "Available drivers:"); list_for_each(item,&ng_vid_drivers) { drv = list_entry(item, struct ng_vid_driver, list); fprintf (stderr, " %s", drv->name); } fprintf (stderr, "\n"); return NULL; } #ifndef __linux__ if (!strcmp(*device, "auto") || !strcmp(*device, "auto_tv")) *device = "/dev/bktr0"; #else if (!strcmp(*device, "auto") || !strcmp(*device, "auto_tv")) { char devpath[PATH_MAX]; *handle = ng_vid_open_auto(drv, devpath, !strcmp(*device, "auto_tv") ? 0 : 1); if (*handle == NULL) { fprintf(stderr, "vid-open: could not find a suitable videodev\n"); return NULL; } *device = strdup(devpath); } else #endif { if (ng_debug) fprintf(stderr,"vid-open: trying: %s... \n", drv->name); if (!(*handle = (drv->open)(*device, 0))) { fprintf(stderr,"vid-open: failed: %s\n", drv->name); return NULL; } if (ng_debug) fprintf(stderr,"vid-open: ok: %s\n", drv->name); } if (NULL != screen && drv->capabilities(*handle) & CAN_OVERLAY) { #ifdef __linux__ int l = strlen(ng_v4l_conf); snprintf(ng_v4l_conf + l, sizeof(ng_v4l_conf) - l, " -c %s", *device); if (ng_debug) fprintf(stderr,"vid-open: closing dev to run v4lconf\n"); drv->close(*handle); switch (system(ng_v4l_conf)) { case -1: /* can't run */ fprintf(stderr,"could'nt start v4l-conf\n"); break; case 0: /* ok */ break; default: /* non-zero return */ fprintf(stderr,"v4l-conf had some trouble, " "trying to continue anyway\n"); break; } if (ng_debug) fprintf(stderr,"vid-open: re-opening dev after v4lconf\n"); if (!(*handle = (drv->open)(*device, 0))) { fprintf(stderr,"vid-open: failed: %s\n", drv->name); return NULL; } if (ng_debug) fprintf(stderr,"vid-open: re-open ok\n"); #endif drv->setupfb(*handle,screen,base); } return drv; } const struct ng_dsp_driver* ng_dsp_open(char *device, struct ng_audio_fmt *fmt, int record, void **handle) { struct list_head *item; struct ng_dsp_driver *drv; /* check all dsp drivers */ list_for_each(item,&ng_dsp_drivers) { drv = list_entry(item, struct ng_dsp_driver, list); if (NULL == drv->name) continue; if (record && NULL == drv->read) continue; if (!record && NULL == drv->write) continue; if (ng_debug) fprintf(stderr,"dsp-open: trying: %s... \n", drv->name); if (NULL != (*handle = (drv->open)(device,fmt,record))) break; if (ng_debug) fprintf(stderr,"dsp-open: failed: %s\n", drv->name); } if (item == &ng_dsp_drivers) return NULL; if (ng_debug) fprintf(stderr,"dsp-open: ok: %s\n",drv->name); return drv; } struct ng_attribute* ng_mix_init(char *device, char *channel) { struct list_head *item; struct ng_mix_driver *drv = NULL; struct ng_attribute *attrs = NULL; void *handle; /* check all mixer drivers */ list_for_each(item, &ng_mix_drivers) { drv = list_entry(item, struct ng_mix_driver, list); if (ng_debug) fprintf(stderr,"mix-init: trying: %s... \n", drv->name); if (NULL != (handle = (drv->open)(device))) { if (NULL != (attrs = drv->volctl(handle,channel))) break; drv->close(handle); } if (ng_debug) fprintf(stderr,"mix-init: failed: %s\n",drv->name); } if (ng_debug && NULL != attrs) fprintf(stderr,"mix-init: ok: %s\n",drv->name); return attrs; } struct ng_reader* ng_find_reader(char *filename) { struct list_head *item; struct ng_reader *reader; char blk[512]; FILE *fp; int m; if (NULL == (fp = fopen(filename, "r"))) { fprintf(stderr,"open %s: %s\n",filename,strerror(errno)); return NULL; } memset(blk,0,sizeof(blk)); fread(blk,1,sizeof(blk),fp); fclose(fp); list_for_each(item,&ng_readers) { reader = list_entry(item, struct ng_reader, list); for (m = 0; m < 4 && reader->mlen[m] > 0; m++) { if (0 == memcmp(blk+reader->moff[m],reader->magic[m], reader->mlen[m])) return reader; } } if (ng_debug) fprintf(stderr,"%s: no reader found\n",filename); return NULL; } int64_t ng_tofday_to_timestamp(struct timeval *tv) { long long ts; ts = tv->tv_sec; ts *= 1000000; ts += tv->tv_usec; ts *= 1000; return ts; } int64_t ng_get_timestamp() { struct timeval tv; gettimeofday(&tv,NULL); return ng_tofday_to_timestamp(&tv); } struct ng_video_buf* ng_filter_single(struct ng_filter *filter, struct ng_video_buf *in) { struct ng_video_buf *out = in; void *handle; if (NULL != filter && filter->fmts & (1 << in->fmt.fmtid)) { handle = filter->init(&in->fmt); out = filter->frame(handle,in); filter->fini(handle); } return out; } /* --------------------------------------------------------------------- */ static void clip_dump(char *state, struct OVERLAY_CLIP *oc, int count) { int i; fprintf(stderr,"clip: %s - %d clips\n",state,count); for (i = 0; i < count; i++) fprintf(stderr,"clip: %d: %dx%d+%d+%d\n",i, oc[i].x2 - oc[i].x1, oc[i].y2 - oc[i].y1, oc[i].x1, oc[i].y1); } static void clip_drop(struct OVERLAY_CLIP *oc, int n, int *count) { (*count)--; memmove(oc+n, oc+n+1, sizeof(struct OVERLAY_CLIP) * (*count-n)); } void ng_check_clipping(int width, int height, int xadjust, int yadjust, struct OVERLAY_CLIP *oc, int *count) { int i,j; if (ng_debug > 1) { fprintf(stderr,"clip: win=%dx%d xa=%d ya=%d\n", width,height,xadjust,yadjust); clip_dump("init",oc,*count); } for (i = 0; i < *count; i++) { /* fixup coordinates */ oc[i].x1 += xadjust; oc[i].x2 += xadjust; oc[i].y1 += yadjust; oc[i].y2 += yadjust; } if (ng_debug > 1) clip_dump("fixup adjust",oc,*count); for (i = 0; i < *count; i++) { /* fixup borders */ if (oc[i].x1 < 0) oc[i].x1 = 0; if (oc[i].x2 < 0) oc[i].x2 = 0; if (oc[i].x1 > width) oc[i].x1 = width; if (oc[i].x2 > width) oc[i].x2 = width; if (oc[i].y1 < 0) oc[i].y1 = 0; if (oc[i].y2 < 0) oc[i].y2 = 0; if (oc[i].y1 > height) oc[i].y1 = height; if (oc[i].y2 > height) oc[i].y2 = height; } if (ng_debug > 1) clip_dump("fixup range",oc,*count); /* drop zero-sized clips */ for (i = 0; i < *count;) { if (oc[i].x1 == oc[i].x2 || oc[i].y1 == oc[i].y2) { clip_drop(oc,i,count); continue; } i++; } if (ng_debug > 1) clip_dump("zerosize done",oc,*count); /* try to merge clips */ restart_merge: for (j = *count - 1; j >= 0; j--) { for (i = 0; i < *count; i++) { if (i == j) continue; if (oc[i].x1 == oc[j].x1 && oc[i].x2 == oc[j].x2 && oc[i].y1 <= oc[j].y1 && oc[i].y2 >= oc[j].y1) { if (ng_debug > 1) fprintf(stderr,"clip: merge y %d,%d\n",i,j); if (oc[i].y2 < oc[j].y2) oc[i].y2 = oc[j].y2; clip_drop(oc,j,count); if (ng_debug > 1) clip_dump("merge y done",oc,*count); goto restart_merge; } if (oc[i].y1 == oc[j].y1 && oc[i].y2 == oc[j].y2 && oc[i].x1 <= oc[j].x1 && oc[i].x2 >= oc[j].x1) { if (ng_debug > 1) fprintf(stderr,"clip: merge x %d,%d\n",i,j); if (oc[i].x2 < oc[j].x2) oc[i].x2 = oc[j].x2; clip_drop(oc,j,count); if (ng_debug > 1) clip_dump("merge x done",oc,*count); goto restart_merge; } } } if (ng_debug) clip_dump("final",oc,*count); } /* --------------------------------------------------------------------- */ static int ng_plugins(char *dirname) { struct dirent **list; char filename[1024]; void *plugin; void (*initcall)(void); int i,n = 0,l = 0; n = scandir(dirname,&list,NULL,alphasort); if (n <= 0) return 0; for (i = 0; i < n; i++) { if (0 != fnmatch("*.so",list[i]->d_name,0)) continue; sprintf(filename,"%s/%s",dirname,list[i]->d_name); if (NULL == (plugin = dlopen(filename,RTLD_NOW))) { fprintf(stderr,"dlopen: %s\n",dlerror()); continue; } if (NULL == (initcall = dlsym(plugin,"ng_plugin_init"))) { if (NULL == (initcall = dlsym(plugin,"_ng_plugin_init"))) { fprintf(stderr,"dlsym[%s]: %s\n",filename,dlerror()); continue; } } initcall(); l--; } for (i = 0; i < n; i++) free(list[i]); free(list); return l; } void ng_init(void) { static int once=0; int count=0; if (once++) { fprintf(stderr,"panic: ng_init called twice\n"); exit(1); } ng_device_init(); ng_color_packed_init(); ng_color_yuv2rgb_init(); ng_writefile_init(); count += ng_plugins(LIBDIR); if (0 == count) { /* nice for development */ count += ng_plugins("../libng/plugins"); count += ng_plugins("../libng/contrib-plugins"); } if (0 == count) fprintf(stderr,"WARNING: no plugins found [%s]\n",LIBDIR); } xawtv-3.106/libng/grab-ng.h000066400000000000000000000423221343350355000154610ustar00rootroot00000000000000/* * next generation[tm] xawtv capture interfaces * * (c) 2001-03 Gerd Knorr * */ #include #include #include "devices.h" #include "list.h" extern int ng_debug; extern int ng_chromakey; extern int ng_jpeg_quality; extern int ng_ratio_x; extern int ng_ratio_y; extern char ng_v4l_conf[256]; #define BUG_ON(condition,message) if (condition) {\ fprintf(stderr,"BUG: %s [%s:%d]\n",\ message,__FILE__,__LINE__);\ exit(1);} #if __STDC_VERSION__ < 199901 # define restrict #endif #define UNSET (-1U) #define DIMOF(array) (sizeof(array)/sizeof(array[0])) #define SDIMOF(array) ((signed int)(sizeof(array)/sizeof(array[0]))) #define GETELEM(array,index,default) \ (index < sizeof(array)/sizeof(array[0]) ? array[index] : default) /* --------------------------------------------------------------------- */ /* defines */ #define VIDEO_NONE 0 #define VIDEO_RGB08 1 /* bt848 dithered */ #define VIDEO_GRAY 2 #define VIDEO_RGB15_LE 3 /* 15 bpp little endian */ #define VIDEO_RGB16_LE 4 /* 16 bpp little endian */ #define VIDEO_RGB15_BE 5 /* 15 bpp big endian */ #define VIDEO_RGB16_BE 6 /* 16 bpp big endian */ #define VIDEO_BGR24 7 /* bgrbgrbgrbgr (LE) */ #define VIDEO_BGR32 8 /* bgr-bgr-bgr- (LE) */ #define VIDEO_RGB24 9 /* rgbrgbrgbrgb (BE) */ #define VIDEO_RGB32 10 /* -rgb-rgb-rgb (BE) */ #define VIDEO_LUT2 11 /* lookup-table 2 byte depth */ #define VIDEO_LUT4 12 /* lookup-table 4 byte depth */ #define VIDEO_YUYV 13 /* 4:2:2 */ #define VIDEO_YUV422P 14 /* YUV 4:2:2 (planar) */ #define VIDEO_YUV420P 15 /* YUV 4:2:0 (planar) */ #define VIDEO_MJPEG 16 /* MJPEG (AVI) */ #define VIDEO_JPEG 17 /* JPEG (JFIF) */ #define VIDEO_UYVY 18 /* 4:2:2 */ #define VIDEO_FMT_COUNT 19 #define AUDIO_NONE 0 #define AUDIO_U8_MONO 1 #define AUDIO_U8_STEREO 2 #define AUDIO_S16_LE_MONO 3 #define AUDIO_S16_LE_STEREO 4 #define AUDIO_S16_BE_MONO 5 #define AUDIO_S16_BE_STEREO 6 #define AUDIO_MP3 7 #define AUDIO_FMT_COUNT 8 #if BYTE_ORDER == BIG_ENDIAN # define AUDIO_S16_NATIVE_MONO AUDIO_S16_BE_MONO # define AUDIO_S16_NATIVE_STEREO AUDIO_S16_BE_STEREO # define VIDEO_RGB15_NATIVE VIDEO_RGB15_BE # define VIDEO_RGB16_NATIVE VIDEO_RGB16_BE #endif #if BYTE_ORDER == LITTLE_ENDIAN # define AUDIO_S16_NATIVE_MONO AUDIO_S16_LE_MONO # define AUDIO_S16_NATIVE_STEREO AUDIO_S16_LE_STEREO # define VIDEO_RGB15_NATIVE VIDEO_RGB15_LE # define VIDEO_RGB16_NATIVE VIDEO_RGB16_LE #endif #define ATTR_TYPE_INTEGER 1 /* range 0 - 65535 */ #define ATTR_TYPE_CHOICE 2 /* multiple choice */ #define ATTR_TYPE_BOOL 3 /* yes/no */ #define ATTR_ID_NORM 1 #define ATTR_ID_INPUT 2 #define ATTR_ID_VOLUME 3 #define ATTR_ID_MUTE 4 #define ATTR_ID_AUDIO_MODE 5 #define ATTR_ID_COLOR 6 #define ATTR_ID_BRIGHT 7 #define ATTR_ID_HUE 8 #define ATTR_ID_CONTRAST 9 #define ATTR_ID_COUNT 10 #define CAN_OVERLAY 1 #define CAN_CAPTURE 2 #define CAN_TUNE 4 #define NEEDS_CHROMAKEY 8 /* --------------------------------------------------------------------- */ extern const unsigned int ng_vfmt_to_depth[VIDEO_FMT_COUNT]; extern const char* ng_vfmt_to_desc[VIDEO_FMT_COUNT]; extern const unsigned int ng_afmt_to_channels[AUDIO_FMT_COUNT]; extern const unsigned int ng_afmt_to_bits[AUDIO_FMT_COUNT]; extern const char* ng_afmt_to_desc[AUDIO_FMT_COUNT]; extern const char* ng_attr_to_desc[ATTR_ID_COUNT]; /* --------------------------------------------------------------------- */ struct STRTAB { long nr; const char *str; }; struct OVERLAY_CLIP { int x1,x2,y1,y2; }; /* --------------------------------------------------------------------- */ /* video data structures */ struct ng_video_fmt { unsigned int fmtid; /* VIDEO_* */ unsigned int width; unsigned int height; unsigned int bytesperline; /* zero for compressed formats */ }; struct ng_video_buf { struct ng_video_fmt fmt; size_t size; unsigned char *data; /* meta info for frame */ struct { int64_t ts; /* time stamp */ int seq; int twice; } info; /* * the lock is for the reference counter. * if the reference counter goes down to zero release() * should be called. priv is for the owner of the * buffer (can be used by the release callback) */ pthread_mutex_t lock; pthread_cond_t cond; int refcount; void (*release)(struct ng_video_buf *buf); void *priv; }; void ng_init_video_buf(struct ng_video_buf *buf); void ng_release_video_buf(struct ng_video_buf *buf); struct ng_video_buf* ng_malloc_video_buf(struct ng_video_fmt *fmt, int size); void ng_wakeup_video_buf(struct ng_video_buf *buf); void ng_waiton_video_buf(struct ng_video_buf *buf); /* --------------------------------------------------------------------- */ /* audio data structures */ struct ng_audio_fmt { unsigned int fmtid; /* AUDIO_* */ unsigned int rate; }; struct ng_audio_buf { struct ng_audio_fmt fmt; int size; int written; /* for partial writes */ char *data; struct { int64_t ts; } info; }; struct ng_audio_buf* ng_malloc_audio_buf(struct ng_audio_fmt *fmt, int size); /* --------------------------------------------------------------------- */ /* someone who receives video and/or audio data (writeavi, ...) */ struct ng_format_list { char *name; char *desc; /* if standard fmtid description doesn't work because it's converted somehow */ char *ext; unsigned int fmtid; void *priv; }; struct ng_writer { const char *name; const char *desc; const struct ng_format_list *video; const struct ng_format_list *audio; const int combined; /* both audio + video in one file */ void* (*wr_open)(char *moviename, char *audioname, struct ng_video_fmt *video, const void *priv_video, int fps, struct ng_audio_fmt *audio, const void *priv_audio); int (*wr_video)(void *handle, struct ng_video_buf *buf); int (*wr_audio)(void *handle, struct ng_audio_buf *buf); int (*wr_close)(void *handle); struct list_head list; }; struct ng_reader { const char *name; const char *desc; char *magic[4]; int moff[4]; int mlen[4]; void* (*rd_open)(char *moviename); struct ng_video_fmt* (*rd_vfmt)(void *handle, int *vfmt, int vn); struct ng_audio_fmt* (*rd_afmt)(void *handle); struct ng_video_buf* (*rd_vdata)(void *handle, unsigned int drop); struct ng_audio_buf* (*rd_adata)(void *handle); int64_t (*frame_time)(void *handle); int (*rd_close)(void *handle); struct list_head list; }; /* --------------------------------------------------------------------- */ /* attributes */ struct ng_attribute { int id; const char *name; int type; int defval; struct STRTAB *choices; /* ATTR_TYPE_CHOICE */ int min,max; /* ATTR_TYPE_INTEGER */ int points; /* ATTR_TYPE_INTEGER -- fixed point */ const void *priv; void *handle; int (*read)(struct ng_attribute*); void (*write)(struct ng_attribute*, int val); }; struct ng_attribute* ng_attr_byid(struct ng_attribute *attrs, int id); struct ng_attribute* ng_attr_byname(struct ng_attribute *attrs, char *name); const char* ng_attr_getstr(struct ng_attribute *attr, int value); int ng_attr_getint(struct ng_attribute *attr, char *value); void ng_attr_listchoices(struct ng_attribute *attr); int ng_attr_int2percent(struct ng_attribute *attr, int value); int ng_attr_percent2int(struct ng_attribute *attr, int percent); int ng_attr_parse_int(struct ng_attribute *attr, char *str); /* --------------------------------------------------------------------- */ void ng_ratio_fixup(int *width, int *height, int *xoff, int *yoff); void ng_ratio_fixup2(int *width, int *height, int *xoff, int *yoff, int ratio_x, int ratio_y, int up); /* --------------------------------------------------------------------- */ /* device informations */ struct ng_devinfo { char device[32]; char name[64]; int flags; }; /* --------------------------------------------------------------------- */ /* capture/overlay interface driver */ struct ng_vid_driver { const char *name; /* open/close */ void* (*open)(char *device, int req_flags); int (*close)(void *handle); /* attributes */ char* (*get_devname)(void *handle); int (*capabilities)(void *handle); struct ng_attribute* (*list_attrs)(void *handle); void (*get_min_size)(void *handle, int *min_width, int *min_height); /* overlay */ int (*setupfb)(void *handle, struct ng_video_fmt *fmt, void *base); int (*overlay)(void *handle, struct ng_video_fmt *fmt, int x, int y, struct OVERLAY_CLIP *oc, int count, int aspect); /* capture */ int (*setformat)(void *handle, struct ng_video_fmt *fmt); int (*startvideo)(void *handle, int fps, unsigned int buffers); void (*stopvideo)(void *handle); struct ng_video_buf* (*nextframe)(void *handle); /* video frame */ struct ng_video_buf* (*getimage)(void *handle); /* single image */ /* tuner */ unsigned long (*getfreq)(void *handle); void (*setfreq)(void *handle, unsigned long freq); int (*is_tuned)(void *handle); struct list_head list; }; /* --------------------------------------------------------------------- */ /* sound driver */ struct ng_dsp_driver { const char *name; void* (*open)(char *device, struct ng_audio_fmt *fmt, int record); void (*close)(void *handle); int (*fd)(void *handle); int (*startrec)(void *handle); struct ng_audio_buf* (*read)(void *handle, int64_t stopby); struct ng_audio_buf* (*write)(void *handle, struct ng_audio_buf *buf); int64_t (*latency)(void *handle); struct list_head list; }; struct ng_mix_driver { const char *name; struct ng_devinfo* (*probe)(void); struct ng_devinfo* (*channels)(char *device); void* (*open)(char *device); struct ng_attribute* (*volctl)(void *handle, char *channel); void (*close)(void *handle); struct list_head list; }; /* --------------------------------------------------------------------- */ /* color space converters */ struct ng_video_conv { unsigned int fmtid_in; unsigned int fmtid_out; void* (*init)(struct ng_video_fmt *out, void *priv); void (*frame)(void *handle, struct ng_video_buf *out, struct ng_video_buf *in); void (*fini)(void *handle); void *priv; struct list_head list; }; struct ng_convert_handle { struct ng_video_fmt ifmt; struct ng_video_fmt ofmt; int isize; int osize; struct ng_video_conv *conv; void *chandle; }; struct ng_convert_handle* ng_convert_alloc(struct ng_video_conv *conv, struct ng_video_fmt *i, struct ng_video_fmt *o); void ng_convert_init(struct ng_convert_handle *h); struct ng_video_buf* ng_convert_frame(struct ng_convert_handle *h, struct ng_video_buf *dest, struct ng_video_buf *buf); void ng_convert_fini(struct ng_convert_handle *h); struct ng_video_buf* ng_convert_single(struct ng_convert_handle *h, struct ng_video_buf *in); /* --------------------------------------------------------------------- */ /* audio converters */ struct ng_audio_conv { unsigned int fmtid_in; unsigned int fmtid_out; void* (*init)(void *priv); struct ng_audio_buf* (*frame)(void *handle, struct ng_audio_buf *in); void (*fini)(void *handle); void *priv; struct list_head list; }; /* --------------------------------------------------------------------- */ /* filters */ struct ng_filter { char *name; int fmts; struct ng_attribute* attrs; void* (*init)(struct ng_video_fmt *fmt); struct ng_video_buf* (*frame)(void *handle, struct ng_video_buf *in); void (*fini)(void *handle); struct list_head list; }; /* --------------------------------------------------------------------- */ /* must be changed if we break compatibility */ #define NG_PLUGIN_MAGIC 0x20030129 extern struct list_head ng_conv; extern struct list_head ng_aconv; extern struct list_head ng_filters; extern struct list_head ng_writers; extern struct list_head ng_readers; extern struct list_head ng_vid_drivers; extern struct list_head ng_dsp_drivers; extern struct list_head ng_mix_drivers; int ng_conv_register(int magic, char *plugname, struct ng_video_conv *list, int count); int ng_aconv_register(int magic, char *plugname, struct ng_audio_conv *list, int count); int ng_filter_register(int magic, char *plugname, struct ng_filter *filter); int ng_writer_register(int magic, char *plugname, struct ng_writer *writer); int ng_reader_register(int magic, char *plugname, struct ng_reader *reader); int ng_vid_driver_register(int magic, char *plugname, struct ng_vid_driver *driver); int ng_dsp_driver_register(int magic, char *plugname, struct ng_dsp_driver *driver); int ng_mix_driver_register(int magic, char *plugname, struct ng_mix_driver *driver); struct ng_video_conv* ng_conv_find_to(unsigned int out, int *i); struct ng_video_conv* ng_conv_find_from(unsigned int out, int *i); struct ng_video_conv* ng_conv_find_match(unsigned int in, unsigned int out); const struct ng_vid_driver* ng_vid_open(char **device, char *driver, struct ng_video_fmt *screen, void *base, void **handle); const struct ng_dsp_driver* ng_dsp_open(char *device, struct ng_audio_fmt *fmt, int record, void **handle); struct ng_attribute* ng_mix_init(char *device, char *channel); struct ng_reader* ng_find_reader(char *filename); int64_t ng_tofday_to_timestamp(struct timeval *tv); int64_t ng_get_timestamp(void); void ng_check_clipping(int width, int height, int xadjust, int yadjust, struct OVERLAY_CLIP *oc, int *count); struct ng_video_buf* ng_filter_single(struct ng_filter *filter, struct ng_video_buf *in); /* --------------------------------------------------------------------- */ void ng_init(void); void ng_lut_init(unsigned long red_mask, unsigned long green_mask, unsigned long blue_mask, unsigned int fmtid, int swap); void ng_rgb24_to_lut2(unsigned char *dest, unsigned char *src, int p); void ng_rgb24_to_lut4(unsigned char *dest, unsigned char *src, int p); /* --------------------------------------------------------------------- */ /* internal stuff starts here */ #ifdef NG_PRIVATE /* init functions */ void ng_color_packed_init(void); void ng_color_yuv2rgb_init(void); void ng_writefile_init(void); /* for yuv2rgb using lookup tables (color_lut.c, color_yuv2rgb.c) */ unsigned long ng_lut_red[256]; unsigned long ng_lut_green[256]; unsigned long ng_lut_blue[256]; void ng_yuv422_to_lut2(unsigned char *dest, unsigned char *s, int p); void ng_yuv422_to_lut4(unsigned char *dest, unsigned char *s, int p); void ng_yuv420p_to_lut2(void *h, struct ng_video_buf *out, struct ng_video_buf *in); void ng_yuv420p_to_lut4(void *h, struct ng_video_buf *out, struct ng_video_buf *in); void ng_yuv422p_to_lut2(void *h, struct ng_video_buf *out, struct ng_video_buf *in); void ng_yuv422p_to_lut4(void *h, struct ng_video_buf *out, struct ng_video_buf *in); /* color_common.c stuff */ void* ng_packed_init(struct ng_video_fmt *out, void *priv); void ng_packed_frame(void *handle, struct ng_video_buf *out, struct ng_video_buf *in); void* ng_conv_nop_init(struct ng_video_fmt *out, void *priv); void ng_conv_nop_fini(void *handle); #define NG_GENERIC_PACKED \ .init = ng_packed_init, \ .frame = ng_packed_frame, \ .fini = ng_conv_nop_fini #endif /* NG_PRIVATE */ /* --------------------------------------------------------------------- */ /* * Local variables: * compile-command: "(cd ..; make)" * End: */ xawtv-3.106/libng/list.h000066400000000000000000000104161343350355000151160ustar00rootroot00000000000000#ifndef _LIST_H #define _LIST_H 1 /* * Simple doubly linked list implementation. * -- shameless stolen from the linux kernel sources * * Some of the internal functions ("__xxx") are useful when * manipulating whole lists rather than single entries, as * sometimes we already know the next/prev entries and we can * generate better code by using them directly rather than * using the generic single-entry routines. */ struct list_head { struct list_head *next, *prev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) #define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0) /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static __inline__ void __list_add(struct list_head * new, struct list_head * prev, struct list_head * next) { next->prev = new; new->next = next; new->prev = prev; prev->next = new; } /** * list_add - add a new entry * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. */ static __inline__ void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); } /** * list_add_tail - add a new entry * @new: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. */ static __inline__ void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } /* * Delete a list entry by making the prev/next entries * point to each other. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static __inline__ void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; } /** * list_del - deletes entry from list. * @entry: the element to delete from the list. * Note: list_empty on entry does not return true after this, the entry is in an undefined state. */ static __inline__ void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); } /** * list_del_init - deletes entry from list and reinitialize it. * @entry: the element to delete from the list. */ static __inline__ void list_del_init(struct list_head *entry) { __list_del(entry->prev, entry->next); INIT_LIST_HEAD(entry); } /** * list_empty - tests whether a list is empty * @head: the list to test. */ static __inline__ int list_empty(struct list_head *head) { return head->next == head; } /** * list_splice - join two lists * @list: the new list to add. * @head: the place to add it in the first list. */ static __inline__ void list_splice(struct list_head *list, struct list_head *head) { struct list_head *first = list->next; if (first != list) { struct list_head *last = list->prev; struct list_head *at = head->next; first->prev = head; head->next = first; last->next = at; at->prev = last; } } /** * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. */ #define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) /** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. */ #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) /** * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop counter. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */ #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) /** * list_for_each_prev - iterate over a list in reverse order * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. */ #define list_for_each_prev(pos, head) \ for (pos = (head)->prev; pos != (head); pos = pos->prev) #endif /* _LIST_H */ xawtv-3.106/libng/plugins/000077500000000000000000000000001343350355000154515ustar00rootroot00000000000000xawtv-3.106/libng/plugins/Subdir.mk000066400000000000000000000056541343350355000172440ustar00rootroot00000000000000 # targets to build TARGETS-plugins := \ libng/plugins/flt-gamma.so \ libng/plugins/flt-invert.so \ libng/plugins/flt-disor.so \ libng/plugins/conv-mjpeg.so \ libng/plugins/read-avi.so \ libng/plugins/write-avi.so # libng/plugins/conv-audio.so ifeq ($(FOUND_LQT),yes) TARGETS-plugins += \ libng/plugins/read-qt.so \ libng/plugins/write-qt.so endif ifeq ($(FOUND_DV),yes) TARGETS-plugins += \ libng/plugins/read-dv.so \ libng/plugins/write-dv.so endif ifeq ($(FOUND_OS),linux) TARGETS-plugins += \ libng/plugins/drv0-v4l2.so \ libng/plugins/snd-oss.so endif ifeq ($(LIBV4L),yes) TARGETS-plugins += \ libng/plugins/drv0-libv4l.so endif ifeq ($(FOUND_OS),bsd) TARGETS-plugins += \ libng/plugins/drv0-bsd.so \ libng/plugins/snd-oss.so endif GONE-plugins := \ $(libdir)/invert.so \ $(libdir)/nop.so \ $(libdir)/flt-nop.so # libraries to link libng/plugins/read-qt.so : LDLIBS := $(QT_LIBS) libng/plugins/write-qt.so : LDLIBS := $(QT_LIBS) libng/plugins/read-dv.so : LDLIBS := $(DV_LIBS) libng/plugins/write-dv.so : LDLIBS := $(DV_LIBS) ifeq ($(FOUND_EXPLAIN),yes) libng/plugins/drv0-libv4l.so: LDLIBS := -lv4l2 -lexplain libng/plugins/drv0-v4l2.so: LDLIBS := -lv4l2 -lexplain else libng/plugins/drv0-libv4l.so: LDLIBS := -lv4l2 endif libng/plugins/flt-disor.so: LDLIBS := -lm libng/plugins/flt-gamma.so: LDLIBS := -lm libng/plugins/conv-mjpeg.so: LDLIBS := -ljpeg # global targets all:: $(TARGETS-plugins) install:: $(INSTALL_DIR) $(libdir) $(INSTALL_PROGRAM) $(STRIP_FLAG) $(TARGETS-plugins) $(libdir) rm -f $(GONE-plugins) clean:: rm -f $(TARGETS-plugins) libng/plugins/conv-mjpeg.so: libng/plugins/conv-mjpeg.o libng/plugins/drv0-bsd.so: libng/plugins/drv0-bsd.o libng/plugins/flt-debug.so: libng/plugins/flt-debug.o libng/plugins/flt-disor.so: libng/plugins/flt-disor.o libng/plugins/flt-gamma.so: libng/plugins/flt-gamma.o libng/plugins/flt-invert.so: libng/plugins/flt-invert.o libng/plugins/read-avi.so: libng/plugins/read-avi.o libng/plugins/read-dv.so: libng/plugins/read-dv.o libng/plugins/read-qt.so: libng/plugins/read-qt.o libng/plugins/snd-oss.so: libng/plugins/snd-oss.o libng/plugins/write-avi.so: libng/plugins/write-avi.o libng/plugins/write-dv.so: libng/plugins/write-dv.o libng/plugins/write-qt.so: libng/plugins/write-qt.o libng/plugins/drv0-v4l2.so: \ libng/plugins/drv0-v4l2.o \ libng/plugins/struct-v4l2.o \ libng/plugins/struct-dump.o libng/plugins/drv0-libv4l.so: \ libng/plugins/drv0-libv4l.o \ libng/plugins/struct-v4l2.o \ libng/plugins/struct-dump.o libng/plugins/drv0-libv4l.o: libng/plugins/drv0-v4l2.tmpl.c @$(echo_compile_c) -DUSE_LIBV4L @$(compile_c) -DUSE_LIBV4L @$(fixup_deps) libng/plugins/drv0-v4l2.o: libng/plugins/drv0-v4l2.tmpl.c @$(echo_compile_c) @$(compile_c) @$(fixup_deps) libng/plugins/struct-dump.o: structs/struct-dump.c @$(echo_compile_c) @$(compile_c) @$(fixup_deps) libng/plugins/struct-v4l2.o: structs/struct-v4l2.c @$(echo_compile_c) @$(compile_c) @$(fixup_deps) xawtv-3.106/libng/plugins/conv-audio.c000066400000000000000000000112141343350355000176600ustar00rootroot00000000000000#include #include #include #include #include #include #include "grab-ng.h" /* ---------------------------------------------------------------------- */ /* stuff we need from lame.h */ struct lame_global_struct; typedef struct lame_global_struct lame_global_flags; static lame_global_flags* (*lame_init)(void); static int (*lame_close)(lame_global_flags *); static int (*lame_set_in_samplerate)(lame_global_flags *, int); static int (*lame_set_num_channels)(lame_global_flags *, int); static int (*lame_set_quality)(lame_global_flags *, int); static int (*lame_init_params)(lame_global_flags * const ); /* * num_samples = number of samples in the L (or R) * channel, not the total number of samples in pcm[] * returns # of output bytes * mp3buffer_size_max = 1.25*num_samples + 7200 */ static int (*lame_encode_buffer_interleaved)( lame_global_flags* gfp, /* global context handlei */ short int pcm[], /* PCM data for left and right channel, interleaved */ int num_samples, /* number of samples per channel, _not_ number of samples in pcm[] */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ int mp3buf_size ); /* number of valid octets in this stream */ static int (*lame_encode_flush)( lame_global_flags * gfp, /* global context handle */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ int size); /* number of valid octets in this stream */ /* ---------------------------------------------------------------------- */ /* simple, portable dynamic linking (call stuff indirectly using */ /* function pointers) */ #define SYM(symbol) { .func = (void*)(&symbol), .name = #symbol } static struct { void **func; char *name; } symtab[] = { SYM(lame_init), SYM(lame_close), SYM(lame_set_in_samplerate), SYM(lame_set_num_channels), SYM(lame_set_quality), SYM(lame_init_params), SYM(lame_encode_buffer_interleaved), SYM(lame_encode_flush), }; static int link_lame(void) { void *handle; void *symbol; unsigned int i; handle = dlopen("libmp3lame.so.0",RTLD_NOW); if (NULL == handle) return -1; for (i = 0; i < sizeof(symtab)/sizeof(symtab[0]); i++) { symbol = dlsym(handle,symtab[i].name); if (NULL == symbol) { fprintf(stderr,"dlsym(mp3lame,%s): %s\n", symtab[i].name, dlerror()); dlclose(handle); return -1; } *(symtab[i].func) = symbol; } return 0; } /* ---------------------------------------------------------------------- */ struct mp3_enc_state { lame_global_flags *gf; int first; }; static void* mp3_enc_init(void *priv) { struct mp3_enc_state *h; h = malloc(sizeof(*h)); if (NULL == h) return NULL; memset(h,0,sizeof(*h)); h->gf = lame_init(); h->first = 1; return h; } static struct ng_audio_buf* mp3_enc_data(void *handle, struct ng_audio_buf *in) { static struct ng_audio_fmt fmt = { .fmtid = AUDIO_MP3, .rate = 0, }; struct mp3_enc_state *h = handle; struct ng_audio_buf *out; int samples, size; if (h->first) { lame_set_in_samplerate(h->gf, in->fmt.rate); lame_set_num_channels(h->gf, ng_afmt_to_channels[in->fmt.fmtid]); lame_set_quality(h->gf, 5 /* FIXME */); lame_init_params(h->gf); h->first = 0; } samples = in->size >> 2; size = 7200 + samples * 5 / 4; /* worst case */ out = ng_malloc_audio_buf(&fmt, size); out->size = lame_encode_buffer_interleaved (h->gf, (short int*) in->data, samples, out->data, size); free(in); return out; } static void mp3_enc_fini(void *handle) { struct mp3_enc_state *h = handle; lame_close(h->gf); free(h); } /* ---------------------------------------------------------------------- */ static struct ng_audio_conv mp3_list[] = { { /* --- compress --- */ init: mp3_enc_init, frame: mp3_enc_data, fini: mp3_enc_fini, fmtid_in: AUDIO_S16_NATIVE_STEREO, fmtid_out: AUDIO_MP3, priv: NULL, } }; static const int nconv = sizeof(mp3_list)/sizeof(mp3_list[0]); /* ---------------------------------------------------------------------- */ /* init stuff */ extern void ng_plugin_init(void); void ng_plugin_init(void) { if (0 != link_lame()) return; ng_aconv_register(NG_PLUGIN_MAGIC,__FILE__,mp3_list,nconv); } xawtv-3.106/libng/plugins/conv-mjpeg.c000066400000000000000000000407101343350355000176640ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include "grab-ng.h" /* ---------------------------------------------------------------------- */ struct mjpeg_compress { struct jpeg_destination_mgr mjpg_dest; /* must be first */ struct jpeg_compress_struct mjpg_cinfo; struct jpeg_error_mgr mjpg_jerr; struct ng_video_fmt fmt; JOCTET *mjpg_buffer; size_t mjpg_bufsize; size_t mjpg_bufused; int mjpg_tables; /* yuv */ unsigned char **mjpg_ptrs[3]; }; struct mjpeg_decompress { struct jpeg_source_mgr mjpg_src; /* must be first */ struct jpeg_decompress_struct mjpg_cinfo; struct jpeg_error_mgr mjpg_jerr; struct ng_video_fmt fmt; struct ng_video_buf *buf; /* yuv */ unsigned char **mjpg_ptrs[3]; }; struct mjpeg_yuv_priv { int luma_h; int luma_v; }; static void swap_rgb24(char *mem, int n) { char c; char *p = mem; int i = n; while (--i) { c = p[0]; p[0] = p[2]; p[2] = c; p += 3; } } /* ---------------------------------------------------------------------- */ /* I/O manager */ static void mjpg_dest_init(struct jpeg_compress_struct *cinfo) { struct mjpeg_compress *h = (struct mjpeg_compress*)cinfo->dest; cinfo->dest->next_output_byte = h->mjpg_buffer; cinfo->dest->free_in_buffer = h->mjpg_bufsize; } static boolean mjpg_dest_flush(struct jpeg_compress_struct *cinfo) { fprintf(stderr,"mjpg: panic: output buffer too small\n"); exit(1); } static void mjpg_dest_term(struct jpeg_compress_struct *cinfo) { struct mjpeg_compress *h = (struct mjpeg_compress*)cinfo->dest; h->mjpg_bufused = h->mjpg_bufsize - cinfo->dest->free_in_buffer; } static void mjpg_src_init(struct jpeg_decompress_struct *cinfo) { struct mjpeg_decompress *h = (struct mjpeg_decompress*)cinfo->src; cinfo->src->next_input_byte = h->buf->data; cinfo->src->bytes_in_buffer = h->buf->size; } static int mjpg_src_fill(struct jpeg_decompress_struct *cinfo) { fprintf(stderr,"mjpg: panic: no more input data\n"); exit(1); } static void mjpg_src_skip(struct jpeg_decompress_struct *cinfo, long num_bytes) { cinfo->src->next_input_byte += num_bytes; } static void mjpg_src_term(struct jpeg_decompress_struct *cinfo) { /* nothing */ } /* ---------------------------------------------------------------------- */ /* compress */ static struct mjpeg_compress* mjpg_init(struct ng_video_fmt *fmt) { struct mjpeg_compress *h; h = malloc(sizeof(*h)); if (NULL == h) return NULL; memset(h,0,sizeof(*h)); h->mjpg_cinfo.err = jpeg_std_error(&h->mjpg_jerr); jpeg_create_compress(&h->mjpg_cinfo); h->mjpg_dest.init_destination = mjpg_dest_init; h->mjpg_dest.empty_output_buffer = mjpg_dest_flush; h->mjpg_dest.term_destination = mjpg_dest_term; h->mjpg_cinfo.dest = &h->mjpg_dest; h->fmt = *fmt; h->mjpg_tables = TRUE; h->mjpg_cinfo.image_width = fmt->width; h->mjpg_cinfo.image_height = fmt->height; h->mjpg_cinfo.image_width &= ~(2*DCTSIZE-1); h->mjpg_cinfo.image_height &= ~(2*DCTSIZE-1); return h; } static void mjpg_cleanup(void *handle) { struct mjpeg_compress *h = handle; int i; if (ng_debug > 1) fprintf(stderr,"mjpg_cleanup\n"); jpeg_destroy_compress(&h->mjpg_cinfo); for (i = 0; i < 3; i++) if (NULL != h->mjpg_ptrs[i]) free(h->mjpg_ptrs[i]); free(h); } /* ---------------------------------------------------------------------- */ static void* mjpg_rgb_init(struct ng_video_fmt *out, void *priv) { struct mjpeg_compress *h; if (ng_debug > 1) fprintf(stderr,"mjpg_rgb_init\n"); h = mjpg_init(out); if (NULL == h) return NULL; h->mjpg_cinfo.input_components = 3; h->mjpg_cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&h->mjpg_cinfo); h->mjpg_cinfo.dct_method = JDCT_FASTEST; jpeg_set_quality(&h->mjpg_cinfo, ng_jpeg_quality, TRUE); jpeg_suppress_tables(&h->mjpg_cinfo, TRUE); return h; } static void mjpg_rgb_compress(void *handle, struct ng_video_buf *out, struct ng_video_buf *in) { struct mjpeg_compress *h = handle; unsigned char *line; unsigned int i; if (ng_debug > 1) fprintf(stderr,"mjpg_rgb_compress\n"); h->mjpg_buffer = out->data; h->mjpg_bufsize = out->size; jpeg_start_compress(&h->mjpg_cinfo, h->mjpg_tables); for (i = 0, line = in->data; i < h->mjpg_cinfo.image_height; i++, line += 3*h->mjpg_cinfo.image_width) jpeg_write_scanlines(&h->mjpg_cinfo, &line, 1); jpeg_finish_compress(&h->mjpg_cinfo); out->size = h->mjpg_bufused; } static void mjpg_bgr_compress(void *handle, struct ng_video_buf *out, struct ng_video_buf *in) { swap_rgb24(in->data,in->fmt.width*in->fmt.height); /* FIXME */ return mjpg_rgb_compress(handle,out,in); } /* ---------------------------------------------------------------------- */ static void* mjpg_yuv_init(struct ng_video_fmt *out, void *priv) { struct mjpeg_compress *h; struct mjpeg_yuv_priv *c = priv; if (ng_debug > 1) fprintf(stderr,"mjpg_yuv_init\n"); h = mjpg_init(out); if (NULL == h) return NULL; h->mjpg_cinfo.input_components = 3; h->mjpg_cinfo.in_color_space = JCS_YCbCr; jpeg_set_defaults(&h->mjpg_cinfo); h->mjpg_cinfo.dct_method = JDCT_FASTEST; jpeg_set_quality(&h->mjpg_cinfo, ng_jpeg_quality, TRUE); h->mjpg_cinfo.raw_data_in = TRUE; #if JPEG_LIB_VERSION >= 70 h->mjpg_cinfo.do_fancy_downsampling = FALSE; // fix segfaulst with libjpeg v7++ #endif jpeg_set_colorspace(&h->mjpg_cinfo,JCS_YCbCr); h->mjpg_ptrs[0] = malloc(h->fmt.height*sizeof(char*)); h->mjpg_ptrs[1] = malloc(h->fmt.height*sizeof(char*)); h->mjpg_ptrs[2] = malloc(h->fmt.height*sizeof(char*)); h->mjpg_cinfo.comp_info[0].h_samp_factor = c->luma_h; h->mjpg_cinfo.comp_info[0].v_samp_factor = c->luma_v; h->mjpg_cinfo.comp_info[1].h_samp_factor = 1; h->mjpg_cinfo.comp_info[1].v_samp_factor = 1; h->mjpg_cinfo.comp_info[2].h_samp_factor = 1; h->mjpg_cinfo.comp_info[2].v_samp_factor = 1; jpeg_suppress_tables(&h->mjpg_cinfo, TRUE); return h; } static void mjpg_420_compress(struct mjpeg_compress *h) { unsigned char **mjpg_run[3]; unsigned int y; mjpg_run[0] = h->mjpg_ptrs[0]; mjpg_run[1] = h->mjpg_ptrs[1]; mjpg_run[2] = h->mjpg_ptrs[2]; jpeg_start_compress(&h->mjpg_cinfo, h->mjpg_tables); for (y = 0; y < h->mjpg_cinfo.image_height; y += 2*DCTSIZE) { jpeg_write_raw_data(&h->mjpg_cinfo, mjpg_run,2*DCTSIZE); mjpg_run[0] += 2*DCTSIZE; mjpg_run[1] += DCTSIZE; mjpg_run[2] += DCTSIZE; } jpeg_finish_compress(&h->mjpg_cinfo); } static void mjpg_422_compress(struct mjpeg_compress *h) { unsigned char **mjpg_run[3]; unsigned int y; mjpg_run[0] = h->mjpg_ptrs[0]; mjpg_run[1] = h->mjpg_ptrs[1]; mjpg_run[2] = h->mjpg_ptrs[2]; h->mjpg_cinfo.write_JFIF_header = FALSE; jpeg_start_compress(&h->mjpg_cinfo, h->mjpg_tables); jpeg_write_marker(&h->mjpg_cinfo, JPEG_APP0, "AVI1\0\0\0\0", 8); for (y = 0; y < h->mjpg_cinfo.image_height; y += DCTSIZE) { jpeg_write_raw_data(&h->mjpg_cinfo, mjpg_run, DCTSIZE); mjpg_run[0] += DCTSIZE; mjpg_run[1] += DCTSIZE; mjpg_run[2] += DCTSIZE; } jpeg_finish_compress(&h->mjpg_cinfo); } /* ---------------------------------------------------------------------- */ static void mjpg_422_420_compress(void *handle, struct ng_video_buf *out, struct ng_video_buf *in) { struct mjpeg_compress *h = handle; unsigned char *line; unsigned int i; if (ng_debug > 1) fprintf(stderr,"mjpg_422_420_compress\n"); h->mjpg_buffer = out->data; h->mjpg_bufsize = out->size; line = in->data; for (i = 0; i < h->mjpg_cinfo.image_height; i++, line += in->fmt.width) h->mjpg_ptrs[0][i] = line; line = in->data + in->fmt.width*in->fmt.height; for (i = 0; i < h->mjpg_cinfo.image_height; i+=2, line += in->fmt.width) h->mjpg_ptrs[1][i/2] = line; line = in->data + in->fmt.width*in->fmt.height*3/2; for (i = 0; i < h->mjpg_cinfo.image_height; i+=2, line += in->fmt.width) h->mjpg_ptrs[2][i/2] = line; mjpg_420_compress(h); out->size = h->mjpg_bufused; } static void mjpg_420_420_compress(void *handle, struct ng_video_buf *out, struct ng_video_buf *in) { struct mjpeg_compress *h = handle; unsigned char *line; unsigned int i; if (ng_debug > 1) fprintf(stderr,"mjpg_420_420_compress\n"); h->mjpg_buffer = out->data; h->mjpg_bufsize = out->size; line = in->data; for (i = 0; i < h->mjpg_cinfo.image_height; i++, line += in->fmt.width) h->mjpg_ptrs[0][i] = line; line = in->data + in->fmt.width*in->fmt.height; for (i = 0; i < h->mjpg_cinfo.image_height; i+=2, line += in->fmt.width/2) h->mjpg_ptrs[1][i/2] = line; line = in->data + in->fmt.width*in->fmt.height*5/4; for (i = 0; i < h->mjpg_cinfo.image_height; i+=2, line += in->fmt.width/2) h->mjpg_ptrs[2][i/2] = line; mjpg_420_compress(h); out->size = h->mjpg_bufused; } /* ---------------------------------------------------------------------- */ static void mjpg_422_422_compress(void *handle, struct ng_video_buf *out, struct ng_video_buf *in) { struct mjpeg_compress *h = handle; unsigned char *line; unsigned int i; if (ng_debug > 1) fprintf(stderr,"mjpg_422_422_compress\n"); h->mjpg_buffer = out->data; h->mjpg_bufsize = out->size; line = in->data; for (i = 0; i < h->mjpg_cinfo.image_height; i++, line += in->fmt.width) h->mjpg_ptrs[0][i] = line; line = in->data + in->fmt.width*in->fmt.height; for (i = 0; i < h->mjpg_cinfo.image_height; i++, line += in->fmt.width/2) h->mjpg_ptrs[1][i] = line; line = in->data + in->fmt.width*in->fmt.height*3/2; for (i = 0; i < h->mjpg_cinfo.image_height; i++, line += in->fmt.width/2) h->mjpg_ptrs[2][i] = line; mjpg_422_compress(h); out->size = h->mjpg_bufused; } /* ---------------------------------------------------------------------- */ /* decompress */ static void* mjpg_de_init(struct ng_video_fmt *fmt, void *priv) { struct mjpeg_decompress *h; h = malloc(sizeof(*h)); if (NULL == h) return NULL; memset(h,0,sizeof(*h)); h->fmt = *fmt; h->mjpg_cinfo.err = jpeg_std_error(&h->mjpg_jerr); jpeg_create_decompress(&h->mjpg_cinfo); h->mjpg_src.init_source = mjpg_src_init; h->mjpg_src.fill_input_buffer = mjpg_src_fill; h->mjpg_src.skip_input_data = mjpg_src_skip; h->mjpg_src.resync_to_restart = jpeg_resync_to_restart; h->mjpg_src.term_source = mjpg_src_term; h->mjpg_cinfo.src = &h->mjpg_src; switch (h->fmt.fmtid) { case VIDEO_YUV420P: h->mjpg_ptrs[0] = malloc(h->fmt.height*sizeof(char*)); h->mjpg_ptrs[1] = malloc(h->fmt.height*sizeof(char*)); h->mjpg_ptrs[2] = malloc(h->fmt.height*sizeof(char*)); break; } return h; } static void mjpg_rgb_decompress(void *handle, struct ng_video_buf *out, struct ng_video_buf *in) { struct mjpeg_decompress *h = handle; unsigned char *line; unsigned int i; if (ng_debug > 1) fprintf(stderr,"mjpg_rgb_decompress\n"); h->buf = in; jpeg_read_header(&h->mjpg_cinfo,1); h->mjpg_cinfo.out_color_space = JCS_RGB; jpeg_start_decompress(&h->mjpg_cinfo); for (i = 0, line = out->data; i < out->fmt.height; i++, line += out->fmt.bytesperline) { jpeg_read_scanlines(&h->mjpg_cinfo, &line, 1); } jpeg_finish_decompress(&h->mjpg_cinfo); } static void mjpg_yuv420_decompress(void *handle, struct ng_video_buf *out, struct ng_video_buf *in) { struct mjpeg_decompress *h = handle; unsigned char **mjpg_run[3]; unsigned char *line; unsigned int i,y; if (ng_debug > 1) fprintf(stderr,"mjpg_yuv_decompress\n"); h->buf = in; jpeg_read_header(&h->mjpg_cinfo,1); h->mjpg_cinfo.raw_data_out = 1; if (ng_debug > 1) fprintf(stderr,"yuv: %dx%d - %d %d / %d %d / %d %d\n", h->mjpg_cinfo.image_width, h->mjpg_cinfo.image_height, h->mjpg_cinfo.comp_info[0].h_samp_factor, h->mjpg_cinfo.comp_info[0].v_samp_factor, h->mjpg_cinfo.comp_info[1].h_samp_factor, h->mjpg_cinfo.comp_info[1].v_samp_factor, h->mjpg_cinfo.comp_info[2].h_samp_factor, h->mjpg_cinfo.comp_info[2].v_samp_factor); jpeg_start_decompress(&h->mjpg_cinfo); mjpg_run[0] = h->mjpg_ptrs[0]; mjpg_run[1] = h->mjpg_ptrs[1]; mjpg_run[2] = h->mjpg_ptrs[2]; line = out->data; for (i = 0; i < h->mjpg_cinfo.image_height; i++, line += out->fmt.width) h->mjpg_ptrs[0][i] = line; if (2 == h->mjpg_cinfo.comp_info[0].v_samp_factor) { /* file has 420 -- all fine */ line = out->data + out->fmt.width*out->fmt.height; for (i = 0; i < out->fmt.height; i+=2, line += out->fmt.width/2) h->mjpg_ptrs[1][i/2] = line; line = out->data + out->fmt.width*out->fmt.height*5/4; for (i = 0; i < out->fmt.height; i+=2, line += out->fmt.width/2) h->mjpg_ptrs[2][i/2] = line; for (y = 0; y < out->fmt.height; y += 2*DCTSIZE) { jpeg_read_raw_data(&h->mjpg_cinfo, mjpg_run,2*DCTSIZE); mjpg_run[0] += 2*DCTSIZE; mjpg_run[1] += DCTSIZE; mjpg_run[2] += DCTSIZE; } } else { /* file has 422 -- drop lines */ line = out->data + out->fmt.width*out->fmt.height; for (i = 0; i < out->fmt.height; i+=2, line += out->fmt.width/2) { h->mjpg_ptrs[1][i+0] = line; h->mjpg_ptrs[1][i+1] = line; } line = out->data + out->fmt.width*out->fmt.height*5/4; for (i = 0; i < out->fmt.height; i+=2, line += out->fmt.width/2) { h->mjpg_ptrs[2][i+0] = line; h->mjpg_ptrs[2][i+1] = line; } for (y = 0; y < h->mjpg_cinfo.image_height; y += DCTSIZE) { jpeg_read_raw_data(&h->mjpg_cinfo, mjpg_run,DCTSIZE); mjpg_run[0] += DCTSIZE; mjpg_run[1] += DCTSIZE; mjpg_run[2] += DCTSIZE; } } jpeg_finish_decompress(&h->mjpg_cinfo); } static void mjpg_de_cleanup(void *handle) { struct mjpeg_decompress *h = handle; if (ng_debug > 1) fprintf(stderr,"mjpg_de_cleanup\n"); jpeg_destroy_decompress(&h->mjpg_cinfo); if (h->mjpg_ptrs[0]) free(h->mjpg_ptrs[0]); if (h->mjpg_ptrs[1]) free(h->mjpg_ptrs[1]); if (h->mjpg_ptrs[2]) free(h->mjpg_ptrs[2]); free(h); } /* ---------------------------------------------------------------------- */ /* static data + register */ static struct mjpeg_yuv_priv priv_420 = { .luma_h = 2, .luma_v = 2, }; static struct mjpeg_yuv_priv priv_422 = { .luma_h = 2, .luma_v = 1, }; static struct ng_video_conv mjpg_list[] = { { /* --- compress --- */ .init = mjpg_yuv_init, .frame = mjpg_420_420_compress, .fini = mjpg_cleanup, .fmtid_in = VIDEO_YUV420P, .fmtid_out = VIDEO_JPEG, .priv = &priv_420, },{ .init = mjpg_yuv_init, .frame = mjpg_422_420_compress, .fini = mjpg_cleanup, .fmtid_in = VIDEO_YUV422P, .fmtid_out = VIDEO_JPEG, .priv = &priv_420, },{ .init = mjpg_rgb_init, .frame = mjpg_rgb_compress, .fini = mjpg_cleanup, .fmtid_in = VIDEO_RGB24, .fmtid_out = VIDEO_JPEG, },{ .init = mjpg_rgb_init, .frame = mjpg_bgr_compress, .fini = mjpg_cleanup, .fmtid_in = VIDEO_BGR24, .fmtid_out = VIDEO_JPEG, },{ .init = mjpg_yuv_init, .frame = mjpg_422_422_compress, .fini = mjpg_cleanup, .fmtid_in = VIDEO_YUV422P, .fmtid_out = VIDEO_MJPEG, .priv = &priv_422, },{ /* --- uncompress --- */ .init = mjpg_de_init, .frame = mjpg_rgb_decompress, .fini = mjpg_de_cleanup, .fmtid_in = VIDEO_MJPEG, .fmtid_out = VIDEO_RGB24, },{ .init = mjpg_de_init, .frame = mjpg_rgb_decompress, .fini = mjpg_de_cleanup, .fmtid_in = VIDEO_JPEG, .fmtid_out = VIDEO_RGB24, },{ .init = mjpg_de_init, .frame = mjpg_yuv420_decompress, .fini = mjpg_de_cleanup, .fmtid_in = VIDEO_MJPEG, .fmtid_out = VIDEO_YUV420P, },{ .init = mjpg_de_init, .frame = mjpg_yuv420_decompress, .fini = mjpg_de_cleanup, .fmtid_in = VIDEO_JPEG, .fmtid_out = VIDEO_YUV420P, } }; static const int nconv = sizeof(mjpg_list)/sizeof(struct ng_video_conv); extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_conv_register(NG_PLUGIN_MAGIC,__FILE__,mjpg_list,nconv); } xawtv-3.106/libng/plugins/drv0-bsd.c000066400000000000000000000500551343350355000172430ustar00rootroot00000000000000/* * interface to the bsd bktr driver * * (c) 2000,01 Gerd Knorr * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_DEV_IC_BT8XX_H # include #endif #ifdef HAVE_MACHINE_IOCTL_BT848_H # include # include #endif #include "grab-ng.h" /* ---------------------------------------------------------------------- */ /* global variables */ struct bsd_handle { int fd; int tfd; /* formats */ int pf_count; struct meteor_pixfmt pf[64]; int xawtv2pf[VIDEO_FMT_COUNT]; unsigned char *map; /* attributes */ int muted; struct ng_attribute *attr; /* overlay */ struct meteor_video fb,pos; struct meteor_geomet ovgeo; struct meteor_pixfmt *ovfmt; struct bktr_clip clip[BT848_MAX_CLIP_NODE]; int ov_enabled,ov_on; /* capture */ int fps; long long start; struct ng_video_fmt fmt; struct meteor_video nofb; struct meteor_geomet capgeo; struct meteor_pixfmt *capfmt; struct bktr_clip noclip[BT848_MAX_CLIP_NODE]; }; /* ---------------------------------------------------------------------- */ /* prototypes */ /* open/close */ static void* bsd_open(char *device, int req_flags); static int bsd_close(void *handle); /* attributes */ static int bsd_flags(void *handle); static struct ng_attribute* bsd_attrs(void *handle); static int bsd_read_attr(struct ng_attribute*); static void bsd_write_attr(struct ng_attribute*, int val); static void bsd_get_min_size(void *hdl, int *min_width, int *min_height); static int bsd_setupfb(void *handle, struct ng_video_fmt *fmt, void *base); static int bsd_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y, struct OVERLAY_CLIP *oc, int count, int aspect); /* capture */ static void catchsignal(int signal); static void siginit(void); static int bsd_setformat(void *handle, struct ng_video_fmt *fmt); static int bsd_startvideo(void *handle, int fps, unsigned int buffers); static void bsd_stopvideo(void *handle); static struct ng_video_buf* bsd_nextframe(void *handle); static struct ng_video_buf* bsd_getimage(void *handle); /* tuner */ static unsigned long bsd_getfreq(void *handle); static void bsd_setfreq(void *handle, unsigned long freq); static int bsd_tuned(void *handle); struct ng_vid_driver bsd_driver = { name: "bktr", open: bsd_open, close: bsd_close, capabilities: bsd_flags, list_attrs: bsd_attrs, get_min_size: bsd_get_min_size, setupfb: bsd_setupfb, overlay: bsd_overlay, setformat: bsd_setformat, startvideo: bsd_startvideo, stopvideo: bsd_stopvideo, nextframe: bsd_nextframe, getimage: bsd_getimage, getfreq: bsd_getfreq, setfreq: bsd_setfreq, is_tuned: bsd_tuned, }; /* ---------------------------------------------------------------------- */ static struct STRTAB inputs[] = { { 0, "Television" }, { 1, "Composite1" }, { 2, "S-Video" }, { 3, "CSVIDEO" }, { -1, NULL } }; static int inputs_map[] = { METEOR_INPUT_DEV1, METEOR_INPUT_DEV0, METEOR_INPUT_DEV_SVIDEO, METEOR_INPUT_DEV2, }; static struct STRTAB norms[] = { { 0, "NTSC" }, { 1, "NTSC-JP" }, { 2, "PAL" }, { 3, "PAL-M" }, { 4, "PAL-N" }, { 5, "SECAM" }, { 6, "RSVD" }, { -1, NULL } }; static int norms_map[] = { BT848_IFORM_F_NTSCM, BT848_IFORM_F_NTSCJ, BT848_IFORM_F_PALBDGHI, BT848_IFORM_F_PALM, BT848_IFORM_F_PALN, BT848_IFORM_F_SECAM, BT848_IFORM_F_RSVD, }; static struct STRTAB audio[] = { { 0, "Tuner" }, { 1, "Extern" }, { 2, "Intern" }, { -1, NULL } }; static int audio_map[] = { AUDIO_TUNER, AUDIO_EXTERN, AUDIO_INTERN, }; static struct ng_attribute bsd_attr[] = { { id: ATTR_ID_COUNT+1, name: "audio", type: ATTR_TYPE_CHOICE, choices: audio, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_NORM, name: "norm", type: ATTR_TYPE_CHOICE, choices: norms, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_INPUT, name: "input", type: ATTR_TYPE_CHOICE, choices: inputs, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_MUTE, name: "mute", type: ATTR_TYPE_BOOL, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_HUE, name: "hue", type: ATTR_TYPE_INTEGER, min: BT848_HUEREGMIN, max: BT848_HUEREGMAX, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_BRIGHT, name: "bright", type: ATTR_TYPE_INTEGER, min: BT848_BRIGHTREGMIN, max: BT848_BRIGHTREGMAX, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_CONTRAST, name: "contrast", type: ATTR_TYPE_INTEGER, min: BT848_CONTRASTREGMIN, max: BT848_CONTRASTREGMAX, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_COLOR, name: "color", type: ATTR_TYPE_INTEGER, min: BT848_CHROMAREGMIN, max: BT848_CHROMAREGMAX, read: bsd_read_attr, write: bsd_write_attr, },{ /* end of list */ } }; static int single = METEOR_CAP_SINGLE; static int start = METEOR_CAP_CONTINOUS; static int stop = METEOR_CAP_STOP_CONT; static int signal_on = SIGUSR1; static int signal_off = METEOR_SIG_MODE_MASK; /* ---------------------------------------------------------------------- */ #define PREFIX "bktr: ioctl: " static int xioctl(int fd, int cmd, void *arg) { int rc; rc = ioctl(fd,cmd,arg); if (0 == rc && ng_debug < 2) return 0; switch (cmd) { case METEORSVIDEO: { struct meteor_video *a = arg; fprintf(stderr,PREFIX "METEORSVIDEO(addr=0x%08lx,width=%ld,bank=%ld,ram=%ld)", a->addr,a->width,a->banksize,a->ramsize); break; } case METEORSETGEO: { struct meteor_geomet *a = arg; fprintf(stderr,PREFIX "METEORSETGEO(%dx%d,frames=%d,oformat=0x%lx)", a->columns,a->rows,a->frames,a->oformat); break; } case METEORSACTPIXFMT: { struct meteor_pixfmt *a = arg; fprintf(stderr,PREFIX "METEORSACTPIXFMT(%d,type=%d,bpp=%d," "masks=0x%lx/0x%lx/0x%lx,sb=%d,ss=%d)", a->index,a->type,a->Bpp,a->masks[0],a->masks[1],a->masks[2], a->swap_bytes,a->swap_shorts); break; } case METEORCAPTUR: { int *a = arg; fprintf(stderr,PREFIX "METEORCAPTUR(%d)",*a); break; } case METEORSSIGNAL: { int *a = arg; fprintf(stderr,PREFIX "METEORSSIGNAL(0x%x)",*a); break; } case BT848SCLIP: { fprintf(stderr,PREFIX "BT848SCLIP"); break; } default: fprintf(stderr,PREFIX "UNKNOWN(cmd=0x%x)",cmd); break; } fprintf(stderr,": %s\n",(rc == 0) ? "ok" : strerror(errno)); return rc; } /* ---------------------------------------------------------------------- */ static void bsd_print_format(struct meteor_pixfmt *pf, int format) { switch (pf->type) { case METEOR_PIXTYPE_RGB: fprintf(stderr, "bktr: pf: rgb bpp=%d mask=%ld,%ld,%ld", pf->Bpp,pf->masks[0],pf->masks[1],pf->masks[2]); break; case METEOR_PIXTYPE_YUV: fprintf(stderr,"bktr: pf: yuv h422 v111 (planar)"); break; case METEOR_PIXTYPE_YUV_PACKED: fprintf(stderr,"bktr: pf: yuyv h422 v111 (packed)"); break; case METEOR_PIXTYPE_YUV_12: fprintf(stderr,"bktr: pf: yuv h422 v422 (planar)"); break; default: fprintf(stderr,"bktr: pf: unknown"); } fprintf(stderr," sbytes=%d sshorts=%d (fmt=%d)\n", pf->swap_bytes,pf->swap_shorts,format); } /* ---------------------------------------------------------------------- */ static void* bsd_open(char *filename, int req_flags) { struct bsd_handle *h; int format,i; h = malloc(sizeof(*h)); if (NULL == h) return NULL; memset(h,0,sizeof(*h)); if (-1 == (h->fd = open(filename,O_RDONLY))) { fprintf(stderr,"bktr: open %s: %s\n", filename,strerror(errno)); goto err; } /* video formats */ for (format = 0; format < VIDEO_FMT_COUNT; format++) h->xawtv2pf[format] = -1; for (h->pf_count = 0; h->pf_count < 64; h->pf_count++) { h->pf[h->pf_count].index = h->pf_count; if (-1 == ioctl(h->fd, METEORGSUPPIXFMT,h->pf+h->pf_count)) { if (ng_debug) perror("bktr: ioctl METEORGSUPPIXFMT"); if (0 == h->pf_count) goto err; break; } format = -1; switch (h->pf[h->pf_count].type) { case METEOR_PIXTYPE_RGB: switch(h->pf[h->pf_count].masks[0]) { case 31744: /* 15 bpp */ format = h->pf[h->pf_count].swap_bytes ? VIDEO_RGB15_LE : VIDEO_RGB15_BE; break; case 63488: /* 16 bpp */ format = h->pf[h->pf_count].swap_bytes ? VIDEO_RGB16_LE : VIDEO_RGB16_BE; break; case 16711680: /* 24/32 bpp */ if (h->pf[h->pf_count].Bpp == 3 && h->pf[h->pf_count].swap_bytes == 1) { format = VIDEO_BGR24; } else if (h->pf[h->pf_count].Bpp == 4 && h->pf[h->pf_count].swap_bytes == 1 && h->pf[h->pf_count].swap_shorts == 1) { format = VIDEO_BGR32; } else if (h->pf[h->pf_count].Bpp == 4 && h->pf[h->pf_count].swap_bytes == 0 && h->pf[h->pf_count].swap_shorts == 0) { format = VIDEO_RGB32; } } break; case METEOR_PIXTYPE_YUV: format = VIDEO_YUV422P; break; #if 0 case METEOR_PIXTYPE_YUV_PACKED: format = VIDEO_YUV422; h->pf[h->pf_count].swap_shorts = 0; /* seems not to work */ break; #endif case METEOR_PIXTYPE_YUV_12: case METEOR_PIXTYPE_YUV_PACKED: /* nothing */ break; } if (-1 != format) h->xawtv2pf[format] = h->pf_count; if (ng_debug) bsd_print_format(h->pf+h->pf_count,format); } h->map = mmap(0,768*576*4, PROT_READ, MAP_SHARED, h->fd, 0); if ((unsigned char*)-1 == h->map) { perror("bktr: mmap"); h->map = NULL; } if (-1 == (h->tfd = open("/dev/tuner0",O_RDONLY))) { fprintf(stderr,"bktr: open %s: %s\n", "/dev/tuner0",strerror(errno)); } siginit(); h->attr = malloc(sizeof(bsd_attr)); memcpy(h->attr,bsd_attr,sizeof(bsd_attr)); for (i = 0; h->attr[i].name != NULL; i++) h->attr[i].handle = h; return h; err: if (-1 != h->fd) close(h->fd); if (-1 != h->tfd) close(h->tfd); if (h) free(h); return NULL; } static int bsd_close(void *handle) { struct bsd_handle *h = handle; if (ng_debug) fprintf(stderr, "bktr: close\n"); close(h->fd); if (-1 != h->tfd) close(h->tfd); if (NULL != h->map) munmap(h->map,768*576*4); free(h); return 0; } static int bsd_flags(void *handle) { int ret = 0; ret |= CAN_OVERLAY; ret |= CAN_CAPTURE; ret |= CAN_TUNE; return ret; } static struct ng_attribute* bsd_attrs(void *handle) { struct bsd_handle *h = handle; return h->attr; } static void bsd_get_min_size(void *handle, int *min_width, int *min_height) { *min_width = 32; *min_height = 24; } /* ---------------------------------------------------------------------- */ static int bsd_get_range(int id, int *get, int *set) { switch (id) { case ATTR_ID_HUE: *get = BT848_GHUE; *set = BT848_SHUE; break; case ATTR_ID_BRIGHT: *get = BT848_GBRIG; *set = BT848_SBRIG; break; case ATTR_ID_CONTRAST: *get = BT848_GCONT; *set = BT848_SCONT; break; case ATTR_ID_COLOR: *get = BT848_GCSAT; *set = BT848_SCSAT; break; default: return -1; } return 0; } static int bsd_read_attr(struct ng_attribute *attr) { struct bsd_handle *h = attr->handle; int arg, get, set, i; int value = -1; switch (attr->id) { case ATTR_ID_NORM: if (-1 != xioctl(h->fd,BT848GFMT,&arg)) for (i = 0; i < sizeof(norms_map)/sizeof(int); i++) if (arg == norms_map[i]) value = i; break; case ATTR_ID_INPUT: if (-1 != xioctl(h->fd,METEORGINPUT,&arg)) for (i = 0; i < sizeof(inputs_map)/sizeof(int); i++) if (arg == inputs_map[i]) value = i; break; case ATTR_ID_MUTE: if (-1 != xioctl(h->tfd, BT848_GAUDIO, &arg)) value = (arg == AUDIO_MUTE) ? 1 : 0; break; case ATTR_ID_HUE: case ATTR_ID_BRIGHT: case ATTR_ID_CONTRAST: case ATTR_ID_COLOR: bsd_get_range(attr->id,&get,&set); if (-1 != xioctl(h->tfd,get,&arg)) value = arg; break; case ATTR_ID_COUNT+1: /* AUDIO */ if (-1 != xioctl(h->tfd, BT848_GAUDIO, &arg)) for (i = 0; i < sizeof(audio_map)/sizeof(int); i++) if (arg == audio_map[i]) value = i; break; default: break; } return value; } static void bsd_write_attr(struct ng_attribute *attr, int value) { struct bsd_handle *h = attr->handle; int arg, get, set; switch (attr->id) { case ATTR_ID_NORM: xioctl(h->fd,BT848SFMT,&norms_map[value]); break; case ATTR_ID_INPUT: xioctl(h->fd,METEORSINPUT,&inputs_map[value]); break; case ATTR_ID_MUTE: h->muted = value; arg = h->muted ? AUDIO_MUTE : AUDIO_UNMUTE; xioctl(h->tfd, BT848_SAUDIO, &arg); break; case ATTR_ID_HUE: case ATTR_ID_BRIGHT: case ATTR_ID_CONTRAST: case ATTR_ID_COLOR: bsd_get_range(attr->id,&get,&set); arg = value; xioctl(h->tfd,set,&arg); break; case ATTR_ID_COUNT+1: /* audio */ xioctl(h->tfd, BT848_SAUDIO,&audio_map[value]); break; default: break; } } static unsigned long bsd_getfreq(void *handle) { struct bsd_handle *h = handle; unsigned long freq = 0; if (-1 == ioctl(h->tfd, TVTUNER_GETFREQ, &freq)) perror("bktr: ioctl TVTUNER_GETFREQ"); if (ng_debug) fprintf(stderr,"bktr: get freq: %.3f\n",(float)freq/16); return freq; } static void bsd_setfreq(void *handle, unsigned long freq) { struct bsd_handle *h = handle; if (ng_debug) fprintf(stderr,"bktr: set freq: %.3f\n",(float)freq/16); if (-1 == ioctl(h->tfd, TVTUNER_SETFREQ, &freq)) perror("bktr: ioctl TVTUNER_SETFREQ"); } static int bsd_tuned(void *handle) { return 0; } /* ---------------------------------------------------------------------- */ /* overlay */ static void set_overlay(struct bsd_handle *h, int state) { if (h->ov_on == state) return; h->ov_on = state; if (state) { /* enable */ xioctl(h->fd, METEORSVIDEO, &h->pos); xioctl(h->fd, METEORSETGEO, &h->ovgeo); xioctl(h->fd, METEORSACTPIXFMT, h->ovfmt); xioctl(h->fd, BT848SCLIP, &h->clip); xioctl(h->fd, METEORCAPTUR, &start); } else { /* disable */ xioctl(h->fd, METEORCAPTUR, &stop); } } static int bsd_setupfb(void *handle, struct ng_video_fmt *fmt, void *base) { struct bsd_handle *h = handle; h->fb.addr = (long)base; h->fb.width = fmt->bytesperline; h->fb.banksize = fmt->bytesperline * fmt->height; h->fb.ramsize = fmt->bytesperline * fmt->height / 1024; return 0; } static int bsd_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y, struct OVERLAY_CLIP *oc, int count, int aspect) { struct bsd_handle *h = handle; int i,win_width,win_height,win_x,win_y; h->ov_enabled = 0; set_overlay(h,h->ov_enabled); if (NULL == fmt) return 0; if (-1 == h->xawtv2pf[fmt->fmtid]) return -1; /* fixups - fixme: no fixed max size */ win_x = x; win_y = y; win_width = fmt->width; win_height = fmt->height; if (win_width > 768) { win_width = 768; win_x += (fmt->width - win_width)/2; } if (win_height > 576) { win_height = 576; win_y += (fmt->height - win_height)/2; } if (aspect) ng_ratio_fixup(&win_width,&win_height,&win_x,&win_y); ng_check_clipping(win_width, win_height, x - win_x, y - win_y, oc, &count); /* fill data */ h->pos = h->fb; h->pos.addr += win_y*h->pos.width; h->pos.addr += win_x*ng_vfmt_to_depth[fmt->fmtid]>>3; h->ovgeo.rows = win_height; h->ovgeo.columns = win_width; h->ovgeo.frames = 1; h->ovgeo.oformat = 0x10000; if (ng_debug) fprintf(stderr,"bktr: overlay win=%dx%d+%d+%d, %d clips\n", win_width,win_height,win_x,win_y,count); /* clipping */ memset(h->clip,0,sizeof(h->clip)); for (i = 0; i < count; i++) { #if 0 /* This way it *should* work IMHO ... */ h->clip[i].x_min = oc[i].x1; h->clip[i].x_max = oc[i].x2; h->clip[i].y_min = oc[i].y1; h->clip[i].y_max = oc[i].y2; #else /* This way it does work. Sort of ... */ h->clip[i].x_min = (oc[i].y1) >> 1; h->clip[i].x_max = (oc[i].y2) >> 1; h->clip[i].y_min = oc[i].x1; h->clip[i].y_max = oc[i].x2; #endif } h->ovfmt = h->pf+h->xawtv2pf[fmt->fmtid]; h->ov_enabled = 1; set_overlay(h,h->ov_enabled); return 0; } /* ---------------------------------------------------------------------- */ /* capture */ static void catchsignal(int signal) { if (signal == SIGUSR1 && ng_debug > 1) fprintf(stderr,"bktr: sigusr1\n"); if (signal == SIGALRM) fprintf(stderr,"bktr: sigalrm\n"); } static void siginit(void) { struct sigaction act,old; memset(&act,0,sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = catchsignal; sigaction(SIGUSR1,&act,&old); sigaction(SIGALRM,&act,&old); } static int bsd_setformat(void *handle, struct ng_video_fmt *fmt) { struct bsd_handle *h = handle; if (-1 == h->xawtv2pf[fmt->fmtid]) return -1; if (fmt->width > 768) fmt->width = 768; if (fmt->height > 576) fmt->height = 576; fmt->bytesperline = fmt->width * ng_vfmt_to_depth[fmt->fmtid] / 8; h->capfmt = h->pf+h->xawtv2pf[fmt->fmtid]; h->capgeo.rows = fmt->height; h->capgeo.columns = fmt->width; h->capgeo.frames = 1; h->capgeo.oformat = 0 /* FIXME */; if (fmt->height <= 320) h->capgeo.oformat |= METEOR_GEO_ODD_ONLY; h->fmt = *fmt; return 0; } static void set_capture(struct bsd_handle *h, int state) { if (state) { /* enable */ xioctl(h->fd, METEORSVIDEO, &h->nofb); xioctl(h->fd, METEORSETGEO, &h->capgeo); xioctl(h->fd, METEORSACTPIXFMT, h->capfmt); xioctl(h->fd, BT848SCLIP, &h->noclip); } else { /* disable */ xioctl(h->fd, METEORCAPTUR, &stop); } } static int bsd_startvideo(void *handle, int fps, unsigned int buffers) { struct bsd_handle *h = handle; set_overlay(h,0); h->fps = fps; h->start = ng_get_timestamp(); set_capture(h,1); xioctl(h->fd, METEORSSIGNAL, &signal_on); xioctl(h->fd, METEORCAPTUR, &start); return 0; } static void bsd_stopvideo(void *handle) { struct bsd_handle *h = handle; h->fps = 0; set_capture(h,0); xioctl(h->fd, METEORCAPTUR, &stop); xioctl(h->fd, METEORSSIGNAL, &signal_off); set_overlay(h,h->ov_enabled); } static struct ng_video_buf* bsd_nextframe(void *handle) { struct bsd_handle *h = handle; struct ng_video_buf *buf; int size; sigset_t sa_mask; size = h->fmt.bytesperline * h->fmt.height; buf = ng_malloc_video_buf(&h->fmt,size); alarm(1); sigfillset(&sa_mask); sigdelset(&sa_mask,SIGUSR1); sigdelset(&sa_mask,SIGALRM); sigsuspend(&sa_mask); alarm(0); memcpy(buf->data,h->map,size); buf->info.ts = ng_get_timestamp() - h->start; return buf; } static struct ng_video_buf* bsd_getimage(void *handle) { struct bsd_handle *h = handle; struct ng_video_buf *buf; int size; set_overlay(h,0); set_capture(h,1); size = h->fmt.bytesperline * h->fmt.height; buf = ng_malloc_video_buf(&h->fmt,size); xioctl(h->fd, METEORCAPTUR, &single); memcpy(buf->data,h->map,size); set_capture(h,0); set_overlay(h,h->ov_enabled); return buf; } /* ---------------------------------------------------------------------- */ extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_vid_driver_register(NG_PLUGIN_MAGIC,__FILE__,&bsd_driver); } xawtv-3.106/libng/plugins/drv0-v4l2.tmpl.c000066400000000000000000001073121343350355000202340ustar00rootroot00000000000000/* * interface to the v4l2 driver * * (c) 1998-2002 Gerd Knorr * * Patch to use libv4l by Hans de Goede */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* XXX glibc */ #include "videodev2.h" #include "grab-ng.h" #include "struct-dump.h" #include "struct-v4l2.h" #ifdef USE_LIBV4L #include #define PLUGIN_NAME "libv4l" #else #define PLUGIN_NAME "v4l2" #endif /* USE_LIBV4L */ #ifdef HAVE_EXPLAIN #include #endif /* ---------------------------------------------------------------------- */ /* open+close */ static void* v4l2_open_handle(char *device, int req_flags); static int v4l2_close_handle(void *handle); /* attributes */ static char* v4l2_devname(void *handle); static int v4l2_flags(void *handle); static struct ng_attribute* v4l2_attrs(void *handle); static int v4l2_read_attr(struct ng_attribute*); static void v4l2_write_attr(struct ng_attribute*, int val); static void v4l2_get_min_size(void *hdl, int *min_width, int *min_height); /* overlay */ static int v4l2_setupfb(void *handle, struct ng_video_fmt *fmt, void *base); static int v4l2_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y, struct OVERLAY_CLIP *oc, int count, int aspect); /* capture video */ static int v4l2_setformat(void *handle, struct ng_video_fmt *fmt); static int v4l2_startvideo(void *handle, int fps, unsigned int buffers); static void v4l2_stopvideo(void *handle); static struct ng_video_buf* v4l2_nextframe(void *handle); static struct ng_video_buf* v4l2_getimage(void *handle); /* tuner */ static unsigned long v4l2_getfreq(void *handle); static void v4l2_setfreq(void *handle, unsigned long freq); static int v4l2_tuned(void *handle); /* ---------------------------------------------------------------------- */ #define WANTED_BUFFERS 32 #undef MAX_INPUT /* To avoid conficts with limits.h */ #define MAX_INPUT 16 #define MAX_NORM 64 #define MAX_FORMAT 32 #define MAX_CTRL 32 struct v4l2_handle { int fd; /* device descriptions */ char *device; int ninputs, nstds, nfmts, read_done; unsigned int min_width, min_height; struct v4l2_capability cap; struct v4l2_input inp[MAX_INPUT]; struct v4l2_standard std[MAX_NORM]; struct v4l2_fmtdesc fmt[MAX_FORMAT]; struct v4l2_queryctrl ctl[MAX_CTRL*2]; /* attributes */ int nattr; struct ng_attribute *attr; /* capture */ int fps,first; long long start; struct v4l2_format fmt_v4l2; struct ng_video_fmt fmt_me; struct v4l2_requestbuffers reqbufs; struct v4l2_buffer buf_v4l2[WANTED_BUFFERS]; int buf_v4l2_size[WANTED_BUFFERS]; struct ng_video_buf buf_me[WANTED_BUFFERS]; unsigned int queue,waiton; /* overlay */ struct v4l2_framebuffer ov_fb; struct v4l2_format ov_win; struct v4l2_clip ov_clips[256]; #if 0 enum v4l2_field ov_fields; #endif int ov_error; int ov_enabled; int ov_on; }; /* ---------------------------------------------------------------------- */ struct ng_vid_driver v4l2_driver = { .name = PLUGIN_NAME, .open = v4l2_open_handle, .close = v4l2_close_handle, .get_devname = v4l2_devname, .capabilities = v4l2_flags, .list_attrs = v4l2_attrs, .get_min_size = v4l2_get_min_size, .setupfb = v4l2_setupfb, .overlay = v4l2_overlay, .setformat = v4l2_setformat, .startvideo = v4l2_startvideo, .stopvideo = v4l2_stopvideo, .nextframe = v4l2_nextframe, .getimage = v4l2_getimage, .getfreq = v4l2_getfreq, .setfreq = v4l2_setfreq, .is_tuned = v4l2_tuned, }; static __u32 xawtv_pixelformat[VIDEO_FMT_COUNT] = { [ VIDEO_RGB08 ] = V4L2_PIX_FMT_HI240, [ VIDEO_GRAY ] = V4L2_PIX_FMT_GREY, [ VIDEO_RGB15_LE ] = V4L2_PIX_FMT_RGB555, [ VIDEO_RGB16_LE ] = V4L2_PIX_FMT_RGB565, [ VIDEO_RGB15_BE ] = V4L2_PIX_FMT_RGB555X, [ VIDEO_RGB16_BE ] = V4L2_PIX_FMT_RGB565X, [ VIDEO_BGR24 ] = V4L2_PIX_FMT_BGR24, [ VIDEO_BGR32 ] = V4L2_PIX_FMT_BGR32, [ VIDEO_RGB24 ] = V4L2_PIX_FMT_RGB24, [ VIDEO_YUYV ] = V4L2_PIX_FMT_YUYV, [ VIDEO_UYVY ] = V4L2_PIX_FMT_UYVY, [ VIDEO_YUV422P ] = V4L2_PIX_FMT_YUV422P, [ VIDEO_YUV420P ] = V4L2_PIX_FMT_YUV420, }; static struct STRTAB stereo[] = { { V4L2_TUNER_MODE_MONO, "mono" }, { V4L2_TUNER_MODE_STEREO, "stereo" }, { V4L2_TUNER_MODE_LANG1, "lang1" }, { V4L2_TUNER_MODE_LANG2, "lang2" }, { -1, NULL }, }; /* ---------------------------------------------------------------------- */ /* debug output */ #define PREFIX "ioctl: " static int xioctl(int fd, int cmd, void *arg, int mayfail) { int rc; #ifndef USE_LIBV4L rc = ioctl(fd,cmd,arg); #else /* USE_LIBV4L */ rc = v4l2_ioctl(fd,cmd,arg); #endif /* USE_LIBV4L */ if (rc >= 0 && ng_debug < 2) return rc; if (mayfail && ((errno == EINVAL) || (errno == ENOTTY)) && ng_debug < 2) return rc; #ifdef HAVE_EXPLAIN fprintf(stderr,"v4l2: %s\n",(rc >= 0) ? "ok" : explain_ioctl(fd,cmd,arg)); #else print_ioctl(stderr,ioctls_v4l2,PREFIX,cmd,arg); fprintf(stderr,": %s\n",(rc >= 0) ? "ok" : strerror(errno)); #endif return rc; } static void print_bufinfo(struct v4l2_buffer *buf) { static char *type[] = { [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", }; fprintf(stderr,"v4l2: buf %d: %s 0x%x+%d, used %d\n", buf->index, buf->type < sizeof(type)/sizeof(char*) ? type[buf->type] : "unknown", buf->m.offset,buf->length,buf->bytesused); } /* ---------------------------------------------------------------------- */ /* helpers */ static void get_device_capabilities(struct v4l2_handle *h) { int i; for (h->ninputs = 0; h->ninputs < MAX_INPUT; h->ninputs++) { h->inp[h->ninputs].index = h->ninputs; if (-1 == xioctl(h->fd, VIDIOC_ENUMINPUT, &h->inp[h->ninputs], 1)) break; } for (h->nstds = 0; h->nstds < MAX_NORM; h->nstds++) { h->std[h->nstds].index = h->nstds; if (-1 == xioctl(h->fd, VIDIOC_ENUMSTD, &h->std[h->nstds], 1)) break; } for (h->nfmts = 0; h->nfmts < MAX_FORMAT; h->nfmts++) { h->fmt[h->nfmts].index = h->nfmts; h->fmt[h->nfmts].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl(h->fd, VIDIOC_ENUM_FMT, &h->fmt[h->nfmts], 1)) break; } /* controls */ for (i = 0; i < MAX_CTRL; i++) { h->ctl[i].id = V4L2_CID_BASE+i; if (-1 == xioctl(h->fd, VIDIOC_QUERYCTRL, &h->ctl[i], 1) || (h->ctl[i].flags & V4L2_CTRL_FLAG_DISABLED)) h->ctl[i].id = -1; } for (i = 0; i < MAX_CTRL; i++) { h->ctl[i+MAX_CTRL].id = V4L2_CID_PRIVATE_BASE+i; if (-1 == xioctl(h->fd, VIDIOC_QUERYCTRL, &h->ctl[i+MAX_CTRL], 1) || (h->ctl[i+MAX_CTRL].flags & V4L2_CTRL_FLAG_DISABLED)) h->ctl[i+MAX_CTRL].id = -1; } } static void find_min_size(struct v4l2_handle *h) { int i; struct v4l2_fmtdesc fmtdesc = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; if (xioctl(h->fd, VIDIOC_G_FMT, &fmt, 0)) { h->min_width = 32; h->min_height = 24; return; } h->min_width = -1; h->min_height = -1; for (i = 0; ; i++) { fmtdesc.index = i; if (xioctl(h->fd, VIDIOC_ENUM_FMT, &fmtdesc, 1)) break; fmt.fmt.pix.pixelformat = fmtdesc.pixelformat; fmt.fmt.pix.width = 32; fmt.fmt.pix.height = 24; if (xioctl(h->fd, VIDIOC_TRY_FMT, &fmt, 0) == 0) { if (fmt.fmt.pix.width < h->min_width) h->min_width = fmt.fmt.pix.width; if (fmt.fmt.pix.height < h->min_height) h->min_height = fmt.fmt.pix.height; } } } static struct STRTAB * build_norms(struct v4l2_handle *h) { struct STRTAB *norms; int i; norms = malloc(sizeof(struct STRTAB) * (h->nstds+1)); for (i = 0; i < h->nstds; i++) { norms[i].nr = i; norms[i].str = h->std[i].name; } norms[i].nr = -1; norms[i].str = NULL; return norms; } static struct STRTAB * build_inputs(struct v4l2_handle *h) { struct STRTAB *inputs; int i; inputs = malloc(sizeof(struct STRTAB) * (h->ninputs+1)); for (i = 0; i < h->ninputs; i++) { inputs[i].nr = i; inputs[i].str = h->inp[i].name; } inputs[i].nr = -1; inputs[i].str = NULL; return inputs; } /* ---------------------------------------------------------------------- */ static struct V4L2_ATTR { unsigned int id; unsigned int v4l2; } v4l2_attr[] = { { ATTR_ID_VOLUME, V4L2_CID_AUDIO_VOLUME }, { ATTR_ID_MUTE, V4L2_CID_AUDIO_MUTE }, { ATTR_ID_COLOR, V4L2_CID_SATURATION }, { ATTR_ID_BRIGHT, V4L2_CID_BRIGHTNESS }, { ATTR_ID_HUE, V4L2_CID_HUE }, { ATTR_ID_CONTRAST, V4L2_CID_CONTRAST }, }; #define NUM_ATTR (sizeof(v4l2_attr)/sizeof(struct V4L2_ATTR)) static struct STRTAB* v4l2_menu(int fd, const struct v4l2_queryctrl *ctl) { struct STRTAB *menu; struct v4l2_querymenu item; int i; if (ng_debug >= 2) fprintf(stderr, "v4l2: menu with %i items\n", ctl->maximum - ctl->minimum); if (ctl->maximum - ctl->minimum == 0) return NULL; menu = malloc(sizeof(struct STRTAB) * (ctl->maximum-ctl->minimum+2)); for (i = ctl->minimum; i <= ctl->maximum; i++) { item.id = ctl->id; item.index = i; if (-1 == xioctl(fd, VIDIOC_QUERYMENU, &item, 0)) { free(menu); return NULL; } menu[i-ctl->minimum].nr = i; menu[i-ctl->minimum].str = strdup(item.name); if (ng_debug >= 2) fprintf(stderr, "v4l2: menu item %li = %s\n", menu[i-ctl->minimum].nr, menu[i-ctl->minimum].str); } menu[i-ctl->minimum].nr = -1; menu[i-ctl->minimum].str = NULL; return menu; } static void v4l2_add_attr(struct v4l2_handle *h, struct v4l2_queryctrl *ctl, int id, struct STRTAB *choices) { static int private_ids = ATTR_ID_COUNT; unsigned int i; h->attr = realloc(h->attr,(h->nattr+2) * sizeof(struct ng_attribute)); memset(h->attr+h->nattr,0,sizeof(struct ng_attribute)*2); if (ctl) { if (ng_debug >= 2) fprintf(stderr, "v4l2: adding V4L2 control id 0x%08x, type %i\n", ctl->id, ctl->type); for (i = 0; i < NUM_ATTR; i++) if (v4l2_attr[i].v4l2 == ctl->id) break; if (i != NUM_ATTR) { h->attr[h->nattr].id = v4l2_attr[i].id; } else { h->attr[h->nattr].id = private_ids++; } h->attr[h->nattr].name = ctl->name; h->attr[h->nattr].priv = ctl; h->attr[h->nattr].defval = ctl->default_value; switch (ctl->type) { case V4L2_CTRL_TYPE_INTEGER: h->attr[h->nattr].type = ATTR_TYPE_INTEGER; h->attr[h->nattr].defval = ctl->default_value; h->attr[h->nattr].min = ctl->minimum; h->attr[h->nattr].max = ctl->maximum; break; case V4L2_CTRL_TYPE_BOOLEAN: h->attr[h->nattr].type = ATTR_TYPE_BOOL; break; case V4L2_CTRL_TYPE_MENU: choices = v4l2_menu(h->fd, ctl); if (NULL == choices) { memset(h->attr+h->nattr,0,sizeof(struct ng_attribute)*2); return; } h->attr[h->nattr].choices = choices; h->attr[h->nattr].type = ATTR_TYPE_CHOICE; break; case V4L2_CTRL_TYPE_STRING: case V4L2_CTRL_TYPE_BUTTON: case V4L2_CTRL_TYPE_INTEGER64: case V4L2_CTRL_TYPE_CTRL_CLASS: default: /* Currently unimplemented */ memset(h->attr+h->nattr,0,sizeof(struct ng_attribute)*2); return; } } else { /* for norms + inputs */ h->attr[h->nattr].id = id; if (-1 == h->attr[h->nattr].id) h->attr[h->nattr].id = private_ids++; h->attr[h->nattr].defval = 0; h->attr[h->nattr].type = ATTR_TYPE_CHOICE; h->attr[h->nattr].choices = choices; } if (h->attr[h->nattr].id < ATTR_ID_COUNT) h->attr[h->nattr].name = ng_attr_to_desc[h->attr[h->nattr].id]; h->attr[h->nattr].read = v4l2_read_attr; h->attr[h->nattr].write = v4l2_write_attr; h->attr[h->nattr].handle = h; h->nattr++; } static int v4l2_read_attr(struct ng_attribute *attr) { struct v4l2_handle *h = attr->handle; const struct v4l2_queryctrl *ctl = attr->priv; struct v4l2_control c; struct v4l2_tuner tuner; v4l2_std_id std = 0; int value = 0; int i; if (NULL != ctl) { c.id = ctl->id; xioctl(h->fd,VIDIOC_G_CTRL,&c,0); value = c.value; } else if (attr->id == ATTR_ID_NORM) { value = -1; xioctl(h->fd,VIDIOC_G_STD,&std, (h->cap.capabilities & V4L2_CAP_TUNER)?0:1); for (i = 0; i < h->nstds; i++) if (std & h->std[i].id) value = i; } else if (attr->id == ATTR_ID_INPUT) { xioctl(h->fd,VIDIOC_G_INPUT,&value,0); } else if (attr->id == ATTR_ID_AUDIO_MODE) { memset(&tuner,0,sizeof(tuner)); if (h->cap.capabilities & V4L2_CAP_TUNER) xioctl(h->fd,VIDIOC_G_TUNER,&tuner,0); value = tuner.audmode; #if 1 if (ng_debug) { fprintf(stderr,"v4l2: tuner cap:%s%s%s\n", (tuner.capability&V4L2_TUNER_CAP_STEREO) ? " STEREO" : "", (tuner.capability&V4L2_TUNER_CAP_LANG1) ? " LANG1" : "", (tuner.capability&V4L2_TUNER_CAP_LANG2) ? " LANG2" : ""); fprintf(stderr,"v4l2: tuner rxs:%s%s%s%s\n", (tuner.rxsubchans&V4L2_TUNER_SUB_MONO) ? " MONO" : "", (tuner.rxsubchans&V4L2_TUNER_SUB_STEREO) ? " STEREO" : "", (tuner.rxsubchans&V4L2_TUNER_SUB_LANG1) ? " LANG1" : "", (tuner.rxsubchans&V4L2_TUNER_SUB_LANG2) ? " LANG2" : ""); fprintf(stderr,"v4l2: tuner cur:%s%s%s%s\n", (tuner.audmode==V4L2_TUNER_MODE_MONO) ? " MONO" : "", (tuner.audmode==V4L2_TUNER_MODE_STEREO) ? " STEREO" : "", (tuner.audmode==V4L2_TUNER_MODE_LANG1) ? " LANG1" : "", (tuner.audmode==V4L2_TUNER_MODE_LANG2) ? " LANG2" : ""); } #endif } return value; } static void v4l2_write_attr(struct ng_attribute *attr, int value) { struct v4l2_handle *h = attr->handle; const struct v4l2_queryctrl *ctl = attr->priv; struct v4l2_control c; struct v4l2_tuner tuner; if (NULL != ctl) { c.id = ctl->id; c.value = value; xioctl(h->fd,VIDIOC_S_CTRL,&c,0); } else if (attr->id == ATTR_ID_NORM) { xioctl(h->fd,VIDIOC_S_STD,&h->std[value].id,0); } else if (attr->id == ATTR_ID_INPUT) { xioctl(h->fd,VIDIOC_S_INPUT,&value,0); } else if ((attr->id == ATTR_ID_AUDIO_MODE) && (h->cap.capabilities & V4L2_CAP_TUNER)) { memset(&tuner,0,sizeof(tuner)); xioctl(h->fd,VIDIOC_G_TUNER,&tuner,0); tuner.audmode = value; xioctl(h->fd,VIDIOC_S_TUNER,&tuner,0); } } /* ---------------------------------------------------------------------- */ static void* v4l2_open_handle(char *device, int req_flags) { struct v4l2_handle *h; int i, caps; #ifdef USE_LIBV4L int libv4l2_fd; #endif /* USE_LIBV4L */ if (ng_debug) fprintf(stderr, "Using %s plugin\n", PLUGIN_NAME); h = malloc(sizeof(*h)); if (NULL == h) return NULL; memset(h,0,sizeof(*h)); h->device = strdup(device); if (!h->device) { free(h); return NULL; } if (-1 == (h->fd = open(device, O_RDWR))) { #ifdef HAVE_EXPLAIN fprintf(stderr,"v4l2: open: %s\n",explain_open(device, O_RDWR, 0)); #else fprintf(stderr,"v4l2: open %s: %s\n",device,strerror(errno)); #endif goto err; } #ifdef USE_LIBV4L /* Note the v4l2_xxx functions are designed so that if they get passed an unknown fd, the will behave exactly as their regular xxx counterparts, so if v4l2_fd_open fails, we continue as normal (missing the libv4l2 custom cam format to normal formats conversion). Chances are big we will still fail then though, as normally v4l2_fd_open only fails if the device is not a v4l2 device. */ libv4l2_fd = v4l2_fd_open(h->fd, 0); if (libv4l2_fd != -1) h->fd = libv4l2_fd; #endif /* USE_LIBV4L */ if (-1 == xioctl(h->fd,VIDIOC_QUERYCAP,&h->cap,1)) goto err; caps = v4l2_flags(h); if (ng_debug) fprintf(stderr, "v4l2: device caps: %d, required %d\n", caps, req_flags); if (req_flags && ((caps & req_flags) != req_flags)) { if (ng_debug) fprintf(stderr, "v4l2: device doesn't support %d capabilities\n", req_flags); goto err; } if (ng_debug) fprintf(stderr, "v4l2: open\n"); fcntl(h->fd,F_SETFD,FD_CLOEXEC); if (ng_debug) fprintf(stderr,"v4l2: device info:\n" " %s %d.%d.%d / %s @ %s\n", h->cap.driver, (h->cap.version >> 16) & 0xff, (h->cap.version >> 8) & 0xff, h->cap.version & 0xff, h->cap.card,h->cap.bus_info); get_device_capabilities(h); find_min_size(h); if (ng_debug) fprintf(stderr,"v4l2: device min size %ux%u\n", h->min_width, h->min_height); /* attributes */ v4l2_add_attr(h, NULL, ATTR_ID_NORM, build_norms(h)); v4l2_add_attr(h, NULL, ATTR_ID_INPUT, build_inputs(h)); if (h->cap.capabilities & V4L2_CAP_TUNER) v4l2_add_attr(h, NULL, ATTR_ID_AUDIO_MODE, stereo); for (i = 0; i < MAX_CTRL*2; i++) { if (h->ctl[i].id == UNSET) continue; v4l2_add_attr(h, &h->ctl[i], 0, NULL); } /* capture buffers */ for (i = 0; i < WANTED_BUFFERS; i++) { ng_init_video_buf(h->buf_me+i); h->buf_me[i].release = ng_wakeup_video_buf; } return h; err: if (h->fd != -1) #ifndef USE_LIBV4L close(h->fd); #else /* USE_LIBV4L */ v4l2_close(h->fd); #endif /* USE_LIBV4L */ if (h) free(h); return NULL; } static int v4l2_close_handle(void *handle) { struct v4l2_handle *h = handle; if (ng_debug) fprintf(stderr, "v4l2: close\n"); #ifndef USE_LIBV4L close(h->fd); #else /* USE_LIBV4L */ v4l2_close(h->fd); #endif /* USE_LIBV4L */ if (NULL != h->attr) { int i; for (i = 0; i < h->nattr; ++i) { if ((NULL != h->attr[i].choices) && (stereo != h->attr[i].choices)) { free(h->attr[i].choices); h->attr[i].choices = NULL; } } free(h->attr); h->attr = NULL; } free(h->device); free(h); h = NULL; return 0; } static char* v4l2_devname(void *handle) { struct v4l2_handle *h = handle; return h->cap.card; } static int v4l2_flags(void *handle) { struct v4l2_handle *h = handle; int ret = 0; if (h->cap.capabilities & V4L2_CAP_VIDEO_OVERLAY && !h->ov_error) ret |= CAN_OVERLAY; if (h->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ret |= CAN_CAPTURE; if (h->cap.capabilities & V4L2_CAP_TUNER) ret |= CAN_TUNE; return ret; } static struct ng_attribute* v4l2_attrs(void *handle) { struct v4l2_handle *h = handle; return h->attr; } static void v4l2_get_min_size(void *handle, int *min_width, int *min_height) { struct v4l2_handle *h = handle; *min_width = h->min_width; *min_height = h->min_height; } /* ---------------------------------------------------------------------- */ static unsigned long v4l2_getfreq(void *handle) { struct v4l2_handle *h = handle; struct v4l2_frequency f; if (!(h->cap.capabilities & V4L2_CAP_TUNER)) return 0; memset(&f,0,sizeof(f)); xioctl(h->fd, VIDIOC_G_FREQUENCY, &f, 0); return f.frequency; } static void v4l2_setfreq(void *handle, unsigned long freq) { struct v4l2_handle *h = handle; struct v4l2_frequency f; if (!(h->cap.capabilities & V4L2_CAP_TUNER)) return; if (ng_debug) fprintf(stderr,"v4l2: freq: %.3f\n",(float)freq/16); memset(&f,0,sizeof(f)); f.type = V4L2_TUNER_ANALOG_TV; f.frequency = freq; xioctl(h->fd, VIDIOC_S_FREQUENCY, &f, 0); } static int v4l2_tuned(void *handle) { struct v4l2_handle *h = handle; struct v4l2_tuner tuner; if (!(h->cap.capabilities & V4L2_CAP_TUNER)) return 0; usleep(10000); memset(&tuner,0,sizeof(tuner)); if (-1 == xioctl(h->fd,VIDIOC_G_TUNER,&tuner,0)) return 0; return tuner.signal ? 1 : 0; } /* ---------------------------------------------------------------------- */ /* overlay */ static int v4l2_setupfb(void *handle, struct ng_video_fmt *fmt, void *base) { struct v4l2_handle *h = handle; if (-1 == xioctl(h->fd, VIDIOC_G_FBUF, &h->ov_fb, 0)) return -1; /* double-check settings */ if ((NULL != base && h->ov_fb.base != base) || h->ov_fb.base == NULL) { fprintf(stderr,"v4l2: WARNING: framebuffer base address mismatch\n"); fprintf(stderr,"v4l2: me=%p v4l=%p\n",base,h->ov_fb.base); h->ov_error = 1; return -1; } if (h->ov_fb.fmt.width != fmt->width || h->ov_fb.fmt.height != fmt->height) { fprintf(stderr,"v4l2: WARNING: framebuffer size mismatch\n"); fprintf(stderr,"v4l2: me=%dx%d v4l=%dx%d\n", fmt->width,fmt->height,h->ov_fb.fmt.width,h->ov_fb.fmt.height); h->ov_error = 1; return -1; } if (fmt->bytesperline > 0 && fmt->bytesperline != h->ov_fb.fmt.bytesperline) { fprintf(stderr,"v4l2: WARNING: framebuffer bpl mismatch\n"); fprintf(stderr,"v4l2: me=%d v4l=%d\n", fmt->bytesperline,h->ov_fb.fmt.bytesperline); h->ov_error = 1; return -1; } #if 0 if (h->ov_fb.fmt.pixelformat != xawtv_pixelformat[fmt->fmtid]) { fprintf(stderr,"v4l2: WARNING: framebuffer format mismatch\n"); fprintf(stderr,"v4l2: me=%c%c%c%c [%s] v4l=%c%c%c%c\n", xawtv_pixelformat[fmt->fmtid] & 0xff, (xawtv_pixelformat[fmt->fmtid] >> 8) & 0xff, (xawtv_pixelformat[fmt->fmtid] >> 16) & 0xff, (xawtv_pixelformat[fmt->fmtid] >> 24) & 0xff, ng_vfmt_to_desc[fmt->fmtid], h->ov_fb.fmt.pixelformat & 0xff, (h->ov_fb.fmt.pixelformat >> 8) & 0xff, (h->ov_fb.fmt.pixelformat >> 16) & 0xff, (h->ov_fb.fmt.pixelformat >> 24) & 0xff); h->ov_error = 1; return -1; } #endif return 0; } static int v4l2_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y, struct OVERLAY_CLIP *oc, int count, int aspect) { struct v4l2_handle *h = handle; struct v4l2_format win; int rc,i; if (h->ov_error) return -1; if (NULL == fmt) { if (ng_debug) fprintf(stderr,"v4l2: overlay off\n"); if (h->ov_enabled) { h->ov_enabled = 0; h->ov_on = 0; xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0); } return 0; } if (ng_debug) fprintf(stderr,"v4l2: overlay win=%dx%d+%d+%d, %d clips\n", fmt->width,fmt->height,x,y,count); memset(&win,0,sizeof(win)); win.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; win.fmt.win.w.left = x; win.fmt.win.w.top = y; win.fmt.win.w.width = fmt->width; win.fmt.win.w.height = fmt->height; /* check against max. size */ xioctl(h->fd,VIDIOC_TRY_FMT,&win,0); if (win.fmt.win.w.width != (int)fmt->width) win.fmt.win.w.left = x + (fmt->width - win.fmt.win.w.width)/2; if (win.fmt.win.w.height != (int)fmt->height) win.fmt.win.w.top = y + (fmt->height - win.fmt.win.w.height)/2; if (aspect) ng_ratio_fixup(&win.fmt.win.w.width,&win.fmt.win.w.height, &win.fmt.win.w.left,&win.fmt.win.w.top); /* fixups */ ng_check_clipping(win.fmt.win.w.width, win.fmt.win.w.height, x - win.fmt.win.w.left, y - win.fmt.win.w.top, oc, &count); h->ov_win = win; if (h->ov_fb.capability & V4L2_FBUF_CAP_LIST_CLIPPING) { h->ov_win.fmt.win.clips = h->ov_clips; h->ov_win.fmt.win.clipcount = count; for (i = 0; i < count; i++) { h->ov_clips[i].next = (i+1 == count) ? NULL : &h->ov_clips[i+1]; h->ov_clips[i].c.left = oc[i].x1; h->ov_clips[i].c.top = oc[i].y1; h->ov_clips[i].c.width = oc[i].x2-oc[i].x1; h->ov_clips[i].c.height = oc[i].y2-oc[i].y1; } } #if 0 if (h->ov_fb.flags & V4L2_FBUF_FLAG_CHROMAKEY) { h->ov_win.chromakey = 0; /* FIXME */ } #endif rc = xioctl(h->fd, VIDIOC_S_FMT, &h->ov_win, 0); h->ov_enabled = (0 == rc) ? 1 : 0; h->ov_on = (0 == rc) ? 1 : 0; xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0); return 0; } /* ---------------------------------------------------------------------- */ /* capture helpers */ static int v4l2_queue_buffer(struct v4l2_handle *h) { int frame = h->queue % h->reqbufs.count; int rc; if (0 != h->buf_me[frame].refcount) { if (0 != h->queue - h->waiton) return -1; fprintf(stderr,"v4l2: waiting for a free buffer\n"); ng_waiton_video_buf(h->buf_me+frame); } rc = xioctl(h->fd,VIDIOC_QBUF,&h->buf_v4l2[frame], 0); if (0 == rc) h->queue++; return rc; } static void v4l2_queue_all(struct v4l2_handle *h) { for (;;) { if (h->queue - h->waiton >= h->reqbufs.count) return; if (0 != v4l2_queue_buffer(h)) return; } } static int v4l2_waiton(struct v4l2_handle *h) { struct v4l2_buffer buf; struct timeval tv; fd_set rdset; /* wait for the next frame */ again: tv.tv_sec = 5; tv.tv_usec = 0; FD_ZERO(&rdset); FD_SET(h->fd, &rdset); switch (select(h->fd + 1, &rdset, NULL, NULL, &tv)) { case -1: if (EINTR == errno) goto again; perror("v4l2: select"); return -1; case 0: fprintf(stderr,"v4l2: oops: select timeout\n"); return -1; } /* get it */ memset(&buf,0,sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl(h->fd,VIDIOC_DQBUF,&buf, 0)) return -1; h->waiton++; h->buf_v4l2[buf.index] = buf; #if 0 if (1) { /* for driver debugging */ static const char *fn[] = { "any", "none", "top", "bottom", "interlaced", "tb", "bt", "alternate", }; static struct timeval last; signed long diff; diff = (buf.timestamp.tv_sec - last.tv_sec) * 1000000; diff += buf.timestamp.tv_usec - last.tv_usec; fprintf(stderr,"\tdiff %6.1f ms buf %d field %d [%s]\n", diff/1000.0, buf.index, buf.field, fn[buf.field%8]); last = buf.timestamp; } #endif return buf.index; } static int v4l2_start_streaming(struct v4l2_handle *h, int buffers) { int disable_overlay = 0; unsigned int i; /* setup buffers */ h->reqbufs.count = buffers; h->reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; h->reqbufs.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl(h->fd, VIDIOC_REQBUFS, &h->reqbufs, 0)) return -1; for (i = 0; i < h->reqbufs.count; i++) { h->buf_v4l2[i].index = i; h->buf_v4l2[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; h->buf_v4l2[i].memory = V4L2_MEMORY_MMAP; if (-1 == xioctl(h->fd, VIDIOC_QUERYBUF, &h->buf_v4l2[i], 0)) return -1; h->buf_v4l2_size[i] = h->buf_v4l2[i].length; h->buf_me[i].fmt = h->fmt_me; h->buf_me[i].size = h->buf_me[i].fmt.bytesperline * h->buf_me[i].fmt.height; #ifndef USE_LIBV4L h->buf_me[i].data = mmap(NULL, h->buf_v4l2[i].length, #else /* USE_LIBV4L */ h->buf_me[i].data = v4l2_mmap(NULL, h->buf_v4l2[i].length, #endif /* USE_LIBV4L */ PROT_READ | PROT_WRITE, MAP_SHARED, h->fd, h->buf_v4l2[i].m.offset); if (MAP_FAILED == h->buf_me[i].data) { perror("mmap"); return -1; } if (ng_debug) print_bufinfo(&h->buf_v4l2[i]); } /* queue up all buffers */ v4l2_queue_all(h); try_again: /* turn off preview (if needed) */ if (disable_overlay) { h->ov_on = 0; xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0); if (ng_debug) fprintf(stderr,"v4l2: overlay off (start_streaming)\n"); } /* start capture */ if (-1 == xioctl(h->fd,VIDIOC_STREAMON,&h->fmt_v4l2.type, h->ov_on ? EBUSY : 0)) { if (h->ov_on && errno == EBUSY) { disable_overlay = 1; goto try_again; } return -1; } return 0; } static void v4l2_stop_streaming(struct v4l2_handle *h) { unsigned int i; /* stop capture */ #ifndef USE_LIBV4L if (-1 == ioctl(h->fd,VIDIOC_STREAMOFF,&h->fmt_v4l2.type)) #else /* USE_LIBV4L */ if (-1 == v4l2_ioctl(h->fd,VIDIOC_STREAMOFF,&h->fmt_v4l2.type)) #endif /* USE_LIBV4L */ perror("ioctl VIDIOC_STREAMOFF"); /* free buffers */ for (i = 0; i < h->reqbufs.count; i++) { if (0 != h->buf_me[i].refcount) ng_waiton_video_buf(&h->buf_me[i]); if (ng_debug) print_bufinfo(&h->buf_v4l2[i]); #ifndef USE_LIBV4L if (-1 == munmap(h->buf_me[i].data, h->buf_v4l2_size[i])) #else /* USE_LIBV4L */ if (-1 == v4l2_munmap(h->buf_me[i].data, h->buf_v4l2_size[i])) #endif /* USE_LIBV4L */ perror("munmap"); } h->queue = 0; h->waiton = 0; /* unrequest buffers (only needed for some drivers) */ h->reqbufs.count = 0; xioctl(h->fd, VIDIOC_REQBUFS, &h->reqbufs, 1); /* turn on preview (if needed) */ if (h->ov_on != h->ov_enabled) { h->ov_on = h->ov_enabled; xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0); if (ng_debug) fprintf(stderr,"v4l2: overlay on (stop_streaming)\n"); } } /* ---------------------------------------------------------------------- */ /* capture interface */ /* set capture parameters */ static int v4l2_setformat(void *handle, struct ng_video_fmt *fmt) { struct v4l2_handle *h = handle; int rc, fd; retry: h->fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; h->fmt_v4l2.fmt.pix.pixelformat = xawtv_pixelformat[fmt->fmtid]; h->fmt_v4l2.fmt.pix.width = fmt->width; h->fmt_v4l2.fmt.pix.height = fmt->height; h->fmt_v4l2.fmt.pix.field = V4L2_FIELD_ANY; //h->fmt_v4l2.fmt.pix.field = V4L2_FIELD_ALTERNATE; if (fmt->bytesperline != fmt->width * ng_vfmt_to_depth[fmt->fmtid]/8) h->fmt_v4l2.fmt.pix.bytesperline = fmt->bytesperline; else h->fmt_v4l2.fmt.pix.bytesperline = 0; #ifdef USE_LIBV4L rc = v4l2_ioctl(h->fd, VIDIOC_S_FMT, &h->fmt_v4l2); #else rc = ioctl(h->fd, VIDIOC_S_FMT, &h->fmt_v4l2); #endif /* Some devices do not like mixing read and mmap, they give EBUSY here after the first read */ if (rc < 0 && errno == EBUSY && h->read_done) { fprintf(stderr, "v4l2: %s does not support switching between " "read and mmap, reopening\n", h->device); /* HACK only way to recover is to close and re-open the fd */ fd = open(h->device, O_RDWR); if (fd == -1) { fprintf(stderr, "v4l2: open %s: %s\n", h->device, strerror(errno)); return -1; } #ifdef USE_LIBV4L rc = v4l2_fd_open(fd, 0); if (rc != -1) fd = rc; v4l2_close(h->fd); #else close(h->fd); #endif h->fd = fd; h->cap.capabilities &= ~V4L2_CAP_READWRITE; h->read_done = 0; goto retry; } if (rc < 0) { print_ioctl(stderr, ioctls_v4l2, PREFIX, VIDIOC_S_FMT, &h->fmt_v4l2); fprintf(stderr,": %s\n", strerror(errno)); return -1; } if (h->fmt_v4l2.fmt.pix.pixelformat != xawtv_pixelformat[fmt->fmtid]) return -1; /* * The bttv driver has a bug where it will return a width which is not * a multiple of 16 for planar formats, while it cannot handle this, * fix this up. * * A kernel fix has been send upstream for this for 4.5 / 4.6, so * eventually this workaround should be removed. */ if (!strcmp(h->cap.driver, "bttv") && (fmt->fmtid == VIDEO_YUV422P || fmt->fmtid == VIDEO_YUV420P) && h->fmt_v4l2.fmt.pix.width % 16) { fmt->width = h->fmt_v4l2.fmt.pix.width & ~15; goto retry; } fmt->width = h->fmt_v4l2.fmt.pix.width; fmt->height = h->fmt_v4l2.fmt.pix.height; fmt->bytesperline = h->fmt_v4l2.fmt.pix.bytesperline; /* struct v4l2_format.fmt.pix.bytesperline is bytesperline for the main plane for planar formats, where as we want it to be the total bytesperline for all planes */ switch (fmt->fmtid) { case VIDEO_YUV422P: fmt->bytesperline *= 2; break; case VIDEO_YUV420P: fmt->bytesperline = fmt->bytesperline * 3 / 2; break; } if (0 == fmt->bytesperline) fmt->bytesperline = fmt->width * ng_vfmt_to_depth[fmt->fmtid] / 8; h->fmt_me = *fmt; if (ng_debug) fprintf(stderr,"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte)\n", fmt->width,fmt->height, h->fmt_v4l2.fmt.pix.pixelformat & 0xff, (h->fmt_v4l2.fmt.pix.pixelformat >> 8) & 0xff, (h->fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff, (h->fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff, h->fmt_v4l2.fmt.pix.sizeimage); return 0; } /* start/stop video */ static int v4l2_startvideo(void *handle, int fps, unsigned int buffers) { struct v4l2_handle *h = handle; if (0 != h->fps) fprintf(stderr,"v4l2_startvideo: oops: fps!=0\n"); h->fps = fps; h->first = 1; h->start = 0; if (h->cap.capabilities & V4L2_CAP_STREAMING) return v4l2_start_streaming(h,buffers); return 0; } static void v4l2_stopvideo(void *handle) { struct v4l2_handle *h = handle; if (0 == h->fps) fprintf(stderr,"v4l2_stopvideo: oops: fps==0\n"); h->fps = 0; if (h->cap.capabilities & V4L2_CAP_STREAMING) v4l2_stop_streaming(h); } /* read images */ static struct ng_video_buf* v4l2_nextframe(void *handle) { struct v4l2_handle *h = handle; struct ng_video_buf *buf = NULL; int rc,size,frame = 0; if (h->cap.capabilities & V4L2_CAP_STREAMING) { v4l2_queue_all(h); frame = v4l2_waiton(h); if (-1 == frame) return NULL; h->buf_me[frame].refcount++; buf = &h->buf_me[frame]; memset(&buf->info,0,sizeof(buf->info)); buf->info.ts = ng_tofday_to_timestamp(&h->buf_v4l2[frame].timestamp); } else { size = h->fmt_me.bytesperline * h->fmt_me.height; buf = ng_malloc_video_buf(&h->fmt_me,size); #ifndef USE_LIBV4L rc = read(h->fd,buf->data,size); #else /* USE_LIBV4L */ rc = v4l2_read(h->fd,buf->data,size); #endif /* USE_LIBV4L */ if (rc != size) { if (-1 == rc) { #ifdef HAVE_EXPLAIN fprintf(stderr,"v4l2: read: %s\n",explain_read(h->fd, buf->data, size)); #else perror("v4l2: read"); #endif } else { fprintf(stderr, "v4l2: read: rc=%d/size=%d\n",rc,size); } ng_release_video_buf(buf); return NULL; } memset(&buf->info,0,sizeof(buf->info)); buf->info.ts = ng_get_timestamp(); } if (h->first) { h->first = 0; h->start = buf->info.ts; if (ng_debug) fprintf(stderr,"v4l2: start ts=%lld\n",h->start); } buf->info.ts -= h->start; return buf; } static struct ng_video_buf* v4l2_getimage(void *handle) { struct v4l2_handle *h = handle; struct ng_video_buf *buf; int size,frame,rc; size = h->fmt_me.bytesperline * h->fmt_me.height; buf = ng_malloc_video_buf(&h->fmt_me,size); if (h->cap.capabilities & V4L2_CAP_STREAMING) { if (-1 == v4l2_start_streaming(h,1)) { v4l2_stop_streaming(h); return NULL; } frame = v4l2_waiton(h); if (-1 == frame) { v4l2_stop_streaming(h); return NULL; } memcpy(buf->data,h->buf_me[0].data,size); v4l2_stop_streaming(h); } else { #ifndef USE_LIBV4L rc = read(h->fd,buf->data,size); #else /* USE_LIBV4L */ rc = v4l2_read(h->fd,buf->data,size); #endif /* USE_LIBV4L */ if (-1 == rc && EBUSY == errno && h->ov_on) { h->ov_on = 0; xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0); #ifndef USE_LIBV4L rc = read(h->fd,buf->data,size); #else /* USE_LIBV4L */ rc = v4l2_read(h->fd,buf->data,size); #endif /* USE_LIBV4L */ h->ov_on = 1; xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0); } if (rc >= 0) h->read_done = 1; if (rc != size) { if (-1 == rc) { perror("v4l2: read"); } else { fprintf(stderr, "v4l2: read: rc=%d/size=%d\n",rc,size); } ng_release_video_buf(buf); return NULL; } } return buf; } /* ---------------------------------------------------------------------- */ extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_vid_driver_register(NG_PLUGIN_MAGIC,__FILE__,&v4l2_driver); } xawtv-3.106/libng/plugins/flt-debug.c000066400000000000000000000047211343350355000174720ustar00rootroot00000000000000/* * This plugin provides some filter controls (for GUI code debugging). * It does nothing else, video frames just passed through as-is. * * You can have a look at the invert filter for sample code which * actually does some image processing. * * (c) 2002 Gerd Knorr * */ #include "config.h" #include #include #include #include "grab-ng.h" /* ------------------------------------------------------------------- */ static void *init(struct ng_video_fmt *out) { /* don't have to carry around status info */ static int dummy; return &dummy; } static struct ng_video_buf* frame(void *handle, struct ng_video_buf *in) { /* do nothing -- just return the frame as-is */ return in; } static void fini(void *handle) { /* nothing to clean up */ } /* ------------------------------------------------------------------- */ static int vals[3] = { 32, 1, 2 }; static int read_attr(struct ng_attribute *attr) { return vals[attr->id]; } static void write_attr(struct ng_attribute *attr, int value) { fprintf(stderr,PLUGNAME ": %s: %d\n", attr->name, value); vals[attr->id] = value; } /* ------------------------------------------------------------------- */ static struct STRTAB items[] = { { 1, "entry 1" }, { 2, "entry 2" }, { 3, "entry 3" }, { -1, NULL }, }; static struct ng_attribute attrs[] = { { id: 0, name: "scale (integer)", type: ATTR_TYPE_INTEGER, min: 0, max: 100, read: read_attr, write: write_attr, },{ id: 1, name: "yes/no (boolean)", type: ATTR_TYPE_BOOL, read: read_attr, write: write_attr, },{ id: 2, name: "menu (choice)", type: ATTR_TYPE_CHOICE, choices: items, read: read_attr, write: write_attr, },{ /* end of list */ } }; static struct ng_filter filter = { name: "gui debug", attrs: attrs, fmts: (1 << VIDEO_RGB08) | (1 << VIDEO_GRAY) | (1 << VIDEO_RGB15_LE) | (1 << VIDEO_RGB16_LE) | (1 << VIDEO_RGB15_BE) | (1 << VIDEO_RGB16_BE) | (1 << VIDEO_BGR24) | (1 << VIDEO_BGR32) | (1 << VIDEO_RGB24) | (1 << VIDEO_RGB32) | (1 << VIDEO_YUV422) | (1 << VIDEO_YUV422P) | (1 << VIDEO_YUV420P), init: init, frame: frame, fini: fini, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_filter_register(NG_PLUGIN_MAGIC,PLUGNAME,&filter); } xawtv-3.106/libng/plugins/flt-disor.c000066400000000000000000000110471343350355000175230ustar00rootroot00000000000000/* * libng filter -- Correction of lens distortion * * (c) 2002 Frederic Helin , * Gerd Knorr * */ #include "config.h" #include #include #include #include #include #include "grab-ng.h" /* ------------------------------------------------------------------- */ int parm_k = 700; int parm_cx = 50; int parm_cy = 50; int parm_zoom = 50; /* ------------------------------------------------------------------- */ static void *init(struct ng_video_fmt *out) { /* don't have to carry around status info */ static int dummy; return &dummy; } static struct ng_video_buf* frame(void *handle, struct ng_video_buf *in) { struct ng_video_buf *out; uint8_t *dst8; uint8_t *src8; uint16_t *dst16; uint16_t *src16; int i, j, cx, cy, di, dj; float dr, cr,ca, sx, zoom, k; out = ng_malloc_video_buf(&in->fmt, in->fmt.height * in->fmt.bytesperline); out->info = in->info; dst8 = out->data; src8 = in->data; dst16 = (uint16_t*) out->data; src16 = (uint16_t*) in->data; zoom = parm_zoom / 100.0; k = parm_k / 100.0; cx = in->fmt.width * parm_cx / 100; cy = in->fmt.height * parm_cy / 100; #if 0 sensor_w = parm_sensorw/100.0; sensor_h = parm_sensorh/100.0; /* calc ratio x/y */ sx = in->fmt.width * sensor_h / (in->fmt.height * sensor_w); /* calc new value of k in the coordonates systeme of computer */ k = k * in->fmt.height / sensor_h; #else sx = 1; k = k * 100.0; #endif for (j = 0; j < (int)in->fmt.height ; j++) { for (i = 0; i < (int)in->fmt.width ; i++) { // compute radial distortion / parameters of center of image cr = sqrt((i-cx)/sx*(i-cx)/sx+(j-cy)*(j-cy)); ca = atan(cr/k/zoom); dr = k * tan(ca/2); if (i == cx && j == cy) { di = cx; dj = cy; } else { di = (i-cx) * dr / cr + cx; dj = (j-cy) * dr / cr + cy; } if (dj >= (int)in->fmt.height || dj < 0 || di >= (int)in->fmt.width || di < 0) continue; switch (in->fmt.fmtid) { case VIDEO_RGB15_LE: case VIDEO_RGB16_LE: case VIDEO_RGB15_BE: case VIDEO_RGB16_BE: dst16[i] = src16[dj*in->fmt.width + di]; break; case VIDEO_BGR24: case VIDEO_RGB24: dst8[3*i ] = src8[3*(dj*in->fmt.width + di) ]; dst8[3*i+1] = src8[3*(dj*in->fmt.width + di)+1]; dst8[3*i+2] = src8[3*(dj*in->fmt.width + di)+2]; break; } } dst8 += out->fmt.bytesperline; dst16 += out->fmt.bytesperline/2; } ng_release_video_buf(in); return out; } static void fini(void *handle) { /* nothing to clean up */ } /* ------------------------------------------------------------------- */ static int read_attr(struct ng_attribute *attr) { switch (attr->id) { case 1000: return parm_k; case 1001: return parm_zoom; case 1002: return parm_cx; case 1003: return parm_cy; } return 0; } static void write_attr(struct ng_attribute *attr, int value) { switch (attr->id) { case 1000: parm_k = value; break; case 1001: parm_zoom = value; break; case 1002: parm_cx = value; break; case 1003: parm_cy = value; break; } } /* ------------------------------------------------------------------- */ static struct ng_attribute attrs[] = { { .id = 1000, .name = "k", .type = ATTR_TYPE_INTEGER, .defval = 700, .min = 1, .max = 2000, .read = read_attr, .write = write_attr, },{ .id = 1001, .name = "zoom", .type = ATTR_TYPE_INTEGER, .defval = 50, .min = 10, .max = 100, .read = read_attr, .write = write_attr, },{ .id = 1002, .name = "center x", .type = ATTR_TYPE_INTEGER, .defval = 50, .min = 0, .max = 100, .read = read_attr, .write = write_attr, },{ .id = 1003, .name = "center y", .type = ATTR_TYPE_INTEGER, .defval = 50, .min = 0, .max = 100, .read = read_attr, .write = write_attr, },{ /* end of list */ } }; static struct ng_filter filter = { .name = "disortion correction", .attrs = attrs, .fmts = (1 << VIDEO_RGB15_BE) | (1 << VIDEO_RGB16_BE) | (1 << VIDEO_RGB15_LE) | (1 << VIDEO_RGB16_LE) | (1 << VIDEO_BGR24) | (1 << VIDEO_RGB24), .init = init, .frame = frame, .fini = fini, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_filter_register(NG_PLUGIN_MAGIC,__FILE__,&filter); } xawtv-3.106/libng/plugins/flt-gamma.c000066400000000000000000000071461343350355000174720ustar00rootroot00000000000000/* * libng filter -- gamma correction * * (c) 2002 Gerd Knorr * */ #include "config.h" #include #include #include #include #include "grab-ng.h" /* ------------------------------------------------------------------- */ static unsigned char lut[256]; static int g = 100; static void inline gamma_bytes(unsigned char *dst, unsigned char *src, int bytes) { while (bytes--) *(dst++) = lut[ *(src++) ]; } static void inline gamma_native_rgb15(void *d, void *s, int pixels) { unsigned short *dst = d; unsigned short *src = s; unsigned short r,g,b; while (pixels--) { r = lut[ ((*src >> 7) & 0xf8) ] & 0xf8; g = lut[ ((*src >> 2) & 0xf8) ] & 0xf8; b = lut[ ((*src << 3) & 0xf8) ] & 0xf8; *dst = (r << 7) | (g << 2) | (b >> 3); src++; dst++; } } static void inline gamma_native_rgb16(void *d, void *s, int pixels) { unsigned short *dst = d; unsigned short *src = s; unsigned short r,g,b; while (pixels--) { r = lut[ ((*src >> 8) & 0xf8) ] & 0xf8; g = lut[ ((*src >> 3) & 0xfc) ] & 0xfc; b = lut[ ((*src << 3) & 0xf8) ] & 0xf8; *dst = (r << 8) | (g << 3) | (b >> 3); src++; dst++; } } /* ------------------------------------------------------------------- */ static void *init(struct ng_video_fmt *out) { /* don't have to carry around status info */ static int dummy; return &dummy; } static struct ng_video_buf* frame(void *handle, struct ng_video_buf *in) { struct ng_video_buf *out; unsigned char *dst; unsigned char *src; unsigned int y,cnt; out = ng_malloc_video_buf(&in->fmt, in->fmt.height * in->fmt.bytesperline); out->info = in->info; dst = out->data; src = in->data; cnt = in->fmt.width * ng_vfmt_to_depth[in->fmt.fmtid] / 8; for (y = 0; y < in->fmt.height; y++) { switch (in->fmt.fmtid) { case VIDEO_GRAY: case VIDEO_BGR24: case VIDEO_RGB24: case VIDEO_BGR32: case VIDEO_RGB32: gamma_bytes(dst,src,cnt); break; case VIDEO_RGB15_NATIVE: gamma_native_rgb15(dst,src,in->fmt.width); break; case VIDEO_RGB16_NATIVE: gamma_native_rgb16(dst,src,in->fmt.width); break; } dst += out->fmt.bytesperline; src += in->fmt.bytesperline; } ng_release_video_buf(in); return out; } static void fini(void *handle) { /* nothing to clean up */ } /* ------------------------------------------------------------------- */ static void calc_lut(void) { int i,val; for (i = 0; i < 256; i++) { val = 255 * pow((float)i/255, 100.0/g); if (val < 0) val = 0; if (val > 255) val = 255; lut[i] = val; } } static int read_attr(struct ng_attribute *attr) { return g; } static void write_attr(struct ng_attribute *attr, int value) { g = value; calc_lut(); } /* ------------------------------------------------------------------- */ static struct ng_attribute attrs[] = { { .id = 0, .name = "gamma value", .type = ATTR_TYPE_INTEGER, .defval = 100, .min = 1, .max = 500, .points = 2, .read = read_attr, .write = write_attr, },{ /* end of list */ } }; static struct ng_filter filter = { .name = "gamma", .attrs = attrs, .fmts = (1 << VIDEO_GRAY) | (1 << VIDEO_RGB15_NATIVE) | (1 << VIDEO_RGB16_NATIVE) | (1 << VIDEO_BGR24) | (1 << VIDEO_RGB24) | (1 << VIDEO_BGR32) | (1 << VIDEO_RGB32), .init = init, .frame = frame, .fini = fini, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { calc_lut(); ng_filter_register(NG_PLUGIN_MAGIC,__FILE__,&filter); } xawtv-3.106/libng/plugins/flt-invert.c000066400000000000000000000055741343350355000177220ustar00rootroot00000000000000/* * simple libng filter -- just invert the image * * (c) 2001 Gerd Knorr * */ #include "config.h" #include #include #include #include "grab-ng.h" /* ------------------------------------------------------------------- */ static void inline invert_bytes(unsigned char *dst, unsigned char *src, int bytes) { while (bytes--) *(dst++) = 0xff - *(src++); } static void inline invert_native_rgb15(void *d, void *s, int pixels) { unsigned short *dst = d; unsigned short *src = s; unsigned short r,g,b; while (pixels--) { r = 0x1f - ((*src >> 10) & 0x1f); g = 0x1f - ((*src >> 5) & 0x1f); b = 0x1f - ( *src & 0x1f); *dst = (r << 10) | (g << 5) | b; src++; dst++; } } static void inline invert_native_rgb16(void *d, void *s, int pixels) { unsigned short *dst = d; unsigned short *src = s; unsigned short r,g,b; while (pixels--) { r = 0x1f - ((*src >> 11) & 0x1f); g = 0x3f - ((*src >> 5) & 0x3f); b = 0x1f - ( *src & 0x1f); *dst = (r << 11) | (g << 5) | b; src++; dst++; } } /* ------------------------------------------------------------------- */ static void *init(struct ng_video_fmt *out) { /* don't have to carry around status info */ static int dummy; return &dummy; } static struct ng_video_buf* frame(void *handle, struct ng_video_buf *in) { struct ng_video_buf *out; unsigned char *dst; unsigned char *src; unsigned int y,cnt; out = ng_malloc_video_buf(&in->fmt, in->fmt.height * in->fmt.bytesperline); out->info = in->info; dst = out->data; src = in->data; cnt = in->fmt.width * ng_vfmt_to_depth[in->fmt.fmtid] / 8; for (y = 0; y < in->fmt.height; y++) { switch (in->fmt.fmtid) { case VIDEO_GRAY: case VIDEO_BGR24: case VIDEO_RGB24: case VIDEO_BGR32: case VIDEO_RGB32: case VIDEO_YUYV: case VIDEO_UYVY: invert_bytes(dst,src,cnt); break; case VIDEO_RGB15_NATIVE: invert_native_rgb15(dst,src,in->fmt.width); break; case VIDEO_RGB16_NATIVE: invert_native_rgb16(dst,src,in->fmt.width); break; } dst += out->fmt.bytesperline; src += in->fmt.bytesperline; } ng_release_video_buf(in); return out; } static void fini(void *handle) { /* nothing to clean up */ } /* ------------------------------------------------------------------- */ static struct ng_filter filter = { .name = "invert", .fmts = (1 << VIDEO_GRAY) | (1 << VIDEO_RGB15_NATIVE) | (1 << VIDEO_RGB16_NATIVE) | (1 << VIDEO_BGR24) | (1 << VIDEO_RGB24) | (1 << VIDEO_BGR32) | (1 << VIDEO_RGB32) | (1 << VIDEO_YUYV) | (1 << VIDEO_UYVY), .init = init, .frame = frame, .fini = fini, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_filter_register(NG_PLUGIN_MAGIC,__FILE__,&filter); } xawtv-3.106/libng/plugins/read-avi.c000066400000000000000000000256631343350355000173210ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include "riff.h" #include "list.h" #include "grab-ng.h" /* ----------------------------------------------------------------------- */ struct movi_range { off_t start; off_t size; }; struct avi_handle { int fd; struct iovec *vec; /* avi header */ unsigned char riff_type[4]; unsigned char fcc_type[4]; struct RIFF_avih avih; struct RIFF_strh v_strh; struct RIFF_strh a_strh; struct RIFF_strf_vids vids; struct RIFF_strf_auds auds; int32_t dml_frames; struct movi_range *movi; int movi_cnt; struct movi_range wave; /* libng stuff */ struct ng_video_fmt vfmt; struct ng_audio_fmt afmt; /* status data */ off_t a_pos; off_t v_pos; int frames; off_t a_bytes; }; /* ----------------------------------------------------------------------- */ #define FCC(a,b,c,d) (((uint32_t)a << 24) |\ ((uint32_t)b << 16) |\ ((uint32_t)c << 8) |\ (uint32_t)d) #define FCCS(str) FCC(str[0],str[1],str[2],str[3]) static void avi_add_movi(struct avi_handle *h, int level, off_t start, off_t size) { if (0 == h->movi_cnt % 16) h->movi = realloc(h->movi,sizeof(struct movi_range)*(h->movi_cnt+16)); h->movi[h->movi_cnt].start = start; h->movi[h->movi_cnt].size = size; h->movi_cnt++; if (ng_debug) fprintf(stderr,"%*s[movie data list: 0x%llx+0x%llx]\n", level, "", (unsigned long long)start, (unsigned long long)size); } static void avi_swap_strh(struct RIFF_strh *strh) { strh->flags = AVI_SWAP4(strh->flags); strh->priority = AVI_SWAP4(strh->priority); strh->init_frames = AVI_SWAP4(strh->init_frames); strh->scale = AVI_SWAP4(strh->scale); strh->rate = AVI_SWAP4(strh->rate); strh->start = AVI_SWAP4(strh->start); strh->length = AVI_SWAP4(strh->length); strh->bufsize = AVI_SWAP4(strh->bufsize); strh->quality = AVI_SWAP4(strh->quality); strh->samplesize = AVI_SWAP4(strh->samplesize); } static void avi_swap_vids(struct RIFF_strf_vids *fmt) { fmt->size = AVI_SWAP4(fmt->size); fmt->width = AVI_SWAP4(fmt->width); fmt->height = AVI_SWAP4(fmt->height); fmt->planes = AVI_SWAP2(fmt->planes); fmt->bit_cnt = AVI_SWAP2(fmt->bit_cnt); fmt->image_size = AVI_SWAP4(fmt->image_size); fmt->xpels_meter = AVI_SWAP4(fmt->xpels_meter); fmt->ypels_meter = AVI_SWAP4(fmt->ypels_meter); fmt->num_colors = AVI_SWAP4(fmt->num_colors); fmt->imp_colors = AVI_SWAP4(fmt->imp_colors); } static void avi_swap_auds(struct RIFF_strf_auds *fmt) { fmt->format = AVI_SWAP2(fmt->format); fmt->channels = AVI_SWAP2(fmt->channels); fmt->rate = AVI_SWAP4(fmt->rate); fmt->av_bps = AVI_SWAP4(fmt->av_bps); fmt->blockalign = AVI_SWAP2(fmt->blockalign); fmt->size = AVI_SWAP2(fmt->size); } static int avi_parse_header(struct avi_handle *h, off_t offset, int level) { struct CHUNK_HDR chunk; struct RIFF_strh strh; unsigned char id[4]; off_t pos = offset; lseek(h->fd,offset,SEEK_SET); pos += read(h->fd,&chunk,sizeof(chunk)); chunk.size = AVI_SWAP4(chunk.size); if (ng_debug) fprintf(stderr,"%*s%4.4s <0x%x>\n",level,"",chunk.id,chunk.size); switch (FCCS(chunk.id)) { case FCC('R','I','F','F'): case FCC('L','I','S','T'): pos += read(h->fd,&id,sizeof(id)); if (FCCS(chunk.id) == FCC('R','I','F','F')) memcpy(h->riff_type,id,4); if (ng_debug) fprintf(stderr,"%*s[list type is %4.4s]\n",level,"",id); if (FCCS(id) == FCC('m','o','v','i')) { avi_add_movi(h,level,pos,chunk.size-4); } else { while (pos < offset + chunk.size) pos += avi_parse_header(h,pos,level+3); } break; case FCC('a','v','i','h'): read(h->fd,&h->avih,sizeof(h->avih)); break; case FCC('s','t','r','h'): read(h->fd,&strh,sizeof(strh)); memcpy(h->fcc_type,strh.type,sizeof(h->fcc_type)); if (ng_debug) fprintf(stderr,"%*s[header type is %4.4s]\n",level,"",h->fcc_type); avi_swap_strh(&strh); if (FCCS(h->fcc_type) == FCC('a','u','d','s')) h->a_strh = strh; if (FCCS(h->fcc_type) == FCC('v','i','d','s')) h->v_strh = strh; break; case FCC('s','t','r','f'): if (FCCS(h->fcc_type) == FCC('a','u','d','s')) { read(h->fd,&h->auds,sizeof(h->auds)); avi_swap_auds(&h->auds); } if (FCCS(h->fcc_type) == FCC('v','i','d','s')) { read(h->fd,&h->vids,sizeof(h->vids)); avi_swap_vids(&h->vids); } break; case FCC('d','m','l','h'): read(h->fd,&h->dml_frames,sizeof(h->dml_frames)); h->dml_frames = AVI_SWAP4(h->dml_frames); break; case FCC('f','m','t',' '): if (FCCS(h->riff_type) == FCC('W','A','V','E')) { read(h->fd,&h->auds,sizeof(h->auds)); avi_swap_auds(&h->auds); } break; case FCC('d','a','t','a'): if (FCCS(h->riff_type) == FCC('W','A','V','E')) { h->wave.start = pos; h->wave.size = chunk.size-4; } break; } return chunk.size+8; } static uint32_t avi_find_chunk(struct avi_handle *h, uint32_t id, off_t *pos) { struct CHUNK_HDR chunk; int n = 0, bytes; if (NULL == h->movi) { /* WAVE */ if (*pos >= h->wave.start + h->wave.size) return 0; lseek(h->fd,*pos,SEEK_SET); bytes = h->wave.start + h->wave.size - *pos; if (bytes > 64*1024) bytes = 64*1024; *pos += bytes; return bytes; } /* AVI + AVIX */ while (*pos >= h->movi[n].start + h->movi[n].size) { n++; if (n >= h->movi_cnt) return 0; } for (;;) { if (*pos >= h->movi[n].start + h->movi[n].size) { n++; if (n >= h->movi_cnt) return 0; *pos = h->movi[n].start; } lseek(h->fd,*pos,SEEK_SET); *pos += read(h->fd,&chunk,sizeof(chunk)); chunk.size = AVI_SWAP4(chunk.size); *pos += (chunk.size + 3) & ~0x03; /* 32-bit align */ if (FCCS(chunk.id) == id) { if (ng_debug) fprintf(stderr,"avi: chunk %4.4s: 0x%llx+0x%x\n", chunk.id,(unsigned long long)(*pos),chunk.size); return chunk.size; } } } /* ----------------------------------------------------------------------- */ static void* avi_open(char *moviename) { struct avi_handle *h; off_t pos, size; h = malloc(sizeof(*h)); memset(h,0,sizeof(*h)); h->fd = -1; h->fd = open(moviename,O_RDONLY); if (-1 == h->fd) { fprintf(stderr,"open %s: %s\n",moviename,strerror(errno)); goto fail; } size = lseek(h->fd,0,SEEK_END); for (pos = 0; pos < size;) pos += avi_parse_header(h,pos,0); if (h->movi) { h->a_pos = h->movi[0].start; h->v_pos = h->movi[0].start; } else if (h->wave.start) { h->a_pos = h->wave.start; } /* audio stream ?? */ if (FCCS(h->a_strh.type) == FCC('a','u','d','s') || FCCS(h->riff_type) == FCC('W','A','V','E')) { switch (h->auds.format) { case WAVE_FORMAT_PCM: if (h->auds.size == 8) h->afmt.fmtid = AUDIO_U8_MONO; if (h->auds.size == 16) h->afmt.fmtid = AUDIO_S16_LE_MONO; if (h->afmt.fmtid) { if (h->auds.channels > 1) h->afmt.fmtid++; /* mono => stereo */ h->afmt.rate = h->auds.rate; } break; } if (h->afmt.fmtid != AUDIO_NONE && ng_debug) fprintf(stderr,"avi: audio is %s @ %d Hz\n", ng_afmt_to_desc[h->afmt.fmtid],h->afmt.rate); } /* video stream ?? */ if (FCCS(h->v_strh.type) == FCC('v','i','d','s')) { switch (FCCS(h->v_strh.handler)) { case 0: if (h->vids.bit_cnt == 15) h->vfmt.fmtid = VIDEO_RGB15_LE; if (h->vids.bit_cnt == 24) h->vfmt.fmtid = VIDEO_BGR24; break; case FCC('M','J','P','G'): h->vfmt.fmtid = VIDEO_MJPEG; break; } if (VIDEO_NONE != h->vfmt.fmtid) { h->vfmt.width = h->vids.width; h->vfmt.height = h->vids.height; h->vfmt.bytesperline = (h->vfmt.width*ng_vfmt_to_depth[h->vfmt.fmtid]) >> 3; h->vec = malloc(sizeof(struct iovec) * h->vfmt.height); if (ng_debug) fprintf(stderr,"avi: video is %s, %dx%d @ %d fps\n", ng_vfmt_to_desc[h->vfmt.fmtid], h->vfmt.width, h->vfmt.height, (int)((long long) 1000000 / h->avih.us_frame)); } } return h; fail: if (-1 != h->fd) close(h->fd); free(h); return NULL; } static struct ng_video_fmt* avi_vfmt(void *handle, int *vfmt, int vn) { struct avi_handle *h = handle; return &h->vfmt; } static struct ng_audio_fmt* avi_afmt(void *handle) { struct avi_handle *h = handle; return AUDIO_NONE != h->afmt.fmtid ? &h->afmt : NULL; } static struct ng_video_buf* avi_vdata(void *handle, unsigned int drop) { struct avi_handle *h = handle; struct ng_video_buf *buf; struct iovec *line; uint32_t size; unsigned int i,y; /* drop frames */ for (i = 0; i < drop; i++) { if (0 == avi_find_chunk(h,FCC('0','0','d','b'),&h->v_pos)) return NULL; h->frames++; } size = avi_find_chunk(h,FCC('0','0','d','b'),&h->v_pos); if (0 == size) return NULL; buf = ng_malloc_video_buf(&h->vfmt,size); switch (h->vfmt.fmtid) { case VIDEO_RGB15_LE: case VIDEO_BGR24: for (line = h->vec, y = h->vfmt.height-1; y >= 0; line++, y--) { line->iov_base = ((unsigned char*)buf->data) + y * h->vfmt.bytesperline; line->iov_len = h->vfmt.bytesperline; } readv(h->fd,h->vec,h->vfmt.height); break; case VIDEO_MJPEG: case VIDEO_JPEG: read(h->fd,buf->data,size); break; } buf->info.seq = h->frames; buf->info.ts = (long long)h->frames * h->avih.us_frame * 1000; h->frames++; return buf; } static struct ng_audio_buf* avi_adata(void *handle) { struct avi_handle *h = handle; struct ng_audio_buf *buf; uint32_t size, samples; size = avi_find_chunk(h,FCC('0','1','w','b'),&h->a_pos); if (0 == size) return NULL; buf = ng_malloc_audio_buf(&h->afmt,size); read(h->fd,buf->data,size); samples = h->a_bytes * 8 / ng_afmt_to_channels[h->afmt.fmtid] / ng_afmt_to_bits[h->afmt.fmtid]; buf->info.ts = (long long)samples * 1000000000 / h->afmt.rate; h->a_bytes += size; return buf; } static int64_t avi_frame_time(void *handle) { struct avi_handle *h = handle; return h->avih.us_frame * 1000; } static int avi_close(void *handle) { struct avi_handle *h = handle; if (h->vec) free(h->vec); close(h->fd); free(h); return 0; } /* ----------------------------------------------------------------------- */ struct ng_reader avi_reader = { .name = "avi", .desc = "Microsoft AVI (RIFF) format", .magic = { "RIFF" }, .moff = { 0 }, .mlen = { 4 }, .rd_open = avi_open, .rd_vfmt = avi_vfmt, .rd_afmt = avi_afmt, .rd_vdata = avi_vdata, .rd_adata = avi_adata, .frame_time = avi_frame_time, .rd_close = avi_close, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_reader_register(NG_PLUGIN_MAGIC,__FILE__,&avi_reader); } xawtv-3.106/libng/plugins/read-dv.c000066400000000000000000000202111343350355000171330ustar00rootroot00000000000000/* gcc 2.95.x doesn't compile some c99 constructs ... */ #if __GNUC__ >= 3 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "grab-ng.h" /* ----------------------------------------------------------------------- */ struct dv_handle { /* handles */ int fd; dv_decoder_t *dec; /* mmap()ed data */ unsigned char *map_start; unsigned char *map_ptr; off_t map_size; int map_frame; /* format */ struct ng_video_fmt vfmt; struct ng_audio_fmt afmt; /* misc video */ int rate,vframe,frames; /* misc audio */ int aframe,samples; int16_t *audiobuf[4]; }; /* ----------------------------------------------------------------------- */ static enum color_space_e fmtid_to_colorspace[VIDEO_FMT_COUNT] = { [ 0 ... VIDEO_FMT_COUNT-1 ] = UNSET, [ VIDEO_YUYV ] = e_dv_color_yuv, [ VIDEO_RGB24 ] = e_dv_color_rgb, [ VIDEO_BGR32 ] = e_dv_color_bgr0, }; /* ----------------------------------------------------------------------- */ static void dv_unmap(struct dv_handle *h) { if (!h->map_ptr) return; munmap(h->map_start,h->map_size); h->map_ptr = NULL; } static void dv_map(struct dv_handle *h, int frame) { off_t map_offset; off_t pgsize, size, offset; size = h->dec->frame_size; if (0 == size) size = 120000; /* NTSC frame size */ offset = frame * size; pgsize = getpagesize(); map_offset = offset & ~(pgsize-1); h->map_size = offset - map_offset + size; h->map_start = mmap(0, h->map_size, PROT_READ, MAP_SHARED, h->fd, map_offset); if (MAP_FAILED == h->map_start) { perror("mmap"); exit(1); } h->map_ptr = h->map_start + (offset - map_offset); } static void dv_fmt(struct dv_handle *h, int *vfmt, int vn) { off_t len; int i; /* video format */ for (i = 0; i < vn; i++) { if (ng_debug) fprintf(stderr,"dv: trying: %d [%s]\n", vfmt[i],ng_vfmt_to_desc[vfmt[i]]); if (UNSET == fmtid_to_colorspace[vfmt[i]]) continue; h->vfmt.fmtid = vfmt[i]; break; } h->vfmt.width = h->dec->width; h->vfmt.height = h->dec->height; h->vfmt.bytesperline = (h->vfmt.width*ng_vfmt_to_depth[h->vfmt.fmtid]) >> 3; h->rate = (e_dv_system_625_50 == h->dec->system) ? 25 : 30; /* audio fmt */ if (1 == h->dec->audio->num_channels || 2 == h->dec->audio->num_channels) { h->afmt.fmtid = (16 == h->dec->audio->quantization) ? AUDIO_S16_NATIVE_MONO : AUDIO_U8_MONO; if (2 == h->dec->audio->num_channels) h->afmt.fmtid++; } h->afmt.rate = h->dec->audio->frequency; /* movie length (# of frames) */ len = lseek(h->fd,0,SEEK_END); h->frames = len / h->dec->frame_size; if (ng_debug) { fprintf(stderr,"dv: len=%lld => %d frames [%" PRId64 "]\n", (unsigned long long)len, h->frames, len - (off_t)h->frames * h->dec->frame_size); fprintf(stderr, "dv: quality=%d system=%d std=%d sampling=%d num_dif_seqs=%d\n" "dv: height=%d width=%d frame_size=%ld\n", h->dec->quality, h->dec->system, h->dec->std, h->dec->sampling, h->dec->num_dif_seqs, h->dec->height, h->dec->width, (long) h->dec->frame_size); fprintf(stderr, "dv: audio: %d Hz, %d bits, %d channels," " emphasis %s\n", h->dec->audio->frequency, h->dec->audio->quantization, h->dec->audio->num_channels, (h->dec->audio->emphasis ? "on" : "off")); } } /* ----------------------------------------------------------------------- */ static void* dv_open(char *moviename) { struct dv_handle *h; if (NULL == (h = malloc(sizeof(*h)))) goto oops; memset(h,0,sizeof(*h)); h->map_frame = -1; if (-1 == (h->fd = open(moviename,O_RDONLY))) { fprintf(stderr,"dv: open %s: %s\n",moviename,strerror(errno)); goto oops; } if (NULL == (h->dec = dv_decoder_new(0,0,0))) { fprintf(stderr,"dv: dv_decoder_new failed\n"); goto oops; } h->dec->quality = 3; dv_map(h, 0); if (dv_parse_header(h->dec, h->map_ptr) < 0) { fprintf(stderr,"dv: dv_parse_header failed\n"); goto oops; } dv_fmt(h,NULL,0); return h; oops: if (h->dec) dv_decoder_free(h->dec); if (-1 != h->fd) close(h->fd); if (h) free(h); return NULL; } static struct ng_video_fmt* dv_vfmt(void *handle, int *vfmt, int vn) { struct dv_handle *h = handle; dv_fmt(h,vfmt,vn); return &h->vfmt; } static struct ng_audio_fmt* dv_afmt(void *handle) { struct dv_handle *h = handle; return h->afmt.fmtid ? &h->afmt : NULL; } static struct ng_video_buf* dv_vdata(void *handle, unsigned int drop) { struct dv_handle *h = handle; struct ng_video_buf *buf; unsigned char *pixels[3]; int pitches[3]; h->vframe += drop; if (h->vframe >= h->frames) return NULL; if (ng_debug > 1) fprintf(stderr,"dv: frame %d [drop=%d]\n",h->vframe,drop); dv_unmap(h); dv_map(h, h->vframe); if (dv_parse_header(h->dec, h->map_ptr) < 0) { fprintf(stderr,"dv: dv_parse_header failed\n"); return NULL; } buf = ng_malloc_video_buf(&h->vfmt,h->vfmt.bytesperline*h->vfmt.height); switch (h->vfmt.fmtid) { case VIDEO_YUYV: pixels[0] = buf->data; pitches[0] = buf->fmt.width*2; break; case VIDEO_RGB24: pixels[0] = buf->data; pitches[0] = buf->fmt.width*3; break; case VIDEO_BGR32: pixels[0] = buf->data; pitches[0] = buf->fmt.width*4; break; default: BUG_ON(1,"unknown fmtid"); } dv_parse_packs(h->dec, h->map_ptr); dv_decode_full_frame(h->dec, h->map_ptr, fmtid_to_colorspace[h->vfmt.fmtid], pixels, pitches); buf->info.seq = h->vframe; buf->info.ts = (long long) buf->info.seq * 1000000000 / h->rate; h->vframe++; return buf; } static struct ng_audio_buf* dv_adata(void *handle) { struct dv_handle *h = handle; struct ng_audio_buf *buf; int16_t *dest; int asize, i; if (h->aframe >= h->frames) return NULL; dv_unmap(h); dv_map(h, h->aframe); if (dv_parse_header(h->dec, h->map_ptr) < 0) { fprintf(stderr,"dv: dv_parse_header failed\n"); return NULL; } asize = h->dec->audio->samples_this_frame * h->dec->audio->num_channels * h->dec->audio->quantization >> 3; if (ng_debug > 1) fprintf(stderr,"dv: audio %d [samples=%d]\n",h->aframe, h->dec->audio->samples_this_frame); buf = ng_malloc_audio_buf(&h->afmt, asize); dest = (int16_t*)buf->data; if (2 == h->dec->audio->num_channels) { if (NULL == h->audiobuf[0]) for (i = 0; i < 4; i++) h->audiobuf[i] = malloc(DV_AUDIO_MAX_SAMPLES*sizeof(int16_t)); dv_decode_full_audio(h->dec, h->map_ptr, h->audiobuf); for (i = 0; i < h->dec->audio->samples_this_frame; i++) { dest[2*i+0] = h->audiobuf[0][i]; dest[2*i+1] = h->audiobuf[1][i]; } } if (1 == h->dec->audio->num_channels) dv_decode_full_audio(h->dec, h->map_ptr, &dest); buf->info.ts = (long long) h->samples * 1000000000 / h->afmt.rate; h->samples += h->dec->audio->samples_this_frame; h->aframe++; return buf; } static int64_t dv_frame_time(void *handle) { struct dv_handle *h = handle; return 1000000000 / h->rate; } static int dv_close(void *handle) { struct dv_handle *h = handle; int i; for (i = 0; i < 4; i++) if (h->audiobuf[i]) free(h->audiobuf[i]); dv_unmap(h); dv_decoder_free(h->dec); close(h->fd); free(h); return 0; } /* ----------------------------------------------------------------------- */ struct ng_reader dv_reader = { .name = "dv", .desc = "Digital Video", .magic = { "\x1f\x07\x00", "\x3f\x07\x00" }, .moff = { 0, 0x50 }, .mlen = { 3, 3 }, .rd_open = dv_open, .rd_vfmt = dv_vfmt, .rd_afmt = dv_afmt, .rd_vdata = dv_vdata, .rd_adata = dv_adata, .frame_time = dv_frame_time, .rd_close = dv_close, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_reader_register(NG_PLUGIN_MAGIC,__FILE__,&dv_reader); } #else /* gcc3 */ extern void ng_plugin_init(void); void ng_plugin_init(void) {} #endif /* gcc3 */ xawtv-3.106/libng/plugins/read-qt.c000066400000000000000000000165351343350355000171640ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #pragma GCC diagnostic ignored "-Wstrict-prototypes" #include #include #pragma GCC diagnostic warning "-Wstrict-prototypes" #include "grab-ng.h" #define AUDIO_SIZE (64*1024) /* ----------------------------------------------------------------------- */ static int fmtid_to_cmodel[VIDEO_FMT_COUNT] = { [ VIDEO_RGB24 ] = BC_RGB888, [ VIDEO_BGR24 ] = BC_BGR888, [ VIDEO_YUYV ] = BC_YUV422, [ VIDEO_YUV420P ] = BC_YUV420P, }; /* ----------------------------------------------------------------------- */ struct qt_handle { /* libquicktime handle */ quicktime_t *qt; /* format */ struct ng_video_fmt vfmt; struct ng_audio_fmt afmt; /* misc video */ unsigned char **rows; int rate; /* misc audio */ int channels; int16_t *left,*right; long long bps; }; static void* qt_open(char *moviename) { struct qt_handle *h; char *str; int i; if (NULL == (h = malloc(sizeof(*h)))) return NULL; memset(h,0,sizeof(*h)); /* open file */ h->qt = quicktime_open(moviename,1,0); if (NULL == h->qt) { fprintf(stderr,"ERROR: can't open file: %s\n",moviename); free(h); return NULL; } if (ng_debug) { /* print misc info */ fprintf(stderr,"quicktime movie %s:\n",moviename); str = quicktime_get_copyright(h->qt); if (str) fprintf(stderr," copyright: %s\n",str); str = quicktime_get_name(h->qt); if (str) fprintf(stderr," name: %s\n",str); str = quicktime_get_info(h->qt); if (str) fprintf(stderr," info: %s\n",str); /* print video info */ if (quicktime_has_video(h->qt)) { fprintf(stderr," video: %d track(s)\n",quicktime_video_tracks(h->qt)); for (i = 0; i < quicktime_video_tracks(h->qt); i++) { fprintf(stderr, " track #%d\n" " width : %d\n" " height: %d\n" " depth : %d bit\n" " rate : %.2f fps\n" " codec : %s\n", i+1, quicktime_video_width(h->qt,i), quicktime_video_height(h->qt,i), quicktime_video_depth(h->qt,i), quicktime_frame_rate(h->qt,i), quicktime_video_compressor(h->qt,i)); } } /* print audio info */ if (quicktime_has_audio(h->qt)) { fprintf(stderr," audio: %d track(s)\n",quicktime_audio_tracks(h->qt)); for (i = 0; i < quicktime_audio_tracks(h->qt); i++) { fprintf(stderr, " track #%d\n" " rate : %ld Hz\n" " bits : %d\n" " chans : %d\n" " codec : %s\n", i+1, quicktime_sample_rate(h->qt,i), quicktime_audio_bits(h->qt,i), quicktime_track_channels(h->qt,i), quicktime_audio_compressor(h->qt,i)); } } } /* video format */ if (!quicktime_has_video(h->qt)) { if (ng_debug) fprintf(stderr,"qt: no video stream\n"); } else if (!quicktime_supported_video(h->qt,0)) { if (ng_debug) fprintf(stderr,"qt: unsupported video codec\n"); } else { h->vfmt.width = quicktime_video_width(h->qt,0); h->vfmt.height = quicktime_video_height(h->qt,0); h->rate = quicktime_frame_rate(h->qt,0); } /* audio format */ if (!quicktime_has_audio(h->qt)) { if (ng_debug) fprintf(stderr,"qt: no audio stream\n"); } else if (!quicktime_supported_audio(h->qt,0)) { if (ng_debug) fprintf(stderr,"qt: unsupported audio codec\n"); } else { h->channels = quicktime_track_channels(h->qt,0); h->afmt.fmtid = (h->channels > 1) ? AUDIO_S16_NATIVE_STEREO : AUDIO_S16_NATIVE_MONO; h->afmt.rate = quicktime_sample_rate(h->qt,0); } return h; } static struct ng_video_fmt* qt_vfmt(void *handle, int *vfmt, int vn) { struct qt_handle *h = handle; int i; for (i = 0; i < vn; i++) { if (ng_debug) fprintf(stderr,"qt: trying: %d [%s]\n", vfmt[i],ng_vfmt_to_desc[vfmt[i]]); if (0 == fmtid_to_cmodel[vfmt[i]]) continue; if (!quicktime_reads_cmodel(h->qt,fmtid_to_cmodel[vfmt[i]],0)) continue; quicktime_set_cmodel(h->qt, fmtid_to_cmodel[vfmt[i]]); h->vfmt.fmtid = vfmt[i]; break; } h->vfmt.bytesperline = (h->vfmt.width*ng_vfmt_to_depth[h->vfmt.fmtid]) >> 3; return &h->vfmt; } static struct ng_audio_fmt* qt_afmt(void *handle) { struct qt_handle *h = handle; return h->afmt.fmtid ? &h->afmt : NULL; } static struct ng_video_buf* qt_vdata(void *handle, unsigned int drop) { struct qt_handle *h = handle; struct ng_video_buf *buf; unsigned int i; if (quicktime_video_position(h->qt,0) >= quicktime_video_length(h->qt,0)) return NULL; buf = ng_malloc_video_buf(&h->vfmt,h->vfmt.bytesperline*h->vfmt.height); if (!h->rows) h->rows = malloc(h->vfmt.height * sizeof(char*)); switch (fmtid_to_cmodel[h->vfmt.fmtid]) { case BC_RGB888: case BC_BGR888: for (i = 0; i < h->vfmt.height; i++) h->rows[i] = buf->data + h->vfmt.width * 3 * i; break; case BC_YUV422: for (i = 0; i < h->vfmt.height; i++) h->rows[i] = buf->data+ h->vfmt.width * 2 * i; break; case BC_YUV420P: h->rows[0] = buf->data; h->rows[1] = buf->data + h->vfmt.width*h->vfmt.height; h->rows[2] = buf->data + h->vfmt.width*h->vfmt.height*5/4; break; default: BUG_ON(1,"unknown cmodel"); } /* drop frames */ for (i = 0; i < drop; i++) quicktime_read_frame(h->qt,buf->data,0); buf->info.seq = quicktime_video_position(h->qt,0); buf->info.ts = (long long) buf->info.seq * 1000000000 / h->rate; lqt_decode_video(h->qt, h->rows, 0); return buf; } static struct ng_audio_buf* qt_adata(void *handle) { struct qt_handle *h = handle; struct ng_audio_buf *buf; int16_t *dest; long pos; int i; if (quicktime_audio_position(h->qt,0) >= quicktime_audio_length(h->qt,0)) return NULL; buf = ng_malloc_audio_buf(&h->afmt,AUDIO_SIZE); dest = (int16_t*)buf->data; pos = quicktime_audio_position(h->qt,0); buf->info.ts = (long long) pos * 1000000000 / h->afmt.rate; if (h->channels > 1) { /* stereo: two channels => interlaved samples */ if (!h->left) h->left = malloc(AUDIO_SIZE/2); if (!h->right) h->right = malloc(AUDIO_SIZE/2); quicktime_set_audio_position(h->qt,pos,0); quicktime_decode_audio(h->qt,h->left,NULL,AUDIO_SIZE/4,0); quicktime_set_audio_position(h->qt,pos,1); quicktime_decode_audio(h->qt,h->right,NULL,AUDIO_SIZE/4,1); for (i = 0; i < AUDIO_SIZE/4; i++) { dest[2*i+0] = h->left[i]; dest[2*i+1] = h->right[i]; } } else { /* mono */ quicktime_decode_audio(h->qt,dest,NULL,AUDIO_SIZE/2,0); } return buf; } static int64_t qt_frame_time(void *handle) { struct qt_handle *h = handle; return 1000000000 / h->rate; } static int qt_close(void *handle) { struct qt_handle *h = handle; quicktime_close(h->qt); if (h->rows) free(h->rows); free(h); return 0; } /* ----------------------------------------------------------------------- */ struct ng_reader qt_reader = { .name = "qt", .desc = "Apple QuickTime format", .magic = { "moov", "mdat" }, .moff = { 4, 4 }, .mlen = { 4, 4 }, .rd_open = qt_open, .rd_vfmt = qt_vfmt, .rd_afmt = qt_afmt, .rd_vdata = qt_vdata, .rd_adata = qt_adata, .frame_time = qt_frame_time, .rd_close = qt_close, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_reader_register(NG_PLUGIN_MAGIC,__FILE__,&qt_reader); } xawtv-3.106/libng/plugins/riff.h000066400000000000000000000102741343350355000165540ustar00rootroot00000000000000#include #include "byteswap.h" #if BYTE_ORDER == BIG_ENDIAN # define AVI_SWAP2(a) SWAP2((a)) # define AVI_SWAP4(a) SWAP4((a)) #else # define AVI_SWAP2(a) (a) # define AVI_SWAP4(a) (a) #endif #define WAVE_FORMAT_PCM (0x0001) #define WAVE_FORMAT_ALAW (0x0006) #define WAVE_FORMAT_MULAW (0x0007) #define AVIF_HASINDEX 0x10 struct RIFF_avih { uint32_t us_frame; /* microsec per frame */ uint32_t bps; /* byte/s overall */ uint32_t unknown1; /* pad_gran (???) */ uint32_t flags; uint32_t frames; /* # of frames (all) */ uint32_t init_frames; /* initial frames (???) */ uint32_t streams; uint32_t bufsize; /* suggested buffer size */ uint32_t width; uint32_t height; uint32_t scale; uint32_t rate; uint32_t start; uint32_t length; }; struct RIFF_strh { unsigned char type[4]; /* stream type */ unsigned char handler[4]; uint32_t flags; uint32_t priority; uint32_t init_frames; /* initial frames (???) */ uint32_t scale; uint32_t rate; uint32_t start; uint32_t length; uint32_t bufsize; /* suggested buffer size */ uint32_t quality; uint32_t samplesize; /* XXX 16 bytes ? */ }; struct RIFF_strf_vids { /* == BitMapInfoHeader */ uint32_t size; uint32_t width; uint32_t height; uint16_t planes; uint16_t bit_cnt; unsigned char compression[4]; uint32_t image_size; uint32_t xpels_meter; uint32_t ypels_meter; uint32_t num_colors; /* used colors */ uint32_t imp_colors; /* important colors */ /* may be more for some codecs */ }; struct RIFF_strf_auds { /* == WaveHeader (?) */ uint16_t format; uint16_t channels; uint32_t rate; uint32_t av_bps; uint16_t blockalign; uint16_t size; }; struct AVI_HDR { unsigned char riff_id[4]; uint32_t riff_size; unsigned char riff_type[4]; unsigned char hdrl_list_id[4]; uint32_t hdrl_size; unsigned char hdrl_type[4]; unsigned char avih_id[4]; uint32_t avih_size; struct RIFF_avih avih; }; struct AVIX_HDR { unsigned char riff_id[4]; uint32_t riff_size; unsigned char riff_type[4]; unsigned char data_list_id[4]; uint32_t data_size; unsigned char data_type[4]; }; struct AVI_HDR_VIDEO { unsigned char strl_list_id[4]; uint32_t strl_size; unsigned char strl_type[4]; unsigned char strh_id[4]; uint32_t strh_size; struct RIFF_strh strh; unsigned char strf_id[4]; uint32_t strf_size; struct RIFF_strf_vids strf; }; struct AVI_HDR_AUDIO { unsigned char strl_list_id[4]; uint32_t strl_size; unsigned char strl_type[4]; unsigned char strh_id[4]; uint32_t strh_size; struct RIFF_strh strh; unsigned char strf_id[4]; uint32_t strf_size; struct RIFF_strf_auds strf; }; struct AVI_HDR_ODML { unsigned char strl_list_id[4]; uint32_t strl_size; unsigned char strl_type[4]; unsigned char strh_id[4]; uint32_t strh_size; uint32_t total_frames; }; struct AVI_DATA { unsigned char data_list_id[4]; uint32_t data_size; unsigned char data_type[4]; /* audio+video data follows */ }; struct CHUNK_HDR { unsigned char id[4]; uint32_t size; }; struct IDX_RECORD { unsigned char id[4]; uint32_t flags; uint32_t offset; uint32_t size; }; xawtv-3.106/libng/plugins/snd-oss.c000066400000000000000000000317261343350355000172140ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #ifdef HAVE_SOUNDCARD_H # include #endif #ifdef HAVE_SYS_SOUNDCARD_H # include #endif #include "grab-ng.h" /* -------------------------------------------------------------------- */ extern int debug; static const char *names[] = SOUND_DEVICE_NAMES; static int mixer_read_attr(struct ng_attribute *attr); static void mixer_write_attr(struct ng_attribute *attr, int val); struct mixer_handle { int mix; int volctl; int volume; int muted; }; static struct ng_attribute mixer_attrs[] = { { .id = ATTR_ID_MUTE, .name = "mute", .type = ATTR_TYPE_BOOL, .read = mixer_read_attr, .write = mixer_write_attr, },{ .id = ATTR_ID_VOLUME, .name = "volume", .type = ATTR_TYPE_INTEGER, .min = 0, .max = 100, .read = mixer_read_attr, .write = mixer_write_attr, },{ /* end of list */ } }; static void mixer_close(void *handle) { struct mixer_handle *h = handle; if (-1 != h->mix) close(h->mix); free(h); } static void* mixer_open(char *device) { struct mixer_handle *h; h = malloc(sizeof(*h)); memset(h,0,sizeof(*h)); h->mix = -1; h->volctl = -1; if (-1 == (h->mix = open(device,O_RDONLY))) { fprintf(stderr,"open %s: %s\n",device,strerror(errno)); goto err; } fcntl(h->mix,F_SETFD,FD_CLOEXEC); return h; err: mixer_close(h); return NULL; } static struct ng_attribute* mixer_volctl(void *handle, char *channel) { struct mixer_handle *h = handle; struct ng_attribute *attrs; int i, devmask; if (-1 == ioctl(h->mix,MIXER_READ(SOUND_MIXER_DEVMASK),&devmask)) { fprintf(stderr,"oss mixer read devmask: %s",strerror(errno)); return NULL; } for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { if ((1<mix,MIXER_READ(i),&h->volume)) { fprintf(stderr,"oss mixer read volume: %s",strerror(errno)); return NULL; } else { h->volctl = i; } } } if (-1 == h->volctl) { fprintf(stderr,"oss mixer: '%s' not found, available:", channel); for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) if ((1<handle; int vol; switch (attr->id) { case ATTR_ID_VOLUME: if (-1 == ioctl(h->mix,MIXER_READ(h->volctl),&h->volume)) perror("oss mixer read volume"); vol = h->volume & 0x7f; return vol; case ATTR_ID_MUTE: return h->muted; default: return -1; } } static void mixer_write_attr(struct ng_attribute *attr, int val) { struct mixer_handle *h = attr->handle; switch (attr->id) { case ATTR_ID_VOLUME: val &= 0x7f; h->volume = val | (val << 8); if (-1 == ioctl(h->mix,MIXER_WRITE(h->volctl),&h->volume)) perror("oss mixer write volume"); h->muted = 0; break; case ATTR_ID_MUTE: h->muted = val; if (h->muted) { int zero = 0; if (-1 == ioctl(h->mix,MIXER_READ(h->volctl),&h->volume)) perror("oss mixer read volume"); if (-1 == ioctl(h->mix,MIXER_WRITE(h->volctl),&zero)) perror("oss mixer write volume"); } else { if (-1 == ioctl(h->mix,MIXER_WRITE(h->volctl),&h->volume)) perror("oss mixer write volume"); } break; } } static struct ng_devinfo* mixer_probe(void) { struct ng_devinfo *info = NULL; int i,n,fd; #ifdef SOUND_MIXER_INFO mixer_info minfo; #endif n = 0; for (i = 0; NULL != ng_dev.mixer_scan[i]; i++) { fd = open(ng_dev.mixer_scan[i],O_RDONLY); if (-1 == fd) continue; info = realloc(info,sizeof(*info) * (n+2)); memset(info+n,0,sizeof(*info)*2); strcpy(info[n].device,ng_dev.mixer_scan[i]); #ifdef SOUND_MIXER_INFO ioctl(fd,SOUND_MIXER_INFO,&minfo); strcpy(info[n].name,minfo.name); #else strcpy(info[n].name,ng_dev.mixer_scan[i]); #endif close(fd); n++; } return info; } static struct ng_devinfo* mixer_channels(char *device) { struct ng_devinfo *info = NULL; static char *names[] = SOUND_DEVICE_NAMES; static char *labels[] = SOUND_DEVICE_LABELS; int fd,i,n,devmask; if (-1 == (fd = open(device,O_RDONLY))) { fprintf(stderr,"open %s: %s\n",device,strerror(errno)); return NULL; } n = 0; ioctl(fd,MIXER_READ(SOUND_MIXER_DEVMASK),&devmask); for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { if (!((1<fmtid]) return -1; h->afmt = afmt_to_oss[fmt->fmtid]; h->channels = ng_afmt_to_channels[fmt->fmtid]; frag = 0x7fff000c; /* 4k */ /* format */ ioctl(h->fd, SNDCTL_DSP_SETFMT, &h->afmt); if (h->afmt != afmt_to_oss[fmt->fmtid]) { if (ng_debug) fprintf(stderr,"oss: SNDCTL_DSP_SETFMT(%d): %s\n", afmt_to_oss[fmt->fmtid],strerror(errno)); goto err; } /* channels */ ioctl(h->fd, SNDCTL_DSP_CHANNELS, &h->channels); if (h->channels != ng_afmt_to_channels[fmt->fmtid]) { if (ng_debug) fprintf(stderr,"oss: SNDCTL_DSP_CHANNELS(%d): %s\n", ng_afmt_to_channels[fmt->fmtid],strerror(errno)); goto err; } /* sample rate */ h->rate = fmt->rate; ioctl(h->fd, SNDCTL_DSP_SPEED, &h->rate); ioctl(h->fd, SNDCTL_DSP_SETFRAGMENT, &frag); if (h->rate != fmt->rate) { fprintf(stderr, "oss: warning: got sample rate %d (asked for %d)\n", h->rate,fmt->rate); if (h->rate < fmt->rate * 1001 / 1000 && h->rate > fmt->rate * 999 / 1000) { /* ignore very small differences ... */ h->rate = fmt->rate; } } if (-1 == ioctl(h->fd, SNDCTL_DSP_GETBLKSIZE, &h->blocksize)) { if (ng_debug) perror("SNDCTL_DSP_GETBLKSIZE"); goto err; } if (0 == h->blocksize) /* dmasound bug compatibility */ h->blocksize = 4096; if (ng_debug) fprintf(stderr,"oss: bs=%d rate=%d channels=%d bits=%d (%s)\n", h->blocksize,h->rate, ng_afmt_to_channels[fmt->fmtid], ng_afmt_to_bits[fmt->fmtid], ng_afmt_to_desc[fmt->fmtid]); return 0; err: if (ng_debug) fprintf(stderr,"oss: sound format not supported [%s]\n", ng_afmt_to_desc[fmt->fmtid]); return -1; } static void* oss_open(char *device, struct ng_audio_fmt *fmt, int record) { struct oss_handle *h; struct ng_audio_fmt ifmt; h = malloc(sizeof(*h)); if (NULL == h) return NULL; memset(h,0,sizeof(*h)); if (-1 == (h->fd = open(device ? device : ng_dev.dsp, record ? O_RDONLY : O_WRONLY | O_NONBLOCK))) { fprintf(stderr,"oss: open %s: %s\n", device ? device : ng_dev.dsp, strerror(errno)); goto err; } fcntl(h->fd,F_SETFD,FD_CLOEXEC); if (0 == oss_setformat(h,fmt)) { /* fine, native format works */ fmt->rate = h->rate; h->ifmt = *fmt; h->ofmt = *fmt; h->bytes_per_sec = ng_afmt_to_bits[h->ifmt.fmtid] * ng_afmt_to_channels[h->ifmt.fmtid] * h->ifmt.rate / 8; return h; } /* try byteswapping */ ifmt = *fmt; switch (fmt->fmtid) { case AUDIO_S16_LE_MONO: ifmt.fmtid = AUDIO_S16_BE_MONO; break; case AUDIO_S16_LE_STEREO: ifmt.fmtid = AUDIO_S16_BE_STEREO; break; case AUDIO_S16_BE_MONO: ifmt.fmtid = AUDIO_S16_LE_MONO; break; case AUDIO_S16_BE_STEREO: ifmt.fmtid = AUDIO_S16_LE_STEREO; break; } if (0 == oss_setformat(h,&ifmt)) { if (ng_debug) fprintf(stderr,"oss: byteswapping pcm data\n"); h->byteswap = 1; ifmt.rate = h->rate; fmt->rate = h->rate; h->ifmt = ifmt; h->ofmt = *fmt; h->bytes_per_sec = ng_afmt_to_bits[h->ifmt.fmtid] * ng_afmt_to_channels[h->ifmt.fmtid] * h->ifmt.rate / 8; return h; } fprintf(stderr,"oss: can't use format %s\n", ng_afmt_to_desc[fmt->fmtid]); err: fmt->rate = 0; fmt->fmtid = AUDIO_NONE; if (h->fd) close(h->fd); free(h); return NULL; } static int oss_startrec(void *handle) { struct oss_handle *h = handle; int trigger; if (ng_debug) fprintf(stderr,"oss: startrec\n"); trigger = 0; ioctl(h->fd,SNDCTL_DSP_SETTRIGGER,&trigger); #if 1 /* * Try to clear the sound driver buffers. IMHO this shouldn't * be needed, but looks like it is with some drivers ... */ { int oflags,flags,rc; unsigned char buf[4096]; oflags = fcntl(h->fd,F_GETFL); flags = oflags | O_NONBLOCK; fcntl(h->fd,F_SETFL,flags); for (;;) { rc = read(h->fd,buf,sizeof(buf)); if (ng_debug) fprintf(stderr,"oss: clearbuf rc=%d errno=%s\n",rc,strerror(errno)); if (rc != sizeof(buf)) break; } fcntl(h->fd,F_SETFL,oflags); } #endif trigger = PCM_ENABLE_INPUT; ioctl(h->fd,SNDCTL_DSP_SETTRIGGER,&trigger); return 0; } static void oss_bufread(int fd,char *buffer,int blocksize) { int rc,count=0; /* why FreeBSD returns chunks smaller than blocksize? */ for (;;) { rc = read(fd,buffer+count,blocksize-count); if (rc < 0) { if ((EINTR == errno) || (EAGAIN == errno)) continue; perror("oss: read"); exit(1); } count += rc; if (count == blocksize) return; } fprintf(stderr,"#"); } static void oss_bufswap(void *ptr, int size) { unsigned short *buf = ptr; int i; size = size >> 1; for (i = 0; i < size; i++) buf[i] = ((buf[i] >> 8) & 0xff) | ((buf[i] << 8) & 0xff00); } static struct ng_audio_buf* oss_read(void *handle, int64_t stopby) { struct oss_handle *h = handle; struct ng_audio_buf* buf; int bytes; if (stopby) { bytes = stopby * h->bytes_per_sec / 1000000000 - h->bytes; if (ng_debug) fprintf(stderr,"oss: left: %d bytes (%.3fs)\n", bytes,(float)bytes/h->bytes_per_sec); if (bytes <= 0) return NULL; bytes = (bytes + 3) & ~3; if (bytes > (int)h->blocksize) bytes = h->blocksize; } else { bytes = h->blocksize; } buf = ng_malloc_audio_buf(&h->ofmt,bytes); oss_bufread(h->fd,buf->data,bytes); if (h->byteswap) oss_bufswap(buf->data,bytes); h->bytes += bytes; buf->info.ts = (long long)h->bytes * 1000000000 / h->bytes_per_sec; return buf; } static struct ng_audio_buf* oss_write(void *handle, struct ng_audio_buf *buf) { struct oss_handle *h = handle; int rc; if (0 == buf->written && h->byteswap) oss_bufswap(buf->data,buf->size); rc = write(h->fd, buf->data+buf->written, buf->size-buf->written); switch (rc) { case -1: perror("write dsp"); free(buf); buf = NULL; case 0: fprintf(stderr,"write dsp: Huh? no data written?\n"); free(buf); buf = NULL; default: buf->written += rc; if (buf->written == buf->size) { free(buf); buf = NULL; } } return buf; } static int64_t oss_latency(void *handle) { struct oss_handle *h = handle; audio_buf_info info; int bytes,samples; long long latency; if (-1 == ioctl(h->fd, SNDCTL_DSP_GETOSPACE, &info)) return 0; bytes = info.fragsize * info.fragstotal; samples = bytes * 8 / ng_afmt_to_bits[h->ifmt.fmtid] / h->channels; latency = (long long)samples * 1000000000 / h->rate; if (ng_debug) fprintf(stderr,"oss: bytes: %d / samples: %d => latency: %lld\n", bytes,samples,latency); return latency; } static int oss_fd(void *handle) { struct oss_handle *h = handle; return h->fd; } static void oss_close(void *handle) { struct oss_handle *h = handle; close(h->fd); free(h); } /* ------------------------------------------------------------------- */ static struct ng_dsp_driver oss_dsp = { .name = "oss", .open = oss_open, .close = oss_close, .fd = oss_fd, .startrec = oss_startrec, .read = oss_read, .write = oss_write, .latency = oss_latency, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_dsp_driver_register(NG_PLUGIN_MAGIC,__FILE__,&oss_dsp); ng_mix_driver_register(NG_PLUGIN_MAGIC,__FILE__,&oss_mixer); } xawtv-3.106/libng/plugins/write-avi.c000066400000000000000000000361751343350355000175400ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include "riff.h" #include "grab-ng.h" #if 0 /* debugging */ # define LIMIT_OPENDML (1024*1024) #else # define LIMIT_OPENDML (2000*1024*1024) #endif /* * M$ vidcap avi video+audio layout * * riff avi * list hdrl header * avih avi header * list strl video stream header * strh * strf * list strl audio stream header * strh * strf * istf ??? software * idit ??? timestamp * yunk ??? 4k page pad * list movi data * 00db video data * yunk ??? 4k page pad * [ ... ] * 01wb audio data * [ ... ] * idx1 video frame index * */ /* ----------------------------------------------------------------------- */ #define TRAP(txt) fprintf(stderr,"%s:%d:%s\n",__FILE__,__LINE__,txt);exit(1); #define size_strl_vids (sizeof(struct RIFF_strh) + \ sizeof(struct RIFF_strf_vids) + \ 4*5) #define size_strl_auds (sizeof(struct RIFF_strh) + \ sizeof(struct RIFF_strf_auds) + \ 4*5) static const struct AVI_HDR avi_hdr = { {'R','I','F','F'}, 0, {'A','V','I',' '}, {'L','I','S','T'}, 0, {'h','d','r','l'}, {'a','v','i','h'}, AVI_SWAP4(sizeof(struct RIFF_avih)), {} }; static const struct AVIX_HDR avix_hdr = { {'R','I','F','F'}, 0, {'A','V','I','X'}, {'L','I','S','T'}, 0, {'m','o','v','i'}, }; static const struct AVI_HDR_VIDEO avi_hdr_video = { {'L','I','S','T'}, AVI_SWAP4(size_strl_vids), {'s','t','r','l'}, {'s','t','r','h'}, AVI_SWAP4(sizeof(struct RIFF_strh)), {{'v','i','d','s'}}, {'s','t','r','f'}, AVI_SWAP4(sizeof(struct RIFF_strf_vids)), {} }; static const struct AVI_HDR_AUDIO avi_hdr_audio = { {'L','I','S','T'}, AVI_SWAP4(size_strl_auds), {'s','t','r','l'}, {'s','t','r','h'}, AVI_SWAP4(sizeof(struct RIFF_strh)), {{'a','u','d','s'}}, {'s','t','r','f'}, AVI_SWAP4(sizeof(struct RIFF_strf_auds)), {} }; static const struct AVI_HDR_ODML avi_hdr_odml = { {'L','I','S','T'}, AVI_SWAP4(sizeof(uint32_t) + 4*3), {'o','d','m','l'}, {'d','m','l','h'}, AVI_SWAP4(sizeof(uint32_t)), }; static const struct AVI_DATA avi_data = { {'L','I','S','T'}, 0, {'m','o','v','i'}, }; static const struct CHUNK_HDR frame_hdr = { {'0','0','d','b'}, 0 }; static const struct CHUNK_HDR sound_hdr = { {'0','1','w','b'}, 0 }; static const struct CHUNK_HDR idx_hdr = { {'i','d','x','1'}, 0 }; /* ----------------------------------------------------------------------- */ struct avi_video_priv { const char handler[4]; const char compress[4]; const int bytesperpixel; }; struct avi_handle { /* file name+handle */ char file[MAXPATHLEN]; int fd; struct iovec *vec; /* format */ struct ng_video_fmt video; struct ng_audio_fmt audio; /* headers */ struct AVI_HDR avi_hdr; struct AVIX_HDR avix_hdr; struct AVI_HDR_ODML avi_hdr_odml; struct AVI_HDR_AUDIO avi_hdr_audio; struct AVI_HDR_VIDEO avi_hdr_video; struct AVI_DATA avi_data; struct CHUNK_HDR frame_hdr; struct CHUNK_HDR sound_hdr; struct CHUNK_HDR idx_hdr; /* statistics -- first chunk */ int frames; off_t hdr_size; off_t audio_size; off_t data_size; /* statistics -- current chunk */ int bigfile; int framesx; off_t avix_start; off_t datax_size; /* statistics -- total */ int frames_total; /* frame index */ struct IDX_RECORD *idx_array; int idx_index, idx_count; off_t idx_offset; off_t idx_size; }; /* ----------------------------------------------------------------------- */ /* idx1 frame index */ static void avi_addindex(struct avi_handle *h, char *fourcc,int flags,int chunksize) { if (h->idx_index == h->idx_count) { h->idx_count += 256; h->idx_array = realloc(h->idx_array,h->idx_count*sizeof(struct IDX_RECORD)); } memcpy(h->idx_array[h->idx_index].id,fourcc,4); h->idx_array[h->idx_index].flags=AVI_SWAP4(flags); h->idx_array[h->idx_index].offset=AVI_SWAP4(h->idx_offset-h->hdr_size-8); h->idx_array[h->idx_index].size=AVI_SWAP4(chunksize); h->idx_index++; h->idx_offset += chunksize + sizeof(struct CHUNK_HDR); } static void avi_writeindex(struct avi_handle *h) { /* write frame index */ h->idx_hdr.size = AVI_SWAP4(h->idx_index * sizeof(struct IDX_RECORD)); write(h->fd,&h->idx_hdr,sizeof(struct CHUNK_HDR)); write(h->fd,h->idx_array,h->idx_index*sizeof(struct IDX_RECORD)); h->idx_size += h->idx_index * sizeof(struct IDX_RECORD) + sizeof(struct CHUNK_HDR); /* update header */ h->avi_hdr.avih.flags |= AVI_SWAP4(AVIF_HASINDEX); } static void avi_bigfile(struct avi_handle *h, int last) { off_t avix_end; if (h->bigfile) { /* finish this chunk */ avix_end = lseek(h->fd,0,SEEK_CUR); lseek(h->fd,h->avix_start,SEEK_SET); h->avix_hdr.riff_size = h->datax_size + 4*4; h->avix_hdr.data_size = h->datax_size + 4; write(h->fd,&h->avix_hdr,sizeof(struct AVIX_HDR)); lseek(h->fd,avix_end,SEEK_SET); h->avix_start = avix_end; } else { h->avix_start = lseek(h->fd,0,SEEK_CUR); } if (last) return; h->bigfile++; h->framesx = 0; h->datax_size = 0; write(h->fd,&h->avix_hdr,sizeof(struct AVIX_HDR)); if (ng_debug) fprintf(stderr,"avi bigfile #%d\n",h->bigfile); } /* ----------------------------------------------------------------------- */ static void avi_write_header(struct avi_handle *h) { off_t curpos; /* fill in some statistic values ... */ h->avi_hdr.riff_size = AVI_SWAP4(h->hdr_size+h->data_size+h->idx_size); h->avi_hdr.hdrl_size = AVI_SWAP4(h->hdr_size - 4*5); h->avi_hdr.avih.frames = AVI_SWAP4(h->frames); if (h->video.fmtid != VIDEO_NONE) h->avi_hdr_video.strh.length = AVI_SWAP4(h->frames); if (h->audio.fmtid != AUDIO_NONE) h->avi_hdr_audio.strh.length = AVI_SWAP4(h->audio_size/h->avi_hdr_audio.strh.scale); h->avi_data.data_size = AVI_SWAP4(h->data_size); /* ... and write header again */ curpos = lseek(h->fd,0,SEEK_CUR); lseek(h->fd,0,SEEK_SET); write(h->fd,&h->avi_hdr,sizeof(struct AVI_HDR)); if (h->video.fmtid != VIDEO_NONE) write(h->fd,&h->avi_hdr_video,sizeof(struct AVI_HDR_VIDEO)); if (h->audio.fmtid != AUDIO_NONE) write(h->fd,&h->avi_hdr_audio,sizeof(struct AVI_HDR_AUDIO)); if (h->video.fmtid != VIDEO_NONE) { h->avi_hdr_odml.total_frames = h->frames_total; write(h->fd,&h->avi_hdr_odml,sizeof(struct AVI_HDR_ODML)); } write(h->fd,&h->avi_data,sizeof(struct AVI_DATA)); lseek(h->fd,curpos,SEEK_SET); } static void* avi_open(char *filename, char *dummy, struct ng_video_fmt *video, const void *priv_video, int fps, struct ng_audio_fmt *audio, const void *priv_audio) { const struct avi_video_priv *pvideo = priv_video; struct avi_handle *h; int i,frame_bytes,depth,streams,rate,us_frame; if (NULL == (h = malloc(sizeof(*h)))) return NULL; if (NULL == filename) return NULL; /* init */ memset(h,0,sizeof(*h)); h->video = *video; h->audio = *audio; h->avi_hdr = avi_hdr; h->avix_hdr = avix_hdr; h->avi_hdr_odml = avi_hdr_odml; h->avi_hdr_video = avi_hdr_video; h->avi_hdr_audio = avi_hdr_audio; h->avi_data = avi_data; h->frame_hdr = frame_hdr; h->sound_hdr = sound_hdr; h->idx_hdr = idx_hdr; h->vec = malloc(sizeof(struct iovec) * video->height); strcpy(h->file,filename); if (-1 == (h->fd = open(h->file,O_CREAT | O_RDWR | O_TRUNC, 0666))) { fprintf(stderr,"open %s: %s\n",h->file,strerror(errno)); free(h); return NULL; } /* general */ streams = 0; rate = 0; if (h->video.fmtid != VIDEO_NONE) { streams++; rate += pvideo->bytesperpixel * fps / 1000; h->avi_hdr.avih.width = AVI_SWAP4(h->video.width); h->avi_hdr.avih.height = AVI_SWAP4(h->video.height); } if (h->audio.fmtid != AUDIO_NONE) { streams++; rate += ng_afmt_to_channels[h->audio.fmtid] * ng_afmt_to_bits[h->audio.fmtid] * h->audio.rate / 8; } us_frame = (long long)1000000000/fps; h->avi_hdr.avih.us_frame = AVI_SWAP4(us_frame); h->avi_hdr.avih.bps = AVI_SWAP4(rate); h->avi_hdr.avih.streams = AVI_SWAP4(streams); h->hdr_size += write(h->fd,&h->avi_hdr,sizeof(struct AVI_HDR)); /* video */ if (h->video.fmtid != VIDEO_NONE) { for (i = 0; i < 4; i++) { h->avi_hdr_video.strh.handler[i] = pvideo->handler[i]; h->avi_hdr_video.strf.compression[i] = pvideo->compress[i]; } frame_bytes = pvideo->bytesperpixel * h->video.width * h->video.height; depth = ng_vfmt_to_depth[h->video.fmtid]; h->frame_hdr.size = AVI_SWAP4(frame_bytes); h->avi_hdr_video.strh.scale = AVI_SWAP4(us_frame); h->avi_hdr_video.strh.rate = AVI_SWAP4(1000000); h->avi_hdr_video.strf.size = AVI_SWAP4(sizeof(avi_hdr_video.strf)); h->avi_hdr_video.strf.width = AVI_SWAP4(h->video.width); h->avi_hdr_video.strf.height = AVI_SWAP4(h->video.height); h->avi_hdr_video.strf.planes = AVI_SWAP2(1); h->avi_hdr_video.strf.bit_cnt = AVI_SWAP2(depth ? depth : 24); h->avi_hdr_video.strf.image_size = AVI_SWAP4(frame_bytes); h->hdr_size += write(h->fd,&h->avi_hdr_video,sizeof(struct AVI_HDR_VIDEO)); } /* audio */ if (h->audio.fmtid != AUDIO_NONE) { h->avi_hdr_audio.strh.scale = AVI_SWAP4(ng_afmt_to_channels[h->audio.fmtid] * ng_afmt_to_bits[h->audio.fmtid] / 8); h->avi_hdr_audio.strh.rate = AVI_SWAP4(ng_afmt_to_channels[h->audio.fmtid] * ng_afmt_to_bits[h->audio.fmtid] * h->audio.rate / 8); h->avi_hdr_audio.strh.samplesize = AVI_SWAP4(ng_afmt_to_channels[h->audio.fmtid] * ng_afmt_to_bits[h->audio.fmtid] / 8); h->avi_hdr_audio.strf.format = AVI_SWAP2(WAVE_FORMAT_PCM); h->avi_hdr_audio.strf.channels = AVI_SWAP2(ng_afmt_to_channels[h->audio.fmtid]); h->avi_hdr_audio.strf.rate = AVI_SWAP4(h->audio.rate); h->avi_hdr_audio.strf.av_bps = AVI_SWAP4(ng_afmt_to_channels[h->audio.fmtid] * ng_afmt_to_bits[h->audio.fmtid] * h->audio.rate / 8); h->avi_hdr_audio.strf.blockalign = AVI_SWAP2(ng_afmt_to_channels[h->audio.fmtid] * ng_afmt_to_bits[h->audio.fmtid] / 8); h->avi_hdr_audio.strf.size = AVI_SWAP2(ng_afmt_to_bits[h->audio.fmtid]); h->hdr_size += write(h->fd,&h->avi_hdr_audio, sizeof(struct AVI_HDR_AUDIO)); } if (h->video.fmtid != VIDEO_NONE) h->hdr_size += write(h->fd,&h->avi_hdr_odml,sizeof(struct AVI_HDR_ODML)); /* data */ if (-1 == write(h->fd,&h->avi_data,sizeof(struct AVI_DATA))) { fprintf(stderr,"write %s: %s\n",h->file,strerror(errno)); free(h); return NULL; } h->data_size = 4; /* list type */ h->idx_index = 0; h->idx_offset = h->hdr_size + sizeof(struct AVI_DATA); avi_write_header(h); return h; } static int avi_video(void *handle, struct ng_video_buf *buf) { struct avi_handle *h = handle; struct iovec *line; int y,bpl,size=0; size = (buf->size + 3) & ~3; h->frame_hdr.size = AVI_SWAP4(size); if (-1 == write(h->fd,&h->frame_hdr,sizeof(struct CHUNK_HDR))) { fprintf(stderr,"write %s: %s\n",h->file,strerror(errno)); return -1; } switch (h->video.fmtid) { case VIDEO_RGB15_LE: case VIDEO_BGR24: bpl = h->video.width * ng_vfmt_to_depth[h->video.fmtid] / 8; for (line = h->vec, y = h->video.height-1; y >= 0; line++, y--) { line->iov_base = ((unsigned char*)buf->data) + y * bpl; line->iov_len = bpl; } if (-1 == writev(h->fd,h->vec,h->video.height)) { fprintf(stderr,"writev %s: %s\n",h->file,strerror(errno)); return -1; } break; case VIDEO_MJPEG: case VIDEO_JPEG: if (-1 == write(h->fd,buf->data,size)) { fprintf(stderr,"write %s: %s\n",h->file,strerror(errno)); return -1; } break; } h->frames_total += 1; if (!h->bigfile) { avi_addindex(h,h->frame_hdr.id,0x12,size); h->data_size += size + sizeof(struct CHUNK_HDR); h->frames += 1; } else { h->datax_size += size + sizeof(struct CHUNK_HDR); h->framesx += 1; } if ((h->bigfile ? h->datax_size : h->data_size) > LIMIT_OPENDML) avi_bigfile(h,0); return 0; } static int avi_audio(void *handle, struct ng_audio_buf *buf) { struct avi_handle *h = handle; h->sound_hdr.size = AVI_SWAP4(buf->size); if (-1 == write(h->fd,&h->sound_hdr,sizeof(struct CHUNK_HDR))) { fprintf(stderr,"write %s: %s\n",h->file,strerror(errno)); return -1; } if (-1 == write(h->fd,buf->data,buf->size)) { fprintf(stderr,"write %s: %s\n",h->file,strerror(errno)); return -1; } if (!h->bigfile) { avi_addindex(h,h->sound_hdr.id,0x0,buf->size); h->data_size += buf->size + sizeof(struct CHUNK_HDR); h->audio_size += buf->size; } else { h->datax_size += buf->size + sizeof(struct CHUNK_HDR); } return 0; } static int avi_close(void *handle) { struct avi_handle *h = handle; /* write frame index */ if (h->video.fmtid != VIDEO_NONE) { if (!h->bigfile) { avi_writeindex(h); } else { avi_bigfile(h,1); h->idx_size = 0; } } avi_write_header(h); close(h->fd); free(h->vec); free(h); return 0; } /* ----------------------------------------------------------------------- */ /* data structures describing our capabilities */ static struct avi_video_priv avi_rgb15 = { .bytesperpixel = 2, }; static struct avi_video_priv avi_rgb24 = { .bytesperpixel = 3, }; static struct avi_video_priv avi_mjpeg = { .handler = {'M','J','P','G'}, .compress = {'M','J','P','G'}, .bytesperpixel = 3, }; static const struct ng_format_list avi_vformats[] = { { .name = "rgb15", .ext = "avi", .fmtid = VIDEO_RGB15_LE, .priv = &avi_rgb15, },{ .name = "rgb24", .ext = "avi", .fmtid = VIDEO_BGR24, .priv = &avi_rgb24, },{ .name = "mjpeg", .ext = "avi", .fmtid = VIDEO_MJPEG, .priv = &avi_mjpeg, },{ .name = "jpeg", .ext = "avi", .fmtid = VIDEO_JPEG, .priv = &avi_mjpeg, },{ /* EOF */ } }; static const struct ng_format_list avi_aformats[] = { { .name = "mono8", .ext = "avi", .fmtid = AUDIO_U8_MONO, },{ .name = "mono16", .ext = "avi", .fmtid = AUDIO_S16_LE_MONO, },{ .name = "stereo", .ext = "avi", .fmtid = AUDIO_S16_LE_STEREO, },{ /* EOF */ } }; struct ng_writer avi_writer = { .name = "avi", .desc = "Microsoft AVI (RIFF) format", .combined = 1, .video = avi_vformats, .audio = avi_aformats, .wr_open = avi_open, .wr_video = avi_video, .wr_audio = avi_audio, .wr_close = avi_close, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { ng_writer_register(NG_PLUGIN_MAGIC,__FILE__,&avi_writer); } xawtv-3.106/libng/plugins/write-dv.c000066400000000000000000000115041343350355000173570ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include "grab-ng.h" #include "list.h" /* ----------------------------------------------------------------------- */ struct dv_frame { struct list_head list; int seq; int video,audio; unsigned char obuf[0]; }; struct dv_handle { /* handles */ int fd; dv_encoder_t *enc; /* format */ struct ng_video_fmt video; struct ng_audio_fmt audio; /* misc */ int framesize, fvideo, faudio; struct list_head frames; }; /* ----------------------------------------------------------------------- */ static struct dv_frame* dv_get_frame(struct dv_handle *h, int nr) { struct dv_frame *frame = NULL; struct list_head *item; list_for_each(item,&h->frames) { frame = list_entry(item,struct dv_frame,list); if (frame->seq == nr) break; } if (NULL == frame || frame->seq != nr) { frame = malloc(sizeof(*frame) + h->framesize); memset(frame,0,sizeof(*frame) + h->framesize); frame->seq = nr; list_add_tail(&frame->list,&h->frames); } return frame; } static int dv_put_frame(struct dv_handle *h, struct dv_frame *frame) { int rc; if (h->video.fmtid && !frame->video) return 0; if (h->audio.fmtid && !frame->audio) return 0; if (ng_debug) fprintf(stderr,"dv: write frame #%d\n",frame->seq); rc = write(h->fd, frame->obuf, h->framesize); list_del(&frame->list); free(frame); return (rc == h->framesize) ? 0 : -1; } /* ----------------------------------------------------------------------- */ static void* dv_open(char *filename, char *dummy, struct ng_video_fmt *video, const void *priv_video, int fps, struct ng_audio_fmt *audio, const void *priv_audio) { struct dv_handle *h; if (NULL == (h = malloc(sizeof(*h)))) return NULL; memset(h,0,sizeof(*h)); h->video = *video; h->audio = *audio; if (-1 == (h->fd = open(filename,O_CREAT | O_RDWR | O_TRUNC, 0666))) { fprintf(stderr,"open %s: %s\n",filename,strerror(errno)); goto fail; } h->enc = dv_encoder_new(0,0,0); if (NULL == h->enc) { fprintf(stderr,"dv: dv_encoder_new failed\n"); goto fail; } if (h->audio.fmtid != AUDIO_NONE) { } if (h->video.fmtid != VIDEO_NONE) { if (720 == h->video.width && 480 == h->video.height && 30000 == fps) { /* NTSC */ h->enc->isPAL = 0; h->framesize = 120000; } else if (720 == h->video.width && 576 == h->video.height && 25000 == fps) { /* PAL */ h->enc->isPAL = 1; h->framesize = 144000; } else { fprintf(stderr, "dv: %dx%d @ %d fps is not allowed for digital video\n" "dv: use 720x480/30 (NTSC) or 720x576/25 (PAL)\n", h->video.width, h->video.height, fps/1000); goto fail; } } INIT_LIST_HEAD(&h->frames); return h; fail: if (h->enc) dv_encoder_free(h->enc); if (-1 != h->fd) close(h->fd); free(h); return NULL; } static int dv_video(void *handle, struct ng_video_buf *buf) { struct dv_handle *h = handle; struct dv_frame *frame; unsigned char *pixels[3]; frame = dv_get_frame(h,h->fvideo); pixels[0] = buf->data; switch (buf->fmt.fmtid) { case VIDEO_YUYV: dv_encode_full_frame(h->enc,pixels,e_dv_color_yuv,frame->obuf); break; case VIDEO_RGB24: dv_encode_full_frame(h->enc,pixels,e_dv_color_rgb,frame->obuf); break; case VIDEO_BGR32: dv_encode_full_frame(h->enc,pixels,e_dv_color_bgr0,frame->obuf); break; default: BUG_ON(1,"unknown fmtid"); } frame->video = 1; dv_put_frame(h,frame); h->fvideo++; return 0; } static int dv_audio(void *handle, struct ng_audio_buf *buf) { //struct dv_handle *h = handle; //struct dv_frame *frame; return -1; } static int dv_close(void *handle) { struct dv_handle *h = handle; dv_encoder_free(h->enc); close(h->fd); free(h); return 0; } /* ----------------------------------------------------------------------- */ static const struct ng_format_list dv_vformats[] = { { .name = "dv", .ext = "dv", .desc = "digital video", .fmtid = VIDEO_YUYV, },{ /* EOF */ } }; #if 0 static const struct ng_format_list dv_aformats[] = { { .name = "stereo16", .ext = "dv", .fmtid = AUDIO_S16_NATIVE_STEREO, },{ /* EOF */ } }; #endif struct ng_writer dv_writer = { .name = "dv", .desc = "Digital Video", //.combined = 1, .video = dv_vformats, //.audio = dv_aformats, .wr_open = dv_open, .wr_video = dv_video, .wr_audio = dv_audio, .wr_close = dv_close, }; extern void ng_plugin_init(void); void ng_plugin_init(void) { //ng_writer_register(NG_PLUGIN_MAGIC,__FILE__,&dv_writer); } xawtv-3.106/libng/plugins/write-qt.c000066400000000000000000000270501343350355000173750ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #pragma GCC diagnostic ignored "-Wstrict-prototypes" #include #include #pragma GCC diagnostic warning "-Wstrict-prototypes" #include "grab-ng.h" /* ----------------------------------------------------------------------- */ struct qt_video_priv { char fcc[5]; int yuvsign; int libencode; int cmodel; }; struct qt_audio_priv { char fcc[5]; int libencode; }; struct qt_handle { /* libquicktime handle */ quicktime_t *fh; /* format */ struct ng_video_fmt video; struct ng_audio_fmt audio; /* misc */ int lib_video; int lib_audio; int yuvsign; int audio_sample; unsigned char **rows; unsigned char *data; }; /* ----------------------------------------------------------------------- */ static void* qt_open(char *filename, char *dummy, struct ng_video_fmt *video, const void *priv_video, int fps, struct ng_audio_fmt *audio, const void *priv_audio) { const struct qt_video_priv *pvideo = priv_video; const struct qt_audio_priv *paudio = priv_audio; struct qt_handle *h; if (NULL == (h = malloc(sizeof(*h)))) return NULL; memset(h,0,sizeof(*h)); h->video = *video; h->audio = *audio; if (h->video.fmtid != VIDEO_NONE) { h->lib_video = pvideo->libencode; h->yuvsign = pvideo->yuvsign; } if (h->audio.fmtid != AUDIO_NONE) h->lib_audio = paudio->libencode; if (NULL == (h->fh = quicktime_open(filename,0,1))) { fprintf(stderr,"quicktime_open failed (%s)\n",filename); goto fail; } if (h->lib_video) if (NULL == (h->rows = malloc(h->video.height * sizeof(char*)))) goto fail; if (h->yuvsign) if (NULL == (h->data = malloc(h->video.height * h->video.width * 2))) goto fail; if (h->audio.fmtid != AUDIO_NONE) { quicktime_set_audio(h->fh, ng_afmt_to_channels[h->audio.fmtid], h->audio.rate, ng_afmt_to_bits[h->audio.fmtid], (char*)paudio->fcc); h->audio_sample = ng_afmt_to_channels[h->audio.fmtid] * ng_afmt_to_bits[h->audio.fmtid] / 8; if (h->lib_audio) { if (!quicktime_supported_audio(h->fh, 0)) { fprintf(stderr,"libquicktime: audio codec not supported\n"); goto fail; } } } if (h->video.fmtid != VIDEO_NONE) { quicktime_set_video(h->fh,1,h->video.width,h->video.height, (float)fps/1000,(char*)pvideo->fcc); if (h->lib_video) { quicktime_set_cmodel(h->fh,pvideo->cmodel); if (!quicktime_supported_video(h->fh, 0)) { fprintf(stderr,"libquicktime: video codec not supported\n"); goto fail; } } } quicktime_set_info(h->fh, "Dumme Bemerkungen gibt's hier umsonst."); return h; fail: if (h->rows) free(h->rows); if (h->data) free(h->data); free(h); return NULL; } static int qt_video(void *handle, struct ng_video_buf *buf) { struct qt_handle *h = handle; unsigned int *src,*dest; int rc,i,n; if (h->lib_video) { unsigned int row,len; char *line; /* QuickTime library expects an array of pointers to image rows (RGB) */ len = h->video.width * 3; for (row = 0, line = buf->data; row < h->video.height; row++, line += len) h->rows[row] = line; rc = quicktime_encode_video(h->fh, h->rows, 0); } else if (h->yuvsign) { dest = (unsigned int *)h->data; src = (unsigned int *)buf->data; n = buf->size / 4; /* U V values are signed but Y R G B values are unsigned. */ for (i = 0; i < n; i++) { #if BYTE_ORDER == BIG_ENDIAN *(dest++) = *(src++) ^ 0x00800080; #else *(dest++) = *(src++) ^ 0x80008000; #endif } rc = quicktime_write_frame(h->fh, h->data, buf->size, 0); } else { rc = quicktime_write_frame(h->fh, buf->data, buf->size, 0); } return rc; } static int qt_audio(void *handle, struct ng_audio_buf *buf) { struct qt_handle *h = handle; int16_t *ch[2]; if (h->lib_audio) { /* FIXME: works for one channel (mono) only */ ch[0] = (int16_t*)buf->data; return quicktime_encode_audio(h->fh, ch, NULL, buf->size / h->audio_sample); } else { return quicktime_write_audio(h->fh, buf->data, buf->size / h->audio_sample, 0); } } static int qt_close(void *handle) { struct qt_handle *h = handle; quicktime_close(h->fh); if (h->rows) free(h->rows); if (h->data) free(h->data); free(h); return 0; } /* ----------------------------------------------------------------------- */ static int cmodels[] = { [BC_BGR888] = VIDEO_BGR24, [BC_RGB888] = VIDEO_RGB24, [BC_YUV422] = VIDEO_YUYV, [BC_YUV422P] = VIDEO_YUV422P, [BC_YUV420P] = VIDEO_YUV420P, }; static struct qt_video_priv qt_raw = { .fcc = QUICKTIME_RAW, .libencode = 0, }; static struct qt_video_priv qt_yuv2 = { .fcc = QUICKTIME_YUV2, .yuvsign = 1, .libencode = 0, }; static struct qt_video_priv qt_yv12 = { .fcc = QUICKTIME_YUV420, .libencode = 0, }; static struct qt_video_priv qt_jpeg = { .fcc = QUICKTIME_JPEG, .libencode = 0, }; static const struct ng_format_list qt_vformats[] = { { .name = "raw", .ext = "mov", .fmtid = VIDEO_RGB24, .priv = &qt_raw, },{ .name = "yuv2", .ext = "mov", .fmtid = VIDEO_YUYV, .priv = &qt_yuv2, },{ .name = "yv12", .ext = "mov", .fmtid = VIDEO_YUV420P, .priv = &qt_yv12, },{ .name = "jpeg", .ext = "mov", .fmtid = VIDEO_JPEG, .priv = &qt_jpeg, },{ /* EOF */ } }; static struct qt_audio_priv qt_mono8 = { .fcc = QUICKTIME_RAW, .libencode = 0, }; static struct qt_audio_priv qt_mono16 = { .fcc = QUICKTIME_TWOS, .libencode = 0, }; static struct qt_audio_priv qt_stereo = { .fcc = QUICKTIME_TWOS, .libencode = 0, }; static const struct ng_format_list qt_aformats[] = { { .name = "mono8", .ext = "mov", .fmtid = AUDIO_U8_MONO, .priv = &qt_mono8, },{ .name = "mono16", .ext = "mov", .fmtid = AUDIO_S16_BE_MONO, .priv = &qt_mono16, },{ .name = "stereo", .ext = "mov", .fmtid = AUDIO_S16_BE_STEREO, .priv = &qt_stereo, },{ /* EOF */ } }; struct ng_writer qt_writer = { .name = "qt", .desc = "Apple QuickTime format", .combined = 1, .video = qt_vformats, .audio = qt_aformats, .wr_open = qt_open, .wr_video = qt_video, .wr_audio = qt_audio, .wr_close = qt_close, }; /* ----------------------------------------------------------------------- */ #if 0 /* debug only */ static void dump_codecs(void) { lqt_codec_info_t **info; int i,j; info = lqt_query_registry(1, 1, 1, 1); for (i = 0; info[i] != NULL; i++) { fprintf(stderr,"lqt: %s codec: %s [%s]\n", info[i]->type == LQT_CODEC_AUDIO ? "audio" : "video", info[i]->name,info[i]->long_name); fprintf(stderr," encode: %s\n", info[i]->direction == LQT_DIRECTION_DECODE ? "no" : "yes"); fprintf(stderr," decode: %s\n", info[i]->direction == LQT_DIRECTION_ENCODE ? "no" : "yes"); for (j = 0; j < info[i]->num_fourccs; j++) fprintf(stderr," fcc : %s\n",info[i]->fourccs[j]); for (j = 0; j < info[i]->num_encoding_colormodels; j++) fprintf(stderr," cmodel: %s\n", lqt_get_colormodel_string(info[i]->encoding_colormodels[j])); fprintf(stderr,"\n"); } lqt_destroy_codec_info(info); } #endif static struct ng_format_list* qt_list_add(struct ng_format_list* list, char *name, char *desc, char *ext, int fmtid, void *priv) { int n; for (n = 0; list[n].name != NULL; n++) /* nothing */; list = realloc(list,sizeof(struct ng_format_list)*(n+2)); memset(list+n,0,sizeof(struct ng_format_list)*2); list[n].name = strdup(name); list[n].desc = strdup(desc); list[n].ext = strdup(ext); list[n].fmtid = fmtid; list[n].priv = priv; return list; } static struct ng_format_list* video_list(void) { static int debug = 0; lqt_codec_info_t **info; struct ng_format_list *video; int i,j,k,skip,fmtid; unsigned int cmodel; struct qt_video_priv *vp; /* handle video encoders */ video = malloc(sizeof(qt_vformats)); memcpy(video,qt_vformats,sizeof(qt_vformats)); info = lqt_query_registry(0, 1, 1, 0); for (i = 0; info[i] != NULL; i++) { if (debug) { fprintf(stderr,"\nlqt: %s codec: %s [%s]\n", info[i]->type == LQT_CODEC_AUDIO ? "audio" : "video", info[i]->name,info[i]->long_name); for (j = 0; j < info[i]->num_fourccs; j++) fprintf(stderr," fcc : %s\n",info[i]->fourccs[j]); for (j = 0; j < info[i]->num_encoding_colormodels; j++) fprintf(stderr," cmodel: %d [%s]\n", info[i]->encoding_colormodels[j], lqt_get_colormodel_string(info[i]->encoding_colormodels[j])); } /* sanity checks */ if (0 == info[i]->num_fourccs) { if (debug) fprintf(stderr," skipping, no fourcc\n"); continue; } /* avoid dup entries */ skip = 0; for (j = 0; video[j].name != NULL; j++) { const struct qt_video_priv *p = video[j].priv; for (k = 0; k < info[i]->num_fourccs; k++) if (0 == strcmp(p->fcc,info[i]->fourccs[k])) skip = 1; } if (skip) { if (debug) fprintf(stderr," skipping, fourcc already in list\n"); continue; } /* pick colormodel */ fmtid = VIDEO_NONE; cmodel = 0; for (j = 0; j < info[i]->num_encoding_colormodels; j++) { cmodel = info[i]->encoding_colormodels[j]; if (cmodel>= sizeof(cmodels)/sizeof(int)) continue; if (!cmodels[cmodel]) continue; fmtid = cmodels[cmodel]; break; } if (VIDEO_NONE == fmtid) { if (debug) fprintf(stderr," skipping, can't handle color model\n"); continue; } /* all fine */ if (debug) fprintf(stderr," ok, using fmtid %d [%s]\n", fmtid,ng_vfmt_to_desc[fmtid]); vp = malloc(sizeof(*vp)); memset(vp,0,sizeof(*vp)); strcpy(vp->fcc,info[i]->fourccs[0]); vp->libencode = 1; vp->cmodel = cmodel; video = qt_list_add(video,vp->fcc,info[i]->long_name,"mov",fmtid,vp); } lqt_destroy_codec_info(info); return video; } static struct ng_format_list* audio_list(void) { static int debug = 0; lqt_codec_info_t **info; struct ng_format_list *audio; int i,j; struct qt_audio_priv *ap; /* handle video encoders */ audio = malloc(sizeof(qt_aformats)); memcpy(audio,qt_aformats,sizeof(qt_aformats)); info = lqt_query_registry(1, 0, 1, 0); for (i = 0; info[i] != NULL; i++) { if (debug) { fprintf(stderr,"\nlqt: %s codec: %s [%s]\n", info[i]->type == LQT_CODEC_AUDIO ? "audio" : "video", info[i]->name,info[i]->long_name); for (j = 0; j < info[i]->num_fourccs; j++) fprintf(stderr," fcc : %s\n",info[i]->fourccs[j]); } /* sanity checks */ if (0 == info[i]->num_fourccs) { if (debug) fprintf(stderr," skipping, no fourcc\n"); continue; } /* skip uncompressed formats */ if (0 == strcmp(info[i]->fourccs[0],QUICKTIME_RAW) || 0 == strcmp(info[i]->fourccs[0],QUICKTIME_ULAW) || 0 == strcmp(info[i]->fourccs[0],QUICKTIME_IMA4) || /* ??? */ 0 == strcmp(info[i]->fourccs[0],QUICKTIME_TWOS)) { if (debug) fprintf(stderr," skipping, uncompressed\n"); continue; } /* all fine */ if (debug) fprintf(stderr," ok\n"); ap = malloc(sizeof(*ap)); memset(ap,0,sizeof(*ap)); strcpy(ap->fcc,info[i]->fourccs[0]); ap->libencode = 1; audio = qt_list_add(audio,ap->fcc,info[i]->long_name,"mov", AUDIO_S16_NATIVE_MONO,ap); } lqt_destroy_codec_info(info); return audio; } extern void ng_plugin_init(void); void ng_plugin_init(void) { qt_writer.video = video_list(); qt_writer.audio = audio_list(); ng_writer_register(NG_PLUGIN_MAGIC,__FILE__,&qt_writer); } xawtv-3.106/libng/v4l2-common.h000066400000000000000000000101211343350355000162110ustar00rootroot00000000000000/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * include/linux/v4l2-common.h * * Common V4L2 and V4L2 subdev definitions. * * Users are advised to #include this file either through videodev2.h * (V4L2) or through v4l2-subdev.h (V4L2 subdev) rather than to refer * to this file directly. * * Copyright (C) 2012 Nokia Corporation * Contact: Sakari Ailus * * 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. * * Alternatively you can redistribute this file under the terms of the * BSD license as stated below: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __V4L2_COMMON__ #define __V4L2_COMMON__ #include /* * * Selection interface definitions * */ /* Current cropping area */ #define V4L2_SEL_TGT_CROP 0x0000 /* Default cropping area */ #define V4L2_SEL_TGT_CROP_DEFAULT 0x0001 /* Cropping bounds */ #define V4L2_SEL_TGT_CROP_BOUNDS 0x0002 /* Native frame size */ #define V4L2_SEL_TGT_NATIVE_SIZE 0x0003 /* Current composing area */ #define V4L2_SEL_TGT_COMPOSE 0x0100 /* Default composing area */ #define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101 /* Composing bounds */ #define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102 /* Current composing area plus all padding pixels */ #define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103 /* Backward compatibility target definitions --- to be removed. */ #define V4L2_SEL_TGT_CROP_ACTIVE V4L2_SEL_TGT_CROP #define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE #define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL V4L2_SEL_TGT_CROP #define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL V4L2_SEL_TGT_COMPOSE #define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS V4L2_SEL_TGT_CROP_BOUNDS #define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS V4L2_SEL_TGT_COMPOSE_BOUNDS /* Selection flags */ #define V4L2_SEL_FLAG_GE (1 << 0) #define V4L2_SEL_FLAG_LE (1 << 1) #define V4L2_SEL_FLAG_KEEP_CONFIG (1 << 2) /* Backward compatibility flag definitions --- to be removed. */ #define V4L2_SUBDEV_SEL_FLAG_SIZE_GE V4L2_SEL_FLAG_GE #define V4L2_SUBDEV_SEL_FLAG_SIZE_LE V4L2_SEL_FLAG_LE #define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG V4L2_SEL_FLAG_KEEP_CONFIG struct v4l2_edid { __u32 pad; __u32 start_block; __u32 blocks; __u32 reserved[5]; __u8 *edid; }; #endif /* __V4L2_COMMON__ */ xawtv-3.106/libng/v4l2-controls.h000066400000000000000000001413761343350355000166050ustar00rootroot00000000000000/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * Video for Linux Two controls header file * * Copyright (C) 1999-2012 the contributors * * 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. * * Alternatively you can redistribute this file under the terms of the * BSD license as stated below: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The contents of this header was split off from videodev2.h. All control * definitions should be added to this header, which is included by * videodev2.h. */ #ifndef __LINUX_V4L2_CONTROLS_H #define __LINUX_V4L2_CONTROLS_H /* Control classes */ #define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ #define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ #define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ #define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator controls */ #define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */ #define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */ #define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009e0000 /* Image source controls */ #define V4L2_CTRL_CLASS_IMAGE_PROC 0x009f0000 /* Image processing controls */ #define V4L2_CTRL_CLASS_DV 0x00a00000 /* Digital Video controls */ #define V4L2_CTRL_CLASS_FM_RX 0x00a10000 /* FM Receiver controls */ #define V4L2_CTRL_CLASS_RF_TUNER 0x00a20000 /* RF tuner controls */ #define V4L2_CTRL_CLASS_DETECT 0x00a30000 /* Detection controls */ /* User-class control IDs */ #define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) #define V4L2_CID_USER_BASE V4L2_CID_BASE #define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) #define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) #define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) #define V4L2_CID_SATURATION (V4L2_CID_BASE+2) #define V4L2_CID_HUE (V4L2_CID_BASE+3) #define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) #define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) #define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) #define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) #define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) #define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) #define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ #define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) #define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) #define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) #define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) #define V4L2_CID_GAMMA (V4L2_CID_BASE+16) #define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ #define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) #define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) #define V4L2_CID_GAIN (V4L2_CID_BASE+19) #define V4L2_CID_HFLIP (V4L2_CID_BASE+20) #define V4L2_CID_VFLIP (V4L2_CID_BASE+21) #define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) enum v4l2_power_line_frequency { V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3, }; #define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) #define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) #define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) #define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) #define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) #define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) #define V4L2_CID_COLORFX (V4L2_CID_BASE+31) enum v4l2_colorfx { V4L2_COLORFX_NONE = 0, V4L2_COLORFX_BW = 1, V4L2_COLORFX_SEPIA = 2, V4L2_COLORFX_NEGATIVE = 3, V4L2_COLORFX_EMBOSS = 4, V4L2_COLORFX_SKETCH = 5, V4L2_COLORFX_SKY_BLUE = 6, V4L2_COLORFX_GRASS_GREEN = 7, V4L2_COLORFX_SKIN_WHITEN = 8, V4L2_COLORFX_VIVID = 9, V4L2_COLORFX_AQUA = 10, V4L2_COLORFX_ART_FREEZE = 11, V4L2_COLORFX_SILHOUETTE = 12, V4L2_COLORFX_SOLARIZATION = 13, V4L2_COLORFX_ANTIQUE = 14, V4L2_COLORFX_SET_CBCR = 15, }; #define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) #define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) #define V4L2_CID_ROTATE (V4L2_CID_BASE+34) #define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) #define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) #define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37) #define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38) #define V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (V4L2_CID_BASE+39) #define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40) #define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41) #define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42) /* last CID + 1 */ #define V4L2_CID_LASTP1 (V4L2_CID_BASE+43) /* USER-class private control IDs */ /* The base for the meye driver controls. See linux/meye.h for the list * of controls. We reserve 16 controls for this driver. */ #define V4L2_CID_USER_MEYE_BASE (V4L2_CID_USER_BASE + 0x1000) /* The base for the bttv driver controls. * We reserve 32 controls for this driver. */ #define V4L2_CID_USER_BTTV_BASE (V4L2_CID_USER_BASE + 0x1010) /* The base for the s2255 driver controls. * We reserve 16 controls for this driver. */ #define V4L2_CID_USER_S2255_BASE (V4L2_CID_USER_BASE + 0x1030) /* * The base for the si476x driver controls. See include/media/drv-intf/si476x.h * for the list of controls. Total of 16 controls is reserved for this driver */ #define V4L2_CID_USER_SI476X_BASE (V4L2_CID_USER_BASE + 0x1040) /* The base for the TI VPE driver controls. Total of 16 controls is reserved for * this driver */ #define V4L2_CID_USER_TI_VPE_BASE (V4L2_CID_USER_BASE + 0x1050) /* The base for the saa7134 driver controls. * We reserve 16 controls for this driver. */ #define V4L2_CID_USER_SAA7134_BASE (V4L2_CID_USER_BASE + 0x1060) /* The base for the adv7180 driver controls. * We reserve 16 controls for this driver. */ #define V4L2_CID_USER_ADV7180_BASE (V4L2_CID_USER_BASE + 0x1070) /* The base for the tc358743 driver controls. * We reserve 16 controls for this driver. */ #define V4L2_CID_USER_TC358743_BASE (V4L2_CID_USER_BASE + 0x1080) /* The base for the max217x driver controls. * We reserve 32 controls for this driver */ #define V4L2_CID_USER_MAX217X_BASE (V4L2_CID_USER_BASE + 0x1090) /* The base for the imx driver controls. * We reserve 16 controls for this driver. */ #define V4L2_CID_USER_IMX_BASE (V4L2_CID_USER_BASE + 0x1090) /* MPEG-class control IDs */ /* The MPEG controls are applicable to all codec controls * and the 'MPEG' part of the define is historical */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) #define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) /* MPEG streams, specific to multiplexed streams */ #define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) enum v4l2_mpeg_stream_type { V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */ V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ }; #define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) #define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) #define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) #define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) #define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) #define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) #define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) enum v4l2_mpeg_stream_vbi_fmt { V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ }; /* MPEG audio controls specific to multiplexed streams */ #define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) enum v4l2_mpeg_audio_sampling_freq { V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, }; #define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) enum v4l2_mpeg_audio_encoding { V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, V4L2_MPEG_AUDIO_ENCODING_AAC = 3, V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, }; #define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) enum v4l2_mpeg_audio_l1_bitrate { V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2, V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3, V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4, V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5, V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6, V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7, V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8, V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9, V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10, V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11, V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, }; #define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) enum v4l2_mpeg_audio_l2_bitrate { V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2, V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3, V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4, V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5, V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6, V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7, V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8, V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9, V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10, V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11, V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, }; #define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) enum v4l2_mpeg_audio_l3_bitrate { V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2, V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3, V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4, V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5, V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6, V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7, V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8, V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9, V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10, V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11, V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, }; #define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) enum v4l2_mpeg_audio_mode { V4L2_MPEG_AUDIO_MODE_STEREO = 0, V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, V4L2_MPEG_AUDIO_MODE_DUAL = 2, V4L2_MPEG_AUDIO_MODE_MONO = 3, }; #define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) enum v4l2_mpeg_audio_mode_extension { V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, }; #define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) enum v4l2_mpeg_audio_emphasis { V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, }; #define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) enum v4l2_mpeg_audio_crc { V4L2_MPEG_AUDIO_CRC_NONE = 0, V4L2_MPEG_AUDIO_CRC_CRC16 = 1, }; #define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) #define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) #define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) enum v4l2_mpeg_audio_ac3_bitrate { V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, }; #define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE+112) enum v4l2_mpeg_audio_dec_playback { V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0, V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1, V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2, V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3, V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4, V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5, }; #define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113) /* MPEG video controls specific to multiplexed streams */ #define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) enum v4l2_mpeg_video_encoding { V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, }; #define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) enum v4l2_mpeg_video_aspect { V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, }; #define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) #define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) #define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) #define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) #define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) enum v4l2_mpeg_video_bitrate_mode { V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, }; #define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) #define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) #define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) #define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) #define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) #define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212) #define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213) #define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214) #define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE+215) #define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE+216) enum v4l2_mpeg_video_header_mode { V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0, V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1, }; #define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217) #define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE+218) #define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE+219) #define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE+220) #define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221) enum v4l2_mpeg_video_multi_slice_mode { V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0, V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1, V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2, }; #define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222) #define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223) #define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224) #define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_BASE+225) #define V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER (V4L2_CID_MPEG_BASE+226) #define V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE (V4L2_CID_MPEG_BASE+227) #define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_MPEG_BASE+228) #define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (V4L2_CID_MPEG_BASE+229) #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) #define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) #define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE+303) #define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE+304) #define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE+350) #define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE+351) #define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE+352) #define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE+353) #define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE+354) #define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE+355) #define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE+356) #define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE+357) enum v4l2_mpeg_video_h264_entropy_mode { V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0, V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1, }; #define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE+358) #define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE+359) enum v4l2_mpeg_video_h264_level { V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0, V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1, V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2, V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3, V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4, V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5, V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6, V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7, V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8, V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9, V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10, V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11, V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12, V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13, V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15, }; #define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE+360) #define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE+361) #define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE+362) enum v4l2_mpeg_video_h264_loop_filter_mode { V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0, V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1, V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2, }; #define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE+363) enum v4l2_mpeg_video_h264_profile { V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2, V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10, V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11, V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12, V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13, V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14, V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15, V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16, }; #define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364) #define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365) #define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE+366) #define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE+367) enum v4l2_mpeg_video_h264_vui_sar_idc { V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16, V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17, }; #define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING (V4L2_CID_MPEG_BASE+368) #define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 (V4L2_CID_MPEG_BASE+369) #define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE (V4L2_CID_MPEG_BASE+370) enum v4l2_mpeg_video_h264_sei_fp_arrangement_type { V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_CHECKERBOARD = 0, V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_COLUMN = 1, V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_ROW = 2, V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE = 3, V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM = 4, V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL = 5, }; #define V4L2_CID_MPEG_VIDEO_H264_FMO (V4L2_CID_MPEG_BASE+371) #define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE (V4L2_CID_MPEG_BASE+372) enum v4l2_mpeg_video_h264_fmo_map_type { V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0, V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1, V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2, V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3, V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4, V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5, V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6, }; #define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (V4L2_CID_MPEG_BASE+373) #define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION (V4L2_CID_MPEG_BASE+374) enum v4l2_mpeg_video_h264_fmo_change_dir { V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0, V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1, }; #define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE (V4L2_CID_MPEG_BASE+375) #define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH (V4L2_CID_MPEG_BASE+376) #define V4L2_CID_MPEG_VIDEO_H264_ASO (V4L2_CID_MPEG_BASE+377) #define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER (V4L2_CID_MPEG_BASE+378) #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING (V4L2_CID_MPEG_BASE+379) #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE (V4L2_CID_MPEG_BASE+380) enum v4l2_mpeg_video_h264_hierarchical_coding_type { V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0, V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1, }; #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_BASE+381) #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE+382) #define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) #define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) #define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) #define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE+403) #define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE+404) #define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE+405) enum v4l2_mpeg_video_mpeg4_level { V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1, V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2, V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3, V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4, V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5, V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6, V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7, }; #define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE+406) enum v4l2_mpeg_video_mpeg4_profile { V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0, V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1, V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2, V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3, V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4, }; #define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE+407) /* Control IDs for VP8 streams * Although VP8 is not part of MPEG we add these controls to the MPEG class * as that class is already handling other video compression standards */ #define V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS (V4L2_CID_MPEG_BASE+500) enum v4l2_vp8_num_partitions { V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION = 0, V4L2_CID_MPEG_VIDEO_VPX_2_PARTITIONS = 1, V4L2_CID_MPEG_VIDEO_VPX_4_PARTITIONS = 2, V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS = 3, }; #define V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4 (V4L2_CID_MPEG_BASE+501) #define V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES (V4L2_CID_MPEG_BASE+502) enum v4l2_vp8_num_ref_frames { V4L2_CID_MPEG_VIDEO_VPX_1_REF_FRAME = 0, V4L2_CID_MPEG_VIDEO_VPX_2_REF_FRAME = 1, V4L2_CID_MPEG_VIDEO_VPX_3_REF_FRAME = 2, }; #define V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL (V4L2_CID_MPEG_BASE+503) #define V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS (V4L2_CID_MPEG_BASE+504) #define V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD (V4L2_CID_MPEG_BASE+505) #define V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL (V4L2_CID_MPEG_BASE+506) enum v4l2_vp8_golden_frame_sel { V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV = 0, V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD = 1, }; #define V4L2_CID_MPEG_VIDEO_VPX_MIN_QP (V4L2_CID_MPEG_BASE+507) #define V4L2_CID_MPEG_VIDEO_VPX_MAX_QP (V4L2_CID_MPEG_BASE+508) #define V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP (V4L2_CID_MPEG_BASE+509) #define V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP (V4L2_CID_MPEG_BASE+510) #define V4L2_CID_MPEG_VIDEO_VPX_PROFILE (V4L2_CID_MPEG_BASE+511) /* CIDs for HEVC encoding. */ #define V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP (V4L2_CID_MPEG_BASE + 600) #define V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP (V4L2_CID_MPEG_BASE + 601) #define V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP (V4L2_CID_MPEG_BASE + 602) #define V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP (V4L2_CID_MPEG_BASE + 603) #define V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP (V4L2_CID_MPEG_BASE + 604) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP (V4L2_CID_MPEG_BASE + 605) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE (V4L2_CID_MPEG_BASE + 606) enum v4l2_mpeg_video_hevc_hier_coding_type { V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B = 0, V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P = 1, }; #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER (V4L2_CID_MPEG_BASE + 607) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP (V4L2_CID_MPEG_BASE + 608) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP (V4L2_CID_MPEG_BASE + 609) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP (V4L2_CID_MPEG_BASE + 610) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP (V4L2_CID_MPEG_BASE + 611) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP (V4L2_CID_MPEG_BASE + 612) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP (V4L2_CID_MPEG_BASE + 613) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP (V4L2_CID_MPEG_BASE + 614) #define V4L2_CID_MPEG_VIDEO_HEVC_PROFILE (V4L2_CID_MPEG_BASE + 615) enum v4l2_mpeg_video_hevc_profile { V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN = 0, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE = 1, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10 = 2, }; #define V4L2_CID_MPEG_VIDEO_HEVC_LEVEL (V4L2_CID_MPEG_BASE + 616) enum v4l2_mpeg_video_hevc_level { V4L2_MPEG_VIDEO_HEVC_LEVEL_1 = 0, V4L2_MPEG_VIDEO_HEVC_LEVEL_2 = 1, V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 = 2, V4L2_MPEG_VIDEO_HEVC_LEVEL_3 = 3, V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 = 4, V4L2_MPEG_VIDEO_HEVC_LEVEL_4 = 5, V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 = 6, V4L2_MPEG_VIDEO_HEVC_LEVEL_5 = 7, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 = 8, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 = 9, V4L2_MPEG_VIDEO_HEVC_LEVEL_6 = 10, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 = 11, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 = 12, }; #define V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION (V4L2_CID_MPEG_BASE + 617) #define V4L2_CID_MPEG_VIDEO_HEVC_TIER (V4L2_CID_MPEG_BASE + 618) enum v4l2_mpeg_video_hevc_tier { V4L2_MPEG_VIDEO_HEVC_TIER_MAIN = 0, V4L2_MPEG_VIDEO_HEVC_TIER_HIGH = 1, }; #define V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH (V4L2_CID_MPEG_BASE + 619) #define V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE + 620) enum v4l2_cid_mpeg_video_hevc_loop_filter_mode { V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED = 0, V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED = 1, V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2, }; #define V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2 (V4L2_CID_MPEG_BASE + 621) #define V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2 (V4L2_CID_MPEG_BASE + 622) #define V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE (V4L2_CID_MPEG_BASE + 623) enum v4l2_cid_mpeg_video_hevc_refresh_type { V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE = 0, V4L2_MPEG_VIDEO_HEVC_REFRESH_CRA = 1, V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR = 2, }; #define V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD (V4L2_CID_MPEG_BASE + 624) #define V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU (V4L2_CID_MPEG_BASE + 625) #define V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED (V4L2_CID_MPEG_BASE + 626) #define V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT (V4L2_CID_MPEG_BASE + 627) #define V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB (V4L2_CID_MPEG_BASE + 628) #define V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID (V4L2_CID_MPEG_BASE + 629) #define V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING (V4L2_CID_MPEG_BASE + 630) #define V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1 (V4L2_CID_MPEG_BASE + 631) #define V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT (V4L2_CID_MPEG_BASE + 632) #define V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION (V4L2_CID_MPEG_BASE + 633) #define V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE (V4L2_CID_MPEG_BASE + 634) #define V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD (V4L2_CID_MPEG_BASE + 635) enum v4l2_cid_mpeg_video_hevc_size_of_length_field { V4L2_MPEG_VIDEO_HEVC_SIZE_0 = 0, V4L2_MPEG_VIDEO_HEVC_SIZE_1 = 1, V4L2_MPEG_VIDEO_HEVC_SIZE_2 = 2, V4L2_MPEG_VIDEO_HEVC_SIZE_4 = 3, }; #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR (V4L2_CID_MPEG_BASE + 636) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR (V4L2_CID_MPEG_BASE + 637) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR (V4L2_CID_MPEG_BASE + 638) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR (V4L2_CID_MPEG_BASE + 639) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR (V4L2_CID_MPEG_BASE + 640) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR (V4L2_CID_MPEG_BASE + 641) #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR (V4L2_CID_MPEG_BASE + 642) #define V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES (V4L2_CID_MPEG_BASE + 643) #define V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_BASE + 644) /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) #define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) enum v4l2_mpeg_cx2341x_video_median_filter_type { V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) #define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) /* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */ #define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100) #define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE+0) #define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE+1) #define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE+2) enum v4l2_mpeg_mfc51_video_frame_skip_mode { V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0, V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1, V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2, }; #define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE+3) enum v4l2_mpeg_mfc51_video_force_frame_type { V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0, V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1, V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2, }; #define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE+4) #define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE+5) #define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE+6) #define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE+7) #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE+50) #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE+51) #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE+52) #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53) #define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54) /* Camera class control IDs */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) #define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) #define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) enum v4l2_exposure_auto_type { V4L2_EXPOSURE_AUTO = 0, V4L2_EXPOSURE_MANUAL = 1, V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, V4L2_EXPOSURE_APERTURE_PRIORITY = 3 }; #define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) #define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) #define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) #define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) #define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) #define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) #define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) #define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) #define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) #define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) #define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) #define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) #define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) #define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) #define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) #define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) #define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) #define V4L2_CID_AUTO_EXPOSURE_BIAS (V4L2_CID_CAMERA_CLASS_BASE+19) #define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE+20) enum v4l2_auto_n_preset_white_balance { V4L2_WHITE_BALANCE_MANUAL = 0, V4L2_WHITE_BALANCE_AUTO = 1, V4L2_WHITE_BALANCE_INCANDESCENT = 2, V4L2_WHITE_BALANCE_FLUORESCENT = 3, V4L2_WHITE_BALANCE_FLUORESCENT_H = 4, V4L2_WHITE_BALANCE_HORIZON = 5, V4L2_WHITE_BALANCE_DAYLIGHT = 6, V4L2_WHITE_BALANCE_FLASH = 7, V4L2_WHITE_BALANCE_CLOUDY = 8, V4L2_WHITE_BALANCE_SHADE = 9, }; #define V4L2_CID_WIDE_DYNAMIC_RANGE (V4L2_CID_CAMERA_CLASS_BASE+21) #define V4L2_CID_IMAGE_STABILIZATION (V4L2_CID_CAMERA_CLASS_BASE+22) #define V4L2_CID_ISO_SENSITIVITY (V4L2_CID_CAMERA_CLASS_BASE+23) #define V4L2_CID_ISO_SENSITIVITY_AUTO (V4L2_CID_CAMERA_CLASS_BASE+24) enum v4l2_iso_sensitivity_auto_type { V4L2_ISO_SENSITIVITY_MANUAL = 0, V4L2_ISO_SENSITIVITY_AUTO = 1, }; #define V4L2_CID_EXPOSURE_METERING (V4L2_CID_CAMERA_CLASS_BASE+25) enum v4l2_exposure_metering { V4L2_EXPOSURE_METERING_AVERAGE = 0, V4L2_EXPOSURE_METERING_CENTER_WEIGHTED = 1, V4L2_EXPOSURE_METERING_SPOT = 2, V4L2_EXPOSURE_METERING_MATRIX = 3, }; #define V4L2_CID_SCENE_MODE (V4L2_CID_CAMERA_CLASS_BASE+26) enum v4l2_scene_mode { V4L2_SCENE_MODE_NONE = 0, V4L2_SCENE_MODE_BACKLIGHT = 1, V4L2_SCENE_MODE_BEACH_SNOW = 2, V4L2_SCENE_MODE_CANDLE_LIGHT = 3, V4L2_SCENE_MODE_DAWN_DUSK = 4, V4L2_SCENE_MODE_FALL_COLORS = 5, V4L2_SCENE_MODE_FIREWORKS = 6, V4L2_SCENE_MODE_LANDSCAPE = 7, V4L2_SCENE_MODE_NIGHT = 8, V4L2_SCENE_MODE_PARTY_INDOOR = 9, V4L2_SCENE_MODE_PORTRAIT = 10, V4L2_SCENE_MODE_SPORTS = 11, V4L2_SCENE_MODE_SUNSET = 12, V4L2_SCENE_MODE_TEXT = 13, }; #define V4L2_CID_3A_LOCK (V4L2_CID_CAMERA_CLASS_BASE+27) #define V4L2_LOCK_EXPOSURE (1 << 0) #define V4L2_LOCK_WHITE_BALANCE (1 << 1) #define V4L2_LOCK_FOCUS (1 << 2) #define V4L2_CID_AUTO_FOCUS_START (V4L2_CID_CAMERA_CLASS_BASE+28) #define V4L2_CID_AUTO_FOCUS_STOP (V4L2_CID_CAMERA_CLASS_BASE+29) #define V4L2_CID_AUTO_FOCUS_STATUS (V4L2_CID_CAMERA_CLASS_BASE+30) #define V4L2_AUTO_FOCUS_STATUS_IDLE (0 << 0) #define V4L2_AUTO_FOCUS_STATUS_BUSY (1 << 0) #define V4L2_AUTO_FOCUS_STATUS_REACHED (1 << 1) #define V4L2_AUTO_FOCUS_STATUS_FAILED (1 << 2) #define V4L2_CID_AUTO_FOCUS_RANGE (V4L2_CID_CAMERA_CLASS_BASE+31) enum v4l2_auto_focus_range { V4L2_AUTO_FOCUS_RANGE_AUTO = 0, V4L2_AUTO_FOCUS_RANGE_NORMAL = 1, V4L2_AUTO_FOCUS_RANGE_MACRO = 2, V4L2_AUTO_FOCUS_RANGE_INFINITY = 3, }; #define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32) #define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33) /* FM Modulator class control IDs */ #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) #define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) #define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1) #define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2) #define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) #define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) #define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) #define V4L2_CID_RDS_TX_MONO_STEREO (V4L2_CID_FM_TX_CLASS_BASE + 7) #define V4L2_CID_RDS_TX_ARTIFICIAL_HEAD (V4L2_CID_FM_TX_CLASS_BASE + 8) #define V4L2_CID_RDS_TX_COMPRESSED (V4L2_CID_FM_TX_CLASS_BASE + 9) #define V4L2_CID_RDS_TX_DYNAMIC_PTY (V4L2_CID_FM_TX_CLASS_BASE + 10) #define V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT (V4L2_CID_FM_TX_CLASS_BASE + 11) #define V4L2_CID_RDS_TX_TRAFFIC_PROGRAM (V4L2_CID_FM_TX_CLASS_BASE + 12) #define V4L2_CID_RDS_TX_MUSIC_SPEECH (V4L2_CID_FM_TX_CLASS_BASE + 13) #define V4L2_CID_RDS_TX_ALT_FREQS_ENABLE (V4L2_CID_FM_TX_CLASS_BASE + 14) #define V4L2_CID_RDS_TX_ALT_FREQS (V4L2_CID_FM_TX_CLASS_BASE + 15) #define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64) #define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65) #define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66) #define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80) #define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81) #define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82) #define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83) #define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84) #define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96) #define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97) #define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98) #define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112) enum v4l2_preemphasis { V4L2_PREEMPHASIS_DISABLED = 0, V4L2_PREEMPHASIS_50_uS = 1, V4L2_PREEMPHASIS_75_uS = 2, }; #define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113) #define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114) /* Flash and privacy (indicator) light controls */ #define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900) #define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1) #define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1) enum v4l2_flash_led_mode { V4L2_FLASH_LED_MODE_NONE, V4L2_FLASH_LED_MODE_FLASH, V4L2_FLASH_LED_MODE_TORCH, }; #define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2) enum v4l2_flash_strobe_source { V4L2_FLASH_STROBE_SOURCE_SOFTWARE, V4L2_FLASH_STROBE_SOURCE_EXTERNAL, }; #define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3) #define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4) #define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5) #define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6) #define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7) #define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8) #define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9) #define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10) #define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0) #define V4L2_FLASH_FAULT_TIMEOUT (1 << 1) #define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2) #define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3) #define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4) #define V4L2_FLASH_FAULT_INDICATOR (1 << 5) #define V4L2_FLASH_FAULT_UNDER_VOLTAGE (1 << 6) #define V4L2_FLASH_FAULT_INPUT_VOLTAGE (1 << 7) #define V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE (1 << 8) #define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) #define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) /* JPEG-class control IDs */ #define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900) #define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1) #define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1) enum v4l2_jpeg_chroma_subsampling { V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0, V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1, V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2, V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3, V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4, V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5, }; #define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2) #define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3) #define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4) #define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0) #define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1) #define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16) #define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17) #define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18) /* Image source controls */ #define V4L2_CID_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900) #define V4L2_CID_IMAGE_SOURCE_CLASS (V4L2_CTRL_CLASS_IMAGE_SOURCE | 1) #define V4L2_CID_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1) #define V4L2_CID_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2) #define V4L2_CID_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3) #define V4L2_CID_TEST_PATTERN_RED (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 4) #define V4L2_CID_TEST_PATTERN_GREENR (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 5) #define V4L2_CID_TEST_PATTERN_BLUE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 6) #define V4L2_CID_TEST_PATTERN_GREENB (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 7) /* Image processing controls */ #define V4L2_CID_IMAGE_PROC_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_PROC | 0x900) #define V4L2_CID_IMAGE_PROC_CLASS (V4L2_CTRL_CLASS_IMAGE_PROC | 1) #define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1) #define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2) #define V4L2_CID_TEST_PATTERN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 3) #define V4L2_CID_DEINTERLACING_MODE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 4) #define V4L2_CID_DIGITAL_GAIN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 5) /* DV-class control IDs defined by V4L2 */ #define V4L2_CID_DV_CLASS_BASE (V4L2_CTRL_CLASS_DV | 0x900) #define V4L2_CID_DV_CLASS (V4L2_CTRL_CLASS_DV | 1) #define V4L2_CID_DV_TX_HOTPLUG (V4L2_CID_DV_CLASS_BASE + 1) #define V4L2_CID_DV_TX_RXSENSE (V4L2_CID_DV_CLASS_BASE + 2) #define V4L2_CID_DV_TX_EDID_PRESENT (V4L2_CID_DV_CLASS_BASE + 3) #define V4L2_CID_DV_TX_MODE (V4L2_CID_DV_CLASS_BASE + 4) enum v4l2_dv_tx_mode { V4L2_DV_TX_MODE_DVI_D = 0, V4L2_DV_TX_MODE_HDMI = 1, }; #define V4L2_CID_DV_TX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 5) enum v4l2_dv_rgb_range { V4L2_DV_RGB_RANGE_AUTO = 0, V4L2_DV_RGB_RANGE_LIMITED = 1, V4L2_DV_RGB_RANGE_FULL = 2, }; #define V4L2_CID_DV_TX_IT_CONTENT_TYPE (V4L2_CID_DV_CLASS_BASE + 6) enum v4l2_dv_it_content_type { V4L2_DV_IT_CONTENT_TYPE_GRAPHICS = 0, V4L2_DV_IT_CONTENT_TYPE_PHOTO = 1, V4L2_DV_IT_CONTENT_TYPE_CINEMA = 2, V4L2_DV_IT_CONTENT_TYPE_GAME = 3, V4L2_DV_IT_CONTENT_TYPE_NO_ITC = 4, }; #define V4L2_CID_DV_RX_POWER_PRESENT (V4L2_CID_DV_CLASS_BASE + 100) #define V4L2_CID_DV_RX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 101) #define V4L2_CID_DV_RX_IT_CONTENT_TYPE (V4L2_CID_DV_CLASS_BASE + 102) #define V4L2_CID_FM_RX_CLASS_BASE (V4L2_CTRL_CLASS_FM_RX | 0x900) #define V4L2_CID_FM_RX_CLASS (V4L2_CTRL_CLASS_FM_RX | 1) #define V4L2_CID_TUNE_DEEMPHASIS (V4L2_CID_FM_RX_CLASS_BASE + 1) enum v4l2_deemphasis { V4L2_DEEMPHASIS_DISABLED = V4L2_PREEMPHASIS_DISABLED, V4L2_DEEMPHASIS_50_uS = V4L2_PREEMPHASIS_50_uS, V4L2_DEEMPHASIS_75_uS = V4L2_PREEMPHASIS_75_uS, }; #define V4L2_CID_RDS_RECEPTION (V4L2_CID_FM_RX_CLASS_BASE + 2) #define V4L2_CID_RDS_RX_PTY (V4L2_CID_FM_RX_CLASS_BASE + 3) #define V4L2_CID_RDS_RX_PS_NAME (V4L2_CID_FM_RX_CLASS_BASE + 4) #define V4L2_CID_RDS_RX_RADIO_TEXT (V4L2_CID_FM_RX_CLASS_BASE + 5) #define V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT (V4L2_CID_FM_RX_CLASS_BASE + 6) #define V4L2_CID_RDS_RX_TRAFFIC_PROGRAM (V4L2_CID_FM_RX_CLASS_BASE + 7) #define V4L2_CID_RDS_RX_MUSIC_SPEECH (V4L2_CID_FM_RX_CLASS_BASE + 8) #define V4L2_CID_RF_TUNER_CLASS_BASE (V4L2_CTRL_CLASS_RF_TUNER | 0x900) #define V4L2_CID_RF_TUNER_CLASS (V4L2_CTRL_CLASS_RF_TUNER | 1) #define V4L2_CID_RF_TUNER_BANDWIDTH_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 11) #define V4L2_CID_RF_TUNER_BANDWIDTH (V4L2_CID_RF_TUNER_CLASS_BASE + 12) #define V4L2_CID_RF_TUNER_RF_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 32) #define V4L2_CID_RF_TUNER_LNA_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 41) #define V4L2_CID_RF_TUNER_LNA_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 42) #define V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 51) #define V4L2_CID_RF_TUNER_MIXER_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 52) #define V4L2_CID_RF_TUNER_IF_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 61) #define V4L2_CID_RF_TUNER_IF_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 62) #define V4L2_CID_RF_TUNER_PLL_LOCK (V4L2_CID_RF_TUNER_CLASS_BASE + 91) /* Detection-class control IDs defined by V4L2 */ #define V4L2_CID_DETECT_CLASS_BASE (V4L2_CTRL_CLASS_DETECT | 0x900) #define V4L2_CID_DETECT_CLASS (V4L2_CTRL_CLASS_DETECT | 1) #define V4L2_CID_DETECT_MD_MODE (V4L2_CID_DETECT_CLASS_BASE + 1) enum v4l2_detect_md_mode { V4L2_DETECT_MD_MODE_DISABLED = 0, V4L2_DETECT_MD_MODE_GLOBAL = 1, V4L2_DETECT_MD_MODE_THRESHOLD_GRID = 2, V4L2_DETECT_MD_MODE_REGION_GRID = 3, }; #define V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD (V4L2_CID_DETECT_CLASS_BASE + 2) #define V4L2_CID_DETECT_MD_THRESHOLD_GRID (V4L2_CID_DETECT_CLASS_BASE + 3) #define V4L2_CID_DETECT_MD_REGION_GRID (V4L2_CID_DETECT_CLASS_BASE + 4) #endif xawtv-3.106/libng/videodev2.h000066400000000000000000002504131343350355000160350ustar00rootroot00000000000000/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * Video for Linux Two header file * * Copyright (C) 1999-2012 the contributors * * 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. * * Alternatively you can redistribute this file under the terms of the * BSD license as stated below: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Header file for v4l or V4L2 drivers and applications * with public API. * All kernel-specific stuff were moved to media/v4l2-dev.h, so * no #if __KERNEL tests are allowed here * * See https://linuxtv.org for more info * * Author: Bill Dirks * Justin Schoeman * Hans Verkuil * et al. */ #ifndef __LINUX_VIDEODEV2_H #define __LINUX_VIDEODEV2_H #include #include #include #include #include /* * Common stuff for both V4L1 and V4L2 * Moved from videodev.h */ #define VIDEO_MAX_FRAME 32 #define VIDEO_MAX_PLANES 8 /* * M I S C E L L A N E O U S */ /* Four-character-code (FOURCC) */ #define v4l2_fourcc(a, b, c, d)\ ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) #define v4l2_fourcc_be(a, b, c, d) (v4l2_fourcc(a, b, c, d) | (1 << 31)) /* * E N U M S */ enum v4l2_field { V4L2_FIELD_ANY = 0, /* driver can choose from none, top, bottom, interlaced depending on whatever it thinks is approximate ... */ V4L2_FIELD_NONE = 1, /* this device has no fields ... */ V4L2_FIELD_TOP = 2, /* top field only */ V4L2_FIELD_BOTTOM = 3, /* bottom field only */ V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one buffer, top-bottom order */ V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into separate buffers */ V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field first and the top field is transmitted first */ V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field first and the bottom field is transmitted first */ }; #define V4L2_FIELD_HAS_TOP(field) \ ((field) == V4L2_FIELD_TOP ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_BOTTOM(field) \ ((field) == V4L2_FIELD_BOTTOM ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_BOTH(field) \ ((field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_T_OR_B(field) \ ((field) == V4L2_FIELD_BOTTOM ||\ (field) == V4L2_FIELD_TOP ||\ (field) == V4L2_FIELD_ALTERNATE) enum v4l2_buf_type { V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, V4L2_BUF_TYPE_VBI_CAPTURE = 4, V4L2_BUF_TYPE_VBI_OUTPUT = 5, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10, V4L2_BUF_TYPE_SDR_CAPTURE = 11, V4L2_BUF_TYPE_SDR_OUTPUT = 12, V4L2_BUF_TYPE_META_CAPTURE = 13, /* Deprecated, do not use */ V4L2_BUF_TYPE_PRIVATE = 0x80, }; #define V4L2_TYPE_IS_MULTIPLANAR(type) \ ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) #define V4L2_TYPE_IS_OUTPUT(type) \ ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \ || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \ || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \ || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT \ || (type) == V4L2_BUF_TYPE_SDR_OUTPUT) enum v4l2_tuner_type { V4L2_TUNER_RADIO = 1, V4L2_TUNER_ANALOG_TV = 2, V4L2_TUNER_DIGITAL_TV = 3, V4L2_TUNER_SDR = 4, V4L2_TUNER_RF = 5, }; /* Deprecated, do not use */ #define V4L2_TUNER_ADC V4L2_TUNER_SDR enum v4l2_memory { V4L2_MEMORY_MMAP = 1, V4L2_MEMORY_USERPTR = 2, V4L2_MEMORY_OVERLAY = 3, V4L2_MEMORY_DMABUF = 4, }; /* see also http://vektor.theorem.ca/graphics/ycbcr/ */ enum v4l2_colorspace { /* * Default colorspace, i.e. let the driver figure it out. * Can only be used with video capture. */ V4L2_COLORSPACE_DEFAULT = 0, /* SMPTE 170M: used for broadcast NTSC/PAL SDTV */ V4L2_COLORSPACE_SMPTE170M = 1, /* Obsolete pre-1998 SMPTE 240M HDTV standard, superseded by Rec 709 */ V4L2_COLORSPACE_SMPTE240M = 2, /* Rec.709: used for HDTV */ V4L2_COLORSPACE_REC709 = 3, /* * Deprecated, do not use. No driver will ever return this. This was * based on a misunderstanding of the bt878 datasheet. */ V4L2_COLORSPACE_BT878 = 4, /* * NTSC 1953 colorspace. This only makes sense when dealing with * really, really old NTSC recordings. Superseded by SMPTE 170M. */ V4L2_COLORSPACE_470_SYSTEM_M = 5, /* * EBU Tech 3213 PAL/SECAM colorspace. This only makes sense when * dealing with really old PAL/SECAM recordings. Superseded by * SMPTE 170M. */ V4L2_COLORSPACE_470_SYSTEM_BG = 6, /* * Effectively shorthand for V4L2_COLORSPACE_SRGB, V4L2_YCBCR_ENC_601 * and V4L2_QUANTIZATION_FULL_RANGE. To be used for (Motion-)JPEG. */ V4L2_COLORSPACE_JPEG = 7, /* For RGB colorspaces such as produces by most webcams. */ V4L2_COLORSPACE_SRGB = 8, /* AdobeRGB colorspace */ V4L2_COLORSPACE_ADOBERGB = 9, /* BT.2020 colorspace, used for UHDTV. */ V4L2_COLORSPACE_BT2020 = 10, /* Raw colorspace: for RAW unprocessed images */ V4L2_COLORSPACE_RAW = 11, /* DCI-P3 colorspace, used by cinema projectors */ V4L2_COLORSPACE_DCI_P3 = 12, }; /* * Determine how COLORSPACE_DEFAULT should map to a proper colorspace. * This depends on whether this is a SDTV image (use SMPTE 170M), an * HDTV image (use Rec. 709), or something else (use sRGB). */ #define V4L2_MAP_COLORSPACE_DEFAULT(is_sdtv, is_hdtv) \ ((is_sdtv) ? V4L2_COLORSPACE_SMPTE170M : \ ((is_hdtv) ? V4L2_COLORSPACE_REC709 : V4L2_COLORSPACE_SRGB)) enum v4l2_xfer_func { /* * Mapping of V4L2_XFER_FUNC_DEFAULT to actual transfer functions * for the various colorspaces: * * V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_470_SYSTEM_M, * V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_REC709 and * V4L2_COLORSPACE_BT2020: V4L2_XFER_FUNC_709 * * V4L2_COLORSPACE_SRGB, V4L2_COLORSPACE_JPEG: V4L2_XFER_FUNC_SRGB * * V4L2_COLORSPACE_ADOBERGB: V4L2_XFER_FUNC_ADOBERGB * * V4L2_COLORSPACE_SMPTE240M: V4L2_XFER_FUNC_SMPTE240M * * V4L2_COLORSPACE_RAW: V4L2_XFER_FUNC_NONE * * V4L2_COLORSPACE_DCI_P3: V4L2_XFER_FUNC_DCI_P3 */ V4L2_XFER_FUNC_DEFAULT = 0, V4L2_XFER_FUNC_709 = 1, V4L2_XFER_FUNC_SRGB = 2, V4L2_XFER_FUNC_ADOBERGB = 3, V4L2_XFER_FUNC_SMPTE240M = 4, V4L2_XFER_FUNC_NONE = 5, V4L2_XFER_FUNC_DCI_P3 = 6, V4L2_XFER_FUNC_SMPTE2084 = 7, }; /* * Determine how XFER_FUNC_DEFAULT should map to a proper transfer function. * This depends on the colorspace. */ #define V4L2_MAP_XFER_FUNC_DEFAULT(colsp) \ ((colsp) == V4L2_COLORSPACE_ADOBERGB ? V4L2_XFER_FUNC_ADOBERGB : \ ((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_XFER_FUNC_SMPTE240M : \ ((colsp) == V4L2_COLORSPACE_DCI_P3 ? V4L2_XFER_FUNC_DCI_P3 : \ ((colsp) == V4L2_COLORSPACE_RAW ? V4L2_XFER_FUNC_NONE : \ ((colsp) == V4L2_COLORSPACE_SRGB || (colsp) == V4L2_COLORSPACE_JPEG ? \ V4L2_XFER_FUNC_SRGB : V4L2_XFER_FUNC_709))))) enum v4l2_ycbcr_encoding { /* * Mapping of V4L2_YCBCR_ENC_DEFAULT to actual encodings for the * various colorspaces: * * V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_470_SYSTEM_M, * V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_SRGB, * V4L2_COLORSPACE_ADOBERGB and V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601 * * V4L2_COLORSPACE_REC709 and V4L2_COLORSPACE_DCI_P3: V4L2_YCBCR_ENC_709 * * V4L2_COLORSPACE_BT2020: V4L2_YCBCR_ENC_BT2020 * * V4L2_COLORSPACE_SMPTE240M: V4L2_YCBCR_ENC_SMPTE240M */ V4L2_YCBCR_ENC_DEFAULT = 0, /* ITU-R 601 -- SDTV */ V4L2_YCBCR_ENC_601 = 1, /* Rec. 709 -- HDTV */ V4L2_YCBCR_ENC_709 = 2, /* ITU-R 601/EN 61966-2-4 Extended Gamut -- SDTV */ V4L2_YCBCR_ENC_XV601 = 3, /* Rec. 709/EN 61966-2-4 Extended Gamut -- HDTV */ V4L2_YCBCR_ENC_XV709 = 4, /* * sYCC (Y'CbCr encoding of sRGB), identical to ENC_601. It was added * originally due to a misunderstanding of the sYCC standard. It should * not be used, instead use V4L2_YCBCR_ENC_601. */ V4L2_YCBCR_ENC_SYCC = 5, /* BT.2020 Non-constant Luminance Y'CbCr */ V4L2_YCBCR_ENC_BT2020 = 6, /* BT.2020 Constant Luminance Y'CbcCrc */ V4L2_YCBCR_ENC_BT2020_CONST_LUM = 7, /* SMPTE 240M -- Obsolete HDTV */ V4L2_YCBCR_ENC_SMPTE240M = 8, }; /* * enum v4l2_hsv_encoding values should not collide with the ones from * enum v4l2_ycbcr_encoding. */ enum v4l2_hsv_encoding { /* Hue mapped to 0 - 179 */ V4L2_HSV_ENC_180 = 128, /* Hue mapped to 0-255 */ V4L2_HSV_ENC_256 = 129, }; /* * Determine how YCBCR_ENC_DEFAULT should map to a proper Y'CbCr encoding. * This depends on the colorspace. */ #define V4L2_MAP_YCBCR_ENC_DEFAULT(colsp) \ (((colsp) == V4L2_COLORSPACE_REC709 || \ (colsp) == V4L2_COLORSPACE_DCI_P3) ? V4L2_YCBCR_ENC_709 : \ ((colsp) == V4L2_COLORSPACE_BT2020 ? V4L2_YCBCR_ENC_BT2020 : \ ((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_YCBCR_ENC_SMPTE240M : \ V4L2_YCBCR_ENC_601))) enum v4l2_quantization { /* * The default for R'G'B' quantization is always full range, except * for the BT2020 colorspace. For Y'CbCr the quantization is always * limited range, except for COLORSPACE_JPEG: this is full range. */ V4L2_QUANTIZATION_DEFAULT = 0, V4L2_QUANTIZATION_FULL_RANGE = 1, V4L2_QUANTIZATION_LIM_RANGE = 2, }; /* * Determine how QUANTIZATION_DEFAULT should map to a proper quantization. * This depends on whether the image is RGB or not, the colorspace and the * Y'CbCr encoding. */ #define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb_or_hsv, colsp, ycbcr_enc) \ (((is_rgb_or_hsv) && (colsp) == V4L2_COLORSPACE_BT2020) ? \ V4L2_QUANTIZATION_LIM_RANGE : \ (((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? \ V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE)) enum v4l2_priority { V4L2_PRIORITY_UNSET = 0, /* not initialized */ V4L2_PRIORITY_BACKGROUND = 1, V4L2_PRIORITY_INTERACTIVE = 2, V4L2_PRIORITY_RECORD = 3, V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, }; struct v4l2_rect { __s32 left; __s32 top; __u32 width; __u32 height; }; struct v4l2_fract { __u32 numerator; __u32 denominator; }; /** * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP * * @driver: name of the driver module (e.g. "bttv") * @card: name of the card (e.g. "Hauppauge WinTV") * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) ) * @version: KERNEL_VERSION * @capabilities: capabilities of the physical device as a whole * @device_caps: capabilities accessed via this particular device (node) * @reserved: reserved fields for future extensions */ struct v4l2_capability { __u8 driver[16]; __u8 card[32]; __u8 bus_info[32]; __u32 version; __u32 capabilities; __u32 device_caps; __u32 reserved[3]; }; /* Values for 'capabilities' field */ #define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ #define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ #define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ #define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ #define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ #define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ #define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ #define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ #define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ #define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ #define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ /* Is a video capture device that supports multiplanar formats */ #define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000 /* Is a video output device that supports multiplanar formats */ #define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000 /* Is a video mem-to-mem device that supports multiplanar formats */ #define V4L2_CAP_VIDEO_M2M_MPLANE 0x00004000 /* Is a video mem-to-mem device */ #define V4L2_CAP_VIDEO_M2M 0x00008000 #define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ #define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ #define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ #define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */ #define V4L2_CAP_SDR_CAPTURE 0x00100000 /* Is a SDR capture device */ #define V4L2_CAP_EXT_PIX_FORMAT 0x00200000 /* Supports the extended pixel format */ #define V4L2_CAP_SDR_OUTPUT 0x00400000 /* Is a SDR output device */ #define V4L2_CAP_META_CAPTURE 0x00800000 /* Is a metadata capture device */ #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ #define V4L2_CAP_TOUCH 0x10000000 /* Is a touch device */ #define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ /* * V I D E O I M A G E F O R M A T */ struct v4l2_pix_format { __u32 width; __u32 height; __u32 pixelformat; __u32 field; /* enum v4l2_field */ __u32 bytesperline; /* for padding, zero if unused */ __u32 sizeimage; __u32 colorspace; /* enum v4l2_colorspace */ __u32 priv; /* private data, depends on pixelformat */ __u32 flags; /* format flags (V4L2_PIX_FMT_FLAG_*) */ union { /* enum v4l2_ycbcr_encoding */ __u32 ycbcr_enc; /* enum v4l2_hsv_encoding */ __u32 hsv_enc; }; __u32 quantization; /* enum v4l2_quantization */ __u32 xfer_func; /* enum v4l2_xfer_func */ }; /* Pixel format FOURCC depth Description */ /* RGB formats */ #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ #define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ #define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2') /* 16 aaaarrrr ggggbbbb */ #define V4L2_PIX_FMT_XRGB444 v4l2_fourcc('X', 'R', '1', '2') /* 16 xxxxrrrr ggggbbbb */ #define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ #define V4L2_PIX_FMT_ARGB555 v4l2_fourcc('A', 'R', '1', '5') /* 16 ARGB-1-5-5-5 */ #define V4L2_PIX_FMT_XRGB555 v4l2_fourcc('X', 'R', '1', '5') /* 16 XRGB-1-5-5-5 */ #define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ #define V4L2_PIX_FMT_ARGB555X v4l2_fourcc_be('A', 'R', '1', '5') /* 16 ARGB-5-5-5 BE */ #define V4L2_PIX_FMT_XRGB555X v4l2_fourcc_be('X', 'R', '1', '5') /* 16 XRGB-5-5-5 BE */ #define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ #define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */ #define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ #define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ #define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') /* 32 BGRA-8-8-8-8 */ #define V4L2_PIX_FMT_XBGR32 v4l2_fourcc('X', 'R', '2', '4') /* 32 BGRX-8-8-8-8 */ #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ #define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') /* 32 ARGB-8-8-8-8 */ #define V4L2_PIX_FMT_XRGB32 v4l2_fourcc('B', 'X', '2', '4') /* 32 XRGB-8-8-8-8 */ /* Grey formats */ #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ #define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ #define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ') /* 16 Greyscale BE */ /* Grey bit-packed formats */ #define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ /* Palette formats */ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ /* Chrominance formats */ #define V4L2_PIX_FMT_UV8 v4l2_fourcc('U', 'V', '8', ' ') /* 8 UV 4:4 */ /* Luminance+Chrominance formats */ #define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ #define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ #define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */ #define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */ #define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */ #define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */ #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ #define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ #define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */ /* two planes -- one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ #define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ #define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ #define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */ #define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */ /* two non contiguous planes - one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/CrCb 4:2:0 */ #define V4L2_PIX_FMT_NV16M v4l2_fourcc('N', 'M', '1', '6') /* 16 Y/CbCr 4:2:2 */ #define V4L2_PIX_FMT_NV61M v4l2_fourcc('N', 'M', '6', '1') /* 16 Y/CrCb 4:2:2 */ #define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ #define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 macroblocks */ /* three planes - Y Cb, Cr */ #define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */ #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 12 YVU411 planar */ #define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ /* three non contiguous planes - Y, Cb, Cr */ #define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */ #define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'M', '2', '1') /* 12 YVU420 planar */ #define V4L2_PIX_FMT_YUV422M v4l2_fourcc('Y', 'M', '1', '6') /* 16 YUV422 planar */ #define V4L2_PIX_FMT_YVU422M v4l2_fourcc('Y', 'M', '6', '1') /* 16 YVU422 planar */ #define V4L2_PIX_FMT_YUV444M v4l2_fourcc('Y', 'M', '2', '4') /* 24 YUV444 planar */ #define V4L2_PIX_FMT_YVU444M v4l2_fourcc('Y', 'M', '4', '2') /* 24 YVU444 planar */ /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ #define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ /* 10bit raw bayer packed, 5 bytes for every 4 pixels */ #define V4L2_PIX_FMT_SBGGR10P v4l2_fourcc('p', 'B', 'A', 'A') #define V4L2_PIX_FMT_SGBRG10P v4l2_fourcc('p', 'G', 'A', 'A') #define V4L2_PIX_FMT_SGRBG10P v4l2_fourcc('p', 'g', 'A', 'A') #define V4L2_PIX_FMT_SRGGB10P v4l2_fourcc('p', 'R', 'A', 'A') /* 10bit raw bayer a-law compressed to 8 bits */ #define V4L2_PIX_FMT_SBGGR10ALAW8 v4l2_fourcc('a', 'B', 'A', '8') #define V4L2_PIX_FMT_SGBRG10ALAW8 v4l2_fourcc('a', 'G', 'A', '8') #define V4L2_PIX_FMT_SGRBG10ALAW8 v4l2_fourcc('a', 'g', 'A', '8') #define V4L2_PIX_FMT_SRGGB10ALAW8 v4l2_fourcc('a', 'R', 'A', '8') /* 10bit raw bayer DPCM compressed to 8 bits */ #define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8') #define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8') #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') #define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8') #define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ /* 12bit raw bayer packed, 6 bytes for every 4 pixels */ #define V4L2_PIX_FMT_SBGGR12P v4l2_fourcc('p', 'B', 'C', 'C') #define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C') #define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C') #define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C') #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') /* 16 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') /* 16 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB16 v4l2_fourcc('R', 'G', '1', '6') /* 16 RGRG.. GBGB.. */ /* HSV formats */ #define V4L2_PIX_FMT_HSV24 v4l2_fourcc('H', 'S', 'V', '3') #define V4L2_PIX_FMT_HSV32 v4l2_fourcc('H', 'S', 'V', '4') /* compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ #define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ #define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */ #define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 Multiplexed */ #define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */ #define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */ #define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */ #define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */ #define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */ #define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */ #define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 part 2 ES */ #define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */ #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ #define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */ #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */ /* Vendor-specific formats */ #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ #define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ #define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ #define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */ #define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ #define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ #define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ #define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ #define V4L2_PIX_FMT_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') /* compressed RGGB bayer */ #define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ #define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ #define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ #define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ #define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ #define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ #define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ #define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ #define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ #define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */ #define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */ #define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I') /* S5C73M3 interleaved UYVY/JPEG */ #define V4L2_PIX_FMT_Y8I v4l2_fourcc('Y', '8', 'I', ' ') /* Greyscale 8-bit L/R interleaved */ #define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */ #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ #define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */ #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */ /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */ #define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */ #define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g') /* IPU3 packed 10-bit GBRG bayer */ #define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G') /* IPU3 packed 10-bit GRBG bayer */ #define V4L2_PIX_FMT_IPU3_SRGGB10 v4l2_fourcc('i', 'p', '3', 'r') /* IPU3 packed 10-bit RGGB bayer */ /* SDR formats - used only for Software Defined Radio devices */ #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */ #define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */ #define V4L2_SDR_FMT_CS8 v4l2_fourcc('C', 'S', '0', '8') /* complex s8 */ #define V4L2_SDR_FMT_CS14LE v4l2_fourcc('C', 'S', '1', '4') /* complex s14le */ #define V4L2_SDR_FMT_RU12LE v4l2_fourcc('R', 'U', '1', '2') /* real u12le */ #define V4L2_SDR_FMT_PCU16BE v4l2_fourcc('P', 'C', '1', '6') /* planar complex u16be */ #define V4L2_SDR_FMT_PCU18BE v4l2_fourcc('P', 'C', '1', '8') /* planar complex u18be */ #define V4L2_SDR_FMT_PCU20BE v4l2_fourcc('P', 'C', '2', '0') /* planar complex u20be */ /* Touch formats - used for Touch devices */ #define V4L2_TCH_FMT_DELTA_TD16 v4l2_fourcc('T', 'D', '1', '6') /* 16-bit signed deltas */ #define V4L2_TCH_FMT_DELTA_TD08 v4l2_fourcc('T', 'D', '0', '8') /* 8-bit signed deltas */ #define V4L2_TCH_FMT_TU16 v4l2_fourcc('T', 'U', '1', '6') /* 16-bit unsigned touch data */ #define V4L2_TCH_FMT_TU08 v4l2_fourcc('T', 'U', '0', '8') /* 8-bit unsigned touch data */ /* Meta-data formats */ #define V4L2_META_FMT_VSP1_HGO v4l2_fourcc('V', 'S', 'P', 'H') /* R-Car VSP1 1-D Histogram */ #define V4L2_META_FMT_VSP1_HGT v4l2_fourcc('V', 'S', 'P', 'T') /* R-Car VSP1 2-D Histogram */ #define V4L2_META_FMT_UVC v4l2_fourcc('U', 'V', 'C', 'H') /* UVC Payload Header metadata */ /* priv field value to indicates that subsequent fields are valid. */ #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe /* Flags */ #define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA 0x00000001 /* * F O R M A T E N U M E R A T I O N */ struct v4l2_fmtdesc { __u32 index; /* Format number */ __u32 type; /* enum v4l2_buf_type */ __u32 flags; __u8 description[32]; /* Description string */ __u32 pixelformat; /* Format fourcc */ __u32 reserved[4]; }; #define V4L2_FMT_FLAG_COMPRESSED 0x0001 #define V4L2_FMT_FLAG_EMULATED 0x0002 /* Frame Size and frame rate enumeration */ /* * F R A M E S I Z E E N U M E R A T I O N */ enum v4l2_frmsizetypes { V4L2_FRMSIZE_TYPE_DISCRETE = 1, V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, V4L2_FRMSIZE_TYPE_STEPWISE = 3, }; struct v4l2_frmsize_discrete { __u32 width; /* Frame width [pixel] */ __u32 height; /* Frame height [pixel] */ }; struct v4l2_frmsize_stepwise { __u32 min_width; /* Minimum frame width [pixel] */ __u32 max_width; /* Maximum frame width [pixel] */ __u32 step_width; /* Frame width step size [pixel] */ __u32 min_height; /* Minimum frame height [pixel] */ __u32 max_height; /* Maximum frame height [pixel] */ __u32 step_height; /* Frame height step size [pixel] */ }; struct v4l2_frmsizeenum { __u32 index; /* Frame size number */ __u32 pixel_format; /* Pixel format */ __u32 type; /* Frame size type the device supports. */ union { /* Frame size */ struct v4l2_frmsize_discrete discrete; struct v4l2_frmsize_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ }; /* * F R A M E R A T E E N U M E R A T I O N */ enum v4l2_frmivaltypes { V4L2_FRMIVAL_TYPE_DISCRETE = 1, V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, V4L2_FRMIVAL_TYPE_STEPWISE = 3, }; struct v4l2_frmival_stepwise { struct v4l2_fract min; /* Minimum frame interval [s] */ struct v4l2_fract max; /* Maximum frame interval [s] */ struct v4l2_fract step; /* Frame interval step size [s] */ }; struct v4l2_frmivalenum { __u32 index; /* Frame format index */ __u32 pixel_format; /* Pixel format */ __u32 width; /* Frame width */ __u32 height; /* Frame height */ __u32 type; /* Frame interval type the device supports. */ union { /* Frame interval */ struct v4l2_fract discrete; struct v4l2_frmival_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ }; /* * T I M E C O D E */ struct v4l2_timecode { __u32 type; __u32 flags; __u8 frames; __u8 seconds; __u8 minutes; __u8 hours; __u8 userbits[4]; }; /* Type */ #define V4L2_TC_TYPE_24FPS 1 #define V4L2_TC_TYPE_25FPS 2 #define V4L2_TC_TYPE_30FPS 3 #define V4L2_TC_TYPE_50FPS 4 #define V4L2_TC_TYPE_60FPS 5 /* Flags */ #define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ #define V4L2_TC_FLAG_COLORFRAME 0x0002 #define V4L2_TC_USERBITS_field 0x000C #define V4L2_TC_USERBITS_USERDEFINED 0x0000 #define V4L2_TC_USERBITS_8BITCHARS 0x0008 /* The above is based on SMPTE timecodes */ struct v4l2_jpegcompression { int quality; int APPn; /* Number of APP segment to be written, * must be 0..15 */ int APP_len; /* Length of data in JPEG APPn segment */ char APP_data[60]; /* Data in the JPEG APPn segment. */ int COM_len; /* Length of data in JPEG COM segment */ char COM_data[60]; /* Data in JPEG COM segment */ __u32 jpeg_markers; /* Which markers should go into the JPEG * output. Unless you exactly know what * you do, leave them untouched. * Including less markers will make the * resulting code smaller, but there will * be fewer applications which can read it. * The presence of the APP and COM marker * is influenced by APP_len and COM_len * ONLY, not by this property! */ #define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ #define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ #define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ #define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ #define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will * always use APP0 */ }; /* * M E M O R Y - M A P P I N G B U F F E R S */ struct v4l2_requestbuffers { __u32 count; __u32 type; /* enum v4l2_buf_type */ __u32 memory; /* enum v4l2_memory */ __u32 reserved[2]; }; /** * struct v4l2_plane - plane info for multi-planar buffers * @bytesused: number of bytes occupied by data in the plane (payload) * @length: size of this plane (NOT the payload) in bytes * @mem_offset: when memory in the associated struct v4l2_buffer is * V4L2_MEMORY_MMAP, equals the offset from the start of * the device memory for this plane (or is a "cookie" that * should be passed to mmap() called on the video node) * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer * pointing to this plane * @fd: when memory is V4L2_MEMORY_DMABUF, a userspace file * descriptor associated with this plane * @data_offset: offset in the plane to the start of data; usually 0, * unless there is a header in front of the data * * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer * with two planes can have one plane for Y, and another for interleaved CbCr * components. Each plane can reside in a separate memory buffer, or even in * a completely separate memory node (e.g. in embedded devices). */ struct v4l2_plane { __u32 bytesused; __u32 length; union { __u32 mem_offset; unsigned long userptr; __s32 fd; } m; __u32 data_offset; __u32 reserved[11]; }; /** * struct v4l2_buffer - video buffer info * @index: id number of the buffer * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for * multiplanar buffers); * @bytesused: number of bytes occupied by data in the buffer (payload); * unused (set to 0) for multiplanar buffers * @flags: buffer informational flags * @field: enum v4l2_field; field order of the image in the buffer * @timestamp: frame timestamp * @timecode: frame timecode * @sequence: sequence count of this frame * @memory: enum v4l2_memory; the method, in which the actual video data is * passed * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; * offset from the start of the device memory for this plane, * (or a "cookie" that should be passed to mmap() as offset) * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR; * a userspace pointer pointing to this buffer * @fd: for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF; * a userspace file descriptor associated with this buffer * @planes: for multiplanar buffers; userspace pointer to the array of plane * info structs for this buffer * @length: size in bytes of the buffer (NOT its payload) for single-plane * buffers (when type != *_MPLANE); number of elements in the * planes array for multi-plane buffers * * Contains data exchanged by application and driver using one of the Streaming * I/O methods. */ struct v4l2_buffer { __u32 index; __u32 type; __u32 bytesused; __u32 flags; __u32 field; struct timeval timestamp; struct v4l2_timecode timecode; __u32 sequence; /* memory location */ __u32 memory; union { __u32 offset; unsigned long userptr; struct v4l2_plane *planes; __s32 fd; } m; __u32 length; __u32 reserved2; __u32 reserved; }; /* Flags for 'flags' field */ /* Buffer is mapped (flag) */ #define V4L2_BUF_FLAG_MAPPED 0x00000001 /* Buffer is queued for processing */ #define V4L2_BUF_FLAG_QUEUED 0x00000002 /* Buffer is ready */ #define V4L2_BUF_FLAG_DONE 0x00000004 /* Image is a keyframe (I-frame) */ #define V4L2_BUF_FLAG_KEYFRAME 0x00000008 /* Image is a P-frame */ #define V4L2_BUF_FLAG_PFRAME 0x00000010 /* Image is a B-frame */ #define V4L2_BUF_FLAG_BFRAME 0x00000020 /* Buffer is ready, but the data contained within is corrupted. */ #define V4L2_BUF_FLAG_ERROR 0x00000040 /* timecode field is valid */ #define V4L2_BUF_FLAG_TIMECODE 0x00000100 /* Buffer is prepared for queuing */ #define V4L2_BUF_FLAG_PREPARED 0x00000400 /* Cache handling flags */ #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x00000800 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x00001000 /* Timestamp type */ #define V4L2_BUF_FLAG_TIMESTAMP_MASK 0x0000e000 #define V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN 0x00000000 #define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC 0x00002000 #define V4L2_BUF_FLAG_TIMESTAMP_COPY 0x00004000 /* Timestamp sources. */ #define V4L2_BUF_FLAG_TSTAMP_SRC_MASK 0x00070000 #define V4L2_BUF_FLAG_TSTAMP_SRC_EOF 0x00000000 #define V4L2_BUF_FLAG_TSTAMP_SRC_SOE 0x00010000 /* mem2mem encoder/decoder */ #define V4L2_BUF_FLAG_LAST 0x00100000 /** * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor * * @index: id number of the buffer * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for * multiplanar buffers); * @plane: index of the plane to be exported, 0 for single plane queues * @flags: flags for newly created file, currently only O_CLOEXEC is * supported, refer to manual of open syscall for more details * @fd: file descriptor associated with DMABUF (set by driver) * * Contains data used for exporting a video buffer as DMABUF file descriptor. * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF * (identical to the cookie used to mmap() the buffer to userspace). All * reserved fields must be set to zero. The field reserved0 is expected to * become a structure 'type' allowing an alternative layout of the structure * content. Therefore this field should not be used for any other extensions. */ struct v4l2_exportbuffer { __u32 type; /* enum v4l2_buf_type */ __u32 index; __u32 plane; __u32 flags; __s32 fd; __u32 reserved[11]; }; /* * O V E R L A Y P R E V I E W */ struct v4l2_framebuffer { __u32 capability; __u32 flags; /* FIXME: in theory we should pass something like PCI device + memory * region + offset instead of some physical address */ void *base; struct { __u32 width; __u32 height; __u32 pixelformat; __u32 field; /* enum v4l2_field */ __u32 bytesperline; /* for padding, zero if unused */ __u32 sizeimage; __u32 colorspace; /* enum v4l2_colorspace */ __u32 priv; /* reserved field, set to 0 */ } fmt; }; /* Flags for the 'capability' field. Read only */ #define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 #define V4L2_FBUF_CAP_CHROMAKEY 0x0002 #define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 #define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 #define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010 #define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020 #define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040 #define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 /* Flags for the 'flags' field. */ #define V4L2_FBUF_FLAG_PRIMARY 0x0001 #define V4L2_FBUF_FLAG_OVERLAY 0x0002 #define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 #define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010 #define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020 #define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040 struct v4l2_clip { struct v4l2_rect c; struct v4l2_clip *next; }; struct v4l2_window { struct v4l2_rect w; __u32 field; /* enum v4l2_field */ __u32 chromakey; struct v4l2_clip *clips; __u32 clipcount; void *bitmap; __u8 global_alpha; }; /* * C A P T U R E P A R A M E T E R S */ struct v4l2_captureparm { __u32 capability; /* Supported modes */ __u32 capturemode; /* Current mode */ struct v4l2_fract timeperframe; /* Time per frame in seconds */ __u32 extendedmode; /* Driver-specific extensions */ __u32 readbuffers; /* # of buffers for read */ __u32 reserved[4]; }; /* Flags for 'capability' and 'capturemode' fields */ #define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ #define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ struct v4l2_outputparm { __u32 capability; /* Supported modes */ __u32 outputmode; /* Current mode */ struct v4l2_fract timeperframe; /* Time per frame in seconds */ __u32 extendedmode; /* Driver-specific extensions */ __u32 writebuffers; /* # of buffers for write */ __u32 reserved[4]; }; /* * I N P U T I M A G E C R O P P I N G */ struct v4l2_cropcap { __u32 type; /* enum v4l2_buf_type */ struct v4l2_rect bounds; struct v4l2_rect defrect; struct v4l2_fract pixelaspect; }; struct v4l2_crop { __u32 type; /* enum v4l2_buf_type */ struct v4l2_rect c; }; /** * struct v4l2_selection - selection info * @type: buffer type (do not use *_MPLANE types) * @target: Selection target, used to choose one of possible rectangles; * defined in v4l2-common.h; V4L2_SEL_TGT_* . * @flags: constraints flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*. * @r: coordinates of selection window * @reserved: for future use, rounds structure size to 64 bytes, set to zero * * Hardware may use multiple helper windows to process a video stream. * The structure is used to exchange this selection areas between * an application and a driver. */ struct v4l2_selection { __u32 type; __u32 target; __u32 flags; struct v4l2_rect r; __u32 reserved[9]; }; /* * A N A L O G V I D E O S T A N D A R D */ typedef __u64 v4l2_std_id; /* one bit for each */ #define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) #define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) #define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) #define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) #define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) #define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) #define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) #define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) #define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) #define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) #define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) #define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) #define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) /* BTSC */ #define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) /* EIA-J */ #define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) #define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) /* FM A2 */ #define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) #define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) #define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) #define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) #define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) #define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) #define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) #define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000) /* ATSC/HDTV */ #define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) #define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) /* FIXME: Although std_id is 64 bits, there is an issue on PPC32 architecture that makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding this value to 32 bits. As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide), it should work fine. However, if needed to add more than two standards, v4l2-common.c should be fixed. */ /* * Some macros to merge video standards in order to make live easier for the * drivers and V4L2 applications */ /* * "Common" NTSC/M - It should be noticed that V4L2_STD_NTSC_443 is * Missing here. */ #define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ V4L2_STD_NTSC_M_JP |\ V4L2_STD_NTSC_M_KR) /* Secam macros */ #define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ V4L2_STD_SECAM_K |\ V4L2_STD_SECAM_K1) /* All Secam Standards */ #define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ V4L2_STD_SECAM_G |\ V4L2_STD_SECAM_H |\ V4L2_STD_SECAM_DK |\ V4L2_STD_SECAM_L |\ V4L2_STD_SECAM_LC) /* PAL macros */ #define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ V4L2_STD_PAL_B1 |\ V4L2_STD_PAL_G) #define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ V4L2_STD_PAL_D1 |\ V4L2_STD_PAL_K) /* * "Common" PAL - This macro is there to be compatible with the old * V4L1 concept of "PAL": /BGDKHI. * Several PAL standards are missing here: /M, /N and /Nc */ #define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ V4L2_STD_PAL_DK |\ V4L2_STD_PAL_H |\ V4L2_STD_PAL_I) /* Chroma "agnostic" standards */ #define V4L2_STD_B (V4L2_STD_PAL_B |\ V4L2_STD_PAL_B1 |\ V4L2_STD_SECAM_B) #define V4L2_STD_G (V4L2_STD_PAL_G |\ V4L2_STD_SECAM_G) #define V4L2_STD_H (V4L2_STD_PAL_H |\ V4L2_STD_SECAM_H) #define V4L2_STD_L (V4L2_STD_SECAM_L |\ V4L2_STD_SECAM_LC) #define V4L2_STD_GH (V4L2_STD_G |\ V4L2_STD_H) #define V4L2_STD_DK (V4L2_STD_PAL_DK |\ V4L2_STD_SECAM_DK) #define V4L2_STD_BG (V4L2_STD_B |\ V4L2_STD_G) #define V4L2_STD_MN (V4L2_STD_PAL_M |\ V4L2_STD_PAL_N |\ V4L2_STD_PAL_Nc |\ V4L2_STD_NTSC) /* Standards where MTS/BTSC stereo could be found */ #define V4L2_STD_MTS (V4L2_STD_NTSC_M |\ V4L2_STD_PAL_M |\ V4L2_STD_PAL_N |\ V4L2_STD_PAL_Nc) /* Standards for Countries with 60Hz Line frequency */ #define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ V4L2_STD_PAL_60 |\ V4L2_STD_NTSC |\ V4L2_STD_NTSC_443) /* Standards for Countries with 50Hz Line frequency */ #define V4L2_STD_625_50 (V4L2_STD_PAL |\ V4L2_STD_PAL_N |\ V4L2_STD_PAL_Nc |\ V4L2_STD_SECAM) #define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ V4L2_STD_ATSC_16_VSB) /* Macros with none and all analog standards */ #define V4L2_STD_UNKNOWN 0 #define V4L2_STD_ALL (V4L2_STD_525_60 |\ V4L2_STD_625_50) struct v4l2_standard { __u32 index; v4l2_std_id id; __u8 name[24]; struct v4l2_fract frameperiod; /* Frames, not fields */ __u32 framelines; __u32 reserved[4]; }; /* * D V B T T I M I N G S */ /** struct v4l2_bt_timings - BT.656/BT.1120 timing data * @width: total width of the active video in pixels * @height: total height of the active video in lines * @interlaced: Interlaced or progressive * @polarities: Positive or negative polarities * @pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000 * @hfrontporch:Horizontal front porch in pixels * @hsync: Horizontal Sync length in pixels * @hbackporch: Horizontal back porch in pixels * @vfrontporch:Vertical front porch in lines * @vsync: Vertical Sync length in lines * @vbackporch: Vertical back porch in lines * @il_vfrontporch:Vertical front porch for the even field * (aka field 2) of interlaced field formats * @il_vsync: Vertical Sync length for the even field * (aka field 2) of interlaced field formats * @il_vbackporch:Vertical back porch for the even field * (aka field 2) of interlaced field formats * @standards: Standards the timing belongs to * @flags: Flags * @picture_aspect: The picture aspect ratio (hor/vert). * @cea861_vic: VIC code as per the CEA-861 standard. * @hdmi_vic: VIC code as per the HDMI standard. * @reserved: Reserved fields, must be zeroed. * * A note regarding vertical interlaced timings: height refers to the total * height of the active video frame (= two fields). The blanking timings refer * to the blanking of each field. So the height of the total frame is * calculated as follows: * * tot_height = height + vfrontporch + vsync + vbackporch + * il_vfrontporch + il_vsync + il_vbackporch * * The active height of each field is height / 2. */ struct v4l2_bt_timings { __u32 width; __u32 height; __u32 interlaced; __u32 polarities; __u64 pixelclock; __u32 hfrontporch; __u32 hsync; __u32 hbackporch; __u32 vfrontporch; __u32 vsync; __u32 vbackporch; __u32 il_vfrontporch; __u32 il_vsync; __u32 il_vbackporch; __u32 standards; __u32 flags; struct v4l2_fract picture_aspect; __u8 cea861_vic; __u8 hdmi_vic; __u8 reserved[46]; } __attribute__ ((packed)); /* Interlaced or progressive format */ #define V4L2_DV_PROGRESSIVE 0 #define V4L2_DV_INTERLACED 1 /* Polarities. If bit is not set, it is assumed to be negative polarity */ #define V4L2_DV_VSYNC_POS_POL 0x00000001 #define V4L2_DV_HSYNC_POS_POL 0x00000002 /* Timings standards */ #define V4L2_DV_BT_STD_CEA861 (1 << 0) /* CEA-861 Digital TV Profile */ #define V4L2_DV_BT_STD_DMT (1 << 1) /* VESA Discrete Monitor Timings */ #define V4L2_DV_BT_STD_CVT (1 << 2) /* VESA Coordinated Video Timings */ #define V4L2_DV_BT_STD_GTF (1 << 3) /* VESA Generalized Timings Formula */ #define V4L2_DV_BT_STD_SDI (1 << 4) /* SDI Timings */ /* Flags */ /* * CVT/GTF specific: timing uses reduced blanking (CVT) or the 'Secondary * GTF' curve (GTF). In both cases the horizontal and/or vertical blanking * intervals are reduced, allowing a higher resolution over the same * bandwidth. This is a read-only flag. */ #define V4L2_DV_FL_REDUCED_BLANKING (1 << 0) /* * CEA-861 specific: set for CEA-861 formats with a framerate of a multiple * of six. These formats can be optionally played at 1 / 1.001 speed. * This is a read-only flag. */ #define V4L2_DV_FL_CAN_REDUCE_FPS (1 << 1) /* * CEA-861 specific: only valid for video transmitters, the flag is cleared * by receivers. * If the framerate of the format is a multiple of six, then the pixelclock * used to set up the transmitter is divided by 1.001 to make it compatible * with 60 Hz based standards such as NTSC and PAL-M that use a framerate of * 29.97 Hz. Otherwise this flag is cleared. If the transmitter can't generate * such frequencies, then the flag will also be cleared. */ #define V4L2_DV_FL_REDUCED_FPS (1 << 2) /* * Specific to interlaced formats: if set, then field 1 is really one half-line * longer and field 2 is really one half-line shorter, so each field has * exactly the same number of half-lines. Whether half-lines can be detected * or used depends on the hardware. */ #define V4L2_DV_FL_HALF_LINE (1 << 3) /* * If set, then this is a Consumer Electronics (CE) video format. Such formats * differ from other formats (commonly called IT formats) in that if RGB * encoding is used then by default the RGB values use limited range (i.e. * use the range 16-235) as opposed to 0-255. All formats defined in CEA-861 * except for the 640x480 format are CE formats. */ #define V4L2_DV_FL_IS_CE_VIDEO (1 << 4) /* Some formats like SMPTE-125M have an interlaced signal with a odd * total height. For these formats, if this flag is set, the first * field has the extra line. If not, it is the second field. */ #define V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE (1 << 5) /* * If set, then the picture_aspect field is valid. Otherwise assume that the * pixels are square, so the picture aspect ratio is the same as the width to * height ratio. */ #define V4L2_DV_FL_HAS_PICTURE_ASPECT (1 << 6) /* * If set, then the cea861_vic field is valid and contains the Video * Identification Code as per the CEA-861 standard. */ #define V4L2_DV_FL_HAS_CEA861_VIC (1 << 7) /* * If set, then the hdmi_vic field is valid and contains the Video * Identification Code as per the HDMI standard (HDMI Vendor Specific * InfoFrame). */ #define V4L2_DV_FL_HAS_HDMI_VIC (1 << 8) /* A few useful defines to calculate the total blanking and frame sizes */ #define V4L2_DV_BT_BLANKING_WIDTH(bt) \ ((bt)->hfrontporch + (bt)->hsync + (bt)->hbackporch) #define V4L2_DV_BT_FRAME_WIDTH(bt) \ ((bt)->width + V4L2_DV_BT_BLANKING_WIDTH(bt)) #define V4L2_DV_BT_BLANKING_HEIGHT(bt) \ ((bt)->vfrontporch + (bt)->vsync + (bt)->vbackporch + \ (bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch) #define V4L2_DV_BT_FRAME_HEIGHT(bt) \ ((bt)->height + V4L2_DV_BT_BLANKING_HEIGHT(bt)) /** struct v4l2_dv_timings - DV timings * @type: the type of the timings * @bt: BT656/1120 timings */ struct v4l2_dv_timings { __u32 type; union { struct v4l2_bt_timings bt; __u32 reserved[32]; }; } __attribute__ ((packed)); /* Values for the type field */ #define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ /** struct v4l2_enum_dv_timings - DV timings enumeration * @index: enumeration index * @pad: the pad number for which to enumerate timings (used with * v4l-subdev nodes only) * @reserved: must be zeroed * @timings: the timings for the given index */ struct v4l2_enum_dv_timings { __u32 index; __u32 pad; __u32 reserved[2]; struct v4l2_dv_timings timings; }; /** struct v4l2_bt_timings_cap - BT.656/BT.1120 timing capabilities * @min_width: width in pixels * @max_width: width in pixels * @min_height: height in lines * @max_height: height in lines * @min_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000 * @max_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000 * @standards: Supported standards * @capabilities: Supported capabilities * @reserved: Must be zeroed */ struct v4l2_bt_timings_cap { __u32 min_width; __u32 max_width; __u32 min_height; __u32 max_height; __u64 min_pixelclock; __u64 max_pixelclock; __u32 standards; __u32 capabilities; __u32 reserved[16]; } __attribute__ ((packed)); /* Supports interlaced formats */ #define V4L2_DV_BT_CAP_INTERLACED (1 << 0) /* Supports progressive formats */ #define V4L2_DV_BT_CAP_PROGRESSIVE (1 << 1) /* Supports CVT/GTF reduced blanking */ #define V4L2_DV_BT_CAP_REDUCED_BLANKING (1 << 2) /* Supports custom formats */ #define V4L2_DV_BT_CAP_CUSTOM (1 << 3) /** struct v4l2_dv_timings_cap - DV timings capabilities * @type: the type of the timings (same as in struct v4l2_dv_timings) * @pad: the pad number for which to query capabilities (used with * v4l-subdev nodes only) * @bt: the BT656/1120 timings capabilities */ struct v4l2_dv_timings_cap { __u32 type; __u32 pad; __u32 reserved[2]; union { struct v4l2_bt_timings_cap bt; __u32 raw_data[32]; }; }; /* * V I D E O I N P U T S */ struct v4l2_input { __u32 index; /* Which input */ __u8 name[32]; /* Label */ __u32 type; /* Type of input */ __u32 audioset; /* Associated audios (bitfield) */ __u32 tuner; /* enum v4l2_tuner_type */ v4l2_std_id std; __u32 status; __u32 capabilities; __u32 reserved[3]; }; /* Values for the 'type' field */ #define V4L2_INPUT_TYPE_TUNER 1 #define V4L2_INPUT_TYPE_CAMERA 2 #define V4L2_INPUT_TYPE_TOUCH 3 /* field 'status' - general */ #define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ #define V4L2_IN_ST_NO_SIGNAL 0x00000002 #define V4L2_IN_ST_NO_COLOR 0x00000004 /* field 'status' - sensor orientation */ /* If sensor is mounted upside down set both bits */ #define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */ #define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */ /* field 'status' - analog */ #define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ #define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ #define V4L2_IN_ST_NO_V_LOCK 0x00000400 /* No vertical sync lock */ #define V4L2_IN_ST_NO_STD_LOCK 0x00000800 /* No standard format lock */ /* field 'status' - digital */ #define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ #define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ #define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ /* field 'status' - VCR and set-top box */ #define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ /* capabilities flags */ #define V4L2_IN_CAP_DV_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ #define V4L2_IN_CAP_CUSTOM_TIMINGS V4L2_IN_CAP_DV_TIMINGS /* For compatibility */ #define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ #define V4L2_IN_CAP_NATIVE_SIZE 0x00000008 /* Supports setting native size */ /* * V I D E O O U T P U T S */ struct v4l2_output { __u32 index; /* Which output */ __u8 name[32]; /* Label */ __u32 type; /* Type of output */ __u32 audioset; /* Associated audios (bitfield) */ __u32 modulator; /* Associated modulator */ v4l2_std_id std; __u32 capabilities; __u32 reserved[3]; }; /* Values for the 'type' field */ #define V4L2_OUTPUT_TYPE_MODULATOR 1 #define V4L2_OUTPUT_TYPE_ANALOG 2 #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 /* capabilities flags */ #define V4L2_OUT_CAP_DV_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ #define V4L2_OUT_CAP_CUSTOM_TIMINGS V4L2_OUT_CAP_DV_TIMINGS /* For compatibility */ #define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ #define V4L2_OUT_CAP_NATIVE_SIZE 0x00000008 /* Supports setting native size */ /* * C O N T R O L S */ struct v4l2_control { __u32 id; __s32 value; }; struct v4l2_ext_control { __u32 id; __u32 size; __u32 reserved2[1]; union { __s32 value; __s64 value64; char *string; __u8 *p_u8; __u16 *p_u16; __u32 *p_u32; void *ptr; }; } __attribute__ ((packed)); struct v4l2_ext_controls { union { __u32 ctrl_class; __u32 which; }; __u32 count; __u32 error_idx; __u32 reserved[2]; struct v4l2_ext_control *controls; }; #define V4L2_CTRL_ID_MASK (0x0fffffff) #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) #define V4L2_CTRL_ID2WHICH(id) ((id) & 0x0fff0000UL) #define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) #define V4L2_CTRL_MAX_DIMS (4) #define V4L2_CTRL_WHICH_CUR_VAL 0 #define V4L2_CTRL_WHICH_DEF_VAL 0x0f000000 enum v4l2_ctrl_type { V4L2_CTRL_TYPE_INTEGER = 1, V4L2_CTRL_TYPE_BOOLEAN = 2, V4L2_CTRL_TYPE_MENU = 3, V4L2_CTRL_TYPE_BUTTON = 4, V4L2_CTRL_TYPE_INTEGER64 = 5, V4L2_CTRL_TYPE_CTRL_CLASS = 6, V4L2_CTRL_TYPE_STRING = 7, V4L2_CTRL_TYPE_BITMASK = 8, V4L2_CTRL_TYPE_INTEGER_MENU = 9, /* Compound types are >= 0x0100 */ V4L2_CTRL_COMPOUND_TYPES = 0x0100, V4L2_CTRL_TYPE_U8 = 0x0100, V4L2_CTRL_TYPE_U16 = 0x0101, V4L2_CTRL_TYPE_U32 = 0x0102, }; /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ struct v4l2_queryctrl { __u32 id; __u32 type; /* enum v4l2_ctrl_type */ __u8 name[32]; /* Whatever */ __s32 minimum; /* Note signedness */ __s32 maximum; __s32 step; __s32 default_value; __u32 flags; __u32 reserved[2]; }; /* Used in the VIDIOC_QUERY_EXT_CTRL ioctl for querying extended controls */ struct v4l2_query_ext_ctrl { __u32 id; __u32 type; char name[32]; __s64 minimum; __s64 maximum; __u64 step; __s64 default_value; __u32 flags; __u32 elem_size; __u32 elems; __u32 nr_of_dims; __u32 dims[V4L2_CTRL_MAX_DIMS]; __u32 reserved[32]; }; /* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ struct v4l2_querymenu { __u32 id; __u32 index; union { __u8 name[32]; /* Whatever */ __s64 value; }; __u32 reserved; } __attribute__ ((packed)); /* Control flags */ #define V4L2_CTRL_FLAG_DISABLED 0x0001 #define V4L2_CTRL_FLAG_GRABBED 0x0002 #define V4L2_CTRL_FLAG_READ_ONLY 0x0004 #define V4L2_CTRL_FLAG_UPDATE 0x0008 #define V4L2_CTRL_FLAG_INACTIVE 0x0010 #define V4L2_CTRL_FLAG_SLIDER 0x0020 #define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 #define V4L2_CTRL_FLAG_VOLATILE 0x0080 #define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100 #define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200 #define V4L2_CTRL_FLAG_MODIFY_LAYOUT 0x0400 /* Query flags, to be ORed with the control ID */ #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 #define V4L2_CTRL_FLAG_NEXT_COMPOUND 0x40000000 /* User-class control IDs defined by V4L2 */ #define V4L2_CID_MAX_CTRLS 1024 /* IDs reserved for driver specific controls */ #define V4L2_CID_PRIVATE_BASE 0x08000000 /* * T U N I N G */ struct v4l2_tuner { __u32 index; __u8 name[32]; __u32 type; /* enum v4l2_tuner_type */ __u32 capability; __u32 rangelow; __u32 rangehigh; __u32 rxsubchans; __u32 audmode; __s32 signal; __s32 afc; __u32 reserved[4]; }; struct v4l2_modulator { __u32 index; __u8 name[32]; __u32 capability; __u32 rangelow; __u32 rangehigh; __u32 txsubchans; __u32 type; /* enum v4l2_tuner_type */ __u32 reserved[3]; }; /* Flags for the 'capability' field */ #define V4L2_TUNER_CAP_LOW 0x0001 #define V4L2_TUNER_CAP_NORM 0x0002 #define V4L2_TUNER_CAP_HWSEEK_BOUNDED 0x0004 #define V4L2_TUNER_CAP_HWSEEK_WRAP 0x0008 #define V4L2_TUNER_CAP_STEREO 0x0010 #define V4L2_TUNER_CAP_LANG2 0x0020 #define V4L2_TUNER_CAP_SAP 0x0020 #define V4L2_TUNER_CAP_LANG1 0x0040 #define V4L2_TUNER_CAP_RDS 0x0080 #define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 #define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 #define V4L2_TUNER_CAP_FREQ_BANDS 0x0400 #define V4L2_TUNER_CAP_HWSEEK_PROG_LIM 0x0800 #define V4L2_TUNER_CAP_1HZ 0x1000 /* Flags for the 'rxsubchans' field */ #define V4L2_TUNER_SUB_MONO 0x0001 #define V4L2_TUNER_SUB_STEREO 0x0002 #define V4L2_TUNER_SUB_LANG2 0x0004 #define V4L2_TUNER_SUB_SAP 0x0004 #define V4L2_TUNER_SUB_LANG1 0x0008 #define V4L2_TUNER_SUB_RDS 0x0010 /* Values for the 'audmode' field */ #define V4L2_TUNER_MODE_MONO 0x0000 #define V4L2_TUNER_MODE_STEREO 0x0001 #define V4L2_TUNER_MODE_LANG2 0x0002 #define V4L2_TUNER_MODE_SAP 0x0002 #define V4L2_TUNER_MODE_LANG1 0x0003 #define V4L2_TUNER_MODE_LANG1_LANG2 0x0004 struct v4l2_frequency { __u32 tuner; __u32 type; /* enum v4l2_tuner_type */ __u32 frequency; __u32 reserved[8]; }; #define V4L2_BAND_MODULATION_VSB (1 << 1) #define V4L2_BAND_MODULATION_FM (1 << 2) #define V4L2_BAND_MODULATION_AM (1 << 3) struct v4l2_frequency_band { __u32 tuner; __u32 type; /* enum v4l2_tuner_type */ __u32 index; __u32 capability; __u32 rangelow; __u32 rangehigh; __u32 modulation; __u32 reserved[9]; }; struct v4l2_hw_freq_seek { __u32 tuner; __u32 type; /* enum v4l2_tuner_type */ __u32 seek_upward; __u32 wrap_around; __u32 spacing; __u32 rangelow; __u32 rangehigh; __u32 reserved[5]; }; /* * R D S */ struct v4l2_rds_data { __u8 lsb; __u8 msb; __u8 block; } __attribute__ ((packed)); #define V4L2_RDS_BLOCK_MSK 0x7 #define V4L2_RDS_BLOCK_A 0 #define V4L2_RDS_BLOCK_B 1 #define V4L2_RDS_BLOCK_C 2 #define V4L2_RDS_BLOCK_D 3 #define V4L2_RDS_BLOCK_C_ALT 4 #define V4L2_RDS_BLOCK_INVALID 7 #define V4L2_RDS_BLOCK_CORRECTED 0x40 #define V4L2_RDS_BLOCK_ERROR 0x80 /* * A U D I O */ struct v4l2_audio { __u32 index; __u8 name[32]; __u32 capability; __u32 mode; __u32 reserved[2]; }; /* Flags for the 'capability' field */ #define V4L2_AUDCAP_STEREO 0x00001 #define V4L2_AUDCAP_AVL 0x00002 /* Flags for the 'mode' field */ #define V4L2_AUDMODE_AVL 0x00001 struct v4l2_audioout { __u32 index; __u8 name[32]; __u32 capability; __u32 mode; __u32 reserved[2]; }; /* * M P E G S E R V I C E S */ #if 1 #define V4L2_ENC_IDX_FRAME_I (0) #define V4L2_ENC_IDX_FRAME_P (1) #define V4L2_ENC_IDX_FRAME_B (2) #define V4L2_ENC_IDX_FRAME_MASK (0xf) struct v4l2_enc_idx_entry { __u64 offset; __u64 pts; __u32 length; __u32 flags; __u32 reserved[2]; }; #define V4L2_ENC_IDX_ENTRIES (64) struct v4l2_enc_idx { __u32 entries; __u32 entries_cap; __u32 reserved[4]; struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES]; }; #define V4L2_ENC_CMD_START (0) #define V4L2_ENC_CMD_STOP (1) #define V4L2_ENC_CMD_PAUSE (2) #define V4L2_ENC_CMD_RESUME (3) /* Flags for V4L2_ENC_CMD_STOP */ #define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0) struct v4l2_encoder_cmd { __u32 cmd; __u32 flags; union { struct { __u32 data[8]; } raw; }; }; /* Decoder commands */ #define V4L2_DEC_CMD_START (0) #define V4L2_DEC_CMD_STOP (1) #define V4L2_DEC_CMD_PAUSE (2) #define V4L2_DEC_CMD_RESUME (3) /* Flags for V4L2_DEC_CMD_START */ #define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0) /* Flags for V4L2_DEC_CMD_PAUSE */ #define V4L2_DEC_CMD_PAUSE_TO_BLACK (1 << 0) /* Flags for V4L2_DEC_CMD_STOP */ #define V4L2_DEC_CMD_STOP_TO_BLACK (1 << 0) #define V4L2_DEC_CMD_STOP_IMMEDIATELY (1 << 1) /* Play format requirements (returned by the driver): */ /* The decoder has no special format requirements */ #define V4L2_DEC_START_FMT_NONE (0) /* The decoder requires full GOPs */ #define V4L2_DEC_START_FMT_GOP (1) /* The structure must be zeroed before use by the application This ensures it can be extended safely in the future. */ struct v4l2_decoder_cmd { __u32 cmd; __u32 flags; union { struct { __u64 pts; } stop; struct { /* 0 or 1000 specifies normal speed, 1 specifies forward single stepping, -1 specifies backward single stepping, >1: playback at speed/1000 of the normal speed, <-1: reverse playback at (-speed/1000) of the normal speed. */ __s32 speed; __u32 format; } start; struct { __u32 data[16]; } raw; }; }; #endif /* * D A T A S E R V I C E S ( V B I ) * * Data services API by Michael Schimek */ /* Raw VBI */ struct v4l2_vbi_format { __u32 sampling_rate; /* in 1 Hz */ __u32 offset; __u32 samples_per_line; __u32 sample_format; /* V4L2_PIX_FMT_* */ __s32 start[2]; __u32 count[2]; __u32 flags; /* V4L2_VBI_* */ __u32 reserved[2]; /* must be zero */ }; /* VBI flags */ #define V4L2_VBI_UNSYNC (1 << 0) #define V4L2_VBI_INTERLACED (1 << 1) /* ITU-R start lines for each field */ #define V4L2_VBI_ITU_525_F1_START (1) #define V4L2_VBI_ITU_525_F2_START (264) #define V4L2_VBI_ITU_625_F1_START (1) #define V4L2_VBI_ITU_625_F2_START (314) /* Sliced VBI * * This implements is a proposal V4L2 API to allow SLICED VBI * required for some hardware encoders. It should change without * notice in the definitive implementation. */ struct v4l2_sliced_vbi_format { __u16 service_set; /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field (equals frame lines 313-336 for 625 line video standards, 263-286 for 525 line standards) */ __u16 service_lines[2][24]; __u32 io_size; __u32 reserved[2]; /* must be zero */ }; /* Teletext World System Teletext (WST), defined on ITU-R BT.653-2 */ #define V4L2_SLICED_TELETEXT_B (0x0001) /* Video Program System, defined on ETS 300 231*/ #define V4L2_SLICED_VPS (0x0400) /* Closed Caption, defined on EIA-608 */ #define V4L2_SLICED_CAPTION_525 (0x1000) /* Wide Screen System, defined on ITU-R BT1119.1 */ #define V4L2_SLICED_WSS_625 (0x4000) #define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) #define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) struct v4l2_sliced_vbi_cap { __u16 service_set; /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field (equals frame lines 313-336 for 625 line video standards, 263-286 for 525 line standards) */ __u16 service_lines[2][24]; __u32 type; /* enum v4l2_buf_type */ __u32 reserved[3]; /* must be 0 */ }; struct v4l2_sliced_vbi_data { __u32 id; __u32 field; /* 0: first field, 1: second field */ __u32 line; /* 1-23 */ __u32 reserved; /* must be 0 */ __u8 data[48]; }; /* * Sliced VBI data inserted into MPEG Streams */ /* * V4L2_MPEG_STREAM_VBI_FMT_IVTV: * * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI * data * * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header * definitions are not included here. See the MPEG-2 specifications for details * on these headers. */ /* Line type IDs */ #define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1) #define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4) #define V4L2_MPEG_VBI_IVTV_WSS_625 (5) #define V4L2_MPEG_VBI_IVTV_VPS (7) struct v4l2_mpeg_vbi_itv0_line { __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */ __u8 data[42]; /* Sliced VBI data for the line */ } __attribute__ ((packed)); struct v4l2_mpeg_vbi_itv0 { __le32 linemask[2]; /* Bitmasks of VBI service lines present */ struct v4l2_mpeg_vbi_itv0_line line[35]; } __attribute__ ((packed)); struct v4l2_mpeg_vbi_ITV0 { struct v4l2_mpeg_vbi_itv0_line line[36]; } __attribute__ ((packed)); #define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0" #define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0" struct v4l2_mpeg_vbi_fmt_ivtv { __u8 magic[4]; union { struct v4l2_mpeg_vbi_itv0 itv0; struct v4l2_mpeg_vbi_ITV0 ITV0; }; } __attribute__ ((packed)); /* * A G G R E G A T E S T R U C T U R E S */ /** * struct v4l2_plane_pix_format - additional, per-plane format definition * @sizeimage: maximum size in bytes required for data, for which * this plane will be used * @bytesperline: distance in bytes between the leftmost pixels in two * adjacent lines */ struct v4l2_plane_pix_format { __u32 sizeimage; __u32 bytesperline; __u16 reserved[6]; } __attribute__ ((packed)); /** * struct v4l2_pix_format_mplane - multiplanar format definition * @width: image width in pixels * @height: image height in pixels * @pixelformat: little endian four character code (fourcc) * @field: enum v4l2_field; field order (for interlaced video) * @colorspace: enum v4l2_colorspace; supplemental to pixelformat * @plane_fmt: per-plane information * @num_planes: number of planes for this format * @flags: format flags (V4L2_PIX_FMT_FLAG_*) * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding * @quantization: enum v4l2_quantization, colorspace quantization * @xfer_func: enum v4l2_xfer_func, colorspace transfer function */ struct v4l2_pix_format_mplane { __u32 width; __u32 height; __u32 pixelformat; __u32 field; __u32 colorspace; struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES]; __u8 num_planes; __u8 flags; union { __u8 ycbcr_enc; __u8 hsv_enc; }; __u8 quantization; __u8 xfer_func; __u8 reserved[7]; } __attribute__ ((packed)); /** * struct v4l2_sdr_format - SDR format definition * @pixelformat: little endian four character code (fourcc) * @buffersize: maximum size in bytes required for data */ struct v4l2_sdr_format { __u32 pixelformat; __u32 buffersize; __u8 reserved[24]; } __attribute__ ((packed)); /** * struct v4l2_meta_format - metadata format definition * @dataformat: little endian four character code (fourcc) * @buffersize: maximum size in bytes required for data */ struct v4l2_meta_format { __u32 dataformat; __u32 buffersize; } __attribute__ ((packed)); /** * struct v4l2_format - stream data format * @type: enum v4l2_buf_type; type of the data stream * @pix: definition of an image format * @pix_mp: definition of a multiplanar image format * @win: definition of an overlaid image * @vbi: raw VBI capture or output parameters * @sliced: sliced VBI capture or output parameters * @raw_data: placeholder for future extensions and custom formats */ struct v4l2_format { __u32 type; union { struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ struct v4l2_sdr_format sdr; /* V4L2_BUF_TYPE_SDR_CAPTURE */ struct v4l2_meta_format meta; /* V4L2_BUF_TYPE_META_CAPTURE */ __u8 raw_data[200]; /* user-defined */ } fmt; }; /* Stream type-dependent parameters */ struct v4l2_streamparm { __u32 type; /* enum v4l2_buf_type */ union { struct v4l2_captureparm capture; struct v4l2_outputparm output; __u8 raw_data[200]; /* user-defined */ } parm; }; /* * E V E N T S */ #define V4L2_EVENT_ALL 0 #define V4L2_EVENT_VSYNC 1 #define V4L2_EVENT_EOS 2 #define V4L2_EVENT_CTRL 3 #define V4L2_EVENT_FRAME_SYNC 4 #define V4L2_EVENT_SOURCE_CHANGE 5 #define V4L2_EVENT_MOTION_DET 6 #define V4L2_EVENT_PRIVATE_START 0x08000000 /* Payload for V4L2_EVENT_VSYNC */ struct v4l2_event_vsync { /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */ __u8 field; } __attribute__ ((packed)); /* Payload for V4L2_EVENT_CTRL */ #define V4L2_EVENT_CTRL_CH_VALUE (1 << 0) #define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1) #define V4L2_EVENT_CTRL_CH_RANGE (1 << 2) struct v4l2_event_ctrl { __u32 changes; __u32 type; union { __s32 value; __s64 value64; }; __u32 flags; __s32 minimum; __s32 maximum; __s32 step; __s32 default_value; }; struct v4l2_event_frame_sync { __u32 frame_sequence; }; #define V4L2_EVENT_SRC_CH_RESOLUTION (1 << 0) struct v4l2_event_src_change { __u32 changes; }; #define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ (1 << 0) /** * struct v4l2_event_motion_det - motion detection event * @flags: if V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ is set, then the * frame_sequence field is valid. * @frame_sequence: the frame sequence number associated with this event. * @region_mask: which regions detected motion. */ struct v4l2_event_motion_det { __u32 flags; __u32 frame_sequence; __u32 region_mask; }; struct v4l2_event { __u32 type; union { struct v4l2_event_vsync vsync; struct v4l2_event_ctrl ctrl; struct v4l2_event_frame_sync frame_sync; struct v4l2_event_src_change src_change; struct v4l2_event_motion_det motion_det; __u8 data[64]; } u; __u32 pending; __u32 sequence; struct timespec timestamp; __u32 id; __u32 reserved[8]; }; #define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0) #define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK (1 << 1) struct v4l2_event_subscription { __u32 type; __u32 id; __u32 flags; __u32 reserved[5]; }; /* * A D V A N C E D D E B U G G I N G * * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY! */ /* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ #define V4L2_CHIP_MATCH_BRIDGE 0 /* Match against chip ID on the bridge (0 for the bridge) */ #define V4L2_CHIP_MATCH_SUBDEV 4 /* Match against subdev index */ /* The following four defines are no longer in use */ #define V4L2_CHIP_MATCH_HOST V4L2_CHIP_MATCH_BRIDGE #define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */ #define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ #define V4L2_CHIP_MATCH_AC97 3 /* Match against ancillary AC97 chip */ struct v4l2_dbg_match { __u32 type; /* Match type */ union { /* Match this chip, meaning determined by type */ __u32 addr; char name[32]; }; } __attribute__ ((packed)); struct v4l2_dbg_register { struct v4l2_dbg_match match; __u32 size; /* register size in bytes */ __u64 reg; __u64 val; } __attribute__ ((packed)); #define V4L2_CHIP_FL_READABLE (1 << 0) #define V4L2_CHIP_FL_WRITABLE (1 << 1) /* VIDIOC_DBG_G_CHIP_INFO */ struct v4l2_dbg_chip_info { struct v4l2_dbg_match match; char name[32]; __u32 flags; __u32 reserved[32]; } __attribute__ ((packed)); /** * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument * @index: on return, index of the first created buffer * @count: entry: number of requested buffers, * return: number of created buffers * @memory: enum v4l2_memory; buffer memory type * @format: frame format, for which buffers are requested * @reserved: future extensions */ struct v4l2_create_buffers { __u32 index; __u32 count; __u32 memory; struct v4l2_format format; __u32 reserved[8]; }; /* * I O C T L C O D E S F O R V I D E O D E V I C E S * */ #define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability) #define VIDIOC_RESERVED _IO('V', 1) #define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc) #define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) #define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format) #define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers) #define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer) #define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer) #define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer) #define VIDIOC_OVERLAY _IOW('V', 14, int) #define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer) #define VIDIOC_EXPBUF _IOWR('V', 16, struct v4l2_exportbuffer) #define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer) #define VIDIOC_STREAMON _IOW('V', 18, int) #define VIDIOC_STREAMOFF _IOW('V', 19, int) #define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm) #define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm) #define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id) #define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id) #define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard) #define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input) #define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control) #define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control) #define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner) #define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner) #define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio) #define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio) #define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl) #define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu) #define VIDIOC_G_INPUT _IOR('V', 38, int) #define VIDIOC_S_INPUT _IOWR('V', 39, int) #define VIDIOC_G_EDID _IOWR('V', 40, struct v4l2_edid) #define VIDIOC_S_EDID _IOWR('V', 41, struct v4l2_edid) #define VIDIOC_G_OUTPUT _IOR('V', 46, int) #define VIDIOC_S_OUTPUT _IOWR('V', 47, int) #define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output) #define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout) #define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout) #define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator) #define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator) #define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency) #define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency) #define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap) #define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop) #define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop) #define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression) #define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression) #define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) #define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) #define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) #define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) #define VIDIOC_G_PRIORITY _IOR('V', 67, __u32) /* enum v4l2_priority */ #define VIDIOC_S_PRIORITY _IOW('V', 68, __u32) /* enum v4l2_priority */ #define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap) #define VIDIOC_LOG_STATUS _IO('V', 70) #define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) #define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls) #define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls) #define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) #define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) #define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) #define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) #define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) /* * Experimental, meant for debugging, testing and internal use. * Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. * You must be root to use these ioctls. Never use these in applications! */ #define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) #define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) #define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) #define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event) #define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) #define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) #define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers) #define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer) #define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection) #define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection) #define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd) #define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd) #define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings) #define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings) #define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap) #define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band) /* * Experimental, meant for debugging, testing and internal use. * Never use this in applications! */ #define VIDIOC_DBG_G_CHIP_INFO _IOWR('V', 102, struct v4l2_dbg_chip_info) #define VIDIOC_QUERY_EXT_CTRL _IOWR('V', 103, struct v4l2_query_ext_ctrl) /* Reminder: when adding new ioctls please add support for them to drivers/media/v4l2-core/v4l2-compat-ioctl32.c as well! */ #define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ #endif /* __LINUX_VIDEODEV2_H */ xawtv-3.106/libng/writefile.c000066400000000000000000000362741343350355000161420ustar00rootroot00000000000000/* * save pictures to disk (ppm,pgm,jpeg) * * (c) 1998-2000 Gerd Knorr * */ #define NG_PRIVATE #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "byteswap.h" #include "grab-ng.h" #include "writefile.h" /* ---------------------------------------------------------------------- */ /* * count up the latest block of digits in the passed string * (used for filename numbering */ int patch_up(char *name) { char *ptr; for (ptr = name+strlen(name); ptr >= name; ptr--) if (isdigit(*ptr)) break; if (ptr < name) return 0; while (*ptr == '9' && ptr >= name) *(ptr--) = '0'; if (ptr < name) return 0; if (isdigit(*ptr)) { (*ptr)++; return 1; } return 0; } char* snap_filename(char *base, char *channel, char *ext) { static time_t last = 0; static int count = 0; static char *filename = NULL; time_t now; struct tm* tm; char timestamp[32]; time(&now); tm = localtime(&now); if (last != now) count = 0; last = now; count++; if (filename != NULL) free(filename); filename = malloc(strlen(base)+strlen(channel)+strlen(ext)+32); strftime(timestamp,31,"%Y%m%d-%H%M%S",tm); sprintf(filename,"%s-%s-%s-%d.%s", base,channel,timestamp,count,ext); return filename; } /* ---------------------------------------------------------------------- */ static int do_write_jpeg(FILE *fp, struct ng_video_buf *buf, int quality, int gray) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; unsigned int i; unsigned char *line; int line_length; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, fp); cinfo.image_width = buf->fmt.width; cinfo.image_height = buf->fmt.height; cinfo.input_components = gray ? 1: 3; cinfo.in_color_space = gray ? JCS_GRAYSCALE: JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); jpeg_start_compress(&cinfo, TRUE); line_length = gray ? buf->fmt.width : buf->fmt.width * 3; for (i = 0, line = buf->data; i < buf->fmt.height; i++, line += line_length) jpeg_write_scanlines(&cinfo, &line, 1); jpeg_finish_compress(&(cinfo)); jpeg_destroy_compress(&(cinfo)); fclose(fp); return 0; } int write_jpeg(char *filename, struct ng_video_buf *buf, int quality, int gray) { FILE *fp; if (NULL == (fp = fopen(filename,"w"))) { fprintf(stderr,"grab: can't open %s: %s\n",filename,strerror(errno)); return -1; } return do_write_jpeg(fp,buf,quality,gray); } #if 0 int write_jpeg_fd(int fd, struct ng_video_buf *buf, int quality, int gray) { FILE *fp; if (NULL == (fp = fdopen(fd,"w"))) { fprintf(stderr,"grab: can't fdopen(%d): %s\n",fd,strerror(errno)); return -1; } return do_write_jpeg(fp,buf,quality,gray); } #endif int write_ppm(char *filename, struct ng_video_buf *buf) { FILE *fp; if (NULL == (fp = fopen(filename,"w"))) { fprintf(stderr,"grab: can't open %s: %s\n",filename,strerror(errno)); return -1; } fprintf(fp,"P6\n%d %d\n255\n", buf->fmt.width,buf->fmt.height); fwrite(buf->data, buf->fmt.height, 3*buf->fmt.width,fp); fclose(fp); return 0; } int write_pgm(char *filename, struct ng_video_buf *buf) { FILE *fp; if (NULL == (fp = fopen(filename,"w"))) { fprintf(stderr,"grab: can't open %s: %s\n",filename,strerror(errno)); return -1; } fprintf(fp,"P5\n%d %d\n255\n", buf->fmt.width, buf->fmt.height); fwrite(buf->data, buf->fmt.height, buf->fmt.width, fp); fclose(fp); return 0; } /* ---------------------------------------------------------------------- */ /* *.wav I/O stolen from cdda2wav */ /* Copyright (C) by Heiko Eissfeldt */ typedef uint8_t BYTE; typedef uint16_t WORD; typedef uint32_t DWORD; typedef uint32_t FOURCC; /* a four character code */ /* flags for 'wFormatTag' field of WAVEFORMAT */ #define WAVE_FORMAT_PCM 1 /* MMIO macros */ #define mmioFOURCC(ch0, ch1, ch2, ch3) \ ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24)) #define FOURCC_RIFF mmioFOURCC ('R', 'I', 'F', 'F') #define FOURCC_LIST mmioFOURCC ('L', 'I', 'S', 'T') #define FOURCC_WAVE mmioFOURCC ('W', 'A', 'V', 'E') #define FOURCC_FMT mmioFOURCC ('f', 'm', 't', ' ') #define FOURCC_DATA mmioFOURCC ('d', 'a', 't', 'a') typedef struct CHUNKHDR { FOURCC ckid; /* chunk ID */ DWORD dwSize; /* chunk size */ } CHUNKHDR; /* simplified Header for standard WAV files */ typedef struct WAVEHDR { CHUNKHDR chkRiff; FOURCC fccWave; CHUNKHDR chkFmt; WORD wFormatTag; /* format type */ WORD nChannels; /* number of channels (i.e. mono, stereo, etc.) */ DWORD nSamplesPerSec; /* sample rate */ DWORD nAvgBytesPerSec; /* for buffer estimation */ WORD nBlockAlign; /* block size of data */ WORD wBitsPerSample; CHUNKHDR chkData; } WAVEHDR; #if BYTE_ORDER == BIG_ENDIAN # define cpu_to_le32(x) SWAP4((x)) # define cpu_to_le16(x) SWAP2((x)) # define le32_to_cpu(x) SWAP4((x)) # define le16_to_cpu(x) SWAP2((x)) #else # define cpu_to_le32(x) (x) # define cpu_to_le16(x) (x) # define le32_to_cpu(x) (x) # define le16_to_cpu(x) (x) #endif static void wav_init_header(WAVEHDR *fileheader, struct ng_audio_fmt *audio) { /* stolen from cdda2wav */ int nBitsPerSample = ng_afmt_to_bits[audio->fmtid]; int channels = ng_afmt_to_channels[audio->fmtid]; int rate = audio->rate; unsigned long nBlockAlign = channels * ((nBitsPerSample + 7) / 8); unsigned long nAvgBytesPerSec = nBlockAlign * rate; unsigned long temp = /* data length */ 0 + sizeof(WAVEHDR) - sizeof(CHUNKHDR); fileheader->chkRiff.ckid = cpu_to_le32(FOURCC_RIFF); fileheader->fccWave = cpu_to_le32(FOURCC_WAVE); fileheader->chkFmt.ckid = cpu_to_le32(FOURCC_FMT); fileheader->chkFmt.dwSize = cpu_to_le32(16); fileheader->wFormatTag = cpu_to_le16(WAVE_FORMAT_PCM); fileheader->nChannels = cpu_to_le16(channels); fileheader->nSamplesPerSec = cpu_to_le32(rate); fileheader->nAvgBytesPerSec = cpu_to_le32(nAvgBytesPerSec); fileheader->nBlockAlign = cpu_to_le16(nBlockAlign); fileheader->wBitsPerSample = cpu_to_le16(nBitsPerSample); fileheader->chkData.ckid = cpu_to_le32(FOURCC_DATA); fileheader->chkRiff.dwSize = cpu_to_le32(temp); fileheader->chkData.dwSize = cpu_to_le32(0 /* data length */); } static void wav_start_write(int fd, WAVEHDR *fileheader, struct ng_audio_fmt *audio) { wav_init_header(fileheader,audio); write(fd,fileheader,sizeof(WAVEHDR)); } static void wav_stop_write(int fd, WAVEHDR *fileheader, int wav_size) { unsigned long temp = wav_size + sizeof(WAVEHDR) - sizeof(CHUNKHDR); fileheader->chkRiff.dwSize = cpu_to_le32(temp); fileheader->chkData.dwSize = cpu_to_le32(wav_size); lseek(fd,0,SEEK_SET); write(fd,fileheader,sizeof(WAVEHDR)); } /* ---------------------------------------------------------------------- */ struct files_handle { /* file name */ char file[MAXPATHLEN]; /* format */ struct ng_video_fmt video; struct ng_audio_fmt audio; /* *.wav file */ int wav_fd; WAVEHDR wav_header; int wav_size; /* misc */ int gotcha; }; static void* files_open(char *filesname, char *audioname, struct ng_video_fmt *video, const void *priv_video, int fps, struct ng_audio_fmt *audio, const void *priv_audio) { struct files_handle *h; if (video->fmtid != VIDEO_NONE && NULL == filesname) return NULL; if (NULL == (h = malloc(sizeof(*h)))) return NULL; /* init */ memset(h,0,sizeof(*h)); h->video = *video; h->audio = *audio; if (filesname) strcpy(h->file,filesname); if (h->audio.fmtid != AUDIO_NONE) { h->wav_fd = open(audioname, O_CREAT | O_RDWR | O_TRUNC, 0666); if (-1 == h->wav_fd) { fprintf(stderr,"open %s: %s\n",audioname,strerror(errno)); free(h); return NULL; } wav_start_write(h->wav_fd,&h->wav_header,&h->audio); } return h; } static int files_video(void *handle, struct ng_video_buf *buf) { struct files_handle *h = handle; int rc = -1; FILE *fp; if (h->gotcha) { fprintf(stderr,"Oops: can't count up file names any more\n"); return -1; } switch (h->video.fmtid) { case VIDEO_RGB24: rc = write_ppm(h->file, buf); break; case VIDEO_GRAY: rc = write_pgm(h->file, buf); break; case VIDEO_JPEG: if (NULL == (fp = fopen(h->file,"w"))) { fprintf(stderr,"grab: can't open %s: %s\n",h->file,strerror(errno)); rc = -1; } else { fwrite(buf->data,buf->size,1,fp); fclose(fp); rc = 0; } } if (1 != patch_up(h->file)) h->gotcha = 1; return rc; } static int files_audio(void *handle, struct ng_audio_buf *buf) { struct files_handle *h = handle; if (buf->size != write(h->wav_fd,buf->data,buf->size)) return -1; h->wav_size += buf->size; return 0; } static int files_close(void *handle) { struct files_handle *h = handle; if (h->audio.fmtid != AUDIO_NONE) { wav_stop_write(h->wav_fd,&h->wav_header,h->wav_size); close(h->wav_fd); } free(h); return 0; } /* ---------------------------------------------------------------------- */ struct raw_priv { int yuv4mpeg; }; struct raw_handle { /* format */ struct ng_video_fmt video; struct ng_audio_fmt audio; const struct raw_priv *vpriv; /* video file*/ int fd; /* *.wav file */ int wav_fd; WAVEHDR wav_header; int wav_size; }; static void* raw_open(char *videoname, char *audioname, struct ng_video_fmt *video, const void *priv_video, int fps, struct ng_audio_fmt *audio, const void *priv_audio) { struct raw_handle *h; int frame_rate_code = 0; int frame_rate_mul = fps; int frame_rate_div = 1000; if (NULL == (h = malloc(sizeof(*h)))) return NULL; /* init */ memset(h,0,sizeof(*h)); h->video = *video; h->audio = *audio; h->vpriv = priv_video; /* audio */ if (h->audio.fmtid != AUDIO_NONE) { h->wav_fd = open(audioname, O_CREAT | O_RDWR | O_TRUNC, 0666); if (-1 == h->wav_fd) { fprintf(stderr,"open %s: %s\n",audioname,strerror(errno)); free(h); return NULL; } wav_start_write(h->wav_fd,&h->wav_header,&h->audio); } /* video */ if (h->video.fmtid != VIDEO_NONE) { if (h->vpriv && h->vpriv->yuv4mpeg) { switch (fps) { case 23976: frame_rate_code = 1; /* 24000 / 1001 */ frame_rate_mul = 24000; frame_rate_div = 1001; break; case 29970: frame_rate_code = 4; /* 30000 / 1001 */ frame_rate_mul = 30000; frame_rate_div = 1001; break; case 59940: frame_rate_code = 7; /* 60000 / 1001 */ frame_rate_mul = 60000; frame_rate_div = 1001; break; case 24000: frame_rate_code = 2; break; case 25000: frame_rate_code = 3; break; case 30000: frame_rate_code = 5; break; case 50000: frame_rate_code = 6; break; case 60000: frame_rate_code = 8; break; default: fprintf(stderr,"illegal frame rate\n"); free(h); return NULL; } } if (NULL != videoname) { h->fd = open(videoname, O_CREAT | O_RDWR | O_TRUNC, 0666); if (-1 == h->fd) { fprintf(stderr,"open %s: %s\n",videoname,strerror(errno)); if (h->wav_fd) close(h->wav_fd); free(h); return NULL; } } else { h->fd = 1; /* use stdout */ } if (h->vpriv && h->vpriv->yuv4mpeg) { char header[64]; switch (h->vpriv->yuv4mpeg) { case 1: sprintf(header, "YUV4MPEG %d %d %d\n", h->video.width, h->video.height,frame_rate_code); break; case 2: sprintf(header, "YUV4MPEG2 W%d H%d F%d:%d\n", h->video.width, h->video.height, frame_rate_mul, frame_rate_div); break; } write(h->fd, header, strlen(header)); } } return h; } static int raw_video(void *handle, struct ng_video_buf *buf) { struct raw_handle *h = handle; if (h->vpriv && h->vpriv->yuv4mpeg) switch (h->vpriv->yuv4mpeg) { case 1: if (6 != write(h->fd, "FRAME\n", 6)) return -1; break; case 2: if (7 != write(h->fd, "FRAME \n", 7)) return -1; break; } if (buf->size != write(h->fd,buf->data,buf->size)) return -1; return 0; } static int raw_audio(void *handle, struct ng_audio_buf *buf) { struct raw_handle *h = handle; if (buf->size != write(h->wav_fd,buf->data,buf->size)) return -1; h->wav_size += buf->size; return 0; } static int raw_close(void *handle) { struct raw_handle *h = handle; if (h->audio.fmtid != AUDIO_NONE) { wav_stop_write(h->wav_fd,&h->wav_header,h->wav_size); close(h->wav_fd); } if (h->video.fmtid != VIDEO_NONE && 1 != h->fd) close(h->fd); free(h); return 0; } /* ----------------------------------------------------------------------- */ /* data structures describing our capabilities */ static const struct ng_format_list files_vformats[] = { { .name = "ppm", .ext = "ppm", .fmtid = VIDEO_RGB24, },{ .name = "pgm", .ext = "pgm", .fmtid = VIDEO_GRAY, },{ .name = "jpeg", .ext = "jpeg", .fmtid = VIDEO_JPEG, },{ /* EOF */ } }; static struct raw_priv yuv4mpeg = { .yuv4mpeg = 1 }; static struct raw_priv yuv4mpeg2 = { .yuv4mpeg = 2 }; static const struct ng_format_list raw_vformats[] = { { .name = "rgb", .ext = "raw", .fmtid = VIDEO_RGB24, },{ .name = "gray", .ext = "raw", .fmtid = VIDEO_GRAY, },{ .name = "422", .ext = "raw", .fmtid = VIDEO_YUYV, },{ .name = "422p", .ext = "raw", .fmtid = VIDEO_YUV422P, },{ .name = "4mpeg", .desc= "yuv4mpeg (mpeg2enc >= 1.6)", .ext = "yuv", .fmtid = VIDEO_YUV420P, .priv = &yuv4mpeg2, },{ .name = "4mpeg-o", .desc = "yuv4mpeg (old mpeg2enc)", .ext = "yuv", .fmtid = VIDEO_YUV420P, .priv = &yuv4mpeg, },{ /* EOF */ } }; static const struct ng_format_list wav_aformats[] = { { .name = "mono8", .ext = "wav", .fmtid = AUDIO_U8_MONO, },{ .name = "mono16", .ext = "wav", .fmtid = AUDIO_S16_LE_MONO, },{ .name = "stereo", .ext = "wav", .fmtid = AUDIO_S16_LE_STEREO, },{ /* EOF */ } }; struct ng_writer files_writer = { .name = "files", .desc = "multiple image files", .video = files_vformats, .audio = wav_aformats, .wr_open = files_open, .wr_video = files_video, .wr_audio = files_audio, .wr_close = files_close, }; struct ng_writer raw_writer = { .name = "raw", .desc = "single file, raw video data", .video = raw_vformats, .audio = wav_aformats, .wr_open = raw_open, .wr_video = raw_video, .wr_audio = raw_audio, .wr_close = raw_close, }; /* ------------------------------------------------------------------- */ void ng_writefile_init(void) { ng_writer_register(NG_PLUGIN_MAGIC,"built-in",&files_writer); ng_writer_register(NG_PLUGIN_MAGIC,"built-in",&raw_writer); } xawtv-3.106/libng/writefile.h000066400000000000000000000004441343350355000161350ustar00rootroot00000000000000int patch_up(char *name); char* snap_filename(char *base, char *channel, char *ext); int write_jpeg(char *filename, struct ng_video_buf *buf, int quality, int gray); int write_ppm(char *filename, struct ng_video_buf *buf); int write_pgm(char *filename, struct ng_video_buf *buf); xawtv-3.106/man/000077500000000000000000000000001343350355000134505ustar00rootroot00000000000000xawtv-3.106/man/Subdir.mk000066400000000000000000000023751343350355000152400ustar00rootroot00000000000000man1 := $(wildcard $(srcdir)/man/*.1) man5 := $(wildcard $(srcdir)/man/*.5) man8 := $(wildcard $(srcdir)/man/*.8) install:: $(INSTALL_DIR) $(mandir)/man1 $(INSTALL_DIR) $(mandir)/man5 $(INSTALL_DIR) $(mandir)/man8 $(INSTALL_DATA) $(man1) $(mandir)/man1 $(INSTALL_DATA) $(man5) $(mandir)/man5 $(INSTALL_DATA) $(man8) $(mandir)/man8 lang-all := $(wildcard $(srcdir)/man/*/*.[0-9]) lang-all := $(patsubst $(srcdir)/man/%,%,$(lang-all)) lang-man1 := $(filter %.1,$(lang-all)) lang-man5 := $(filter %.5,$(lang-all)) lang-man8 := $(filter %.8,$(lang-all)) langs-1 := $(patsubst %/,inst1-%,$(sort $(dir $(lang-man1)))) langs-5 := $(patsubst %/,inst5-%,$(sort $(dir $(lang-man5)))) langs-8 := $(patsubst %/,inst8-%,$(sort $(dir $(lang-man8)))) pages-1 = $(patsubst %,$(srcdir)/man/%,$(filter $*/%,$(lang-man1))) pages-5 = $(patsubst %,$(srcdir)/man/%,$(filter $*/%,$(lang-man5))) pages-8 = $(patsubst %,$(srcdir)/man/%,$(filter $*/%,$(lang-man8))) install:: $(langs-1) $(langs-5) $(langs-8) inst1-%: $(INSTALL_DIR) $(mandir)/$*/man1 $(INSTALL_DATA) $(pages-1) $(mandir)/$*/man1 inst5-%: $(INSTALL_DIR) $(mandir)/$*/man5 $(INSTALL_DATA) $(pages-5) $(mandir)/$*/man5 inst8-%: $(INSTALL_DIR) $(mandir)/$*/man8 $(INSTALL_DATA) $(pages-8) $(mandir)/$*/man8 xawtv-3.106/man/alevtd.1000066400000000000000000000055541343350355000150220ustar00rootroot00000000000000.TH alevtd 1 "(c) 2000 Gerd Knorr" .SH NAME alevtd - webserver for videotext pages .SH SYNOPSIS .B alevtd [ options ] .SH DESCRIPTION .B alevtd is http daemon which serves videotext pages as HTML. Tune in some station with a utility like v4lctl or some TV application. Then start it and point your browser to http://localhost:5654/ .P Pages may be requested either in HTML format (http://localhost:5654// or http://localhost:5654//.html) or in ASCII text format (http://localhost:5654//.txt). Subpage "00" can be used for pages without subpages. .SH OPTIONS .TP .B -h print a short \fBh\fPelp text and the default values for all options. .TP .B -v dev set \fBv\fPbi device (default: /dev/vbi0). .TP .B -d enable \fBd\fPebug output. .TP .B -s Write a start/stop notice and serious errors to the \fBs\fPyslog. Specify this option twice to get a verbose log (additional log events like dropped connections). .TP .B -t sec set network \fBt\fPimeout to >sec< seconds. .TP .B -c n set the number of allowed parallel \fBc\fPonnections to >n<. This is a per-thread limit. .TP .B -p port listen on \fBp\fPort >port< for incoming connections. Default 5654. .TP .B -n hostname set the host\fBn\fPame which the server should use (required for redirects). .TP .B -i ip bind to \fBI\fPP-address >ip<. .TP .B -l log \fBl\fPog all requests to the logfile >log< (common log format). Using "-" as filename makes alevtd print the access log to stdout, which is only useful together with the -F switch (see below). .TP .B -L log same as above, but additional flush every line. Useful if you want monitor the logfile with tail -f. .TP .B -u user set \fBu\fPid to >user< (after binding to the tcp port). This option is allowed for root only. .TP .B -g group set \fBg\fPid to >group< (after binding to the tcp port). This option is allowed for root only. .TP .B -F don't run as daemon. alevtd will not fork into background, not detach from terminal and report errors to stderr. .TP .B -r poll tv frequency, clear vtx page cache if a frequency change was detected. .SH SEE ALSO alevt(1), xawtv(1), v4lctl(1) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 2000 Gerd Knorr .P 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. .P 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. .P 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. xawtv-3.106/man/dump-mixers.1000066400000000000000000000004421343350355000160040ustar00rootroot00000000000000.TH dump-mixers 1 "(c) Gerd Knorr" .SH NAME dump-mixers - dump OSS mixer settings to standard output .SH SYNOPSIS .B dump-mixers .SH DESCRIPTION .B dump-mixers just does what the name suggests: it dumps the current (oss) mixer settings to stdout. .SH AUTHOR Gerd Knorr xawtv-3.106/man/es/000077500000000000000000000000001343350355000140575ustar00rootroot00000000000000xawtv-3.106/man/es/fbtv.1000066400000000000000000000132421343350355000151040ustar00rootroot00000000000000.TH fbtv 1 "(c) 1998 Gerd Knorr" .SH NOMBRE fbtv - un programa para ver la tele en la consola .SH SINOPSIS .B fbtv [ opciones ] [ nombre cadena ] .SH DESCRIPCIÓN .B fbtv es un programa para ver la tele en su equipo linux. Se ejecuta sobre el dispositivo del framebuffer gráfico (/dev/fb0). Necesitará un kernel 2.1.x para poder usarlo. .B fbtv comparte el fichero de configuración ($HOME/.xawtv) con el programa .B xawtv. Mire la página del xawtv(1) para más detalles sobre el formato del fichero de configuración. .SH OPCIONES .TP .B -o base establece la cadena base para los ficheros de capturas. El nombre del fichero será "base-fecha-nr.ext". .TP .B -v Mostrar más información. .TP .B -c dispositivo dispositivo video4linux (por defecto /dev/video0). .TP .B -D driver driver video4linux (por defecto "libv4l"). .TP .B -d dispositivo dispositivo framebuffer (por defecto $FRAMEBUFFER; o /dev/fb0 si esa variable de entorno no está establecida) .TP .B -g imagen en escala de grises (sólo funciona en modo de 256 colores) .TP .B -s anchoxalto muestra la imagen de TV de tamaño .B ancho x .B alto en la esquina superior derecha. .TP .B -f fuente fuente para el texto. Por defecto buscará lat1-16.psf en /usr/lib/kbd/consolefonts y /usr/share/consolefonts. Si tiene un servidor de fuentes X11 local ejecutándose (o la variable de entorno FONTSERVER apuntando a algún servidor en funcionamiento), puede dar aquí una especificación de fuentes X11. .TP .B -m modo modo de video para la televisión. fbtv buscará el modo en /etc/fb.modes. .TP .B -j joydev dispositivo de joystick para controlar a fbtv. .TP .B -k mantiene la captura al cambiar de consola. Puede ser útil junto con la opción -s, tendrá la imagen de video mientras trabaja en otra consola. Esto es más o menos un truco feo. Sólo funciona si todas las consolas tienen el mismo modo de video y fbcon no usa "panning" para acelerar el scroll. También es útil para una configuración multi-pantalla. .TP .B -q modo silencioso. No reserva espacio para la línea de estado en la parte superior, no muestra los mensajes de estado ni el reloj. Se puede cambiar esta opción en tiempo de ejecución ('F'). .TP .B -M EXPERIMENTAL: Activa el modo de escalado (escribe yuv en la memoria fuera de la pantalla y le permite a la tarjeta gráfica escalar el video). Hardware soportado: Matrox G200/G400 (con matroxfb) y ATI Mach64 VT/GT (con atyfb, sólo a 16bpp). Necesita al menos bttv-0.7.16 y kernel 2.3.50. .SH MODO DE USO fbtv funciona más o menos como el xawtv desde el punto de vista del usuario. Habrá notado que el xawtv tiene un montón de atajos de teclado. También funcionan en fbtv (si son de utilidad). Aquí va la lista: .nf G Capturar (\fBG\fPrab) imagen (tamaño completo, ppm) J Capturar imagen (tamaño completo, \fBj\fPpeg) F Pantalla completa. Selecciona modo silencioso (ver arriba). arr./abaj. sintoniza el anterior/siguiente canal izq./der. ajuste fino repag/avpag anterior/siguiente cadena ESC,Q \fBQ\fPuitar X \fBQ\fPuitar, pero dejando el sonido activado. +/- Subir o bajar volumen Intro silencio .fi Las teclas asignadas a canales, definidas en $HOME/.xawtv funcionan también, con una excepción: las teclas modificadoras (algo como "key = Ctrl+F1") no funcionan. .SH TV A PANTALLA COMPLETA Algunos truquillos de Dag Bakke : .P Las tarjetas BT8xx pueden producir imágenes de hasta 768x576 pixels. Para que el fbtv pueda hacer uso de todo el tamaño del monitor y obtener la mejor calidad de imagen, necesita crear una consola framebuffer de 768x576 pixels. Se puede conseguir esto con la utilidad fbset(1), que está disponible en varios sitios. Mire en: http://www.cs.kuleuven.ac.be/~geert/bin/ .P O, puede dejar a fbtv que realice los cambios de modo con la opción -m. Esto requiere de una pequeña base de datos con los modos de video disponibles. El fichero que contiene los modos de video es normalmente /etc/fb.modes. Por ejemplo, la siguiente entrada produce un modo 768x576x32bpp, con 75Hz de refresco en una Matrox G200. .nf mode "tv" # D: 49.188 MHz, H: 46.580 kHz, V: 75.008 Hz geometry 768 576 768 576 32 timings 20330 128 32 32 8 128 5 endmode .fi El comando "fbtv -q -mtv" da por tanto una imagen clara de TV (bueno, dependiendo de la señal recibida, claro) en toda la pantalla. Ponga el alias 'tv' a este comando, y ya está. .P .B ¡OJO! Por favor tenga en cuenta que su monitor puede soportar, o puede que no, esa resolución "personalizada". Y que un mal uso de la mencionada utilidad fbset puede tostar su monitor. Es mucho más fácil sacar humo de un componente electrónico, que meterlo dentro. .P Se puede conseguir una base de datos de modos estándar VESA en: ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/fb.modes.vesa60.gz .SH VEA TAMBIÉN xawtv(1) .SH AUTOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997,98 Gerd Knorr 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. .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/es/rootv.1000066400000000000000000000030241343350355000153110ustar00rootroot00000000000000.TH rootv 1 "(c) 2000 Gerd Knorr" .SH NOMBRE rootv - muestra TV/video como fondo de la ventana raíz .SH SINOPSIS .B rootv [ -stop | -wm ] .SH DESCRIPCIÓN .B rootv pone video en la ventana raíz (fondo) de su pantalla. Requiere la extensión Xvideo. Si se arranca con -stop se parará el video. .P rootv por si mismo no provee de ningún control sobre el video/audio/sintonizador. Se puede usar v4lctl para esta función. Puede poner, por ejemplo, llamadas a v4lctl dentro de los menús de su window manager. "rootv -wm" creará un menú para el WindowMaker con todos los canales del fichero de configuración ~/.xawtv. .SH VEA TAMBIÉN xawtv(1), fbtv(1), v4lctl(1) .SH AUTOR Gerd Knorr .SH COPYRIGHT Copyright (C) 2000 Gerd Knorr .P 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. .P 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. .P 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. .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/es/scantv.1000066400000000000000000000036321343350355000154430ustar00rootroot00000000000000.TH scantv 1 "(c) 2000 Gerd Knorr" .SH NOMBRE scantv - escanea un dispositivo v4l en busca de canales de TV. .SH SINOPSIS .B scantv [ opciones ] .SH DESCRIPCIÓN .B scantv escanea un dispositivo v4l en busca de canales de TV en emisión y escribe un fichero de configuración para xawtv/fbtv. .SH OPCIONES .TP .B -n norma establece la \fBn\fPorma de tv. scantv preguntará interactivamente si no se le da ninguna. .TP .B -f tabla establece la tabla de \fBf\fPrecuencias. scantv preguntará interactivamente si no se le da ninguna. .TP .B -o fichero especifica el fichero de salida. Si no se especifica ninguno scantv lo escribirá por la salida estándar. .TP .B -c dispositivo especifica el fichero de dispositivo de video. Por defecto /dev/video0. .TP .B -D driver especifica el nombre de driver. Por defecto "libv4l". .TP .B -C dispositivo especifica el fichero de dispositivo vbi. Por defecto /dev/vbi0. .TP .B -s saltar el e\fBs\fPcaneo de canales, simplemente escribe la norma y tabla de frecuencias en el fichero de configuración. .SH VEA TAMBIÉN xawtv(1), fbtv(1) .SH AUTOR Gerd Knorr .SH COPYRIGHT Copyright (C) 2000 Gerd Knorr .P 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. .P 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. .P 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. .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/es/streamer.1000066400000000000000000000034471343350355000157730ustar00rootroot00000000000000.TH streamer 1 .SH NOMBRE streamer - graba audio y/o video .SH SINOPSIS .B streamer [ opciones ] .SH DESCRIPCIÓN .B streamer lee datos de audio y/o de video de /dev/video0 y /dev/dsp, y los escribe en el disco. Se soportan varios formatos de salida. Arranque el streamer con la opción '-h' para obtener una lista de las opciones y de los formatos de salida soportados. .P streamer usará la extensión del fichero de salida para averiguar el formato a usar. Sólo son necesarias las opciones -f/-F si la extensión permite más de un formato. .P Puede parar la grabación sin problemas en cualquier momento con Ctrl+C. streamer capturará la señal y parará la grabación correctamente (por ejemplo, escribe la cabecera del fichero de la película) antes de salir. .SH EJEMPLOS .TP .B streamer -o foobar.jpeg escribe un fichero jpeg. .TP .B streamer -o quicktime.mov -f yuv2 -F stereo -r 12 -t 120 graba una película corta en quicktime (120 imágenes / 12 fps => 10 segundos). .SH VEA TAMBIÉN xawtv(1), v4lctl(1) .SH AUTOR Gerd Knorr .SH COPYRIGHT 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. .P 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. .P 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. .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/es/subtitles.1000066400000000000000000000013431343350355000161600ustar00rootroot00000000000000.TH subtitles 1 "(c) 2000 Gerd Knorr" .SH NOMBRE subtitles - muestra subtítulos en xawtv. .SH SINOPSIS .B subtitles [ -help | -tty ] .SH DESCRIPCIÓN .B subtitles obtiene la página especificada del teletexto mediante la utilidad alevt-cap y la muestra por medio de xawtv-remote en un bucle sin fin. Es sobre todo útil para páginas que incorporan subtítulos para el programa de TV que se emite. Es la página 150 en alemania (y la 888 en españa). .SH OPCIONES .TP .B -help muestra un breve mensaje de ayuda. .TP .B -tty vuelca una copia de la página del teletexto a la tty. .SH VEA TAMBIÉN xawtv(1), xawtv-remote(1), alevt-cap(1) .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/es/ttv.1000066400000000000000000000027411343350355000147620ustar00rootroot00000000000000.TH ttv 1 "(c) 2001 Gerd Knorr" .SH NOMBRE ttv - muestra TV/video en una tty .SH SYNOPSIS .B ttv [ opciones ] [ nombre cadena ] .SH DESCRIPTION .B ttv muestra TV/video en un terminal, dibujando las imágenes mediante aalib. .SH OPCIONES .TP .B -h muestra un mensaje de ayuda. .TP .B -f usa la función de dibujado rápido de aalib. .TP .B -c dispositivo dispositivo de video4linux (por defecto /dev/video0). .TP .B -D driver driver de video4linux (por defecto "libv4l"). .P Hay además muchas opciones para aalib, mire la documentación de aalib para más detalles. El texto de ayuda incluye una lista. .SH VEA TAMBIÉN xawtv(1), fbtv(1) .SH AUTOR Gerd Knorr .SH COPYRIGHT Copyright (C) 2000 Gerd Knorr .P 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. .P 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. .P 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. .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/es/v4l-conf.8000066400000000000000000000060211343350355000155770ustar00rootroot00000000000000.TH v4l-conf 8 "(c) 1997-99 Gerd Knorr" .SH NOMBRE v4l-conf - configura un driver video4linux .SH SINOPSIS .B v4l-conf [ opciones ] .SH DESCRIPCIÓN .B v4l-conf es una pequeña herramienta auxiliar. Trata de averiguar el modo del video y la dirección base del framebuffer de la tarjeta gráfica y configura un driver video4linux como el bttv. Esto es necesario para drivers que pueden enviar el video por DMA a través de PCI directamente a la memoria de video. .P Normalmente no es necesario usar v4l-conf manualmente, xawtv(1) y fbtv(1) lo ejecutan automáticamente al inicio. Puede ser útil en caso de problemas en la ejecución de esos programas. Se debe instalar .B v4l-conf como suid-root. .P .B v4l-conf tiene tres maneras para obtener la información: .TP 3 * Pregunta al servidor X usando la extensión DGA de XF86. Esto es lo que hace por defecto si la variable de entorno DISPLAY está establecida. .TP 3 * Pregunta al driver framebuffer. Esto es lo que hace por defecto si DISPLAY no está establecida. .TP 3 * Pregunta al driver de la consola. Se usa sólamente en mklinux. .SH OPCIONES .TP 4 \fB-h\fP Muestra una breve descripción de todas las opciones. .TP 4 \fB-q\fP Estar callado. .TP 4 \fB-d\fP dpy Usa el display X11 \fBdpy\fP para obtener los parámetros. .TP 4 \fB-f\fP Usa el driver framebuffer para obtener los parámetros. .TP 4 \fB-c\fP dispositivo Establece el dispositivo de video4linux. .TP 4 \fB-b\fP n fuerza una profundidad de color de .B n bpp. Funciona para cambiar entre 15/16 y 24/32 bpp. .TP 4 \fB-s\fP n Desplaza la imagen de video .B n bytes. .TP 4 \fB-a\fP adr Establece la dirección del framebuffer a \fBadr\fP. El valor hay que especificarlo en hexadecimal. Sólo se le permite esta opción a root. No se puede sobreescribir el valor detectado automáticamente, esta opción sólo es válida si la autodetección no funciona debido a que el servidor X no tiene soporte DGA. Puede poner esto en el fichero /etc/conf.modules, como "post-install bttv ..." por ejemplo. .SH BUGS Espero no haber dejado ninguna fisura de seguridad. Si encuentra alguna envíeme una nota. Prefiero correos que incluyan parches :-) .SH VEA TAMBIÉN xawtv(1), fbtv(1) .SH AUTOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997-99 Gerd Knorr .P 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. .P 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. .P 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. .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/es/v4lctl.1000066400000000000000000000000301343350355000153420ustar00rootroot00000000000000.so man1/xawtv-remote.1 xawtv-3.106/man/es/xawtv-remote.1000066400000000000000000000132211343350355000166020ustar00rootroot00000000000000.TH xawtv-remote 1 "(c) 1997-99 Gerd Knorr" .SH NOMBRE xawtv-remote, v4lctl -- control de dispositivos video4linux .SH SINOPSIS .B xawtv-remote [ opciones ] comando .br .B v4lctl [ opciones ] comando .SH DESCRIPCIÓN .B xawtv-remote y .B v4lctl se pueden usar para controlar una tarjeta de televisión bajo video4linux. .B xawtv-remote le pasa el comando a una instancia en ejecución de xawtv o motv por medio de propiedades X11. .B v4lctl establece los parámetros directamente. .SH OPCIONES .B xawtv-remote conoce las siguientes opciones: .TP .B -h muestra un breve mensaje de ayuda .TP .B -d dpy Establece el display X11 .TP .B -i id Establece el identificador (ID) de ventana. .P .B v4lctl entiende estas opciones: .TP .B -h muestra un breve mensaje de ayuda .TP .B -c device Establece el dispositivo video4linux. .TP .B -v n Establece el nivel \fBn\fP de mensajes de salida, donde n = [0..2] .SH COMANDOS Las dos herramientas usan básicamente el mismo juego de comandos. Algunos son sólamente útiles para el xawtv-remote (pantalla completa, por ejemplo). .TP .B setstation [ | | next | prev | back ] Establece el canal de TV. La selección se realiza con las cadenas configuradas en el fichero de configuración .xawtv. El argumento puede ser el nombre de la cadena o un número (el primero listado en el fichero de configuración es el 0, ...). next/prev salta a la cadena siguiente o previa de la lista de cadenas, y back a la seleccionada previamente. .TP .B setchannel [ | next | prev ] Sintoniza un canal. .TP .B setfreqtab Establece la tabla de frecuencias. En el menú del xawtv hay una lista de las opciones válidas. .TP .B setnorm Establece la norma de TV (NTSC/PAL/SECAM). .TP .B setinput [ | next ] Establece la entrada de video (Television/Composite1/...) .TP .B capture [ on | off | overlay | grabdisplay ] Establece el modo de captura. .TP .B volume .TP .B color .TP .B hue .TP .B bright .TP .B contrast Establece el parámetro al valor especificado. debe ser algo de lo siguiente: Un valor en tanto por ciento ("70%" por ejemplo). Valores absolutos ("32768"), el rango válido es específico del hardware. Los valores relativos se pueden especificar precediendo el número con "+=" o "-=" ("+=10%" o "-=2000"). También se aceptan las palabras "inc" y "dec" que incrementarán y disminuirán el valor en pequeños pasos. .TP .B setattr El valor de algún atributo (color, contraste, ...) también se puede especificar de esta manera. .TP .B show [ ] Muestra el valor actual de algún atributo. .TP .B list Lista todos los atributos válidos con todas sus propiedades (valor por defecto, rango, ...) .TP .B snap [ jpeg | ppm ] [ full | win | widthxheight ] Captura una imagen. .TP .B webcam Captura una imagen. Básicamente hace lo mismo que "snap jpeg win ". También funciona cuando la grabación avi está activa. Escribe en un fichero temporal y lo renombra cuando ha realizado la acción, por lo tanto no habrá nunca un fichero inválido. .TP .B movie driver [ files | raw | avi | qt ] .TP .B movie video [ ppm | pgm | jpeg | rgb | gray | 422 | 422p | rgb15 | rgb24 | mjpeg | jpeg | raw | mjpa | png ] .TP .B movie fps .TP .B movie audio [ mono8 | mono16 | stereo ] .TP .B movie rate .TP .B movie fvideo .TP .B movie faudio .TP .B movie start .TP .B movie stop controla la grabación de películas del xawtv. .TP .B fullscreen Selecciona el modo a pantalla completa. .TP .B showtime Muestra la hora (lo mismo que hace la tecla 'D' en xawtv). .TP .B msg texto Muestra el texto en el display on-screen (título de la ventana / esquina superior izquierda a pantalla completa). .TP .B vtx linea1 linea2 [ ... ] Muestra subtítulos. Saca una pequeña ventana en la parte inferior de la pantalla. Está pensado para actuar como interfaz para mostrar subtítulos (con frecuencia en la página 150 del teletexto en europa, de ahí el nombre) de programas externos. Nota: en españa se suele usar la página 888 para los subtítulos. .br Cada línea de comandos del argumento es una línea, cero líneas quita la ventana. Se puede dar color al texto con la secuencia de control "ESC tinta fondo". Tanto tinta como fondo tienen un rango de 0 a 7 (colores ansi term). Ejemplo: "\\03347 hola mundo" está en azúl sobre fondo blanco. "\\033" debe ser un carácter de escape real, no vale con una cadena. Con bash lo puedes obtener con ^V ESC. vtx también entiende secuencias de escape ANSI tty para el color. .TP .B quit cierra el xawtv .TP .B keypad n entra el dígito 'n'. Eso es la selección de canales mediante dos dígitos, entrando dos dígitos en 5 segundos cambia a la cadena seleccionada. Útil para el lirc. .SH VEA TAMBIÉN xawtv(1), motv(1), xawtvrc(5) .SH AUTOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997-2001 Gerd Knorr .P 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. .P 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. .P 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. .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/es/xawtv.1000066400000000000000000000220461343350355000153160ustar00rootroot00000000000000.TH xawtv 1 "(c) 1997-2001 Gerd Knorr" .SH NOMBRE xawtv - un programa X11 para ver la tele .SH SINOPSIS .B xawtv [ opciones ] [ nombre cadena ] .SH DESCRIPCIÓN .B xawtv es un programa para X11 para ver la tele en su equipo unix. Usa los widgets Athena. .SH OPCIONES Todas las opciones de la línea de comandos tienen un recurso, por tanto puede ponerlas también en el fichero .Xdefaults. .TP \fB-h\fP, \fB-help\fP Muestra una breve descripción de todas las opciones de línea de comandos. .TP \fB-hwscan\fP Muestra una lista de los dispositivos disponibles. .TP \fB-f\fP, \fB-fullscreen\fP arranca en modo de pantalla completa. .br Recurso: xawtv.fullscreen (bool). .TP \fB-n\fP, \fB-noconf\fP no lee el fichero de configuración ($HOME/.xawtv). .br Recurso: xawtv.readconfig (bool). .TP \fB-o\fP, \fB-outfile\fP base establece la cadena base para los ficheros de capturas. El nombre del fichero será "base-fecha-nr.ext". .br Recurso: xawtv.basename (string). .TP \fB-c\fP, \fB-device\fP dispositivo establece el dispositivo video4linux (por defecto /dev/video0). Esta opción también deshabilita Xvideo. .br Recurso: xawtv.device (string). .TP \fB-D\fP, \fB-driver\fP nombre establece el driver video4linux (por defecto "libv4l"). Esta opción también deshabilita Xvideo. .br Recurso: xawtv.driver (string). .TP \fB-C\fP, \fB-dspdev\fP dispositivo establece el dispositivo de audio (por defecto /dev/dsp). .br Recurso: xawtv.dspdev (string). .TP \fB-vbidev\fP dispositivo establece el dispositivo vbi (por defecto /dev/vbi0). .br Recurso: xawtv.vbidev (string). .TP \fB-c\fP, \fB-xvport\fP número establece el puerto Xvideo (por defecto el primero que sea usable si Xvideo está disponible). Esta opción también habilita el soporte Xvideo. .br Recurso: xawtv.xvport (int). .TP \fB-joydev\fP dispositivo dispositivo del joystick a usar para controlar xawtv. .br Recurso: xawtv.joydev (string). .TP \fB-v\fP, \fB-debug\fP nivel Aporta mayor nivel de información, .B nivel puede ser 0 (por defecto), 1 o 2. Existe sólo para depuración y en caso de problemas. .br Recurso: xawtv.debug (int). .TP \fB-remote\fP el display X11 es remoto. Esto básicamente deshabilita el modo overlay, lo puede necesitar si xawtv no consigue detectar un display X11 remoto. .br Recurso: xawtv.remote (bool). .TP \fB-b\fP, \fB-bpp\fP n obliga a xawtv a usar un color de profundidad .B n. Funciona para seleccionar entre 15/16 y 24/32 bpp. Simplemente se le pasa la opción a v4l-conf(1). .br Recurso: xawtv.bpp (int). .TP \fB-shift\fP n Desplaza la imagen de video .B n bytes. Puede usar esta opción si la imagen de video no está dentro de la ventana del xawtv, algunas tarjetas antiguas matrox muestran este problema. Simplemente se le pasa la opción a v4l-conf(1). .br Recurso: xawtv.shift (int). .TP \fB-fb\fP Usa el dispositivo framebuffer para determinar la dirección del buffer de video (en lugar de la extensión DGA). De nuevo un simple paso de opciones. .br Recurso: xawtv.fbdev (bool). .TP \fB-xv/-noxv \fP habilita/deshabilita el uso de la extensión Xvideo (para overlay), por defecto está activado. .br Recurso: xawtv.xvideo (bool). .TP \fB-scale/-noscale \fP habilita/deshabilita el uso de la extensión Xvideo (para escalada por hardware en modo grabdisplay), por defecto está activado. .br Recurso: xawtv.hwscale (bool). .TP \fB-vm/-novm\fP habilita/deshabilita el uso de la extensión VidMode, por defecto desactivado. Si hay un modo a pantalla completa configurado en el fichero de configuración, entonces se habilitará automáticamente la extensión vidmode. .br Recurso: xawtv.vidmode (bool). .TP \fB-dga/-nodga\fP habilita/deshabilita el uso de la extensión DGA, por defecto activada. .br Recurso: xawtv.dga (bool). .TP \fB-parallel\fP n usa n hilos de compresión (por defecto: uno). .br Recurso: xawtv.parallel (int). .P Se soportan también las opciones habituales del toolkit como \fB-geometry\fP. .SH HARDWARE / INTERFACES SOPORTADOS .TP .B v4l2 video4linux dos - moderna Linux estándar de captura de vídeo API. .TP .B libv4l trabajo a través de la biblioteca libv4l, que proporciona una fina capa adicional en la parte superior de Video4Linux2 dispositivos de apoyo a la más amplia gama de formatos de dispositivos 'pixel (a menudo necesaria para cámaras web, etc). Es la interfaz por defecto en sistemas Linux. .TP .B bktr Driver para tarjetas bt848/878 para FreeBSD / OpenBSD. .TP .B Xvideo Extensión X11 para dispositivos de video. Tenga en cuenta que la extensión Xvideo sólo soporta overlay, no puede capturar imágenes o películas si se usa la extensión Xvideo. Por otra parte es la única manera para escalar video en overlay (por ejemplo, pantalla completa sin bordes negros a 1024x748) en el caso de que tanto el hardware como el driver xfree86 lo soporten. Mire el fichero README.xfree4 para más detalles y pistas para configurar Xvideo. .SH EMPEZANDO Arranque xawtv. Entonces verifique las opciones del menú (botón derecho del ratón) y ajuste las opciones (norma de TV, fuente de video, tabla de frecuencias). Con las teclas del cursor puede controlar el sintonizador y buscar cadenas de TV. Otras teclas útiles se listan a continuación. .P La tecla 'E' mostrará el editor de canales donde puede crear/editar entradas para sus cadenas de TV. No olvide pulsar en "save" para grabar el fichero de configuración. También puede crear o editar un fichero de configuración con cualquier editor de textos, vea xawtvrc(5) para la descripción de la sintaxis del fichero de configuración. Hay unas cuantas opciones de configuración que sólo se pueden establecer editando el fichero de configuración. .P También puede probar scantv. Se trata de una herramienta de línea de comandos que realizará una búsqueda de canales y escribirá un fichero de configuración para el xawtv con todos los canales que haya encontrado. .SS Funciones del ratón El botón izquierdo del ratón mostrará un menú con todas las cadenas de TV encontradas en el fichero de configuración. El botón central cambia a la siguiente cadena. El botón derecho mostrará una ventana con un montón de opciones y funciones. .SS Atajos de teclado .nf V Captura de \fIV\fPideo on/off A \fIA\fPudio on/off F Pantalla completa (\fIF\fPullscreen) on/off G Capturar (\fIG\fPrab) imagen (tamaño completo, ppm) J Capturar imagen (tamaño completo, \fIj\fPpeg) Ctrl+G Capturar (\fIG\fPrab) imagen (tamaño ventana, ppm) Ctrl+J Capturar imagen (tamaño ventana, \fIj\fPpeg) O Muestra ventana de \fIO\fPpciones C Muestra ventana de \fIC\fPanales E Muestra \fIE\fPditor de canales R Muestra ventana de grabación AVI (\fIR\fPecording) Z Salto de canales (\fIz\fPapping, sintoniza cada cadena unos cuantos segundos) Ctrl+Z Salto rápido de canales (captura las imágenes para los botones de los canales) arr./abaj. sintoniza el anterior/siguiente canal izq./der. ajuste fino repag/avpag anterior/siguiente cadena (las del fichero de configuración) espacio siguiente cadena (lo mismo que repag.) retroceso cadena sintonizada anteriormente Ctrl+arr. busca la siguiente cadena F5-F12 ajusta brillo/tonalidad/contraste/color ESC,Q \fIQ\fPuitar +/- Subir o bajar volumen (en el teclado numérico) Intro silencio (teclado numérico) .fi .SH BUGS .B Los informes de bugs con imágenes adjuntas van a /dev/null sin ser vistos. .P xawtv depende de una correcta configuración del driver. Si no puede sintonizar cadenas de TV incluso si los ajustes en la ventana de opciones son correctos, es muy posible que se trate de un asunto del driver. .P La indicación mono/estéreo \fBno\fP es fiable debido a restricciones en el API del v4l. El API no informa del modo actual del audio, sino que devuelve una lista de los modos disponibles en ese momento. xawtv simplemente hace una suposición basándose en que el driver usa el mejor modo disponible. Dependiendo de su hardware puede que esto no sea cierto. Si duda de si \fBde verdad\fP el modo estéreo funciona, sintonice la MTV y escuche, no se fie en lo que le diga xawtv. .SH VEA TAMBIÉN xawtvrc(5), fbtv(1), v4l-conf(1), scantv(1) .br http://bytesex.org/xawtv/ (homepage) .SH AUTOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997-2001 Gerd Knorr 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. .SH MISC Eres el visitante 4711 de esta página. .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/es/xawtvrc.5000066400000000000000000000242231343350355000156460ustar00rootroot00000000000000.TH xawtvrc 5 .SH NOMBRE xawtvrc -- fichero de configuración de programas de TV .SH SINOPSIS /etc/X11/xawtvrc .br $HOME/.xawtv .SH DESCRIPCIÓN .B xawtvrc es el fichero de configuración que originalmente usaba sólamente el xawtv (de ahí el nombre xawtvrc). Ahora hay otros programas y utilidades de TV que lo leen también para obtener información de configuración. .P Estos programas usan tanto un fichero global (/etc/X11/xawtvrc) como uno personal ($HOME/.xawtv). Las opciones establecidas en el fichero personal tendrán preferencias sobre las globales. .SS Programas Los siguientes programas usan estos ficheros de configuración: .TP .B xawtv El programa de TV clásico de X11. .TP .B motv Un mejorado GUI, basado en motif del xawtv ... .TP .B fbtv El programa para ver la tele en linux para la consola con framebuffer. .TP .B ttv Aplicación basada en aalib para ver la tele en cualquier terminal. .TP .B v4lctl Herramienta de línea de comandos para controlar dispositivos video4linux. .SS Crear el fichero de configuración Tanto .B xawtv como .B motv disponen de funciones para editar los canales y guardar la configuración. Pero la función para grabarla \fBno\fP conservará los comentarios que hubiera en el fichero de configuración ... .P También puede usar su editor de textos favorito y modificar el fichero de configuración directamente. .P También es posible usar la utilidad de línea de comandos .B scantv para crear un fichero de configuración inicial. scantv escaneará automáticamente todos los canales en busca de cadenas con emisión y escribirá las que encuentre en el fichero de configuración. .SH SINTAXIS .B xawtvrc usa una sintaxis similar a la de smb.conf: las secciones empiezan con [nombre], seguida de líneas con parejas opción = valor. .P Hay cuatro secciones especiales: [global], [launch], [eventmap] y [defaults]. Todas las demás secciones describen una cadena de TV cada una. .SS Opciones de cadenas de TV. Las siguientes opciones son válidas para cadenas de TV y la sección [defaults]. Las opciones de la sección [defaults] se usan -- como su nombre sugiere -- como valores por defecto para todoslos demás canales. Puede poner todo lo que es común para todos los canales (como la norma de TV que se usa en su país) en la sección [defaults], de modo que ya no deberá especificarla para cada canal. .P Con una sección [defaults] razonable, sólo necesitará especificar el canal para cada cadena de TV de esta manera: .nf [TVE] channel = 27 .fi El resto de opciones son: .TP .B fine = n ajuste fino (lo mismo que las teclas cursor izq.+cursor der. hacen en el xawtv), por defecto: 0 .TP .B norm = pal | ntsc | secam la norma de TV, la opción por defecto es pal .TP .B key = keysym Tecla para el canal. Se permiten todas las teclas keysyms de X11. Puede preceder una tecla con Modificador+, por ejemplo "Ctrl+F". .TP .B capture = off | overlay | grabdisplay modo de captura: off, overlay (por defecto, tarjeta de TV => video, 0% cpu) o grabdisplay (tarjeta de TV => memoria principal => Servidor X => video, la proporción de cuadros por segundo depende de la carga y tamaño de la imagen). Por defecto se usa overlay. Si no es posible usar el modo overlay por alguna razón (display remoto, no soportado por el hardware, lo que sea) las aplicaciones seleccionarán automáticamente el modo grabdisplay. .TP .B input = Television | Composite1 | Composite2 | SVHS fuente de entrada. Los valores válidos dependen del driver del hardware, los valores de arriba son sólo ejemplos. Puede usar "v4lctl list" para obtener una lista con las opciones válidas. .TP .B color = n .TP .B bright = n .TP .B hue = n .TP .B contrast = n El rango válido va de 0 a 65535, siendo 32768 el valor por defecto. Añadiendo el símbolo del tanto por ciento cambia el rango de 0 a 100, por ejemplo "50%" es lo mismo que "32768". .TP .B audio = mono | stereo | lang1 | lang2 Establece el modo de audio para un determinado canal. .TP .B freq = n Especifica la frecuencia para un determinado canal (en MHz, el transportador de video). No debería necesitar esto para un uso normal, todos los canales deberían estar listado en la tabla de frecuencia de su zona (si no, envíeme un parche). A no ser que quizás viva cerca de la frontera y el país vecino use un esquema de canales diferente. .TP .B midi = nota Establece el evento midi de como tecla para el canal. .P .SS Opciones globales Un número de opciones sin relación a los canales van en la sección "[global]": .TP .B fullscreen = ancho x alto especifica el modo de video que se debe usar para el modo de pantalla completa. Sólamente funciona con XFree, y por supuest es necesario un modeline válido para este modo en su fichero XF86Config. También debe habilitar la extensión VidMode (opción -vm, mire abajo) para que funcione. .TP .B wm-off-by = [+-]x[+-]y Algunos gestores de ventanas no manejan correctamente la gravedad estática (que yo sepa mwm y kwm). Esto es algo fastidioso en el modo a pantalla completa. Con esta opción puede corregirlo mediante un desplazamiento para mover las ventanas. Por ejemplo, wm-off-by = -4-24 soluciona el problema en el kwm (el window manager del KDE1). .TP .B freqtab = selecciona el mapeo de canal a frecuencia. La tabla de "Options window->Frequency" (en el xawtv) muestra un menú con todas las entradas válidas (y permite cambiar de tabla en tiempo de ejecución). .TP .B pixsize = ancho x alto tamaño de los pixmaps de los canales (dentro de la ventana de canales). 0x0 deshabilita esta opción. .TP .B pixcols = n número de columnas que se usarán en la ventana de canales. Por defecto: 1. .TP .B mixer = ctl | device:ctl Esta opción permite controlar el volumen por medio del mezclador de la tarjeta de sonido. ctl es el control del mezclador, como por ejemplo "vol" para el volumen maestro. "line1" puede ser un buen candidato para la tarjeta de TV. device es el dispositivo mezclador (sino se especifica se usará /dev/mixer). El volumen se controla con las teclas del teclado numérico: + sube el volumen, - lo baja, Intro lo silencia. .TP .B jpeg-quality = n establece el nivel de calidad para imágenes o cuadros (M)JPEG. El rango válido es para n es [0 .. 100] siendo 75 el valor por defecto. .TP .B keypad-ntsc = on | off Configura el modo del teclado numérico. Por defecto off. Cuando se pone a on, los números que se tecleen en el teclado numérico serán interpretados como número de canales (así es como funciona el NTSC TV). De otro modo serán interpretados como canales programados, es decir, 1 es el primer canal del $HOME/.xawtv, ... .TP .B keypad-partial = on | off Otro modo de configuración del teclado numérico. Por defectos on. Cuando se pone a off, teclear un dígito en el teclado numérico no cambia el canal si hay canales de dos dígitos que empiezan por ese número. .TP .B osd = on | off Habilita o deshabilita los textos en pantalla en el modo de pantalla completa. Por defecto on. .TP .B ratio = x:y Establece un aspect ratio fijo para la imagen de TV. El valor por defecto es 4:3. Use 0:0 si no quiere un aspect ratio fijo. .TP .B mov-driver = files | raw | avi | mov .TP .B mov-video = ppm | pgm | jpeg | rgb | gray | 422 | 422p | rgb15 | rgb24 | mjpeg | jpeg | raw | mjpa | png .TP .B mov-fps = fps .TP .B mov-audio = mono8 | mono16 | stereo .TP .B mov-rate = rate Establece los valores para grabaciones. No todas las combinaciones son posibles. "streamer -h" mostrará una lista. .TP .B midi = puerto Puede especificar un puerto ALSA por el cual xawtv recibirá eventos midi. Configurado de este modo, puede programar las teclas de su teclado midi como teclas asignadas a canales y usar eventos del controlador midi para controlar los ajustes de volumen, brillo, etc. Mire la descripción de la sección [eventmap] que hay más abajo para más detalles. .SS La sección [launch] Es posible arrancar otros programas desde el xawtv. Se configura con entradas en la sección "[launch]": .TP .B label = tecla, línea de comandos La tecla especificada ejecutará el programa. También vale llamar la acción como "Launch(label)". Si quiere jugar con las tablas de traducción de Xt, siéntase libre de hacerlo. Pero no se queje si rompe algo... .SS La sección [eventmap] La sección eventmap consiste simplemente en un número de líneas "evento = acción". "acción" puede ser cualquier comando que el xawtv entienda (mire la página man del xawtv-remote para una lista). "evento" es un evento generado por cualquier dispositivo de entrada de los que escucha el xawtv. Un evento puede tener algún argumento, por ejemplo los eventos del midi-ctrl tienen uno. Si está presente el argumento será añadido a la acción. .P Hay mapeos por defecto para eventos de entrada del lirc y del joystick, por tanto no será necesario que cree un eventmap para poder usarlos. Pero en caso de que no le guste los valores por defecto puede cambiarlos fácilmente. .P A continuación hay una lista de eventos válidos: .TP .B lirc-key- Se ha pulsado la tecla en el mando a distancia IR. .TP .B joy-button- Se pulsó el botón del joystick. .TP .B joy-axis- El joystick se ha movido en la dirección especificada. .TP .B midi-note- Se ha recibido un evento de nota (porque se ha pulsado una tecla en el teclado midi). .TP .B midi-ctrl- Se ha recibido un mensaje del controlador midi para el control . Este evento tiene un argumento (el valor actual del control). .TP .B kbd-key- La tecla se ha pulsado en el teclado. Sólamente fbtv soporta esta opción. .SS Ejemplo de fichero de configuración .nf # esto es un comentario # las línea vacías también se ignoran [global] freqtab = europe-west #mixer = line jpeg-quality = 75 midi = 64:0 fullscreen = 768x576 # para el /etc/XF86Config # Modeline "pal" 50.00 768 832 856 1000 576 590 595 630 -hsync -vsync [launch] mixer = M, gtkaumix AleVT = Ctrl+A, alevt [eventmap] midi-ctrl-7 = volume [defaults] input = television norm = pal [TVE 1] channel=E11 key=F1 [La 2] channel = 43 key = F2 # las demás cadenas van aquí [Cámara] input = Composite1 key = K .fi .SH VEA TAMBIÉN scantv(1), xawtv(1), motv(1), fbtv(1), ttv(1), v4lctl(1) .SH TRADUCCIÓN Página traducida al español por Ricardo Villalba xawtv-3.106/man/fbtv.1000066400000000000000000000132461343350355000145010ustar00rootroot00000000000000.TH fbtv 1 "(c) 1998 Gerd Knorr" .SH NAME fbtv - a console program for watching TV .SH SYNOPSIS .B fbtv [ options ] [ station name ] .SH DESCRIPTION .B fbtv is a program for watching TV with your linux box. It runs on top of a graphic framebuffer device (\fB/dev/fb0\fR). You'll need a kernel newer than 2.1.x to play with this. \fBfbtv\fR shares the config file (\fB$HOME/.xawtv\fR) with the \fBxawtv\fR application. Check the \fBxawtv(1)\fR manpage for details about the config file format. .SH OPTIONS .TP .B -h Display a command line options summary. .TP .B -o base set \fBbase\fR string for the snapshot output files. The filename will be \fBbase-timestamp-nr.ext\fR. .TP .B -v Be verbose. .TP .B -c device video4linux device (default is \fB/dev/video0\fR). .TP .B -D driver video4linux driver (default is \fBlibv4l\fR). .TP .B -d device framebuffer device (default is \fB$FRAMEBUFFER\fR; \fB/dev/fb0\fR if unset) .TP .B -g grayscaled display (works for 256 color mode only) .TP .B -s \fIwidth\fRx\fIheight\fR sets the V4L2 capture in \fIwidth\fR x \fIheight\fR resolution if possible. .TP .B -f font font for text. Default is to look for \fBlat1-16\fR console font. It no path is specified, it will seek for the font at the following directories: .nf \fB/usr/share/consolefonts/\fR \fB/usr/share/kbd/consolefonts/\fR \fB/usr/lib/kbd/consolefonts/\fR \fB/lib/kbd/consolefonts/\fR .fi If you have a local X11 font server running (or the \fBFONTSERVER\fR environment variable set to some working server), you can also give X11 font specs here. .TP .B -m mode video mode for TV. \fBfbtv\fR will look up the mode in \fB/etc/fb.modes\fR. .TP .B -j joydev joystick device to use for controlling \fBfbtv\fR. .TP .B -k keep capture on when switching consoles. Might be useful together with -s switch, you have a video picture while working on another console. This is more or less a dirty hack. Works only if all your consoles have the same video mode and fbcon does not use panning to speed up scrolling. For a multiheaded setup this is useful too. .TP .B -q quiet mode. Doesn't reserve space for the status line at the top, doesn't display the status messages and clock. When \fBfbtv\fR is started on this mode, it won't try to load the font file at start. You can toggle this at runtime too (using the \fB'F'\fR key). .TP .B -M EXPERIMENTAL: Turn on backend scaler mode (write yuv to offscreen memory and let the gfx board scale up the video). Supported hardware: Matrox G200/G400 (with matroxfb) and ATI Mach64 VT/GT (with atyfb, 16bpp only). You'll need at least bttv-0.7.16 or kernel 2.3.50. .SH USAGE \fBfbtv\fR is supported to work much like \fBxawtv\fR from user's point of view. You might have noticed that \fBxawtv\fR has a lot of keyboard shortcuts. They work in \fBfbtv\fR too (if it useful). Here is the list: .nf \fBG\fR \fBG\fPrab picture (full size, ppm) \fBJ\fR Grab picture (full size, \fBj\fPpeg) \fBF\fR \fBF\fPullscreen. Toggle quiet mode (see above). \fBup\fR/\fBdown\fR tune up/down one channel \fBleft\fR/\fBright\fR fine tuning \fBpgup\fR/\fBpgdown\fR station up/down \fBESC\fR,\fBQ\fR \fBQ\fPuit \fBX\fr \fBQ\fPuit, but leave sound on. \fB+\fR/\fB\-\fR Volume up/down \fBEnter\fR mute .fi The channel hotkeys defined in \fB$HOME/.xawtv\fR are supported too, with one exception: modifier keys (something like "\fBkey = Ctrl+F1\fR") do not work. .SH FULLSCREEN TV Some hints from Dag Bakke : .P The BT8xx cards can produce images up to 768x576 pixels. In order to have \fBfbtv\fR make use of your entire monitor-size and get maximum image quality, you need to create a 768x576 pixels framebufferconsole. This can be accomplished with the \fBfbset(1)\fR utility, which is available at various locations. See: http://www.cs.kuleuven.ac.be/~geert/bin/ .P Or, you can let \fBfbtv\fR handle the videomode changes with the -m switch. This requires that you have a small database with the various videomodes available. The file containing the videomodes is normally named \fB/etc/fb.modes\fR. For example, the following entry produces a 768x576x32bpp mode, with 75Hz refresh on a Matrox G200. .nf mode "tv" # D: 49.188 MHz, H: 46.580 kHz, V: 75.008 Hz geometry 768 576 768 576 32 timings 20330 128 32 32 8 128 5 endmode .fi The command "\fBfbtv -q -mtv\fR" thus gives you crisp clear (well, as good as the received signal anyway) tv on your entire screen. Alias this command to '\fBtv\fR', and you're set. .P .B NB! Please note that your monitor may or may not be able to handle such a "custom" resolution. And that misuse of the aforementioned fbset utility can toast your monitor. It is a lot easier to pull smoke out of electronic components, than to put it back in. .P A database of the standard VESA-modes can be downloaded from: ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/fb.modes.vesa60.gz .SH SEE ALSO xawtv(1) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997,98 Gerd Knorr 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. xawtv-3.106/man/fr/000077500000000000000000000000001343350355000140575ustar00rootroot00000000000000xawtv-3.106/man/fr/xawtv.1000066400000000000000000000236521343350355000153220ustar00rootroot00000000000000.TH xawtv 1 "(c) 1997-2002 Gerd Knorr" .SH NOM xawtv - un programme X11 pour regarder la télévision .SH SYNOPSIS .B xawtv [ options ] [ nom de la station ] .SH DESCRIPTION .B xawtv est une application X11 permettant de regarder la télévision avec votre machine unix. Elle utilise les contrôles Athena. .SH OPTIONS Toutes les options de la ligne de commande correspondent à une ressource, vous pouvez donc les mettre aussi dans votre fichier .Xdefaults. .TP \fB-h\fP, \fB-help\fP Affiche une courte description de toutes les options de la ligne de commande. .TP \fB-hwscan\fP Affiche une liste des périphériques disponibles. .TP \fB-f\fP, \fB-fullscreen\fP Démarre en mode plein écran. .br Ressource: xawtv.fullscreen (booléen). .TP \fB-n\fP, \fB-noconf\fP ne lit pas le fichier de configuration ($HOME/.xawtv). .br Ressource: xawtv.readconfig (booléen). .TP \fB-o\fP, \fB-outfile\fP base définit le nom de base pour les fichiers de capture d'écran. Le nom du fichier sera du type "base-date-numéro.ext". .br Ressource: xawtv.basename (chaîne). .TP \fB-c\fP, \fB-périphérique\fP périphérique définit le périphérique video4linux (par défaut /dev/video0). Cette option désactive aussi Xvideo. .br Ressource: xawtv.périphérique (chaîne). .TP \fB-D\fP, \fB-driver\fP nom définit le driver video4linux (par défaut "libv4l"). Cette option désactive aussi Xvideo. .br Ressource: xawtv.driver (chaîne). .TP \fB-C\fP, \fB-dspdev\fP périphérique définit le périphérique audio (par défaut /dev/dsp). .br Ressource: xawtv.dspdev (chaîne). .TP \fB-vbidev\fP périphérique définit le périphérique vbi (par défaut /dev/vbi0). .br Ressource: xawtv.vbidev (chaîne). .TP \fB-c\fP, \fB-xvport\fP nombre définit le port Xvideo (par défaut le premier utilisable si Xvideo est disponible). Cette option active aussi Xvideo. .br Ressource: xawtv.xvport (int). .TP \fB-joydev\fP périphérique périphérique manette de jeu à utiliser pour contrôler xawtv. .br Ressource: xawtv.joydev (chaîne). .TP \fB-v\fP, \fB-debug\fP niveau Etre plus explicite, le .B niveau peut être 0 (par défaut), 1 ou 2. Cela n'existe que pour le débogage ou pour l'analyse de problèmes. .br Ressource: xawtv.debug (int). .TP \fB-remote\fP L'affichage X11 est distant. Ceci désactive en fait le mode overlay, vous pouvez en avoir besoin si xawtv n'arrive pas à détecter automatiquement un affichage X11 distant. .br Ressource: xawtv.remote (booléen). .TP \fB-b\fP, \fB-bpp\fP n force xawtv à basculer dans la profondeur de couleur .B n. Permet de basculer entre 15/16 et 24/32 bpp. Ce paramètre est seulement renvoyé à v4l-conf(1). .br Ressource: xawtv.bpp (int). .TP \fB-shift\fP n Décale l'affichage video de .B n octets. Essayez ceci si l'image video n'est pas dans la fenêtre de xawtv, quelques cartes matrox anciennes sont affectées de ce problème. Ce paramètre aussi est seulement renvoyé à v4l-conf(1). .br Ressource: xawtv.shift (int). .TP \fB-fb\fP Utilise le périphérique framebuffer pour déterminer l'adresse du framebuffer (plutôt que l'extension DGA). Encore un argument renvoyé. .br Ressource: xawtv.fbdev (booléen). .TP \fB-xv/-noxv \fP Active/Désactive l'utilisation de l'extension Xvideo globalement, cad. que -noxv équivaut aux options -noxv-video et -noxv-image combinées. (voir ci-dessous). .br Ressource: xawtv.xv (booléen). .TP \fB-xv-video/-noxv-video \fP Active/Désactive l'utilisation de l'extension Xvideo pour l'overlay (ex. XvPutVideo). Le mode overlay utilise ceci. Est activé par défault. .br Ressource: xawtv.xvVideo (booléen). .TP \fB-xv-image/-noxv-image \fP Active/Désactive l'utilisation de l'extension Xvideo pour la mise à l'échelle de l'image (ex. XvPutImage). Le mode grabdisplay utilise ceci. Est activé par défault. .br Ressource: xawtv.xvImage (booléen). .TP \fB-vm/-novm\fP Active/Désactive l'utilisation de l'extension VidMode, est désactivé par défaut. S'il y a un mode plein écran défini dans le fichier de configuration, l'extension VidMode est activée automatiquement. .br Ressource: xawtv.vidmode (booléen). .TP \fB-dga/-nodga\fP Active/Désactive l'utilisation de l'extension DGA, activée par défaut. .br Ressource: xawtv.dga (booléen). .TP \fB-parallel\fP n utilise n instances (threads) de compression (par défaut~: un). .br Ressource: xawtv.parallel (int). .P L'options habituelles de l'environnement comme \fB-geometry\fP sont aussi supportées. .SH MATÉRIEL SUPPORTÉ / INTERFACES .TP .B v4l2 video4linux deux - modernes de capture vidéo standard linux API. .TP .B libv4l travail grâce à la bibliothèque libv4l, qui fournit une couche mince supplémentaire sur le dessus de video4linux2 les appareils d'appui d'une large gamme de formats plus périphériques "pixel (souvent nécessaire pour les webcams, etc). Il est l'interface par défaut sur les systèmes Linux. .TP .B bktr Pilote pour FreeBSD / OpenBSD des cartes d'acquisition bt848/878. .TP .B Xvideo Extention X11 pour les périphériques video. Notez que l'extention Xvideo ne supporte que le mode overlay, vous ne pouvez pas enregistrer des images ou des videos quand l'extension est utilisée. Dans un autre sens c'est le seul moyen d'obtenir une mise à l'échelle de la video (ex. plein écran sans bordures en 1024x768) si à la fois le matériel et le pilote de xfree86 le permettent. Lire README.xfree4 pour plus de détails et de conseils sur comment régler Xvideo. .SH PREMIÈRE UTILISATION Démarrez seulement xawtv. Vérifiez alors les réglages dans le menu des options (bouton droit de la souris) et ajustez les réglages (norme TV, source video, table de fréquences). Avec les touches flèches vous pouvez contrôler le syntoniseur et rechercher des émetteurs TV. Les autres touches très utiles sont listées ci-dessous. .P La touche 'E' affiche l'éditeur des chaînes où vous pouvez créer/changer vos pré-sélections pour les émetteurs TV. N'oubliez pas de cliquer sur "save" pour écrire un fichier de configuration. Vous pouvez aussi créer/changer un fichier de configuration avec n'importe quel éditeur de texte, lisez xawtvrc(5) pour une description de la syntaxe du fichier de configuration. Il y a certaines options que ne peuvent être changées qu'en éditant le fichier de configuration. .P Vous pouvez aussi essayer scantv. c'est un outil en ligne de commande qui recherche les émetteurs et écrit un fichier de configuration de xawtv avec toutes les chaînes qu'il a trouvé. .SS Utilisation de la souris Le bouton gauche de la souris fait apparaître un menu avec toutes les chaînes trouvées dans el fichier de configuration. Le bouton du milieu passe à la chaîne suivante. Le bouton droit fait apparaître un menu avec beaucoup de réglages et de contrôles. .SS Raccourcis clavier .nf V \fIV\fPideo (Capture) active/inactive A \fIA\fPudio Son actif/inactif F Plein Ecran actif/inactif G Sauver image (Taille Maximum, ppm) J Sauver image (Taille Maximum, \fIj\fPpeg) Ctrl+G Sauver image (Taille de la fenêtre, ppm) Ctrl+J Sauver image (Taille de la fenêtre, \fIj\fPpeg) O Affiche le menu d'\fIO\fPptions C Affiche le menu des \fIC\fPhaînes E Affiche l'\fIé\fPditeur des chaînes R Affiche la fenêtre d'en\fIr\fPegistrement AVI Z \fIZ\fPappette (\fIz\fPappe, cad. change de chaîne après quelques secondes). Ctrl+Z Zappette rapide (prend des images de chaque chaîne pour les vignettes de la fenêtre des chaînes. haut/bas syntonise la fréquence suivante/précédente gauche/droite syntonisation affinée pgup/pgdown chaîne suivante/précédente dans le fichier de configuration espace chaîne suivante (comme pgup) backspace chaîne précédente Ctrl+haut cherche l'émetteur suivant F5-F12 réglage luminosité/hue/contraste/couleur ESC,Q \fIQ\fPuitte +/- Augmenter diminuer le volume sonore (pavé numérique) Entrée Silence (pavé numérique) .fi .SH BOGUES .B Les rapports de bogues avec une image attachée vont dans /dev/null sans être regardés. .P xawtv a besoin d'un pilote correctement configuré. Si vous ne pouvez pas syntoniser des émetteurs alors que les réglages dans la fenêtre des options sont corrects c'est certainement un problème de pilote. .P L'affichage mono/stereo n'est \fBpas\fP fiable de par les limitations de l'API v4l. L'API ne peut pas renvoyer le mode audio en cours, seulement une liste des modes disponibles. Xawtv essaye seulement de deviner, partant du principe que le pilote utilise le meilleur mode disponible. Suivant votre matériel ceci peut être faux. Si vous n'êtes pas sûr du fait que la stereo fonctionne \fBréèllement\fP, veuillez syntoniser une chaîne musicale et écoutez, ne faites pas confiance à ce que xawtv dit. .SH VOIR AUSSI xawtvrc(5), fbtv(1), v4l-conf(1), scantv(1) .br http://bytesex.org/xawtv/ (homepage) .SH AUTEUR Gerd Knorr .SH TRADUCTION José Jorge .SH COPYRIGHT Copyright (C) 1997-2002 Gerd Knorr Permission est donnée à tout individu ou institution d'utiliser, copier, ou redistribuer ce logiciel dès lors que tous les fichiers d'origine sont inclus, que ce n'est pas vendu pour des bénéfices, et que cette notice sur le copyright est incluse. Ce programme est un logiciel libre; vous pouvez le redistribuer et/ou le modifier sous les termes de la licence GNU GPL telle que publiée par la Free Software Foundation; soit la version 2, soit (à votre convenance) toute version ultérieure. Ce programme est distribué dans l'espoir qu'il soit utile, mais SANS AUCUNE GARANTIE; même sans la garantie implicite de UTILISABILITE ou d'ADAPTATION A UN USAGE PRECIS. Lisez la licence GNU GPL pour plus de détails. Vous devriez avoir reçu une copie de la licence GNU GPL avec ce programme; si ce n'est pas le cas, écrivez à Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .SH DIVERS Vous êtes le 4711ème visiteur de cette page. xawtv-3.106/man/motv.1000066400000000000000000000173611343350355000145270ustar00rootroot00000000000000.TH motv 1 "(c) 1997-2001 Gerd Knorr" .SH NAME motv - a Motif program for watching TV .SH SYNOPSIS .B motv [ options ] [ station name ] .SH DESCRIPTION .B motv is a Motif application for watching TV with your unix box. .P It is basically xawtv with a more userfriendly GUI. It has the same features, uses the same config file, has the same command line switches, you can control it using xawtv-remote. Most keyboards shortcuts are identical too. .SH OPTIONS All command line options also have a Resource, so you can put them into your .Xdefaults file too. .TP \fB-h\fP, \fB-help\fP Print a short description of all command line options. .TP \fB-hwscan\fP Print a list of available devices. .TP \fB-f\fP, \fB-fullscreen\fP startup in fullscreen mode. .br Resource: motv.fullscreen (bool). .TP \fB-n\fP, \fB-noconf\fP don't read the config file ($HOME/.xawtv). .br Resource: motv.readconfig (bool). .TP \fB-o\fP, \fB-outfile\fP base set basestring for the snapshot output files. The filename will be "base-timestamp-nr.ext". .br Resource: motv.basename (string). .TP \fB-c\fP, \fB-device\fP device set video4linux device (default is /dev/video0). This option also disables Xvideo support. .br Resource: motv.device (string). .TP \fB-D\fP, \fB-driver\fP name set video4linux driver (default is "libv4l"). This option also disables Xvideo support. .br Resource: motv.driver (string). .TP \fB-C\fP, \fB-dspdev\fP device set audio device (default is /dev/dsp). .br Resource: motv.dspdev (string). .TP \fB-vbidev\fP device set vbi device (default is /dev/vbi0). .br Resource: motv.vbidev (string). .TP \fB-c\fP, \fB-xvport\fP number set Xvideo port (defaults to the first usable if Xvideo is available). This option also enables Xvideo support. .br Resource: motv.xvport (int). .TP \fB-joydev\fP device joystick device to use for controlling xawtv. .br Resource: xawtv.joydev (string). .TP \fB-v\fP, \fB-debug\fP level Be verbose, .B level may be 0 (default), 1 or 2. It exists just for debugging and trouble-shooting. .br Resource: motv.debug (int). .TP \fB-remote\fP X11 display is remote. This basically disables overlay mode, you might need this if xawtv fails to autodetect a remote X11 display. .br Resource: motv.remote (bool). .TP \fB-b\fP, \fB-bpp\fP n force xawtv into .B n bpp color depth. Works for switching between 15/16 and 24/32 bpp. This gets just passed through to v4l-conf(8). .br Resource: motv.bpp (int). .TP \fB-shift\fP n Shift the video display by .B n bytes. Try this if your video display is'nt within the xawtv window, some older matrox cards show this problem. This gets passed through to v4l-conf(8) too. .br Resource: motv.shift (int). .TP \fB-fb\fP Use the framebuffer device to determine the video framebuffer address (instead of the DGA extension). Yet another pass through argument. .br Resource: motv.fbdev (bool). .TP \fB-xv/-noxv \fP enable/disable the usage of the Xvideo extension altogether, i.e. -noxv has the same effect as both -noxv-video and -noxv-image switches (see below). .br Resource: xawtv.xv (bool). .TP \fB-xv-video/-noxv-video \fP enable/disable the usage of the Xvideo extension for video overlay (i.e. XvPutVideo). overlay mode uses this. default is on. .br Resource: xawtv.xvVideo (bool). .TP \fB-xv-image/-noxv-image \fP enable/disable the usage of the Xvideo extension for image scaling (i.e. XvPutImage). grabdisplay mode uses this. default is on. .br Resource: xawtv.xvImage (bool). .TP \fB-vm/-novm\fP enable/disable the usage of the VidMode extension, default is off. If there is a fullscreen video mode configured in the config file, the vidmode extension will be enabled automatically. .br Resource: motv.vidmode (bool). .TP \fB-dga/-nodga\fP enable/disable the usage of the DGA extension, default is on. .br Resource: motv.dga (bool). .TP \fB-parallel\fP n use n compression threads (default: one). .br Resource: xawtv.parallel (int). .P The usual toolkit options like \fB-geometry\fP are supported too. .SH SUPPORTED HARDWARE / INTERFACES .TP .B v4l video4linux - \fBthe\fP linux video capture API. .TP .B v4l2 video4linux two - new, improved capture interface which fixes a number of v4l design bugs. .TP .B bktr FreeBSD / OpenBSD driver for bt848/878 grabber cards. .TP .B Xvideo X11 Extension for video devices. Note that the Xvideo extension does support overlay only, you can't capture images/movies if the Xvideo extension is used. On the other hand this is the only way to scaled video overlay (i.e. fullscreen without black borders @ 1024x748) if both hardware and xfree86 driver support it. See README.xfree4 for more details and hints on how to setup Xvideo. .SH GETTING STARTED .B motv starts up with the TV window. The left mouse button shows a menu with all TV Stations (empty until you have defined some). The right mouse button brings up the control window. .P The first time you have configure motv, i.e. set TV norm and frequency table to the correct values. Check if the hardware works correctly (if tuning does not work it is very likely a driver configuration issue). If the hardware operates fine, you can let motv look for TV stations (Options => Channel scan). The channel buttons have a context menu for deleting and editing. Don't forget to save your configuration when you are done. .P You can also create/edit a config file with any text editor, see xawtvrc(5) for a description of the config file syntax. There are a number of config options which can only be set by editing the config file. .SH KEYBOARD SHORTCUTS Some of them work in the TV window only. The cursor keys for example are used by the motif toolkit to allow full keyboard control of the GUI and therefore have other functions in the control window. .P .nf V \fIV\fPideo (Capture) on/off A \fIA\fPudio on/off F \fIF\fPullscreen on/off G \fIG\fPrab picture (full size, ppm) J Grab picture (full size, \fIj\fPpeg) Ctrl+G \fIG\fPrab picture (window size, ppm) Ctrl+J Grab picture (window size, \fIj\fPpeg) Ctrl+C Copy to clipboard. C Popup \fIC\fPontrol Window R Popup AVI \fIR\fPecording Window S Popup \fIS\fPcale controls Z Channel Hopper (\fIz\fPapping, tune in every station a few seconds) Ctrl+Z Fast Channel Hopping (grab the images for the Channel Bottons) up/down tune up/down one channel left/right fine tuning pgup/pgdown station up/down (the ones you have in the config file) space next station (same as pgup) backspace previously tuned station Ctrl+up scan for next station ESC,Q \fIQ\fPuit +/- Volume up/down (keypad) Enter mute (keypad) .fi .SH BUGS .B Bug reports with images attached go to /dev/null unseen. .P motv depends on a correct driver configuration. If you can't tune TV stations even if the settings in the options window are correct it is very likely a driver issue. .SH SEE ALSO xawtvrc(5), xawtv(1), fbtv(1), v4l-conf(8), mtt(1) .br http://bytesex.org/xawtv/ (homepage) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997-2001 Gerd Knorr 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. .SH MISC Huh? Still with me? Looks like some people \fBdo\fP read manuals carefully. xawtv-3.106/man/mtt.1000066400000000000000000000025431343350355000143420ustar00rootroot00000000000000.TH mtt 1 "(c) 2002 Gerd Knorr" .SH NAME mtt - teletext browser for X11 and console. .SH SYNOPSIS .B mtt [ options ] .SH DESCRIPTION .B mtt is a browser for teletext pages. If the DISPLAY environment variable is set .B mtt will come up with the X11 GUI (motif), otherwise it will use the tty it was started from. .SH OPTIONS .B mtt understands the usual toolkit options (-geometry + friends). Additional options are: .TP .B -help print help text. .TP .B -debug enable debug messages. .TP .B -device vbi device (default is /dev/vbi0). .TP .B -tty force using the console mode. .SH SEE ALSO motv(1) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 2000 Gerd Knorr .P 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. .P 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. .P 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. xawtv-3.106/man/ntsc-cc.1000066400000000000000000000020051343350355000150610ustar00rootroot00000000000000.TH ntsc-cc 1 .SH NAME ntsc-cc - closed caption decoder .SH SYNOPSIS .B ntsc-cc [ options ] .SH DESCRIPTION .B ntsc-cc reads vbi data from /dev/vbi0 and decodes the enclosed cc data. Start it with '-h' to get a list of cmd line options. .SH SEE ALSO alevt(1) .SH AUTHORS timecop@japan.co.jp .br Mike Baker .br Adam .SH COPYRIGHT 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. .P 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. .P 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. xawtv-3.106/man/pia.1000066400000000000000000000041671343350355000143130ustar00rootroot00000000000000.TH pia 1 "(c) 2002 Gerd Knorr" .SH NAME pia - play media files .SH SYNOPSIS .B pia [ options ] movie .SH DESCRIPTION .B pia is a small X11 tool which plays movie files. .SH OPTIONS .B pia understands the usual toolkit options (-geometry + friends). Additional options are: .TP .B -h display help text .TP .B -v be verbose. .TP .B -debug enable debug messages. .TP .B -dsp Use OSS device for sound. .TP .B -noxv Disable Xvideo extension. .TP .B -nogl Disable OpenGL. .TP .B -noaudio Don't play sound. .TP .B -novideo Don't play video. .TP .B -slow n Slowdown video playback by factor n. n=2 doubles playback time, ... This also turns off audio playback. .SH SUPPORTED MOVIE FORMATS Main purpose of this utility is to playback movie files recorded by xawtv, motv and streamer. It should be able to playback every AVI or QuickTime movie written by one of the mentioned utilities. Feel free to submit a bug report if this doesn't work for some file. .SS QuickTime .B pia uses libquicktime to decode quicktime movies, thus it should be able to decode and playback all movies with codecs supported by libquicktime. .SS AVI AVI support is very limited. Video: uncompressed RGB data (15 and 24 bpp) and mjpeg is supported. Audio: only uncompressed PCM data works. .SS WAV WAV files are playable too, with the same limitation like AVI audio: only uncompressed PCM data. .SH AUTHOR Gerd Knorr .SH COPYRIGHT 2002 Gerd Knorr .P Copyright (C) 2002 Gerd Knorr 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. xawtv-3.106/man/propwatch.1000066400000000000000000000025321343350355000155430ustar00rootroot00000000000000.TH propwatch 1 "(c) 1997-2003 Gerd Knorr" .SH NAME propwatch - a tool to monitor X11 properties .SH SYNOPSIS .B propwatch [ options ] property-name ... .SH DESCRIPTION .B propwatch is a tool to monitor window properties of root and application windows. Nice for debugging property-based IPC of X11 programs. .SH OPTIONS .B propwatch uses the Athena Widgets and accepts the usual toolkit options like -display and -geometry. .P Additional options are: .TP .B -watch display Display to monitor the windows on. By default the display specified in the DISPLAY environment variable or via -display is used, but it is possible to watch another display instead. .TP .B -verbose be verbose. .TP .B -proplog Log property changes to stdout. .TP .B -kbdlog Log keystrokes to stdout. .P All remaining command line arguments are assumed to be property names which should be monitored. If no property names are specified, a build in default (WM_COMMAND) will be used. .SH ENVIRONMENT .TP .B DISPLAY specifies the display to use for the propwatch window. .SH SEE ALSO xprop(1), xhost(1), xauth(1), xwd(1) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997-2003 Gerd Knorr .br 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. xawtv-3.106/man/radio.1000066400000000000000000000055761343350355000146450ustar00rootroot00000000000000.TH radio 1 "(c) 1998-2001 Gerd Knorr" .SH NAME radio - console radio application .SH SYNOPSIS .B radio [ options ] .SH DESCRIPTION .B radio is a interactive, ncurses-bases console radio application. .SH OPTIONS .TP .B -h print a short help text. .TP .B -d enable debug output. .TP .B -q quit after processing the cmd line options, don't enter interactive ncurses mode. Only useful together with other options for obvious reasons ... .TP .B -m mute radio. .TP .B -f freq tune the specified radio frequency (and unmute the radio). .TP .B -c dev specify radio device (default is /dev/radio0). .TP .B -s Do a scan for radio stations. .TP .B -S Same as above + write a radio.fmmap with the signal for every frequency. You can get a graph for it with gnuplot (plot "radio.fmmap" w lin). .TP .B -i Scan, write a initial ~/.radio file to stdout and quit. So you can create a config file where you only have to fill in the correct station names later this way: "radio -i > ~/.radio". See below for the config file syntax. .SH CONFIGURATION .B radio picks up station names and present stations from a config file. It can parse kradio (KDE radio app) config files, therefore it first tries the usual KDE config file location: \fB~/.kde/share/config/kradiorc\fP. Failing that, .B radio tries \fB~/.radio\fP (which makes things a bit easier for people who don't use kradio). .P The format looks like this: .P .nf # KDE Config File [Buttons] 1=95800000 2=91400000 [Stations] 100600000=Hundert,6 95800000=Radio eins 102600000=Fritz 94300000=r.s.2 91400000=Berliner Rundfunk .fi .P The [Buttons] section can have up to eight entries. That are the present stations, they get mapped to F1-F8. The [Stations] section maps frequencies to station names. The frequencies in both sections are specified in Hz. .SH KEYS .nf X exit ESC,Q,E mute and exit. up/down inc/dec frequency pgup/pgdown next/previous station. This one uses the stations from the config file by default. When started with the -s option these keys will cycle througth the stations found during the scan. F1-F8, 1-8 preset buttons. Ctrl+L redraw screen. .fi .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997-2001 Gerd Knorr 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. xawtv-3.106/man/record.1000066400000000000000000000042521343350355000150130ustar00rootroot00000000000000.TH record 1 "(c) Gerd Knorr" .SH NAME record - records *.wav files .SH SYNOPSIS .B record [ options ] .SH DESCRIPTION .B record records *.wav files in CD quality (i.e. 44100 Hz, 16bit, stereo). It has a input level meter, which might be useful for sound trouble shooting (check if the mixer settings ok for recording from the TV card etc.) .SH OPTIONS .TP .B -h display help text .TP .B -o file basename for the output file(s), a number and the .wav extension are added by record. Default is "record". .TP .B -i dev mixer control. This should be the one where you can adjust the record level for your audio source. Default is "line". "mic" and "igain" are good candidates too. Best way to figure is to start your favorite mixer tool and check out which one works ... .TP .B -m dev set mixer device. Default is "/dev/mixer". .TP .B -d dev set audio device. Default is "/dev/dsp". .TP .B -r rate set sample rate. Default is 44100. .TP .B -p sec peak seconds (number of seconds which should be scanned for the volume maximum). This affects both peak level display and level triggered recording (see below). Default is 1.5 seconds. .P record can also be used non-interactive: .TP .B -c enable console (non-interactive) mode. .TP .B -v be verbose (console mode only). .TP .B -t mm:ss Limit the record time (console mode only). By default record records until stopped by a signal (by typing ^C for example). .TP .B -s size Limit the file size (console mode only). record will continue with a new file once the limit is reached. .TP .B -n num Limit the file count (console mode only). record will stop recording after num files. .TP .B -l Enable level triggered recording (console mode only) with the default trigger level (1000). .TP .B -L level Enable level triggered recording with the specified trigger level. .P If level triggered recording is active, record will start and stop recording depending on the signal strength. Recording will be started if the signal strength is above the trigger level (1000/32768 => around 3%). Recording will be stopped if the signal is below the trigger level for some time (1.5 seconds by default, the -p switch changes this). .SH AUTHOR Gerd Knorr xawtv-3.106/man/rootv.1000066400000000000000000000041701343350355000147050ustar00rootroot00000000000000.TH rootv 1 "(c) 2000-2002 Gerd Knorr" .SH NAME rootv - display TV using the Xvideo extension .SH SYNOPSIS .B rootv [ options ] .SH DESCRIPTION .B rootv puts a video to some window. By default it creates its own window, but you can also ask it to use the root window (thus the name) or any other window. .B rootv needs the Xvideo extension. .P .B rootv itself provides no way to control video/audio/tuner. You can use v4lctl to do this. .SH OPTIONS .B rootv knows a number of command line options to modify the behaviour. .TP .B -help Print a short description of all command line options. .TP .B -verbose Be verbose. That will dump some debug messages to stderr. .TP .B -root Put the video onto the root window instead of creating a new window. .TP .B -id Put the video into the window instead of creating a new window. .TP .B -station Tune station . This just calls v4lctl, which in turn will look up the station in your ~/.xawtv config file. .TP .B -no-mute Don't toggle mute. By default rootv will unmute the TV card when it starts and mute it on exit. It does this using the XV_MUTE attribute (if available). .TP .B -port Use Xvideo port . Try the -verbose switch if you want to know which ones are available. .TP .B -bg Fork into background. .TP .B -wm Print WindowMaker menu (set stations using v4lctl). .SH SEE ALSO xawtv(1), fbtv(1), v4lctl(1) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 2000-2002 Gerd Knorr .P 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. .P 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. .P 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. xawtv-3.106/man/scantv.1000066400000000000000000000034031343350355000150300ustar00rootroot00000000000000.TH scantv 1 "(c) 2000 Gerd Knorr" .SH NAME scantv - scan a v4l device for TV stations. .SH SYNOPSIS .B scantv [ options ] .SH DESCRIPTION .B scantv scans a v4l device for available TV stations and writes a xawtv/fbtv config file. .SH OPTIONS .TP .B -i input set tv \fBi\fPnput (Television/Composite1/S-video and so on). Default is Television. .TP .B -n norm set tv \fBn\fPorm. scantv will ask interactively if none is given. .TP .B -f table set \fBf\fPrequency table. scantv will ask interactively if none is given. .TP .B -o outfile specify \fBo\fPutput file. If none is specified, scantv writes to stdout. .TP .B -c device specify video device file. Default is /dev/video0. .TP .B -D driver specify video driver name. Default is "libv4l". .TP .B -C device specify vbi device file. Default is /dev/vbi0. .TP .B -s skip channel \fBs\fPcan, just write norm + freqtab to the config file. .TP .B -a Do a full scan (i.e. all frequencies, not just the ones from the frequency table). .SH SEE ALSO xawtv(1), fbtv(1) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 2000 Gerd Knorr .P 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. .P 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. .P 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. xawtv-3.106/man/showriff.1000066400000000000000000000014361343350355000153650ustar00rootroot00000000000000.TH showriff 1 "(c) 1994 UP-Vision Computergrafik, 1998-2000 Gerd Knorr" .SH NAME showriff - show structure of RIFF files (wav, avi, ...) .SH SYNOPSIS .B showriff [ options ] filename .SH DESCRIPTION .B showriff displays the structure of RIFF files. Common media files which use the RIFF format are wave-files and avi-movies. .SH OPTIONS .TP .B -h display help text .TP .B -j try to decode mjpeg headers .TP .B -e try to continue on errors. .SH SEE ALSO c't 11/1994, page 327 ff. (german computer mag) .SH AUTHOR Gerd Knorr .SH COPYRIGHT 1994 UP-Vision Computergrafik .br 1998-2000 Gerd Knorr .P 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. xawtv-3.106/man/streamer.1000066400000000000000000000033431343350355000153570ustar00rootroot00000000000000.TH streamer 1 .SH NAME streamer - record audio and/or video .SH SYNOPSIS .B streamer [ options ] .SH DESCRIPTION .B streamer reads audio and/or video data from /dev/video0 and /dev/dsp and writes the data to the disk. Various output formats are supported. Start streamer with '-h' for a list of options and supported output formats. .P streamer will use the file extention of the output file name to figure which format to use. You need the -f/-F options only if the extention allows more than one format. If you get the "neither audio nor video format specified/found" message and don't know why, you can enable the debug output (-d switch) to see what is going on. .P You can safely stop the recording at any time with Ctrl+C. streamer will catch the signal and stop recording correctly (i.e. write movie file headers) before exiting. .SH EXAMPLES .TP .B streamer -o foobar.jpeg write a single jpeg file. .TP .B streamer -o quicktime.mov -f yuv2 -F stereo -r 12 -t 0:10 record a short quicktime movie. .SH SEE ALSO xawtv(1), v4lctl(1) .SH AUTHOR Gerd Knorr .SH COPYRIGHT 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. .P 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. .P 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. xawtv-3.106/man/subtitles.1000066400000000000000000000010451343350355000155500ustar00rootroot00000000000000.TH subtitles 1 "(c) 2000 Gerd Knorr" .SH NAME subtitles - display subtitles within xawtv. .SH SYNOPSIS .B subtitles [ -help | -tty ] .SH DESCRIPTION .B subtitles fetches the given teletext page with the alevt-cap utility and displays it using xawtv-remote in an endless loop. It's most useful for pages which carry subtitles for the current TV program. It's page 150 in Germany. .SH OPTIONS .TP .B -help print a short help text. .TP .B -tty dump a copy of the videotext page to the tty. .SH SEE ALSO xawtv(1), xawtv-remote(1), alevt-cap(1) xawtv-3.106/man/ttv.1000066400000000000000000000025121343350355000143470ustar00rootroot00000000000000.TH ttv 1 "(c) 2001 Gerd Knorr" .SH NAME ttv - display TV/video on a tty .SH SYNOPSIS .B ttv [ options ] [ station name ] .SH DESCRIPTION .B ttv displays TV/video on a terminal, rendering the images using aalib. .SH OPTIONS .TP .B -h print help text. .TP .B -f use fast aalib render function. .TP .B -c device video4linux device (default is /dev/video0). .TP .B -D driver video4linux driver (default is "libv4l"). .P There are also lots of options for aalib, check the aalib documentation for more details on them. The help text includes a list. .SH SEE ALSO xawtv(1), fbtv(1) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 2000 Gerd Knorr .P 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. .P 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. .P 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. xawtv-3.106/man/v4l-conf.8000066400000000000000000000053761343350355000152040ustar00rootroot00000000000000.TH v4l-conf 8 "(c) 1997-99 Gerd Knorr" .SH NAME v4l-conf - configure a video4linux driver .SH SYNOPSIS .B v4l-conf [ options ] .SH DESCRIPTION .B v4l-conf is a small helper tool. It figures out the video mode and framebuffer base address of the graphics board and configures a video4linux driver like bttv. This is needed for drivers which can DMA the video over PCI directly into the video memory. .P Usually it is not required to use v4l-conf manually, xawtv(1) and fbtv(1) run it automatically at startup. It might be useful for trouble-shooting. .B v4l-conf must be installed suid-root. .P .B v4l-conf knows three ways to get the informations: .TP 3 * Query the X-Server using the XF86 DGA extension. This is the default if the DISPLAY environment variable is set. .TP 3 * Query the framebuffer driver. This is the default if DISPLAY is not set. .TP 3 * Query the console driver. This is used on mklinux only. .SH OPTIONS .TP 4 \fB-h\fP Print a short description of all command line options. .TP 4 \fB-q\fP Be quiet. .TP 4 \fB-d\fP dpy Use the X11 display \fBdpy\fP to get the parameters. .TP 4 \fB-f\fP Use the framebuffer driver to get the parameters. .TP 4 \fB-c\fP device Set the video4linux device. .TP 4 \fB-b\fP n enforce .B n bpp color depth. Works for switching between 15/16 and 24/32 bpp. .TP 4 \fB-s\fP n Shift the video display by .B n bytes. .TP 4 \fB-a\fP adr Set framebuffer address to \fBadr\fP. The value should be specified in hex. This option is allowed for root only. You can't overwrite the autodetected value, this switch is only useful if autodetect doesn't work because the X-Server lacks DGA support. You can put this into /etc/conf.modules, as "post-install bttv ..." for example. .TP 4 \fB-p\fP pitch Set framebuffer pitch to \fBpitch\fP bytes. The value should be specified in decimal. Allowed for root only. .SH BUGS Hope I haven't any security flaws in there. If you find one, drop me a note. Mails with patches are preferred :-) .SH SEE ALSO xawtv(1), fbtv(1) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997-99 Gerd Knorr .P 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. .P 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. .P 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. xawtv-3.106/man/v4l-info.1000066400000000000000000000007101343350355000151660ustar00rootroot00000000000000.TH v4l-info 1 "(c) Gerd Knorr" .SH NAME v4l-info - dump video4linux(2) device info to stdout .SH SYNOPSIS .B v4l-info [ device ] .SH DESCRIPTION .B v4l-info just prints the v4l(2) device info, i.e. calls lots of ioctls and dumps the results to stdout. It optionally accepts the device you want to query. Default is /dev/video0. .P Was written to help debug drivers, probably not that useful for end users ... .SH AUTHOR Gerd Knorr xawtv-3.106/man/v4lctl.1000066400000000000000000000000301343350355000147330ustar00rootroot00000000000000.so man1/xawtv-remote.1 xawtv-3.106/man/webcam.1000066400000000000000000000122361343350355000147740ustar00rootroot00000000000000.TH webcam 1 "(c) 1998-2000 Gerd Knorr" .SH NAME webcam - capture images and upload them to a webserver using ftp .SH SYNOPSIS .B webcam [ config file ] .SH DESCRIPTION .B webcam captures images from a video4linux device like bttv, annotates them and and uploads them to a webserver using ftp in a endless loop. .SH CONFIGURATION At startup .B webcam reads the configuration from the given config file or ~/.webcamrc if none is specified in the command line. .P The config file has at least two sections. The "grab" section holds the capture parameters. Any other section describes where the image should be uploaded. Older versions used "ftp" as name for that section. Recently the webcam utility got support for multiple connections, thus any section name is accepted and you can have more than one ftp section (you have to use another name for each section througth, name them by upload servers for example). .P Here is an sample config file (the given values are the defaults): .nf [grab] device = /dev/video0 driver = libv4l text = "webcam %Y-%m-%d %H:%M:%S" infofile = filename fg_red = 255 fg_green = 255 fg_blue = 255 width = 320 height = 240 delay = 3 wait = 0 input = composite1 norm = pal rotate = 0 top = 0 left = 0 bottom = -1 right = -1 quality = 75 trigger = 0 once = 0 [ftp] host = www user = webcam pass = xxxxxx dir = public_html/images file = webcam.jpeg tmp = uploading.jpeg passive = 1 debug = 0 auto = 0 local = 0 ssh = 0 .fi The annotation .B text is processed with strftime. Check the strftime(3) or date(1) manpage to see how you can format the timestamps. The text can also be read from a extern file (use .B infofile for that). The default color for the text overlay is white (RGB=255,255,255). Entries in the range of 0 through 255 for .B fg_red, .B fg_green, and .B fg_blue can be used to define a different color. Likewise .B bg_red, .B bg_green, and .B bg_blue can be used to set the background color (which defaults to transparent). .P .B input is the video source (TV/composite/whatever), .B norm the TV norm. .B delay is the delay between two images in seconds. .B wait is the initial delay before the first image is grabbed (some cameras need some time for adapting to lightning, thus don't return images with reasonable quality within the first few seconds ...). .B quality is the JPEG quality for the stored images. .P .B top, bottom, left, and .B right in the grab section allow cropping the image after it is grabbed. They should satisfy 0<=top .SH COPYRIGHT Copyright (C) 1997-2002 Gerd Knorr .br 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. xawtv-3.106/man/xawtv-remote.1000066400000000000000000000121251343350355000161750ustar00rootroot00000000000000.TH xawtv-remote 1 "(c) 1997-99 Gerd Knorr" .SH NAME xawtv-remote, v4lctl -- control video4linux devices .SH SYNOPSIS .B xawtv-remote [ options ] command .br .B v4lctl [ options ] command .SH DESCRIPTION .B xawtv-remote and .B v4lctl can be used to control a video4linux driven TV card. .B xawtv-remote passes the command to a already running xawtv or motv instance using X11 properties. .B v4lctl sets the parameters directly. .SH OPTIONS .B xawtv-remote knows the following options: .TP .B -h print a short help text .TP .B -d dpy Set the X11 display .TP .B -i id Set the Window ID. .P .B v4lctl understands these options: .TP .B -h print a short help text .TP .B -c device Set video4linux device. .TP .B -D driver Set video4linux driver. .TP .B -v n Set debug level to \fBn\fP, where n = [0..2] .SH COMMANDS Both tools basically use the same set of commands. Some of them are useful for xawtv-remote only (fullscreen for example). .TP .B setstation [ | | next | prev | back ] Set the TV station. This selects on of the TV stations which are configured in the .xawtv config file. The argument can be the station name or a number (the first one listed in the config file is 0, ...). next/prev jumps to the next/previous station in the list, back to the previously selected one. .TP .B setchannel [ | next | prev ] Tune in some channel. .TP .B setfreqtab Set the frequency table. See the menu in xawtv for a list of valid choices. .TP .B setnorm Set the TV norm (NTSC/PAL/SECAM). .TP .B setinput [ | next ] Set the video input (Television/Composite1/...) .TP .B capture [ on | off | overlay | grabdisplay ] Set capture mode. .TP .B volume mute on | off mute / unmute audio. .TP .B volume .TP .B color .TP .B hue .TP .B bright .TP .B contrast Set the parameter to the specified value. can be one of the following: A percent value ("70%" for example). Some absolute value ("32768"), the valid range is hardware specific. Relative values can be specified too by prefixing with "+=" or "-=" ("+=10%" or "-=2000"). The keywords "inc" and "dec" are accepted to and will increase and decrease the given value in small steps. .TP .B setattr Set set the value of some attribute (color, contrast, ... can be set this way too). .TP .B show [ ] Show the value current of some attribute. .TP .B list List all available attributes with all properties (default value, range, ...) .TP .B snap [ jpeg | ppm ] [ full | win | widthxheight ] Capture one image. .TP .B webcam Capture one image. Does basically the same as "snap jpeg win ". Works also while avi recording is active. It writes to a temporary file and renames it when done, so there is never a invalid file. .TP .B movie driver [ files | raw | avi | qt ] .TP .B movie video [ ppm | pgm | jpeg | rgb | gray | 422 | 422p | rgb15 | rgb24 | mjpeg | jpeg | raw | mjpa | png ] .TP .B movie fps .TP .B movie audio [ mono8 | mono16 | stereo ] .TP .B movie rate .TP .B movie fvideo .TP .B movie faudio .TP .B movie start .TP .B movie stop control xawtv's movie recorder. .TP .B fullscreen Toggle fullscreen mode. .TP .B showtime Display time (same what the 'D' key does in xawtv). .TP .B msg text Display text on the on-screen display (window title / upper left corner in fullscreen mode). .TP .B vtx line1 line2 [ ... ] Display subtitles. It pops up a small window at the bottom of the screen. It is intended to be used as an interface for displaying subtitles (often on videotext page 150 in Europe, that's why the name) by external programs. .br Every command line argument is one line, zero lines removes the window. You can colorize the text with the control sequence "ESC foreground background". foreground/background has the range 0-7 (ansi term colors). Example: "\\03347 hello world " is blue on white. "\\033" must be a real escape character, the string doesn't work. With the bash you'll get it with ^V ESC. vtx does also understand the ANSI tty escape sequences for color. .TP .B quit quit xawtv .TP .B keypad n enter digit 'n'. That's the two-digit channel selection, entering two digits within 5 seconds switches to the selected station. Useful for lirc. .TP .B vdr command send "command" to vdr (via connect on localhost:2001). .SH SEE ALSO xawtv(1), motv(1), xawtvrc(5) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997-2001 Gerd Knorr .P 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. .P 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. .P 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. xawtv-3.106/man/xawtv.1000066400000000000000000000201751343350355000147100ustar00rootroot00000000000000.TH xawtv 1 "(c) 1997-2001 Gerd Knorr" .SH NAME xawtv - a X11 program for watching TV .SH SYNOPSIS .B xawtv [ options ] [ station name ] .SH DESCRIPTION .B xawtv is a X11 application for watching TV with your unix box. It uses the Athena widgets. .SH OPTIONS All command line options also have a Resource, so you can put them into your .Xdefaults file too. .TP \fB-h\fP, \fB-help\fP Print a short description of all command line options. .TP \fB-hwscan\fP Print a list of available devices. .TP \fB-f\fP, \fB-fullscreen\fP startup in fullscreen mode. .br Resource: xawtv.fullscreen (bool). .TP \fB-n\fP, \fB-noconf\fP don't read the config file ($HOME/.xawtv). .br Resource: xawtv.readconfig (bool). .TP \fB-o\fP, \fB-outfile\fP base set basestring for the snapshot output files. The filename will be "base-timestamp-nr.ext". .br Resource: xawtv.basename (string). .TP \fB-c\fP, \fB-device\fP device set video4linux device (default is /dev/video0). This option also disables Xvideo support. .br Resource: xawtv.device (string). .TP \fB-D\fP, \fB-driver\fP name set video4linux driver (default is "libv4l"). This option also disables Xvideo support. .br Resource: xawtv.driver (string). .TP \fB-C\fP, \fB-dspdev\fP device set audio device (default is /dev/dsp). .br Resource: xawtv.dspdev (string). .TP \fB-vbidev\fP device set vbi device (default is /dev/vbi0). .br Resource: xawtv.vbidev (string). .TP \fB-c\fP, \fB-xvport\fP number set Xvideo port (defaults to the first usable if Xvideo is available). This option also enables Xvideo support. .br Resource: xawtv.xvport (int). .TP \fB-joydev\fP device joystick device to use for controlling xawtv. .br Resource: xawtv.joydev (string). .TP \fB-v\fP, \fB-debug\fP level Be verbose, .B level may be 0 (default), 1 or 2. It exists just for debugging and trouble-shooting. .br Resource: xawtv.debug (int). .TP \fB-remote\fP X11 display is remote. This basically disables overlay mode, you might need this if xawtv fails to autodetect a remote X11 display. .br Resource: xawtv.remote (bool). .TP \fB-b\fP, \fB-bpp\fP n force xawtv into .B n bpp color depth. Works for switching between 15/16 and 24/32 bpp. This gets just passed through to v4l-conf(8). .br Resource: xawtv.bpp (int). .TP \fB-shift\fP n Shift the video display by .B n bytes. Try this if your video display isn't within the xawtv window, some older matrox cards show this problem. This gets passed through to v4l-conf(8) too. .br Resource: xawtv.shift (int). .TP \fB-fb\fP Use the framebuffer device to determine the video framebuffer address (instead of the DGA extension). Yet another pass through argument. .br Resource: xawtv.fbdev (bool). .TP \fB-xv/-noxv \fP enable/disable the usage of the Xvideo extension altogether, i.e. -noxv has the same effect as both -noxv-video and -noxv-image switches (see below). .br Resource: xawtv.xv (bool). .TP \fB-xv-video/-noxv-video \fP enable/disable the usage of the Xvideo extension for video overlay (i.e. XvPutVideo). overlay mode uses this. default is on. .br Resource: xawtv.xvVideo (bool). .TP \fB-xv-image/-noxv-image \fP enable/disable the usage of the Xvideo extension for image scaling (i.e. XvPutImage). grabdisplay mode uses this. default is on. .br Resource: xawtv.xvImage (bool). .TP \fB-vm/-novm\fP enable/disable the usage of the VidMode extension, default is off. If there is a fullscreen video mode configured in the config file, the vidmode extension will be enabled automatically. .br Resource: xawtv.vidmode (bool). .TP \fB-dga/-nodga\fP enable/disable the usage of the DGA extension, default is on. .br Resource: xawtv.dga (bool). .TP \fB-parallel\fP n use n compression threads (default: one). .br Resource: xawtv.parallel (int). .P The usual toolkit options like \fB-geometry\fP are supported too. .SH SUPPORTED HARDWARE / INTERFACES .TP .B v4l2 video4linux two - modern standard linux video capture API .TP .B libv4l work through the libv4l library, which provides an additional thin layer on top of video4linux2 devices for support of more wide range of devices' pixel formats (often required for webcams etc.) It is default for Xawtv on Linux systems. .TP .B bktr FreeBSD / OpenBSD driver for bt848/878 grabber cards. .TP .B Xvideo X11 Extension for video devices. Note that the Xvideo extension does support overlay only, you can't capture images/movies if the Xvideo extension is used. On the other hand this is the only way to scaled video overlay (i.e. fullscreen without black borders @ 1024x748) if both hardware and xfree86 driver support it. See README.xfree4 for more details and hints on how to setup Xvideo. .SH GETTING STARTED Just start xawtv. Then verify the settings in the options menu (right mouse button) and adjust the settings (TV norm, Video source, frequency table). With the cursor keys you can control the tuner and look for TV Stations. Other useful hotkeys are listed below. .P The hotkey 'E' will show the channel editor where you can create/edit entries your TV stations. Don't forget to click on "save" to write a config file. You can also create/edit a config file with any text editor, see xawtvrc(5) for a description of the config file syntax. There are a number of config options which can only be set by editing the config file. .P You can also check out scantv. That's a command line tool which will perform a channel scan and write out a xawtv config file with all channels it has found. .SS Mouse functions The left mouse button will popup a menu with all TV stations found in the config file. The middle button switches to the next station. The right button brings up a window with a lot of options and control functions. .SS Keyboard Shortcuts .nf V \fIV\fPideo (Capture) on/off A \fIA\fPudio on/off F \fIF\fPullscreen on/off G \fIG\fPrab picture (full size, ppm) J Grab picture (full size, \fIj\fPpeg) Ctrl+G \fIG\fPrab picture (window size, ppm) Ctrl+J Grab picture (window size, \fIj\fPpeg) O Popup \fIO\fPptions Window C Popup \fIC\fPhannels Window E Popup Channel \fIE\fPditor R Popup AVI \fIR\fPecording Window Z Channel Hopper (\fIz\fPapping, tune in every station a few seconds) Ctrl+Z Fast Channel Hopping (grab the images for the Channel Buttons) up/down tune up/down one channel left/right fine tuning pgup/pgdown station up/down (the ones you have in the config file) space next station (same as pgup) backspace previously tuned station Ctrl+up scan for next station F5-F12 adjust bright/hue/contrast/color ESC,Q \fIQ\fPuit +/- Volume up/down (keypad) Enter mute (keypad) .fi .SH BUGS .B Bug reports with images attached go to /dev/null unseen. .P xawtv depends on a correct driver configuration. If you can't tune TV stations even if the settings in the options window are correct it is very likely a driver issue. .P The mono/stereo display is \fBnot\fP reliable due to v4l API restrictions. The API can not report back the current audio mode, but a list of the currently available modes. xawtv just does a guess based on that, assuming the driver uses the best available mode. Depending on your hardware this might not be true. If in doubt whenever stereo \fBreally\fP works, please tune in MTV and listen, don't trust what xawtv says. .SH SEE ALSO xawtvrc(5), fbtv(1), v4l-conf(8), scantv(1) .br http://bytesex.org/xawtv/ (homepage) .SH AUTHOR Gerd Knorr .SH COPYRIGHT Copyright (C) 1997-2001 Gerd Knorr 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. .SH MISC You are the 4711th visitor of this page. xawtv-3.106/man/xawtvrc.5000066400000000000000000000225441343350355000152430ustar00rootroot00000000000000.TH xawtvrc 5 .SH NAME xawtvrc -- TV apps config file .SH SYNOPSIS /etc/X11/xawtvrc .br $HOME/.xawtv .SH DESCRIPTION .B xawtvrc is the config file originally used by xawtv only (that's why the name xawtvrc). These days a number of other TV applications / utilities read it too to get configuration information from it. .P Both a global (/etc/X11/xawtvrc) and personal ($HOME/.xawtv) config file are used by the applications. Settings in the personal config file will overwrite the global ones. .SS Applications The following applications use these config files: .TP .B xawtv The classic X11 TV application. .TP .B motv A better, motif-based GUI for xawtv ... .TP .B fbtv TV application for the linux framebuffer console. .TP .B ttv aalib-based TV application for any terminal. .TP .B v4lctl command line tool to control video4linux devices. .SS Create a config file .B xawtv and .B motv both provide some functions to edit the channels and save the configuration. The save function will \fBnot\fP preserve any comments you might have put into the config file throught ... .P You can also use your favorite text editor and modify the config file directly. .P You can use the command line utility .B scantv to create a initial config file. scantv will automatically scan all channels for TV stations and write the ones it has found to the config file. .SH SYNTAX .B xawtvrc uses the same syntax like smb.conf: sections starting with [name], followed by lines with option = value pairs. .P There are four special sections: [global], [launch], [eventmap] and [defaults]. All other sections describe a TV station each. .SS TV station options. The following options are allowed for TV stations and the [defaults] section. The options from the [defaults] sections are used -- as the name suggests -- as defaults for all other channels. You can put everything which is common for all TV stations (like the TV norm which is used in your country) into the [defaults] section, so you don't have to specify it for every single channel. .P With a reasonable [defaults] section you usually only need to specify the channel for each TV station, like this: .nf [ORB] channel = 27 .fi The other options are: .TP .B fine = n finetuning (what left+right keys do within xawtv), default: 0 .TP .B norm = pal | ntsc | secam which TV norm, default is pal .TP .B key = keysym Hotkey for the channel. All X11 keysyms allowed here. You can prefix a keysym with Modifier+, "Ctrl+F" for example. .TP .B capture = off | overlay | grabdisplay capture mode: off, overlay (default, TV card => video, 0% cpu) or grabdisplay (TV card => main memory => X-Server => video, frame rate depends on load and picture size). Default is overlay. If it is not possible to use overlay for some reason (remote display, not supported by the hardware, whatever) the applications will automatically fallback to grabdisplay. .TP .B input = Television | Composite1 | Composite2 | SVHS input source. The valid choices depend on the hardware driver, the values above are just examples. You can use "v4lctl list" to get a list of valid choices. .TP .B color = n .TP .B bright = n .TP .B hue = n .TP .B contrast = n Valid range is 0-65535, default is 32768. Adding a percent symbol changes the range to 0-100, i.e. "50%" has the same effect like "32768". .TP .B audio = mono | stereo | lang1 | lang2 Set the audio mode for the given channel. .TP .B freq = n Specify the frequency for the given station (MHz, video carrier). You shouldn't need this for normal operation, all your channels should be listed in the frequency table for your area (if not, mail me a patch). Maybe unless you live near the border and the foreign country uses another channel scheme. .TP .B midi = note Use midi noteon event for as hotkey for the channel. .TP .B group = name Put the channel into the group . motv uses that to create submenus per channel group. .P .SS Global options A number of not channel-related settings go to the "[global]" section: .TP .B fullscreen = width x height specify which video mode should be used for full-screen. Works with XFree only, and of course you need a valid modeline for this mode in your XF86Config file. You also have to enable the VidMode extension (option -vm, see above) to make this work. .TP .B wm-off-by = [+-]x[+-]y Some WM's handle static gravity incorrectly (I know mwm and kwm). This is somewhat boring with fullscreen mode. With this option you can correct this with a displacement for moving windows. For example, wm-off-by = -4-24 does the trick for kwm (the KDE1 window manager). .TP .B freqtab = select a channel-to-freqency mapping. Options window->Frequency table (in xawtv) brings up a menu with all valid entries (and allows table-switching at runtime). .TP .B pixsize = width x height size of the channel pixmaps (within Channels window). 0x0 disables this feature. .TP .B pixcols = n number of columns the channel window should use. Defaults to 1. .TP .B mixer = ctl | device:ctl This allows volume control using the sound card mixer. ctl is the mixer control, i.e. "vol" for the master volume. "line1" is a good candidate for the TV card. device is the mixer device (defaults to /dev/mixer in unspecified). Volume-control works with the keypad: + is up, - is down, Enter is mute. .TP .B jpeg-quality = n set the quality for (M)JPEG images/frames. As usual the valid range for n is [0 .. 100] with 75 as default. .TP .B keypad-ntsc = on | off Configure keypad mode. Default is off. When set to on, numbers typed on the keypad are interpreted as channel numbers (this is like NTSC TV sets work). Otherwise they are interpreted as programmed station, i.e. 1 is the first station from $HOME/.xawtv, ... .TP .B keypad-partial = on | off Another configuration of keypad mode. Default is on. When set to off, typing one digit on the keypad doesn't change the station number when there are two-digit station numbers starting with that digit. .TP .B osd = on | off Enable/disable the onscreen display in fullscreen mode. Default is on. .TP .B osd-position = x , y Position the onscreen display, in pixels. Default is 30,20. .TP .B use-wm-fullscreen = on | off Enter fullscreen mode by asking the window manager to handle that via _NET_WM_STATE_FULLSCREEN (if supported by the wm). Default is on. .TP .B ratio = x:y Set a fixed aspect ratio for the TV image. Default is 4:3. Use 0:0 if you don't want a fixed aspect ratio. .TP .B mov-driver = files | raw | avi | mov .TP .B mov-video = ppm | pgm | jpeg | rgb | gray | 422 | 422p | rgb15 | rgb24 | mjpeg | jpeg | raw | mjpa | png .TP .B mov-fps = fps .TP .B mov-audio = mono8 | mono16 | stereo .TP .B mov-rate = rate Set defaults for movie recording. Not all possible combinations are valid choices. "streamer -h" will print a nice list. .TP .B midi = port You can specify a ALSA port where xawtv should receive midi events from. If configured this way, you can program your midi keyboard keys as station hotkeys and use midi controller events to control settings like volume, bright etc. Check the [eventmap] description below for details. .TP .B filter = name Enable the specified filter. .TP .B alsa_latency = time_in_ms This can be used to specify the latency for the ALSA digital sound loopback which xawtv does. The default is 30ms if you're getting sound dropouts on your system try increasing this setting. .SS The [launch] section You can start other programs from within xawtv. This is configured with entries in the "[launch]" section: .TP .B label = key, command line The specified hotkey will run the configured program. Calling the Action "Launch(label)" works too. If you want to play with the Xt translation tables, feel free to do so. But don't complain if you broke something while doing so... .SS The [eventmap] section The eventmap simply has a number of "event = action" lines. "action" can be any command which xawtv understands (check the xawtv-remote man page for a list). "event" is some event generated by any input device xawtv listens to. An event might have some argument, the midi-ctrl events for example have one. If present the argument is appended to the action. .P There are default mappings for lirc and joystick input events, so you don't have to create an eventmap to use them. But if you don't like the defaults you can change them easily. .P Here is a list of valid events: .TP .B lirc-key- The key was pressed on the IR remote control. .TP .B joy-button- Joystick button was pressed. .TP .B joy-axis- Joystick was moved into the given direction. .TP .B midi-note- noteon event for note was received (i.e. you probably pressed some key on the midi keyboard). .TP .B midi-ctrl- midi controller message for control was received. This event has an argument (the current value of the control). .TP .B kbd-key- Key was pressed on the keyboard. .SS sample config file .nf # this is a comment # empty lines are ignored too [global] freqtab = europe-west #mixer = line jpeg-quality = 75 midi = 64:0 fullscreen = 768x576 # for /etc/XF86Config # Modeline "pal" 50.00 768 832 856 1000 576 590 595 630 -hsync -vsync [launch] mixer = M, gtkaumix AleVT = Ctrl+A, alevt [eventmap] midi-ctrl-7 = volume kbd-key-h = msg "hello world" [defaults] input = television norm = pal [ZDF] channel=33 key=F1 [ORB] channel = 27 key = F2 # more stations follow here [Camera] input = Composite1 key = K .fi .SH SEE ALSO scantv(1), xawtv(1), motv(1), fbtv(1), ttv(1), v4lctl(1) xawtv-3.106/mk/000077500000000000000000000000001343350355000133045ustar00rootroot00000000000000xawtv-3.106/mk/Compile.mk000066400000000000000000000034251343350355000152310ustar00rootroot00000000000000# # some rules to compile stuff ... # # (c) 2002 Gerd Knorr # # main features: # * autodependencies via "cpp -MD" # * fancy, non-verbose output # # This file is public domain. No warranty. If it breaks you keep # both pieces. # ######################################################################## # verbose yes/no verbose ?= no # dependency files tmpdep = mk/$(subst /,_,$*).tmp depfile = mk/$(subst /,_,$*).dep depfiles = mk/*.dep compile_c = $(CC) $(CFLAGS) -Wp,-MD,$(tmpdep) -c -o $@ $< compile_cc = $(CXX) $(CXXFLAGS) -Wp,-MD,$(tmpdep) -c -o $@ $< fixup_deps = sed -e "s|.*\.o:|$@:|" < $(tmpdep) > $(depfile) && rm -f $(tmpdep) link_app = $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) link_so = $(CC) $(LDFLAGS) -shared -Wl,-soname,$(@F) -o $@ $^ $(LDLIBS) ar_lib = rm -f $@ && ar -r $@ $^ && ranlib $@ moc_h = $(MOC) $< -o $@ msgfmt_po = msgfmt -o $@ $< # non-verbose output ifeq ($(verbose),no) echo_compile_c = echo " CC " $@ echo_compile_cc = echo " CXX " $@ echo_link_app = echo " LD " $@ echo_link_so = echo " LD " $@ echo_ar_lib = echo " AR " $@ echo_moc_h = echo " MOC " $@ echo_msgfmt_po = echo " MSGFMT " $@ else echo_compile_c = echo $(compile_c) echo_compile_cc = echo $(compile_cc) echo_link_app = echo $(link_app) echo_link_so = echo $(link_so) echo_ar_lib = echo $(ar_lib) echo_moc_h = echo $(moc_h) echo_msgfmt_po = echo $(msgfmt_po) endif %.o: %.c @$(echo_compile_c) @$(compile_c) @$(fixup_deps) %.o: %.cc @$(echo_compile_cc) @$(compile_cc) @$(fixup_deps) %.o: %.cpp @$(echo_compile_cc) @$(compile_cc) @$(fixup_deps) %.so: %.o @$(echo_link_so) @$(link_so) %: %.o @$(echo_link_app) @$(link_app) %.moc : %.h @$(echo_moc_h) @$(moc_h) %.mo : %.po @$(echo_msgfmt_po) @$(msgfmt_po) xawtv-3.106/scripts/000077500000000000000000000000001343350355000143645ustar00rootroot00000000000000xawtv-3.106/scripts/Subdir.mk000066400000000000000000000001101343350355000161350ustar00rootroot00000000000000 install:: $(INSTALL_DATA) -m755 $(srcdir)/scripts/subtitles $(bindir) xawtv-3.106/scripts/bigfont.pl000066400000000000000000000057371343350355000163650ustar00rootroot00000000000000#!/usr/bin/perl -w # defaults $fname = "fixed"; $debug = 0; # parse args while (defined($ARGV[0]) && $ARGV[0] =~ /^-(.+)/) { if ($1 eq "fn") { $fname = $ARGV[1]; shift; shift; } else { printf STDERR "unknown option $ARGV[0]"; exit 1; } } ######################################################################## sub bitscale() { local($in) = $_[0]; local($scale) = $_[1]; local($i, $out); for ($i = 0, $out = 0; $in != 0; $i++) { if ($in & (1 << $i)) { $in &= ~(1 << $i); $out |= (1 << ($i * $scale + $scale-1)); } } return $out; } sub printline () { local($bits) = $_[0]; local($left) = $_[1]; local($width) = $_[2]; local($start,$val,$i); $start = 4 * length($bits); $val = hex($bits); print STDERR "|" if $debug; for ($i = $start-1; $i >= $start-$width; $i--) { if ($val & (1 << ($left+$i))) { print STDERR "*" if $debug; } else { print STDERR " " if $debug; } } $big = &bitscale($val,3); printf(STDERR "| %s | %0*x |\n",$bits,$start/4*3,$big) if $debug; $big |= ($big >> 1); printf("%0*x\n",$start/4*3,$big); printf("%0*x\n",$start/4*3,$big); printf("%0*x\n",$start/4*3,0); } sub parsechar () { local($name) = $_[0]; local($sw,$sh,$dw,$dh); local($b1,$b2,$b3,$b4); local(@bitmap); local($i) = 0; local($n) = 0; local($s) = 3; print STDERR "--\n" if $debug; print STDERR "*" if !$debug; print "STARTCHAR $name\n"; while () { last if /ENDCHAR/; if (/(ENCODING|BITMAP)/) { print; } elsif (/SWIDTH (\S*) (\S*)/) { $sw = $1, $sh = $2; printf("SWIDTH %d %d\n",$s*$sw,$s*$sh); } elsif (/DWIDTH (\S*) (\S*)/) { $dw = $1, $dh = $2; printf("DWIDTH %d %d\n",$s*$dw,$s*$dh); } elsif (/BBX (\S*) (\S*) (\S*) (\S*)/){ $b1 = $1, $b2 = $2, $b3 = $3, $b4 = $4; printf("BBX %d %d %d %d\n",$s*$b1,$s*$b2,$s*$b3,$s*$b4); } elsif (/^([a-f0-9]*)$/){ $bitmap[$n++] = $1; } else { print "oops: $_"; exit(1); } } for ($i = 0; $i < $n; $i++) { &printline($bitmap[$i],$b3,$dw); } print "ENDCHAR\n"; } ######################################################################## open(FONT,"fstobdf -fn $fname |") || die; while () { if (/STARTCHAR (.*)/) { &parsechar($1); } elsif (/FONT -(\w*)-(\w*)-(\w*)-(\w*)-(\w*)-(\w*)-(\d*)-(\w*)-(\w*)-(\w*)-(\w*)-(\d*)-(.*)/) { printf("FONT -Xxl-Led$2-$3-$4-$5-$6-%d-$8-$9-$10-$11-%d-$13\n", $7*3,$12*3); } elsif (/FONT \"-(\w*)-(\w*)-(\w*)-(\w*)-(\w*)-(\w*)-(\d*)-(\w*)-(\w*)-(\w*)-(\w*)-(\d*)-(.*)/) { printf("FONT \"-Xxl-Led$2-$3-$4-$5-$6-%d-$8-$9-$10-$11-%d-$13\n", $7*3,$12*3); } elsif (/SIZE (\S*) (\S*) (\S*)/) { printf("SIZE %d %d %d\n",$1*3,$2,$3); } elsif (/FOUNDRY \"(\S*)\"/) { printf("FOUNDRY \"Led\"\n"); } elsif (/(PIXEL_SIZE|POINT_SIZE|AVERAGE_WIDTH|X_HEIGHT|QUAD_WIDTH|FONT_ASCENT|FONT_DESCENT) (\S*)/) { printf("$1 %d\n",3*$2); } else { print; } } print STDERR " done\n" if !$debug; xawtv-3.106/scripts/build-test000066400000000000000000000026771343350355000163770ustar00rootroot00000000000000#!/bin/bash # signal when done function beep { echo -en "\007"; } trap beep EXIT ########################################################################## # xawtv # cleanup first make distclean # make sure autoconf stuff is up-to-date autoconf || exit 1 autoheader || exit 1 rm -rf autom4te.cache set -x # normal ./configure && make -j2 || exit 1 make distclean # parallel builds ./configure && nice make -j || exit 1 make distclean # no lirc ./configure --disable-lirc && make || exit 1 make distclean # no xfree extentions ./configure --disable-xfree-ext && make || exit 1 make distclean # no xvideo extention ./configure --disable-xvideo && make || exit 1 make distclean # no aalib ./configure --disable-aa && make || exit 1 make distclean # no motif ./configure --disable-motif && make || exit 1 make distclean # no alsa ./configure --disable-alsa && make || exit 1 make distclean # no zvbi ./configure --disable-zvbi && make || exit 1 make distclean # no opengl ./configure --disable-gl && make || exit 1 make distclean # no xft ./configure --disable-xft && make || exit 1 make distclean # no X11 ./configure --without-x && make || exit 1 make distclean # library link order #CFLAGS="-static" ./configure && make || exit 1 #make distclean set +x ########################################################################## # done echo echo "*** cool, compile test passed ***" echo exit 0 xawtv-3.106/scripts/capture-test000066400000000000000000000034521343350355000167330ustar00rootroot00000000000000#!/bin/sh # # test capture... # STREAMER=src/streamer PLAYBACK="xanim +f +Sr +Ze -Zr -Av" LEN=600 #DEST=/media/test DEST=/tmp/media ################################################################ # init test -d $DEST || mkdir $DEST function run () { echo "*** $* ***" $* sync sleep 2 } ################################################################ # images # single ppm run $STREAMER -o $DEST/image.ppm run $STREAMER -o $DEST/image.pgm # single jpeg run $STREAMER -o $DEST/image.jpeg # multiple images run $STREAMER -r5 -t10 -o $DEST/movie000.jpeg ################################################################ # movies # avi run $STREAMER -r10 -t$LEN -f rgb15 -F mono8 -b 32 -o $DEST/rgb15.avi run $STREAMER -r10 -t$LEN -f rgb24 -F mono16 -b 32 -o $DEST/rgb24.avi run $STREAMER -r10 -t$LEN -f mjpeg -F stereo -b 32 -o $DEST/mjpeg.avi # quicktime run $STREAMER -r10 -t$LEN -f raw -F mono8 -b 32 -o $DEST/raw.mov run $STREAMER -r10 -t$LEN -f jpeg -F mono8 -b 32 -o $DEST/jpeg.mov run $STREAMER -r10 -t$LEN -f mjpa -F mono8 -b 32 -o $DEST/mjpa.mov run $STREAMER -r10 -t$LEN -f png -F mono8 -b 32 -o $DEST/png.mov ################################################################ # raw data for format in rgb gray 422 422p; do run $STREAMER -d -f $format -o $DEST/$format.raw 2>&1 | grep ^grab: done ################################################################ # check xv $DEST/*.p[pg]m $DEST/*.jpeg $PLAYBACK $DEST/rgb15.avi $PLAYBACK $DEST/rgb24.avi $PLAYBACK $DEST/mjpeg.avi $PLAYBACK $DEST/raw.mov $PLAYBACK $DEST/jpeg.mov $PLAYBACK $DEST/mjpa.mov $PLAYBACK $DEST/png.mov display -size 320x240 gray:$DEST/gray.raw display -size 320x240 rgb:$DEST/rgb.raw display -size 640x240 gray:$DEST/422.raw display -size 320x480 gray:$DEST/422p.raw #display -size 320x360 gray:$DEST/420p.raw xawtv-3.106/scripts/fallback.pl000066400000000000000000000005511343350355000164610ustar00rootroot00000000000000#!/usr/bin/perl -w # # build header file from # use strict; while (my $line = <>) { chomp $line; # ignore comments next if $line =~ /^!/; # next if $line =~ /^\s*$/; # quote stuff $line =~ s/\\/\\\\/g; $line =~ s/\"/\\\"/g; # continued line? if ($line =~ s/\\\\$//) { printf "\"%s\"\n",$line; next; } # write out printf "\"%s\",\n",$line; } xawtv-3.106/scripts/html.pl000066400000000000000000000001201343350355000156560ustar00rootroot00000000000000#!/usr/bin/perl while (<>) { chop; s/([\\\"])/\\$1/g; print "\"$_\\n\"\n"; } xawtv-3.106/scripts/subtitles000066400000000000000000000033041343350355000163250ustar00rootroot00000000000000#! /bin/bash # # display teletext subtitles (PAL) in xawtv # required: alevt-cap, xawtv-remote # # config cc_tty=0 charset="latin-1" device="/dev/vbi0" ########################################################################## # helpers function usage() { cat < is the teletext page which is used for the subtitles. In germany it is usually page 150. options: -help this text -tty write subtitles also to the tty -charset latin-1/2 (default: $charset) -vbi vbi device (default: $device) EOF } ########################################################################## # parse args done=0 while test "$done" = "0"; do case "$1" in -h | -help | --help) usage exit 0 ;; -tty) cc_tty=1 shift ;; -charset) charset="$2" shift; shift ;; -vbi) device="$2" shift; shift ;; -*) echo "unknown option: $1, try -h for help" exit 1 ;; *) page="$1" done=1 ;; esac done if test "$page" = ""; then usage exit 1 fi ########################################################################## # main loop echo "displaying subtitles, using page $page" echo "hit ^C to exit" IFS=" " xawtv-remote vtx || exit trap "xawtv-remote vtx" EXIT while true; do set -- `alevt-cap -finetune auto -format ansi \ -charset $charset -vbi $device \ -name /dev/stdout $page | grep -v "^\[40m[ ]\+\[m$"` shift xawtv-remote vtx $* || exit if test "${cc_tty}" != 0; then while test "$1" != ""; do echo $1; shift; done echo "-- " fi done xawtv-3.106/scripts/webcam.cgi000066400000000000000000000025221343350355000163070ustar00rootroot00000000000000#!/usr/bin/perl # # send a movie (well, sort of) to the browser. Works with netscape only, # other browsers get a static image. Uses serverpush, i.e. sends the frames # as multipart/x-mixed-replace elements. # # (c) 1999 Gerd Knorr # use strict; # config my $IMAGE = "$ENV{DOCUMENT_ROOT}/images/webcam.jpeg"; my $MAXSEC = 600; # 10 min timeout ########################################################################### undef $/; $|=1; my $BO = "wrdlbrmpft"; my $serverpush = ($ENV{HTTP_USER_AGENT} =~ /^Mozilla/ && $ENV{HTTP_USER_AGENT} !~ /[Cc]ompatible/); my $start = time; my @st = stat($IMAGE) or die "stat $IMAGE: $!"; my $mtime = $st[9]; if ($serverpush) { print "Content-Type: multipart/x-mixed-replace; boundary=\"$BO\"\r\n"; print "\r\n"; print "\r\n--$BO\r\n"; } for (;;) { # read image open IMG, "<$IMAGE"; my $image = ; close IMG; # send it print "Content-Type: image/jpeg\r\n"; printf "Content-Length: %d\r\n",length($image); print "\r\n"; print $image; last unless $serverpush; # send multipart border if (time - $start > $MAXSEC) { print "\r\n--$BO--\r\n"; last; } else { print "\r\n--$BO\r\n"; } # wait until there is a new image foreach my $i (1 .. $MAXSEC) { sleep 1; @st = stat($IMAGE); if ($st[9] != $mtime) { $mtime = $st[9]; last; } } } exit; xawtv-3.106/structs/000077500000000000000000000000001343350355000144045ustar00rootroot00000000000000xawtv-3.106/structs/README000066400000000000000000000004551343350355000152700ustar00rootroot00000000000000 some infrastructure to dump the content of structures for info/debugging struct-dump.[ch] the actual code struct-.[ch] descriptions for structs of API struct2desc quick&dirty perl script to build initial description data files. used by: console/v4l-info libng/plugins/ xawtv-3.106/structs/ioctl2desc000066400000000000000000000004411343350355000163610ustar00rootroot00000000000000#!/usr/bin/perl use strict; my ($name,$type); while (<>) { ($name,$type) = m/\#define\s+(\w+)\s+_IO\w+\s*\([^,]+,\s*\d+,\s*(.*?)\)/ or next; $type =~ s/struct /desc_/; print "[_IOC_NR($name)] = {\n"; print "\t.name = \"$name\",\n"; print "\t.desc = $type,\n"; print "},\n"; } xawtv-3.106/structs/struct-dump.c000066400000000000000000000126371343350355000170500ustar00rootroot00000000000000#include #include #include #include #include #include #include "struct-dump.h" /* ---------------------------------------------------------------------- */ struct struct_desc desc_int[] = {{ .type = SINT32, .name = "int", },{ /* end of list */ }}; struct struct_desc desc_long[] = {{ .type = SINT32, .name = "long", },{ /* end of list */ }}; struct struct_desc desc_timeval[] = {{ /* FIXME */ /* end of list */ }}; /* ---------------------------------------------------------------------- */ int print_struct(FILE *fp, struct struct_desc *desc, void *data, char *prefix, int tab) { char name[256]; unsigned char *ptr = data; uint64_t u64; int64_t s64; uint32_t u32; int32_t s32; uint16_t u16; int16_t s16; uint8_t u8; int8_t s8; struct al64_t { char c; uint64_t t; } al64_t; int al = sizeof(long)-1; /* struct + union */ int al64 = (unsigned long)&al64_t.t - (unsigned long)&al64_t.c - 1; /* 64 bit alignement */ void *p; unsigned int i,j,first; for (i = 0; desc[i].name != NULL; i++) { sprintf(name,"%s%s",prefix,desc[i].name); if (STRUCT == desc[i].type) { strcat(name,"."); ptr = (void*)(((intptr_t)ptr + al) & ~al); print_struct(fp,desc[i].desc, ptr, name, tab); ptr += desc[i].length; if (!tab && desc[i+1].name != NULL) fprintf(fp,";"); continue; } if (UNION == desc[i].type) { u32 = *((uint32_t*)(ptr-4)); ptr = (void*)(((intptr_t)ptr + al) & ~al); for (j = 0; desc[i].u[j].name != NULL; j++) if (desc[i].u[j].value == u32) break; if (desc[i].u[j].name != NULL) { strcat(name,"."); strcat(name,desc[i].u[j].name); strcat(name,"."); print_struct(fp,desc[i].u[j].desc, ptr, name, tab); } return 0; /* FIXME */ } if (tab) fprintf(fp,"\t%-24s: ",name); else fprintf(fp,"%s=",name); switch (desc[i].type) { case STRING: fprintf(fp,"\"%-.*s\"",desc[i].length,ptr); ptr += desc[i].length; break; case PTR: p = *(void**)ptr; fprintf(fp,"%p",p); ptr += sizeof(p); break; case VER: u32 = *((uint32_t*)ptr); fprintf(fp,"%d.%d.%d", (u32 >> 16) & 0xff, (u32 >> 8) & 0xff, u32 & 0xff); ptr += 4; break; case FOURCC: u32 = *((uint32_t*)ptr); fprintf(fp,"0x%08x [%c%c%c%c]", u32, isprint(ptr[0]) ? ptr[0] : '.', isprint(ptr[1]) ? ptr[1] : '.', isprint(ptr[2]) ? ptr[2] : '.', isprint(ptr[3]) ? ptr[3] : '.'); ptr += 4; break; case ENUM16: u16 = *((uint16_t*)ptr); fprintf(fp,"%s", (u16 < desc[i].length && desc[i].enums[u16]) ? desc[i].enums[u16] : "unknown"); ptr += 2; break; case ENUM32: u32 = *((uint32_t*)ptr); fprintf(fp,"%s", (u32 < desc[i].length && desc[i].enums[u32]) ? desc[i].enums[u32] : "unknown"); ptr += 4; break; case BITS16: u16 = *((uint16_t*)ptr); first = 1; fprintf(fp,"0x%x [",u16); for (j = 0; j < 16; j++) { if (0 == (u16 & (1 << j))) continue; fprintf(fp,"%s%s", first ? "" : ",", desc[i].bits[j]); first = 0; } fprintf(fp,"]"); ptr += 2; break; case BITS32: u32 = *((uint32_t*)ptr); first = 1; fprintf(fp,"0x%x [",u32); for (j = 0; j < 32; j++) { if (0 == (u32 & (1 << j))) continue; fprintf(fp,"%s%s", first ? "" : ",", desc[i].bits[j]); first = 0; } fprintf(fp,"]"); ptr += 4; break; case BITS64: ptr = (void*)(((intptr_t)ptr + al64) & ~al64); u64 = *((uint64_t*)ptr); first = 1; fprintf(fp,"0x%" PRIx64 " [",u64); for (j = 0; j < 64; j++) { if (0 == (u64 & ((int64_t)1 << j))) continue; fprintf(fp,"%s%s", first ? "" : ",", desc[i].bits[j]); first = 0; } fprintf(fp,"]"); ptr += 8; break; case UINT64: ptr = (void*)(((intptr_t)ptr + al64) & ~al64); u64 = *((uint64_t*)ptr); fprintf(fp,"%" PRIu64,u64); ptr += 8; break; case SINT64: ptr = (void*)(((intptr_t)ptr + al64) & ~al64); s64 = *((int64_t*)ptr); fprintf(fp,"%" PRId64,s64); ptr += 8; break; case UINT32: u32 = *((uint32_t*)ptr); fprintf(fp,"%u",u32); ptr += 4; break; case SINT32: s32 = *((int32_t*)ptr); fprintf(fp,"%d",s32); ptr += 4; break; case UINT16: u16 = *((uint16_t*)ptr); fprintf(fp,"%u",u16); ptr += 2; break; case SINT16: s16 = *((int16_t*)ptr); fprintf(fp,"%d",s16); ptr += 2; break; case UINT8: u8 = *((uint8_t*)ptr); fprintf(fp,"%u",u8); ptr += 1; break; case SINT8: s8 = *((int8_t*)ptr); fprintf(fp,"%d",s8); ptr += 1; break; case PADDING: ptr += desc[i].length; break; case STRUCT: case UNION: /* shouldn't happen */ fprintf(fp,"FIXME [type=%d]\n",desc[i].type); exit(1); } if (tab) fprintf(fp,"\n"); else if (desc[i+1].name != NULL) fprintf(fp,";"); } return 0; } /* ---------------------------------------------------------------------- */ int print_ioctl(FILE *fp, struct ioctl_desc *ioctls, char *prefix, int cmd, void *ptr) { int index = _IOC_NR(cmd); char *name = ioctls[index].name; struct struct_desc *desc = ioctls[index].desc; fprintf(fp,"%s%s(", prefix, name ? name : "UNKNOWN"); if (desc) { print_struct(fp,desc,ptr,"",0); } else { fprintf(stderr,"???"); } fprintf(fp,")"); return 0; } /* ---------------------------------------------------------------------- */ /* * Local variables: * c-basic-offset: 8 * End: */ xawtv-3.106/structs/struct-dump.h000066400000000000000000000020131343350355000170400ustar00rootroot00000000000000 enum desc_type { UINT64, SINT64, UINT32, SINT32, UINT16, SINT16, UINT8, SINT8, FOURCC, STRING, PTR, ENUM16, ENUM32, STRUCT, UNION, BITS16, BITS32, BITS64, VER, PADDING, }; struct struct_desc { enum desc_type type; char *name; unsigned int length; char **enums; char **bits; struct struct_desc *desc; struct { unsigned int value; char *name; struct struct_desc *desc; } u[16]; }; struct ioctl_desc { char *name; struct struct_desc *desc; }; /* ---------------------------------------------------------------------- */ extern struct struct_desc desc_int[]; extern struct struct_desc desc_long[]; extern struct struct_desc desc_timeval[]; /* ---------------------------------------------------------------------- */ int print_struct(FILE *fp, struct struct_desc *desc, void *data, char *prefix, int tab); int print_ioctl(FILE *fp, struct ioctl_desc *ioctls, char *prefix, int cmd, void *ptr); xawtv-3.106/structs/struct-v4l2.c000066400000000000000000000474571343350355000167020ustar00rootroot00000000000000#include #include #include #include #include "videodev2.h" #include "struct-dump.h" #include "struct-v4l2.h" /* ---------------------------------------------------------------------- */ char *desc_v4l2_field[] = { [V4L2_FIELD_ANY] = "ANY", [V4L2_FIELD_NONE] = "NONE", [V4L2_FIELD_TOP] = "TOP", [V4L2_FIELD_BOTTOM] = "BOTTOM", [V4L2_FIELD_INTERLACED] = "INTERLACED", [V4L2_FIELD_SEQ_TB] = "SEQ_TB", [V4L2_FIELD_SEQ_BT] = "SEQ_BT", [V4L2_FIELD_ALTERNATE] = "ALTERNATE", }; char *desc_v4l2_buf_type[] = { [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "VIDEO_CAPTURE", [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "VIDEO_OUTPUT", [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "VIDEO_OVERLAY", [V4L2_BUF_TYPE_VBI_CAPTURE] = "VBI_CAPTURE", [V4L2_BUF_TYPE_VBI_OUTPUT] = "VBI_OUTPUT", [V4L2_BUF_TYPE_PRIVATE] = "PRIVATE", }; char *desc_v4l2_ctrl_type[] = { [V4L2_CTRL_TYPE_INTEGER] = "INTEGER", [V4L2_CTRL_TYPE_BOOLEAN] = "BOOLEAN", [V4L2_CTRL_TYPE_MENU] = "MENU", [V4L2_CTRL_TYPE_BUTTON] = "BUTTON", }; char *desc_v4l2_tuner_type[] = { [V4L2_TUNER_RADIO] = "RADIO", [V4L2_TUNER_ANALOG_TV] = "ANALOG_TV", }; char *desc_v4l2_memory[] = { [V4L2_MEMORY_MMAP] = "MMAP", [V4L2_MEMORY_USERPTR] = "USERPTR", [V4L2_MEMORY_OVERLAY] = "OVERLAY", }; char *desc_v4l2_colorspace[] = { [V4L2_COLORSPACE_SMPTE170M] = "SMPTE170M", [V4L2_COLORSPACE_SMPTE240M] = "SMPTE240M", [V4L2_COLORSPACE_REC709] = "REC709", [V4L2_COLORSPACE_BT878] = "BT878", [V4L2_COLORSPACE_470_SYSTEM_M] = "470_SYSTEM_M", [V4L2_COLORSPACE_470_SYSTEM_BG] = "470_SYSTEM_BG", [V4L2_COLORSPACE_JPEG] = "JPEG", [V4L2_COLORSPACE_SRGB] = "SRGB", }; char *bits_capabilities[32] = { "VIDEO_CAPTURE", "VIDEO_OUTPUT", "VIDEO_OVERLAY", "", "VBI_CAPTURE", "VBI_OUTPUT", "?","?", "RDS_CAPTURE", "?", "?", "?", "?", "?", "?", "?", "TUNER", "AUDIO", "?", "?", "?", "?", "?", "?", "READWRITE", "ASYNCIO", "STREAMING", "?", }; char *bits_standard[64] = { "PAL_B", "PAL_B1", "PAL_G", "PAL_H", "PAL_I", "PAL_D", "PAL_D1", "PAL_K", "PAL_M", "PAL_N", "PAL_Nc", "PAL_60", "NTSC_M", "NTSC_M_JP", "?", "?", "SECAM_B", "SECAM_D", "SECAM_G", "SECAM_H", "SECAM_K", "SECAM_K1", "SECAM_L", "?" "ATSC_8_VSB", "ATSC_16_VSB", }; char *bits_buf_flags[32] = { "MAPPED", "QUEUED", "DONE", "KEYFRAME", "PFRAME", "BFRAME", "?", "?", "TIMECODE", }; char *bits_fbuf_cap[32] = { "EXTERNOVERLAY", "CHROMAKEY", "LIST_CLIPPING", "BITMAP_CLIPPING", }; char *bits_fbuf_flags[32] = { "PRIMARY", "OVERLAY", "CHROMAKEY", }; char *desc_input_type[32] = { [ V4L2_INPUT_TYPE_TUNER ] = "TUNER", [ V4L2_INPUT_TYPE_CAMERA ] = "CAMERA", }; char *bits_input_status[32] = { "NO_POWER", "NO_SIGNAL", "NO_COLOR", "?", "?","?","?","?", "NO_H_LOCK", "COLOR_KILL", "?", "?", "?","?","?","?", "NO_SYNC", "NO_EQU", "NO_CARRIER", "?", "?","?","?","?", "MACROVISION", "NO_ACCESS", "VTR", "?", "?","?","?","?", }; char *bits_tuner_cap[32] = { "LOW", "NORM", "?", "?", "STEREO", "LANG2", "LANG1", "?", }; char *bits_tuner_rx[32] = { "MONO", "STEREO", "LANG2", "LANG1", }; char *desc_tuner2_mode[] = { [ V4L2_TUNER_MODE_MONO ] = "MONO", [ V4L2_TUNER_MODE_STEREO ] = "STEREO", [ V4L2_TUNER_MODE_LANG2 ] = "LANG2", [ V4L2_TUNER_MODE_LANG1 ] = "LANG1", }; /* ---------------------------------------------------------------------- */ struct struct_desc desc_v4l2_rect[] = {{ .type = SINT32, .name = "left", },{ .type = SINT32, .name = "top", },{ .type = SINT32, .name = "width", },{ .type = SINT32, .name = "height", },{ /* end of list */ }}; struct struct_desc desc_v4l2_fract[] = {{ .type = UINT32, .name = "numerator", },{ .type = UINT32, .name = "denominator", },{ /* end of list */ }}; struct struct_desc desc_v4l2_capability[] = {{ .type = STRING, .name = "driver", .length = 16, },{ .type = STRING, .name = "card", .length = 32, },{ .type = STRING, .name = "bus_info", .length = 32, },{ .type = VER, .name = "version", },{ .type = BITS32, .name = "capabilities", .bits = bits_capabilities, },{ /* end of list */ }}; struct struct_desc desc_v4l2_pix_format[] = {{ .type = UINT32, .name = "width", },{ .type = UINT32, .name = "height", },{ .type = FOURCC, .name = "pixelformat", },{ .type = ENUM32, .name = "field", .enums = desc_v4l2_field, .length = sizeof(desc_v4l2_field) / sizeof(char*), },{ .type = UINT32, .name = "bytesperline", },{ .type = UINT32, .name = "sizeimage", },{ .type = ENUM32, .name = "colorspace", .enums = desc_v4l2_colorspace, .length = sizeof(desc_v4l2_colorspace) / sizeof(char*), },{ .type = UINT32, .name = "priv", },{ /* end of list */ }}; struct struct_desc desc_v4l2_fmtdesc[] = {{ .type = UINT32, .name = "index", },{ .type = ENUM32, .name = "type", .enums = desc_v4l2_buf_type, .length = sizeof(desc_v4l2_buf_type) / sizeof(char*), },{ .type = UINT32, .name = "flags", },{ .type = STRING, .name = "description", .length = 32, },{ .type = FOURCC, .name = "pixelformat", },{ /* end of list */ }}; struct struct_desc desc_v4l2_timecode[] = {{ .type = UINT32, .name = "type", },{ .type = UINT32, .name = "flags", },{ .type = UINT8, .name = "frames", },{ .type = UINT8, .name = "seconds", },{ .type = UINT8, .name = "minutes", },{ .type = UINT8, .name = "hours", },{ .type = STRING, .name = "userbits", .length = 4, },{ /* end of list */ }}; struct struct_desc desc_v4l2_compression[] = {{ .type = UINT32, .name = "quality", },{ .type = UINT32, .name = "keyframerate", },{ .type = UINT32, .name = "pframerate", },{ /* end of list */ }}; struct struct_desc desc_v4l2_jpegcompression[] = {{ .type = SINT32, .name = "quality", },{ .type = SINT32, .name = "APPn", },{ .type = SINT32, .name = "APP_len", },{ .type = STRING, .name = "APP_data", .length = 60, },{ .type = SINT32, .name = "COM_len", },{ .type = STRING, .name = "COM_data", .length = 60, },{ .type = UINT32, .name = "jpeg_markers", },{ /* end of list */ }}; struct struct_desc desc_v4l2_requestbuffers[] = {{ .type = UINT32, .name = "count", },{ .type = ENUM32, .name = "type", .enums = desc_v4l2_buf_type, .length = sizeof(desc_v4l2_buf_type) / sizeof(char*), },{ .type = ENUM32, .name = "memory", .enums = desc_v4l2_memory, .length = sizeof(desc_v4l2_memory) / sizeof(char*), },{ /* end of list */ }}; struct struct_desc desc_v4l2_buffer[] = {{ .type = UINT32, .name = "index", },{ .type = ENUM32, .name = "type", .enums = desc_v4l2_buf_type, .length = sizeof(desc_v4l2_buf_type) / sizeof(char*), },{ .type = UINT32, .name = "bytesused", },{ .type = BITS32, .name = "flags", .bits = bits_buf_flags, },{ .type = ENUM32, .name = "field", .enums = desc_v4l2_field, .length = sizeof(desc_v4l2_field) / sizeof(char*), },{ .type = STRUCT, .name = "timestamp", .desc = desc_timeval, .length = sizeof(struct timeval), },{ .type = STRUCT, .name = "timecode", .desc = desc_v4l2_timecode, .length = sizeof(struct v4l2_timecode), },{ .type = UINT32, .name = "sequence", },{ .type = ENUM32, .name = "memory", .enums = desc_v4l2_memory, .length = sizeof(desc_v4l2_memory) / sizeof(char*), },{ /* FIXME ... */ /* end of list */ }}; struct struct_desc desc_v4l2_framebuffer[] = {{ .type = BITS32, .name = "capability", .bits = bits_fbuf_cap, },{ .type = BITS32, .name = "flags", .bits = bits_fbuf_flags, },{ .type = PTR, .name = "base", },{ .type = STRUCT, .name = "fmt", .desc = desc_v4l2_pix_format, .length = sizeof(struct v4l2_pix_format), },{ /* end of list */ }}; struct struct_desc desc_v4l2_clip[] = {{ .type = STRUCT, .name = "c", .desc = desc_v4l2_rect, .length = sizeof(struct v4l2_rect), },{ /* end of list */ }}; struct struct_desc desc_v4l2_window[] = {{ .type = STRUCT, .name = "w", .desc = desc_v4l2_rect, .length = sizeof(struct v4l2_rect), },{ .type = ENUM32, .name = "field", .enums = desc_v4l2_field, .length = sizeof(desc_v4l2_field) / sizeof(char*), },{ .type = UINT32, .name = "chromakey", },{ .type = PTR, .name = "clips", },{ .type = UINT32, .name = "clipcount", },{ .type = PTR, .name = "bitmap", },{ /* end of list */ }}; struct struct_desc desc_v4l2_captureparm[] = {{ .type = UINT32, .name = "capability", },{ .type = UINT32, .name = "capturemode", },{ .type = STRUCT, .name = "timeperframe", .desc = desc_v4l2_fract, .length = sizeof(struct v4l2_fract), },{ .type = UINT32, .name = "extendedmode", },{ .type = UINT32, .name = "readbuffers", },{ /* end of list */ }}; struct struct_desc desc_v4l2_outputparm[] = {{ .type = UINT32, .name = "capability", },{ .type = UINT32, .name = "outputmode", },{ .type = STRUCT, .name = "timeperframe", .desc = desc_v4l2_fract, .length = sizeof(struct v4l2_fract), },{ .type = UINT32, .name = "extendedmode", },{ .type = UINT32, .name = "writebuffers", },{ /* end of list */ }}; struct struct_desc desc_v4l2_cropcap[] = {{ .type = ENUM32, .name = "type", .enums = desc_v4l2_buf_type, .length = sizeof(desc_v4l2_buf_type) / sizeof(char*), },{ .type = STRUCT, .name = "bounds", .desc = desc_v4l2_rect, .length = sizeof(struct v4l2_rect), },{ .type = STRUCT, .name = "defrect", .desc = desc_v4l2_rect, .length = sizeof(struct v4l2_rect), },{ .type = STRUCT, .name = "pixelaspect", .desc = desc_v4l2_fract, .length = sizeof(struct v4l2_fract), },{ /* end of list */ }}; struct struct_desc desc_v4l2_crop[] = {{ .type = ENUM32, .name = "type", .enums = desc_v4l2_buf_type, .length = sizeof(desc_v4l2_buf_type) / sizeof(char*), },{ .type = STRUCT, .name = "c", .desc = desc_v4l2_rect, .length = sizeof(struct v4l2_rect), },{ /* end of list */ }}; struct struct_desc desc_v4l2_standard[] = {{ .type = UINT32, .name = "index", },{ .type = BITS64, .name = "id", .bits = bits_standard, },{ .type = STRING, .name = "name", .length = 24, },{ .type = STRUCT, .name = "frameperiod", .desc = desc_v4l2_fract, .length = sizeof(struct v4l2_fract), },{ .type = UINT32, .name = "framelines", },{ /* end of list */ }}; struct struct_desc desc_v4l2_input[] = {{ .type = UINT32, .name = "index", },{ .type = STRING, .name = "name", .length = 32, },{ .type = ENUM32, .name = "type", .enums = desc_input_type, .length = sizeof(desc_input_type) / sizeof(char*), },{ .type = UINT32, .name = "audioset", },{ .type = UINT32, .name = "tuner", },{ .type = BITS64, .name = "std", .bits = bits_standard },{ .type = BITS32, .name = "status", .bits = bits_input_status, },{ /* end of list */ }}; struct struct_desc desc_v4l2_output[] = {{ .type = UINT32, .name = "index", },{ .type = STRING, .name = "name", .length = 32, },{ .type = UINT32, .name = "type", },{ .type = UINT32, .name = "audioset", },{ .type = UINT32, .name = "modulator", },{ .type = BITS64, .name = "std", .bits = bits_standard },{ /* end of list */ }}; struct struct_desc desc_v4l2_control[] = {{ .type = UINT32, .name = "id", },{ .type = SINT32, .name = "value", },{ /* end of list */ }}; struct struct_desc desc_v4l2_queryctrl[] = {{ .type = UINT32, .name = "id", },{ .type = ENUM32, .name = "type", .enums = desc_v4l2_ctrl_type, .length = sizeof(desc_v4l2_buf_type) / sizeof(char*), },{ .type = STRING, .name = "name", .length = 32, },{ .type = SINT32, .name = "minimum", },{ .type = SINT32, .name = "maximum", },{ .type = SINT32, .name = "step", },{ .type = SINT32, .name = "default_value", },{ .type = UINT32, .name = "flags", },{ /* end of list */ }}; struct struct_desc desc_v4l2_querymenu[] = {{ .type = UINT32, .name = "id", },{ .type = UINT32, .name = "index", },{ .type = STRING, .name = "name", .length = 32, },{ .type = UINT32, .name = "reserved", },{ /* end of list */ }}; struct struct_desc desc_v4l2_tuner[] = {{ .type = UINT32, .name = "index", },{ .type = STRING, .name = "name", .length = 32, },{ .type = ENUM32, .name = "type", .enums = desc_v4l2_tuner_type, .length = sizeof(desc_v4l2_tuner_type) / sizeof(char*), },{ .type = BITS32, .name = "capability", .bits = bits_tuner_cap, },{ .type = UINT32, .name = "rangelow", },{ .type = UINT32, .name = "rangehigh", },{ .type = BITS32, .name = "rxsubchans", .bits = bits_tuner_rx, },{ .type = ENUM32, .name = "audmode", .enums = desc_tuner2_mode, .length = sizeof(desc_tuner2_mode) / sizeof(char*), },{ .type = SINT32, .name = "signal", },{ .type = SINT32, .name = "afc", },{ /* end of list */ }}; struct struct_desc desc_v4l2_modulator[] = {{ .type = UINT32, .name = "index", },{ .type = STRING, .name = "name", .length = 32, },{ .type = UINT32, .name = "capability", },{ .type = UINT32, .name = "rangelow", },{ .type = UINT32, .name = "rangehigh", },{ .type = UINT32, .name = "txsubchans", },{ /* end of list */ }}; struct struct_desc desc_v4l2_frequency[] = {{ .type = UINT32, .name = "tuner", },{ .type = ENUM32, .name = "type", .enums = desc_v4l2_tuner_type, .length = sizeof(desc_v4l2_tuner_type) / sizeof(char*), },{ .type = UINT32, .name = "frequency", },{ /* end of list */ }}; struct struct_desc desc_v4l2_audio[] = {{ .type = UINT32, .name = "index", },{ .type = STRING, .name = "name", .length = 32, },{ .type = UINT32, .name = "capability", },{ .type = UINT32, .name = "mode", },{ /* end of list */ }}; struct struct_desc desc_v4l2_audioout[] = {{ .type = UINT32, .name = "index", },{ .type = STRING, .name = "name", .length = 32, },{ .type = UINT32, .name = "capability", },{ .type = UINT32, .name = "mode", },{ /* end of list */ }}; struct struct_desc desc_v4l2_vbi_format[] = {{ .type = UINT32, .name = "sampling_rate", },{ .type = UINT32, .name = "offset", },{ .type = UINT32, .name = "samples_per_line", },{ .type = FOURCC, .name = "sample_format", },{ .type = UINT32, .name = "start[0]", },{ .type = UINT32, .name = "start[1]", },{ .type = UINT32, .name = "count[0]", },{ .type = UINT32, .name = "count[1]", },{ .type = UINT32, .name = "flags", },{ /* end of list */ }}; struct struct_desc desc_v4l2_format[] = {{ .type = ENUM32, .name = "type", .enums = desc_v4l2_buf_type, .length = sizeof(desc_v4l2_buf_type) / sizeof(char*), },{ .type = UNION, .name = "fmt", .u = {{ .value = V4L2_BUF_TYPE_VIDEO_CAPTURE, .name = "pix", .desc = desc_v4l2_pix_format, },{ .value = V4L2_BUF_TYPE_VIDEO_OVERLAY, .name = "win", .desc = desc_v4l2_window, },{ .value = V4L2_BUF_TYPE_VBI_CAPTURE, .name = "vbi", .desc = desc_v4l2_vbi_format, },{ /* end of list */ }}, },{ /* end of list */ }}; struct struct_desc desc_v4l2_streamparm[] = {{ .type = ENUM32, .name = "type", .enums = desc_v4l2_buf_type, .length = sizeof(desc_v4l2_buf_type) / sizeof(char*), },{ /* FIXME ... */ /* end of list */ }}; struct struct_desc desc_v4l2_std_id[] = {{ .type = BITS64, .name = "std", .bits = bits_standard, },{ /* end of list */ }}; /* ---------------------------------------------------------------------- */ struct ioctl_desc ioctls_v4l2[256] = { [_IOC_NR(VIDIOC_QUERYCAP)] = { .name = "VIDIOC_QUERYCAP", .desc = desc_v4l2_capability, }, [_IOC_NR(VIDIOC_ENUM_FMT)] = { .name = "VIDIOC_ENUM_FMT", .desc = desc_v4l2_fmtdesc, }, [_IOC_NR(VIDIOC_G_FMT)] = { .name = "VIDIOC_G_FMT", .desc = desc_v4l2_format, }, [_IOC_NR(VIDIOC_S_FMT)] = { .name = "VIDIOC_S_FMT", .desc = desc_v4l2_format, }, #if 0 [_IOC_NR(VIDIOC_G_COMP)] = { .name = "VIDIOC_G_COMP", .desc = desc_v4l2_compression, }, [_IOC_NR(VIDIOC_S_COMP)] = { .name = "VIDIOC_S_COMP", .desc = desc_v4l2_compression, }, #endif [_IOC_NR(VIDIOC_REQBUFS)] = { .name = "VIDIOC_REQBUFS", .desc = desc_v4l2_requestbuffers, }, [_IOC_NR(VIDIOC_QUERYBUF)] = { .name = "VIDIOC_QUERYBUF", .desc = desc_v4l2_buffer, }, [_IOC_NR(VIDIOC_G_FBUF)] = { .name = "VIDIOC_G_FBUF", .desc = desc_v4l2_framebuffer, }, [_IOC_NR(VIDIOC_S_FBUF)] = { .name = "VIDIOC_S_FBUF", .desc = desc_v4l2_framebuffer, }, [_IOC_NR(VIDIOC_OVERLAY)] = { .name = "VIDIOC_OVERLAY", .desc = desc_int, }, [_IOC_NR(VIDIOC_QBUF)] = { .name = "VIDIOC_QBUF", .desc = desc_v4l2_buffer, }, [_IOC_NR(VIDIOC_DQBUF)] = { .name = "VIDIOC_DQBUF", .desc = desc_v4l2_buffer, }, [_IOC_NR(VIDIOC_STREAMON)] = { .name = "VIDIOC_STREAMON", .desc = desc_int, }, [_IOC_NR(VIDIOC_STREAMOFF)] = { .name = "VIDIOC_STREAMOFF", .desc = desc_int, }, [_IOC_NR(VIDIOC_G_PARM)] = { .name = "VIDIOC_G_PARM", .desc = desc_v4l2_streamparm, }, [_IOC_NR(VIDIOC_S_PARM)] = { .name = "VIDIOC_S_PARM", .desc = desc_v4l2_streamparm, }, [_IOC_NR(VIDIOC_G_STD)] = { .name = "VIDIOC_G_STD", .desc = desc_v4l2_std_id, }, [_IOC_NR(VIDIOC_S_STD)] = { .name = "VIDIOC_S_STD", .desc = desc_v4l2_std_id, }, [_IOC_NR(VIDIOC_ENUMSTD)] = { .name = "VIDIOC_ENUMSTD", .desc = desc_v4l2_standard, }, [_IOC_NR(VIDIOC_ENUMINPUT)] = { .name = "VIDIOC_ENUMINPUT", .desc = desc_v4l2_input, }, [_IOC_NR(VIDIOC_G_CTRL)] = { .name = "VIDIOC_G_CTRL", .desc = desc_v4l2_control, }, [_IOC_NR(VIDIOC_S_CTRL)] = { .name = "VIDIOC_S_CTRL", .desc = desc_v4l2_control, }, [_IOC_NR(VIDIOC_G_TUNER)] = { .name = "VIDIOC_G_TUNER", .desc = desc_v4l2_tuner, }, [_IOC_NR(VIDIOC_S_TUNER)] = { .name = "VIDIOC_S_TUNER", .desc = desc_v4l2_tuner, }, [_IOC_NR(VIDIOC_G_AUDIO)] = { .name = "VIDIOC_G_AUDIO", .desc = desc_v4l2_audio, }, [_IOC_NR(VIDIOC_S_AUDIO)] = { .name = "VIDIOC_S_AUDIO", .desc = desc_v4l2_audio, }, [_IOC_NR(VIDIOC_QUERYCTRL)] = { .name = "VIDIOC_QUERYCTRL", .desc = desc_v4l2_queryctrl, }, [_IOC_NR(VIDIOC_QUERYMENU)] = { .name = "VIDIOC_QUERYMENU", .desc = desc_v4l2_querymenu, }, [_IOC_NR(VIDIOC_G_INPUT)] = { .name = "VIDIOC_G_INPUT", .desc = desc_int, }, [_IOC_NR(VIDIOC_S_INPUT)] = { .name = "VIDIOC_S_INPUT", .desc = desc_int, }, [_IOC_NR(VIDIOC_G_OUTPUT)] = { .name = "VIDIOC_G_OUTPUT", .desc = desc_int, }, [_IOC_NR(VIDIOC_S_OUTPUT)] = { .name = "VIDIOC_S_OUTPUT", .desc = desc_int, }, [_IOC_NR(VIDIOC_ENUMOUTPUT)] = { .name = "VIDIOC_ENUMOUTPUT", .desc = desc_v4l2_output, }, [_IOC_NR(VIDIOC_G_AUDOUT)] = { .name = "VIDIOC_G_AUDOUT", .desc = desc_v4l2_audioout, }, [_IOC_NR(VIDIOC_S_AUDOUT)] = { .name = "VIDIOC_S_AUDOUT", .desc = desc_v4l2_audioout, }, [_IOC_NR(VIDIOC_G_MODULATOR)] = { .name = "VIDIOC_G_MODULATOR", .desc = desc_v4l2_modulator, }, [_IOC_NR(VIDIOC_S_MODULATOR)] = { .name = "VIDIOC_S_MODULATOR", .desc = desc_v4l2_modulator, }, [_IOC_NR(VIDIOC_G_FREQUENCY)] = { .name = "VIDIOC_G_FREQUENCY", .desc = desc_v4l2_frequency, }, [_IOC_NR(VIDIOC_S_FREQUENCY)] = { .name = "VIDIOC_S_FREQUENCY", .desc = desc_v4l2_frequency, }, [_IOC_NR(VIDIOC_CROPCAP)] = { .name = "VIDIOC_CROPCAP", .desc = desc_v4l2_cropcap, }, [_IOC_NR(VIDIOC_G_CROP)] = { .name = "VIDIOC_G_CROP", .desc = desc_v4l2_crop, }, [_IOC_NR(VIDIOC_S_CROP)] = { .name = "VIDIOC_S_CROP", .desc = desc_v4l2_crop, }, [_IOC_NR(VIDIOC_G_JPEGCOMP)] = { .name = "VIDIOC_G_JPEGCOMP", .desc = desc_v4l2_jpegcompression, }, [_IOC_NR(VIDIOC_S_JPEGCOMP)] = { .name = "VIDIOC_S_JPEGCOMP", .desc = desc_v4l2_jpegcompression, }, [_IOC_NR(VIDIOC_QUERYSTD)] = { .name = "VIDIOC_QUERYSTD", .desc = desc_v4l2_std_id, }, [_IOC_NR(VIDIOC_TRY_FMT)] = { .name = "VIDIOC_TRY_FMT", .desc = desc_v4l2_format, }, }; /* ---------------------------------------------------------------------- */ /* * Local variables: * c-basic-offset: 8 * End: */ xawtv-3.106/structs/struct-v4l2.h000066400000000000000000000040371343350355000166720ustar00rootroot00000000000000extern char *desc_v4l2_field[]; extern char *desc_v4l2_buf_type[]; extern char *desc_v4l2_ctrl_type[]; extern char *desc_v4l2_tuner_type[]; extern char *desc_v4l2_memory[]; extern char *desc_v4l2_colorspace[]; extern char *bits_capabilities[32]; extern char *bits_standard[64]; extern char *bits_buf_flags[32]; extern char *bits_fbuf_cap[32]; extern char *bits_fbuf_flags[32]; extern char *desc_input_type[32]; extern char *bits_input_status[32]; extern char *bits_tuner_cap[32]; extern char *bits_tuner_rx[32]; extern char *desc_tuner2_mode[]; extern struct struct_desc desc_v4l2_rect[]; extern struct struct_desc desc_v4l2_fract[]; extern struct struct_desc desc_v4l2_capability[]; extern struct struct_desc desc_v4l2_pix_format[]; extern struct struct_desc desc_v4l2_fmtdesc[]; extern struct struct_desc desc_v4l2_timecode[]; extern struct struct_desc desc_v4l2_compression[]; extern struct struct_desc desc_v4l2_jpegcompression[]; extern struct struct_desc desc_v4l2_requestbuffers[]; extern struct struct_desc desc_v4l2_buffer[]; extern struct struct_desc desc_v4l2_framebuffer[]; extern struct struct_desc desc_v4l2_clip[]; extern struct struct_desc desc_v4l2_window[]; extern struct struct_desc desc_v4l2_captureparm[]; extern struct struct_desc desc_v4l2_outputparm[]; extern struct struct_desc desc_v4l2_cropcap[]; extern struct struct_desc desc_v4l2_crop[]; extern struct struct_desc desc_v4l2_standard[]; extern struct struct_desc desc_v4l2_input[]; extern struct struct_desc desc_v4l2_output[]; extern struct struct_desc desc_v4l2_control[]; extern struct struct_desc desc_v4l2_queryctrl[]; extern struct struct_desc desc_v4l2_querymenu[]; extern struct struct_desc desc_v4l2_tuner[]; extern struct struct_desc desc_v4l2_modulator[]; extern struct struct_desc desc_v4l2_frequency[]; extern struct struct_desc desc_v4l2_audio[]; extern struct struct_desc desc_v4l2_audioout[]; extern struct struct_desc desc_v4l2_vbi_format[]; extern struct struct_desc desc_v4l2_format[]; extern struct struct_desc desc_v4l2_streamparm[]; extern struct ioctl_desc ioctls_v4l2[256]; xawtv-3.106/structs/struct2desc000066400000000000000000000032311343350355000165730ustar00rootroot00000000000000#!/usr/bin/perl use strict; my %mapit = ( "int" => "SINT32", "__s32" => "SINT32", "__u32" => "UINT32", "__s16" => "SINT16", "__u16" => "UINT16", "__s8" => "SINT8", "__u8" => "UINT8", ); my $struct = 0; my $enum = 0; while (my $line = <>) { # start of struct if ($line =~ m/^struct\s+(\w+)/) { die "--\n$line\nstruct is 1" if $struct == 1; $struct = 1; print "\n"; print "struct struct_desc desc_$1\[\] = {{\n"; next; } next if ($struct == 1 && $line =~ /^\{/); # end of struct if ($struct == 1 && $line =~ m/^\};/) { $struct = 0; print " .type = END_OF_LIST,\n"; print "}};\n"; next; } # struct elements if ($struct == 1 && $line =~ m/^\s+(int|__u32|__s32|__u16|__s16|__u8|__s8)\s+(\w+);/) { print " .type = $mapit{$1},\n"; print " .name = \"$2\",\n"; print "},{\n"; next; } if ($struct == 1 && $line =~ m/^\s+(char|__u8)\s+(\w+)\[(\d+)\];/) { print " .type = STRING,\n"; print " .name = \"$2\",\n"; print " .length = $3,\n"; print "},{\n"; next; } if ($struct == 1 && $line =~ m/^\s+enum\s+(\w+)\s+(\w+);/) { print " .type = ENUM,\n"; print " .name = \"$2\",\n"; print " .enums = desc_$1,\n"; print "},{\n"; next; } # start of enum if ($line =~ m/^enum\s+(\w+)/) { die "--\n$line\nenum is 1" if $enum == 1; $enum = 1; print "\n"; print "char desc_$1\[\] = {\n"; next; } # end of enum if ($enum == 1 && $line =~ m/^\};/) { $enum = 0; print "};\n"; next; } # enum elements if ($enum == 1 && $line =~ m/^\s+(\w+)/) { print " [$1] = \"$1\",\n"; next; } next if $line =~ m/#define/; next if $struct == 0; chomp $line; print "/* FIXME $line */\n"; } xawtv-3.106/todo/000077500000000000000000000000001343350355000136425ustar00rootroot00000000000000xawtv-3.106/todo/tmohan/000077500000000000000000000000001343350355000151305ustar00rootroot00000000000000xawtv-3.106/todo/tmohan/webcam.c000066400000000000000000001107271343350355000165420ustar00rootroot00000000000000/* * (c) 1998-2002 Gerd Knorr * * capture a image, compress as jpeg and upload to the webserver * using the ftp utility or ssh * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "grab-ng.h" #include "jpeglib.h" #include "ftp.h" #include "parseconfig.h" #include "list.h" const char *HTMLSTART = { "\n" "\n\n" "\n" "Webcam\n" "\n" "\n" "\n" "\n" "\n" "\n\n" "\n\n" }; const char *HTMLEND = { "\n\n\n" "\n" }; const char *HTMLIMAGE = { "\n" }; /* ---------------------------------------------------------------------- */ /* configuration */ int daemonize = 0; char *archive = NULL; char *tmpdir; struct list_head connections; struct list_head plugin_list; struct plugin_s { struct ng_filter *filter; struct list_head list; }; char *grab_text = "webcam %Y-%m-%d %H:%M:%S"; /* strftime */ char *grab_infofile = NULL; int grab_width = 320; int grab_height = 240; int grab_delay = 3; int grab_wait = 0; int grab_rotate = 0; int grab_top = 0; int grab_left = 0; int grab_bottom = -1; int grab_right = -1; int grab_quality = 75; int grab_trigger = 0; char *grab_trigger_area = "0%,0%,100%,100%"; int grab_trigger_average = 0; int grab_trigger_delay = 0; int grab_times = -1; int grab_fg_r = 255; int grab_fg_g = 255; int grab_fg_b = 255; int grab_bg_r = -1; int grab_bg_g = -1; int grab_bg_b = -1; char *grab_input = NULL; char *grab_norm = NULL; /* ---------------------------------------------------------------------- */ /* jpeg stuff */ static int write_file (int fd, char *data, int width, int height) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE *fp; int i; unsigned char *line; fp = fdopen (fd, "w"); cinfo.err = jpeg_std_error (&jerr); jpeg_create_compress (&cinfo); jpeg_stdio_dest (&cinfo, fp); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults (&cinfo); jpeg_set_quality (&cinfo, grab_quality, TRUE); jpeg_start_compress (&cinfo, TRUE); for (i = 0, line = data; i < height; i++, line += width * 3) jpeg_write_scanlines (&cinfo, &line, 1); jpeg_finish_compress (&(cinfo)); jpeg_destroy_compress (&(cinfo)); fclose (fp); return 0; } /* ---------------------------------------------------------------------- */ /* image transfer */ struct xfer_ops; struct xfer_state { char *name; struct list_head list; /* xfer options */ char *host; char *user; char *pass; char *dir; char *file; char *tmpfile; int debug; int keepjpegs; int currentCount; char *htmlfile; char *custom_htmlfile; /* ftp options */ int passive, autologin; /* function pointers + private date */ struct xfer_ops *ops; void *data; }; struct xfer_ops { int (*open) (struct xfer_state *); void (*info) (struct xfer_state *); int (*xfer) (struct xfer_state *, char *image, int width, int height); void (*close) (struct xfer_state *); }; static int ftp_open (struct xfer_state *s) { s->data = ftp_init (s->name, s->autologin, s->passive, s->debug); ftp_connect (s->data, s->host, s->user, s->pass, s->dir); return 0; } static void ftp_info (struct xfer_state *s) { fprintf (stderr, "ftp config [%s]:\n %s@%s:%s\n %s => %s\n", s->name, s->user, s->host, s->dir, s->tmpfile, s->file); } static int ftp_xfer (struct xfer_state *s, char *image, int width, int height) { char filename[1024]; int fh; sprintf (filename, "%s/webcamXXXXXX", tmpdir); if (-1 == (fh = mkstemp (filename))) { perror ("mkstemp"); exit (1); } write_file (fh, image, width, height); if (!ftp_stillconnected (s->data)) ftp_connect (s->data, s->host, s->user, s->pass, s->dir); char ftpfilename[1024]; strcpy (ftpfilename, s->file); if (s->keepjpegs > 1) { //tack a number to the file. ..before the extension char *extpos, *ext = NULL; if ((extpos = strrchr (ftpfilename, '.'))) { ext = strdup (extpos); *(extpos) = '\0'; } sprintf (ftpfilename, "%s%02i", ftpfilename, s->currentCount); if (ext) { strcat (ftpfilename, ext); free (ext); } } ftp_upload (s->data, filename, ftpfilename, s->tmpfile); unlink (filename); return 0; } static void ftp_close (struct xfer_state *s) { ftp_fini (s->data); } static struct xfer_ops ftp_ops = { open:ftp_open, info:ftp_info, xfer:ftp_xfer, close:ftp_close, }; static int ssh_open (struct xfer_state *s) { s->data = malloc (strlen (s->user) + strlen (s->host) + strlen (s->tmpfile) * 2 + strlen (s->dir) + strlen (s->file) + 32); sprintf (s->data, "ssh %s@%s \"cat >%s && mv %s %s/%s\"", s->user, s->host, s->tmpfile, s->tmpfile, s->dir, s->file); return 0; } static void ssh_info (struct xfer_state *s) { fprintf (stderr, "ssh config [%s]:\n %s@%s:%s\n %s => %s\n", s->name, s->user, s->host, s->dir, s->tmpfile, s->file); } static int ssh_xfer (struct xfer_state *s, char *image, int width, int height) { char filename[1024]; char *cmd = s->data; unsigned char buf[4096]; FILE *sshp, *imgdata; int len, fh; sprintf (filename, "%s/webcamXXXXXX", tmpdir); if (-1 == (fh = mkstemp (filename))) { perror ("mkstemp"); exit (1); } write_file (fh, image, width, height); if ((sshp = popen (cmd, "w")) == NULL) { perror ("popen"); exit (1); } if ((imgdata = fopen (filename, "rb")) == NULL) { perror ("fopen"); exit (1); } for (;;) { len = fread (buf, 1, sizeof (buf), imgdata); if (len <= 0) break; fwrite (buf, 1, len, sshp); } fclose (imgdata); pclose (sshp); unlink (filename); return 0; } static void ssh_close (struct xfer_state *s) { char *cmd = s->data; free (cmd); } static struct xfer_ops ssh_ops = { open:ssh_open, info:ssh_info, xfer:ssh_xfer, close:ssh_close, }; static int local_open (struct xfer_state *s) { char *t; if (s->dir != NULL && s->dir[0] != '\0') { t = malloc (strlen (s->tmpfile) + strlen (s->dir) + 2); sprintf (t, "%s/%s", s->dir, s->tmpfile); s->tmpfile = t; t = malloc (strlen (s->file) + strlen (s->dir) + 2); sprintf (t, "%s/%s", s->dir, s->file); s->file = t; } return 0; } static void local_info (struct xfer_state *s) { fprintf (stderr, "write config [%s]:\n local transfer %s => %s\n", s->name, s->tmpfile, s->file); } static int local_xfer (struct xfer_state *s, char *image, int width, int height) { int fh; if (-1 == (fh = open (s->tmpfile, O_CREAT | O_WRONLY | O_TRUNC, 0666))) { fprintf (stderr, "open %s: %s\n", s->tmpfile, strerror (errno)); exit (1); } write_file (fh, image, width, height); if (rename (s->tmpfile, s->file)) { fprintf (stderr, "can't move %s -> %s\n", s->tmpfile, s->file); exit (1); } return 0; } static void local_close (struct xfer_state *s) { /* nothing */ } static struct xfer_ops local_ops = { open:local_open, info:local_info, xfer:local_xfer, close:local_close, }; /* ---------------------------------------------------------------------- */ /* capture stuff */ static struct ng_video_buf *ng_buf; const struct ng_vid_driver *drv; void *h_drv; struct ng_video_fmt fmt, gfmt; struct ng_video_conv *conv; struct ng_filter filter; void *hconv; static void grab_init (void) { struct ng_attribute *attr; int val, i; drv = ng_vid_open (ng_dev.video, ng_dev.driver, NULL, 0, &h_drv); if (NULL == drv) { fprintf (stderr, "no grabber device available\n"); exit (1); } if (!(drv->capabilities (h_drv) & CAN_CAPTURE)) { fprintf (stderr, "device does'nt support capture\n"); exit (1); } if (grab_input) { attr = ng_attr_byid (drv->list_attrs (h_drv), ATTR_ID_INPUT); val = ng_attr_getint (attr, grab_input); if (-1 == val) { fprintf (stderr, "invalid input: %s\n", grab_input); exit (1); } attr->write (attr, val); } if (grab_norm) { attr = ng_attr_byid (drv->list_attrs (h_drv), ATTR_ID_NORM); val = ng_attr_getint (attr, grab_norm); if (-1 == val) { fprintf (stderr, "invalid norm: %s\n", grab_norm); exit (1); } attr->write (attr, val); } /* try native */ fmt.fmtid = VIDEO_RGB24; fmt.width = grab_width; fmt.height = grab_height; if (0 == drv->setformat (h_drv, &fmt)) return; /* check all available conversion functions */ fmt.bytesperline = fmt.width * ng_vfmt_to_depth[fmt.fmtid] / 8; for (i = 0;;) { conv = ng_conv_find_to (fmt.fmtid, &i); if (NULL == conv) break; gfmt = fmt; gfmt.fmtid = conv->fmtid_in; gfmt.bytesperline = 0; if (0 == drv->setformat (h_drv, &gfmt)) { fmt.width = gfmt.width; fmt.height = gfmt.height; hconv = conv->init (&fmt, conv->priv); return; } } fprintf (stderr, "can't get rgb24 data\n"); exit (1); } static unsigned char * grab_one (int *width, int *height, struct ng_video_buf **buf) { struct ng_video_buf *ng_cap; if (NULL != *buf) ng_release_video_buf (*buf); if (NULL == (ng_cap = drv->getimage (h_drv))) { fprintf (stderr, "capturing image failed\n"); exit (1); } if (NULL != conv) { *buf = ng_malloc_video_buf (&fmt, 3 * fmt.width * fmt.height); conv->frame (hconv, *buf, ng_cap); (*buf)->info = ng_cap->info; ng_release_video_buf (ng_cap); } else { *buf = ng_cap; } *width = (*buf)->fmt.width; *height = (*buf)->fmt.height; return (*buf)->data; } /* ---------------------------------------------------------------------- */ #define MSG_MAXLEN 256 #define CHAR_HEIGHT 11 #define CHAR_WIDTH 6 #define CHAR_START 4 #include "font-6x11.h" static char * get_message (void) { static char buffer[MSG_MAXLEN + 1]; FILE *fp; char *p; if (NULL == grab_infofile) return grab_text; if (NULL == (fp = fopen (grab_infofile, "r"))) { fprintf (stderr, "open %s: %s\n", grab_infofile, strerror (errno)); return grab_text; } fgets (buffer, MSG_MAXLEN, fp); fclose (fp); if (NULL != (p = strchr (buffer, '\n'))) *p = '\0'; return buffer; } static void add_text (char *image, int width, int height) { time_t t; struct tm *tm; char line[MSG_MAXLEN + 1], *ptr; int i, x, y, f, len; time (&t); tm = localtime (&t); len = strftime (line, MSG_MAXLEN, get_message (), tm); fprintf (stderr, "%s\n", line); for (y = 0; y < CHAR_HEIGHT; y++) { ptr = image + 3 * width * (height - CHAR_HEIGHT - 2 + y) + 12; for (x = 0; x < len; x++) { f = fontdata[line[x] * CHAR_HEIGHT + y]; for (i = CHAR_WIDTH - 1; i >= 0; i--) { if (f & (CHAR_START << i)) { ptr[0] = grab_fg_r; ptr[1] = grab_fg_g; ptr[2] = grab_fg_b; } else if (grab_bg_r != -1) { ptr[0] = grab_bg_r; ptr[1] = grab_bg_g; ptr[2] = grab_bg_b; } ptr += 3; } } } } /* ---------------------------------------------------------------------- */ /* Frederic Helin - 15/07/2002 */ /* Correction fonction of stereographic radial distortion */ int grab_dist_on = 0; int grab_dist_k = 700; int grab_dist_cx = -1; int grab_dist_cy = -1; int grab_dist_zoom = 50; int grab_dist_sensorw = 640; int grab_dist_sensorh = 480; static unsigned char * correct_distor (unsigned char *in, int width, int height, int grab_zoom, int grap_k, int cx, int cy, int grab_sensorw, int grab_sensorh) { static unsigned char *corrimg = NULL; int i, j, di, dj; float dr, cr, ca, sensor_w, sensor_h, sx, zoom, k; sensor_w = grab_dist_sensorw / 100.0; sensor_h = grab_dist_sensorh / 100.0; zoom = grab_zoom / 100.0; k = grap_k / 100.0; if (corrimg == NULL && (corrimg = malloc (width * height * 3)) == NULL) { fprintf (stderr, "out of memory\n"); exit (1); } sensor_w = 6.4; sensor_h = 4.8; // calc ratio x/y sx = width * sensor_h / (height * sensor_w); // calc new value of k in the coordonates systeme of computer k = k * height / sensor_h; // Clear image for (i = 0; i < height * width * 3; i++) corrimg[i] = 255; for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { // compute radial distortion / parameters of center of image cr = sqrt ((i - cx) / sx * (i - cx) / sx + (j - cy) * (j - cy)); ca = atan (cr / k / zoom); dr = k * tan (ca / 2); if (i == cx && j == cy) { di = cx; dj = cy; } else { di = (i - cx) * dr / cr + cx; dj = (j - cy) * dr / cr + cy; } if (dj < height && di < width && di >= 0 && dj >= 0 && j < height && i < width && i >= 0 && j >= 0) { corrimg[3 * (j * width + i)] = in[3 * (dj * width + di)]; corrimg[3 * (j * width + i) + 1] = in[3 * (dj * width + di) + 1]; corrimg[3 * (j * width + i) + 2] = in[3 * (dj * width + di) + 2]; } } } return corrimg; } /* ---------------------------------------------------------------------- */ /*static unsigned int compare_images(unsigned char *last, unsigned char *current, int width, int height) { unsigned char *p1 = last; unsigned char *p2 = current; int avg, diff, max, i = width*height*3; for (max = 0, avg = 0; --i; p1++,p2++) { //diff = (*p1 < *p2) ? (*p2 - *p1) : (*p1 - *p2); diff = abs(*p1 - *p2); avg += diff; if (diff > max) max = diff; } avg = avg / width / height; fprintf(stderr,"compare: max=%d,avg=%d\n",max,avg); // return max return max; }*/ static unsigned int compare_images (unsigned char *last, unsigned char *current, int offsetx, int offsety, int iwidth, int iheight, int imagewidth) { unsigned char *p1 = last; unsigned char *p2 = current; unsigned int p; int x, y, diff, max = 0; unsigned int avg = 0; offsety *= 3; offsetx *= 3; iheight *= 3; iwidth *= 3; for (y = offsety; y < offsety + iheight; y += 3) { p = imagewidth * y; for (x = offsetx; x < offsetx + iwidth; x++) { p1 = last + p + x; p2 = current + p + x; diff = abs (*p1 - *p2); avg += diff; if (diff > max) max = diff; } } avg = 3 * avg / iwidth / iheight; fprintf (stderr, "compare: max=%d,avg=%d\n", max, avg); // return max and average return (max << 8) | avg; } /*int max2 = 0; static unsigned int compare_images(unsigned char *saved, unsigned char *last, unsigned char *current, int width, int height) { unsigned char *p1 = last; unsigned char *p2 = current; unsigned char *p3 = saved; int avg, diff, max, i = width*height*3; int avg2, diff2; for (max = 0, avg = 0, max2=0,avg2=0; --i; p1++,p2++,p3++) { diff = abs(*p1 - *p2); avg += diff; if (diff > max) max = diff; diff2 = abs(*p3 - *p2); avg2 += diff2; if (diff2 > max2) max2 = diff2; } avg = avg / width / height; avg2 = avg2 / width / height; fprintf(stderr,"compare: max=%d,%d,avg=%d,%d\n",max,max2,avg,avg2); return max; }*/ static unsigned char * rotate_image (unsigned char *in, int *wp, int *hp, int rot, int top, int left, int bottom, int right) { static unsigned char *rotimg = NULL; int i, j; int w = *wp; int ow = (right - left); int oh = (bottom - top); if (rotimg == NULL && (rotimg = malloc (ow * oh * 3)) == NULL) { fprintf (stderr, "out of memory\n"); exit (1); } switch (rot) { default: case 0: for (j = 0; j < oh; j++) { int ir = (j + top) * w + left; int or = j * ow; for (i = 0; i < ow; i++) { rotimg[3 * (or + i)] = in[3 * (ir + i)]; rotimg[3 * (or + i) + 1] = in[3 * (ir + i) + 1]; rotimg[3 * (or + i) + 2] = in[3 * (ir + i) + 2]; } } *wp = ow; *hp = oh; break; case 1: for (i = 0; i < ow; i++) { int rr = (ow - 1 - i) * oh; int ic = i + left; for (j = 0; j < oh; j++) { rotimg[3 * (rr + j)] = in[3 * ((j + top) * w + ic)]; rotimg[3 * (rr + j) + 1] = in[3 * ((j + top) * w + ic) + 1]; rotimg[3 * (rr + j) + 2] = in[3 * ((j + top) * w + ic) + 2]; } } *wp = oh; *hp = ow; break; case 2: for (j = 0; j < oh; j++) { int ir = (j + top) * w; for (i = 0; i < ow; i++) { rotimg[3 * ((oh - 1 - j) * ow + (ow - 1 - i))] = in[3 * (ir + i + left)]; rotimg[3 * ((oh - 1 - j) * ow + (ow - 1 - i)) + 1] = in[3 * (ir + i + left) + 1]; rotimg[3 * ((oh - 1 - j) * ow + (ow - 1 - i)) + 2] = in[3 * (ir + i + left) + 2]; } } *wp = ow; *hp = oh; break; case 3: for (i = 0; i < ow; i++) { int rr = i * oh; int ic = i + left; rr += oh - 1; for (j = 0; j < oh; j++) { rotimg[3 * (rr - j)] = in[3 * ((j + top) * w + ic)]; rotimg[3 * (rr - j) + 1] = in[3 * ((j + top) * w + ic) + 1]; rotimg[3 * (rr - j) + 2] = in[3 * ((j + top) * w + ic) + 2]; } } *wp = oh; *hp = ow; break; } return rotimg; } //----------------------------------------------------- // T.Mohan - 28 July 2002 // # strnsub() is based on source by Erik Bachmann and // # was released to public domain on 27 Oct 1995. //----------------------------------------------------- static char * strnsub (char *pszString, char *pszPattern, char *pszReplacement, int iMaxLength, int bOnce) { char *pszSubstring, *pszTmpSubstring, *pszlast, *pszTempReplacement; int iPatternLength, iReplacementLength; pszSubstring = pszString; pszTmpSubstring = NULL; iPatternLength = strlen (pszPattern); pszlast = NULL; if (!strcmp (pszPattern, pszReplacement)) return NULL; // Pattern == replacement: loop while ((pszSubstring = strstr (pszSubstring, pszPattern))) { iReplacementLength = strlen (pszReplacement); pszTempReplacement = pszReplacement; if ((strlen (pszString) + (iReplacementLength - iPatternLength)) > iMaxLength) break; // Not enough space for replacement if (pszTmpSubstring == NULL) //allocate some memory only once { if ((pszTmpSubstring = (char *) calloc (iMaxLength, sizeof (char))) == NULL) return NULL; // oops, not enough memory? } strcpy (pszTmpSubstring, pszSubstring + iPatternLength); while (iReplacementLength--) { // Copy replacement *pszSubstring++ = *pszTempReplacement++; } strcpy (pszSubstring, pszTmpSubstring); pszlast = pszSubstring - iPatternLength; if (bOnce) break; //just change one } if (pszTmpSubstring) free (pszTmpSubstring); return pszlast; } //----------------------------------------------------- // T.Mohan - 28 July 2002 //----------------------------------------------------- static int ftp_upload_htmlfile (struct xfer_state *s) { #define MAXLINELEN 1024 FILE *filecustom, *filewrite; int filetemp; char line[MAXLINELEN]; char tmpfname[1024]; char jpegnumbered[1024], jpegfilename[1024]; char pattern[20], pattern_newest[20]; char *pszFound; strcpy (pattern, "%%webcam.jpg%%"); //replace with numbered .jpg's strcpy (pattern_newest, "%%newest.jpg%%"); //replace with newest .jpg pszFound = NULL; filecustom = filewrite = NULL; //open the custom html file if requested if (s->custom_htmlfile) { if ((filecustom = fopen (s->custom_htmlfile, "r")) == NULL) { perror (s->htmlfile); return 1; } } //create a temporary file sprintf (tmpfname, "%s/webcamhtmlXXXXXX", tmpdir); if (-1 == (filetemp = mkstemp (tmpfname))) { perror ("mkstemp create"); fclose (filecustom); return 1; } if ((filewrite = fdopen (filetemp, "w")) == NULL) { perror ("htmlfile open for write"); fclose (filecustom); unlink (tmpfname); return 1; } if (s->keepjpegs > 1) //format the filename { strcpy (jpegfilename, s->file); char *extpos, *ext = NULL; if ((extpos = strrchr (jpegfilename, '.'))) { ext = strdup (extpos); *(extpos) = '\0'; } //end up with something like 'webcam%02i.jpg' sprintf (jpegfilename, "%s%%02i", jpegfilename); if (ext) //tack on the extension if there is one { strcat (jpegfilename, ext); free (ext); } } else { strcpy (jpegnumbered, s->file); } //find pattern and replace with approriate filename in custom html file int count = s->currentCount; if (filecustom) { int actualcount = 0; while (fgets (line, sizeof (line), filecustom) != NULL) { if (s->keepjpegs > 1) sprintf (jpegnumbered, jpegfilename, count); //replace patterns in entire line with the numbered jpeg if (strnsub (line, pattern, jpegnumbered, MAXLINELEN, FALSE)) { if (--count < 1) count = s->keepjpegs; actualcount++; } //replace tag for %%newest.jpg%% if (s->keepjpegs > 1) sprintf (jpegnumbered, jpegfilename, s->currentCount); strnsub (line, pattern_newest, jpegnumbered, MAXLINELEN, FALSE); //write line fputs (line, filewrite); } if ((s->keepjpegs > 1) && (actualcount != s->keepjpegs)) fprintf (stderr, "\n*** Warning: Found %i patterns, but keepjpegs = %i\n\n", actualcount, s->keepjpegs); } else { fputs (HTMLSTART, filewrite); int i = s->keepjpegs; while (i--) { strcpy (line, HTMLIMAGE); if (s->keepjpegs > 1) sprintf (jpegnumbered, jpegfilename, count); if (strnsub (line, pattern, jpegnumbered, MAXLINELEN, TRUE)) { if (--count < 1) count = s->keepjpegs; } //replace tag for %%newest.jpg%% //sprintf(jpegnumbered,jpegfilename,s->currentCount); //strnsub(line, pattern_newest, jpegnumbered, MAXLINELEN, FALSE); fputs (line, filewrite); } fputs (HTMLEND, filewrite); } if (filecustom) fclose (filecustom); if (filewrite) fclose (filewrite); //upload the html file sprintf (jpegfilename, "%s%s", s->tmpfile, ".html"); fprintf (stderr, "%s,%s,%s\n", tmpfname, s->htmlfile, jpegfilename); ftp_upload (s->data, tmpfname, s->htmlfile, jpegfilename); unlink (tmpfname); return 0; } static void parse_trigger_area (char *pszTriggerArea, int *ixoffset, int *iyoffset, int *width, int *height) { if (!ixoffset || !iyoffset || !width || !height) return; if (!pszTriggerArea) pszTriggerArea = "0%,0%,100%,100%"; char *str, *perc, *tmpStr; int count = -1, ta[4], err = 0; tmpStr = strdup (pszTriggerArea); str = strtok (tmpStr, ","); while (str && (++count < 4)) { if ((perc = strstr (str, "%"))) *perc = '\0'; if (perc) ta[count] = atoi (str) * ((count % 2) ? *height : *width) / 100; else ta[count] = atoi (str); str = strtok (NULL, ","); } free (tmpStr); //some foolproofing... if ((ta[0] < 0) || (ta[0] > *width)) { ta[0] = 0; err = 1; } if ((ta[1] < 0) || (ta[1] > *height)) { ta[1] = 0; err = 1; } if ((ta[2] < 0) || (ta[2] > *width)) { ta[2] = *width; err = 1; } if ((ta[3] < 0) || (ta[3] > *height)) { ta[3] = *height; err = 1; } if (ta[0] >= ta[2]) { ta[2] = *width; err = 1; } if (ta[1] >= ta[3]) { ta[3] = *height; err = 1; } if (ta[2] <= ta[0]) { ta[0] = 0; err = 1; } if (ta[3] <= ta[1]) { ta[1] = 0; err = 1; } if (err) fprintf (stderr, "\n*** Invalid trigger area was fixed.\n\n"); *ixoffset = ta[0]; *iyoffset = ta[1]; *width = ta[2] - ta[0]; *height = ta[3] - ta[1]; } static void draw_trigger_area (unsigned char *image, int offsetx, int offsety, int iTriggerwidth, int iTriggerheight, int iImageWidth) { unsigned char *p; int x, y; offsety *= 3; offsetx *= 3; iTriggerheight *= 3; iTriggerwidth *= 3; for (y = offsety; y < offsety + iTriggerheight; y += 3) { p = image + iImageWidth * y; for (x = offsetx; x < offsetx + iTriggerwidth; x++) { //trigger area is drawn inverted *(p + x) = 255 - *(p + x); } } } static char * trim (char *p) { while ((*p == ' ')) p++; while ((p[strlen (p) - 1]) == ' ') p[strlen (p) - 1] = '\0'; return p; } static struct ng_filter * get_plugin (char *name) { int i; for (i = 0; NULL != ng_filters[i]; i++) if (!strcmp (ng_filters[i]->name, name)) return ng_filters[i]; return NULL; } static void parse_plugins (void) { char *name, *attributes, *str; int count = 0; struct ng_filter *plugin; struct plugin_s *currfilter = NULL; INIT_LIST_HEAD (&plugin_list); if ((str = cfg_get_str ("plugins", "names")) == NULL) return; while ((name = strtok (str, ","))) { str = NULL; //remove asterix for spaces strnsub (name, "*", " ", strlen (name), FALSE); name = trim (name); //plugin actually exists? if ((plugin = get_plugin (name)) == NULL) { fprintf (stderr, "plugin: [%s] not found.\n", name); continue; } currfilter = malloc (sizeof (*currfilter)); memset (currfilter, 0, sizeof (*currfilter)); currfilter->filter = plugin; list_add_tail (&currfilter->list, &plugin_list); fprintf (stderr, "plugin: [%s] found.\n", name); count++; } //parse the attributes struct list_head *item; name = NULL; list_for_each (item, &plugin_list) { struct plugin_s *currfilter = NULL; currfilter = list_entry (item, struct plugin_s, list); if (name) free (name); name = strdup (currfilter->filter->name); //replace spaces in the name with asterix strnsub (name, " ", "*", strlen (name), FALSE); attributes = cfg_get_str ("plugins", name); //remove asterix for spaces strnsub (name, "*", " ", strlen (name), FALSE); //parse the attributes if (!attributes) { if (currfilter->filter->attrs) fprintf (stderr, "plugin: [%s] Using default attributes.\n", name); continue; } char *attr = attributes; char attrname[64], attrvalue[192]; struct ng_attribute *nga = NULL; while ((attributes = strtok (attr, ","))) { attr = NULL; if (sscanf (attributes, " %63[^=] = %191[^\n]", attrname, attrvalue) != 2) fprintf (stderr, "plugin: [%s] Parse error for attribute %s\n", name, attrname); trim (attrname); if (currfilter->filter->attrs == NULL) { fprintf (stderr, "plugin: [%s] has no attributes to set.\n", name); break; } if (!(nga = ng_attr_byname (currfilter->filter->attrs, attrname))) { fprintf (stderr, "plugin: [%s] Unkown attribute: %s\n", name, attrname); } else { nga->write (nga, atoi (attrvalue)); fprintf (stderr, "plugin: [%s] Wrote attribute: %s, value: %s\n", name, attrname, attrvalue); } } } if (name) free (name); if (count) fprintf (stderr, "plugin: Using %d plugin%s.\n", count, (count == 1) ? "" : "s"); } /* ---------------------------------------------------------------------- */ int main (int argc, char *argv[]) { unsigned char *image, *val, *gimg, *lastimg = NULL; int width, height, i, fh; char filename[1024]; char **sections; struct list_head *item; struct xfer_state *s = NULL; int iTrigX, iTrigY, iTrigWidth, iTrigHeight; struct plugin_s *currfilter; /* read config */ if (argc > 1) { strcpy (filename, argv[1]); } else { sprintf (filename, "%s/%s", getenv ("HOME"), ".webcamrc"); } fprintf (stderr, "reading config file: %s\n", filename); cfg_parse_file (filename); ng_init (); //setup the plugins parse_plugins (); if (NULL != (val = cfg_get_str ("grab", "device"))) ng_dev.video = val; if (NULL != (val = cfg_get_str ("grab", "driver"))) ng_dev.driver = val; if (NULL != (val = cfg_get_str ("grab", "text"))) grab_text = val; if (NULL != (val = cfg_get_str ("grab", "infofile"))) grab_infofile = val; if (NULL != (val = cfg_get_str ("grab", "input"))) grab_input = val; if (NULL != (val = cfg_get_str ("grab", "norm"))) grab_norm = val; if (-1 != (i = cfg_get_int ("grab", "width"))) grab_width = i; if (-1 != (i = cfg_get_int ("grab", "height"))) grab_height = i; if (-1 != (i = cfg_get_int ("grab", "delay"))) grab_delay = i; if (-1 != (i = cfg_get_int ("grab", "wait"))) grab_wait = i; if (-1 != (i = cfg_get_int ("grab", "rotate"))) grab_rotate = i; if (-1 != (i = cfg_get_int ("grab", "top"))) grab_top = i; if (-1 != (i = cfg_get_int ("grab", "left"))) grab_left = i; grab_bottom = cfg_get_int ("grab", "bottom"); grab_right = cfg_get_int ("grab", "right"); if (-1 != (i = cfg_get_int ("grab", "quality"))) grab_quality = i; if (-1 != (i = cfg_get_int ("grab", "trigger"))) grab_trigger = i; if (NULL != (val = cfg_get_str ("grab", "trigger_area"))) grab_trigger_area = val; if (-1 != (i = cfg_get_int ("grab", "trigger_average"))) grab_trigger_average = i; if (-1 != (i = cfg_get_int ("grab", "trigger_delay"))) grab_trigger_delay = i; if (-1 != (i = cfg_get_int ("grab", "once"))) if (i) grab_times = 1; if (-1 != (i = cfg_get_int ("grab", "times"))) grab_times = i; if (NULL != (val = cfg_get_str ("grab", "archive"))) archive = val; if (-1 != (i = cfg_get_int ("grab", "fg_red"))) if (i >= 0 && i <= 255) grab_fg_r = i; if (-1 != (i = cfg_get_int ("grab", "fg_green"))) if (i >= 0 && i <= 255) grab_fg_g = i; if (-1 != (i = cfg_get_int ("grab", "fg_blue"))) if (i >= 0 && i <= 255) grab_fg_b = i; if (-1 != (i = cfg_get_int ("grab", "bg_red"))) if (i >= 0 && i <= 255) grab_bg_r = i; if (-1 != (i = cfg_get_int ("grab", "bg_green"))) if (i >= 0 && i <= 255) grab_bg_g = i; if (-1 != (i = cfg_get_int ("grab", "bg_blue"))) if (i >= 0 && i <= 255) grab_bg_b = i; if (-1 != (i = cfg_get_int ("grab", "distor"))) grab_dist_on = i; if (-1 != (i = cfg_get_int ("grab", "distor_k"))) grab_dist_k = i; if (-1 != (i = cfg_get_int ("grab", "distor_cx"))) grab_dist_cx = i; if (-1 != (i = cfg_get_int ("grab", "distor_cy"))) grab_dist_cy = i; if (-1 != (i = cfg_get_int ("grab", "distor_zoom"))) grab_dist_zoom = i; if (-1 != (i = cfg_get_int ("grab", "distor_sensorw"))) grab_dist_sensorw = i; if (-1 != (i = cfg_get_int ("grab", "distor_sensorh"))) grab_dist_sensorh = i; if (grab_top < 0) grab_top = 0; if (grab_left < 0) grab_left = 0; if (grab_bottom > grab_height) grab_bottom = grab_height; if (grab_right > grab_width) grab_right = grab_width; if (grab_bottom < 0) grab_bottom = grab_height; if (grab_right < 0) grab_right = grab_width; if (grab_top >= grab_bottom) grab_top = 0; if (grab_left >= grab_right) grab_left = 0; if (grab_dist_k < 1 || grab_dist_k > 10000) grab_dist_k = 700; if (grab_dist_cx < 0 || grab_dist_cx > grab_width) grab_dist_cx = grab_width / 2; if (grab_dist_cy < 0 || grab_dist_cy > grab_height) grab_dist_cy = grab_height / 2; if (grab_dist_zoom < 1 || grab_dist_zoom > 1000) grab_dist_zoom = 100; if (grab_dist_sensorw < 1 || grab_dist_sensorw > 9999) grab_dist_sensorw = 640; if (grab_dist_sensorh < 1 || grab_dist_sensorh > 9999) grab_dist_sensorh = 480; INIT_LIST_HEAD (&connections); for (sections = cfg_list_sections (); *sections != NULL; sections++) { if ((0 == strcasecmp (*sections, "grab")) || (0 == strcasecmp (*sections, "plugins"))) continue; /* init + set defaults */ s = malloc (sizeof (*s)); memset (s, 0, sizeof (*s)); s->name = *sections; s->host = "www"; s->user = "webcam"; s->pass = "xxxxxx"; s->dir = "public_html/images"; s->file = "webcam.jpeg"; s->tmpfile = "uploading.jpeg"; s->passive = 1; s->autologin = 0; s->ops = &ftp_ops; s->keepjpegs = 1; //number of jpeg files to rotate through. 0 & 1 are synonymous s->htmlfile = NULL; s->custom_htmlfile = NULL; s->currentCount = 0; /* from config */ if (NULL != (val = cfg_get_str (*sections, "host"))) s->host = val; if (NULL != (val = cfg_get_str (*sections, "user"))) s->user = val; if (NULL != (val = cfg_get_str (*sections, "pass"))) s->pass = val; if (NULL != (val = cfg_get_str (*sections, "dir"))) s->dir = val; if (NULL != (val = cfg_get_str (*sections, "file"))) s->file = val; if (NULL != (val = cfg_get_str (*sections, "tmp"))) s->tmpfile = val; if (-1 != (i = cfg_get_int (*sections, "passive"))) s->passive = i; if (-1 != (i = cfg_get_int (*sections, "auto"))) s->autologin = i; if (-1 != (i = cfg_get_int (*sections, "debug"))) s->debug = i; if (-1 != (i = cfg_get_int (*sections, "local"))) if (i) s->ops = &local_ops; if (-1 != (i = cfg_get_int (*sections, "ssh"))) if (i) s->ops = &ssh_ops; if (-1 != (i = cfg_get_int (*sections, "keepjpegs"))) s->keepjpegs = (i < 1) ? 1 : i; if (NULL != (val = cfg_get_str (*sections, "htmlfile"))) s->htmlfile = val; if (NULL != (val = cfg_get_str (*sections, "custom_htmlfile"))) s->custom_htmlfile = val; /* all done */ list_add_tail (&s->list, &connections); } /* init everything */ grab_init (); sleep (grab_wait); tmpdir = (NULL != getenv ("TMPDIR")) ? getenv ("TMPDIR") : "/tmp"; list_for_each (item, &connections) { s = list_entry (item, struct xfer_state, list); s->ops->open (s); } /* print config */ fprintf (stderr, "video4linux webcam v1.5 - (c) 1998-2002 Gerd Knorr\n"); fprintf (stderr, "grabber config:\n size %dx%d [%s]\n", fmt.width, fmt.height, ng_vfmt_to_desc[gfmt.fmtid]); fprintf (stderr, " input %s, norm %s, jpeg quality %d\n", grab_input, grab_norm, grab_quality); fprintf (stderr, " rotate=%d, top=%d, left=%d, bottom=%d, right=%d\n", grab_rotate, grab_top, grab_left, grab_bottom, grab_right); list_for_each (item, &connections) { s = list_entry (item, struct xfer_state, list); s->ops->info (s); } /* run as daemon - detach from terminal */ if (daemonize) { switch (fork ()) { case -1: perror ("fork"); exit (1); case 0: close (0); close (1); close (2); setsid (); break; default: exit (0); } } /* main loop */ for (;;) { /* grab a new one */ gimg = grab_one (&width, &height, &ng_buf); if (grab_top != 0 || grab_left != 0 || grab_right != width || grab_bottom != height) { //don't call rotate_image() if nothing to do gimg = rotate_image (gimg, &width, &height, grab_rotate, grab_top, grab_left, grab_bottom, grab_right); } if (grab_dist_on) { gimg = correct_distor (gimg, width, height, grab_dist_zoom, grab_dist_k, grab_dist_cx, grab_dist_cy, grab_dist_sensorw, grab_dist_sensorh); } image = gimg; if (grab_trigger) { /* look if it has changed */ if (NULL != lastimg) { i = compare_images (lastimg, image, iTrigX, iTrigY, iTrigWidth, iTrigHeight, width); if (grab_trigger_average) i = i & 0xFF; else i = i >> 8; if (i < grab_trigger) { if (grab_trigger_delay) usleep (grab_trigger_delay * 1000); continue; } } else { lastimg = malloc (width * height * 3); iTrigWidth = width; iTrigHeight = height; fprintf (stderr, "width: %d,height:%d\n", width, height); parse_trigger_area (grab_trigger_area, &iTrigX, &iTrigY, &iTrigWidth, &iTrigHeight); } memcpy (lastimg, image, width * height * 3); //draw inverted trigger area if debug > 1 if (s->debug > 1) draw_trigger_area (image, iTrigX, iTrigY, iTrigWidth, iTrigHeight, width); } if (!list_empty (&plugin_list)) { //if we're using plugins ng_buf will have to be valid // to pass to the filters. //assign the current image to ng_buf and make sure fmt is // valid due to possible size change in rotate_image() if (!conv && !ng_buf) ng_buf = ng_malloc_video_buf (&fmt, 3 * fmt.width * fmt.height); ng_buf->fmt.width = width; ng_buf->fmt.height = height; ng_buf->fmt.bytesperline = width * (ng_vfmt_to_depth[fmt.fmtid] / 8); ng_buf->size = ng_buf->fmt.bytesperline * height; memcpy (ng_buf->data, image, ng_buf->size); //call the plugins.... list_for_each (item, &plugin_list) { currfilter = list_entry (item, struct plugin_s, list); ng_buf = ng_filter_single (currfilter->filter, ng_buf); image = ng_buf->data; } } /* ok, label it and upload */ add_text (image, width, height); list_for_each (item, &connections) { s = list_entry (item, struct xfer_state, list); if (++s->currentCount > s->keepjpegs) s->currentCount = 1; s->ops->xfer (s, image, width, height); if (s->htmlfile) // || s->custom_htmlfile) ftp_upload_htmlfile (s); } if (archive) { time_t t; struct tm *tm; time (&t); tm = localtime (&t); strftime (filename, sizeof (filename) - 1, archive, tm); if (-1 == (fh = open (filename, O_CREAT | O_WRONLY | O_TRUNC, 0666))) { fprintf (stderr, "open %s: %s\n", filename, strerror (errno)); exit (1); } write_file (fh, image, width, height); } if (-1 != grab_times && --grab_times == 0) { fprintf (stderr, "grab \"times\" reached 0\n"); break; } if (grab_delay > 0) { fprintf (stderr, "delay for %d seconds...\n", grab_delay); sleep (grab_delay); } } list_for_each (item, &connections) { s = list_entry (item, struct xfer_state, list); s->ops->close (s); } return 0; } xawtv-3.106/travis/000077500000000000000000000000001343350355000142055ustar00rootroot00000000000000xawtv-3.106/travis/linux.bionic.before_install000077500000000000000000000000421343350355000215170ustar00rootroot00000000000000#!/bin/sh sudo apt-get update -qq xawtv-3.106/travis/linux.bionic.install000077500000000000000000000010351343350355000202000ustar00rootroot00000000000000#!/bin/sh sudo apt-get install -y \ autoconf \ automake \ libv4l-dev \ debhelper \ libaa1-dev \ libasound2-dev \ libdv-dev \ libfs-dev \ libgl1-mesa-dev \ libglib2.0-dev \ libjpeg-dev \ liblircclient-dev \ libmotif-dev \ libncurses5-dev \ libpng-dev \ libquicktime-dev \ libx11-dev \ libxaw7-dev \ libxext-dev \ libxft-dev \ libxinerama-dev \ libxmu-dev \ libxpm-dev \ libxrandr-dev \ libxt-dev \ libxv-dev \ libxxf86dga-dev \ libxxf86vm-dev \ libzvbi-dev \ po-debconf \ x11-xserver-utils \ x11proto-core-dev xawtv-3.106/travis/linux.bionic.script000077500000000000000000000001071343350355000200350ustar00rootroot00000000000000#!/bin/sh set -e autoreconf -vfi ./configure make sudo make install xawtv-3.106/vbistuff/000077500000000000000000000000001343350355000145255ustar00rootroot00000000000000xawtv-3.106/vbistuff/Subdir.mk000066400000000000000000000014431343350355000163100ustar00rootroot00000000000000 # targets to build TARGETS-vbistuff := \ vbistuff/ntsc-cc ifeq ($(FOUND_ZVBI),yes) TARGETS-vbistuff += \ vbistuff/alevtd endif HTML-alevtd := \ vbistuff/alevt.css.h \ vbistuff/top.html.h \ vbistuff/bottom.html.h \ vbistuff/about.html.h # objects for targets vbistuff/alevtd: \ vbistuff/alevtd.o \ vbistuff/request.o \ vbistuff/response.o \ vbistuff/page.o \ common/vbi-data.o \ libng/devices.o vbistuff/ntsc-cc: vbistuff/ntsc-cc.o # libraries to link vbistuff/alevtd : LDLIBS += $(VBI_LIBS) vbistuff/ntsc-cc : LDLIBS += $(ATHENA_LIBS) # global targets all:: $(TARGETS-vbistuff) install:: $(INSTALL_PROGRAM) $(STRIP_FLAG) $(TARGETS-vbistuff) $(bindir) clean:: rm -f $(HTML-alevtd) distclean:: rm -f $(TARGETS-vbistuff) # special dependences vbistuff/alevtd.o: $(HTML-alevtd) xawtv-3.106/vbistuff/about.html.in000066400000000000000000000173321343350355000171400ustar00rootroot00000000000000 about alevtd

About the alevt http daemon

This daemon serves videotext pages as HTML.  It uses the zvbi library to decode the vbi data.   Source code of this daemon comes with xawtv.

© 1999-2002 Gerd Knorr <kraxel@bytesex.org>

Jump to page ...

100   200   300   400   500   600   700   800  

teletext characters


ETS 300 706 Table 36: Latin National Option Sub-sets

# ů Ä Å¥ ž ý í Å™ é á Ä› ú Å¡ 
£ $ @ ↠½ → ↑ # — ¼ ‖ ¾ ÷ 
# õ Š Ä Ö Ž Ü Õ š ä ö ž ü 
é ï à ë ê ù î # è â ô û ç 
# $ § Ä Ö Ü ^ _ ° ä ö ü ß 
£ $ é ° ç → ↑ # ù à ò è ì 
# $ Å  Ä— È© Ž Ä Å« Å¡ Ä… ų ž į 
# ń ą Ƶ Ś Šć ó ę ż ś ł ź 
ç $ ¡ á é í ó ú ¿ ü ñ è à 
# ¤ Å¢  Ş Ç Ã Ä± Å£ â ÅŸ ÇŽ î 
# Ë ÄŒ Ć Ž à Š ë Ä Ä‡ ž ð Å¡ 
# ¤ É Ä Ö Å Ü _ é ä ö å ü 
 ğ İ Ş Ö Ç Ü Ğ ı ş ö ç ü 

ETS 300 706 Table 35: Latin G0 Primary Set


  0 @ P ` p 
! 1 A Q a q 
" 2 B R b r 
# 3 C S c s 
¤ 4 D T d t 
% 5 E U e u 
& 6 F V f v 
' 7 G W g w 
( 8 H X h x 
) 9 I Y i y 
* : J Z j z 
+ ; K [ k { 
, < L \ l ¦ 
- = M ] m } 
. > N ^ n ~ 
/ ? O _ o â–  

ETS 300 706 Table 37: Latin G2 Supplementary Set


  °   — Ω ĸ 
¡ ± ˋ ¹ Æ æ 
¢ ² ˊ ® à đ 
£ ³ ˆ © ª ð 
$ × ˜ ™ Ħ ħ 
¥ µ ˉ ♪   ı 
# ¶ ˘ ₠ IJ ij 
§ · ˙ ‰ Ŀ ŀ 
¤ ÷ ¨ ɑ Šł 
‘ ’ .   Ø ø 
“ †˚   Œ œ 
« » Ë   º ß 
↠¼ Ë â…› Þ þ 
↑ ½ Ë â…œ Ŧ ŧ 
→ ¾ Ë› â… ÅŠ Å‹ 
↓ ¿ ˇ ⅞ ʼn ■ 

ETS 300 706 Table 38: Cyrillic G0 Primary Set - Option 1 - Serbian/Croatian


  0 Ч П ч п 
! 1 РЌ а ќ 
" 2 Б Р б р 
# 3 Ц С ц Ñ 
$ 4 Д Т д т 
% 5 Е У е у 
& 6 Ф В ф в 
' 7 Г Ѓ г ѓ 
( 8 Х Љ х љ 
) 9 И Њ и њ 
* : Ј З ј з 
+ ; К Ћ к ћ 
, < Л Ж л ж 
- = М Ђ м ђ 
. > РШ н ш 
/ ? О Ро ■ 

ETS 300 706 Table 39: Cyrillic G0 Primary Set - Option 2 - Russian/Bulgarian


  0 Ю П ю п 
! 1 РЯ а Ñ 
" 2 Б Р б р 
# 3 Ц С ц Ñ 
$ 4 Д Т д т 
% 5 Е У е у 
ы 6 Ф Ж ф ж 
' 7 Г В г в 
( 8 Х Ь х ь 
) 9 И Ъ и ъ 
* : РЗ Ñ Ð· 
+ ; К Ш к ш 
, < Л Э л Ñ 
- = М Щ м щ 
. > РЧ н ч 
/ ? О Ы о ■ 

ETS 300 706 Table 40: Cyrillic G0 Primary Set - Option 3 - Ukrainian


  0 Ю П ю п 
! 1 РЯ а Ñ 
" 2 Б Р б р 
# 3 Ц С ц Ñ 
$ 4 Д Т д т 
% 5 Е У е у 
ï 6 Ф Ж ф ж 
' 7 Г В г в 
( 8 Х Ь х ь 
) 9 И І и і 
* : РЗ Ñ Ð· 
+ ; К Ш к ш 
, < Л Є л є 
- = М Щ м щ 
. > РЧ н ч 
/ ? О Ї о ■ 

ETS 300 706 Table 41: Cyrillic G2 Supplementary Set


  °   — D d 
¡ ± ˋ ¹ E e 
¢ ² ˊ ® F f 
£ ³ ˆ © G g 
  × ˜ ™ I i 
¥ µ ˉ ♪ J j 
# ¶ ˘ ₠ K k 
§ · ˙ ‰ L l 
  ÷ ¨ ɑ N n 
‘ ’ . ŠQ q 
“ †˚ ł R r 
« » Ë ÃŸ S s 
↠¼ Ë â…› U u 
↑ ½ Ë â…œ V v 
→ ¾ Ë› â… W w 
↓ ¿ ˇ ⅞ Z z 

ETS 300 706 Table 42: Greek G0 Primary Set


  0 ΠΠ ΰ π 
! 1 Α Ρ α Ï 
" 2 Β ʹ β ς 
# 3 Γ Σ γ σ 
$ 4 Δ Τ δ τ 
% 5 Ε Υ ε υ 
& 6 Ζ Φ ζ φ 
' 7 Η Χ η χ 
( 8 Θ Ψ θ ψ 
) 9 Ι Ω ι ω 
* : Κ Ϊ κ ϊ 
+ ; Λ Ϋ λ ϋ 
, « Μ ά μ ό 
- = Πέ ν Ï 
. » Ξ ή ξ ώ 
/ ? Ο ί ο ■ 

ETS 300 706 Table 43: Greek G2 Supplementary Set


  °   ? C c 
a ± ˋ ¹ D d 
b ² ˊ ® F f 
£ ³ ˆ © G g 
e x ˜ ™ J j 
h m ˉ ♪ L l 
i n ˘ ₠ Q q 
§ p ˙ ‰ R r 
: ÷ ¨ ɑ S s 
‘ ’ . Ί U u 
“ †˚ Ύ V v 
k t Ë Î W w 
↠¼ Ë â…› Y y 
↑ ½ Ë â…œ Z z 
→ ¾ Ë› â… Î† Έ 
↓ x ˇ ⅞ Ή ■ 

ETS 300 706 Table 44: Arabic G0 Primary Set


  0    î™ 
! 1   î™ î™‘ 
" 2     
£ 3     
$ 4     
% 5     
 6     
 7     
) 8     
( 9     
* :     
+ ؛     
، >     
- =   î™ î™ 
. <     
/ ØŸ  # î™ â–  

ETS 300 706 Table 45: Arabic G2 Supplementary Set


  à P é p 
  A Q a q 
  B R b r 
  C S c s 
  D T d t 
  E U e u 
  F V f v 
î™§ î™· G W g w 
  H X h x 
  I Y i y 
  J Z j z 
  K ë k â 
  L ê l ô 
  M ù m û 
  N î n ç 
  O îŸ o   

ETS 300 706 Table 46: Hebrew G0 Primary Set


  0 @ P × ×  
! 1 A Q ב ס 
" 2 B R ×’ ×¢ 
# 3 C S ד ף 
$ 4 D T ה פ 
% 5 E U ו ץ 
& 6 F V ז צ 
' 7 G W ×— ×§ 
( 8 H X ט ר 
) 9 I Y י ש 
* : J Z ך ת 
+ ; K ↠כ ₪ 
, < L ½ ל ‖ 
- = M → × Â¾ 
. > N ↑ מ ÷ 
/ ? O # ן ■ 

ETS 300 706 Table 47: G1 Block Mosaics Set

        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        

ETS 300 706 Table 48: G3 Smooth Mosaics and Line Drawing Set


î¼  î¼° î½€ î½ î½  î½° 
 î¼± î½ î½‘  î½± 
      
      
      
      
      
      
      
      
      
      
      
î¼­ î¼½ î½ î½ î½­ î½½ 
      
  î½ î½Ÿ   

Teletext composed glyphs

   @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_

   @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
ˋ  -À---È---Ì-----Ò-----Ù----------
ËŠ  -Ã-Ć-É---Ã--Ĺ-ŃÓ--ŔŚ-Ú---ÃŹ-----
ˆ  -Â-Ĉ-Ê-ĜĤÎĴ----Ô---Ŝ-Û-Ŵ-Ŷ------
˜  -Ã-------Ĩ----ÑÕ-----Ũ----------
ˉ  -Ā---Ē---Ī-----Ō-----Ū----------
˘  -Ă---Ĕ-Ğ-Ĭ-----Ŏ-----Ŭ----------
˙  ---Ċ-Ė-Ġ-İ----------------Ż-----
¨  -Ä---Ë---Ã-----Ö-----Ü---Ÿ------
.  --------------------------------
Ëš  -Ã…-------------------Å®----------
Ë  ---Ç---------------ŞŢ-----------
Ë  --------------------------------
Ë  ---------------Å-----Ű----------
˛  -Ą---Ę---Į-----------Ų----------
ˇ  ---ČĎĚ------Ľ-Ň---ŘŠ------Ž-----

Teletext composed glyphs

   `abcdefghijklmnopqrstuvwxyz{¦}~■

   `abcdefghijklmnopqrstuvwxyz{¦}~■
ˋ  -à---è---ì-----ò-----ù----------
ˊ  -á-ć-é---í----ńó--ŕś-ú---ýź-----
ˆ  -â-ĉ-ê-Äĥîĵ----ô---Å-û-ŵ-Å·------
˜  -ã-------ĩ----ñõ-----ũ----------
ˉ  -Ä---Ä“---Ä«-----Å-----Å«----------
˘  -ă---Ä•-ÄŸ-Ä­-----Å-----Å­----------
˙  ---ċ-ė-ġ------------------ż-----
¨  -ä---ë---ï-----ö-----ü---ÿ------
.  --------------------------------
˚  -å-------------------ů----------
Ë  ---ç---------------ÅŸÅ£-----------
Ë  --------------------------------
Ë  ---------------Å‘-----ű----------
˛  -ą---ę---į-----------ų----------
ˇ  ---ÄÄÄ›------ľ-ň---řš------ž-----

EIA 608 Closed Captioning Basic Character Set

  ( 0 8 @ H P X ú h p x 
! ) 1 9 A I Q Y a i q y 
" á 2 : B J R Z b j r z 
# + 3 ; C K S [ c k s ç 
$ , 4 < D L T é d l t ÷ 
% - 5 = E M U ] e m u Ñ 
& . 6 > F N V í f n v ñ 
' / 7 ? G O W ó g o w ■ 

EIA 608 Closed Captioning Special Characters

®°½¿™¢£♪à èâêîôû
xawtv-3.106/vbistuff/alevt.css.in000066400000000000000000000076331343350355000167700ustar00rootroot00000000000000body { background-color: white; color: black } pre.vt { border: 1pt solid black; padding: 12pt } pre.vt { background-color: #c0c0c0; width: auto; float: left } pre.vt { white-space: pre } pre.vt { font-family: "teletext"; font-size: 20px; line-height: 20px } div.quick { clear: both } /* videotext colors */ span.c00 { color: #000000; background-color: #000000 } span.c10 { color: #ff0000; background-color: #000000 } span.c20 { color: #00ff00; background-color: #000000 } span.c30 { color: #ffff00; background-color: #000000 } span.c40 { color: #0000ff; background-color: #000000 } span.c50 { color: #ff00ff; background-color: #000000 } span.c60 { color: #00ffff; background-color: #000000 } span.c70 { color: #ffffff; background-color: #000000 } span.c01 { color: #000000; background-color: #ff0000 } span.c11 { color: #ff0000; background-color: #ff0000 } span.c21 { color: #00ff00; background-color: #ff0000 } span.c31 { color: #ffff00; background-color: #ff0000 } span.c41 { color: #0000ff; background-color: #ff0000 } span.c51 { color: #ff00ff; background-color: #ff0000 } span.c61 { color: #00ffff; background-color: #ff0000 } span.c71 { color: #ffffff; background-color: #ff0000 } span.c02 { color: #000000; background-color: #00ff00 } span.c12 { color: #ff0000; background-color: #00ff00 } span.c22 { color: #00ff00; background-color: #00ff00 } span.c32 { color: #ffff00; background-color: #00ff00 } span.c42 { color: #0000ff; background-color: #00ff00 } span.c52 { color: #ff00ff; background-color: #00ff00 } span.c62 { color: #00ffff; background-color: #00ff00 } span.c72 { color: #ffffff; background-color: #00ff00 } span.c03 { color: #000000; background-color: #ffff00 } span.c13 { color: #ff0000; background-color: #ffff00 } span.c23 { color: #00ff00; background-color: #ffff00 } span.c33 { color: #ffff00; background-color: #ffff00 } span.c43 { color: #0000ff; background-color: #ffff00 } span.c53 { color: #ff00ff; background-color: #ffff00 } span.c63 { color: #00ffff; background-color: #ffff00 } span.c73 { color: #ffffff; background-color: #ffff00 } span.c04 { color: #000000; background-color: #0000ff } span.c14 { color: #ff0000; background-color: #0000ff } span.c24 { color: #00ff00; background-color: #0000ff } span.c34 { color: #ffff00; background-color: #0000ff } span.c44 { color: #0000ff; background-color: #0000ff } span.c54 { color: #ff00ff; background-color: #0000ff } span.c64 { color: #00ffff; background-color: #0000ff } span.c74 { color: #ffffff; background-color: #0000ff } span.c05 { color: #000000; background-color: #ff00ff } span.c15 { color: #ff0000; background-color: #ff00ff } span.c25 { color: #00ff00; background-color: #ff00ff } span.c35 { color: #ffff00; background-color: #ff00ff } span.c45 { color: #0000ff; background-color: #ff00ff } span.c55 { color: #ff00ff; background-color: #ff00ff } span.c65 { color: #00ffff; background-color: #ff00ff } span.c75 { color: #ffffff; background-color: #ff00ff } span.c06 { color: #000000; background-color: #00ffff } span.c16 { color: #ff0000; background-color: #00ffff } span.c26 { color: #00ff00; background-color: #00ffff } span.c36 { color: #ffff00; background-color: #00ffff } span.c46 { color: #0000ff; background-color: #00ffff } span.c56 { color: #ff00ff; background-color: #00ffff } span.c66 { color: #00ffff; background-color: #00ffff } span.c76 { color: #ffffff; background-color: #00ffff } span.c07 { color: #000000; background-color: #ffffff } span.c17 { color: #ff0000; background-color: #ffffff } span.c27 { color: #00ff00; background-color: #ffffff } span.c37 { color: #ffff00; background-color: #ffffff } span.c47 { color: #0000ff; background-color: #ffffff } span.c57 { color: #ff00ff; background-color: #ffffff } span.c67 { color: #00ffff; background-color: #ffffff } span.c77 { color: #ffffff; background-color: #ffffff } /* please don't re-color my links (underline is fine) */ span a { color: inherit; background-color: inherit; } span a { text-decoration: underline } xawtv-3.106/vbistuff/alevtd.c000066400000000000000000000434361343350355000161620ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if 0 /* def __linux__ */ #include # include "videodev2.h" #endif #include "httpd.h" #include "devices.h" #include "vbi-data.h" /* ---------------------------------------------------------------------- */ /* public variables - server configuration */ char *server_name = "alevtd/2.0"; int debug = 0; int dontdetach = 0; int timeout = 60; int keepalive_time = 5; int tcp_port = 0; int ascii_art = 0; char *listen_ip = NULL; char *listen_port = "5654"; int canonicalhost = 0; char server_host[256]; char user[17]; char group[17]; char *logfile = NULL; FILE *logfd = NULL; int flushlog = 0; int usesyslog = 0; int have_tty = 1; int max_conn = 32; int cachereset = 0; time_t now,start; int slisten; struct vbi_state *vbi; /* ---------------------------------------------------------------------- */ static int termsig,got_sighup,got_sigusr1; static void catchsig(int sig) { if (SIGTERM == sig || SIGINT == sig) termsig = sig; if (SIGHUP == sig) got_sighup = 1; if (SIGUSR1 == sig) got_sigusr1 = 1; } /* ---------------------------------------------------------------------- */ static void usage(char *name) { char *h; struct passwd *pw; struct group *gr; h = strrchr(name,'/'); fprintf(stderr, "alevt http daemon.\n" "\n" "usage: %s [ options ]\n" "\n" "Options:\n" " -h print this text\n" " -v dev vbi device [%s]\n" " -d enable debug output [%s]\n" " -F do not fork into background [%s]\n" " -s enable syslog (start/stop/errors) [%s]\n" " -t sec set network timeout [%i]\n" " -c n set max. allowed connections [%i]\n" " -p port use tcp-port >port< [%s]\n" " -n host server hostname is >host< [%s]\n" " -N host same as above + UseCanonicalName\n" " -i ip bind to IP-address >ip< [%s]\n" " -l log write access log to file >log< [%s]\n" " -L log same as above + flush every line\n" #if 0 " -r poll tv frequency and clear cache\n" " on station changes [%s]\n" " -a use ascii art for block graphics [%s]\n" #endif "", h ? h+1 : name, ng_dev.vbi, debug ? "on" : "off", dontdetach ? "on" : "off", usesyslog ? "on" : "off", timeout, max_conn, listen_port, server_host, listen_ip ? listen_ip : "any", logfile ? logfile : "none"); #if 0 logfile ? logfile : "none", cachereset ? "on" : "off", ascii_art ? "on" : "off"); #endif if (getuid() == 0) { pw = getpwuid(0); gr = getgrgid(getgid()); fprintf(stderr, " -u user run as user >user< [%s]\n" " -g group run as group >group< [%s]\n", pw ? pw->pw_name : "???", gr ? gr->gr_name : "???"); } exit(1); } static void fix_ug(void) { struct passwd *pw = NULL; struct group *gr = NULL; /* root is allowed to use any uid/gid, * others will get their real uid/gid */ if (0 == getuid() && strlen(user) > 0) { if (NULL == (pw = getpwnam(user))) pw = getpwuid(atoi(user)); } else { pw = getpwuid(getuid()); } if (0 == getuid() && strlen(group) > 0) { if (NULL == (gr = getgrnam(group))) gr = getgrgid(atoi(group)); } else { gr = getgrgid(getgid()); } if (NULL == pw) { xerror(LOG_ERR,"user unknown",NULL); exit(1); } if (NULL == gr) { xerror(LOG_ERR,"group unknown",NULL); exit(1); } /* set group */ if (getegid() != gr->gr_gid || getgid() != gr->gr_gid) { setgroups(0, NULL); setgid(gr->gr_gid); } if (getegid() != gr->gr_gid || getgid() != gr->gr_gid) { xerror(LOG_ERR,"setgid failed",NULL); exit(1); } strncpy(group,gr->gr_name,16); /* set user */ if (geteuid() != pw->pw_uid || getuid() != pw->pw_uid) { setgroups(0, NULL); setuid(pw->pw_uid); } if (geteuid() != pw->pw_uid || getuid() != pw->pw_uid) { xerror(LOG_ERR,"setuid failed",NULL); exit(1); } strncpy(user,pw->pw_name,16); } /* ---------------------------------------------------------------------- */ static void access_log(struct REQUEST *req, time_t now) { char timestamp[32]; /* common log format: host ident authuser date request status bytes */ strftime(timestamp,31,"[%d/%b/%Y:%H:%M:%S +0000]",gmtime(&now)); if (0 == req->status) req->status = 400; /* bad request */ if (400 == req->status) { fprintf(logfd,"%s - - %s \"-\" 400 %d\n", req->peerhost, timestamp, req->bc); } else { fprintf(logfd,"%s - - %s \"%s %s HTTP/%d.%d\" %d %d\n", req->peerhost, timestamp, req->type, req->uri, req->major, req->minor, req->status, req->bc); } if (flushlog) fflush(logfd); } /* * loglevel usage * ERR : fatal errors (which are followed by exit(1)) * WARNING: this should'nt happen error (oom, ...) * NOTICE : start/stop of the daemon * INFO : "normal" errors (canceled downloads, timeouts, * stuff what happens all the time) */ static void syslog_init(void) { openlog("alevtd",LOG_PID, LOG_DAEMON); } static void syslog_start(void) { syslog(LOG_NOTICE, "started (listen on %s:%d, user=%s, group=%s)\n", listen_ip,tcp_port,user,group); } static void syslog_stop(void) { if (termsig) syslog(LOG_NOTICE,"stopped on signal %d\n",termsig); else syslog(LOG_NOTICE,"stopped\n"); closelog(); } void xperror(int loglevel, char *txt, char *peerhost) { if (LOG_INFO == loglevel && usesyslog < 2 && !debug) return; if (have_tty) { if (NULL == peerhost) perror(txt); else fprintf(stderr,"%s: %s (peer=%s)\n",txt,strerror(errno), peerhost); } if (usesyslog) { if (NULL == peerhost) syslog(loglevel,"%s: %s\n",txt,strerror(errno)); else syslog(loglevel,"%s: %s (peer=%s)\n",txt,strerror(errno), peerhost); } } void xerror(int loglevel, char *txt, char *peerhost) { if (LOG_INFO == loglevel && usesyslog < 2 && !debug) return; if (have_tty) { if (NULL == peerhost) fprintf(stderr,"%s\n",txt); else fprintf(stderr,"%s (peer=%s)\n",txt,peerhost); } if (usesyslog) { if (NULL == peerhost) syslog(loglevel,"%s\n",txt); else syslog(loglevel,"%s (peer=%s)\n",txt,peerhost); } } static void dummy_handler(vbi_event *ev, void *unused) { return; } /* ---------------------------------------------------------------------- */ /* main loop */ static void* mainloop(void) { struct REQUEST *conns = NULL; int curr_conn = 0; struct REQUEST *req,*prev,*tmp; struct timeval tv; int max,length; fd_set rd,wr; for (;!termsig;) { if (got_sighup) { if (NULL != logfile && 0 != strcmp(logfile,"-")) { if (debug) fprintf(stderr,"got SIGHUP, reopen logfile %s\n",logfile); if (logfd) fclose(logfd); if (NULL == (logfd = fopen(logfile,"a"))) xperror(LOG_WARNING,"reopen access log",NULL); } got_sighup = 0; } #if 0 if (got_sigusr1) { if (debug) fprintf(stderr,"got SIGUSR1, reset cached vbi pages\n"); vbi->cache->op->reset(vbi->cache); got_sigusr1 = 0; } #endif FD_ZERO(&rd); FD_ZERO(&wr); FD_SET(vbi->fd,&rd); max = vbi->fd; /* add listening socket */ if (curr_conn < max_conn) { FD_SET(slisten,&rd); max = slisten; } /* add connection sockets */ for (req = conns; req != NULL; req = req->next) { switch (req->state) { case STATE_KEEPALIVE: case STATE_READ_HEADER: FD_SET(req->fd,&rd); if (req->fd > max) max = req->fd; break; case STATE_WRITE_HEADER: case STATE_WRITE_BODY: FD_SET(req->fd,&wr); if (req->fd > max) max = req->fd; break; } } /* go! */ tv.tv_sec = keepalive_time; tv.tv_usec = 0; if (-1 == select(max+1,&rd,&wr,NULL,(curr_conn > 0) ? &tv : NULL)) { if (debug) perror("select"); continue; } now = time(NULL); /* vbi data? */ if (FD_ISSET(vbi->fd,&rd)) { #if 0 /* def __linux__ */ if (cachereset) { struct v4l2_frequency freq = { }; __u32 lastfreq; freq.tuner = 0; if (!ioctl(vbi->fd, VIDIOC_G_FREQUENCY, &freq)) { if (lastfreq != freq.frequency) { lastfreq = freq.frequency; vbi->cache->op->reset( vbi->cache) ; } if (debug) fprintf(stderr, "frequency change: cache cleared.\n"); } } #endif vbi_hasdata(vbi); } /* new connection ? */ if (FD_ISSET(slisten,&rd)) { req = malloc(sizeof(struct REQUEST)); if (NULL == req) { /* oom: let the request sit in the listen queue */ if (debug) fprintf(stderr,"oom\n"); } else { memset(req,0,sizeof(struct REQUEST)); if (-1 == (req->fd = accept(slisten,NULL,NULL))) { if (EAGAIN != errno) xperror(LOG_WARNING,"accept",NULL); free(req); } else { fcntl(req->fd,F_SETFL,O_NONBLOCK); req->state = STATE_READ_HEADER; req->ping = now; req->next = conns; conns = req; curr_conn++; if (debug) fprintf(stderr,"%03d: new request (%d)\n",req->fd,curr_conn); length = sizeof(req->peer); if (-1 == getpeername(req->fd,(struct sockaddr*)&(req->peer),&length)) { xperror(LOG_WARNING,"getpeername",NULL); req->state = STATE_CLOSE; } getnameinfo((struct sockaddr*)&req->peer,length, req->peerhost,64,req->peerserv,8, NI_NUMERICHOST | NI_NUMERICSERV); if (debug) fprintf(stderr,"%03d: connect from (%s)\n", req->fd,req->peerhost); } } } /* check active connections */ for (req = conns, prev = NULL; req != NULL;) { /* I/O */ if (FD_ISSET(req->fd,&rd)) { if (req->state == STATE_KEEPALIVE) req->state = STATE_READ_HEADER; read_request(req,0); req->ping = now; } if (FD_ISSET(req->fd,&wr)) { write_request(req); req->ping = now; } /* check timeouts */ if (req->state == STATE_KEEPALIVE) { if (now > req->ping + keepalive_time) { if (debug) fprintf(stderr,"%03d: keepalive timeout\n",req->fd); req->state = STATE_CLOSE; } } else { if (now > req->ping + timeout) { if (req->state == STATE_READ_HEADER) { mkerror(req,408,0); } else { xerror(LOG_INFO,"network timeout",req->peerhost); req->state = STATE_CLOSE; } } } /* header parsing */ header_parsing: if (req->state == STATE_PARSE_HEADER) { parse_request(req); if (req->state == STATE_WRITE_HEADER) write_request(req); } /* handle finished requests */ if (req->state == STATE_FINISHED && !req->keep_alive) req->state = STATE_CLOSE; if (req->state == STATE_FINISHED) { if (logfd) access_log(req,now); /* cleanup */ if (req->free_the_mallocs) free(req->body); req->free_the_mallocs = 0; req->body = NULL; req->written = 0; req->head_only = 0; if (req->hdata == req->lreq) { /* ok, wait for the next one ... */ if (debug) fprintf(stderr,"%03d: keepalive wait\n",req->fd); req->state = STATE_KEEPALIVE; req->hdata = 0; req->lreq = 0; } else { /* there is a pipelined request in the queue ... */ if (debug) fprintf(stderr,"%03d: keepalive pipeline\n",req->fd); req->state = STATE_READ_HEADER; memmove(req->hreq,req->hreq+req->lreq, req->hdata-req->lreq); req->hdata -= req->lreq; req->lreq = 0; read_request(req,1); goto header_parsing; } } /* connections to close */ if (req->state == STATE_CLOSE) { if (logfd) access_log(req,now); /* cleanup */ close(req->fd); curr_conn--; if (debug) fprintf(stderr,"%03d: done (%d)\n",req->fd,curr_conn); /* unlink from list */ tmp = req; if (prev == NULL) { conns = req->next; req = conns; } else { prev->next = req->next; req = req->next; } /* free memory */ if (tmp->free_the_mallocs) free(tmp->body); free(tmp); } else { prev = req; req = req->next; } } } return NULL; } /* ---------------------------------------------------------------------- */ int main(int argc, char *argv[]) { struct sigaction act,old; struct addrinfo ask,*res; #ifdef HAVE_SOCKADDR_STORAGE struct sockaddr_storage ss; #else struct sockaddr ss; #endif int c, opt, rc, ss_len, v4, v6, simulate; char host[INET6_ADDRSTRLEN+1]; char serv[16]; ng_device_init(); gethostname(server_host,255); memset(&ask,0,sizeof(ask)); ask.ai_flags = AI_CANONNAME; if (0 == (rc = getaddrinfo(server_host, NULL, &ask, &res))) { if (res->ai_canonname) strcpy(server_host,res->ai_canonname); } /* parse options */ v4 = 1; v6 = 1; simulate = 0; for (;;) { if (-1 == (c = getopt(argc,argv,"hasdFr46S" "p:N:n:i:t:c:u:g:l:L:v:"))) break; switch (c) { case 'h': usage(argv[0]); break; case '4': v4 = 1; v6 = 0; break; case '6': v4 = 0; v6 = 1; break; case 'a': ascii_art++; break; case 's': usesyslog++; break; case 'S': simulate++; break; case 'd': debug++; break; case 'F': dontdetach++; break; case 'r': cachereset++; break; case 'N': canonicalhost = 1; /* fall through */ case 'n': strncpy(server_host,optarg,sizeof(server_host)-1); break; case 'i': listen_ip = optarg; break; case 'p': listen_port = optarg; break; case 't': timeout = atoi(optarg); break; case 'c': max_conn = atoi(optarg); break; case 'u': strncpy(user,optarg,16); break; case 'g': strncpy(group,optarg,16); break; case 'L': flushlog = 1; /* fall through */ case 'l': logfile = optarg; break; case 'v': ng_dev.vbi = optarg; break; default: exit(1); } } if (usesyslog) syslog_init(); /* open vbi device */ vbi = vbi_open(ng_dev.vbi,debug,simulate); if (NULL == vbi) { xperror(LOG_ERR,"cannot open vbi device",NULL); exit(1); } if (debug) vbi_event_handler_add(vbi->dec,~0,vbi_dump_event,vbi); else vbi_event_handler_add(vbi->dec,~0,dummy_handler,vbi); /* bind to socket */ slisten = -1; memset(&ask,0,sizeof(ask)); ask.ai_flags = AI_PASSIVE; if (listen_ip) ask.ai_flags |= AI_CANONNAME; ask.ai_socktype = SOCK_STREAM; /* try ipv6 first ... */ if (-1 == slisten && v6) { ask.ai_family = PF_INET6; if (0 != (rc = getaddrinfo(listen_ip, listen_port, &ask, &res))) { if (debug) fprintf(stderr,"getaddrinfo (ipv6): %s\n",gai_strerror(rc)); } else { if (-1 == (slisten = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) && debug) xperror(LOG_ERR,"socket (ipv6)",NULL); } } /* ... failing that try ipv4 */ if (-1 == slisten && v4) { ask.ai_family = PF_INET; if (0 != (rc = getaddrinfo(listen_ip, listen_port, &ask, &res))) { fprintf(stderr,"getaddrinfo (ipv4): %s\n",gai_strerror(rc)); } else { if (-1 == (slisten = socket(res->ai_family, res->ai_socktype, res->ai_protocol))) xperror(LOG_ERR,"socket (ipv4)",NULL); } } if (-1 == slisten) exit(1); memcpy(&ss,res->ai_addr,res->ai_addrlen); ss_len = res->ai_addrlen; if (res->ai_canonname) strcpy(server_host,res->ai_canonname); if (0 != (rc = getnameinfo((struct sockaddr*)&ss,ss_len, host,INET6_ADDRSTRLEN,serv,15, NI_NUMERICHOST | NI_NUMERICSERV))) { fprintf(stderr,"getnameinfo: %s\n",gai_strerror(rc)); exit(1); } tcp_port = atoi(serv); opt = 1; setsockopt(slisten,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); fcntl(slisten,F_SETFL,O_NONBLOCK); if (-1 == bind(slisten, (struct sockaddr*) &ss, ss_len)) { xperror(LOG_ERR,"bind",NULL); exit(1); } if (-1 == listen(slisten, 2*max_conn)) { xperror(LOG_ERR,"listen",NULL); exit(1); } /* change user/group - also does chroot */ fix_ug(); if (logfile) { if (0 == strcmp(logfile,"-")) { logfd = stdout; } else { if (NULL == (logfd = fopen(logfile,"a"))) xperror(LOG_WARNING,"open access log",NULL); } } if (debug) { fprintf(stderr, "alevt http server started\n" " ipv6 : %s\n" " node : %s\n" " ipaddr: %s\n" " port : %d\n" " user : %s\n" " group : %s\n", res->ai_family == PF_INET6 ? "yes" : "no", server_host,host,tcp_port,user,group); } /* run as daemon - detach from terminal */ if ((!debug) && (!dontdetach)) { switch (fork()) { case -1: xperror(LOG_ERR,"fork",NULL); exit(1); case 0: close(0); close(1); close(2); setsid(); have_tty = 0; break; default: exit(0); } } if (usesyslog) { syslog_start(); atexit(syslog_stop); } /* setup signal handler */ memset(&act,0,sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = SIG_IGN; sigaction(SIGPIPE,&act,&old); act.sa_handler = catchsig; sigaction(SIGHUP,&act,&old); sigaction(SIGUSR1,&act,&old); sigaction(SIGTERM,&act,&old); if (debug) sigaction(SIGINT,&act,&old); /* go! */ start = time(NULL); mainloop(); if (logfd) fclose(logfd); if (debug) fprintf(stderr,"bye...\n"); exit(0); } xawtv-3.106/vbistuff/bottom.html.in000066400000000000000000000011141343350355000173210ustar00rootroot00000000000000100   200   300   400   500   600   700   800   about
Jump to page xawtv-3.106/vbistuff/httpd.h000066400000000000000000000046241343350355000160270ustar00rootroot00000000000000#include #define STATE_READ_HEADER 1 #define STATE_PARSE_HEADER 2 #define STATE_WRITE_HEADER 3 #define STATE_WRITE_BODY 4 #define STATE_FINISHED 7 #define STATE_KEEPALIVE 8 #define STATE_CLOSE 9 #define MAX_HEADER 4096 #define BR_HEADER 512 struct REQUEST { int fd; /* socket handle */ int state; /* what to to ??? */ time_t ping; /* last read/write (for timeouts) */ int keep_alive; #ifdef HAVE_SOCKADDR_STORAGE struct sockaddr_storage peer; /* client (log) */ #else struct sockaddr peer; #endif char peerhost[65]; char peerserv[9]; /* request */ char hreq[MAX_HEADER+1]; /* request header */ int lreq; /* request length */ int hdata; /* data in hreq */ char type[16]; /* req type */ char uri[1024]; /* req uri */ char hostname[65]; /* hostname */ char path[1024]; /* file path */ int major,minor; /* http version */ /* response */ int status; /* status code (log) */ int bc; /* byte counter (log) */ char hres[MAX_HEADER+1]; /* response header */ int lres; /* header length */ char *mime; /* mime type */ char *body; int lbody; int free_the_mallocs; int head_only; off_t written; /* linked list */ struct REQUEST *next; }; /* --- alevtd.c ------------------------------------------------- */ extern int debug; extern int tcp_port; extern char *server_name; extern int canonicalhost; extern char server_host[]; extern time_t now,start; extern struct vbi_state *vbi; void xperror(int loglevel, char *txt, char *peerhost); void xerror(int loglevel, char *txt, char *peerhost); /* --- request.c ------------------------------------------------ */ void read_request(struct REQUEST *req, int pipelined); void parse_request(struct REQUEST *req); /* --- response.c ----------------------------------------------- */ void mkerror(struct REQUEST *req, int status, int ka); void mkredirect(struct REQUEST *req); void mkheader(struct REQUEST *req, int status, time_t mtime); void write_request(struct REQUEST *req); /* --- page.c ----------------------------------------------- */ void buildpage(struct REQUEST *req); xawtv-3.106/vbistuff/ntsc-cc.c000066400000000000000000000407021343350355000162260ustar00rootroot00000000000000/* cc.c -- closed caption decoder * Mike Baker (mbm@linux.com) * (based on code by timecop@japan.co.jp) * * 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 "config.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_GETOPT_H # include #endif #ifndef X_DISPLAY_MISSING # include # include # include # include Display *dpy; Window Win,Root; char dpyname[256] = ""; GC WinGC; GC WinGC0; GC WinGC1; int x; #endif //XDSdecode char info[8][25][256]; char newinfo[8][25][256]; char *infoptr=newinfo[0][0]; int mode,type; char infochecksum; //ccdecode char *ratings[] = {"(NOT RATED)","TV-Y","TV-Y7","TV-G","TV-PG","TV-14","TV-MA","(NOT RATED)"}; int rowdata[] = {11,-1,1,2,3,4,12,13,14,15,5,6,7,8,9,10}; char *specialchar[] = {"\xae","\xb0","\xbd","\xbf","(TM)","\xa2","\xa3","o/~ ","\xe0"," ","\xe8","\xe2","\xea","\xee","\xf4","\xfb"}; char *modes[]={"current","future","channel","miscellaneous","public service","reserved","invalid","invalid","invalid","invalid"}; int lastcode; int ccmode=1; //cc1 or cc2 char ccbuf[3][256]; //cc is 32 columns per row, this allows for extra characters int keywords=0; char *keyword[32]; //args (this should probably be put into a structure later) char useraw=0; char semirawdata=0; char usexds=0; char usecc=0; char plain=0; char usesen=0; char debugwin=0; char rawline=-1; int sen; int inval; static int parityok(int n) /* check parity for 2 bytes packed in n */ { int mask=0; int j, k; for (k = 1, j = 0; j < 7; j++) { if (n & (1<>7)&1)) mask|=0x00FF; for (k = 1, j = 8; j < 15; j++) { if (n & (1<>15)&1)) mask|=0xFF00; return mask; } static int decodebit(unsigned char *data, int threshold) { int i, sum = 0; for (i = 0; i < 23; i++) sum += data[i]; return (sum > threshold*23); } static int decode(unsigned char *vbiline) { int max[7], min[7], val[7], i, clk, tmp, sample, packedbits = 0; for (clk=0; clk<7; clk++) max[clk] = min[clk] = val[clk] = -1; clk = tmp = 0; i=30; while (i < 600 && clk < 7) { /* find and lock all 7 clocks */ sample = vbiline[i]; if (max[clk] < 0) { /* find maximum value before drop */ if (sample > 85 && sample > val[clk]) (val[clk] = sample, tmp = i); /* mark new maximum found */ else if (val[clk] - sample > 30) /* far enough */ (max[clk] = tmp, i = tmp + 10); } else { /* find minimum value after drop */ if (sample < 85 && sample < val[clk]) (val[clk] = sample, tmp = i); /* mark new minimum found */ else if (sample - val[clk] > 30) /* searched far enough */ (min[clk++] = tmp, i = tmp + 10); } i++; } i=min[6]=min[5]-max[5]+max[6]; if (clk != 7 || vbiline[max[3]] - vbiline[min[5]] < 45) /* failure to locate clock lead-in */ return -1; #ifndef X_DISPLAY_MISSING if (debugwin) { for (clk=0;clk<7;clk++) { XDrawLine(dpy,Win,WinGC,min[clk]/2,0,min[clk]/2,128); XDrawLine(dpy,Win,WinGC1,max[clk]/2,0,max[clk]/2,128); } XFlush(dpy); } #endif /* calculate threshold */ for (i=0,sample=0;i<7;i++) sample=(sample + vbiline[min[i]] + vbiline[max[i]])/3; for(i=min[6];vbiline[i]>8) & 0x7F; if (b1 < 15) // start packet { mode = b1; type = b2; infochecksum = b1 + b2 + 15; if (mode > 8 || type > 20) { // printf("%% Unsupported mode %s(%d) [%d]\n",modes[(mode-1)>>1],mode,type); mode=0; type=0; } infoptr = newinfo[mode][type]; } else if (b1 == 15) // eof (next byte is checksum) { #if 0 //debug if (mode == 0) { length=infoptr - newinfo[0][0]; infoptr[1]=0; printf("LEN: %d\n",length); for (y=0;y5) break; printf(" LENGTH: %d:%02d:%02d of %d:%02d:00", infoptr[3]&0x3f,infoptr[2]&0x3f,infoptr[4]&0x3f,infoptr[1]&0x3f,infoptr[0]&0x3f); break; case 0x0103: infoptr[length] = 0; printf(" TITLE: %s",infoptr); break; case 0x0105: printf(" RATING: %s (%d)",ratings[infoptr[0]&0x07],infoptr[0]); if ((infoptr[0]&0x07)>0) { if (infoptr[0]&0x20) printf(" VIOLENCE"); if (infoptr[0]&0x10) printf(" SEXUAL"); if (infoptr[0]&0x08) printf(" LANGUAGE"); } break; case 0x0501: infoptr[length] = 0; printf(" NETWORK: %s",infoptr); break; case 0x0502: infoptr[length] = 0; printf(" CALL: %s",infoptr); break; case 0x0701: printf(" CUR.TIME: %d:%02d %d/%02d/%04d UTC",infoptr[1]&0x1F,infoptr[0]&0x3f,infoptr[3]&0x0f,infoptr[2]&0x1f,(infoptr[5]&0x3f)+1990); break; case 0x0704: //timezone printf(" TIMEZONE: UTC-%d",infoptr[0]&0x1f); break; case 0x0104: //program genere break; case 0x0110: case 0x0111: case 0x0112: case 0x0113: case 0x0114: case 0x0115: case 0x0116: case 0x0117: infoptr[length+1] = 0; printf(" DESC: %s",infoptr); break; } if (!plain) printf("\33[0m"); putchar('\n'); fflush(stdout); } mode = 0; type = 0; } else if( (infoptr - newinfo[mode][type]) < 250 ) // must be a data packet, check if we're in a supported mode { infoptr[0] = b1; infoptr++; infoptr[0] = b2; infoptr++; infochecksum += b1 + b2; } return 0; } static int webtv_check(char * buf,int len) { unsigned long sum; unsigned long nwords; unsigned short csum=0; char temp[9]; int nbytes=0; while (buf[0]!='<' && len > 6) //search for the start { buf++; len--; } if (len == 6) //failure to find start return 0; while (nbytes+6 <= len) { //look for end of object checksum, it's enclosed in []'s and there shouldn't be any [' after if (buf[nbytes] == '[' && buf[nbytes+5] == ']' && buf[nbytes+6] != '[') break; else nbytes++; } if (nbytes+6>len) //failure to find end return 0; nwords = nbytes >> 1; sum = 0; //add up all two byte words while (nwords-- > 0) { sum += *buf++ << 8; sum += *buf++; } if (nbytes & 1) { sum += *buf << 8; } csum = (unsigned short)(sum >> 16); while(csum !=0) { sum = csum + (sum & 0xffff); csum = (unsigned short)(sum >> 16); } sprintf(temp,"%04X\n",(int)~sum&0xffff); buf++; if(!strncmp(buf,temp,4)) { buf[5]=0; if (!plain) printf("\33[35mWEBTV: %s\33[0m\n",buf-nbytes-1); else printf("WEBTV: %s\n",buf-nbytes-1); fflush(stdout); } return 0; } static int CCdecode(int data) { int b1, b2, len, x,y; if (data == -1) //invalid data. flush buffers to be safe. { memset(ccbuf[1],0,255); memset(ccbuf[2],0,255); return -1; } b1 = data & 0x7f; b2 = (data>>8) & 0x7f; len = strlen(ccbuf[ccmode]); if (b1&0x60 && data != lastcode) // text { ccbuf[ccmode][len++]=b1; if (b2&0x60) ccbuf[ccmode][len++]=b2; if (b1 == ']' || b2 == ']') webtv_check(ccbuf[ccmode],len); } else if ((b1&0x10) && (b2>0x1F) && (data != lastcode)) //codes are always transmitted twice (apparently not, ignore the second occurance) { ccmode=((b1>>3)&1)+1; len = strlen(ccbuf[ccmode]); if (b2 & 0x40) //preamble address code (row & indent) { if (len!=0) ccbuf[ccmode][len++]='\n'; if (b2&0x10) //row contains indent flag for (x=0;x<(b2&0x0F)<<1;x++) ccbuf[ccmode][len++]=' '; } else { switch (b1 & 0x07) { case 0x00: //attribute printf("\n",b1,b2); fflush(stdout); break; case 0x01: //midrow or char switch (b2&0x70) { case 0x20: //midrow attribute change switch (b2&0x0e) { case 0x00: //italics off if (!plain) strcat(ccbuf[ccmode],"\33[0m "); break; case 0x0e: //italics on if (!plain) strcat(ccbuf[ccmode],"\33[36m "); break; } if (b2&0x01) { //underline if (!plain) strcat(ccbuf[ccmode],"\33[4m"); } else { if (!plain) strcat(ccbuf[ccmode],"\33[24m"); } break; case 0x30: //special character.. strcat(ccbuf[ccmode],specialchar[b2&0x0f]); break; } break; case 0x04: //misc case 0x05: //misc + F // printf("ccmode %d cmd %02x\n",ccmode,b2); switch (b2) { case 0x21: //backspace ccbuf[ccmode][len--]=0; break; /* these codes are insignifigant if we're ignoring positioning */ case 0x25: //2 row caption case 0x26: //3 row caption case 0x27: //4 row caption case 0x29: //resume direct caption case 0x2B: //resume text display case 0x2C: //erase displayed memory break; case 0x2D: //carriage return if (ccmode==2) break; case 0x2F: //end caption + swap memory case 0x20: //resume caption (new caption) if (!strlen(ccbuf[ccmode])) break; for (x=0;x>8) & 0x7f; if (!semirawdata) { fprintf(stderr,"%c%c",b1,b2); return 0; } // semi-raw data output begins here... // a control code. if ( ( b1 >= 0x10 ) && ( b1 <= 0x1F ) ) { if ( ( b2 >= 0x20 ) && ( b2 <= 0x7F ) ) fprintf(stderr,"[%02X-%02X]",b1,b2); return 0; } // next two rules: // supposed to be one printable char // and the other char to be discarded if ( ( b1 >= 0x0 ) && ( b1 <= 0xF ) ) { fprintf(stderr,"(%02x)%c",b1,b2); //fprintf(stderr,"%c",b2); //fprintf(stderr,"%c%c",0,b2); return 0; } if ( ( b2 >= 0x0 ) && ( b2 <= 0xF ) ) { fprintf(stderr,"%c{%02x}",b1,b2); //fprintf(stderr,"%c",b1); //fprintf(stderr,"%c%c",b1,1); return 0; } // just classic two chars to print. fprintf(stderr,"%c%c",b1,b2); return 0; } static int sentence(int data) { int b1, b2; if (data == -1) return -1; b1 = data & 0x7f; b2 = (data>>8) & 0x7f; inval++; if (data==lastcode) { if (sen==1) { printf(" "); sen=0; } if (inval>10 && sen) { printf("\n"); fflush(stdout); sen=0; } return 0; } lastcode=data; if (b1&96) { inval=0; if (sen==2 && b1!='.' && b2!='.' && b1!='!' && b2!='!' && b1!='?' && b2!='?' && b1!=')' && b2!=')') { printf("\n"); fflush(stdout); sen=1; } else if (b1=='.' || b2=='.' || b1=='!' || b2=='!' || b1=='?' || b2=='?' || b1==')' || b2==')') sen=2; else sen=1; printf("%c%c",tolower(b1),tolower(b2)); } return 0; } #ifndef X_DISPLAY_MISSING static unsigned long getColor(char *colorName, float dim) { XColor Color; XWindowAttributes Attributes; XGetWindowAttributes(dpy, Root, &Attributes); Color.pixel = 0; XParseColor (dpy, Attributes.colormap, colorName, &Color); Color.red=(unsigned short)(Color.red/dim); Color.blue=(unsigned short)(Color.blue/dim); Color.green=(unsigned short)(Color.green/dim); Color.flags=DoRed | DoGreen | DoBlue; XAllocColor (dpy, Attributes.colormap, &Color); return Color.pixel; } #endif int main(int argc,char **argv) { char *vbifile = "/dev/vbi0"; unsigned char buf[65536]; int arg; int args=0; int vbifd; fd_set rfds; int x; for (;;) //commandline parsing { if (-1 == (arg = getopt(argc, argv, "?hxsckpwRr:d:"))) break; switch (arg) { case '?': case 'h': printf("CCDecoder 0.9.1 (mbm@linux.com)\n" "\tx \t decode XDS info\n" "\ts \t decode by sentences \n" "\tc \t decode Closed Caption (includes webtv)\n" "\tk word \t keywords to break line at [broken???]\n" "\tp \t plain output. do not display underline and italic\n" "\tw \t open debugging window (used with -r option)\n" "\tR \t semi-raw data (used with -r option)\n" "\tr #\t raw dump of data (use 11 or 27 as line number)\n" "\td dev \t file to open (default: /dev/vbi0)\n" ); exit(0); case 'x': usexds=1; args++; break; case 's': usesen=1; args++; break; case 'c': usecc=1; args++; break; case 'k': //args++; keyword[keywords++]=optarg; break; case 'p': plain=1; args++; break; case 'w': debugwin=1; break; case 'R': semirawdata=1; break; case 'r': useraw=1; args++; rawline=atoi(optarg); break; case 'd': vbifile = optarg; break; } } if ((vbifd = open(vbifile, O_RDONLY)) < 0) { perror(vbifile); exit(1); } else if (!args) exit(0); for (x=0;x #include #include #include #include #include #include #include #include #include #include #include #include #include "httpd.h" #include "vbi-data.h" /* ---------------------------------------------------------------------- */ static char stylesheet[] = #include "alevt.css.h" ; static char page_about[] = #include "about.html.h" ; static wchar_t page_top[] = L"" #include "top.html.h" ; static wchar_t page_bottom[] = L"" #include "bottom.html.h" ; #if 0 /* 01234567890123456789012345678901 */ static char graphic1[32] = " °°¯·'²²·°°°-°°°.:::.;;;.}/}.÷/#"; /* 012345 6789 0123 456789012345678901 */ static char graphic2[32] = ".:::.\\{{.\\||.\\÷#_:::.¿¿[.||].###"; #endif enum mime_type { TYPE_TEXT = 1, TYPE_HTML = 2, }; #define CHARSET "utf-8" #define TXTBUF (25*41*8) #define HTMLBUF (25*1024) /* ---------------------------------------------------------------------- */ static int vbi_export_html(wchar_t *dest, int size, struct vbi_state *vbi, struct vbi_page *pg, int pagenr, int subnr) { int x,y,i,link; int fg,bg,len=0; vbi_char *ch; wchar_t wch,*obuf; struct vbi_page dummy; obuf = dest; link = -1; len = swprintf(obuf,size,page_top,pagenr,subnr); obuf += len; size -= len; for (y = 0; y < 25; y++) { ch = pg->text + 41*y; fg = -1; bg = -1; for (x = 0; x <= 40; x++) { /* close link tags */ if (link >= 0) { if (0 == link) { len = swprintf(obuf,size,L""); obuf += len; size -= len; } link--; } /* this char */ wch = ch[x].unicode; if (ch[x].size > VBI_DOUBLE_SIZE) wch = ' '; if (ch[x].conceal) wch = ' '; /* handle colors */ if (fg != ch[x].foreground || bg != ch[x].background) { if (-1 != fg) { len = swprintf(obuf,size,L""); obuf += len; size -= len; } fg = ch[x].foreground; bg = ch[x].background; len = swprintf(obuf,size,L"", fg * 10 + bg); obuf += len; size -= len; } /* check for references to other pages */ if (y > 0 && -1 == link && x > 0 && x < 39 && iswdigit(ch[x+0].unicode) && iswdigit(ch[x+1].unicode) && iswdigit(ch[x+2].unicode) && !iswdigit(ch[x-1].unicode) && !iswdigit(ch[x+3].unicode)) { len = swprintf(obuf,size,L"", (wchar_t)ch[x+0].unicode, (wchar_t)ch[x+1].unicode, (wchar_t)ch[x+2].unicode); obuf += len; size -= len; link = 2; } if (y > 0 && -1 == link && x > 0 && x < 40 && '>' == ch[x+0].unicode && '>' == ch[x+1].unicode) { len = swprintf(obuf,size,L"", vbi_calc_page(pagenr, +0x01)); link = 1; } if (y > 0 && -1 == link && x > 0 && x < 40 && '<' == ch[x+0].unicode && '<' == ch[x+1].unicode) { len = swprintf(obuf,size,L"", vbi_calc_page(pagenr, -0x01)); link = 1; } /* check for references to other subpages */ if (subnr > 0 && y > 0 && -1 == link && x > 0 && x < 39 && iswdigit(ch[x+0].unicode) && '/' == ch[x+1].unicode && iswdigit(ch[x+2].unicode) && !iswdigit(ch[x-1].unicode) && !iswdigit(ch[x+3].unicode)) { if (ch[x+0].unicode == ch[x+2].unicode) { len = swprintf(obuf,size,L""); } else { len = swprintf(obuf,size,L"", ch[x+0].unicode-'0' +1); } len = swprintf(obuf,size,L"", (wchar_t)ch[x+0].unicode, (wchar_t)ch[x+1].unicode, (wchar_t)ch[x+2].unicode); obuf += len; size -= len; link = 2; } #if 0 /* check for references to WWW pages */ if (html && y > 0 && -1 == link && x < W-9 && (((tolower(L[x+0].ch) == 'w') && (tolower(L[x+1].ch) == 'w') && (tolower(L[x+2].ch) == 'w') && (L[x+3].ch == '.')) || ((tolower(L[x+0].ch) == 'h') && (tolower(L[x+1].ch) == 't') && (tolower(L[x+2].ch) == 't') && (tolower(L[x+3].ch) == 'p')))) { int offs = 0; len += sprintf(out+len,"'z') ) { len--; offs--; } len += sprintf(out+len,"\">"); link = offs - 1; } #endif /* FIXME: fasttext links */ if (size > 0) { *obuf = wch; obuf++; size--; } } if (-1 != fg) { len = swprintf(obuf,size,L""); obuf += len; size -= len; } if (size > 0) { *obuf = '\n'; obuf++; size--; } } len = swprintf(obuf,size,L"\n
\n"); obuf += len; size -= len; if (0 != subnr) { /* link all subpages */ for (i = 1; i <= VBI_MAX_SUBPAGES; i++) { if (!vbi_fetch_vt_page(vbi->dec,&dummy,pagenr,i, VBI_WST_LEVEL_1p5,0,0)) continue; if (i != subnr) { len = swprintf(obuf,size,L" %02x", pagenr, i, i); } else { len = swprintf(obuf,size,L" %02x", i); } obuf += len; size -= len; len = swprintf(obuf,size,L"
\n"); obuf += len; size -= len; } } /* page navigation links */ len = swprintf(obuf,size,L"<<  ", vbi_calc_page(pagenr, -0x10)); obuf += len; size -= len; len = swprintf(obuf,size,L"<  ", vbi_calc_page(pagenr, -0x01)); obuf += len; size -= len; len = swprintf(obuf,size,L"o  ", pagenr, subnr); obuf += len; size -= len; len = swprintf(obuf,size,L">  ", vbi_calc_page(pagenr, +0x01)); obuf += len; size -= len; len = swprintf(obuf,size,L">>", vbi_calc_page(pagenr, +0x10)); obuf += len; size -= len; len = swprintf(obuf,size,L"
\n") ; obuf += len; size -= len; len = swprintf(obuf,size,page_bottom); obuf += len; size -= len; *obuf = 0; return obuf - dest; } static int wchar_to_charset(wchar_t *istr, int ilen, char *charset, char **ostr, int *olen) { size_t il,ol; wchar_t *err; char *ib,*ob; iconv_t ic; int rc; ic = iconv_open(CHARSET,"WCHAR_T"); if (NULL == ic) { if (debug) fprintf(stderr,"iconf_open failed on %s => %s\n", CHARSET,"WCHAR_T"); return -1; } ib = (char*)istr; il = ilen * sizeof(wchar_t); ob = malloc(ilen * 8); ol = ilen * 8; *ostr = ob; for (;;) { rc = iconv(ic,&ib,&il,&ob,&ol); if (rc >= 0) { /* done */ break; } /* handle errors */ err = (wchar_t*)ib; if (EILSEQ == errno && *err != '?') { *err = '?'; continue; } /* unknown error */ if (debug) fprintf(stderr,"unknown iconv error\n"); return -1; } iconv_close(ic); *olen = ob - *ostr; return 0; } static int vbi_render_page(struct REQUEST *req, struct vbi_state *vbi, struct vbi_page *pg, int pagenr, int subnr, enum mime_type type) { wchar_t *wpage; int wlen; switch (type) { case TYPE_TEXT: req->body = malloc(TXTBUF); req->lbody = vbi_export_txt(req->body, CHARSET, TXTBUF, pg, &vbi_fullrect, 0); req->mime = "text/plain; charset=" CHARSET; break; case TYPE_HTML: wpage = malloc(HTMLBUF*sizeof(wchar_t)); wlen = vbi_export_html(wpage,HTMLBUF,vbi,pg,pagenr,subnr); if (-1 == wchar_to_charset(wpage,wlen,CHARSET,&req->body,&req->lbody)) return -1; free(wpage); req->mime = "text/html; charset=" CHARSET; break; } req->free_the_mallocs = 1; mkheader(req,200,-1); return 0; } /* ---------------------------------------------------------------------- */ void buildpage(struct REQUEST *req) { int pagenr, subpage; char type[10]; struct vbi_page page; enum mime_type t; /* style sheet */ if (0 == strcmp(req->path,"/alevt.css")) { req->mime = "text/css; charset=us-ascii"; req->body = stylesheet; req->lbody = sizeof(stylesheet); mkheader(req,200,start); return; } /* about */ if (0 == strcmp(req->path,"/about.html")) { req->mime = "text/html; charset=utf-8"; req->body = page_about; req->lbody = sizeof(page_about); mkheader(req,200,start); return; } /* entry page */ if (0 == strcmp(req->path,"/")) { strcpy(req->path,"/100/00.html"); mkredirect(req); return; } /* pages */ if (3 == sscanf(req->path,"/%3x/%2x.%8s",&pagenr,&subpage,type)) { t = 0; if (0 == strcmp(type,"html")) t = TYPE_HTML; if (0 == strcmp(type,"txt")) t = TYPE_TEXT; if (0 == t) { mkerror(req,404,1); return; } if (debug) fprintf(stderr,"%03d: lookup %03x/%02x [%s]\n", req->fd,pagenr,subpage,type); memset(&page,0,sizeof(page)); if (!vbi_fetch_vt_page(vbi->dec,&page,pagenr,subpage, VBI_WST_LEVEL_1p5,25,1)) { if (!vbi_fetch_vt_page(vbi->dec,&page,pagenr,VBI_ANY_SUBNO, VBI_WST_LEVEL_1p5,25,1)) { mkerror(req,404,1); return; } sprintf(req->path,"/%03x/%02x.html",pagenr,page.subno); mkredirect(req); return; } if (-1 == vbi_render_page(req,vbi,&page,pagenr,subpage,t)) mkerror(req,500,1); return; } /* goto form */ if (1 == sscanf(req->path,"/goto/?p=%d",&pagenr)) { sprintf(req->path,"/%d/00.html",pagenr); mkredirect(req); return; } mkerror(req,404,1); return; } xawtv-3.106/vbistuff/request.c000066400000000000000000000101521343350355000163600ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "httpd.h" /* ---------------------------------------------------------------------- */ void read_request(struct REQUEST *req, int pipelined) { int rc; char *h; restart: rc = read(req->fd, req->hreq + req->hdata, MAX_HEADER - req->hdata); switch (rc) { case -1: if (errno == EAGAIN) { if (pipelined) break; /* check if there is already a full request */ else return; } if (errno == EINTR) goto restart; xperror(LOG_INFO,"read",req->peerhost); /* fall through */ case 0: req->state = STATE_CLOSE; return; default: req->hdata += rc; req->hreq[req->hdata] = 0; } /* check if this looks like a http request after the first few bytes... */ if (req->hdata < 5) return; if (strncmp(req->hreq,"GET ",4) != 0 && strncmp(req->hreq,"PUT ",4) != 0 && strncmp(req->hreq,"HEAD ",5) != 0 && strncmp(req->hreq,"POST ",5) != 0) { mkerror(req,400,0); return; } /* header complete ?? */ if (NULL != (h = strstr(req->hreq,"\r\n\r\n")) || NULL != (h = strstr(req->hreq,"\n\n"))) { if (*h == '\r') { h += 4; *(h-2) = 0; } else { h += 2; *(h-1) = 0; } req->lreq = h - req->hreq; req->state = STATE_PARSE_HEADER; return; } if (req->hdata == MAX_HEADER) { /* oops: buffer full, but found no complete request ... */ mkerror(req,400,0); return; } return; } /* ---------------------------------------------------------------------- */ static int unhex(unsigned char c) { if (c < '@') return c - '0'; return (c & 0x0f) + 9; } static void unquote(unsigned char *dst, unsigned char *src) { int i,j,q,n=strlen(src); q=0; for (i=0, j=0; i 2) fprintf(stderr,"%s\n",req->hreq); /* parse request. Hehe, scanf is powerfull :-) */ if (4 != sscanf(req->hreq, "%4[A-Z] %255[^ \t\r\n] HTTP/%d.%d", req->type,filename,&(req->major),&(req->minor))) { mkerror(req,400,0); return; } if (filename[0] == '/') { strcpy(req->uri,filename); } else { port = 0; *proto = 0; if (4 != sscanf(filename,"%4[a-zA-Z]://%64[a-zA-Z0-9.-]:%d%255[^ \t\r\n]", proto,req->hostname,&port,req->uri) && 3 != sscanf(filename,"%4[a-zA-Z]://%64[a-zA-Z0-9.-]%255[^ \t\r\n]", proto,req->hostname,req->uri)) { mkerror(req,400,0); return; } if (*proto != 0 && 0 != strcasecmp(proto,"http")) { mkerror(req,400,0); return; } } unquote(req->path,req->uri); if (debug) fprintf(stderr,"%03d: %s \"%s\" HTTP/%d.%d\n", req->fd, req->type, req->path, req->major, req->minor); if (0 != strcmp(req->type,"GET") && 0 != strcmp(req->type,"HEAD")) { mkerror(req,501,0); return; } if (0 == strcmp(req->type,"HEAD")) { req->head_only = 1; } /* checks */ if (req->path[0] != '/') { mkerror(req,400,0); return; } /* parse header lines */ req->keep_alive = req->minor; for (h = req->hreq; h - req->hreq < req->lreq;) { h = strchr(h,'\n'); if (NULL == h) break; h++; if (0 == strncasecmp(h,"Connection: ",12)) { req->keep_alive = (0 == strncasecmp(h+12,"Keep-Alive",10)); } else if (0 == strncasecmp(h,"Host: ",6)) { sscanf(h+6,"%64[a-zA-Z0-9.-]",req->hostname); } } /* make sure we have a hostname */ if (req->hostname[0] == '\0' || canonicalhost) strncpy(req->hostname,server_host,64); /* lowercase hostname */ for (h = req->hostname; *h != 0; h++) { if (*h < 'A' || *h > 'Z') continue; *h += 32; } /* handle request (more to come) */ buildpage(req); return; } xawtv-3.106/vbistuff/response.c000066400000000000000000000114251343350355000165320ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "httpd.h" /* ---------------------------------------------------------------------- */ static struct HTTP_STATUS { int status; char *head; char *body; } http[] = { { 200, "200 OK", NULL }, { 400, "400 Bad Request", "*PLONK*\n" }, { 404, "404 Not Found", "videotext page not found in cache\n" }, { 408, "408 Request Timeout", "Request Timeout\n" }, { 500, "500 Internal Server Error", "Sorry folks\n" }, { 501, "501 Not Implemented", "Sorry folks\n" }, { 0, NULL, NULL } }; /* ---------------------------------------------------------------------- */ #define RESPONSE_START \ "HTTP/1.1 %s\r\n" \ "Server: %s\r\n" \ "Connection: %s\r\n" #define RFCTIME \ "%a, %d %b %Y %H:%M:%S GMT" #define BOUNDARY \ "XXX_CUT_HERE_%ld_XXX" void mkerror(struct REQUEST *req, int status, int ka) { int i; for (i = 0; http[i].status != 0; i++) if (http[i].status == status) break; req->status = status; req->body = http[i].body; req->lbody = strlen(req->body); if (!ka) req->keep_alive = 0; req->lres = sprintf(req->hres, RESPONSE_START "Content-Type: text/plain\r\n" "Content-Length: %d\r\n", http[i].head,server_name, req->keep_alive ? "Keep-Alive" : "Close", req->lbody); if (401 == status) req->lres += sprintf(req->hres+req->lres, "WWW-Authenticate: Basic, realm=\"webfs\"\r\n"); req->lres += strftime(req->hres+req->lres,80, "Date: " RFCTIME "\r\n\r\n", gmtime(&now)); req->state = STATE_WRITE_HEADER; if (debug) fprintf(stderr,"%03d: error: %d, connection=%s\n", req->fd, status, req->keep_alive ? "Keep-Alive" : "Close"); } void mkredirect(struct REQUEST *req) { req->status = 302; req->body = req->path; req->lbody = strlen(req->body); req->lres = sprintf(req->hres, RESPONSE_START "Location: http://%s:%d%s\r\n" "Content-Type: text/plain\r\n" "Content-Length: %d\r\n", "302 Redirect",server_name, req->keep_alive ? "Keep-Alive" : "Close", req->hostname,tcp_port,req->path, req->lbody); req->lres += strftime(req->hres+req->lres,80, "Date: " RFCTIME "\r\n\r\n", gmtime(&now)); req->state = STATE_WRITE_HEADER; if (debug) fprintf(stderr,"%03d: 302 redirect: %s, connection=%s\n", req->fd, req->path, req->keep_alive ? "Keep-Alive" : "Close"); } void mkheader(struct REQUEST *req, int status, time_t mtime) { int i; for (i = 0; http[i].status != 0; i++) if (http[i].status == status) break; req->status = status; req->lres = sprintf(req->hres, RESPONSE_START, http[i].head,server_name, req->keep_alive ? "Keep-Alive" : "Close"); req->lres += sprintf(req->hres+req->lres, "Content-Type: %s\r\n" "Content-Length: %d\r\n", req->mime, req->lbody); if (mtime != -1) req->lres += strftime(req->hres+req->lres,80, "Last-Modified: " RFCTIME "\r\n", gmtime(&mtime)); req->lres += strftime(req->hres+req->lres,80, "Date: " RFCTIME "\r\n\r\n", gmtime(&now)); req->state = STATE_WRITE_HEADER; if (debug) fprintf(stderr,"%03d: %d, connection=%s\n", req->fd, status, req->keep_alive ? "Keep-Alive" : "Close"); } /* ---------------------------------------------------------------------- */ void write_request(struct REQUEST *req) { int rc; for (;;) { switch (req->state) { case STATE_WRITE_HEADER: rc = write(req->fd,req->hres + req->written, req->lres - req->written); switch (rc) { case -1: if (errno == EAGAIN) return; if (errno == EINTR) continue; xperror(LOG_INFO,"write",req->peerhost); /* fall through */ case 0: req->state = STATE_CLOSE; return; default: req->written += rc; req->bc += rc; if (req->written != req->lres) return; } req->written = 0; if (req->head_only) { req->state = STATE_FINISHED; return; } else { req->state = STATE_WRITE_BODY; } break; case STATE_WRITE_BODY: rc = write(req->fd,req->body + req->written, req->lbody - req->written); switch (rc) { case -1: if (errno == EAGAIN) return; if (errno == EINTR) continue; xperror(LOG_INFO,"write",req->peerhost); /* fall through */ case 0: req->state = STATE_CLOSE; return; default: req->written += rc; req->bc += rc; if (req->written != req->lbody) return; } req->state = STATE_FINISHED; return; } /* switch(state) */ } /* for (;;) */ } xawtv-3.106/vbistuff/top.html.in000066400000000000000000000003421343350355000166210ustar00rootroot00000000000000 page %03x/%02x
xawtv-3.106/x11/000077500000000000000000000000001343350355000133065ustar00rootroot00000000000000xawtv-3.106/x11/MoTV-de_DE.UTF-8000066400000000000000000000220141343350355000156150ustar00rootroot00000000000000
! ----------------------------------------------------------------------------
! some standard motif stuff [i18n]

*.cancelLabelString:				Abbrechen
*.applyLabelString:				Übernehmen
*.XmFileSelectionBox.dirListLabelString:	Verzeichnisse
*.XmFileSelectionBox.fileListLabelString:	Dateien
*.XmFileSelectionBox.selectionLabelString:	Auswahl


! ----------------------------------------------------------------------------
! strings [i18n]

MoTV.about_box_popup.title:		Über motv
MoTV*about_box_popup*messageString:	\
	motv - Motif TV application	\n\
	\n\
	(c) 2002 Gerd Knorr 

MoTV.errbox_popup.title:		Fehler

control*menubar*fileM.tearOffTitle:	Datei
control*menubar*editM.tearOffTitle:	Bearbeiten
control*menubar*toolsM.tearOffTitle:	Tools
control*menubar*tuneM.tearOffTitle:	Tuner
control*menubar*grabM.tearOffTitle:	Bild speichern
control*menubar*ratioM.tearOffTitle:	Seitenverhältnis
control*menubar*launchM.tearOffTitle:	Launch
control*menubar*subM.tearOffTitle:	Untertitel
control*menubar*stationsM.tearOffTitle:	Sender
control*menubar*optionsM.tearOffTitle:	Einstellungen
control*menubar*helpM.tearOffTitle:	Hilfe
control*menubar*captureM.tearOffTitle:	Capture
control*menubar*freqM.tearOffTitle:	Frequenztabelle
control*menubar*inputM.tearOffTitle:	Eingang
control*menubar*normM.tearOffTitle:	TV Norm

control*menubar.file.labelString:	Datei
control*menubar.file.mnemonic:		D
control*menubar.edit.labelString:	Bearbeiten
control*menubar.edit.mnemonic:		B
control*menubar.tools.labelString:	Tools
control*menubar.tools.mnemonic:		T
control*menubar*tune.labelString:	Tuner
control*menubar*grab.labelString:	Bild speichern
control*menubar*ratio.labelString:	Seitenverhältnis
control*menubar*launch.labelString:	Launch
control*menubar*sub.labelString:	Untertitel
control*menubar.stations.labelString:	Sender
control*menubar.stations.mnemonic:	S
control*menubar.options.labelString:	Einstellungen
control*menubar.options.mnemonic:	E
control*menubar.filter.labelString:	Filter
control*menubar.filter.mnemonic:	F
control*menubar.help.labelString:	Hilfe
control*menubar.help.mnemonic:		H

! file menu
control*menubar*rec.labelString:	Film aufnehmen ...
control*menubar*rec.mnemonic:		F
control*menubar*rec.acceleratorText:	R
control*menubar*rec.accelerator:	R
control*menubar*quit.labelString:	Beenden
control*menubar*quit.mnemonic:		B
control*menubar*quit.acceleratorText:	Q
control*menubar*quit.accelerator:	Q

! edit menu
control*menubar*copy.labelString:	Kopieren
control*menubar*copy.mnemonic:		K
control*menubar*copy.acceleratorText:	Ctrl+C
control*menubar*copy.accelerator:	CtrlC

! tools menu
control*menubar*mute.labelString:	Ton aus
control*menubar*mute.mnemonic:		a
control*menubar*mute.acceleratorText:	A
control*menubar*mute.accelerator:	A
control*menubar*full.labelString:	Vollbild
control*menubar*full.acceleratorText:	F
control*menubar*full.accelerator:	F
control*menubar*ontop.labelString:	Stay on Top
control*menubar*ontop.mnemonic:		T
control*menubar*ontop.acceleratorText:	T
control*menubar*ontop.accelerator:	T
control*menubar*levels.labelString:	Aufnahmepegel ...
control*menubar*levels.acceleratorText:	L
control*menubar*levels.accelerator:	L
control*menubar*st_up.labelString:	Nächster Sender
control*menubar*st_up.acceleratorText:	page up
control*menubar*st_dn.labelString:	Vorheriger Sender
control*menubar*st_dn.acceleratorText:	page down

control*menubar*ch_up.labelString:	Nächster Kanal
control*menubar*ch_up.acceleratorText:	up
control*menubar*ch_dn.labelString:	Vorheriger Kanal
control*menubar*ch_dn.acceleratorText:	down
control*menubar*fi_up.labelString:	Finetune up
control*menubar*fi_up.acceleratorText:	right
control*menubar*fi_dn.labelString:	Finetune down
control*menubar*fi_dn.acceleratorText:	left

control*menubar*ppm_f.labelString:	PPM, maximale Größe
control*menubar*ppm_f.acceleratorText:	G
control*menubar*ppm_f.accelerator:	~CtrlG
control*menubar*ppm_w.labelString:	PPM, Fenstergröße
control*menubar*ppm_w.acceleratorText:	Ctrl+G
control*menubar*ppm_w.accelerator:	CtrlG
control*menubar*jpg_f.labelString:	JPEG, maximale Größe
control*menubar*jpg_f.mnemonic:		J
control*menubar*jpg_f.acceleratorText:	J
control*menubar*jpg_f.accelerator:	~CtrlJ
control*menubar*jpg_w.labelString:	JPEG, Fenstergröße
control*menubar*jpg_w.acceleratorText:	Ctrl+J
control*menubar*jpg_w.accelerator:	CtrlJ

control*menubar*r_no.labelString:	keines
control*menubar*r_no.mnemonic:		k
control*menubar*r_43.labelString:	4:3
control*menubar*r_43.mnemonic:		4

control*menubar*s_off.labelString:	keine
control*menubar*s_150.labelString:	Seite 150
control*menubar*s_150.mnemonic:		1
control*menubar*s_333.labelString:	Seite 333
control*menubar*s_333.mnemonic:		3
control*menubar*s_777.labelString:	Seite 777
control*menubar*s_777.mnemonic:		7
control*menubar*s_801.labelString:	Seite 801
control*menubar*s_801.mnemonic:		0
control*menubar*s_888.labelString:	Seite 888
control*menubar*s_888.mnemonic:		8

! options menu
control*menubar*add.labelString:	Sender hinzufügen ...
control*menubar*add.mnemonic:		h
control*menubar*scan.labelString:	Sendersuche ...
control*menubar*pref.labelString:	Konfiguration ...
control*menubar*save.labelString:	Einstellungen speichern
control*menubar*save.mnemonic:		s

control*menubar*capture.labelString:	Capture
control*menubar*capture.mnemonic:	C
control*menubar*freq.labelString:	Frequenztabelle
control*menubar*freq.mnemonic:		F
control*menubar*scale.labelString:	Regler ...
control*menubar*scale.acceleratorText:	S
control*menubar*scale.accelerator:	S

control*menubar*input.labelString:	Eingang
control*menubar*input.mnemonic:		E
control*menubar*norm.labelString:	Fernsehnorm
control*menubar*norm.mnemonic:		n

! filter menu
control*menubar*fnone.labelString:	Kein filter
control*menubar*fnone.mnemonic:		K

! help menu
control*menubar*man.labelString:	Manual anzeigen
control*menubar*man.mnemonic:		M
control*menubar*about.labelString:	Über ...
control*menubar*about.mnemonic:		b

! tooltips (needs openmotif 2.2)
control*tool.prev.toolTipString:	nächster Sender
control*tool.next.toolTipString:	vorheriger Sender
control*tool.snap.toolTipString:	Bild speichern
control*tool.movie.toolTipString:	Film aufnehmen
control*tool.mute.toolTipString:	Ton aus
control*tool.exit.toolTipString:	Beenden

control*box.XmPushButton*menu.del.labelString:	Löschen
control*box.XmPushButton*menu.edit.labelString:	Ändern ...

! channel scan
*chscan_popup.title:			Sendersuche
*chscan_popup*okLabelString:		Start
*chscan_popup*hints.labelString:	\
	Der Sendersuchlauf baut eine komplett neue\n\
	Senderliste auf, die jetzige Liste wird\n\
	überschrieben.\n\
	\n\
	Damit die Sendersuche richtig funkioniert\n\
	müssen Fernsehnorm und Frequenztabelle\n\
	richtig eingestellt sein.  Beides ist auch\n\
	unter "Einstellungen" zu finden.\n

! channel properties
*prop_popup.title:			Einstellungen
*prop_popup*rc.nameL.labelString:	Sendername
*prop_popup*rc.keyL.labelString:	Hotkey
*prop_popup*rc.groupL.labelString:	Gruppe
*prop_popup*rc.channelL.labelString:	Kanal
*prop_popup*rc.buttons.ok.labelString:	OK
*prop_popup*rc.buttons.cancel.labelString: Abbrechen
*prop_popup*no_name_popup.title:	Fehler
*prop_popup*no_name_popup*messageString: \
	Einen Namen für den Sender mußt Du schon vergeben.

! preferences
*pref_popup.title:			Einstellungen
*pref_popup*okLabelString:		Speichern
*pref_popup*fsL.labelString:		Vollbild
*pref_popup*fsT.labelString:		Auflösung umschalten
*pref_popup*fsO.labelString:		Auflösung:
*pref_popup*mixL.labelString:		\
	Lautstärke (funkioniert erst nach Neustart)
*pref_popup*mixT.labelString:		Lautstärke mit Mixer regeln
*pref_popup*mix1O.labelString:		Gerät:
*pref_popup*mix2O.labelString:		Regler:
*pref_popup*optL.labelString:		Optionen
*pref_popup*osd.labelString:		Bei Vollbild OSD benutzen
*pref_popup*keypad-ntsc.labelString:	Nummernblock: ntsc modus
*pref_popup*keypad-partial.labelString:	\
	Nummernblock: beim ersten Tastendruck umschalten
*pref_popup*jpeg.label.labelString:	JPEG Bildqualität:

scale.title:				Regler
scale*volume.titleString:		Lautstärke
scale*bright.titleString:		Helligkeit
scale*hue.titleString:			Farbe
scale*color.titleString:		Sättigung
scale*contrast.titleString:		Kontrast

levels.title:				Monitor
levels*enable.labelstring:		einschalten

streamer.title:				Film aufnehmen
streamer*driverL.labelString:		Ausgabeformat
streamer*driver.labelString:		Driver:
streamer*videoL.labelString:		Video Einstellungen
streamer*video.labelString:		Format:
streamer*fpsL.labelString:		fps:
streamer*audioL.labelString:		Audio Einstellungen
streamer*audio.labelString:		Format:
streamer*rateL.labelString:		Rate:
streamer*fileL.labelString:		Dateinamen
streamer*fvideoL.labelString:		Video:
streamer*faudioL.labelString:		Audio:
streamer*status.labelString:		fixme

streamer*files.labelString:		Browse ...
streamer*buttons.rec.labelString:	Aufnahme
streamer*buttons.stop.labelString:	Stop
streamer*buttons.play.labelString:	Abspielen
streamer*buttons.cancel.labelString:	Schließen

MoTV.man_popup.title:			Manual page
MoTV.man_popup*okLabelString:		Fenster schließen
MoTV.man_popup*label.labelString:	bitte warten ...

xawtv-3.106/x11/MoTV-default000066400000000000000000000220461343350355000155040ustar00rootroot00000000000000
! ----------------------------------------------------------------------------
! some standard motif stuff [i18n]

!*.cancelLabelString:				Cancel
!*.applyLabelString:				Apply
!*.XmFileSelectionBox.dirListLabelString:	Directories
!*.XmFileSelectionBox.fileListLabelString:	Files
!*.XmFileSelectionBox.selectionLabelString:	Selection


! ----------------------------------------------------------------------------
! strings [i18n]

MoTV.about_box_popup.title:		About motv
MoTV*about_box_popup*messageString:	\
	motv - Motif TV application	\n\
	\n\
	(c) 2002 Gerd Knorr 

MoTV.errbox_popup.title:		Errors

control*menubar*fileM.tearOffTitle:	File
control*menubar*editM.tearOffTitle:	Edit
control*menubar*toolsM.tearOffTitle:	Tools
control*menubar*tuneM.tearOffTitle:	Tuner control
control*menubar*grabM.tearOffTitle:	Grab image
control*menubar*ratioM.tearOffTitle:	Aspect ratio
control*menubar*launchM.tearOffTitle:	Launch
control*menubar*subM.tearOffTitle:	Subtitles
control*menubar*stationsM.tearOffTitle:	TV Stations
control*menubar*optionsM.tearOffTitle:	Options
control*menubar*helpM.tearOffTitle:	Help
control*menubar*captureM.tearOffTitle:	Capture
control*menubar*freqM.tearOffTitle:	Frequency table
control*menubar*inputM.tearOffTitle:	Inputs
control*menubar*normM.tearOffTitle:	TV Norm

control*menubar.file.labelString:	File
control*menubar.file.mnemonic:		F
control*menubar.edit.labelString:	Edit
control*menubar.edit.mnemonic:		E
control*menubar.tools.labelString:	Tools
control*menubar.tools.mnemonic:		T
control*menubar*tune.labelString:	Tuner
control*menubar*grab.labelString:	Grab image
control*menubar*ratio.labelString:	Aspect ratio
control*menubar*launch.labelString:	Launch
control*menubar*sub.labelString:	Subtitles
control*menubar.stations.labelString:	Stations
control*menubar.stations.mnemonic:	S
control*menubar.options.labelString:	Options
control*menubar.options.mnemonic:	O
control*menubar.filter.labelString:	Filter
control*menubar.filter.mnemonic:	F
control*menubar.help.labelString:	Help
control*menubar.help.mnemonic:		H

! file menu
control*menubar*rec.labelString:	Record movie ...
control*menubar*rec.mnemonic:		R
control*menubar*rec.acceleratorText:	R
control*menubar*rec.accelerator:	R
control*menubar*quit.labelString:	Quit
control*menubar*quit.mnemonic:		Q
control*menubar*quit.acceleratorText:	Q
control*menubar*quit.accelerator:	Q

! edit menu
control*menubar*copy.labelString:	Copy
control*menubar*copy.mnemonic:		C
control*menubar*copy.acceleratorText:	Ctrl+C
control*menubar*copy.accelerator:	CtrlC

! tools menu
control*menubar*mute.labelString:	Mute audio
control*menubar*mute.mnemonic:		a
control*menubar*mute.acceleratorText:	A
control*menubar*mute.accelerator:	A
control*menubar*full.labelString:	Fullscreen
control*menubar*full.mnemonic:		F
control*menubar*full.acceleratorText:	F
control*menubar*full.accelerator:	F
control*menubar*ontop.labelString:	Stay on Top
control*menubar*ontop.mnemonic:		T
control*menubar*ontop.acceleratorText:	T
control*menubar*ontop.accelerator:	T
control*menubar*levels.labelString:	Record level monitor ...
control*menubar*levels.mnemonic:	l
control*menubar*levels.acceleratorText:	L
control*menubar*levels.accelerator:	L
control*menubar*st_up.labelString:	Next station
control*menubar*st_up.acceleratorText:	page up
control*menubar*st_dn.labelString:	Previous station
control*menubar*st_dn.acceleratorText:	page down

control*menubar*ch_up.labelString:	Channel up
control*menubar*ch_up.acceleratorText:	up
control*menubar*ch_dn.labelString:	Channel down
control*menubar*ch_dn.acceleratorText:	down
control*menubar*fi_up.labelString:	Finetune up
control*menubar*fi_up.acceleratorText:	right
control*menubar*fi_dn.labelString:	Finetune down
control*menubar*fi_dn.acceleratorText:	left

control*menubar*ppm_f.labelString:	PPM, max size
control*menubar*ppm_f.acceleratorText:	G
control*menubar*ppm_f.accelerator:	~CtrlG
control*menubar*ppm_w.labelString:	PPM, window size
control*menubar*ppm_w.acceleratorText:	Ctrl+G
control*menubar*ppm_w.accelerator:	CtrlG
control*menubar*jpg_f.labelString:	JPEG, max size
control*menubar*jpg_f.mnemonic:		J
control*menubar*jpg_f.acceleratorText:	J
control*menubar*jpg_f.accelerator:	~CtrlJ
control*menubar*jpg_w.labelString:	JPEG, window size
control*menubar*jpg_w.acceleratorText:	Ctrl+J
control*menubar*jpg_w.accelerator:	CtrlJ

control*menubar*r_no.labelString:	no ratio
control*menubar*r_no.mnemonic:		n
control*menubar*r_43.labelString:	4:3
control*menubar*r_43.mnemonic:		4

control*menubar*s_off.labelString:	disable
control*menubar*s_150.labelString:	page 150
control*menubar*s_150.mnemonic:		1
control*menubar*s_333.labelString:	page 333
control*menubar*s_333.mnemonic:		3
control*menubar*s_777.labelString:	page 777
control*menubar*s_777.mnemonic:		7
control*menubar*s_801.labelString:	page 801
control*menubar*s_801.mnemonic:		0
control*menubar*s_888.labelString:	page 888
control*menubar*s_888.mnemonic:		8

! options menu
control*menubar*add.labelString:	Add station ...
control*menubar*add.mnemonic:		A
control*menubar*scan.labelString:	Channel scan ...
control*menubar*pref.labelString:	Preferences ...
control*menubar*pref.mnemonic:		P
control*menubar*save.labelString:	Save configuration
control*menubar*save.mnemonic:		S

control*menubar*capture.labelString:	Capture
control*menubar*capture.mnemonic:	C
control*menubar*freq.labelString:	Frequency table
control*menubar*freq.mnemonic:		F
control*menubar*scale.labelString:	Scales ...
control*menubar*scale.mnemonic:		S
control*menubar*scale.acceleratorText:	S
control*menubar*scale.accelerator:	S

control*menubar*input.labelString:	Input
control*menubar*input.mnemonic:		I
control*menubar*norm.labelString:	TV Norm
control*menubar*norm.mnemonic:		N

! filter menu
control*menubar*fnone.labelString:	No filter
control*menubar*fnone.mnemonic:		N

! help menu
control*menubar*man.labelString:	Show manpage
control*menubar*man.mnemonic:		m
control*menubar*about.labelString:	About ...
control*menubar*about.mnemonic:		A

! tooltips (needs openmotif 2.2)
control*tool.prev.toolTipString:	previous station
control*tool.next.toolTipString:	next station
control*tool.snap.toolTipString:	grab image
control*tool.movie.toolTipString:	record movie
control*tool.mute.toolTipString:	mute audio
control*tool.exit.toolTipString:	quit

control*box.XmPushButton*menu.del.labelString:	Delete
control*box.XmPushButton*menu.edit.labelString:	Edit ...

! channel scan
*chscan_popup.title:		Channel scan
*chscan_popup*okLabelString:	Start
*chscan_popup*hints.labelString:	\
	You can let me scan all channels for\n\
	TV stations here.  This will create a\n\
	new channel list from scratch, your\n\
	current list will be lost.\n\
	\n\
	Make sure you have configured the correct\n\
	TV norm and Frequency table first (it's in\n\
	the options menu too), otherwise the scan\n\
	will not find any station ...\n\
	\n

! channel properties
*prop_popup.title:			Edit Station
*prop_popup*rc.nameL.labelString:	Station name
*prop_popup*rc.keyL.labelString:	Hotkey
*prop_popup*rc.groupL.labelString:	Group
*prop_popup*rc.channelL.labelString:	Channel
*prop_popup*rc.buttons.ok.labelString:	OK
*prop_popup*rc.buttons.cancel.labelString: Cancel
*prop_popup*no_name_popup.title:	Error
*prop_popup*no_name_popup*messageString: \
	You have to specify a name for the TV Station

! preferences
*pref_popup.title:			Preferences
*pref_popup*okLabelString:		Save
*pref_popup*fsL.labelString:		Fullscreen
*pref_popup*fsT.labelString:		Enable mode switching
*pref_popup*fsO.labelString:		Video mode:
*pref_popup*mixL.labelString:		Volume (needs restart to take effect)
*pref_popup*mixT.labelString:		Use mixer device for volume control
*pref_popup*mix1O.labelString:		mixer device:
*pref_popup*mix2O.labelString:		mixer control:
*pref_popup*optL.labelString:		Options
*pref_popup*osd.labelString:		Use onscreen display in Fullscreen mode
*pref_popup*keypad-ntsc.labelString:	keypad: ntsc mode
*pref_popup*keypad-partial.labelString:	\
	keypad: enable partial (switch on first key)
*pref_popup*jpeg.label.labelString:	JPEG quality:

scale.title:				Scale controls
scale*volume.titleString:		Volume
scale*bright.titleString:		Bright
scale*hue.titleString:			Hue
scale*color.titleString:		Saturation
scale*contrast.titleString:		Contrast

levels.title:				Monitor
levels*enable.labelstring:		enable

streamer.title:				record a movie
streamer*driverL.labelString:		Output format
streamer*driver.labelString:		Driver:
streamer*videoL.labelString:		Video options
streamer*video.labelString:		Format:
streamer*fpsL.labelString:		fps:
streamer*audioL.labelString:		Audio options
streamer*audio.labelString:		Format:
streamer*rateL.labelString:		Rate:
streamer*fileL.labelString:		Filenames
streamer*fvideoL.labelString:		Video:
streamer*faudioL.labelString:		Audio:
streamer*status.labelString:		fixme

streamer*files.labelString:		Browse ...
streamer*buttons.rec.labelString:	Record
streamer*buttons.stop.labelString:	Stop
streamer*buttons.play.labelString:	Playback
streamer*buttons.cancel.labelString:	Close

MoTV.man_popup.title:			Manual page
MoTV.man_popup*okLabelString:		close window
MoTV.man_popup*label.labelString:	please wait ...

xawtv-3.106/x11/MoTV-fixed000066400000000000000000000303411343350355000151540ustar00rootroot00000000000000
! ----------------------------------------------------------------------------
! fonts

*renderTable:
*renderTable.fontType: FONT_IS_FONTSET
*renderTable.fontName: \
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso10646-1, \
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso8859-* \
 -*-*-*-*--13-*-*-*-*-*-*-*,*

MoTV.onscreen.label.renderTable:
MoTV.onscreen.label.renderTable.fontType: FONT_IS_FONTSET
MoTV.onscreen.label.renderTable.fontName: \
 -misc-fixed-medium-r-normal--20-*-*-*-*-*-iso10646-1, \
 -misc-fixed-medium-r-normal--20-*-*-*-*-*-iso8859-* \
 -*-*-*-*--20-*-*-*-*-*-*-*,*

MoTV.vtx.label.renderTable:
MoTV.vtx.label.renderTable.fontType: FONT_IS_FONTSET
MoTV.vtx.label.renderTable.fontName: \
 -misc-fixed-medium-r-normal--20-*-*-*-*-*-iso10646-1, \
 -misc-fixed-medium-r-normal--20-*-*-*-*-*-iso8859-* \
 -*-*-*-*--20-*-*-*-*-*-*-*,*


! ----------------------------------------------------------------------------
! main window

MoTV.geometry:			320x240+50+50
MoTV.winGravity:		Static

!  This is commented out to avoid warnings
!  (seems not working now, as of 20110216)
!MoTV.translations:		#override			\n\
!	:	Remote()

MoTV.tv.traversalOn:		false
MoTV.tv.highlightThickness:	0
MoTV.tv.background:		black
MoTV.tv.translations:		#replace			\n\
	:		Ipc(drag)			\n\
	:		Popup(control)			\n\
	~Alt ~Ctrl C:	Popup(control)			\n\
	Ctrl C:		Ipc(clipboard)			\n\
	Alt C:		Ipc(clipboard)			\n\
	R:			Popup(streamer)			\n\
	S:			Popup(scale)			\n\
	L:			Popup(levels)			\n\
	T:			StayOnTop()			\n\
	H:			man(motv)			\n\
	F1:		man(motv)			\n\
	\
	Q:			CloseMain()			\n\
	KP_Add:		Command(volume,inc)		\n\
	KP_Subtract:	Command(volume,dec)		\n\
	KP_Enter:		Command(volume,mute)		\n\
	A:			Command(volume,mute)		\n\
	F:			Command(fullscreen)		\n\
	CtrlZ:		Zap(fast)			\n\
	Z:			Zap()				\n\
	CtrlG:		Command(snap,ppm,win)		\n\
	CtrlJ:		Command(snap,jpeg,win)		\n\
	G:			Command(snap,ppm,full)		\n\
	J:			Command(snap,jpeg,full)		\n\
	CtrlUp:		Scan()				\n\
	~CtrlUp:		Command(setchannel,next)	\n\
	Down:		Command(setchannel,prev)	\n\
	Right:		Command(setchannel,fine_up)	\n\
	Left:		Command(setchannel,fine_down)	\n\
	Page_Up:		Command(setstation,next)	\n\
	Page_Down:		Command(setstation,prev)	\n\
	BackSpace:		Command(setstation,back)	\n\
	:		Command(setstation,next)	\n\
	:		Command(setstation,prev)	\n\
	V:			Command(capture,toggle)		\n\
	space:		Command(setstation,next)	\n\
	\
	XF86AudioRaiseVolume: Command(volume,inc)		\n\
	XF86AudioLowerVolume: Command(volume,dec)		\n\
	XF86AudioMute:	Command(volume,mute)		\n\
	XF86AudioNext:	Command(setstation,next)	\n\
	XF86AudioPrev:	Command(setstation,prev)	\n\
	XF86AudioPlay:	Command(capture,on)		\n\
	XF86AudioStop:	Command(capture,off)		\n\
	\
	KP_0:		Command(keypad,0)		\n\
	KP_1:		Command(keypad,1)		\n\
	KP_2:		Command(keypad,2)		\n\
	KP_3:		Command(keypad,3)		\n\
	KP_4:		Command(keypad,4)		\n\
	KP_5:		Command(keypad,5)		\n\
	KP_6:		Command(keypad,6)		\n\
	KP_7:		Command(keypad,7)		\n\
	KP_8:		Command(keypad,8)		\n\
	KP_9:		Command(keypad,9)		\n\
	\
	osfHelp:		man(motv)			\n\
	osfActivate:	Command(volume,mute)		\n\
	CtrlosfUp:		Scan()				\n\
	~CtrlosfUp:	Command(setchannel,next)	\n\
	osfDown:		Command(setchannel,prev)	\n\
	osfRight:		Command(setchannel,fine_up)	\n\
	osfLeft:		Command(setchannel,fine_down)	\n\
	osfPageUp:		Command(setstation,next)	\n\
	osfPageDown:	Command(setstation,prev)	\n\
	osfBackSpace:	Command(setstation,back)


MoTV.tv*stationsM.menuPost:	

MoTV.about_box_popup.deleteResponse:	DESTROY
MoTV.errbox_popup.deleteResponse:	UNMAP

MoTV.tv*stationsM.packing:		PACK_COLUMN
control*menubar*stationsM.packing:	PACK_COLUMN


! ----------------------------------------------------------------------------
! control window

control.title:				MoTV
control.iconName:			MoTV
control.iconPixmap:			TVimg
control.iconMask:			TVmask
control*highlightThickness:		0
control*XmPushButton.highlightThickness: 1
control.XmDialogShell*highlightThickness: 1

control.toolTipEnable:			1
control.toolTipPostDelay:		3000
control.toolTipPostDuration:		8000
control*TipLabel.foreground:		black
control*TipLabel.background:		lightyellow
control*TipShell.borderWidth:		1
control*TipShell.borderColor:		black
control*tool.orientation:		HORIZONTAL
control*tool.?.shadowThickness:		1
control*tool.?.labelType:		PIXMAP
control*tool.XmSeparator.orientation:	VERTICAL
control*tool.XmSeparator.width:		12
control*tool.XmSeparator.margin:	3
control*tool.prev.labelPixmap:		prev
control*tool.next.labelPixmap:		next
control*tool.snap.labelPixmap:		snap
control*tool.movie.labelPixmap:		movie
control*tool.mute.labelPixmap:		mute
control*tool.exit.labelPixmap:		exit

control*menubar*XmMenuShell.XmRowColumn.tearOffModel:	TEAR_OFF_ENABLED
!control*box.XmPushButton*menu.tearOffModel:	TEAR_OFF_DISABLED

control.form.view.scrollingPolicy:	AUTOMATIC
!control.form.view.scrollBarDisplayPolicy: STATIC
control.form.view.scrollBarPlacement:	BOTTOM_RIGHT
control.form.view.scrolledWindowChildType: SCROLL_VERT
control.form.view.box.resizeWidth:	false
control.form.view.box.packing:		PACK_TIGHT
control.form.view.box.orientation:	HORIZONTAL
control.form.view.box.entryAlignment:	ALIGNMENT_CENTER

control.form.?.leftAttachment:		ATTACH_FORM
control.form.?.rightAttachment:		ATTACH_FORM
control.form.tool.topAttachment:	ATTACH_WIDGET
control.form.tool.topWidget:		menubar
control.form.view.topAttachment:	ATTACH_WIDGET
control.form.view.topWidget:		tool
control.form.view.bottomAttachment:	ATTACH_WIDGET
control.form.view.bottomWidget:		status
control.form.status.bottomAttachment:	ATTACH_FORM
control.form.status.orientation:	HORIZONTAL
control.form.status.marginWidth:	0
control.form.status.marginHeight:	0
control.form.status.spacing:		0
!control.form.status.adjustLast:		True
control.form.status.f.shadowType:	SHADOW_IN
control.form.status.f.shadowThickness:	1
control.form.status.f.?.marginLeft:	3
control.form.status.f.?.marginRight:	3
control.form.status.f.?.labelString:


! ----------------------------------------------------------------------------
! channel scan

*chscan_popup.deleteResponse:		DESTROY
*chscan_popup*dialogStyle:		DIALOG_PRIMARY_APPLICATION_MODAL
*chscan_popup*okLabelString:		Start
*chscan_popup*channel.editable:		False
*chscan_popup*channel.slidingMode:	THERMOMETER
*chscan_popup*channel.orientation:	HORIZONTAL
*chscan_popup*channel.titleString:	-
*chscan_popup*channel.sliderVisual:	SHADOWED_BACKGROUND


! ----------------------------------------------------------------------------
! channel properties

*prop_popup.deleteResponse:		UNMAP
*prop_popup*rc.key.editable:		false
*prop_popup*rc.channel.visibleItemCount: 16
*prop_popup*rc.channel.comboBoxType:	DROP_DOWN_LIST
*prop_popup*rc.channel.positionMode:	ONE_BASED
*prop_popup*rc.keyL.marginTop:		10
*prop_popup*rc.groupL.marginTop:	10
*prop_popup*rc.channelL.marginTop:	10
*prop_popup*rc.XmLabel.alignment:	ALIGNMENT_BEGINNING

*prop_popup*no_name_popup.deleteResponse: DESTROY


! ----------------------------------------------------------------------------
! preferences

*pref_popup.deleteResponse:		UNMAP
*pref_popup*fsL.frameChildType:		FRAME_TITLE_CHILD
*pref_popup*optL.frameChildType:	FRAME_TITLE_CHILD
*pref_popup*mixL.frameChildType:	FRAME_TITLE_CHILD
*pref_popup*jpeg.orientation:		HORIZONTAL
*pref_popup*jpeg.quality.columns:	3


! ----------------------------------------------------------------------------
! scale controls

scale.form.shadowThickness:		0
scale*XmScale.orientation:		HORIZONTAL
scale*XmScale.showValue:		true
scale*XmScale.highlightOnEnter:		true
scale*XmScale.highlightThickness:	1
scale*XmScale.topAttachment:		ATTACH_WIDGET
scale*XmScale.leftAttachment:		ATTACH_FORM
scale*XmScale.rightAttachment:		ATTACH_FORM
scale*XmScale.topOffset:		5
scale*XmScale.BottomOffset:		5
scale*XmScale.leftOffset:		10
scale*XmScale.rightOffset:		10
scale*XmScale.width:			160


! ----------------------------------------------------------------------------
! filter property controls

filter*label.frameChildType:		FRAME_TITLE_CHILD
filter*XmScale.showValue:		true
filter*XmScale.highlightOnEnter:	true
filter*XmScale.highlightThickness:	1
filter*XmScale.orientation:		HORIZONTAL


! ----------------------------------------------------------------------------
! levels window (sound level monitor)

levels*highlightThickness:		1
levels*XmScale.editable:		False
levels*XmScale.slidingMode:		THERMOMETER
levels*XmScale.orientation:		HORIZONTAL
levels*XmScale.sliderVisual:		SHADOWED_BACKGROUND
levels*XmScale.minimum:			0
levels*XmScale.maximum:			128
levels*XmScale.width:			256


! ----------------------------------------------------------------------------
! streamer window

streamer.title:				record a movie
streamer*XmComboBox.comboBoxType:	DROP_DOWN_COMBO_BOX
streamer*XmComboBox.width:		100
streamer*XmLabel.alignment:		ALIGNMENT_BEGINNING

streamer*highlightThickness:		1
!streamer*navigationType:		STICKY_TAB_GROUP

streamer*form.?.leftAttachment:			ATTACH_FORM
streamer*form.?.rightAttachment:		ATTACH_FORM
streamer*form.?.topAttachment:			ATTACH_WIDGET
streamer*form.?.topOffset:			10
streamer*form.?.leftOffset:			10
streamer*form.?.rightOffset:			10
streamer*form.XmFrame.marginWidth:		5
streamer*form.XmFrame.marginHeight:		5

streamer*XmFrame.XmRowColumn.orientation:	HORIZONTAL
streamer*XmFrame.fbox.orientation:		VERTICAL
streamer*XmFrame.fbox.spacing:			0
streamer*XmFrame.fbox.marginWidth:		0
streamer*XmFrame.fbox.marginHeight:		0
streamer*XmFrame.fbox.?.orientation:		HORIZONTAL

streamer*form.buttons.marginWidth:		0
streamer*form.buttons.packing:			PACK_COLUMN
streamer*form.buttons.orientation:		HORIZONTAL
streamer*form.buttons.entryAlignment:		ALIGNMENT_CENTER
streamer*form.buttons.bottomAttachment:		ATTACH_FORM

streamer*driverL.frameChildType:	FRAME_TITLE_CHILD
streamer*videoL.frameChildType:		FRAME_TITLE_CHILD
streamer*audioL.frameChildType:		FRAME_TITLE_CHILD
streamer*fileL.frameChildType:		FRAME_TITLE_CHILD

streamer*videoF.topWidget:		driverF
streamer*audioF.topWidget:		videoF
streamer*fileF.topWidget:		audioF
streamer*status.topWidget:		fileF
streamer*buttons.topWidget:		status
streamer*buttons.bottomOffset:		10

streamer*rate.itemCount:		6
streamer*rate.visibleItemCount:		6
streamer*rate.items:			8000,11025,22050,32000,44100,48000
streamer*rate.selectedItem:		44100
streamer*fps.itemCount:			11
streamer*fps.visibleItemCount:		11
streamer*fps.items:			3,5,8,10,12,15,18,20,24,25,30
streamer*fps.selectedItem:		12

streamer*fvideo.translations:		#override\
	CtrlTab:			Complete()
streamer*faudio.translations:		#override\
	CtrlTab:			Complete()

! debug
streamer.form.*.borderWidth:		0
!streamer.form.*.borderColor:		darkred
!streamer*form.XmFrame.background:	yellow


! ----------------------------------------------------------------------------
! man page renderer

MoTV.man_popup.deleteResponse:			DESTROY
MoTV.man_popup*view.width:			500
MoTV.man_popup*view.height:			600
MoTV.man_popup*view.scrollingPolicy:		AUTOMATIC
MoTV.man_popup*view.scrollBarPlacement:		BOTTOM_RIGHT

MoTV.man_popup*label.alignment:			ALIGNMENT_BEGINNING
MoTV.man_popup*label.marginWidth:		5
MoTV.man_popup*label.marginHeight:		5
MoTV.man_popup*label.renderTable: bold,underline
MoTV.man_popup*label.renderTable.fontType: FONT_IS_FONTSET
MoTV.man_popup*label.renderTable.fontName: \
 -misc-fixed-medium-r-normal--13-*-*-*-*-*-iso10646-1, \
 -misc-fixed-medium-r-normal--13-*-*-*-*-*-iso8859-* \
 -*-*-*-*--13-*-*-*-*-*-*-*,*
MoTV.man_popup*label.renderTable.bold.fontType: FONT_IS_FONTSET
MoTV.man_popup*label.renderTable.bold.fontName: \
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso10646-1, \
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso8859-* \
 -*-*-*-*--13-*-*-*-*-*-*-*,*
MoTV.man_popup*label.renderTable.underline.underlineType: SINGLE_LINE


! ----------------------------------------------------------------------------
! Onscreen window

MoTV.onscreen.allowShellResize:		true
MoTV.onscreen*background:		black
MoTV.onscreen*borderColor:		black
MoTV.onscreen*foreground:		lightgreen
MoTV.onscreen*highlightThickness:	0

MoTV.vtx.allowShellResize:		true
MoTV.vtx*borderColor:			black
MoTV.vtx*background:			black
MoTV.vtx*foreground:			white
MoTV.vtx*highlightThickness:		0

xawtv-3.106/x11/MoTV-fr000066400000000000000000000230441343350355000144660ustar00rootroot00000000000000
! ----------------------------------------------------------------------------
! some standard motif stuff [i18n]

!*.cancelLabelString:				Annuler
!*.applyLabelString:				Appliquer
!*.XmFileSelectionBox.dirListLabelString:	Dossiers
!*.XmFileSelectionBox.fileListLabelString:	Fichiers
!*.XmFileSelectionBox.selectionLabelString:	Sélection


! ----------------------------------------------------------------------------
! strings [i18n]

MoTV.about_box_popup.title:		A propos de motv
MoTV*about_box_popup*messageString:	\
	motv -  application TV en Motif	\n\
	\n\
	(c) 2002 Gerd Knorr 

MoTV.errbox_popup.title:		Erreurs

control*menubar*fileM.tearOffTitle:	Fichier
control*menubar*editM.tearOffTitle:	Edition
control*menubar*toolsM.tearOffTitle:	Outils
control*menubar*tuneM.tearOffTitle:	Contrôle du syntoniseur
control*menubar*grabM.tearOffTitle:	Capturer image
control*menubar*ratioM.tearOffTitle:	Proportions image
control*menubar*launchM.tearOffTitle:	Lancer
control*menubar*subM.tearOffTitle:	Soustitres
control*menubar*stationsM.tearOffTitle:	Emetteurs TV
control*menubar*optionsM.tearOffTitle:	Options
control*menubar*helpM.tearOffTitle:	Aide
control*menubar*captureM.tearOffTitle:	Capture
control*menubar*freqM.tearOffTitle:	Table de fréquences
control*menubar*inputM.tearOffTitle:	Entrée
control*menubar*normM.tearOffTitle:	Norme TV

control*menubar.file.labelString:	Fichier
control*menubar.file.mnemonic:		F
control*menubar.edit.labelString:	Edition
control*menubar.edit.mnemonic:		E
control*menubar.tools.labelString:	Outils
control*menubar.tools.mnemonic:		T
control*menubar*tune.labelString:	Syntoniseur
control*menubar*grab.labelString:	Capturer image
control*menubar*ratio.labelString:	Proportions image
control*menubar*launch.labelString:	Lancer
control*menubar*sub.labelString:	Soustitres
control*menubar.stations.labelString:	Chaînes
control*menubar.stations.mnemonic:	C
control*menubar.options.labelString:	Options
control*menubar.options.mnemonic:	O
control*menubar.filter.labelString:	Filtre
control*menubar.filter.mnemonic:	F
control*menubar.help.labelString:	Aide
control*menubar.help.mnemonic:		A

! file menu
control*menubar*rec.labelString:	Enregistrer film ...
control*menubar*rec.mnemonic:		R
control*menubar*rec.acceleratorText:	R
control*menubar*rec.accelerator:	R
control*menubar*quit.labelString:	Quitte
control*menubar*quit.mnemonic:		Q
control*menubar*quit.acceleratorText:	Q
control*menubar*quit.accelerator:	Q

! edit menu
control*menubar*copy.labelString:	Copier
control*menubar*copy.mnemonic:		C
control*menubar*copy.acceleratorText:	Ctrl+C
control*menubar*copy.accelerator:	CtrlC

! tools menu
control*menubar*mute.labelString:	Couper le son
control*menubar*mute.mnemonic:		a
control*menubar*mute.acceleratorText:	A
control*menubar*mute.accelerator:	A
control*menubar*full.labelString:	Plein Ecran
control*menubar*full.mnemonic:		F
control*menubar*full.acceleratorText:	F
control*menubar*full.accelerator:	F
control*menubar*ontop.labelString:	Toujours visible
control*menubar*ontop.mnemonic:		T
control*menubar*ontop.acceleratorText:	T
control*menubar*ontop.accelerator:	T
control*menubar*levels.labelString:	Moniteur du niveau d'enregistrement ...
control*menubar*levels.mnemonic:	l
control*menubar*levels.acceleratorText:	L
control*menubar*levels.accelerator:	L
control*menubar*st_up.labelString:	Emetteur suivant
control*menubar*st_up.acceleratorText:	page suivante
control*menubar*st_dn.labelString:	Emetteur précédent
control*menubar*st_dn.acceleratorText:	page précédente

control*menubar*ch_up.labelString:	Fréquence suivante
control*menubar*ch_up.acceleratorText:	haut
control*menubar*ch_dn.labelString:	Fréquence précédente
control*menubar*ch_dn.acceleratorText:	bas
control*menubar*fi_up.labelString:	Syntonisation fine +
control*menubar*fi_up.acceleratorText:	droite
control*menubar*fi_dn.labelString:	Syntonisation fine -
control*menubar*fi_dn.acceleratorText:	gauche

control*menubar*ppm_f.labelString:	PPM, taille maximum
control*menubar*ppm_f.acceleratorText:	G
control*menubar*ppm_f.accelerator:	~CtrlG
control*menubar*ppm_w.labelString:	PPM, taille de la fenêtre
control*menubar*ppm_w.acceleratorText:	Ctrl+G
control*menubar*ppm_w.accelerator:	CtrlG
control*menubar*jpg_f.labelString:	JPEG, taille maximum
control*menubar*jpg_f.mnemonic:		J
control*menubar*jpg_f.acceleratorText:	J
control*menubar*jpg_f.accelerator:	~CtrlJ
control*menubar*jpg_w.labelString:	JPEG, taille de la fenêtre
control*menubar*jpg_w.acceleratorText:	Ctrl+J
control*menubar*jpg_w.accelerator:	CtrlJ

control*menubar*r_no.labelString:	pas de proportion
control*menubar*r_no.mnemonic:		n
control*menubar*r_43.labelString:	4:3
control*menubar*r_43.mnemonic:		4

control*menubar*s_off.labelString:	désactiver
control*menubar*s_150.labelString:	page 150
control*menubar*s_150.mnemonic:		1
control*menubar*s_333.labelString:	page 333
control*menubar*s_333.mnemonic:		3
control*menubar*s_777.labelString:	page 777
control*menubar*s_777.mnemonic:		7
control*menubar*s_801.labelString:	page 801
control*menubar*s_801.mnemonic:		0
control*menubar*s_888.labelString:	page 888
control*menubar*s_888.mnemonic:		8

! options menu
control*menubar*add.labelString:	Ajouter émetteur ...
control*menubar*add.mnemonic:		A
control*menubar*scan.labelString:	Rechercher émetteur ...
control*menubar*pref.labelString:	Preférences ...
control*menubar*pref.mnemonic:		P
control*menubar*save.labelString:	Sauver configuration
control*menubar*save.mnemonic:		S

control*menubar*capture.labelString:	Capturer
control*menubar*capture.mnemonic:	C
control*menubar*freq.labelString:	Table de fréquences
control*menubar*freq.mnemonic:		F
control*menubar*scale.labelString:	Echèlle ...
control*menubar*scale.mnemonic:		S
control*menubar*scale.acceleratorText:	S
control*menubar*scale.accelerator:	S

control*menubar*input.labelString:	Entrée
control*menubar*input.mnemonic:		I
control*menubar*norm.labelString:	Norme TV
control*menubar*norm.mnemonic:		N

! filter menu
control*menubar*fnone.labelString:	Pas de filtre
control*menubar*fnone.mnemonic:		N

! help menu
control*menubar*man.labelString:	Afficher la page de man
control*menubar*man.mnemonic:		m
control*menubar*about.labelString:	A propos ...
control*menubar*about.mnemonic:		A

! tooltips (needs openmotif 2.2)
control*tool.prev.toolTipString:	Emetteur précédent
control*tool.next.toolTipString:	Emetteur suivant
control*tool.snap.toolTipString:	Capture une image
control*tool.movie.toolTipString:	Enregistre un film
control*tool.mute.toolTipString:	Coupe le son
control*tool.exit.toolTipString:	Quitte

control*box.XmPushButton*menu.del.labelString:	Supprimer
control*box.XmPushButton*menu.edit.labelString:	Editer ...

! channel scan
*chscan_popup.title:		Rechercher un émetteur
*chscan_popup*okLabelString:	Commencer
*chscan_popup*hints.labelString:	\
	Vous pouvez me faire rechercher tous\n\
	les émetteurs disponibles ici. Ceci\n\
	va créer une nouvelle liste d'émetteurs\n\
	à partir de zéro, votre liste actuelle\n\
	sera perdue.\n\
	\n\
	Assurez-vous d'avoir choisi la bonne\n\
	norme TV et la table de fréquences\n\
	d'abord (c'est aussi dans le menu des\n\
	options), sinon la recherche ne\n\
	trouvera aucun émetteur...\n\
	\n

! channel properties
*prop_popup.title:			Editer émetteur
*prop_popup*rc.nameL.labelString:	Nom de l'émetteur
*prop_popup*rc.keyL.labelString:	Raccourci clavier
*prop_popup*rc.groupL.labelString:	[en] Group
*prop_popup*rc.channelL.labelString:	Emetteur
*prop_popup*rc.buttons.ok.labelString:	OK
*prop_popup*rc.buttons.cancel.labelString: Annuler
*prop_popup*no_name_popup.title:	Erreur
*prop_popup*no_name_popup*messageString: \
	Vous devez donner un nom à l'émetteur

! preferences
*pref_popup.title:			Preférences
*pref_popup*okLabelString:		Sauver
*pref_popup*fsL.labelString:		Plein écran
*pref_popup*fsT.labelString:		Permettre le changement de résolution
*pref_popup*fsO.labelString:		Résolution:
*pref_popup*mixL.labelString:		Volume (redémarrer motv pour appliquer)
*pref_popup*mixT.labelString:		Utilise le périphérique de mixage pour régler le volume
*pref_popup*mix1O.labelString:		périphérique de mixage:
*pref_popup*mix2O.labelString:		entrée de mixage:
*pref_popup*optL.labelString:		Options
*pref_popup*osd.labelString:		Utiliser la surimpression en mode plein écran
*pref_popup*keypad-ntsc.labelString:	pavé numérique : mode ntsc
*pref_popup*keypad-partial.labelString:	\
	pavé numérique : permettre partition (bascule sur la première touche)
*pref_popup*jpeg.label.labelString:	Qualité JPEG :

scale.title:				Contrôles d'échelle
scale*volume.titleString:		Volume
scale*bright.titleString:		Luminosité
scale*hue.titleString:			Hue
scale*color.titleString:		Saturation
scale*contrast.titleString:		Contraste

levels.title:				Moniteur
levels*enable.labelstring:		activer

streamer.title:				enregistrer un film
streamer*driverL.labelString:		Format de sortie
streamer*driver.labelString:		Pilote :
streamer*videoL.labelString:		Options video
streamer*video.labelString:		Format :
streamer*fpsL.labelString:		ips :
streamer*audioL.labelString:		Options audio
streamer*audio.labelString:		Format :
streamer*rateL.labelString:		Echantillonage :
streamer*fileL.labelString:		Noms des fichiers
streamer*fvideoL.labelString:		Video :
streamer*faudioL.labelString:		Audio :
streamer*status.labelString:		corrigez-moi

streamer*files.labelString:		Naviguer ...
streamer*buttons.rec.labelString:	Enregistrer
streamer*buttons.stop.labelString:	Arrêter
streamer*buttons.play.labelString:	Lire
streamer*buttons.cancel.labelString:	Fermer

MoTV.man_popup.title:			Page de manuel
MoTV.man_popup*okLabelString:		Fermer la fenêtre
MoTV.man_popup*label.labelString:	attendez svp ...

xawtv-3.106/x11/MoTV-fr_FR.UTF-8000066400000000000000000000231371343350355000156620ustar00rootroot00000000000000
! ----------------------------------------------------------------------------
! some standard motif stuff [i18n]

!*.cancelLabelString:				Annuler
!*.applyLabelString:				Appliquer
!*.XmFileSelectionBox.dirListLabelString:	Dossiers
!*.XmFileSelectionBox.fileListLabelString:	Fichiers
!*.XmFileSelectionBox.selectionLabelString:	Sélection


! ----------------------------------------------------------------------------
! strings [i18n]

MoTV.about_box_popup.title:		A propos de motv
MoTV*about_box_popup*messageString:	\
	motv -  application TV en Motif	\n\
	\n\
	(c) 2002 Gerd Knorr 

MoTV.errbox_popup.title:		Erreurs

control*menubar*fileM.tearOffTitle:	Fichier
control*menubar*editM.tearOffTitle:	Edition
control*menubar*toolsM.tearOffTitle:	Outils
control*menubar*tuneM.tearOffTitle:	Contrôle du syntoniseur
control*menubar*grabM.tearOffTitle:	Capturer image
control*menubar*ratioM.tearOffTitle:	Proportions image
control*menubar*launchM.tearOffTitle:	Lancer
control*menubar*subM.tearOffTitle:	Soustitres
control*menubar*stationsM.tearOffTitle:	Emetteurs TV
control*menubar*optionsM.tearOffTitle:	Options
control*menubar*helpM.tearOffTitle:	Aide
control*menubar*captureM.tearOffTitle:	Capture
control*menubar*freqM.tearOffTitle:	Table de fréquences
control*menubar*inputM.tearOffTitle:	Entrée
control*menubar*normM.tearOffTitle:	Norme TV

control*menubar.file.labelString:	Fichier
control*menubar.file.mnemonic:		F
control*menubar.edit.labelString:	Edition
control*menubar.edit.mnemonic:		E
control*menubar.tools.labelString:	Outils
control*menubar.tools.mnemonic:		T
control*menubar*tune.labelString:	Syntoniseur
control*menubar*grab.labelString:	Capturer image
control*menubar*ratio.labelString:	Proportions image
control*menubar*launch.labelString:	Lancer
control*menubar*sub.labelString:	Soustitres
control*menubar.stations.labelString:	Chaînes
control*menubar.stations.mnemonic:	C
control*menubar.options.labelString:	Options
control*menubar.options.mnemonic:	O
control*menubar.filter.labelString:	Filtre
control*menubar.filter.mnemonic:	F
control*menubar.help.labelString:	Aide
control*menubar.help.mnemonic:		A

! file menu
control*menubar*rec.labelString:	Enregistrer film ...
control*menubar*rec.mnemonic:		R
control*menubar*rec.acceleratorText:	R
control*menubar*rec.accelerator:	R
control*menubar*quit.labelString:	Quitte
control*menubar*quit.mnemonic:		Q
control*menubar*quit.acceleratorText:	Q
control*menubar*quit.accelerator:	Q

! edit menu
control*menubar*copy.labelString:	Copier
control*menubar*copy.mnemonic:		C
control*menubar*copy.acceleratorText:	Ctrl+C
control*menubar*copy.accelerator:	CtrlC

! tools menu
control*menubar*mute.labelString:	Couper le son
control*menubar*mute.mnemonic:		a
control*menubar*mute.acceleratorText:	A
control*menubar*mute.accelerator:	A
control*menubar*full.labelString:	Plein Ecran
control*menubar*full.mnemonic:		F
control*menubar*full.acceleratorText:	F
control*menubar*full.accelerator:	F
control*menubar*ontop.labelString:	Toujours visible
control*menubar*ontop.mnemonic:		T
control*menubar*ontop.acceleratorText:	T
control*menubar*ontop.accelerator:	T
control*menubar*levels.labelString:	Moniteur du niveau d'enregistrement ...
control*menubar*levels.mnemonic:	l
control*menubar*levels.acceleratorText:	L
control*menubar*levels.accelerator:	L
control*menubar*st_up.labelString:	Emetteur suivant
control*menubar*st_up.acceleratorText:	page suivante
control*menubar*st_dn.labelString:	Emetteur précédent
control*menubar*st_dn.acceleratorText:	page précédente

control*menubar*ch_up.labelString:	Fréquence suivante
control*menubar*ch_up.acceleratorText:	haut
control*menubar*ch_dn.labelString:	Fréquence précédente
control*menubar*ch_dn.acceleratorText:	bas
control*menubar*fi_up.labelString:	Syntonisation fine +
control*menubar*fi_up.acceleratorText:	droite
control*menubar*fi_dn.labelString:	Syntonisation fine -
control*menubar*fi_dn.acceleratorText:	gauche

control*menubar*ppm_f.labelString:	PPM, taille maximum
control*menubar*ppm_f.acceleratorText:	G
control*menubar*ppm_f.accelerator:	~CtrlG
control*menubar*ppm_w.labelString:	PPM, taille de la fenêtre
control*menubar*ppm_w.acceleratorText:	Ctrl+G
control*menubar*ppm_w.accelerator:	CtrlG
control*menubar*jpg_f.labelString:	JPEG, taille maximum
control*menubar*jpg_f.mnemonic:		J
control*menubar*jpg_f.acceleratorText:	J
control*menubar*jpg_f.accelerator:	~CtrlJ
control*menubar*jpg_w.labelString:	JPEG, taille de la fenêtre
control*menubar*jpg_w.acceleratorText:	Ctrl+J
control*menubar*jpg_w.accelerator:	CtrlJ

control*menubar*r_no.labelString:	pas de proportion
control*menubar*r_no.mnemonic:		n
control*menubar*r_43.labelString:	4:3
control*menubar*r_43.mnemonic:		4

control*menubar*s_off.labelString:	désactiver
control*menubar*s_150.labelString:	page 150
control*menubar*s_150.mnemonic:		1
control*menubar*s_333.labelString:	page 333
control*menubar*s_333.mnemonic:		3
control*menubar*s_777.labelString:	page 777
control*menubar*s_777.mnemonic:		7
control*menubar*s_801.labelString:	page 801
control*menubar*s_801.mnemonic:		0
control*menubar*s_888.labelString:	page 888
control*menubar*s_888.mnemonic:		8

! options menu
control*menubar*add.labelString:	Ajouter émetteur ...
control*menubar*add.mnemonic:		A
control*menubar*scan.labelString:	Rechercher émetteur ...
control*menubar*pref.labelString:	Preférences ...
control*menubar*pref.mnemonic:		P
control*menubar*save.labelString:	Sauver configuration
control*menubar*save.mnemonic:		S

control*menubar*capture.labelString:	Capturer
control*menubar*capture.mnemonic:	C
control*menubar*freq.labelString:	Table de fréquences
control*menubar*freq.mnemonic:		F
control*menubar*scale.labelString:	Echèlle ...
control*menubar*scale.mnemonic:		S
control*menubar*scale.acceleratorText:	S
control*menubar*scale.accelerator:	S

control*menubar*input.labelString:	Entrée
control*menubar*input.mnemonic:		I
control*menubar*norm.labelString:	Norme TV
control*menubar*norm.mnemonic:		N

! filter menu
control*menubar*fnone.labelString:	Pas de filtre
control*menubar*fnone.mnemonic:		N

! help menu
control*menubar*man.labelString:	Afficher la page de man
control*menubar*man.mnemonic:		m
control*menubar*about.labelString:	A propos ...
control*menubar*about.mnemonic:		A

! tooltips (needs openmotif 2.2)
control*tool.prev.toolTipString:	Emetteur précédent
control*tool.next.toolTipString:	Emetteur suivant
control*tool.snap.toolTipString:	Capture une image
control*tool.movie.toolTipString:	Enregistre un film
control*tool.mute.toolTipString:	Coupe le son
control*tool.exit.toolTipString:	Quitte

control*box.XmPushButton*menu.del.labelString:	Supprimer
control*box.XmPushButton*menu.edit.labelString:	Editer ...

! channel scan
*chscan_popup.title:		Rechercher un émetteur
*chscan_popup*okLabelString:	Commencer
*chscan_popup*hints.labelString:	\
	Vous pouvez me faire rechercher tous\n\
	les émetteurs disponibles ici. Ceci\n\
	va créer une nouvelle liste d'émetteurs\n\
	à partir de zéro, votre liste actuelle\n\
	sera perdue.\n\
	\n\
	Assurez-vous d'avoir choisi la bonne\n\
	norme TV et la table de fréquences\n\
	d'abord (c'est aussi dans le menu des\n\
	options), sinon la recherche ne\n\
	trouvera aucun émetteur...\n\
	\n

! channel properties
*prop_popup.title:			Editer émetteur
*prop_popup*rc.nameL.labelString:	Nom de l'émetteur
*prop_popup*rc.keyL.labelString:	Raccourci clavier
*prop_popup*rc.groupL.labelString:	[en] Group
*prop_popup*rc.channelL.labelString:	Emetteur
*prop_popup*rc.buttons.ok.labelString:	OK
*prop_popup*rc.buttons.cancel.labelString: Annuler
*prop_popup*no_name_popup.title:	Erreur
*prop_popup*no_name_popup*messageString: \
	Vous devez donner un nom à l'émetteur

! preferences
*pref_popup.title:			Preférences
*pref_popup*okLabelString:		Sauver
*pref_popup*fsL.labelString:		Plein écran
*pref_popup*fsT.labelString:		Permettre le changement de résolution
*pref_popup*fsO.labelString:		Résolution:
*pref_popup*mixL.labelString:		Volume (redémarrer motv pour appliquer)
*pref_popup*mixT.labelString:		Utilise le périphérique de mixage pour régler le volume
*pref_popup*mix1O.labelString:		périphérique de mixage:
*pref_popup*mix2O.labelString:		entrée de mixage:
*pref_popup*optL.labelString:		Options
*pref_popup*osd.labelString:		Utiliser la surimpression en mode plein écran
*pref_popup*keypad-ntsc.labelString:	pavé numérique : mode ntsc
*pref_popup*keypad-partial.labelString:	\
	pavé numérique : permettre partition (bascule sur la première touche)
*pref_popup*jpeg.label.labelString:	Qualité JPEG :

scale.title:				Contrôles d'échelle
scale*volume.titleString:		Volume
scale*bright.titleString:		Luminosité
scale*hue.titleString:			Hue
scale*color.titleString:		Saturation
scale*contrast.titleString:		Contraste

levels.title:				Moniteur
levels*enable.labelstring:		activer

streamer.title:				enregistrer un film
streamer*driverL.labelString:		Format de sortie
streamer*driver.labelString:		Pilote :
streamer*videoL.labelString:		Options video
streamer*video.labelString:		Format :
streamer*fpsL.labelString:		ips :
streamer*audioL.labelString:		Options audio
streamer*audio.labelString:		Format :
streamer*rateL.labelString:		Echantillonage :
streamer*fileL.labelString:		Noms des fichiers
streamer*fvideoL.labelString:		Video :
streamer*faudioL.labelString:		Audio :
streamer*status.labelString:		corrigez-moi

streamer*files.labelString:		Naviguer ...
streamer*buttons.rec.labelString:	Enregistrer
streamer*buttons.stop.labelString:	Arrêter
streamer*buttons.play.labelString:	Lire
streamer*buttons.cancel.labelString:	Fermer

MoTV.man_popup.title:			Page de manuel
MoTV.man_popup*okLabelString:		Fermer la fenêtre
MoTV.man_popup*label.labelString:	attendez svp ...

xawtv-3.106/x11/MoTV-it_IT.UTF-8000066400000000000000000000225051343350355000156720ustar00rootroot00000000000000! Mij 

! ----------------------------------------------------------------------------
! some standard motif stuff [i18n]

*.cancelLabelString:				Annulla
*.applyLabelString:				Applica
*.XmFileSelectionBox.dirListLabelString:	Directory
*.XmFileSelectionBox.fileListLabelString:	File
*.XmFileSelectionBox.selectionLabelString:	Seleziona


! ----------------------------------------------------------------------------
! strings [i18n]

MoTV.about_box_popup.title:		Info su motv
MoTV*about_box_popup*messageString:	\
	motv - Motif TV application	\n\
	\n\
	(c) 2002 Gerd Knorr 

MoTV.errbox_popup.title:		Errori

control*menubar*fileM.tearOffTitle:	File
control*menubar*editM.tearOffTitle:	Modifica
control*menubar*toolsM.tearOffTitle:	Strumenti
control*menubar*tuneM.tearOffTitle:	Sintonizzatore
control*menubar*grabM.tearOffTitle:	Cattura immagine
control*menubar*ratioM.tearOffTitle:	Aspetto
control*menubar*launchM.tearOffTitle:	Avvia
control*menubar*subM.tearOffTitle:	Sottotitoli
control*menubar*stationsM.tearOffTitle:	Stazioni TV
control*menubar*optionsM.tearOffTitle:	Opzioni
control*menubar*helpM.tearOffTitle:	Aiuto
control*menubar*captureM.tearOffTitle:	Cattura
control*menubar*freqM.tearOffTitle:	Frequency table
control*menubar*inputM.tearOffTitle:	Input
control*menubar*normM.tearOffTitle:	Protocollo TV

control*menubar.file.labelString:	File
control*menubar.file.mnemonic:		F
control*menubar.edit.labelString:	Modifica
control*menubar.edit.mnemonic:		M
control*menubar.tools.labelString:	Tools
control*menubar.tools.mnemonic:		T
control*menubar*tune.labelString:	Sintonizzatore
control*menubar*grab.labelString:	Cattura immagine
control*menubar*ratio.labelString:	Aspetto
control*menubar*launch.labelString:	Avvia
control*menubar*sub.labelString:	Sottotitoli
control*menubar.stations.labelString:	Stazioni
control*menubar.stations.mnemonic:	S
control*menubar.options.labelString:	Opzioni
control*menubar.options.mnemonic:	O
!control*menubar.filter.labelString:	Filter
!control*menubar.filter.mnemonic:	F
control*menubar.help.labelString:	Aiuto
control*menubar.help.mnemonic:		A

! file menu
control*menubar*rec.labelString:	Registra filmato ...
control*menubar*rec.mnemonic:		R
control*menubar*rec.acceleratorText:	R
control*menubar*rec.accelerator:	R
control*menubar*quit.labelString:	Esci
control*menubar*quit.mnemonic:		Q
control*menubar*quit.acceleratorText:	Q
control*menubar*quit.accelerator:	Q

! edit menu
control*menubar*copy.labelString:	Copia
control*menubar*copy.mnemonic:		C
control*menubar*copy.acceleratorText:	Ctrl+C
control*menubar*copy.accelerator:	CtrlC

! tools menu
control*menubar*mute.labelString:	Muto
control*menubar*mute.mnemonic:		a
control*menubar*mute.acceleratorText:	A
control*menubar*mute.accelerator:	A
control*menubar*full.labelString:	Fullscreen
control*menubar*full.mnemonic:		F
control*menubar*full.acceleratorText:	F
control*menubar*full.accelerator:	F
control*menubar*ontop.labelString:	Stay on Top
control*menubar*ontop.mnemonic:		T
control*menubar*ontop.acceleratorText:	T
control*menubar*ontop.accelerator:	T
!control*menubar*levels.labelString:	Record level monitor ...
!control*menubar*levels.mnemonic:	l
!control*menubar*levels.acceleratorText: L
!control*menubar*levels.accelerator:	L
control*menubar*st_up.labelString:	Stazione successiva
control*menubar*st_up.acceleratorText:	pagina su
control*menubar*st_dn.labelString:	Stazione precedente
control*menubar*st_dn.acceleratorText:	pagina giù

control*menubar*ch_up.labelString:	Canale Successivo
control*menubar*ch_up.acceleratorText:	su
control*menubar*ch_dn.labelString:	Canale precedente
control*menubar*ch_dn.acceleratorText:	giù
control*menubar*fi_up.labelString:	Sintonizzazione di precisione su
control*menubar*fi_up.acceleratorText:	destra
control*menubar*fi_dn.labelString:	Sintonizzazione di precisione giù
control*menubar*fi_dn.acceleratorText:	sinistra

control*menubar*ppm_f.labelString:	PPM, dimensione max
control*menubar*ppm_f.acceleratorText:	G
control*menubar*ppm_f.accelerator:	~CtrlG
control*menubar*ppm_w.labelString:	PPM, dimensione finestra
control*menubar*ppm_w.acceleratorText:	Ctrl+G
control*menubar*ppm_w.accelerator:	CtrlG
control*menubar*jpg_f.labelString:	JPEG, dimensione max
control*menubar*jpg_f.mnemonic:		J
control*menubar*jpg_f.acceleratorText:	J
control*menubar*jpg_f.accelerator:	~CtrlJ
control*menubar*jpg_w.labelString:	JPEG, dimensione finestra
control*menubar*jpg_w.acceleratorText:	Ctrl+J
control*menubar*jpg_w.accelerator:	CtrlJ

control*menubar*r_no.labelString:	non fisso
control*menubar*r_no.mnemonic:		n
control*menubar*r_43.labelString:	4:3
control*menubar*r_43.mnemonic:		4

control*menubar*s_off.labelString:	disabilita
control*menubar*s_150.labelString:	pagina 150
control*menubar*s_150.mnemonic:		1
control*menubar*s_333.labelString:	pagina 333
control*menubar*s_333.mnemonic:		3
control*menubar*s_777.labelString:	pagina 777
control*menubar*s_777.mnemonic:		7
control*menubar*s_801.labelString:	pagina 801
control*menubar*s_801.mnemonic:		0
control*menubar*s_888.labelString:	pagina 888
control*menubar*s_888.mnemonic:		8

! options menu
control*menubar*add.labelString:	Aggiungi stazione ...
control*menubar*add.mnemonic:		A
control*menubar*scan.labelString:	Scansiona canale ...
control*menubar*pref.labelString:	Preferenze ...
control*menubar*pref.mnemonic:		P
control*menubar*save.labelString:	Salva configurazione
control*menubar*save.mnemonic:		S

control*menubar*capture.labelString:	Cattura
control*menubar*capture.mnemonic:	C
control*menubar*freq.labelString:	Frequency table
control*menubar*freq.mnemonic:		F
control*menubar*scale.labelString:	Scala ...
control*menubar*scale.mnemonic:		S
control*menubar*scale.acceleratorText:	S
control*menubar*scale.accelerator:	S

control*menubar*input.labelString:	Input
control*menubar*input.mnemonic:		I
control*menubar*norm.labelString:	Protocollo TV
control*menubar*norm.mnemonic:		N

! filter menu
!control*menubar*fnone.labelString:	No filter
!control*menubar*fnone.mnemonic:	N

! help menu
control*menubar*man.labelString:	Mostra la manpage
control*menubar*man.mnemonic:		m
control*menubar*about.labelString:	Informazioni ...
control*menubar*about.mnemonic:		A

! tooltips (needs openmotif 2.2)
control*tool.prev.toolTipString:	Stazione precedente
control*tool.next.toolTipString:	Stazione successiva
control*tool.snap.toolTipString:	Cattura immagine
control*tool.movie.toolTipString:	Registra filmato
control*tool.mute.toolTipString:	Muto
control*tool.exit.toolTipString:	Esci

control*box.XmPushButton*menu.del.labelString:	Cancella
control*box.XmPushButton*menu.edit.labelString:	Modifica ...

! channel scan
*chscan_popup.title:		Scansiona canale
*chscan_popup*okLabelString:	Inizia
*chscan_popup*hints.labelString:	\
	COn questa opzione puoi lasciarmi\n\
	scansionare tutti i canali TV. Così\n\
	sarà creata una nuova lista canali\n\
	che sovrascriverà quella attuale.\n\
	\n\
	Prima assicurati di aver configurato\n\
	correttamente TV Norm e Frequency table\n\
	(vedi menu Opzioni), altrimenti la scansione\n\
	non individuerà alcuna stazione ...\n\
	\n

! channel properties
*prop_popup.title:			Modifica stazione
*prop_popup*rc.nameL.labelString:	Nome stazione
*prop_popup*rc.keyL.labelString:	Acceleratore
*prop_popup*rc.groupL.labelString:	[en] Group
*prop_popup*rc.channelL.labelString:	Canale
*prop_popup*rc.buttons.ok.labelString:	OK
*prop_popup*rc.buttons.cancel.labelString: Annulla
*prop_popup*no_name_popup.title:	Errore
*prop_popup*no_name_popup*messageString: \
	Devi specificare un nome per la stazione

! preferences
*pref_popup.title:			Preferenze
*pref_popup*okLabelString:		Salva
*pref_popup*fsL.labelString:		Fullscreen
*pref_popup*fsT.labelString:		Abilita lo switchng video
*pref_popup*fsO.labelString:		Modalità video:
*pref_popup*mixL.labelString:		Volume (necessario riavviare)
*pref_popup*mixT.labelString:		Usa il mixer per regolare il volume
*pref_popup*mix1O.labelString:		Periferica mixer:
*pref_popup*mix2O.labelString:		Controllo mixer:
*pref_popup*optL.labelString:		Opzioni
*pref_popup*osd.labelString:		Usa onscreen display in modalità fullscreen
*pref_popup*keypad-ntsc.labelString:	keypad: modalità ntsc
*pref_popup*keypad-partial.labelString:	\
	keypad: abilita parzialmente (cambia al primo tasto)
*pref_popup*jpeg.label.labelString:	Qaulità JPEG:

scale.title:				Controlli scala
scale*volume.titleString:		Volume
scale*bright.titleString:		Luminosità
scale*hue.titleString:			Tono
scale*color.titleString:		Saturazione
scale*contrast.titleString:		Contrasto

!levels.title:				Monitor
!levels*enable.labelstring:		enable

streamer.title:				registra filmato
streamer*driverL.labelString:		Formato
streamer*driver.labelString:		Driver:
streamer*videoL.labelString:		Opzioni video
streamer*video.labelString:		Formato:
streamer*fpsL.labelString:		fps:
streamer*audioL.labelString:		Opzioni audio
streamer*audio.labelString:		Formato:
streamer*rateL.labelString:		frequenza:
streamer*fileL.labelString:		Nome file
streamer*fvideoL.labelString:		Video:
streamer*faudioL.labelString:		Audio:
streamer*status.labelString:		fissa

streamer*files.labelString:		Naviga ...
streamer*buttons.rec.labelString:	Registra
streamer*buttons.stop.labelString:	Stop
streamer*buttons.play.labelString:	Playback
streamer*buttons.cancel.labelString:	Chiudi

MoTV.man_popup.title:			Manuale
MoTV.man_popup*okLabelString:		chiudi finestra
MoTV.man_popup*label.labelString:	Attendi ...

xawtv-3.106/x11/Subdir.mk000066400000000000000000000074231343350355000150750ustar00rootroot00000000000000
# targets to build
TARGETS-x11 := \
	x11/v4lctl

ifeq ($(FOUND_X11),yes)
TARGETS-x11 += \
	x11/propwatch \
	x11/xawtv-remote \
	x11/rootv \
	x11/xawtv \
	x11/pia
endif
ifeq ($(FOUND_MOTIF),yes)
TARGETS-x11 += \
	x11/motv
endif
ifeq ($(FOUND_OS)$(FOUND_MOTIF)$(FOUND_ZVBI),linuxyesyes)
TARGETS-x11 += \
	x11/mtt
endif

# objects for targets
x11/xawtv: \
	x11/xawtv.o \
	x11/wmhooks.o \
	x11/atoms.o \
	x11/x11.o \
	x11/blit.o \
	x11/xt.o \
	x11/xv.o \
	x11/toolbox.o \
	x11/conf.o \
	x11/complete-xaw.o \
	x11/vbi-x11.o \
	jwz/remote.o \
	common/channel.o \
	common/vbi-data.o \
	$(OBJS-common-alsa) \
	$(OBJS-common-input) \
	$(OBJS-common-capture)

x11/motv: \
	x11/motv.o \
	x11/man.o \
	x11/icons.o \
	x11/wmhooks.o \
	x11/atoms.o \
	x11/x11.o \
	x11/blit.o \
	x11/xt.o \
	x11/xv.o \
	x11/complete-motif.o \
	x11/vbi-x11.o \
	jwz/remote.o \
	common/channel-no-x11.o \
	common/vbi-data.o \
	$(OBJS-common-alsa) \
	$(OBJS-common-input) \
	$(OBJS-common-capture)

x11/mtt: \
	x11/mtt.o \
	x11/icons.o \
	x11/atoms.o \
	x11/vbi-x11.o \
	x11/vbi-gui.o \
	console/vbi-tty.o \
	console/fbtools.o \
	common/vbi-data.o \
	common/channel-no-x11.o \
	$(OBJS-common-capture)

x11/v4lctl: \
	x11/v4lctl.o \
	common/channel-no-x11.o \
	$(OBJS-common-capture)

ifeq ($(FOUND_X11),yes)
x11/v4lctl: \
	x11/atoms.o \
	x11/xv.o
endif

x11/rootv: \
	x11/rootv.o \
	x11/atoms.o \
	common/parseconfig.o

x11/pia: \
	x11/pia.o \
	x11/blit.o \
	libng/libng.a

x11/xawtv-remote: x11/xawtv-remote.o
x11/propwatch:    x11/propwatch.o

# libraries to link
x11/xawtv        : LDLIBS  += \
	$(THREAD_LIBS) $(CURSES_LIBS) $(LIRC_LIBS) $(ALSA_LIBS) \
	$(ATHENA_LIBS) $(VBI_LIBS) $(GL_LIBS) -ljpeg -lm -ldl -lfontconfig
x11/motv         : LDLIBS  += \
	$(THREAD_LIBS) $(CURSES_LIBS) $(LIRC_LIBS) $(ALSA_LIBS) \
	$(MOTIF_LIBS) $(VBI_LIBS) $(GL_LIBS) -ljpeg -lm -ldl
x11/mtt          : LDLIBS  += $(THREAD_LIBS) $(MOTIF_LIBS) $(VBI_LIBS) -ljpeg -ldl
x11/v4lctl       : LDLIBS  += $(THREAD_LIBS) $(ATHENA_LIBS) -ljpeg -lm -ldl
x11/pia          : LDLIBS  += $(ATHENA_LIBS) $(GL_LIBS) -ljpeg -lm -ldl
x11/rootv        : LDLIBS  += $(ATHENA_LIBS)
x11/xawtv-remote : LDLIBS  += $(ATHENA_LIBS)
x11/propwatch    : LDLIBS  += $(ATHENA_LIBS)

# linker flags
x11/xawtv        : LDFLAGS := $(DLFLAGS)
x11/motv         : LDFLAGS := $(DLFLAGS)
x11/mtt          : LDFLAGS := $(DLFLAGS)
x11/v4lctl       : LDFLAGS := $(DLFLAGS)
x11/pia          : LDFLAGS := $(DLFLAGS)

# compile flags
x11/complete-xaw.o   : CFLAGS += -DATHENA=1
x11/complete-motif.o : CFLAGS += -DMOTIF=1


# i18n
LANGUAGES := de_DE.UTF-8 fr_FR.UTF-8 it_IT.UTF-8
MOTV-app  := $(patsubst %,x11/MoTV.%.ad,$(LANGUAGES))


# local targets
x11/complete-xaw.o: x11/complete.c
	@$(echo_compile_c)
	@$(compile_c)
	@$(fixup_deps)

x11/complete-motif.o: x11/complete.c
	@$(echo_compile_c)
	@$(compile_c)
	@$(fixup_deps)


# global targets
all:: $(TARGETS-x11)
ifeq ($(FOUND_MOTIF),yes)
all:: $(MOTV-app)
endif

ifeq ($(FOUND_X11),yes)
install::
	$(INSTALL_PROGRAM) $(STRIP_FLAG) $(TARGETS-x11) $(bindir)
	$(INSTALL_DIR) $(resdir)/app-defaults
	$(INSTALL_DATA) $(srcdir)/x11/Xawtv.ad $(resdir)/app-defaults/Xawtv
endif
ifeq ($(FOUND_MOTIF),yes)
install:: $(patsubst %,install-motv-%,$(LANGUAGES))
	$(INSTALL_DATA) $(srcdir)/x11/mtt.ad $(resdir)/app-defaults/mtt
	$(INSTALL_DATA) x11/MoTV.ad $(resdir)/app-defaults/MoTV
endif

distclean::
	rm -f $(TARGETS-x11)
	rm -f $(MOTV-app) x11/MoTV.ad x11/MoTV.h x11/Xawtv.h x11/mtt.h

# special dependences / rules
x11/xawtv.o: x11/Xawtv.h
x11/motv.o: x11/MoTV.h
x11/mtt.o: x11/mtt.h

x11/MoTV.ad: $(srcdir)/x11/MoTV-default $(srcdir)/x11/MoTV-fixed
	cat $(srcdir)/x11/MoTV-default $(srcdir)/x11/MoTV-fixed > x11/MoTV.ad

x11/MoTV.%.ad: x11/MoTV-%
	cat $< $(srcdir)/x11/MoTV-fixed > $@

install-motv-%:
	$(INSTALL_DIR) $(resdir)/$*/app-defaults
	$(INSTALL_DATA) x11/MoTV.$*.ad $(resdir)/$*/app-defaults/MoTV
xawtv-3.106/x11/Xawtv.ad000066400000000000000000000416231343350355000147330ustar00rootroot00000000000000
! ----------------------------------------------------------------------------
! Strings

Xawtv*international:		true
Xawtv*fontSet:			\
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso10646-1, \
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso8859-* \
 -*-*-*-*--13-*-*-*-*-*-*-*,*

TopLevelShell*international:	true
TopLevelShell*fontSet:		\
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso10646-1, \
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso8859-* \
 -*-*-*-*--13-*-*-*-*-*-*-*,*

*popup_help.title:		Welcome to xawtv!
xawtv.tv.help: \
\n\
Copyright (c) 1997-2001 Gerd Knorr \n\
\n\
If nothing else works, read the manual.  xawtv has a fine\n\
manual page, check it out.  Some text files with additional\n\
documentation and hints for trouble shooting come with the\n\
source code.  If you have installed a binary package, these\n\
files should be somewhere in /usr/share/doc.\n\
\n\
Here is the most important for a quick start:\n\
\n\
The right mouse button (or the 'O' key) pops up a window,\n\
where you can adjust all important settings.  Becauce you\n\
probably don't want to do this every time you start xawtv,\n\
stick your settings into the config file ($HOME/.xawtv).\n\
\n\
Tuning works with the cursor keys.  Of cource you can put\n\
the TV-Stations into the config file too.  You can either\n\
use your favorite text editor or xawtv's new channel editor.\n\
\n\
Once you have created a config file, this message will no\n\
longer pop up automatically at startup.  You can get it\n\
with the 'H' key then.\n\
\n\
Hit Return to start watching TV...\n\
\n

Options*mute.label:		Audio (un)mute                  A
Options*fs.label:		Full Screen on/off              F
Options*grabppm.label:		Grab Image (ppm)                G
Options*grabjpeg.label:		Grab Image (jpeg)               J
Options*recavi.label:		Record Movie (avi)              R
Options*chanwin.label:		Channel Window                  C
Options*confwin.label:		Channel Editor                  E
Options*launchwin.label:	Launcher Window                 L
Options*zap.label:		Channel Hopping                 Z
Options*top.label:		Stay On Top                     T

Options*cap.label:		Capture            >
Options*norm.label:		TV norm            >
Options*input.label:		Video source       >
Options*freq.label:		Frequency table    >
Options*audio.label:		Audio              >
Options*quit.label:		Quit                            Q

!Options*auto.label:		autodetect
!Options*mono.label:		mono
!Options*stereo.label:		stereo
Options*lang1.label:		Language 1
Options*lang2.label:		Language 2

Options*bright.l.label:		Bright
Options*hue.l.label:		Hue
Options*contrast.l.label:	Contrast
Options*color.l.label:		Color
Options*volume.l.label:		Volume

Config*lchannel.label:		Channel
Config*lname.label:		Station ID
Config*lkey.label:		Hotkey
Config*add.label:		Add
Config*delete.label:		Delete
Config*modify.label:		Update
Config*save.label:		Save
Config*close.label:		Close

Streamer.title:			record a movie
Streamer*vlabel.label:		movie/images filename
Streamer*alabel.label:		*.wav filename
Streamer*streamer.label:	start/stop recording
Streamer*xanim.label:		playback (start pia)


! ----------------------------------------------------------------------------
! general settings

Xawtv*beNiceToColormap:			false
Xawtv*highlightThickness:		0

Xawtv*foreground:			black
Xawtv*background:			lightgray
Xawtv*justify:				left

Xawtv*menu.translations:		#override	\n\
	:	Autoscroll() highlight()

TopLevelShell*beNiceToColormap:		false
TopLevelShell*highlightThickness:	0

TopLevelShell*foreground:		black
TopLevelShell*background:		lightgray
TopLevelShell*justify:			left

TopLevelShell*menu.translations:	#override	\n\
	:	highlight()


! ----------------------------------------------------------------------------
! TV Window

xawtv.tv.width:			384
xawtv.tv.height:		288
xawtv.tv.background:		green
xawtv.winGravity:		Static
xawtv.translations:		#override			\n\
	:	Remote()			\n\
	WM_PROTOCOLS:	CloseMain()

xawtv.tv.background:		black
xawtv.tv.translations:		#override			\n\
	C:			Popup(channels)			\n\
	O:			Popup(options)			\n\
	H:			Help()				\n\
	E:			Popup(config)			\n\
	T:			StayOnTop()			\n\
	R:			Popup(streamer)			\n\
	L:			Popup(launcher)			\n\
	space:		Command(setstation,next)	\n\
	:		Channel()			\n\
	:		Command(setstation,next)	\n\
	:		Popup(options)			\n\
	Escape:		CloseMain()			\n\
	\
	Q:			CloseMain()			\n\
	KP_Add:		Command(volume,inc)		\n\
	KP_Subtract:	Command(volume,dec)		\n\
	KP_Enter:		Mute()				\n\
	A:			Mute()				\n\
	F:			Command(fullscreen)		\n\
	CtrlZ:		Zap(fast)			\n\
	Z:			Zap()				\n\
	CtrlG:		Command(snap,ppm,win)		\n\
	CtrlJ:		Command(snap,jpeg,win)		\n\
	G:			Command(snap,ppm,full)		\n\
	J:			Command(snap,jpeg,full)		\n\
	CtrlUp:		Scan()				\n\
	~CtrlUp:		Command(setchannel,next)	\n\
	Down:		Command(setchannel,prev)	\n\
	Right:		Command(setchannel,fine_up)	\n\
	Left:		Command(setchannel,fine_down)	\n\
	question:		Command(setstation,query)	\n\
	Page_Up:		Command(setstation,next)	\n\
	Page_Down:		Command(setstation,prev)	\n\
	BackSpace:		Command(setstation,back)	\n\
	:		Command(setstation,next)	\n\
	:		Command(setstation,prev)	\n\
	V:			Command(capture,toggle)		\n\
	D:			Command(showtime)		\n\
	\
	XF86AudioRaiseVolume: Command(volume,inc)		\n\
	XF86AudioLowerVolume: Command(volume,dec)		\n\
	XF86AudioMute:	Mute()				\n\
	XF86AudioNext:	Command(setstation,next)	\n\
	XF86AudioPrev:	Command(setstation,prev)	\n\
	XF86AudioPlay:	Command(capture,on)		\n\
	XF86AudioStop:	Command(capture,off)		\n\
	\
	F5:		Command(bright,dec)		\n\
	F6:		Command(bright,inc)		\n\
	F7:		Command(hue,dec)		\n\
	F8:		Command(hue,inc)		\n\
	F9:		Command(contrast,dec)		\n\
	F10:		Command(contrast,inc)		\n\
	F11:		Command(color,dec)		\n\
	F12:		Command(color,inc)		\n\
	\
	KP_0:		Command(keypad,0)		\n\
	KP_1:		Command(keypad,1)		\n\
	KP_2:		Command(keypad,2)		\n\
	KP_3:		Command(keypad,3)		\n\
	KP_4:		Command(keypad,4)		\n\
	KP_5:		Command(keypad,5)		\n\
	KP_6:		Command(keypad,6)		\n\
	KP_7:		Command(keypad,7)		\n\
	KP_8:		Command(keypad,8)		\n\
	KP_9:		Command(keypad,9)

! ----------------------------------------------------------------------------
! Options window

Options.paned.internalBorderWidth:	0
Options.paned*Scrollbar.orientation:	horizontal
Options.paned*Scrollbar.length:		150
Options.paned*Scrollbar.width:		150
Options.paned*Scrollbar.minimumThumb:	3
Options.paned*Scrollbar.displayList:		\
	fg gray50; lines +0,-1,+0,+0,-1,+0;	\
	fg white; lines +1,-1,-1,-1,-1,+1;

Options.paned.translations:	#override\n\
	Escape:		Popup(options)			\n\
	\
	Q:			CloseMain()			\n\
	KP_Add:		Command(volume,inc)		\n\
	KP_Subtract:	Command(volume,dec)		\n\
	KP_Enter:		Mute()				\n\
	A:			Mute()				\n\
	F:			Command(fullscreen)		\n\
	CtrlZ:		Zap(fast)			\n\
	Z:			Zap()				\n\
	CtrlG:		Command(snap,ppm,win)		\n\
	CtrlJ:		Command(snap,jpeg,win)		\n\
	G:			Command(snap,ppm,full)		\n\
	J:			Command(snap,jpeg,full)		\n\
	CtrlUp:		Scan()				\n\
	Up:		Command(setchannel,next)	\n\
	Down:		Command(setchannel,prev)	\n\
	Right:		Command(setchannel,fine_up)	\n\
	Left:		Command(setchannel,fine_down)	\n\
	Page_Up:		Command(setstation,next)	\n\
	Page_Down:		Command(setstation,prev)	\n\
	BackSpace:		Command(setstation,back)	\n\
	:		Command(setstation,next)	\n\
	:		Command(setstation,prev)	\n\
	V:			Command(capture,toggle)		\n\
	\
	XF86AudioRaiseVolume: Command(volume,inc)		\n\
	XF86AudioLowerVolume: Command(volume,dec)		\n\
	XF86AudioMute:	Mute()				\n\
	XF86AudioNext:	Command(setstation,next)	\n\
	XF86AudioPrev:	Command(setstation,prev)	\n\
	XF86AudioPlay:	Command(capture,on)		\n\
	XF86AudioStop:	Command(capture,off)

Options*Command.testcolor:	red
Options*Command.translations:	#override			\n\
	:	set-values(true,displayList,		\
		"fg white; lines +0,-1,+0,+0,-1,+0; 		\
		 fg gray50; lines +1,-1,-1,-1,-1,+1; ")		\n\
	:	set-values(true,displayList,"")

! ----------------------------------------------------------------------------
! Streamer frontend window

Streamer*Label.width:		360
Streamer*Label.resize:		false
Streamer*Label.borderWidth:	0
Streamer*Text.width:		360
Streamer*Text*background:	white
Streamer*Text*Scrollbar.background: lightgray
Streamer*Text*autoFill:		false
Streamer*Text*editType:		edit
!Streamer*Text*type:		string
Streamer*Text*useStringInPlace:	false
Streamer*status.foreground:	darkred

Streamer*driver.vertDistance:	10
Streamer*vlabel.vertDistance:	15
Streamer*vname.vertDistance:	0
Streamer*alabel.vertDistance:	15
Streamer*aname.vertDistance:	0
Streamer*audio.vertDistance:	5
Streamer*rate.vertDistance:	0
Streamer*video.vertDistance:	5
Streamer*fps.vertDistance:	0
Streamer*size.vertDistance:	0
Streamer*status.vertDistance:	5
Streamer*streamer.vertDistance:	5
Streamer*xanim.vertDistance:	5

Streamer*vname.translations:	#override			\n\
	Tab:		Complete()			\n\
	:		set-values(1,background,lightyellow) \n\
	:		set-values(1,background,white)
Streamer*aname.translations:	#override			\n\
	Tab:		Complete()			\n\
	:		set-values(1,background,lightyellow) \n\
	:		set-values(1,background,white)

Streamer*Command.width:		360
Streamer*Command.resize:	false
Streamer*Command.justify:	left
Streamer*Command.borderWidth:	0
Streamer*Command.translations:	#override			\n\
	:	set-values(true,displayList,		\
		"fg white; lines +0,-1,+0,+0,-1,+0; 		\
		 fg gray50; lines +1,-1,-1,-1,-1,+1; ")		\n\
	:	set-values(true,displayList,"")

Streamer*streamer.borderWidth:	0
Streamer*streamer.justify:	center
Streamer*streamer.translations:	#override			\n\
	:		set-values(1,background,white)	\n\
	:		set-values(1,background,lightgray)
Streamer*streamer.displayList:			\
	fg white; lines +0,-1,+0,+0,-1,+0;	\
	fg gray50; lines +1,-1,-1,-1,-1,+1;

Streamer*xanim.borderWidth:	0
Streamer*xanim.justify:		center
Streamer*xanim.translations:	#override			\n\
	:		set-values(1,background,white)	\n\
	:		set-values(1,background,lightgray)
Streamer*xanim.displayList:			\
	fg white; lines +0,-1,+0,+0,-1,+0;	\
	fg gray50; lines +1,-1,-1,-1,-1,+1;

Streamer.form.translations:	#override\n\
	Escape:		Popup(streamer)

! ----------------------------------------------------------------------------
! Channel window

Channels.viewport.useRight:				true
Channels.viewport.channelbox.hSpace:			0
Channels.viewport.channelbox.vSpace:			0
Channels.viewport.channelbox.background:		black
Channels.viewport.channelbox.Command.justify:		center
Channels.viewport.channelbox.Command.foreground:	yellow
Channels.viewport.channelbox.Command.background:	black

Channels.viewport.translations:	#override\n\
	Escape:		Popup(channels)			\n\
								\
	Q:			CloseMain()			\n\
	KP_Add:		Command(volume,inc)		\n\
	KP_Subtract:	Command(volume,dec)		\n\
	KP_Enter:		Mute()				\n\
	A:			Mute()				\n\
	F:			Command(fullscreen)		\n\
	CtrlZ:		Zap(fast)			\n\
	Z:			Zap()				\n\
	CtrlG:		Command(snap,ppm,win)		\n\
	CtrlJ:		Command(snap,jpeg,win)		\n\
	G:			Command(snap,ppm,full)		\n\
	J:			Command(snap,jpeg,full)		\n\
	CtrlUp:		Scan()				\n\
	Up:		Command(setchannel,next)	\n\
	Down:		Command(setchannel,prev)	\n\
	Right:		Command(setchannel,fine_up)	\n\
	Left:		Command(setchannel,fine_down)	\n\
	Page_Up:		Command(setstation,next)	\n\
	Page_Down:		Command(setstation,prev)	\n\
	BackSpace:		Command(setstation,back)	\n\
	:		Command(setstation,next)	\n\
	:		Command(setstation,prev)	\n\
	V:			Command(capture,toggle)		\n\
	\
	XF86AudioRaiseVolume: Command(volume,inc)		\n\
	XF86AudioLowerVolume: Command(volume,dec)		\n\
	XF86AudioMute:	Mute()				\n\
	XF86AudioNext:	Command(setstation,next)	\n\
	XF86AudioPrev:	Command(setstation,prev)	\n\
	XF86AudioPlay:	Command(capture,on)		\n\
	XF86AudioStop:	Command(capture,off)

! ----------------------------------------------------------------------------
! onscreen + vtx window

xawtv.onscreen.allowShellResize:	true
xawtv.onscreen.label.resize:		true

xawtv.onscreen*background:		black
xawtv.onscreen*borderColor:		black
xawtv.onscreen*foreground:		lightgreen
xawtv.onscreen.label.justify:		left
xawtv.onscreen.label.fontSet:		\
 -misc-fixed-medium-r-normal--20-*-*-*-*-*-iso10646-1, \
 -misc-fixed-medium-r-normal--20-*-*-*-*-*-iso8859-* \
 -*-*-*-*--20-*-*-*-*-*-*-*,*

xawtv.vtx.allowShellResize:		true
xawtv.vtx.label.resize:			true

xawtv.vtx*background:			black
xawtv.vtx*borderColor:			black
xawtv.vtx*foreground:			lightgreen
xawtv.vtx.label.justify:		center


! ----------------------------------------------------------------------------
! Config window

Config.translations:		#override			\n\
	WM_PROTOCOLS:	Popup(config)

Config*Label.width:		120
Config*Label.resize:		false
Config*Label.borderWidth:	0
Config*Command.width:		120
Config*Command.justify:		center
Config*Text*width:		120
!Config*Text*resize:		false
Config*Text*autoFill:		false
Config*Text*editType:		edit
!Config*Text*type:		string
Config*Text*useStringInPlace:	false
Config*Text*background:		white

Config*channel.borderWidth:	1
Config*channel.background:	white
Config*lname.vertDistance:	15
Config*lkey.vertDistance:	15
Config*key.borderWidth:		1
Config*key.background:		white
Config*add.vertDistance:	15

Config*viewport.width:		120
Config*viewport.height:		300
Config*viewport.allowVert:	true
Config*viewport.allowHoriz:	false
Config*viewport.resize:		false

Config*list.defaultColumns:	1
Config*list.forceColumns:	true
Config*list.background:		white

Config.form.translations:	#override			\n\
	Escape:		Popup(config)

Config*modify.accelerators:	#override			\n\
	Return:		set()notify()unset()		\n\

Config*Command.borderWidth:	0
Config*Command.translations:	#override			\n\
	:		set-values(1,background,white)	\n\
	:		set-values(1,background,lightgray)
Config*Command.displayList:			\
	fg white; lines +0,-1,+0,+0,-1,+0;	\
	fg gray50; lines +1,-1,-1,-1,-1,+1;

Config*channel.translations:	#override			\n\
	CtrlUp:		Scan()				\n\
	Up:		Command(setchannel,next)	\n\
	Down:		Command(setchannel,prev)	\n\
	Right:		Command(setchannel,fine_up)	\n\
	Left:		Command(setchannel,fine_down)	\n\
	:		set-values(1,background,lightyellow) \n\
	:		set-values(1,background,white)
Config*name.translations:	#override			\n\
	:		set-values(1,background,lightyellow) \n\
	:		set-values(1,background,white)
Config*key.translations:	#override			\n\
	:		set-values(1,background,lightyellow) \n\
	:		set-values(1,background,white)
Config*list.translations:	#override			\n\
	:		set-values(1,background,lightyellow) \n\
	:		set-values(1,background,white)	\n\
	Up:		Command(setstation,prev)	\n\
	Down:		Command(setstation,next)


!--------------------------------------------------------------------------
! Launcher

Launcher.paned.internalBorderWidth: 0
Launcher.paned.translations:	#override			\n\
	Escape:		Popup(launcher)

Launcher*Command.translations:	#override			\n\
	:	set-values(true,displayList,		\
		"fg white; lines +0,-1,+0,+0,-1,+0; 		\
		 fg gray50; lines +1,-1,-1,-1,-1,+1; ")		\n\
	:	set-values(true,displayList,"")


!--------------------------------------------------------------------------
! help window

Xawtv*popup_help.help.ok.justify:	center

*popup_help.help.ok.borderWidth:	0
*popup_help.help.ok.width:		100
*popup_help.help.ok.label:		OK
*popup_help.help.ok.accelerators:	#override		\n\
	Q:			set()notify()unset()		\n\
	Return:		set()notify()unset()		\n\
	Escape:		set()notify()unset()
*popup_help.help.ok.translations:	#override		\n\
	:		set-values(1,background,white)	\n\
	:		set-values(1,background,lightgray)
*popup_help.help.ok.displayList:		\
	fg white; lines +0,-1,+0,+0,-1,+0;	\
	fg gray50; lines +1,-1,-1,-1,-1,+1;


! ----------------------------------------------------------------------------
! File dialog

Xawtv*Dialog.value.background:	white
Xawtv*Dialog.Command.justify:	center
Xawtv*Dialog.Command.width:	100
Xawtv*Dialog.label.justify:	left

*Dialog.ok.label:		OK
*Dialog.cancel.label:		Cancel

!*Dialog.label.width:		300
*Dialog.value.width:		300
*Dialog*resizable:		True
*Dialog.Command.translations:	#override			\n\
	:		set-values(1,background,white)	\n\
	:		set-values(1,background,lightgray)
*Dialog.ok.accelerators:	#override \n\
	Return: set()notify()unset()
*Dialog.cancel.accelerators:	#override \n\
	Escape: set()notify()unset()
*Dialog.value.translations:	#override \n\
	Tab: Complete()
xawtv-3.106/x11/atoms.c000066400000000000000000000057241343350355000146050ustar00rootroot00000000000000
#include 
#include "atoms.h"

/* window manager */
Atom WM_PROTOCOLS;
Atom WM_DELETE_WINDOW;

Atom _NET_SUPPORTED;
Atom _NET_WM_STATE;
Atom _NET_WM_STATE_STAYS_ON_TOP;
Atom _NET_WM_STATE_ABOVE;
Atom _NET_WM_STATE_FULLSCREEN;
Atom _WIN_SUPPORTING_WM_CHECK;
Atom _WIN_PROTOCOLS;
Atom _WIN_LAYER;

/* ipc: xawtv, xscreensaver */
Atom _XAWTV_STATION;
Atom _XAWTV_REMOTE;

Atom XA_DEACTIVATE;

/* selections / dnd */
Atom _MOTIF_CLIPBOARD_TARGETS;
Atom _MOTIF_DEFERRED_CLIPBOARD_TARGETS;
Atom _MOTIF_SNAPSHOT;
Atom _MOTIF_DROP;
Atom _MOTIF_EXPORT_TARGETS;
Atom _MOTIF_LOSE_SELECTION;

Atom XA_TARGETS;
Atom XA_DONE;
Atom XA_CLIPBOARD;
Atom XA_UTF8_STRING;
Atom XA_FILE_NAME;
Atom XA_FILE;
Atom XA_PIXEL;
Atom XA_BACKGROUND;
Atom XA_FOREGROUND;

Atom MIME_TEXT_ISO8859_1;
Atom MIME_TEXT_UTF_8;

Atom MIME_IMAGE_PPM;
Atom MIME_IMAGE_JPEG;

Atom MIME_TEXT_URI_LIST;
Atom _NETSCAPE_URL;

/* Xvideo */
Atom XV_MUTE;
Atom XV_ENCODING;
Atom XV_FREQ;
Atom XV_COLORKEY;

#define INIT_ATOM(dpy,atom) atom = XInternAtom(dpy,#atom,False)

void init_atoms(Display *dpy)
{
    INIT_ATOM(dpy, WM_PROTOCOLS);
    INIT_ATOM(dpy, WM_DELETE_WINDOW);
    INIT_ATOM(dpy, _NET_SUPPORTED);
    INIT_ATOM(dpy, _NET_WM_STATE);
    INIT_ATOM(dpy, _NET_WM_STATE_STAYS_ON_TOP);
    INIT_ATOM(dpy, _NET_WM_STATE_ABOVE);
    INIT_ATOM(dpy, _NET_WM_STATE_FULLSCREEN);
    INIT_ATOM(dpy, _WIN_SUPPORTING_WM_CHECK);
    INIT_ATOM(dpy, _WIN_PROTOCOLS);
    INIT_ATOM(dpy, _WIN_LAYER);

    INIT_ATOM(dpy, _NETSCAPE_URL);

    INIT_ATOM(dpy, _XAWTV_STATION);
    INIT_ATOM(dpy, _XAWTV_REMOTE);

    INIT_ATOM(dpy, XV_MUTE);
    INIT_ATOM(dpy, XV_ENCODING);
    INIT_ATOM(dpy, XV_FREQ);
    INIT_ATOM(dpy, XV_COLORKEY);

    INIT_ATOM(dpy, _MOTIF_CLIPBOARD_TARGETS);
    INIT_ATOM(dpy, _MOTIF_DEFERRED_CLIPBOARD_TARGETS);
    INIT_ATOM(dpy, _MOTIF_SNAPSHOT);
    INIT_ATOM(dpy, _MOTIF_DROP);
    INIT_ATOM(dpy, _MOTIF_EXPORT_TARGETS);
    INIT_ATOM(dpy, _MOTIF_LOSE_SELECTION);

    XA_DEACTIVATE      = XInternAtom(dpy, "DEACTIVATE",       False);

    XA_TARGETS         = XInternAtom(dpy, "TARGETS",          False);
    XA_DONE            = XInternAtom(dpy, "DONE",             False);
    XA_CLIPBOARD       = XInternAtom(dpy, "CLIPBOARD",        False);
    XA_UTF8_STRING     = XInternAtom(dpy, "UTF8_STRING",      False);
    XA_FILE_NAME       = XInternAtom(dpy, "FILE_NAME",        False);
    XA_FILE            = XInternAtom(dpy, "FILE",             False);
    XA_BACKGROUND      = XInternAtom(dpy, "BACKGROUND",       False);
    XA_FOREGROUND      = XInternAtom(dpy, "FOREGROUND",       False);
    XA_PIXEL           = XInternAtom(dpy, "PIXEL",            False);

    MIME_TEXT_ISO8859_1 =
	XInternAtom(dpy, "text/plain;charset=ISO-8859-1", False);
    MIME_TEXT_UTF_8 =
	XInternAtom(dpy, "text/plain;charset=UTF-8", False);

    MIME_IMAGE_PPM     = XInternAtom(dpy, "image/ppm",        False);
    MIME_IMAGE_JPEG    = XInternAtom(dpy, "image/jpeg",       False);

    MIME_TEXT_URI_LIST = XInternAtom(dpy, "text/uri-list",    False);
}
xawtv-3.106/x11/atoms.h000066400000000000000000000023121343350355000146000ustar00rootroot00000000000000
void init_atoms(Display *dpy);

/* window manager */
extern Atom WM_PROTOCOLS;
extern Atom WM_DELETE_WINDOW;

extern Atom _NET_SUPPORTED;
extern Atom _NET_WM_STATE;
extern Atom _NET_WM_STATE_STAYS_ON_TOP;
extern Atom _NET_WM_STATE_ABOVE;
extern Atom _NET_WM_STATE_FULLSCREEN;
extern Atom _WIN_SUPPORTING_WM_CHECK;
extern Atom _WIN_PROTOCOLS;
extern Atom _WIN_LAYER;

/* ipc: xawtv, xscreensaver */
extern Atom _XAWTV_STATION;
extern Atom _XAWTV_REMOTE;

extern Atom XA_DEACTIVATE;

/* selections / dnd */
extern Atom _MOTIF_CLIPBOARD_TARGETS;
extern Atom _MOTIF_DEFERRED_CLIPBOARD_TARGETS;
extern Atom _MOTIF_SNAPSHOT;
extern Atom _MOTIF_DROP;
extern Atom _MOTIF_EXPORT_TARGETS;
extern Atom _MOTIF_LOSE_SELECTION;

extern Atom XA_TARGETS;
extern Atom XA_DONE;
extern Atom XA_CLIPBOARD;
extern Atom XA_UTF8_STRING;
extern Atom XA_FILE_NAME;
extern Atom XA_FILE;
extern Atom XA_PIXEL;
extern Atom XA_BACKGROUND;
extern Atom XA_FOREGROUND;

extern Atom MIME_TEXT_ISO8859_1;
extern Atom MIME_TEXT_UTF_8;

extern Atom MIME_IMAGE_PPM;
extern Atom MIME_IMAGE_JPEG;

extern Atom MIME_TEXT_URI_LIST;
extern Atom _NETSCAPE_URL;

/* Xvideo */
extern Atom XV_MUTE;
extern Atom XV_ENCODING;
extern Atom XV_FREQ;
extern Atom XV_COLORKEY;

xawtv-3.106/x11/blit.c000066400000000000000000000620211343350355000144050ustar00rootroot00000000000000/*
 * x11 helper functions -- blit frames to the screen
 *
 */

#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#ifdef HAVE_LIBXV
# include 
# include 
#endif

#if HAVE_GL
# include 
# include 
#endif

#include "grab-ng.h"
#include "blit.h"

/* ------------------------------------------------------------------------ */

extern XtAppContext    app_context;
extern int             debug;

unsigned int           x11_dpy_fmtid;

static int             display_bits = 0;
static unsigned int    display_bytes = 0;
static unsigned int    pixmap_bytes = 0;
static int             x11_byteswap = 0;
static int             no_mitshm = 0;
static int             gl_error = 0;

#if HAVE_LIBXV
static int             ver, rel, req, ev, err;
static int             formats;
static int             adaptors;
static XvImageFormatValues  *fo;
static XvAdaptorInfo        *ai;
#endif

static unsigned int    im_adaptor,im_port = UNSET;
static unsigned int    im_formats[VIDEO_FMT_COUNT];

static struct SEARCHFORMAT {
    unsigned int   depth;
    int            order;
    unsigned long  red;
    unsigned long  green;
    unsigned long  blue;
    unsigned int   format;
} fmt[] = {
    { 2, MSBFirst, 0x7c00,     0x03e0,     0x001f,     VIDEO_RGB15_BE },
    { 2, MSBFirst, 0xf800,     0x07e0,     0x001f,     VIDEO_RGB16_BE },
    { 2, LSBFirst, 0x7c00,     0x03e0,     0x001f,     VIDEO_RGB15_LE },
    { 2, LSBFirst, 0xf800,     0x07e0,     0x001f,     VIDEO_RGB16_LE },

    { 3, LSBFirst, 0x00ff0000, 0x0000ff00, 0x000000ff, VIDEO_BGR24    },
    { 3, LSBFirst, 0x000000ff, 0x0000ff00, 0x00ff0000, VIDEO_RGB24    },
    { 3, MSBFirst, 0x00ff0000, 0x0000ff00, 0x000000ff, VIDEO_RGB24    },
    { 3, MSBFirst, 0x000000ff, 0x0000ff00, 0x00ff0000, VIDEO_BGR24    },

    { 4, LSBFirst, 0x00ff0000, 0x0000ff00, 0x000000ff, VIDEO_BGR32    },
    { 4, LSBFirst, 0x0000ff00, 0x00ff0000, 0xff000000, VIDEO_RGB32    },
    { 4, MSBFirst, 0x00ff0000, 0x0000ff00, 0x000000ff, VIDEO_RGB32    },
    { 4, MSBFirst, 0x0000ff00, 0x00ff0000, 0xff000000, VIDEO_BGR32    },

    { 2, -1,       0,          0,          0,          VIDEO_LUT2     },
    { 4, -1,       0,          0,          0,          VIDEO_LUT4     },
    { 0 /* END OF LIST */ },
};

static int
catch_no_mitshm(Display * dpy, XErrorEvent * event)
{
    no_mitshm++;
    return 0;
}

static int
catch_gl_error(Display * dpy, XErrorEvent * event)
{
    fprintf(stderr,"WARNING: Your OpenGL setup is broken.\n");
    gl_error++;
    return 0;
}

/* ------------------------------------------------------------------------ */
/* plain X11 stuff                                                          */

Visual*
x11_find_visual(Display *dpy)
{
    XVisualInfo  *info, template;
    Visual*      vi = CopyFromParent;
    int          found,i;
    char         *class;

    template.screen = XDefaultScreen(dpy);
    info = XGetVisualInfo(dpy, VisualScreenMask,&template,&found);
    for (i = 0; i < found; i++) {
	switch (info[i].class) {
	case StaticGray:   class = "StaticGray";  break;
	case GrayScale:    class = "GrayScale";   break;
	case StaticColor:  class = "StaticColor"; break;
	case PseudoColor:  class = "PseudoColor"; break;
	case TrueColor:    class = "TrueColor";   break;
	case DirectColor:  class = "DirectColor"; break;
	default:           class = "UNKNOWN";     break;
	}
	if (debug)
	    fprintf(stderr,"visual: id=0x%lx class=%d (%s), depth=%d\n",
		    info[i].visualid,info[i].class,class,info[i].depth);
    }
    for (i = 0; vi == CopyFromParent && i < found; i++)
	if (info[i].class == TrueColor && info[i].depth >= 15)
	    vi = info[i].visual;
    for (i = 0; vi == CopyFromParent && i < found; i++)
	if (info[i].class == StaticGray && info[i].depth == 8)
	    vi = info[i].visual;
    return vi;
}

void
x11_init_visual(Display *dpy, XVisualInfo *vinfo)
{
    XPixmapFormatValues *pf;
    int                  i,n;
    int                  format = 0;

    if (!XShmQueryExtension(dpy))
	no_mitshm = 1;

    display_bits = vinfo->depth;
    display_bytes = (display_bits+7)/8;

    pf = XListPixmapFormats(dpy,&n);
    for (i = 0; i < n; i++)
	if (pf[i].depth == display_bits)
	    pixmap_bytes = pf[i].bits_per_pixel/8;

    if (debug) {
	fprintf(stderr,"x11: color depth: "
		"%d bits, %d bytes - pixmap: %d bytes\n",
		display_bits,display_bytes,pixmap_bytes);
	if (vinfo->class == TrueColor || vinfo->class == DirectColor)
	    fprintf(stderr, "x11: color masks: "
		    "red=0x%08lx green=0x%08lx blue=0x%08lx\n",
		    vinfo->red_mask, vinfo->green_mask, vinfo->blue_mask);
	fprintf(stderr,"x11: server byte order: %s\n",
		ImageByteOrder(dpy)==LSBFirst ? "little endian":"big endian");
	fprintf(stderr,"x11: client byte order: %s\n",
		BYTE_ORDER==LITTLE_ENDIAN ? "little endian":"big endian");
    }
    if (ImageByteOrder(dpy)==LSBFirst && BYTE_ORDER!=LITTLE_ENDIAN)
	x11_byteswap=1;
    if (ImageByteOrder(dpy)==MSBFirst && BYTE_ORDER!=BIG_ENDIAN)
	x11_byteswap=1;
    if (vinfo->class == TrueColor /* || vinfo->class == DirectColor */) {
	/* pixmap format */
	for (i = 0; fmt[i].depth > 0; i++) {
	    if (fmt[i].depth  == pixmap_bytes                               &&
		(fmt[i].order == ImageByteOrder(dpy) || fmt[i].order == -1) &&
		(fmt[i].red   == vinfo->red_mask     || fmt[i].red   == 0)  &&
		(fmt[i].green == vinfo->green_mask   || fmt[i].green == 0)  &&
		(fmt[i].blue  == vinfo->blue_mask    || fmt[i].blue  == 0)) {
		x11_dpy_fmtid = fmt[i].format;
		break;
	    }
	}
	if (fmt[i].depth == 0) {
	    fprintf(stderr, "Huh?\n");
	    exit(1);
	}
	ng_lut_init(vinfo->red_mask, vinfo->green_mask, vinfo->blue_mask,
		    x11_dpy_fmtid,x11_byteswap);
	/* guess physical screen format */
	if (ImageByteOrder(dpy) == MSBFirst) {
	    switch (pixmap_bytes) {
	    case 2: format = (display_bits==15) ?
			VIDEO_RGB15_BE : VIDEO_RGB16_BE; break;
	    case 3: format = VIDEO_RGB24; break;
	    case 4: format = VIDEO_RGB32; break;
	    }
	} else {
	    switch (pixmap_bytes) {
	    case 2: format = (display_bits==15) ?
			VIDEO_RGB15_LE : VIDEO_RGB16_LE; break;
	    case 3: format = VIDEO_BGR24; break;
	    case 4: format = VIDEO_BGR32; break;
	    }
	}
    }
    if (vinfo->class == StaticGray && vinfo->depth == 8) {
	format = VIDEO_GRAY;
    }
    if (0 == format) {
	if (vinfo->class == PseudoColor && vinfo->depth == 8) {
	    fprintf(stderr,
"\n"
"8-bit Pseudocolor Visual (256 colors) is *not* supported.\n"
"You can startup X11 either with 15 bpp (or more)...\n"
"	xinit -- -bpp 16\n"
"... or with StaticGray visual:\n"
"	xinit -- -cc StaticGray\n"
	    );
	} else {
	    fprintf(stderr, "Sorry, I can't handle your strange display\n");
	}
	exit(1);
    }
    x11_dpy_fmtid = format;
}

XImage*
x11_create_ximage(Display *dpy, XVisualInfo *vinfo,
		  int width, int height, XShmSegmentInfo **shm)
{
    XImage          *ximage = NULL;
    unsigned char   *ximage_data;
    XShmSegmentInfo *shminfo = NULL;
    void            *old_handler;

    if (no_mitshm)
	goto no_mitshm;

    assert(width > 0 && height > 0);

    old_handler = XSetErrorHandler(catch_no_mitshm);
    shminfo = malloc(sizeof(XShmSegmentInfo));
    memset(shminfo, 0, sizeof(XShmSegmentInfo));
    ximage = XShmCreateImage(dpy,vinfo->visual,vinfo->depth,
			     ZPixmap, NULL,
			     shminfo, width, height);
    if (NULL == ximage)
	goto shm_error;
    shminfo->shmid = shmget(IPC_PRIVATE,
			    ximage->bytes_per_line * ximage->height,
			    IPC_CREAT | 0777);
    if (-1 == shminfo->shmid) {
	perror("shmget [x11]");
	goto shm_error;
    }
    shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
    if ((void *)-1 == shminfo->shmaddr) {
	perror("shmat");
	goto shm_error;
    }
    ximage->data = shminfo->shmaddr;
    shminfo->readOnly = False;

    XShmAttach(dpy, shminfo);
    XSync(dpy, False);
    if (no_mitshm)
	goto shm_error;
    shmctl(shminfo->shmid, IPC_RMID, 0);
    XSetErrorHandler(old_handler);
    *shm = shminfo;
    return ximage;

 shm_error:
    if (ximage) {
	XDestroyImage(ximage);
	ximage = NULL;
    }
    if ((void *)-1 != shminfo->shmaddr  &&  NULL != shminfo->shmaddr)
	shmdt(shminfo->shmaddr);
    free(shminfo);
    XSetErrorHandler(old_handler);
    no_mitshm = 1;

 no_mitshm:
    *shm = NULL;
    if (NULL == (ximage_data = malloc(width * height * pixmap_bytes))) {
	fprintf(stderr,"out of memory\n");
	exit(1);
    }
    ximage = XCreateImage(dpy, vinfo->visual, vinfo->depth,
			  ZPixmap, 0, ximage_data,
			  width, height,
			  8, 0);
    memset(ximage->data, 0, ximage->bytes_per_line * ximage->height);
    return ximage;
}

void
x11_destroy_ximage(Display *dpy, XImage *ximage, XShmSegmentInfo *shm)
{
    if (shm && !no_mitshm) {
	XShmDetach(dpy, shm);
	XDestroyImage(ximage);
	shmdt(shm->shmaddr);
	free(shm);
    } else
	XDestroyImage(ximage);
}

void x11_blit(Display *dpy, Drawable dr, GC gc, XImage *xi,
	      int a, int b, int c, int d, int w, int h)
{
    if (no_mitshm)
	XPutImage(dpy,dr,gc,xi,a,b,c,d,w,h);
    else
	XShmPutImage(dpy,dr,gc,xi,a,b,c,d,w,h,True);
}

Pixmap
x11_create_pixmap(Display *dpy, XVisualInfo *vinfo, struct ng_video_buf *buf)
{
    Pixmap          pixmap;
    XImage          *ximage;
    GC              gc;
    XShmSegmentInfo *shm;
    Screen          *scr = DefaultScreenOfDisplay(dpy);

    pixmap = XCreatePixmap(dpy,RootWindowOfScreen(scr),
			   buf->fmt.width, buf->fmt.height, vinfo->depth);

    gc = XCreateGC(dpy, pixmap, 0, NULL);

    if (NULL == (ximage = x11_create_ximage(dpy, vinfo, buf->fmt.width,
					    buf->fmt.height, &shm))) {
	XFreePixmap(dpy, pixmap);
	XFreeGC(dpy, gc);
	return 0;
    }
    memcpy(ximage->data,buf->data,buf->size);
    x11_blit(dpy, pixmap, gc, ximage, 0, 0, 0, 0,
	     buf->fmt.width, buf->fmt.height);
    x11_destroy_ximage(dpy, ximage, shm);
    XFreeGC(dpy, gc);
    return pixmap;
}

/* ------------------------------------------------------------------------ */
/* XVideo extention code                                                    */

#ifdef HAVE_LIBXV
void xv_image_init(Display *dpy)
{
    int i;

    if (Success != XvQueryExtension(dpy,&ver,&rel,&req,&ev,&err)) {
	if (debug)
	    fprintf(stderr,"Xvideo: Server has no Xvideo extention support\n");
	return;
    }
    if (Success != XvQueryAdaptors(dpy,DefaultRootWindow(dpy),&adaptors,&ai)) {
	fprintf(stderr,"Xvideo: XvQueryAdaptors failed");
	return;
    }
    for (i = 0; i < adaptors; i++) {
	if ((ai[i].type & XvInputMask) &&
	    (ai[i].type & XvImageMask) &&
	    (im_port == UNSET)) {
	    im_port = ai[i].base_id;
	    im_adaptor = i;
	}
    }
    if (UNSET == im_port)
	return;

    fo = XvListImageFormats(dpy, im_port, &formats);
    for(i = 0; i < formats; i++) {
	if (debug)
	    fprintf(stderr, "blit: xv: 0x%x (%c%c%c%c) %s",
		    fo[i].id,
		    (fo[i].id)       & 0xff,
		    (fo[i].id >>  8) & 0xff,
		    (fo[i].id >> 16) & 0xff,
		    (fo[i].id >> 24) & 0xff,
		    (fo[i].format == XvPacked) ? "packed" : "planar");
	if (0x32595559 == fo[i].id) {
	    im_formats[VIDEO_YUYV] = fo[i].id;
	    if (debug)
		fprintf(stderr," [ok: %s]",ng_vfmt_to_desc[VIDEO_YUYV]);
	}
	if (0x59565955 == fo[i].id) {
	    im_formats[VIDEO_UYVY] = fo[i].id;
	    if (debug)
		fprintf(stderr," [ok: %s]",ng_vfmt_to_desc[VIDEO_UYVY]);
	}
	if (0x30323449 == fo[i].id) {
	    im_formats[VIDEO_YUV420P] = fo[i].id;
	    if (debug)
		fprintf(stderr," [ok: %s]",ng_vfmt_to_desc[VIDEO_YUV420P]);
	}
	if (debug)
	    fprintf(stderr,"\n");
    }
}

XvImage*
xv_create_ximage(Display *dpy, int width, int height, int format,
		 XShmSegmentInfo **shm)
{
    XvImage         *xvimage = NULL;
    unsigned char   *ximage_data;
    XShmSegmentInfo *shminfo = NULL;
    void            *old_handler;

    if (no_mitshm)
	goto no_mitshm;

    old_handler = XSetErrorHandler(catch_no_mitshm);
    shminfo = malloc(sizeof(XShmSegmentInfo));
    memset(shminfo, 0, sizeof(XShmSegmentInfo));
    xvimage = XvShmCreateImage(dpy, im_port, format, 0,
			       width, height, shminfo);
    if (NULL == xvimage)
	goto shm_error;
    shminfo->shmid = shmget(IPC_PRIVATE, xvimage->data_size,
			    IPC_CREAT | 0777);
    if (-1 == shminfo->shmid) {
	perror("shmget [xv]");
	goto shm_error;
    }
    shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
    if ((void *)-1 == shminfo->shmaddr) {
	perror("shmat");
	goto shm_error;
    }
    xvimage->data = shminfo->shmaddr;
    shminfo->readOnly = False;

    XShmAttach(dpy, shminfo);
    XSync(dpy, False);
    if (no_mitshm)
	goto shm_error;
    shmctl(shminfo->shmid, IPC_RMID, 0);
    XSetErrorHandler(old_handler);
    *shm = shminfo;
    return xvimage;

shm_error:
    if (xvimage) {
	XFree(xvimage);
	xvimage = NULL;
    }
    if ((void *)-1 != shminfo->shmaddr  &&  NULL != shminfo->shmaddr)
	shmdt(shminfo->shmaddr);
    free(shminfo);
    XSetErrorHandler(old_handler);
    no_mitshm = 1;

 no_mitshm:
    *shm = NULL;
    if (NULL == (ximage_data = malloc(width * height * 2))) {
	fprintf(stderr,"out of memory\n");
	exit(1);
    }
    xvimage = XvCreateImage(dpy, im_port, format, ximage_data,
			    width, height);
    return xvimage;
}

void
xv_destroy_ximage(Display *dpy, XvImage * xvimage, XShmSegmentInfo *shm)
{
    if (shm && !no_mitshm) {
	XShmDetach(dpy, shm);
	XFree(xvimage);
	shmdt(shm->shmaddr);
	free(shm);
    } else
	XFree(xvimage);
}

void xv_blit(Display *dpy, Drawable dr, GC gc, XvImage *xi,
	     int a, int b, int c, int d, int x, int y, int w, int h)
{
    if (no_mitshm)
	XvPutImage(dpy,im_port,dr,gc,xi,a,b,c,d,x,y,w,h);
    else
	XvShmPutImage(dpy,im_port,dr,gc,xi,a,b,c,d,x,y,w,h,True);
}
#endif

/* ------------------------------------------------------------------------ */
/* OpenGL code                                                              */

#if HAVE_GL
static int have_gl,max_gl;
static int gl_attrib[] = { GLX_RGBA,
			   GLX_RED_SIZE, 1,
			   GLX_GREEN_SIZE, 1,
			   GLX_BLUE_SIZE, 1,
			   GLX_DOUBLEBUFFER,
			   None };

struct {
    int  fmt;
    int  type;
    char *ext;
} gl_formats[VIDEO_FMT_COUNT] = {
    [ VIDEO_RGB24 ] = {
	.fmt =  GL_RGB,
	.type = GL_UNSIGNED_BYTE,
    },
#ifdef GL_EXT_bgra
    [ VIDEO_BGR24 ] = {
	.fmt =  GL_BGR_EXT,
	.type = GL_UNSIGNED_BYTE,
	.ext =  "GL_EXT_bgra",
    },
    [ VIDEO_BGR32 ] = {
	.fmt =  GL_BGRA_EXT,
	.type = GL_UNSIGNED_BYTE,
	.ext =  "GL_EXT_bgra",
    },
#endif
};

static int gl_init(Widget widget)
{
    void *old_handler;
    XVisualInfo *visinfo;
    GLXContext ctx;

    if (debug)
	fprintf(stderr,"blit: gl: init\n");
    visinfo = glXChooseVisual(XtDisplay(widget),
			      XScreenNumberOfScreen(XtScreen(widget)),
			      gl_attrib);
    if (!visinfo) {
	if (debug)
	    fprintf(stderr,"blit: gl: can't get visual (rgb,db)\n");
	return -1;
    }
    ctx = glXCreateContext(XtDisplay(widget), visinfo, NULL, True);
    if (!ctx) {
	if (debug)
	    fprintf(stderr,"blit: gl: can't create context\n");
	return -1;
    }

    /* there is no point in using OpenGL for image scaling if it
     * isn't hardware accelerated ... */
    if (debug)
	fprintf(stderr, "blit: gl: DRI=%s\n",
		glXIsDirect(XtDisplay(widget), ctx) ? "Yes" : "No");
    if (!glXIsDirect(XtDisplay(widget), ctx))
	return -1;

    old_handler = XSetErrorHandler(catch_gl_error);
    glXMakeCurrent(XtDisplay(widget),XtWindow(widget),ctx);
    XSync(XtDisplay(widget), False);
    XSetErrorHandler(old_handler);
    if (gl_error)
	return -1;

    have_gl = 1;
    glGetIntegerv(GL_MAX_TEXTURE_SIZE,&max_gl);
    if (debug)
	fprintf(stderr,"blit: gl: texture max size: %d\n",max_gl);
    return 0;
}

static int gl_ext(GLubyte *find)
{
    int len = strlen(find);
    const GLubyte *ext;
    GLubyte *pos;

    ext = glGetString(GL_EXTENSIONS);
    if (NULL == ext)
	return 0;
    if (NULL == (pos = strstr(ext,find)))
	return 0;
    if (pos != ext && pos[-1] != ' ')
	return 0;
    if (pos[len] != ' ' && pos[len] != '\0')
	return 0;
    if (debug)
	fprintf(stderr,"blit: gl: extention %s is available\n",find);
    return 1;
}

static int gl_resize(int iw, int ih, int ww, int wh,
		     GLint *tex, int *tw, int *th, int fmt, int type)
{
    char *dummy;
    int i;

    /* check against max size */
    if (iw > max_gl)
	return -1;
    if (ih > max_gl)
	return -1;

    /* textures have power-of-two x,y dimensions */
    for (i = 0; iw >= (1 << i); i++)
	;
    *tw = (1 << i);
    for (i = 0; ih >= (1 << i); i++)
	;
    *th = (1 << i);
    if (debug)
	fprintf(stderr,"blit: gl: frame=%dx%d, texture=%dx%d\n",
		iw,ih,*tw,*th);

    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glViewport(0, 0, ww, wh);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, ww, 0.0, wh, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glGenTextures(1,tex);
    glBindTexture(GL_TEXTURE_2D,*tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    dummy = malloc((*tw)*(*th)*3);
    memset(dummy,128,(*tw)*(*th)*3);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,*tw,*th,0,
		 fmt,type,dummy);
    free(dummy);

    return 0;
}

static void gl_cleanup(GLint tex)
{
    /* FIXME: del texture */
}

static void gl_blit(Widget widget, char *rgbbuf,
		    int iw, int ih, int ww, int wh,
		    GLint tex, int tw, int th, int fmt, int type)
{
    float x,y;

    glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0,iw,ih, fmt,type,rgbbuf);
    x = (float)iw/tw;
    y = (float)ih/th;

    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glBegin(GL_QUADS);
    glTexCoord2f(0,y);  glVertex3f(0,0,0);
    glTexCoord2f(0,0);  glVertex3f(0,wh,0);
    glTexCoord2f(x,0);  glVertex3f(ww,wh,0);
    glTexCoord2f(x,y);  glVertex3f(ww,0,0);
    glEnd();
    glXSwapBuffers(XtDisplay(widget), XtWindow(widget));
    glDisable(GL_TEXTURE_2D);
}
#endif

/* ------------------------------------------------------------------------ */
/* video frame blitter                                                      */

enum blit_status {
    STATUS_UNKNOWN = 0,
    STATUS_BROKEN  = 1,
    STATUS_CONVERT = 2,
    STATUS_XVIDEO  = 3,
    STATUS_OPENGL  = 4,
};

struct blit_state {
    enum blit_status          status;
    Widget                    widget;
    Dimension                 win_width, win_height;
    int                       wx,wy,ww,wh;
    GC                        gc;
    XVisualInfo               *vinfo;
    struct ng_video_fmt       fmt;
    struct ng_video_buf       buf;
    struct ng_video_conv      *conv;
    struct ng_convert_handle  *chandle;
    XShmSegmentInfo           *shm;
    XImage                    *ximage;
#ifdef HAVE_LIBXV
    XvImage                   *xvimage;
#endif
#if HAVE_GL
    GLint                     tex;
    int                       tw,th;
#endif
};

struct blit_state*
blit_init(Widget widget, XVisualInfo *vinfo, int use_gl)
{
    struct blit_state *st;

    if (debug)
	fprintf(stderr,"blit: init\n");
    BUG_ON(0 == XtWindow(widget), "no blit window");

    st = malloc(sizeof(*st));
    memset(st,0,sizeof(*st));

    st->widget = widget;
    st->vinfo  = vinfo;
    st->gc     = XCreateGC(XtDisplay(st->widget),XtWindow(st->widget),0,NULL);
#ifdef HAVE_GL
    if (use_gl)
	gl_init(st->widget);
#endif

    return st;
}

void blit_get_formats(struct blit_state *st, int *fmtids, int max)
{
    struct ng_video_conv *conv;
    int i, n=0;

    BUG_ON(NULL == st, "blit handle is NULL");

    /* Xvideo extention */
#ifdef HAVE_LIBXV
    for (i = 0; i < VIDEO_FMT_COUNT; i++) {
	if (0 != im_formats[i])
	    fmtids[n++] = i;
	if (n == max)
	    return;
    }
#endif

#if HAVE_GL
    /* OpenGL */
    if (have_gl) {
	for (i = 0; i < VIDEO_FMT_COUNT; i++) {
	    if (0 != gl_formats[i].fmt  &&
		(NULL == gl_formats[i].ext || gl_ext(gl_formats[i].ext)))
		fmtids[n++] = i;
	    if (n == max)
		return;
	}
    }
#endif

    /* plain X11 */
    fmtids[n++] = x11_dpy_fmtid;
    if (n == max)
	return;
    for (i = 0;;) {
	conv = ng_conv_find_to(x11_dpy_fmtid, &i);
	if (NULL == conv)
	    break;
	fmtids[n++] = conv->fmtid_in;
	if (n == max)
	    return;
    }
    for (; n < max; n++)
	fmtids[n] = 0;
}

void blit_resize(struct blit_state *st, Dimension width, Dimension height)
{
    if (debug)
	fprintf(stderr,"blit: resize %dx%d\n",width,height);
    st->win_width  = width;
    st->win_height = height;

    st->wx = 0;
    st->wy = 0;
    st->ww = st->win_width;
    st->wh = st->win_height;
    ng_ratio_fixup(&st->ww, &st->wh, &st->wx, &st->wy);

    blit_fini_frame(st);
}

void blit_init_frame(struct blit_state *st, struct ng_video_fmt *fmt)
{
    struct ng_video_conv *conv;
    int i;

    /* Xvideo extention */
#ifdef HAVE_LIBXV
    if (0 != im_formats[fmt->fmtid]) {
	st->xvimage = xv_create_ximage(XtDisplay(st->widget),
				       fmt->width, fmt->height,
				       im_formats[fmt->fmtid],
				       &st->shm);
	st->buf.fmt = *fmt;
	st->status  = STATUS_XVIDEO;
	if (debug)
	    fprintf(stderr,"blit: %dx%d/[%s] => Xvideo\n",
		    fmt->width, fmt->height, ng_vfmt_to_desc[fmt->fmtid]);
	return;
    }
#endif

#if HAVE_GL
    /* OpenGL */
    if (have_gl  &&  0 != gl_formats[fmt->fmtid].fmt  &&
	(NULL == gl_formats[fmt->fmtid].ext ||
	 gl_ext(gl_formats[fmt->fmtid].ext)) &&
	0 == gl_resize(fmt->width,fmt->height,
		       st->win_width,st->win_height,
		       &st->tex,&st->tw,&st->th,
		       gl_formats[fmt->fmtid].fmt,
		       gl_formats[fmt->fmtid].type)) {
	st->buf.fmt = *fmt;
	st->status  = STATUS_OPENGL;
	if (debug)
	    fprintf(stderr,"blit: %dx%d/[%s] => OpenGL\n",
		    fmt->width, fmt->height, ng_vfmt_to_desc[fmt->fmtid]);
	return;
    }
#endif

    /* plain X11 */
    st->ximage = x11_create_ximage(XtDisplay(st->widget), st->vinfo,
				   fmt->width, fmt->height,
				   &st->shm);
    st->buf.data = st->ximage->data;
    if (x11_dpy_fmtid == fmt->fmtid) {
	st->buf.fmt = *fmt;
	st->status  = STATUS_CONVERT;
	if (debug)
	    fprintf(stderr,"blit: %dx%d/[%s] => X11 direct\n",
		    fmt->width, fmt->height, ng_vfmt_to_desc[fmt->fmtid]);
	return;
    }
    for (i = 0;;) {
	conv = ng_conv_find_to(x11_dpy_fmtid, &i);
	if (NULL == conv) {
	    st->status = STATUS_BROKEN;
	    if (debug)
		fprintf(stderr,"blit: %dx%d/[%s] => can't display\n",
			fmt->width, fmt->height, ng_vfmt_to_desc[fmt->fmtid]);
	    return;
	}
	if (debug)
	    fprintf(stderr,"blit test: %s\n",ng_vfmt_to_desc[conv->fmtid_in]);
	if (conv->fmtid_in != fmt->fmtid)
	    continue;
	break;
    }
    st->buf.fmt = *fmt;
    st->status  = STATUS_CONVERT;
    st->conv    = conv;
    st->buf.fmt.fmtid  = x11_dpy_fmtid;
    st->buf.fmt.bytesperline = 0;
    st->chandle = ng_convert_alloc(st->conv,fmt,&st->buf.fmt);
    ng_convert_init(st->chandle);
    if (debug)
	fprintf(stderr,"blit: %dx%d/[%s] => X11 via [%s]\n",
		fmt->width, fmt->height, ng_vfmt_to_desc[fmt->fmtid],
		ng_vfmt_to_desc[st->buf.fmt.fmtid]);
    return;
}

void blit_fini_frame(struct blit_state *st)
{
    switch (st->status) {
    case STATUS_CONVERT:
	if (st->chandle) {
	    ng_convert_fini(st->chandle);
	    st->chandle = NULL;
	}
	if (st->ximage) {
	    x11_destroy_ximage(XtDisplay(st->widget),st->ximage,st->shm);
	    st->ximage = NULL;
	}
	break;

#if HAVE_LIBXV
    case STATUS_XVIDEO:
	if (st->xvimage) {
	    xv_destroy_ximage(XtDisplay(st->widget),st->xvimage,st->shm);
	    st->xvimage = NULL;
	}
	XvStopVideo(XtDisplay(st->widget), im_port, XtWindow(st->widget));
	break;
#endif

#if HAVE_GL
    case STATUS_OPENGL:
	gl_cleanup(st->tex);
	break;
#endif

    case STATUS_UNKNOWN:
    case STATUS_BROKEN:
	break;
    }
    memset(&st->fmt,0,sizeof(st->fmt));
    memset(&st->buf,0,sizeof(st->buf));
    st->status = STATUS_UNKNOWN;
}

void blit_fini(struct blit_state *st)
{
    free(st);
}

void blit_putframe(struct blit_state *st, struct ng_video_buf *buf)
{
    if (st->fmt.fmtid  != buf->fmt.fmtid &&
	st->fmt.width  != buf->fmt.width &&
	st->fmt.height != buf->fmt.height) {
	blit_fini_frame(st);
	blit_init_frame(st,&buf->fmt);
	st->fmt = buf->fmt;
    }

    if (debug > 1)
	fprintf(stderr,"blit: putframe\n");
    switch (st->status) {
    case STATUS_CONVERT:
	if (NULL == st->chandle) {
	    memcpy(st->ximage->data,buf->data,buf->size);
	    ng_release_video_buf(buf);
	} else {
	    buf = ng_convert_frame(st->chandle,&st->buf,buf);
	}
	x11_blit(XtDisplay(st->widget), XtWindow(st->widget),
		 st->gc,st->ximage,0,0,
		 (st->win_width  - st->buf.fmt.width)  >> 1,
		 (st->win_height - st->buf.fmt.height) >> 1,
		 st->buf.fmt.width, st->buf.fmt.height);
	break;

#ifdef HAVE_LIBXV
    case STATUS_XVIDEO:
	memcpy(st->xvimage->data,buf->data,
	    buf->size < st->xvimage->data_size ? buf->size : st->xvimage->data_size);
	ng_release_video_buf(buf);
	xv_blit(XtDisplay(st->widget), XtWindow(st->widget),
		st->gc, st->xvimage,
		0, 0,  st->buf.fmt.width, st->buf.fmt.height,
		st->wx, st->wy, st->ww, st->wh);
	break;
#endif

#if HAVE_GL
    case STATUS_OPENGL:
	gl_blit(st->widget,buf->data,
		st->buf.fmt.width, st->buf.fmt.height,
		st->win_width, st->win_height,
		st->tex, st->tw, st->th,
		gl_formats[buf->fmt.fmtid].fmt,
		gl_formats[buf->fmt.fmtid].type);
	ng_release_video_buf(buf);
	break;
#endif

    case STATUS_UNKNOWN:
    case STATUS_BROKEN:
	if (debug > 1)
	    fprintf(stderr,"blit: putframe: oops: status = %d\n",st->status);
	ng_release_video_buf(buf);
	break;
    }
}
xawtv-3.106/x11/blit.h000066400000000000000000000026131343350355000144130ustar00rootroot00000000000000/* plain X11 */
extern unsigned int x11_dpy_fmtid;

Visual* x11_find_visual(Display *dpy);
void x11_init_visual(Display *dpy, XVisualInfo *vinfo);

XImage *x11_create_ximage(Display *dpy,  XVisualInfo *vinfo,
			  int width, int height, XShmSegmentInfo **shm);
void x11_destroy_ximage(Display *dpy, XImage * ximage, XShmSegmentInfo *shm);
Pixmap x11_create_pixmap(Display *dpy, XVisualInfo *vinfo,
			 struct ng_video_buf *buf);
void x11_blit(Display *dpy, Drawable dr, GC gc, XImage *xi,
	      int a, int b, int c, int d, int w, int h);

/* xvideo extention */
#ifdef HAVE_LIBXV
void xv_image_init(Display *dpy);
XvImage* xv_create_ximage(Display *dpy, int width, int height,
			  int format, XShmSegmentInfo **shm);
void xv_destroy_ximage(Display *dpy, XvImage * xvimage, XShmSegmentInfo *shm);
void xv_blit(Display *dpy, Drawable dr, GC gc, XvImage *xi,
	     int a, int b, int c, int d, int x, int y, int w, int h);
#endif

/* video frame blitter */
struct blit_state;
struct blit_state* blit_init(Widget widget, XVisualInfo *vinfo, int use_gl);
void blit_get_formats(struct blit_state *st, int *fmtids, int max);
void blit_resize(struct blit_state *st, Dimension width, Dimension height);
void blit_init_frame(struct blit_state *st, struct ng_video_fmt *fmt);
void blit_fini_frame(struct blit_state *st);
void blit_fini(struct blit_state *st);
void blit_putframe(struct blit_state *st, struct ng_video_buf *buf);
xawtv-3.106/x11/complete.c000066400000000000000000000135651343350355000152740ustar00rootroot00000000000000#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#ifdef ATHENA
# include 
#endif
#ifdef MOTIF
# include 
#endif

#include "complete.h"

#ifndef MIN
#define MIN(x,y)   ((xd_name, match, len))
	    continue;
#if 0
	fprintf(stderr, "%s %s\n", e->d_name, match);
#endif
	if (0 == (n % 16)) {
	    if (0 == n)
		*namelist = malloc(16 * sizeof(**namelist));
	    else
		*namelist = realloc(*namelist, (n + 16) * sizeof(**namelist));
	}
	(*namelist)[n] = malloc(strlen(e->d_name) + 1);
	strcpy((*namelist)[n], e->d_name);
	n++;
    }
    closedir(d);
    qsort(*namelist, n, sizeof(**namelist), my_cmp);
    return n;
}

void
CompleteAction(Widget widget,
	       XEvent * event,
	       String * params,
	       Cardinal * num_params)
{
    static char     thisdir[] = ".", rootdir[] = "/", *file;
    char           *fn, *fn2, *expand, *dir;
    char            filename[513];
    char          **list;
    struct stat     st;
    int             i, n, len;
#ifdef ATHENA
    XawTextPosition pos;
#endif
#ifdef MOTIF
    XmTextPosition  pos;
#endif
    struct passwd  *pw;
    char           *user, pwmatch[32];	/* anybody with more than 32 char uid ? */

#ifdef ATHENA
    XtVaGetValues(widget,
		  XtNstring, &fn,
		  NULL);
    pos = XawTextGetInsertionPoint(widget);
#endif
#ifdef MOTIF
    fn  = XmTextGetString(widget);
    pos = XmTextGetInsertionPosition(widget);
#endif
    fn2 = strdup(fn+pos);
    fn[pos] = 0;
    expand = tilde_expand(fn);
    if (!expand)
	/* failsave */
	return;

    list = NULL;
    memset(filename, 0, 513);

    if (expand[0] == '~') {
	/* try user name complete */
	if (strchr(expand, '/'))
	    /* ...but not if there is a slash */
	    return;
	user = &expand[1];
	len = strlen(user);
	n = 0;
	while ((pw = getpwent()) != NULL) {
	    if (!strncmp(user, pw->pw_name, len)) {
#ifdef DEBUG
		puts(pw->pw_name);
#endif
		if (0 == n) {
		    strcpy(pwmatch, pw->pw_name);
		} else {
		    for (i = len; !strncmp(pw->pw_name, pwmatch, i); i++);
		    pwmatch[i - 1] = 0;
#ifdef DEBUG
		    printf("%i: %s\n", i, pwmatch);
#endif
		}
		n++;
	    }
	}
	endpwent();
	if (0 == n) {
	    /* no match */
	    XBell(dpy, 100);
	    strcpy(filename, expand);
	} else if (1 == n) {
	    sprintf(filename, "~%s/", pwmatch);
	} else {
	    sprintf(filename, "~%s", pwmatch);
	}

    } else {
	/* try file name complete */
	file = strrchr(expand, '/');
	if (file) {
	    if (file == expand) {
		dir = rootdir;
	    } else {
		dir = expand;
	    }
	    *file = '\0';
	    file++;
	} else {
	    file = expand;
	    dir = thisdir;
	}
#ifdef DEBUG
	printf("%s %s\n", dir, file);
#endif

	n = my_scandir(dir, file, &list);
#if 0
	for (i = 0; i < n; i++) {
	    printf("--> %s\n", list[i]);
	}
#endif
	if (-1 == n) {
	    /* Oops, maybe permission denied ??? */
	    PERROR("scandir");
	    strcpy(filename, fn);
	} else if (0 == n) {
	    /* no match */
	    XBell(dpy, 100);
	    strcpy(filename, fn);
	} else if (1 == n) {
	    /* one match */
	    sprintf(filename, "%s/%s", dir, list[0]);
	    stat(filename, &st);
	    if (strchr(fn, '/')) {
		strcpy(filename, fn);
		*(strrchr(filename, '/') + 1) = '\0';
		strcat(filename, list[0]);
	    } else {
		strcpy(filename, list[0]);
	    }
	    if (S_ISDIR(st.st_mode))
		strcat(filename, "/");
	    else
		strcat(filename, " ");
	} else {
	    /* more than one match */
	    len = MIN(strlen(list[0]), strlen(list[n - 1]));
	    for (i = 0; !strncmp(list[0], list[n - 1], i + 1) && i <= len; i++);
	    if (strchr(fn, '/')) {
		strcpy(filename, fn);
		*(strrchr(filename, '/') + 1) = '\0';
		strncat(filename, list[0], i);
	    } else {
		strncpy(filename, list[0], i);
	    }
	}
    }

#ifdef DEBUG
    printf("result: `%s'\n", filename);
#endif
    pos = strlen(filename);
    strcat(filename,fn2);
#ifdef ATHENA
    XtVaSetValues(widget,
		  XtNstring, filename,
		  NULL);
    XawTextSetInsertionPoint(widget,pos);
#endif
#ifdef MOTIF
    XmTextSetString(widget,filename);
    XmTextSetInsertionPosition(widget,pos);
#endif

    if (list) {
	for (i = 0; i < n; i++)
	    free(list[i]);
	free(list);
    }
    free(expand);
    return;
}

/*-------------------------------------------------------------------------*/

char*
tilde_expand(char *file)
{
    char           *ret, *user;
    struct passwd  *pw;
    int             len;

    if (!file)
	return NULL;

#ifdef DEBUG
    printf("tilde_expand: in : `%s'\n", file);
#endif
    if (!(file[0] == '~' && strchr(file, '/'))) {
	ret = strdup(file);
    } else {
	if (file[1] == '/') {
	    pw = getpwuid(getuid());
	} else {
	    user = strdup(&file[1]);
	    *(strchr(user, '/')) = '\0';
	    pw = getpwnam(user);
	    free(user);
	}
	if (pw == NULL) {
	    ret = strdup(file);
	} else {
#ifdef DEBUG
	    printf("tilde_expand: pw : %s=%s\n", pw->pw_name, pw->pw_dir);
#endif
	    ret = malloc(strlen(file) + strlen(pw->pw_dir));
	    sprintf(ret, "%s%s", pw->pw_dir, strchr(file, '/'));
	}
    }
    /* trim */
    len = strlen(ret);
    while (ret[len - 1] == ' ')
	ret[len - 1] = '\0', len--;
#ifdef DEBUG
    printf("tilde_expand: out: `%s'\n", ret);
#endif
    return ret;
}
xawtv-3.106/x11/complete.h000066400000000000000000000001561343350355000152710ustar00rootroot00000000000000char           *tilde_expand(char *);
void            CompleteAction(Widget, XEvent *, String *, Cardinal *);
xawtv-3.106/x11/conf.c000066400000000000000000000214641343350355000144060ustar00rootroot00000000000000/*
 * channel editor.
 *
 *   (c) 1998 Gerd Knorr 
 *
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "grab-ng.h"
#include "channel.h"
#include "frequencies.h"
#include "wmhooks.h"
#include "commands.h"
#include "conf.h"

/*-------------------------------------------------------------------------*/

void pixit(void);
void set_channel(struct CHANNEL *channel);
void channel_menu(void);

extern Widget   app_shell,conf_shell;
extern Display  *dpy;
extern Atom     wm_protocols[2];
extern int      debug;
extern int      stay_on_top;
extern XVisualInfo vinfo;
extern Colormap colormap;

Widget conf_channel, conf_name, conf_key, conf_list;

static Widget last_command, viewport;
static String *channel_list;

/*-------------------------------------------------------------------------*/

static void list_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XawListReturnStruct *lr = call_data;

    if (channel_switch_hook)
	channel_switch_hook();
    do_va_cmd(2,"setstation",lr->string);
}

static void add_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct CHANNEL *channel;
    char *name,*key;

    XtVaGetValues(conf_name,XtNstring,&name,NULL);
    XtVaGetValues(conf_key,XtNlabel,&key,NULL);

    if (0 == strlen(name))
	return;

    channel = add_channel(name);
    if (strlen(key) > 0)
	channel->key = strdup(key);
    channel->cname = (cur_channel != -1) ? chanlist[cur_channel].name : "???";
    channel->channel = cur_channel;
    channel->input = cur_attrs[ATTR_ID_INPUT];
    channel->fine = cur_fine;
    fprintf(stderr,"add_cb #1: %d %s\n",channel->channel,channel->cname);
    configure_channel(channel);
    fprintf(stderr,"add_cb #2: %d %s\n",channel->channel,channel->cname);
    channel_menu();
    fprintf(stderr,"add_cb #3: %d %s\n",channel->channel,channel->cname);
}

static void del_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    if(cur_sender == -1)
	return;
    XtDestroyWidget(channels[cur_sender]->button);
    del_channel(cur_sender);
    channel_menu();
    cur_sender = -1;
    conf_station_switched();
}

static void modify_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    char *name,*key;

    XtVaGetValues(conf_name,XtNstring,&name,NULL);
    XtVaGetValues(conf_key,XtNlabel,&key,NULL);

    if (0 == strlen(name))
	return;

    /* no channel yet ... */
    if (-1 == cur_sender) {
	add_cb(widget, clientdata, call_data);
	return;
    }

    free(channels[cur_sender]->name);
    channels[cur_sender]->name = strdup(name);

    if (channels[cur_sender]->key)
	free(channels[cur_sender]->key);
    if (0 != strlen(key))
	channels[cur_sender]->key = strdup(key);
    else
	channels[cur_sender]->key = 0;
    hotkey_channel(channels[cur_sender]);
    channel_menu();
    conf_station_switched();
}

static void save_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    save_config();
}

static void close_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XtCallActionProc(conf_shell,"Popup",NULL,NULL,0);
}

static void key_eh(Widget widget, XtPointer client_data,
		   XEvent *event, Boolean *cont)
{
    XKeyEvent *ke = (XKeyEvent*)event;
    KeySym sym;
    char *key;
    char line[64];

    sym = XkbKeycodeToKeysym(dpy,ke->keycode,0,0);
    if (NoSymbol == sym) {
	fprintf(stderr,"can't translate keycode %d\n",ke->keycode);
	return;
    }
    key = XKeysymToString(sym);

    line[0] = '\0';
    if (ke->state & ShiftMask)   strcpy(line,"Shift+");
    if (ke->state & ControlMask) strcpy(line,"Ctrl+");
    strcat(line,key);
    XtVaSetValues(conf_key,XtNlabel,line,NULL);
}

/*-------------------------------------------------------------------------*/

#define FIX_RIGHT_TOP       \
    XtNleft,XawChainRight,  \
    XtNright,XawChainRight, \
    XtNtop,XawChainTop,     \
    XtNbottom,XawChainTop

void
create_confwin(void)
{
    Widget form, label, command;

    conf_shell = XtVaAppCreateShell("Config", "Xawtv",
				    topLevelShellWidgetClass,
				    dpy,
				    XtNclientLeader,app_shell,
				    XtNvisual,vinfo.visual,
				    XtNcolormap,colormap,
				    XtNdepth,vinfo.depth,
				    NULL);
    XtOverrideTranslations(conf_shell, XtParseTranslationTable
			   ("WM_PROTOCOLS: Popup()"));
    form = XtVaCreateManagedWidget("form", formWidgetClass, conf_shell,
				   NULL);

    /* list */
    viewport =
	XtVaCreateManagedWidget("viewport", viewportWidgetClass, form,
				XtNleft,XawChainLeft,
				XtNright,XawChainRight,
				XtNtop,XawChainTop,
				XtNbottom,XawChainBottom,
				NULL);
    conf_list =
	XtVaCreateManagedWidget("list", listWidgetClass, viewport,
				NULL);
    XtAddCallback(conf_list,XtNcallback,list_cb,(XtPointer)NULL);

    /* Einstellungen */
    label =
	XtVaCreateManagedWidget("lchannel", labelWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				NULL);
    conf_channel =
	XtVaCreateManagedWidget("channel", labelWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, label,
				NULL);
    label =
	XtVaCreateManagedWidget("lkey", labelWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, conf_channel,
				NULL);
    conf_key =
	XtVaCreateManagedWidget("key", labelWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, label,
				NULL);
    label =
	XtVaCreateManagedWidget("lname", labelWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, conf_key,
				NULL);
    conf_name =
	XtVaCreateManagedWidget("name", asciiTextWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, label,
				NULL);
    XtAddEventHandler(conf_key, KeyPressMask, False, key_eh, NULL);

    /* buttons */
    command =
	XtVaCreateManagedWidget("add", commandWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, conf_name,
				NULL);
    XtAddCallback(command,XtNcallback,add_cb,(XtPointer)NULL);
    command =
	XtVaCreateManagedWidget("delete", commandWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, command,
				NULL);
    XtAddCallback(command,XtNcallback,del_cb,(XtPointer)NULL);
    command =
	XtVaCreateManagedWidget("modify", commandWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, command,
				NULL);
    XtAddCallback(command,XtNcallback,modify_cb,(XtPointer)NULL);
    command =
	XtVaCreateManagedWidget("save", commandWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, command,
				NULL);
    XtAddCallback(command,XtNcallback,save_cb,(XtPointer)NULL);
    last_command = command =
	XtVaCreateManagedWidget("close", commandWidgetClass, form,
				FIX_RIGHT_TOP,
				XtNfromHoriz, viewport,
				XtNfromVert, command,
				NULL);
    XtAddCallback(command,XtNcallback,close_cb,(XtPointer)NULL);

    XtInstallAllAccelerators(conf_name, conf_shell);
}

/*-------------------------------------------------------------------------*/

void conf_station_switched(void)
{
    char line[128] = "???";

    /* channel */
    if (cur_channel != -1) {
	strcpy(line,chanlist[cur_channel].name);
	if (cur_fine != 0)
	    sprintf(line+strlen(line)," (%+d)",cur_fine);
    }
    XtVaSetValues(conf_channel, XtNlabel, line, NULL);

    if (cur_sender == -1) {
	XtVaSetValues(conf_key, XtNlabel, "", NULL);
	XtVaSetValues(conf_name, XtNstring, "", NULL);
	XawListUnhighlight(conf_list);
    } else {
	if (channels[cur_sender]->key)
	    XtVaSetValues(conf_key,XtNlabel,channels[cur_sender]->key, NULL);
	else
	    XtVaSetValues(conf_key,XtNlabel,"", NULL);
#if 0
	/* This is needed for Xaw3d
	   libXaw3d doesn't get the memory management right with
	   the international ressource set to true.  Keeps crashing
	   without the strdup() */
	XtVaSetValues(conf_name,
		      XtNstring, strdup(channels[cur_sender]->name),
		      NULL);
#else
	XtVaSetValues(conf_name, XtNstring, channels[cur_sender]->name, NULL);
#endif
	XawListHighlight(conf_list,cur_sender);
    }
}

void
conf_list_update(void)
{
    int i;

    if (channel_list)
	free(channel_list);

    XawListUnhighlight(conf_list);
    if (count) {
	/* rebuild list */
	channel_list = malloc((count+1)*sizeof(String));
	for (i = 0; i < count; i++)
	    channel_list[i] = channels[i]->name;
	channel_list[i] = NULL;
    } else {
	/* empty list */
	channel_list    = malloc(2*sizeof(String));
	channel_list[0] = "empty";
	channel_list[1] = NULL;
    }
    XtVaSetValues(conf_list,
		  XtNlist, channel_list,
		  XtNnumberStrings, 0,
		  NULL);
}
xawtv-3.106/x11/conf.h000066400000000000000000000001571343350355000144070ustar00rootroot00000000000000extern void create_confwin(void);
extern void conf_station_switched(void);
extern void conf_list_update(void);
xawtv-3.106/x11/icons.c000066400000000000000000000027071343350355000145730ustar00rootroot00000000000000#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "icons.h"
#include "xpm/home.xpm"
#include "xpm/prev.xpm"
#include "xpm/next.xpm"
#include "xpm/movie.xpm"
#include "xpm/snap.xpm"
#include "xpm/mute.xpm"
#include "xpm/exit.xpm"
#include "xpm/tv.xpm"

static void
add_pixmap(Display *dpy, unsigned long bg,
	   char *imgname, char *maskname, char **data)
{
    XImage *image,*shape;
    XpmAttributes attr;
    unsigned int x,y;

    memset(&attr,0,sizeof(attr));
    XpmCreateImageFromData(dpy,data,&image,&shape,&attr);

    if (maskname) {
	XmInstallImage(image,imgname);
	if (shape)
	    XmInstallImage(shape,maskname);
	return;
    }

    if (shape) {
	for (y = 0; y < attr.height; y++)
	    for (x = 0; x < attr.width; x++)
		if (!XGetPixel(shape, x, y))
		    XPutPixel(image, x, y, bg);
    }
    XmInstallImage(image,imgname);
}

void
x11_icons_init(Display *dpy, unsigned long bg)
{
    add_pixmap(dpy, bg,  "home",   NULL,      home_xpm);
    add_pixmap(dpy, bg,  "prev",   NULL,      prev_xpm);
    add_pixmap(dpy, bg,  "next",   NULL,      next_xpm);
    add_pixmap(dpy, bg,  "movie",  NULL,      movie_xpm);
    add_pixmap(dpy, bg,  "snap",   NULL,      snap_xpm);
    add_pixmap(dpy, bg,  "mute",   NULL,      mute_xpm);
    add_pixmap(dpy, bg,  "exit",   NULL,      exit_xpm);
    add_pixmap(dpy, bg,  "TVimg",  "TVmask",  tv_xpm);
}
xawtv-3.106/x11/icons.h000066400000000000000000000000651343350355000145730ustar00rootroot00000000000000void x11_icons_init(Display *dpy, unsigned long bg);
xawtv-3.106/x11/man.c000066400000000000000000000061311343350355000142260ustar00rootroot00000000000000/*
 * motif-based man page renderer
 * (c) 2001 Gerd Knorr 
 *
 */

#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "man.h"

extern Display *dpy;
extern Widget app_shell;
extern XVisualInfo vinfo;
extern Colormap colormap;

/*----------------------------------------------------------------------*/

#define MAN_UNDEF      0
#define MAN_NORMAL     1
#define MAN_BOLD       2
#define MAN_UNDERLINE  3

static XmStringTag man_tags[] = {
    NULL, NULL, "bold", "underline"
};

static void
man_destroy(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XtDestroyWidget(clientdata);
}

void
man(char *page)
{
    Widget dlg,view,label;
    XmString xmpage,xmchunk;
    char line[1024],chunk[256];
    int s,d,cur,last;
    FILE *fp;

    /* build dialog */
    dlg = XmCreatePromptDialog(app_shell,"man",NULL,0);
    XtAddEventHandler(XtParent(dlg), (EventMask) 0, True,
                     (XtEventHandler) _XEditResCheckMessages, NULL);
    XtUnmanageChild(XmSelectionBoxGetChild(dlg,XmDIALOG_SELECTION_LABEL));
    XtUnmanageChild(XmSelectionBoxGetChild(dlg,XmDIALOG_HELP_BUTTON));
    XtUnmanageChild(XmSelectionBoxGetChild(dlg,XmDIALOG_CANCEL_BUTTON));
    XtUnmanageChild(XmSelectionBoxGetChild(dlg,XmDIALOG_TEXT));
    XtAddCallback(dlg,XmNokCallback,man_destroy,dlg);
    view = XmCreateScrolledWindow(dlg,"view",NULL,0);
    XtManageChild(view);
    label = XtVaCreateManagedWidget("label", xmLabelWidgetClass,view, NULL);
    XtManageChild(dlg);

    /* fetch page and render into XmString */
    sprintf(line,"man %s 2>/dev/null",page);
    fp = popen(line,"r");
    xmpage = XmStringGenerate("", NULL, XmMULTIBYTE_TEXT, NULL);
    while (NULL != fgets(line,sizeof(line)-1,fp)) {
	last = MAN_UNDEF;
	for (s = 0, d = 0; line[s] != '\0';) {
	    /* check current char */
	    cur = MAN_NORMAL;
	    if (line[s+1] == '\010' && line[s] == line[s+2])
		cur = MAN_BOLD;
	    if (line[s] == '_' && line[s+1] == '\010')
		cur = MAN_UNDERLINE;
	    /* add chunk if completed */
	    if (MAN_UNDEF != last  &&  cur != last) {
		xmchunk = XmStringGenerate(chunk,NULL,XmMULTIBYTE_TEXT,
					   man_tags[last]);
		xmpage  = XmStringConcatAndFree(xmpage,xmchunk);
		d = 0;
	    }
	    /* add char to chunk */
	    switch (cur) {
	    case MAN_BOLD:
	    case MAN_UNDERLINE:
		s += 2;
	    case MAN_NORMAL:
		chunk[d++] = line[s++];
		break;
	    }
	    chunk[d] = '\0';
	    last = cur;
	}
	/* add last chunk for line */
	xmchunk = XmStringGenerate(chunk, NULL, XmMULTIBYTE_TEXT,
				   man_tags[last]);
	xmpage  = XmStringConcatAndFree(xmpage,xmchunk);
    }
    XtVaSetValues(label,XmNlabelString,xmpage,NULL);
    XmStringFree(xmpage);
    fclose(fp);
}

void
man_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    char *page = clientdata;
    man(page);
}

void
man_action(Widget widget, XEvent *event,
	   String *params, Cardinal *num_params)
{
    if (*num_params > 0)
	man(params[0]);
}

xawtv-3.106/x11/man.h000066400000000000000000000002641343350355000142340ustar00rootroot00000000000000void man(char *page);
void man_cb(Widget widget, XtPointer clientdata, XtPointer call_data);
void man_action(Widget widget, XEvent *event,
		String *params, Cardinal *num_params);
xawtv-3.106/x11/motv.c000066400000000000000000003045721343350355000144520ustar00rootroot00000000000000/*
 * Openmotif user interface
 *
 *   (c) 2000-2002 Gerd Knorr 
 *
 */

#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "grab-ng.h"
#include "channel.h"
#include "commands.h"
#include "frequencies.h"
#include "capture.h"
#include "wmhooks.h"
#include "atoms.h"
#include "x11.h"
#include "xt.h"
#include "xv.h"
#include "man.h"
#include "icons.h"
#include "sound.h"
#include "complete.h"
#include "writefile.h"
#include "list.h"
#include "vbi-data.h"
#include "vbi-x11.h"
#include "blit.h"

/*----------------------------------------------------------------------*/

int jpeg_quality, mjpeg_quality, debug;

/*----------------------------------------------------------------------*/

static void PopupAction(Widget, XEvent*, String*, Cardinal*);
static void DebugAction(Widget, XEvent*, String*, Cardinal*);
static void IpcAction(Widget, XEvent*, String*, Cardinal*);
static void ontop_ac(Widget, XEvent*, String*, Cardinal*);
static void chan_makebutton(struct CHANNEL *channel);
static void channel_menu(void);

#ifdef HAVE_ZVBI
static void chscan_cb(Widget widget, XtPointer clientdata,
		      XtPointer call_data);
#endif
static void pref_manage_cb(Widget widget, XtPointer clientdata,
			   XtPointer call_data);
static void add_cmd_callback(Widget widget, String callback,char *command,
			     const char *arg1, const char *arg2);

static XtActionsRec actionTable[] = {
    { "CloseMain",   CloseMainAction   },
    { "Command",     CommandAction     },
    { "Popup",       PopupAction       },
    { "Debug",       DebugAction       },
    { "Remote",      RemoteAction      },
    { "Zap",         ZapAction         },
    { "Scan",        ScanAction        },
    { "man",         man_action        },
    { "Ratio",       RatioAction       },
    { "Launch",      LaunchAction      },
#ifdef HAVE_ZVBI
    { "Vtx",         VtxAction         },
#endif
    { "Complete",    CompleteAction    },
    { "Ipc",         IpcAction         },
    { "Filter",      FilterAction      },
    { "StayOnTop",   ontop_ac          },
    { "Event",       EventAction       },
};

static String fallback_ressources[] = {
#include "MoTV.h"
    NULL
};

XtIntervalId audio_timer;

static Widget st_menu1,st_menu2;
static Widget control_shell,str_shell,levels_shell,levels_toggle;
static Widget launch_menu,opt_menu,cap_menu,freq_menu;
static Widget chan_viewport,chan_box;
static Widget st_freq,st_chan,st_name,st_key;
static Widget scale_shell,filter_shell;
static Widget w_full;
static Widget b_ontop;
#ifdef HAVE_ZVBI
static struct vbi_window *vtx;
#endif

/* properties */
static Widget prop_dlg,prop_name,prop_key,prop_channel,prop_button;
static Widget prop_group;

/* preferences */
static Widget pref_dlg,pref_fs_toggle,pref_fs_menu,pref_fs_option;
static Widget pref_osd,pref_ntsc,pref_partial,pref_quality;
static Widget pref_mix_toggle,pref_mix1_menu,pref_mix1_option;
static Widget pref_mix2_menu,pref_mix2_option;

/* streamer */
static Widget driver_menu, driver_option;
static Widget audio_menu, audio_option;
static Widget video_menu, video_option;
static Widget m_rate,m_fps,m_fvideo,m_status;
static Widget m_faudio,m_faudioL,m_faudioB;

static struct ng_writer *movie_driver;
static unsigned int i_movie_driver;
static unsigned int movie_audio;
static unsigned int movie_video;
static XtWorkProcId rec_work_id;

static struct MY_TOPLEVELS {
    char        *name;
    Widget      *shell;
    int         mapped;
} my_toplevels [] = {
    { "control",   &control_shell },
    { "streamer",  &str_shell     },
    { "scale",     &scale_shell   },
    { "filter",    &filter_shell  },
    { "levels",    &levels_shell  },
};
#define TOPLEVELS (sizeof(my_toplevels)/sizeof(struct MY_TOPLEVELS))

struct motif_attribute {
    struct motif_attribute  *next;
    struct ng_attribute     *attr;
    Widget                  widget;
};
static struct motif_attribute *motif_attrs;

struct filter_attribute {
    struct filter_attribute *next;
    struct ng_filter        *filter;
    struct ng_attribute     *attr;
    int                     value;
    Widget                  widget;
};
static struct filter_attribute *filter_attrs;

/*----------------------------------------------------------------------*/
/* debug/test code                                                      */

#if 0
static void
print_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    char *msg = (char*) clientdata;
    fprintf(stderr,"debug: %s\n",msg);
}

static void
toggle_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmToggleButtonCallbackStruct *tb = call_data;

    if (tb->reason != XmCR_VALUE_CHANGED)
	return;
    fprintf(stderr,"toggle: [%s] set=%s\n",
	    clientdata ? (char*)clientdata : "???",
	    tb->set ? "on" : "off");
}
#endif

void
DebugAction(Widget widget, XEvent *event,
	  String *params, Cardinal *num_params)
{
    fprintf(stderr,"debug: foo\n");
}

/*----------------------------------------------------------------------*/

void toolkit_set_label(Widget widget, char *str)
{
    XmString xmstr;

    xmstr = XmStringGenerate(str, NULL, XmMULTIBYTE_TEXT, NULL);
    XtVaSetValues(widget,XmNlabelString,xmstr,NULL);
    XmStringFree(xmstr);
}

static void delete_children(Widget widget)
{
    WidgetList children,list;
    Cardinal nchildren;
    unsigned int i;

    XtVaGetValues(widget,XtNchildren,&children,
		  XtNnumChildren,&nchildren,NULL);
    if (0 == nchildren)
	return;
    list = malloc(sizeof(Widget*)*nchildren);
    memcpy(list,children,sizeof(Widget*)*nchildren);
    for (i = 0; i < nchildren; i++)
	XtDestroyWidget(list[i]);
    free(list);
}

static void
watch_audio(XtPointer data, XtIntervalId *id)
{
    if (-1 != cur_sender)
	change_audio(channels[cur_sender]->audio);
    audio_timer = 0;
}

static void
new_channel(void)
{
    char line[1024];

    set_property(cur_freq,
		 (cur_channel == -1) ? NULL : chanlist[cur_channel].name,
		 (cur_sender == -1)  ? NULL : channels[cur_sender]->name);

    sprintf(line,"%d.%02d MHz",cur_freq / 16, (cur_freq % 16) * 100 / 16);
    toolkit_set_label(st_freq,line);
    toolkit_set_label(st_chan, (cur_channel != -1) ?
		      chanlist[cur_channel].name : "");
    toolkit_set_label(st_name, (cur_sender != -1) ?
		      channels[cur_sender]->name : "");
    toolkit_set_label(st_key,(cur_sender != -1 &&
			      NULL != channels[cur_sender]->key) ?
	channels[cur_sender]->key : "");

    if (zap_timer) {
	XtRemoveTimeOut(zap_timer);
	zap_timer = 0;
    }
    if (scan_timer) {
	XtRemoveTimeOut(scan_timer);
	scan_timer = 0;
    }
    if (audio_timer) {
	XtRemoveTimeOut(audio_timer);
	audio_timer = 0;
    }
    audio_timer = XtAppAddTimeOut(app_context, 5000, watch_audio, NULL);
}

static void
do_ontop(Boolean state)
{
    unsigned int i;

    if (!wm_stay_on_top)
	return;

    stay_on_top = state;
    wm_stay_on_top(dpy,XtWindow(app_shell),stay_on_top);
    wm_stay_on_top(dpy,XtWindow(on_shell),stay_on_top);
    for (i = 0; i < TOPLEVELS; i++)
	wm_stay_on_top(dpy,XtWindow(*(my_toplevels[i].shell)),
		       (stay_on_top == -1) ? 0 : stay_on_top);
    XmToggleButtonSetState(b_ontop,state,False);
}

static void
ontop_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmToggleButtonCallbackStruct *tb = call_data;

    if (tb->reason != XmCR_VALUE_CHANGED)
	return;
    do_ontop(tb->set);
}

static void
ontop_ac(Widget widget, XEvent *event, String *params, Cardinal *num_params)
{
    do_ontop(stay_on_top ? False : True);
}

/*----------------------------------------------------------------------*/

static void
resize_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d)
{
    static int width = 0, height = 0, first = 1;

    switch(event->type) {
    case ConfigureNotify:
	if (first) {
	    video_gd_init(tv,args.gl);
	    first = 0;
	}
	if (width  != event->xconfigure.width ||
	    height != event->xconfigure.height) {
	    width  = event->xconfigure.width;
	    height = event->xconfigure.height;
	    video_gd_configure(width, height);
	    XClearWindow(XtDisplay(tv),XtWindow(tv));
	}
	break;
    }
}

static void
PopupAction(Widget widget, XEvent *event,
	    String *params, Cardinal *num_params)
{
    unsigned int i;

    /* which window we are talking about ? */
    if (*num_params > 0) {
	for (i = 0; i < TOPLEVELS; i++) {
	    if (0 == strcasecmp(my_toplevels[i].name,params[0]))
		break;
	}
	if (i == TOPLEVELS) {
	    fprintf(stderr,"PopupAction: oops: shell not found (name=%s)\n",
		    params[0]);
	    return;
	}
    } else {
	for (i = 0; i < TOPLEVELS; i++) {
	    if (*(my_toplevels[i].shell) == widget)
		break;
	}
	if (i == TOPLEVELS) {
	    fprintf(stderr,"PopupAction: oops: shell not found (%p:%s)\n",
		    widget,XtName(widget));
	    return;
	}
    }

    /* popup/down window */
    if (!my_toplevels[i].mapped) {
	XtPopup(*(my_toplevels[i].shell), XtGrabNone);
	if (wm_stay_on_top && stay_on_top > 0)
	    wm_stay_on_top(dpy,XtWindow(*(my_toplevels[i].shell)),1);
	my_toplevels[i].mapped = 1;
    } else {
	XtPopdown(*(my_toplevels[i].shell));
	my_toplevels[i].mapped = 0;
    }
}

static void
popup_eh(Widget widget, XtPointer clientdata, XEvent *event, Boolean *cont)
{
    Widget popup = clientdata;

    XmMenuPosition(popup,(XButtonPressedEvent*)event);
    XtManageChild(popup);
}

static void
popupdown_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    int i = 0;
    PopupAction(clientdata, NULL, NULL, &i);
}

static void
destroy_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XtDestroyWidget(clientdata);
}

static void
free_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    free(clientdata);
}

static void
about_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    Widget msgbox;

    msgbox = XmCreateInformationDialog(app_shell,"about_box",NULL,0);
    XtUnmanageChild(XmMessageBoxGetChild(msgbox,XmDIALOG_HELP_BUTTON));
    XtUnmanageChild(XmMessageBoxGetChild(msgbox,XmDIALOG_CANCEL_BUTTON));
    XtAddCallback(msgbox,XmNokCallback,destroy_cb,msgbox);
    XtManageChild(msgbox);
}

static void
action_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    char *calls, *action, *argv[8];
    int argc;

    calls = strdup(clientdata);
    action = strtok(calls,"(),");
    for (argc = 0; NULL != (argv[argc] = strtok(NULL,"(),")); argc++)
	/* nothing */;
    XtCallActionProc(widget,action,NULL,argv,argc);
    free(calls);
}

/*--- videotext ----------------------------------------------------------*/

#if TT
static void
rend_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmDisplayCallbackStruct *arg = call_data;
    XmRendition rend;
    Colormap cmap;
    XColor color,dummy;
    char fg[16],bg[16];
    Arg args[4];
    int n = 0;

    if (arg->reason != XmCR_NO_RENDITION)
	return;
    if (2 != sscanf(arg->tag,"%[a-z]_on_%[a-z]",fg,bg))
	return;

    XtVaGetValues(app_shell, XmNcolormap, &cmap, NULL);
    if (0 != strcmp(fg,"def"))
	if (XAllocNamedColor(dpy, cmap, fg, &color, &dummy))
	    XtSetArg(args[n],XmNrenditionForeground,color.pixel), n++;
    if (0 != strcmp(bg,"def"))
	if (XAllocNamedColor(dpy, cmap, bg, &color, &dummy))
	    XtSetArg(args[n],XmNrenditionBackground,color.pixel), n++;
    if (debug)
	fprintf(stderr,"rend_cb: %s: %d %s/%s\n",arg->tag,n,fg,bg);
    rend = XmRenditionCreate(app_shell, arg->tag, args, n);
    arg->render_table = XmRenderTableAddRenditions
	(arg->render_table,&rend,1,XmMERGE_NEW);
}
#endif

static void create_vtx(void)
{
    Widget shell,label;

    shell = XtVaCreateWidget("vtx",transientShellWidgetClass,
			     app_shell,
			     XtNoverrideRedirect,True,
			     XtNvisual,vinfo.visual,
			     XtNcolormap,colormap,
			     XtNdepth,vinfo.depth,
			     NULL);
    label = XtVaCreateManagedWidget("label", xmLabelWidgetClass, shell,
				    NULL);
#if TT
    XtAddCallback(XmGetXmDisplay(dpy),XmNnoRenditionCallback,rend_cb,NULL);
#endif
#ifdef HAVE_ZVBI
    vtx = vbi_render_init(shell,label,NULL);
#endif
}

#if TT
static void
display_vtx(struct TEXTELEM *tt)
{
    static int first = 1;
    Dimension x,y,w,h,sw,sh;
    char tag[32];
    int i,lastline;
    XmString str,elem;

    if (NULL == tt) {
	XtPopdown(vtx_shell);
	return;
    }

    /* build xmstring */
    str = NULL;
    lastline = tt[0].line;
    for (i = 0; tt[i].len > 0; i++) {
	tt[i].str[tt[i].len] = 0;
	sprintf(tag,"%s_on_%s",
		tt[i].fg ? tt[i].fg : "def",
		tt[i].bg ? tt[i].bg : "def");
	if (NULL != str && tt[i].line != lastline) {
	    lastline = tt[i].line;
	    str = XmStringConcatAndFree(str,XmStringSeparatorCreate());
	}
	elem = XmStringGenerate(tt[i].str, NULL, XmMULTIBYTE_TEXT, tag);
	if (NULL != str)
	    str = XmStringConcatAndFree(str,elem);
	else
	    str = elem;
    }
    XtVaSetValues(vtx_label,XmNlabelString,str,NULL);
    XmStringFree(str);

    /* show popup */
    XtVaGetValues(app_shell,XtNx,&x,XtNy,&y,XtNwidth,&w,XtNheight,&h,NULL);
    XtVaGetValues(vtx_shell,XtNwidth,&sw,XtNheight,&sh,NULL);
    XtVaSetValues(vtx_shell,XtNx,x+(w-sw)/2,XtNy,y+h-10-sh,NULL);
    XtPopup(vtx_shell, XtGrabNone);
    if (wm_stay_on_top && stay_on_top > 0)
	wm_stay_on_top(dpy,XtWindow(vtx_shell),1);

    if (first) {
	first = 0;
	XDefineCursor(dpy, XtWindow(vtx_shell), left_ptr);
	XDefineCursor(dpy, XtWindow(vtx_label), left_ptr);
    }
}
#endif

#ifdef HAVE_ZVBI
static void
display_subtitle(struct vbi_page *pg, struct vbi_rect *rect)
{
    static int first = 1;
    static Pixmap pix;
    Dimension x,y,w,h,sw,sh;

    if (NULL == pg) {
	XtPopdown(vtx->shell);
	return;
    }

    if (pix)
	XFreePixmap(dpy,pix);
    pix = vbi_export_pixmap(vtx,pg,rect);
    XtVaSetValues(vtx->tt,XmNlabelPixmap,pix,XmNlabelType,XmPIXMAP,NULL);

    XtVaGetValues(app_shell,XtNx,&x,XtNy,&y,XtNwidth,&w,XtNheight,&h,NULL);
    XtVaGetValues(vtx->shell,XtNwidth,&sw,XtNheight,&sh,NULL);
    XtVaSetValues(vtx->shell,XtNx,x+(w-sw)/2,XtNy,y+h-10-sh,NULL);
    XtPopup(vtx->shell, XtGrabNone);
    if (wm_stay_on_top && stay_on_top > 0)
	wm_stay_on_top(dpy,XtWindow(vtx->shell),1);

    if (first) {
	first = 0;
	XDefineCursor(dpy, XtWindow(vtx->shell), left_ptr);
	XDefineCursor(dpy, XtWindow(vtx->tt), left_ptr);
    }
}
#endif

/*----------------------------------------------------------------------*/

static void
new_attr(struct ng_attribute *attr, int val)
{
    struct motif_attribute *a;
    WidgetList children;
    Cardinal nchildren;
    unsigned int i;

    for (a = motif_attrs; NULL != a; a = a->next) {
	if (a->attr->id == attr->id)
	    break;
    }
    if (NULL == a)
	return;

    switch (attr->type) {
    case ATTR_TYPE_CHOICE:
	XtVaGetValues(a->widget,XtNchildren,&children,
		      XtNnumChildren,&nchildren,NULL);
	for (i = 0; i < nchildren; i++) {
	    XmToggleButtonSetState(children[i],a->attr->choices[i].nr == val,
				   False);
	}
	break;
    case ATTR_TYPE_BOOL:
	XmToggleButtonSetState(a->widget,val,False);
	break;
    case ATTR_TYPE_INTEGER:
	XmScaleSetValue(a->widget,val);
	break;
    }
    return;
}

static void
new_volume(void)
{
    struct ng_attribute *attr;

    attr = ng_attr_byid(attrs,ATTR_ID_VOLUME);
    if (NULL != attr)
	new_attr(attr,cur_attrs[ATTR_ID_VOLUME]);
    attr = ng_attr_byid(attrs,ATTR_ID_MUTE);
    if (NULL != attr)
	new_attr(attr,cur_attrs[ATTR_ID_MUTE]);
}

static void
new_freqtab(void)
{
    WidgetList children;
    Cardinal nchildren;
    XmStringTable tab;
    int i;

    /* update menu */
    XtVaGetValues(freq_menu,XtNchildren,&children,
		  XtNnumChildren,&nchildren,NULL);
    for (i = 0; chanlist_names[i].str != NULL; i++)
	XmToggleButtonSetState(children[i],chanlist_names[i].nr == chantab,
			       False);

    /* update property window */
    tab = malloc(chancount*sizeof(*tab));
    for (i = 0; i < chancount; i++)
	tab[i] = XmStringGenerate(chanlist[i].name,
				  NULL, XmMULTIBYTE_TEXT, NULL);
    XtVaSetValues(prop_channel,
		  XmNitemCount,chancount,
		  XmNitems,tab,
		  XmNselectedItem,tab[0],
		  NULL);
    for (i = 0; i < chancount; i++)
	XmStringFree(tab[i]);
    free(tab);
}

/*----------------------------------------------------------------------*/

static void
chan_key_eh(Widget widget, XtPointer client_data, XEvent *event, Boolean *cont)
{
    XKeyEvent *ke = (XKeyEvent*)event;
    KeySym sym;
    char *key;
    char line[64];

    sym = XkbKeycodeToKeysym(dpy,ke->keycode,0,0);
    if (NoSymbol == sym) {
	fprintf(stderr,"can't translate keycode %d\n",ke->keycode);
	return;
    }
    key = XKeysymToString(sym);

    line[0] = '\0';
    if (ke->state & ShiftMask)   strcpy(line,"Shift+");
    if (ke->state & ControlMask) strcpy(line,"Ctrl+");
    strcat(line,key);
    XmTextSetString(prop_key,line);
}

static void
chan_add_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmString str;
    int i;

    /* init stuff */
    prop_button = NULL;
    XmTextSetString(prop_name,"");
    XmTextSetString(prop_key,"");
    XmTextSetString(prop_group,"main");
    i = (-1 == cur_channel) ? 0 : cur_channel;
    str = XmStringGenerate(chanlist[i].name, NULL, XmMULTIBYTE_TEXT, NULL);
    XtVaSetValues(prop_channel,XmNselectedItem,str,NULL);
    XmStringFree(str);

    XtManageChild(prop_dlg);
}

static void
chan_edit_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmString str;
    int i;

    /* find channel */
    prop_button = clientdata;
    for (i = 0; i < count; i++)
	if (prop_button == channels[i]->button)
	    break;
    if (i == count)
	return;

    /* init stuff */
    XmTextSetString(prop_name,channels[i]->name);
    XmTextSetString(prop_key,channels[i]->key);
    XmTextSetString(prop_group,channels[i]->group);
    i = (-1 == channels[i]->channel) ? 0 : channels[i]->channel;
    str = XmStringGenerate(chanlist[i].name, NULL, XmMULTIBYTE_TEXT, NULL);
    XtVaSetValues(prop_channel,XmNselectedItem,str,NULL);
    XmStringFree(str);

    XtManageChild(prop_dlg);
}

static void
chan_apply_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    char *name, *key, *cname, *group;
    struct CHANNEL *c;
    XmString str;
    int i,channel;
    Widget msgbox;

    /* find channel */
    i = count;
    if (NULL != prop_button)
	for (i = 0; i < count; i++)
	    if (prop_button == channels[i]->button)
		break;

    name  = XmTextGetString(prop_name);
    key   = XmTextGetString(prop_key);
    group = XmTextGetString(prop_group);
    if (0 == strlen(group))
	group = "main";

    XtVaGetValues(prop_channel,XmNselectedItem,&str,NULL);
    cname = XmStringUnparse(str,NULL,XmMULTIBYTE_TEXT,XmMULTIBYTE_TEXT,
			    NULL,0,0);
    channel = lookup_channel(cname);

    if (0 == strlen(name)) {
	msgbox = XmCreateErrorDialog(prop_dlg,"no_name",NULL,0);
	XtUnmanageChild(XmMessageBoxGetChild(msgbox,XmDIALOG_HELP_BUTTON));
	XtUnmanageChild(XmMessageBoxGetChild(msgbox,XmDIALOG_CANCEL_BUTTON));
	XtAddCallback(msgbox,XmNokCallback,destroy_cb,msgbox);
	XtManageChild(msgbox);
	return;
    }

    if (i == count) {
	/* add */
	c = add_channel(name);
	if (strlen(key) > 0)
	    c->key = strdup(key);
	c->cname   = strdup(cname);
	c->group   = strdup(group);
	c->channel = channel;
    } else {
	/* update */
	c = channels[i];
	free(c->name);
	c->name = strdup(name);
	if (c->key) {
	    free(c->key);
	    c->key = NULL;
	}
	if (0 != strlen(key))
	    c->key = strdup(key);
	c->cname   = strdup(cname);
	c->group   = strdup(group);
	c->channel = channel;
	XtRemoveAllCallbacks(c->button, XmNactivateCallback);
	add_cmd_callback(c->button, XmNactivateCallback,
			 "setstation", c->name, NULL);
	toolkit_set_label(c->button,c->name);
    }
#if 0
    c->input   = cur_attrs[ATTR_ID_INPUT];
    c->fine    = cur_fine;
#endif
    channel_menu();
}

static void
chan_save_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    save_config();
}

static void
chan_tune_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmComboBoxCallbackStruct *cb = call_data;
    char *line;

    line = XmStringUnparse(cb->item_or_text,NULL,
			   XmMULTIBYTE_TEXT,XmMULTIBYTE_TEXT,
			   NULL,0,0);
    do_va_cmd(3,"setchannel",line);
}

static void
create_prop(void)
{
    Widget rowcol;

    prop_dlg = XmCreatePromptDialog(control_shell,"prop",NULL,0);
    XtAddEventHandler(XtParent(prop_dlg), (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    XtUnmanageChild(XmSelectionBoxGetChild(prop_dlg,XmDIALOG_SELECTION_LABEL));
    XtUnmanageChild(XmSelectionBoxGetChild(prop_dlg,XmDIALOG_HELP_BUTTON));
    XtUnmanageChild(XmSelectionBoxGetChild(prop_dlg,XmDIALOG_TEXT));

    rowcol = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, prop_dlg,
				     NULL);
    XtVaCreateManagedWidget("nameL", xmLabelWidgetClass, rowcol, NULL);
    prop_name = XtVaCreateManagedWidget("name", xmTextWidgetClass, rowcol,
					NULL);

    XtVaCreateManagedWidget("keyL", xmLabelWidgetClass, rowcol, NULL);
    prop_key = XtVaCreateManagedWidget("key", xmTextWidgetClass, rowcol,
				       NULL);
    XtAddEventHandler(prop_key, KeyPressMask, False, chan_key_eh, NULL);

    XtVaCreateManagedWidget("groupL", xmLabelWidgetClass, rowcol, NULL);
    prop_group = XtVaCreateManagedWidget("group", xmTextWidgetClass, rowcol,
					 NULL);

    XtVaCreateManagedWidget("channelL", xmLabelWidgetClass, rowcol, NULL);
    prop_channel = XtVaCreateManagedWidget("channel",xmComboBoxWidgetClass,
					   rowcol,NULL);
    XtAddCallback(prop_channel,XmNselectionCallback, chan_tune_cb, NULL);

    XtAddCallback(prop_dlg,XmNokCallback, chan_apply_cb, NULL);
}

/*----------------------------------------------------------------------*/

static void
filter_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct filter_attribute *f = clientdata;
    Widget w;

    switch (f->attr->type) {
    case ATTR_TYPE_INTEGER:
	XmScaleGetValue(f->widget,&f->value);
	break;
    case ATTR_TYPE_BOOL:
	f->value = XmToggleButtonGetState(f->widget);
	break;
    case ATTR_TYPE_CHOICE:
	w = NULL;
	XtVaGetValues(f->widget,XmNmenuHistory,&w,NULL);
	f->value = ng_attr_getint(f->attr,XtName(w));
	break;
    }
    f->attr->write(f->attr,f->value);
}

static void
filter_add_ctrls(Widget rc, struct ng_filter *filter,
		 struct ng_attribute *attr)
{
    struct filter_attribute *f;
    Widget opt,push;
    XmString str;
    Arg args[2];
    int i;

    f = malloc(sizeof(*f));
    memset(f,0,sizeof(*f));
    f->filter = filter;
    f->attr   = attr;
    f->next   = filter_attrs;
    f->value  = attr->read(attr);
    filter_attrs = f;

    str = XmStringGenerate((char*)attr->name, NULL, XmMULTIBYTE_TEXT, NULL);
    switch (attr->type) {
    case ATTR_TYPE_INTEGER:
	f->widget = XtVaCreateManagedWidget("scale",
					    xmScaleWidgetClass,rc,
					    XmNtitleString,str,
					    XmNminimum,attr->min,
					    XmNmaximum,attr->max,
					    XmNdecimalPoints,attr->points,
					    NULL);
	XmScaleSetValue(f->widget,f->value);
	XtAddCallback(f->widget,XmNvalueChangedCallback,filter_cb,f);
	break;
    case ATTR_TYPE_BOOL:
	f->widget = XtVaCreateManagedWidget("bool",
					    xmToggleButtonWidgetClass,rc,
					    XmNlabelString,str,
					    NULL);
	XmToggleButtonSetState(f->widget,f->value,False);
	XtAddCallback(f->widget,XmNvalueChangedCallback,filter_cb,f);
	break;
    case ATTR_TYPE_CHOICE:
	f->widget = XmCreatePulldownMenu(rc,"choiceM",NULL,0);
	XtSetArg(args[0],XmNsubMenuId,f->widget);
	XtSetArg(args[1],XmNlabelString,str);
	opt = XmCreateOptionMenu(rc,"choiceO",args,2);
	XtManageChild(opt);
	for (i = 0; attr->choices[i].str != NULL; i++) {
	    push = XtVaCreateManagedWidget(attr->choices[i].str,
					   xmPushButtonWidgetClass,f->widget,
					   NULL);
	    XtAddCallback(push,XmNactivateCallback,filter_cb,f);
	    if (f->value == attr->choices[i].nr)
		XtVaSetValues(f->widget,XmNmenuHistory,push,NULL);
	}
	break;
    }
    XmStringFree(str);
}

static void
create_filter_prop(void)
{
    Widget rc1,frame,rc2;
    XmString str;
    struct list_head *item;
    struct ng_filter *filter;
    int j;

    filter_shell = XtVaAppCreateShell("filter","MoTV",
				      topLevelShellWidgetClass,
				      dpy,
				      XtNclientLeader,app_shell,
				      XtNvisual,vinfo.visual,
				      XtNcolormap,colormap,
				      XtNdepth,vinfo.depth,
				      XmNdeleteResponse,XmDO_NOTHING,
				      NULL);
    XtAddEventHandler(filter_shell, (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    XmAddWMProtocolCallback(filter_shell,WM_DELETE_WINDOW,
			    popupdown_cb,filter_shell);

    rc1 = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, filter_shell,
				  NULL);

    list_for_each(item,&ng_filters) {
	filter = list_entry(item, struct ng_filter, list);
	if (NULL == filter->attrs)
	    continue;
	str = XmStringGenerate(filter->name, NULL,
			       XmMULTIBYTE_TEXT, NULL);
	frame = XtVaCreateManagedWidget("frame",xmFrameWidgetClass,rc1,NULL);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,frame,
				XmNlabelString,str,
				NULL);
	rc2 = XtVaCreateManagedWidget("rc",xmRowColumnWidgetClass,frame,NULL);
	XmStringFree(str);
	for (j = 0; NULL != filter->attrs[j].name; j++)
	    filter_add_ctrls(rc2,filter,&filter->attrs[j]);
    }
}

/*----------------------------------------------------------------------*/

static void
scroll_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct motif_attribute *a = clientdata;
    int ret;
    char val[10];

    XmScaleGetValue(a->widget,&ret);
    sprintf(val,"%d", ret);
    do_va_cmd(3,"setattr",a->attr->name,val);
}


void
add_cmd_callback(Widget widget, String callback,
		 char *command, const char *arg1, const char *arg2)
{
    struct DO_CMD *cmd;

    cmd = malloc(sizeof(*cmd));
    cmd->argc    = 1;
    cmd->argv[0] = command;
    if (arg1) {
	cmd->argc    = 2;
	cmd->argv[1] = (char*)arg1;
    }
    if (arg2) {
	cmd->argc    = 3;
	cmd->argv[2] = (char*)arg2;
    }
    XtAddCallback(widget,callback,command_cb,cmd);
    XtAddCallback(widget,XmNdestroyCallback,free_cb,cmd);
}

static Widget
add_cmd_menuitem(const char *n, int nr, Widget parent, const char *l,
		 char *k, char *a,  int toggle,
		 char *c, const char *arg1, const char *arg2)
{
    char name[21];
    XmString label,accel;
    Widget w;
    WidgetClass class;
    String callback;

    sprintf(name,"%.10s%d",n,nr);
    label = XmStringGenerate((char*)l, NULL, XmMULTIBYTE_TEXT, NULL);
    if (toggle) {
	class    = xmToggleButtonWidgetClass;
	callback = XmNvalueChangedCallback;
    } else {
	class    = xmPushButtonWidgetClass;
	callback = XmNactivateCallback;
    }
    if (k && a) {
	accel = XmStringGenerate(k, NULL, XmMULTIBYTE_TEXT, NULL);
	w = XtVaCreateManagedWidget(name,class,parent,
				    XmNlabelString,label,
				    XmNacceleratorText,accel,
				    XmNaccelerator,a,
				    NULL);
    } else {
	w = XtVaCreateManagedWidget(name,class,parent,
				    XmNlabelString,label,
				    NULL);
    }
    if (toggle)
	XtVaSetValues(w,XmNindicatorType,toggle,NULL);
    if (c)
	add_cmd_callback(w,callback,c,arg1,arg2);
    XmStringFree(label);
    return w;
}

static void
add_attr_option(Widget menu, struct ng_attribute *attr)
{
    int i;
    struct motif_attribute *a;

    a = malloc(sizeof(*a));
    memset(a,0,sizeof(*a));
    a->attr = attr;

    switch (attr->type) {
    case ATTR_TYPE_CHOICE:
	a->widget = XmCreatePulldownMenu(menu,(char*)attr->name,NULL,0);
	XtVaCreateManagedWidget(attr->name,xmCascadeButtonWidgetClass,menu,
				XmNsubMenuId,a->widget,NULL);
	for (i = 0; attr->choices[i].str != NULL; i++)
	    add_cmd_menuitem(attr->name, i, a->widget,
			     attr->choices[i].str, NULL, NULL, XmONE_OF_MANY,
			     "setattr",attr->name,attr->choices[i].str);
	break;
    case ATTR_TYPE_BOOL:
	a->widget = XtVaCreateManagedWidget(attr->name,
					    xmToggleButtonWidgetClass,menu,
					    NULL);
	add_cmd_callback(a->widget,XmNvalueChangedCallback,
			 "setattr", attr->name, "toggle");
	break;
    }
    a->next = motif_attrs;
    motif_attrs = a;
}

/* use more columns until the menu fits onto the screen */
static void
menu_cols_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    Dimension height,num;
    int i = 8;

    for (;i;i--) {
	XtVaGetValues(widget,
		      XtNheight,&height,
		      XmNnumColumns,&num,
		      NULL);
	if (height < XtScreen(widget)->height - 100)
	    break;
	XtVaSetValues(widget,XmNnumColumns,num+1,NULL);
    }
}

void
channel_menu(void)
{
    struct {
	char *name;
	Widget menu1;
	Widget menu2;
    } *sub = NULL;
    int subs = 0;

    Widget menu1,menu2;
    char ctrl[16],key[32],accel[64];
    int  i,j;

    if (0 == st_menu2) {
	st_menu2 = XmCreatePopupMenu(tv,"stationsM",NULL,0);
	XtAddEventHandler(tv,ButtonPressMask,False,popup_eh,st_menu2);
	XtAddCallback(st_menu2,XmNmapCallback,menu_cols_cb,NULL);
    }

    /* delete entries */
    delete_children(st_menu1);
    delete_children(st_menu2);

    /* rebuild everything */
    for (i = 0; i < count; i++) {
	if (channels[i]->key) {
	    if (2 == sscanf(channels[i]->key,
			    "%15[A-Za-z0-9_]+%31[A-Za-z0-9_]",
			    ctrl,key)) {
		sprintf(accel,"%s%s",ctrl,key);
	    } else {
		sprintf(accel,"%s",channels[i]->key);
	    }
	} else {
	    accel[0] = 0;
	}

	menu1 = st_menu1;
	menu2 = st_menu2;
	if (0 != strcmp(channels[i]->group,"main")) {
	    for (j = 0; j < subs; j++)
		if (0 == strcmp(channels[i]->group,sub[j].name))
		    break;
	    if (j == subs) {
		subs++;
		sub = realloc(sub, subs * sizeof(*sub));
		sub[j].name  = channels[i]->group;
		sub[j].menu1 = XmCreatePulldownMenu(st_menu1,
						    channels[i]->group,
						    NULL,0);
		sub[j].menu2 = XmCreatePulldownMenu(st_menu2,
						    channels[i]->group,
						    NULL,0);
		XtVaCreateManagedWidget(channels[i]->group,
					xmCascadeButtonWidgetClass, st_menu1,
					XmNsubMenuId, sub[j].menu1,
					NULL);
		XtVaCreateManagedWidget(channels[i]->group,
					xmCascadeButtonWidgetClass, st_menu2,
					XmNsubMenuId, sub[j].menu2,
					NULL);
	    }
	    menu1 = sub[j].menu1;
	    menu2 = sub[j].menu2;
	}

	add_cmd_menuitem("station", i, menu1,
			 channels[i]->name, channels[i]->key, accel, FALSE,
			 "setstation",channels[i]->name,NULL);
	add_cmd_menuitem("station", i, menu2,
			 channels[i]->name, channels[i]->key, accel, FALSE,
			 "setstation",channels[i]->name,NULL);
	if (NULL == channels[i]->button)
	    chan_makebutton(channels[i]);
    }
    free(sub);
    calc_frequencies();
}

static void
chan_resize_eh(Widget widget, XtPointer client_data, XEvent *event, Boolean *d)
{
    Widget clip;
    Dimension width;

    XtVaGetValues(chan_viewport,XmNclipWindow,&clip,NULL);
    XtVaGetValues(clip,XtNwidth,&width,NULL);
    XtVaSetValues(chan_box,XtNwidth,width,NULL);
}

static void
chan_del_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    Widget button = clientdata;
    int i;

    for (i = 0; i < count; i++)
	if (button == channels[i]->button)
	    break;
    if (i == count)
	return;
    XtDestroyWidget(channels[i]->button);
    del_channel(i);
    if (cur_sender == i)
	cur_sender = -1;
    if (cur_sender > i)
	cur_sender--;
    channel_menu();
}

static void
chan_makebutton(struct CHANNEL *channel)
{
    Widget menu,push;

    if (NULL != channel->button)
	return;

    channel->button =
	XtVaCreateManagedWidget(channel->name,
				xmPushButtonWidgetClass, chan_box,
				NULL);
    add_cmd_callback(channel->button, XmNactivateCallback,
		     "setstation", channel->name, NULL);
    menu = XmCreatePopupMenu(channel->button,"menu",NULL,0);
    XtAddEventHandler(channel->button,ButtonPressMask,False,popup_eh,menu);
    push = XtVaCreateManagedWidget("del",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,chan_del_cb,channel->button);
    push = XtVaCreateManagedWidget("edit",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,chan_edit_cb,channel->button);
}

static void
create_control(void)
{
    Widget form,menubar,menu,smenu,push,clip,tool,rc,fr;
    char action[256];
    int i;

    control_shell = XtVaAppCreateShell("control","MoTV",
				       topLevelShellWidgetClass,
				       dpy,
				       XtNclientLeader,app_shell,
				       XtNvisual,vinfo.visual,
				       XtNcolormap,colormap,
				       XtNdepth,vinfo.depth,
				       XmNdeleteResponse,XmDO_NOTHING,
				       NULL);
    XtAddEventHandler(control_shell, (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    XmAddWMProtocolCallback(control_shell,WM_DELETE_WINDOW,
			    popupdown_cb,control_shell);
    form = XtVaCreateManagedWidget("form", xmFormWidgetClass, control_shell,
				   NULL);

    /* menbar */
    menubar = XmCreateMenuBar(form,"menubar",NULL,0);
    XtManageChild(menubar);

    tool = XtVaCreateManagedWidget("tool",xmRowColumnWidgetClass,form,NULL);

    /* status line */
    rc = XtVaCreateManagedWidget("status", xmRowColumnWidgetClass, form,
				 NULL);
    fr = XtVaCreateManagedWidget("f", xmFrameWidgetClass, rc, NULL);
    st_freq = XtVaCreateManagedWidget("freq", xmLabelWidgetClass, fr, NULL);
    fr = XtVaCreateManagedWidget("f", xmFrameWidgetClass, rc, NULL);
    st_chan = XtVaCreateManagedWidget("chan", xmLabelWidgetClass, fr, NULL);
    fr = XtVaCreateManagedWidget("f", xmFrameWidgetClass, rc, NULL);
    st_name = XtVaCreateManagedWidget("name", xmLabelWidgetClass, fr, NULL);
    fr = XtVaCreateManagedWidget("f", xmFrameWidgetClass, rc, NULL);
    st_key = XtVaCreateManagedWidget("key", xmLabelWidgetClass, fr, NULL);
#if 0
    fr = XtVaCreateManagedWidget("f", xmFrameWidgetClass, rc, NULL);
    st_other = XtVaCreateManagedWidget("other", xmLabelWidgetClass, fr, NULL);
#endif

    /* channel buttons */
    chan_viewport = XmCreateScrolledWindow(form,"view",NULL,0);
    XtManageChild(chan_viewport);
    chan_box = XtVaCreateManagedWidget("box", xmRowColumnWidgetClass,
				       chan_viewport, NULL);
    XtVaGetValues(chan_viewport,XmNclipWindow,&clip,NULL);
    XtAddEventHandler(clip,StructureNotifyMask, True,
		      chan_resize_eh, NULL);

    /* menu - file */
    menu = XmCreatePulldownMenu(menubar,"fileM",NULL,0);
    XtVaCreateManagedWidget("file",xmCascadeButtonWidgetClass,menubar,
			    XmNsubMenuId,menu,NULL);
    push = XtVaCreateManagedWidget("rec",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,popupdown_cb,str_shell);
    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,menu,NULL);
    push = XtVaCreateManagedWidget("quit",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,ExitCB,NULL);

#if 1
    /* menu - edit */
    if (f_drv & CAN_CAPTURE) {
	menu = XmCreatePulldownMenu(menubar,"editM",NULL,0);
	XtVaCreateManagedWidget("edit",xmCascadeButtonWidgetClass,menubar,
				XmNsubMenuId,menu,NULL);
	push = XtVaCreateManagedWidget("copy",xmPushButtonWidgetClass,menu,
				       NULL);
	XtAddCallback(push,XmNactivateCallback,action_cb,"Ipc(clipboard)");
    }
#endif

    /* menu - tv stations */
    st_menu1 = XmCreatePulldownMenu(menubar,"stationsM",NULL,0);
    XtVaCreateManagedWidget("stations",xmCascadeButtonWidgetClass,menubar,
			    XmNsubMenuId,st_menu1,NULL);
    XtAddCallback(st_menu1,XmNmapCallback,menu_cols_cb,NULL);

    /* menu - tools (name?) */
    menu = XmCreatePulldownMenu(menubar,"toolsM",NULL,0);
    XtVaCreateManagedWidget("tools",xmCascadeButtonWidgetClass,menubar,
			    XmNsubMenuId,menu,NULL);
    w_full = XtVaCreateManagedWidget("full",xmToggleButtonWidgetClass,menu,
				     NULL);
    XtAddCallback(w_full,XmNvalueChangedCallback,action_cb,
		  "Command(fullscreen)");
    push = XtVaCreateManagedWidget("ontop",xmToggleButtonWidgetClass,menu,
				   NULL);
    b_ontop = push;
    XtAddCallback(push,XmNvalueChangedCallback,ontop_cb,NULL);
    push = XtVaCreateManagedWidget("levels",xmPushButtonWidgetClass,menu,
				   NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Popup(levels)");
    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,menu,NULL);
    push = XtVaCreateManagedWidget("st_up",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(setstation,next)");
    push = XtVaCreateManagedWidget("st_dn",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(setstation,prev)");

    /* menu - tools / tuner */
    smenu = XmCreatePulldownMenu(menu,"tuneM",NULL,0);
    XtVaCreateManagedWidget("tune",xmCascadeButtonWidgetClass,menu,
			    XmNsubMenuId,smenu,NULL);
    push = XtVaCreateManagedWidget("ch_up",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(setchannel,next)");
    push = XtVaCreateManagedWidget("ch_dn",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(setchannel,prev)");
    push = XtVaCreateManagedWidget("fi_up",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(setchannel,fine_up)");
    push = XtVaCreateManagedWidget("fi_dn",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(setchannel,fine_down)");

    /* menu - tools / capture */
    smenu = XmCreatePulldownMenu(menu,"grabM",NULL,0);
    XtVaCreateManagedWidget("grab",xmCascadeButtonWidgetClass,menu,
			    XmNsubMenuId,smenu,NULL);
    push = XtVaCreateManagedWidget("ppm_f",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(snap,ppm,full)");
    push = XtVaCreateManagedWidget("ppm_w",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(snap,ppm,win)");
    push = XtVaCreateManagedWidget("jpg_f",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(snap,jpeg,full)");
    push = XtVaCreateManagedWidget("jpg_w",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(snap,jpeg,win)");

    /* menu - tools / aspect ratio */
    smenu = XmCreatePulldownMenu(menu,"ratioM",NULL,0);
    XtVaCreateManagedWidget("ratio",xmCascadeButtonWidgetClass,menu,
			    XmNsubMenuId,smenu,NULL);
    push = XtVaCreateManagedWidget("r_no",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Ratio(0,0)");
    push = XtVaCreateManagedWidget("r_43",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Ratio(4,3)");

    /* menu - tools / launch */
    launch_menu = XmCreatePulldownMenu(menu,"launchM",NULL,0);
    XtVaCreateManagedWidget("launch",xmCascadeButtonWidgetClass,menu,
			    XmNsubMenuId,launch_menu,NULL);

#ifdef HAVE_ZVBI
    /* menu - tools / subtitles */
    smenu = XmCreatePulldownMenu(menu,"subM",NULL,0);
    XtVaCreateManagedWidget("sub",xmCascadeButtonWidgetClass,menu,
			    XmNsubMenuId,smenu,NULL);
    push = XtVaCreateManagedWidget("s_off",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Vtx(stop)");
    push = XtVaCreateManagedWidget("s_150",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Vtx(start,150)");
    push = XtVaCreateManagedWidget("s_333",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Vtx(start,333)");
    push = XtVaCreateManagedWidget("s_777",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Vtx(start,777)");
    push = XtVaCreateManagedWidget("s_801",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Vtx(start,801)");
    push = XtVaCreateManagedWidget("s_888",xmPushButtonWidgetClass,smenu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Vtx(start,888)");
#endif

    /* menu - internal options */
    opt_menu = menu = XmCreatePulldownMenu(menubar,"optionsM",NULL,0);
    XtVaCreateManagedWidget("options",xmCascadeButtonWidgetClass,menubar,
			    XmNsubMenuId,menu,NULL);
    push = XtVaCreateManagedWidget("add",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,chan_add_cb,NULL);
#ifdef HAVE_ZVBI
    push = XtVaCreateManagedWidget("scan",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,chscan_cb,NULL);
#endif
#if 1
    push = XtVaCreateManagedWidget("pref",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,pref_manage_cb,NULL);
#endif
    push = XtVaCreateManagedWidget("save",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,chan_save_cb,NULL);
    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,menu,NULL);

    cap_menu = XmCreatePulldownMenu(menu,"captureM",NULL,0);
    XtVaCreateManagedWidget("capture",xmCascadeButtonWidgetClass,menu,
			    XmNsubMenuId,cap_menu,NULL);
    push = XtVaCreateManagedWidget("overlay",xmToggleButtonWidgetClass,
				   cap_menu,XmNindicatorType,XmONE_OF_MANY,
				   NULL);
    add_cmd_callback(push,XmNvalueChangedCallback,"capture","overlay",NULL);
    push = XtVaCreateManagedWidget("grabdisplay",xmToggleButtonWidgetClass,
				   cap_menu,XmNindicatorType,XmONE_OF_MANY,
				   NULL);
    add_cmd_callback(push,XmNvalueChangedCallback,"capture","grab",NULL);
    push = XtVaCreateManagedWidget("none",xmToggleButtonWidgetClass,
				   cap_menu,XmNindicatorType,XmONE_OF_MANY,
				   NULL);
    add_cmd_callback(push,XmNvalueChangedCallback,"capture","off",NULL);

    freq_menu = XmCreatePulldownMenu(menu,"freqM",NULL,0);
    XtVaCreateManagedWidget("freq",xmCascadeButtonWidgetClass,menu,
			    XmNsubMenuId,freq_menu,NULL);
    for (i = 0; chanlist_names[i].str != NULL; i++) {
	push = XtVaCreateManagedWidget(chanlist_names[i].str,
				       xmToggleButtonWidgetClass,freq_menu,
				       XmNindicatorType,XmONE_OF_MANY,
				       NULL);
	add_cmd_callback(push,XmNvalueChangedCallback,
			 "setfreqtab", chanlist_names[i].str, NULL);
    }
    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,menu,NULL);

    /* menu - filter */
    if ((f_drv & CAN_CAPTURE)  &&  !list_empty(&ng_filters))  {
	struct list_head *item;
	struct ng_filter *filter;

	menu = XmCreatePulldownMenu(menubar,"filterM",NULL,0);
	XtVaCreateManagedWidget("filter",xmCascadeButtonWidgetClass,menubar,
				XmNsubMenuId,menu,NULL);
	push = XtVaCreateManagedWidget("fnone",
				       xmPushButtonWidgetClass,menu,
				       NULL);
	XtAddCallback(push,XmNactivateCallback,action_cb,"Filter()");
	list_for_each(item,&ng_filters) {
	    filter = list_entry(item, struct ng_filter, list);
	    push = XtVaCreateManagedWidget(filter->name,
					   xmPushButtonWidgetClass,menu,
					   NULL);
	    sprintf(action,"Filter(%s)",filter->name);
	    XtAddCallback(push,XmNactivateCallback,action_cb,strdup(action));
	}
	XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,menu,NULL);
	push = XtVaCreateManagedWidget("fopts",xmPushButtonWidgetClass,menu,
				       NULL);
	XtAddCallback(push,XmNactivateCallback,action_cb,"Popup(filter)");
    }

    /* menu - help */
    menu = XmCreatePulldownMenu(menubar,"helpM",NULL,0);
    push = XtVaCreateManagedWidget("help",xmCascadeButtonWidgetClass,menubar,
				   XmNsubMenuId,menu,NULL);
    XtVaSetValues(menubar,XmNmenuHelpWidget,push,NULL);
    push = XtVaCreateManagedWidget("man",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,man_cb,"motv");
    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,menu,NULL);
    push = XtVaCreateManagedWidget("about",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,about_cb,NULL);

    /* toolbar */
    push = XtVaCreateManagedWidget("prev",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(setstation,prev)");
    push = XtVaCreateManagedWidget("next",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(setstation,next)");

    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,tool,NULL);
    push = XtVaCreateManagedWidget("snap",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(snap,jpeg,full)");
    push = XtVaCreateManagedWidget("movie",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,popupdown_cb,str_shell);
    push = XtVaCreateManagedWidget("mute",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,
		  "Command(volume,mute,toggle)");

    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,tool,NULL);
    push = XtVaCreateManagedWidget("exit",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,ExitCB,NULL);
}

static void create_attr_widgets(void)
{
    struct ng_attribute *attr;
    Widget push;
    XmString label,accel;
    char str[100],key[32],ctrl[16];
    Arg argv[8];
    Cardinal argc;
    int i;

    /* menu - driver options
       input + norm */
    attr = ng_attr_byid(attrs,ATTR_ID_NORM);
    if (NULL != attr)
	add_attr_option(opt_menu, attr);
    attr = ng_attr_byid(attrs,ATTR_ID_INPUT);
    if (NULL != attr)
	add_attr_option(opt_menu,attr);
    attr = ng_attr_byid(attrs,ATTR_ID_AUDIO_MODE);
    if (NULL != attr)
	add_attr_option(opt_menu,attr);
    for (attr = attrs; attr->name != NULL; attr++) {
	if (attr->id < ATTR_ID_COUNT)
	    continue;
	if (attr->type != ATTR_TYPE_CHOICE)
	    continue;
	add_attr_option(opt_menu,attr);
    }

    /* bools */
    attr = ng_attr_byid(attrs,ATTR_ID_MUTE);
    if (NULL != attr)
	add_attr_option(opt_menu,attr);
    for (attr = attrs; attr->name != NULL; attr++) {
	if (attr->id < ATTR_ID_COUNT)
	    continue;
	if (attr->type != ATTR_TYPE_BOOL)
	    continue;
	add_attr_option(opt_menu,attr);
    }

    /* integer (scales) */
    push = XtVaCreateManagedWidget("scale",xmPushButtonWidgetClass,
				   opt_menu,NULL);
    XtAddCallback(push,XmNactivateCallback,action_cb,"Popup(scale)");

    /* launch menu entries */
    for (i = 0; i < nlaunch; i++) {
	argc  = 0;
	label = NULL;
	accel = NULL;

	label = XmStringGenerate(launch[i].name,NULL,XmMULTIBYTE_TEXT,NULL);
	XtSetArg(argv[argc],XmNlabelString,label); argc++;
	if (NULL != launch[i].key) {
	    accel = XmStringGenerate(launch[i].key,NULL,XmMULTIBYTE_TEXT,NULL);
	    XtSetArg(argv[argc],XmNacceleratorText,accel); argc++;
	    if (2 == sscanf(launch[i].key,"%15[A-Za-z0-9_]+%31[A-Za-z0-9_]",
			    ctrl,key))
		sprintf(str,"%s%s",ctrl,key);
	    else
		sprintf(str,"%s",launch[i].key);
	    XtSetArg(argv[argc],XmNaccelerator,str); argc++;
	}
	push = XtCreateManagedWidget(launch[i].name,
				     xmPushButtonWidgetClass,
				     launch_menu,argv,argc);
	if (label)
	    XmStringFree(label);
	if (accel)
	    XmStringFree(accel);

	/* translations */
	strcat(str,": Launch(");
	strcat(str,launch[i].name);
	strcat(str,")");
	XtOverrideTranslations(tv,XtParseTranslationTable(str));

	/* button callback */
	sprintf(str,"Launch(%s)",launch[i].name);
	XtAddCallback(push,XmNactivateCallback,action_cb,
		      strdup(str));
    }
}

static void
create_scale(void)
{
    Widget form,attach;
    struct ng_attribute *attr;
    struct motif_attribute *a;
    int vol = 0;
    XmString str;

    scale_shell = XtVaAppCreateShell("scale","MoTV",
				     topLevelShellWidgetClass,
				     dpy,
				     XtNclientLeader,app_shell,
				     XtNvisual,vinfo.visual,
				     XtNcolormap,colormap,
				     XtNdepth,vinfo.depth,
				     XmNdeleteResponse,XmDO_NOTHING,
				     NULL);
    XtAddEventHandler(scale_shell, (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    XmAddWMProtocolCallback(scale_shell,WM_DELETE_WINDOW,
			    popupdown_cb,scale_shell);
    form = XtVaCreateManagedWidget("form", xmFormWidgetClass, scale_shell,
				   NULL);
    /* scales */
    attach = NULL;
    for (attr = attrs; attr->name != NULL; attr++) {
	if (attr->type != ATTR_TYPE_INTEGER)
	    continue;
	if (attr->id == ATTR_ID_VOLUME) {
	    if (vol)
		continue;
	    vol++;
	}
	a = malloc(sizeof(*a));
	memset(a,0,sizeof(*a));
	a->attr = attr;
	a->next = motif_attrs;
	motif_attrs = a;
	if (a->attr->id < ATTR_ID_COUNT) {
	    a->widget = XtVaCreateManagedWidget(attr->name,
						xmScaleWidgetClass, form,
						XmNtopWidget,attach,
						XmNminimum,attr->min,
						XmNmaximum,attr->max,
						XmNdecimalPoints,attr->points,
						NULL);
	} else {
	    str = XmStringGenerate((char*)attr->name, NULL,
				   XmMULTIBYTE_TEXT, NULL);
	    a->widget = XtVaCreateManagedWidget(attr->name,
						xmScaleWidgetClass, form,
						XmNtopWidget,attach,
						XmNtitleString,str,
						XmNminimum,attr->min,
						XmNmaximum,attr->max,
						XmNdecimalPoints,attr->points,
						NULL);
	    XmStringFree(str);
	}
	XtAddCallback(a->widget,XmNvalueChangedCallback,scroll_cb,a);
	XtAddCallback(a->widget,XmNdragCallback,scroll_cb,a);
	attach = a->widget;
    }
}

/*----------------------------------------------------------------------*/

#if 0
void create_chanwin(void)
{
    Widget form,clip,menu,push;

}
#endif

/* gets called before switching away from a channel */
static void
pixit(void)
{
    Pixmap pix;
    struct ng_video_fmt fmt;
    struct ng_video_buf *buf;

    if (cur_sender == -1)
	return;

    /* save picture settings */
    channels[cur_sender]->color    = cur_attrs[ATTR_ID_COLOR];
    channels[cur_sender]->bright   = cur_attrs[ATTR_ID_BRIGHT];
    channels[cur_sender]->hue      = cur_attrs[ATTR_ID_HUE];
    channels[cur_sender]->contrast = cur_attrs[ATTR_ID_CONTRAST];
    channels[cur_sender]->input    = cur_attrs[ATTR_ID_INPUT];
    channels[cur_sender]->norm     = cur_attrs[ATTR_ID_NORM];

    if (0 == pix_width || 0 == pix_height)
	return;

    /* capture mini picture */
    if (!(f_drv & CAN_CAPTURE))
	return;

    video_gd_suspend();
    memset(&fmt,0,sizeof(fmt));
    fmt.fmtid  = x11_dpy_fmtid;
    fmt.width  = pix_width;
    fmt.height = pix_height;
    if (NULL == (buf = ng_grabber_get_image(&fmt)))
	goto done1;
    buf = ng_filter_single(cur_filter,buf);
    if (0 == (pix = x11_create_pixmap(dpy,&vinfo,buf)))
	goto done2;
    x11_label_pixmap(dpy,colormap,pix,buf->fmt.height,
		     channels[cur_sender]->name);
    XtVaSetValues(channels[cur_sender]->button,
		  XmNlabelPixmap,pix,
		  XmNlabelType,XmPIXMAP,
		  NULL);
    if (channels[cur_sender]->pixmap)
	XFreePixmap(dpy,channels[cur_sender]->pixmap);
    channels[cur_sender]->pixmap = pix;
 done2:
    ng_release_video_buf(buf);
 done1:
    video_gd_restart();
}

/*----------------------------------------------------------------------*/

static void
do_capture(int from, int to, int tmp_switch)
{
    static int niced = 0;
    WidgetList children;

    /* off */
    switch (from) {
    case CAPTURE_GRABDISPLAY:
	video_gd_stop();
	if (!tmp_switch)
	    XClearArea(XtDisplay(tv), XtWindow(tv), 0,0,0,0, True);
	break;
    case CAPTURE_OVERLAY:
	video_overlay(0);
	break;
    }

    /* on */
    switch (to) {
    case CAPTURE_GRABDISPLAY:
	if (!niced)
	    nice(niced = 10);
	video_gd_start();
	break;
    case CAPTURE_OVERLAY:
	video_overlay(1);
	break;
    }

    /* update menu */
    XtVaGetValues(cap_menu,XtNchildren,&children,NULL);
    XmToggleButtonSetState(children[0],to == CAPTURE_OVERLAY,    False);
    XmToggleButtonSetState(children[1],to == CAPTURE_GRABDISPLAY,False);
    XmToggleButtonSetState(children[2],to == CAPTURE_OFF,        False);
}

static void
do_motif_fullscreen(void)
{
    XmToggleButtonSetState(w_full,!fs,False);
    do_fullscreen();
}

/*----------------------------------------------------------------------*/

struct FILE_DATA {
    Widget filebox;
    Widget text;
    Widget push;
};

static void
file_done_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmFileSelectionBoxCallbackStruct *cb = call_data;
    struct FILE_DATA *h = clientdata;
    char *line;

    if (cb->reason == XmCR_OK) {
	line = XmStringUnparse(cb->value,NULL,
			       XmMULTIBYTE_TEXT,XmMULTIBYTE_TEXT,
			       NULL,0,0);
	XmTextSetString(h->text,line);
    }
    XtUnmanageChild(h->filebox);
}

static void
file_browse_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct FILE_DATA *h = clientdata;
    Widget help;
    /* XmString str; */

    if (NULL == h->filebox) {
	h->filebox = XmCreateFileSelectionDialog(h->push,"filebox",NULL,0);
	help = XmFileSelectionBoxGetChild(h->filebox,XmDIALOG_HELP_BUTTON);
	XtUnmanageChild(help);
	XtAddCallback(h->filebox,XmNokCallback,file_done_cb,h);
	XtAddCallback(h->filebox,XmNcancelCallback,file_done_cb,h);
    }
#if 0
    str = XmStringGenerate(XmTextGetString(h->text),
			   NULL, XmMULTIBYTE_TEXT, NULL);
    XtVaSetValues(h->filebox,XmNdirMask,str,NULL);
    XmStringFree(str);
#endif
    XtManageChild(h->filebox);
}

static void
exec_player_cb(Widget widget, XtPointer client_data, XtPointer calldata)
{
    char *filename;

    filename = XmTextGetString(m_fvideo);
    exec_player(filename);
}

static void
create_strwin(void)
{
    Widget form,push,rowcol,frame,fbox;
    struct FILE_DATA *h;
    Arg args[2];

    str_shell = XtVaAppCreateShell("streamer", "MoTV",
				   topLevelShellWidgetClass,
				   dpy,
				   XtNclientLeader,app_shell,
				   XtNvisual,vinfo.visual,
				   XtNcolormap,colormap,
				   XtNdepth,vinfo.depth,
				   XmNdeleteResponse,XmDO_NOTHING,
				   NULL);
    XtAddEventHandler(str_shell, (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    XmAddWMProtocolCallback(str_shell,WM_DELETE_WINDOW,
			    popupdown_cb,str_shell);
    form = XtVaCreateManagedWidget("form", xmFormWidgetClass, str_shell,
				   NULL);

    /* driver */
    frame = XtVaCreateManagedWidget("driverF", xmFrameWidgetClass, form, NULL);
    XtVaCreateManagedWidget("driverL",xmLabelWidgetClass,frame,NULL);
    driver_menu = XmCreatePulldownMenu(form,"driverM",NULL,0);
    XtSetArg(args[0],XmNsubMenuId,driver_menu);
    driver_option = XmCreateOptionMenu(frame,"driver",args,1);
    XtManageChild(driver_option);

    /* video format + frame rate */
    frame = XtVaCreateManagedWidget("videoF", xmFrameWidgetClass, form, NULL);
    XtVaCreateManagedWidget("videoL",xmLabelWidgetClass,frame,NULL);
    rowcol = XtVaCreateManagedWidget("videoB",xmRowColumnWidgetClass,
				     frame,NULL);
    video_menu = XmCreatePulldownMenu(rowcol,"videoM",NULL,0);
    XtSetArg(args[0],XmNsubMenuId,video_menu);
    video_option = XmCreateOptionMenu(rowcol,"video",args,1);
    XtManageChild(video_option);
    XtVaCreateManagedWidget("fpsL",xmLabelWidgetClass,rowcol,NULL);
    m_fps = XtVaCreateManagedWidget("fps",xmComboBoxWidgetClass,rowcol,NULL);

    /* audio format + sample rate */
    frame = XtVaCreateManagedWidget("audioF", xmFrameWidgetClass, form, NULL);
    XtVaCreateManagedWidget("audioL",xmLabelWidgetClass,frame,NULL);
    rowcol = XtVaCreateManagedWidget("audioB",xmRowColumnWidgetClass,
				     frame,NULL);
    audio_menu = XmCreatePulldownMenu(rowcol,"audioM",NULL,0);
    XtSetArg(args[0],XmNsubMenuId,audio_menu);
    audio_option = XmCreateOptionMenu(rowcol,"audio",args,1);
    XtManageChild(audio_option);
    XtVaCreateManagedWidget("rateL",xmLabelWidgetClass,rowcol,NULL);
    m_rate = XtVaCreateManagedWidget("rate",xmComboBoxWidgetClass,rowcol,NULL);

    /* filenames */
    frame = XtVaCreateManagedWidget("fileF", xmFrameWidgetClass, form, NULL);
    XtVaCreateManagedWidget("fileL",xmLabelWidgetClass,frame,NULL);
    fbox = XtVaCreateManagedWidget("fbox",xmRowColumnWidgetClass,
				   frame,NULL);

    rowcol = XtVaCreateManagedWidget("fvideoB",xmRowColumnWidgetClass,
				     fbox,NULL);
    XtVaCreateManagedWidget("fvideoL",xmLabelWidgetClass,rowcol,NULL);
    h = malloc(sizeof(*h));
    memset(h,0,sizeof(*h));
    h->text = XtVaCreateManagedWidget("fvideo",xmTextWidgetClass,
				      rowcol,NULL);
    m_fvideo = h->text;
    h->push = XtVaCreateManagedWidget("files",xmPushButtonWidgetClass,rowcol,
				      NULL);
    XtAddCallback(h->push,XmNactivateCallback,file_browse_cb,h);

    rowcol = XtVaCreateManagedWidget("faudioB",xmRowColumnWidgetClass,
				     fbox,NULL);
    m_faudioL = XtVaCreateManagedWidget("faudioL",xmLabelWidgetClass,rowcol,
					NULL);
    h = malloc(sizeof(*h));
    memset(h,0,sizeof(*h));
    h->text = XtVaCreateManagedWidget("faudio",xmTextWidgetClass,rowcol,
				      NULL);
    m_faudio = h->text;
    h->push = XtVaCreateManagedWidget("files",xmPushButtonWidgetClass,rowcol,
				      NULL);
    m_faudioB = h->push;
    XtAddCallback(h->push,XmNactivateCallback,file_browse_cb,h);

    /* seperator, buttons */
    m_status = XtVaCreateManagedWidget("status",xmLabelWidgetClass,form,NULL);
    rowcol = XtVaCreateManagedWidget("buttons",xmRowColumnWidgetClass,form,
				   NULL);
    push = XtVaCreateManagedWidget("rec", xmPushButtonWidgetClass, rowcol,
				   NULL);
    add_cmd_callback(push,XmNactivateCallback, "movie","start",NULL);
    push = XtVaCreateManagedWidget("stop", xmPushButtonWidgetClass, rowcol,
				   NULL);
    add_cmd_callback(push,XmNactivateCallback, "movie","stop",NULL);
    push = XtVaCreateManagedWidget("play", xmPushButtonWidgetClass, rowcol,
				   NULL);
    XtAddCallback(push,XmNactivateCallback,exec_player_cb,NULL);
    push = XtVaCreateManagedWidget("cancel", xmPushButtonWidgetClass, rowcol,
				   NULL);
    XtAddCallback(push,XmNactivateCallback, popupdown_cb, str_shell);
}

static void
update_movie_menus(void)
{
    struct list_head *item;
    struct ng_writer *writer;
    static int first = 1;
    Widget push;
    XmString str;
    Boolean sensitive;
    int i;

    /* drivers  */
    if (first) {
	first = 0;
	i = 0;
	list_for_each(item,&ng_writers) {
	    writer = list_entry(item, struct ng_writer, list);
	    str = XmStringGenerate((char*)writer->desc,
				   NULL, XmMULTIBYTE_TEXT, NULL);
	    push = XtVaCreateManagedWidget(writer->name,
					   xmPushButtonWidgetClass,driver_menu,
					   XmNlabelString,str,
					   NULL);
	    XmStringFree(str);
	    add_cmd_callback(push,XmNactivateCallback,
			     "movie","driver",writer->name);
	    if (NULL == movie_driver ||
		(NULL != mov_driver && 0 == strcasecmp(mov_driver,writer->name))) {
		movie_driver = writer;
		i_movie_driver = i;
		XtVaSetValues(driver_option,XmNmenuHistory,push,NULL);
	    }
	    i++;
	}
    }

    /* audio formats */
    delete_children(audio_menu);
    for (i = 0; NULL != movie_driver->audio[i].name; i++) {
	str = XmStringGenerate
	    ((char*)(movie_driver->audio[i].desc ?
		     movie_driver->audio[i].desc :
		     ng_afmt_to_desc[movie_driver->audio[i].fmtid]),
	     NULL, XmMULTIBYTE_TEXT, NULL);
	push = XtVaCreateManagedWidget(movie_driver->audio[i].name,
				       xmPushButtonWidgetClass,audio_menu,
				       XmNlabelString,str,
				       NULL);
	XmStringFree(str);
	add_cmd_callback(push,XmNactivateCallback,
			 "movie","audio",movie_driver->audio[i].name);
	if (NULL != mov_audio)
	    if (0 == strcasecmp(mov_audio,movie_driver->audio[i].name)) {
		XtVaSetValues(audio_option,XmNmenuHistory,push,NULL);
		movie_audio = i;
	    }
    }
    str = XmStringGenerate("no sound", NULL, XmMULTIBYTE_TEXT, NULL);
    push = XtVaCreateManagedWidget("none",xmPushButtonWidgetClass,audio_menu,
				   XmNlabelString,str,NULL);
    XmStringFree(str);
    add_cmd_callback(push,XmNactivateCallback, "movie","audio","none");

    /* video formats */
    delete_children(video_menu);
    for (i = 0; NULL != movie_driver->video[i].name; i++) {
	str = XmStringGenerate
	    ((char*)(movie_driver->video[i].desc ?
		     movie_driver->video[i].desc :
		     ng_vfmt_to_desc[movie_driver->video[i].fmtid]),
	     NULL, XmMULTIBYTE_TEXT, NULL);
	push = XtVaCreateManagedWidget(movie_driver->video[i].name,
				       xmPushButtonWidgetClass,video_menu,
				       XmNlabelString,str,
				       NULL);
	XmStringFree(str);
	add_cmd_callback(push,XmNactivateCallback,
			 "movie","video",movie_driver->video[i].name);
	if (NULL != mov_video)
	    if (0 == strcasecmp(mov_video,movie_driver->video[i].name)) {
		XtVaSetValues(video_option,XmNmenuHistory,push,NULL);
		movie_video = i;
	    }
    }

    /* need audio filename? */
    sensitive = movie_driver->combined ? False : True;
    XtVaSetValues(m_faudio, XtNsensitive,sensitive, NULL);
    XtVaSetValues(m_faudioL, XtNsensitive,sensitive, NULL);
    XtVaSetValues(m_faudioB, XtNsensitive,sensitive, NULL);
}

static void
init_movie_menus(void)
{
    update_movie_menus();

    if (mov_rate)
	do_va_cmd(3,"movie","rate",mov_rate);
    if (mov_fps)
	do_va_cmd(3,"movie","fps",mov_fps);
}

static void
do_movie_record(int argc, char **argv)
{
    char *fvideo,*faudio;
    struct ng_video_fmt video;
    struct ng_audio_fmt audio;
    const struct ng_writer *wr;
    WidgetList children;
    Cardinal nchildren;
    Widget text;
    int i,rate,fps;

    /* set parameters */
    if (argc > 1 && 0 == strcasecmp(argv[0],"driver")) {
	struct list_head *item;
	struct ng_writer *writer;

	if (debug)
	    fprintf(stderr,"set driver: %s\n",argv[1]);
	XtVaGetValues(driver_menu,XtNchildren,&children,
		      XtNnumChildren,&nchildren,NULL);
	i = 0;
	list_for_each(item,&ng_writers) {
	    writer = list_entry(item, struct ng_writer, list);
	    if (0 == strcasecmp(argv[1],writer->name)) {
		movie_driver = writer;
		i_movie_driver = i;
	    }
	    i++;
	}
	update_movie_menus();
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"audio")) {
	if (debug)
	    fprintf(stderr,"set audio: %s\n",argv[1]);
	XtVaGetValues(audio_menu,XtNchildren,&children,
		      XtNnumChildren,&nchildren,NULL);
	for (i = 0; NULL != movie_driver->audio[i].name; i++) {
	    if (0 == strcasecmp(argv[1],movie_driver->audio[i].name)) {
		XtVaSetValues(audio_option,XmNmenuHistory,children[i],NULL);
		movie_audio = i;
	    }
	}
	if (0 == strcmp(argv[1],"none")) {
	    XtVaSetValues(audio_option,XmNmenuHistory,children[i],NULL);
	    movie_audio = i;
	}
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"video")) {
	if (debug)
	    fprintf(stderr,"set video: %s\n",argv[1]);
	XtVaGetValues(video_menu,XtNchildren,&children,
		      XtNnumChildren,&nchildren,NULL);
	for (i = 0; NULL != movie_driver->video[i].name; i++) {
	    if (0 == strcasecmp(argv[1],movie_driver->video[i].name)) {
		XtVaSetValues(video_option,XmNmenuHistory,children[i],NULL);
		movie_video = i;
	    }
	}
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"rate")) {
	XtVaGetValues(m_rate,XmNtextField,&text,NULL);
	XmTextSetString(text,argv[1]);
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"fps")) {
	XtVaGetValues(m_fps,XmNtextField,&text,NULL);
	XmTextSetString(text,argv[1]);
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"fvideo")) {
	XmTextSetString(m_fvideo,argv[1]);
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"faudio")) {
	XmTextSetString(m_faudio,argv[1]);
    }

    /* start */
    if (argc > 0 && 0 == strcasecmp(argv[0],"start")) {
	if (0 != cur_movie)
	    return; /* records already */
	cur_movie = 1;
	movie_blit = (cur_capture == CAPTURE_GRABDISPLAY);
	video_gd_suspend();
	XmToggleButtonSetState(levels_toggle,0,True);

	fvideo = XmTextGetString(m_fvideo);
	faudio = XmTextGetString(m_faudio);
	fvideo = tilde_expand(fvideo);
	faudio = tilde_expand(faudio);

	XtVaGetValues(m_rate,XmNtextField,&text,NULL);
	rate = atoi(XmTextGetString(text));
	XtVaGetValues(m_fps,XmNtextField,&text,NULL);
	fps = (int)(atof(XmTextGetString(text))*1000);

	memset(&video,0,sizeof(video));
	memset(&audio,0,sizeof(audio));

	wr = movie_driver;
	video.fmtid  = wr->video[movie_video].fmtid;
	video.width  = cur_tv_width;
	video.height = cur_tv_height;
	audio.fmtid  = wr->audio[movie_audio].fmtid;
	audio.rate   = rate;

	movie_state = movie_writer_init
	    (fvideo, faudio, wr,
	     &video, wr->video[movie_video].priv, fps,
	     &audio, wr->audio[movie_audio].priv, args.dspdev,
	     args.bufcount,args.parallel);
	if (NULL == movie_state) {
	    /* init failed */
	    video_gd_restart();
	    cur_movie = 0;
	    /* hmm, not the most elegant way to flag an error ... */
	    toolkit_set_label(m_status, "error [init]");
	    return;
	}
	if (0 != movie_writer_start(movie_state)) {
	    /* start failed */
	    movie_writer_stop(movie_state);
	    video_gd_restart();
	    cur_movie = 0;
	    /* hmm, not the most elegant way to flag an error ... */
	    toolkit_set_label(m_status, "error [start]");
	    return;
	}
	rec_work_id  = XtAppAddWorkProc(app_context,rec_work,NULL);
	toolkit_set_label(m_status, "recording");
	return;
    }

    /* stop */
    if (argc > 0 && 0 == strcasecmp(argv[0],"stop")) {
	if (0 == cur_movie)
	    return; /* nothing to stop here */

	movie_writer_stop(movie_state);
	XtRemoveWorkProc(rec_work_id);
	rec_work_id = 0;
	video_gd_restart();
	cur_movie = 0;
	return;
    }
}

static void
do_rec_status(char *message)
{
    toolkit_set_label(m_status, message);
}

/*----------------------------------------------------------------------*/

#ifdef HAVE_ZVBI
#define CHSCAN 250
static int chscan;
static int chvbi;
static XtIntervalId chtimer;
static Widget chdlg,chscale;

static void
chscan_timeout(XtPointer client_data, XtIntervalId *id)
{
    struct CHANNEL *c;
    char title[32];
    XmString xmstr;

    if (!x11_vbi_tuned()) {
	if (debug)
	    fprintf(stderr,"scan [%s]: no station\n",chanlist[chscan].name);
	goto next_station;
    }

    if (0 != x11_vbi_station[0]) {
	if (debug)
	    fprintf(stderr,"scan [%s]: %s\n",chanlist[chscan].name,
		    x11_vbi_station);
	c = add_channel(x11_vbi_station);
	c->cname   = strdup(chanlist[chscan].name);
	c->channel = chscan;
	cur_sender = count-1;
	channel_menu();
	goto next_station;
    }

    if (chvbi++ > 3) {
	if (debug)
	    fprintf(stderr,"scan [%s]: no vbi name\n",chanlist[chscan].name);
	sprintf(title,"%s [no name]",chanlist[chscan].name);
	c = add_channel(title);
	c->cname   = strdup(chanlist[chscan].name);
	c->channel = chscan;
	cur_sender = count-1;
	channel_menu();
	goto next_station;
    }

    if (debug)
	fprintf(stderr,"scan [%s] vbi ...\n",chanlist[chscan].name);
    chtimer = XtAppAddTimeOut(app_context, CHSCAN, chscan_timeout, NULL);
    return;

 next_station:
    chscan++;
    if (chscan >= chancount) {
	/* all done */
	x11_vbi_stop();
	chtimer = 0;
	if (count)
	    do_va_cmd(2,"setchannel",channels[0]->name);
	XtDestroyWidget(chdlg);
	chdlg = NULL;
	return;
    }
    chvbi  = 0;
    if (channel_switch_hook)
	channel_switch_hook();
    xmstr = XmStringGenerate(chanlist[chscan].name, NULL,
			     XmMULTIBYTE_TEXT, NULL);
    XtVaSetValues(chscale,XmNtitleString,xmstr,NULL);
    XmStringFree(xmstr);
    XmScaleSetValue(chscale,chscan);
    do_va_cmd(2,"setchannel",chanlist[chscan]);
    x11_vbi_station[0] = 0;
    chtimer = XtAppAddTimeOut(app_context, CHSCAN, chscan_timeout,NULL);
    return;
}

static void
chscan_start_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmString xmstr;

    /* check */
    if (!(f_drv & CAN_TUNE))
	return;
    if (channel_switch_hook)
	channel_switch_hook();

    /* clear */
    while (count) {
	XtDestroyWidget(channels[count-1]->button);
	del_channel(count-1);
    }
    cur_sender = -1;
    channel_menu();

    x11_vbi_start(args.vbidev);
    chscan = 0;
    chvbi  = 0;
    xmstr = XmStringGenerate(chanlist[chscan].name, NULL,
			     XmMULTIBYTE_TEXT, NULL);
    XtVaSetValues(chscale,XmNtitleString,xmstr,XmNmaximum,chancount,NULL);
    XmStringFree(xmstr);
    XmScaleSetValue(chscale,chscan);
    do_va_cmd(2,"setchannel",chanlist[chscan]);
    x11_vbi_station[0] = 0;
    chtimer = XtAppAddTimeOut(app_context, CHSCAN, chscan_timeout,NULL);
}

static void
chscan_cancel_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    x11_vbi_stop();
    if (chtimer)
	XtRemoveTimeOut(chtimer);
    chtimer = 0;
    XtDestroyWidget(chdlg);
    chdlg = NULL;
}

static void
chscan_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    Widget rc;

    chdlg = XmCreatePromptDialog(control_shell,"chscan",NULL,0);
    XtAddEventHandler(XtParent(chdlg), (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    XtUnmanageChild(XmSelectionBoxGetChild(chdlg,XmDIALOG_SELECTION_LABEL));
    XtUnmanageChild(XmSelectionBoxGetChild(chdlg,XmDIALOG_HELP_BUTTON));
    XtUnmanageChild(XmSelectionBoxGetChild(chdlg,XmDIALOG_TEXT));

    rc = XtVaCreateManagedWidget("rc",xmRowColumnWidgetClass,chdlg,NULL);
    XtVaCreateManagedWidget("hints",xmLabelWidgetClass,rc,NULL);
    chscale = XtVaCreateManagedWidget("channel",xmScaleWidgetClass,rc,NULL);
    XtRemoveAllCallbacks(XmSelectionBoxGetChild(chdlg,XmDIALOG_OK_BUTTON),
			 XmNactivateCallback);
    XtAddCallback(XmSelectionBoxGetChild(chdlg,XmDIALOG_OK_BUTTON),
		  XmNactivateCallback,chscan_start_cb,NULL);
    XtAddCallback(chdlg,XmNcancelCallback,chscan_cancel_cb,NULL);
    XtManageChild(chdlg);
}
#endif

/*----------------------------------------------------------------------*/

static void
pref_menu(Widget option, Widget menu, int enable)
{
    delete_children(menu);
    XtVaSetValues(XmOptionButtonGadget(option),XtNsensitive,enable,NULL);
    XtVaSetValues(XmOptionLabelGadget(option),XtNsensitive,enable,NULL);
    if (!enable)
	XtVaCreateManagedWidget("none",xmPushButtonWidgetClass,menu,NULL);
}

#if defined(HAVE_LIBXXF86VM) || defined(HAVE_LIBXRANDR)

static void
pref_fs(void)
{
    Widget push;
    char s[32];
    int i,on;

    on = XmToggleButtonGetState(pref_fs_toggle);
    if (on) {
#if defined(HAVE_LIBXXF86VM)
	if (0 == have_randr  &&  0 == args.vidmode) {
	    args.vidmode = 1;
	    xfree_vm_init(dpy);
	}
#endif
	if (0 == have_randr  &&  0 == have_vm) {
	    on = 0;
	    XtVaSetValues(pref_fs_toggle,XtNsensitive,0,NULL);
	}
    }

    XmToggleButtonSetState(pref_fs_toggle,on,False);
    if (on) {
	pref_menu(pref_fs_option,pref_fs_menu,1);
#if defined(HAVE_LIBXRANDR)
	if (have_randr) {
	    for (i = 0; i < nrandr; i++) {
		sprintf(s,"%d x %d",randr[i].width,randr[i].height);
		push = XtVaCreateManagedWidget(s,xmPushButtonWidgetClass,
					       pref_fs_menu,NULL);
		if (randr[i].width  == fs_width &&
		    randr[i].height == fs_height) {
		    XtVaSetValues(pref_fs_menu,XmNmenuHistory,push,NULL);
		}
	    }
	}
#endif
#if defined(HAVE_LIBXXF86VM)
	if (!have_randr) {
	    for (i = 0; i < vm_count; i++) {
		sprintf(s,"%d x %d",
			vm_modelines[i]->hdisplay,
			vm_modelines[i]->vdisplay);
		push = XtVaCreateManagedWidget(s,xmPushButtonWidgetClass,
					       pref_fs_menu,NULL);
		if (vm_modelines[i]->hdisplay == fs_width &&
		    vm_modelines[i]->vdisplay == fs_height) {
		    XtVaSetValues(pref_fs_menu,XmNmenuHistory,push,NULL);
		}
	    }
	}
#endif
    } else {
	pref_menu(pref_fs_option,pref_fs_menu,0);
    }
}

static void
pref_fst_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    pref_fs();
}
#endif

static void
pref_mix2(void)
{
    struct ng_mix_driver *mix;
    Widget push,w = NULL;
    char *name;
    int i,on;
    struct ng_devinfo *info = NULL;

    on = XmToggleButtonGetState(pref_mix_toggle);
    XtVaGetValues(pref_mix1_menu,XmNmenuHistory,&w,NULL);
    if (w) {
	name = XtName(w);
	if (!list_empty(&ng_mix_drivers) && 0 != strcmp(name,"none")) {
	    mix = list_entry(ng_mix_drivers.next,struct ng_mix_driver,list);
	    info = mix->channels(name);
	}
    }

    if (NULL != info && on) {
	pref_menu(pref_mix2_option,pref_mix2_menu,1);
	for (i = 0; 0 != strlen(info[i].name); i++) {
	    push = XtVaCreateManagedWidget(info[i].device,
					   xmPushButtonWidgetClass,
					   pref_mix2_menu,NULL);
	    toolkit_set_label(push,info[i].name);
	    if (strcasecmp(info[i].device,mixerctl) == 0)
		XtVaSetValues(pref_mix2_menu,XmNmenuHistory,push,NULL);
	}
    } else {
	pref_menu(pref_mix2_option,pref_mix2_menu,0);
    }
}

static void
pref_mix2_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    pref_mix2();
}

static void
pref_mix1(void)
{
    struct ng_mix_driver *mix;
    Widget push;
    int on,i;
    struct ng_devinfo *info = NULL;

    on = XmToggleButtonGetState(pref_mix_toggle);
    if (!list_empty(&ng_mix_drivers)) {
	mix = list_entry(ng_mix_drivers.next,struct ng_mix_driver,list);
	info = mix->probe();
    }
    if (NULL != info && on) {
	pref_menu(pref_mix1_option,pref_mix1_menu,1);
	for (i = 0; 0 != strlen(info[i].name); i++) {
	    push = XtVaCreateManagedWidget(info[i].device,
					   xmPushButtonWidgetClass,
					   pref_mix1_menu,
					   NULL);
	    XtAddCallback(push,XmNactivateCallback,pref_mix2_cb,NULL);
	    toolkit_set_label(push,info[i].name);
	    if (0 == i  ||  0 == strcmp(info[i].device,mixerdev))
		XtVaSetValues(pref_mix1_menu,XmNmenuHistory,push,NULL);
	}
    } else {
	pref_menu(pref_mix1_option,pref_mix1_menu,0);
    }
}

static void
pref_mix1_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    pref_mix1();
    pref_mix2();
}

static void
pref_done_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmSelectionBoxCallbackStruct *cb = call_data;
    Widget w;
    char *name = NULL;
    int on,width,height;

    if (cb->reason == XmCR_OK  ||  cb->reason == XmCR_APPLY) {
#ifdef HAVE_LIBXXF86VM
	on = XmToggleButtonGetState(pref_fs_toggle);
	if (on) {
	    XtVaGetValues(pref_fs_menu,XmNmenuHistory,&w,NULL);
	    name = XtName(w);
	    sscanf(name,"%d x %d",&width,&height);
	    fs_width  = width;
	    fs_height = height;
	} else {
	    fs_width  = 0;
	    fs_height = 0;
	}
#endif
	on = XmToggleButtonGetState(pref_mix_toggle);
	if (on) {
	    w = NULL;
	    XtVaGetValues(pref_mix1_menu,XmNmenuHistory,&w,NULL);
	    if (w)
		strcpy(mixerdev,XtName(w));
	    w = NULL;
	    XtVaGetValues(pref_mix2_menu,XmNmenuHistory,&w,NULL);
	    if (w)
		strcpy(mixerctl,XtName(w));
	} else {
	    mixerdev[0] = '\0';
	    mixerctl[0] = '\0';
	}
	use_osd = XmToggleButtonGetState(pref_osd);
	keypad_ntsc = XmToggleButtonGetState(pref_ntsc);
	keypad_partial = XmToggleButtonGetState(pref_partial);
	ng_jpeg_quality = atoi(XmTextGetString(pref_quality));
    }
    if (cb->reason == XmCR_OK) {
	save_config();
    }
    XtUnmanageChild(pref_dlg);
}

static void
pref_manage_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    char tmp[16];

#ifdef HAVE_LIBXXF86VM
    XmToggleButtonSetState(pref_fs_toggle,fs_width && fs_height,False);
    pref_fs();
#endif
    XmToggleButtonSetState(pref_mix_toggle,strlen(mixerdev) > 0,False);
    pref_mix1();
    pref_mix2();
    XmToggleButtonSetState(pref_osd,use_osd,False);
    XmToggleButtonSetState(pref_ntsc,keypad_ntsc,False);
    XmToggleButtonSetState(pref_partial,keypad_partial,False);
    sprintf(tmp,"%d",ng_jpeg_quality);
    XmTextSetString(pref_quality,tmp);
    XtManageChild(pref_dlg);
}

static void
create_pref(void)
{
    Widget rc1,frame,rc2,rc3;
    Arg args[2];

    pref_dlg = XmCreatePromptDialog(control_shell,"pref",NULL,0);
    XtAddEventHandler(XtParent(pref_dlg), (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    XtUnmanageChild(XmSelectionBoxGetChild(pref_dlg,XmDIALOG_SELECTION_LABEL));
    XtUnmanageChild(XmSelectionBoxGetChild(pref_dlg,XmDIALOG_HELP_BUTTON));
    XtManageChild(XmSelectionBoxGetChild(pref_dlg,XmDIALOG_APPLY_BUTTON));
    XtUnmanageChild(XmSelectionBoxGetChild(pref_dlg,XmDIALOG_TEXT));

    rc1 = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, pref_dlg,
				  NULL);

#ifdef HAVE_LIBXXF86VM
    /* first frame */
    frame = XtVaCreateManagedWidget("fsF",xmFrameWidgetClass,rc1,NULL);
    XtVaCreateManagedWidget("fsL",xmLabelWidgetClass,frame,NULL);
    rc2 = XtVaCreateManagedWidget("rc",xmRowColumnWidgetClass,frame,NULL);

    /* fullscreen */
    pref_fs_toggle = XtVaCreateManagedWidget("fsT",xmToggleButtonWidgetClass,
					     rc2,NULL);
    XtAddCallback(pref_fs_toggle,XmNvalueChangedCallback,pref_fst_cb,NULL);
    pref_fs_menu = XmCreatePulldownMenu(rc2,"fsM",NULL,0);
    XtSetArg(args[0],XmNsubMenuId,pref_fs_menu);
    pref_fs_option = XmCreateOptionMenu(rc2,"fsO",args,1);
    XtManageChild(pref_fs_option);
#endif

    /* second frame */
    frame = XtVaCreateManagedWidget("mixF",xmFrameWidgetClass,rc1,NULL);
    XtVaCreateManagedWidget("mixL",xmLabelWidgetClass,frame,NULL);
    rc2 = XtVaCreateManagedWidget("rc",xmRowColumnWidgetClass,frame,NULL);
    pref_mix_toggle = XtVaCreateManagedWidget("mixT",xmToggleButtonWidgetClass,
					      rc2,NULL);
    XtAddCallback(pref_mix_toggle,XmNvalueChangedCallback,pref_mix1_cb,NULL);

    pref_mix1_menu = XmCreatePulldownMenu(rc2,"mix1M",NULL,0);
    XtSetArg(args[0],XmNsubMenuId,pref_mix1_menu);
    pref_mix1_option = XmCreateOptionMenu(rc2,"mix1O",args,1);
    XtManageChild(pref_mix1_option);

    pref_mix2_menu = XmCreatePulldownMenu(rc2,"mix2M",NULL,0);
    XtSetArg(args[0],XmNsubMenuId,pref_mix2_menu);
    pref_mix2_option = XmCreateOptionMenu(rc2,"mix2O",args,1);
    XtManageChild(pref_mix2_option);

    /* third frame */
    frame = XtVaCreateManagedWidget("optF",xmFrameWidgetClass,rc1,NULL);
    XtVaCreateManagedWidget("optL",xmLabelWidgetClass,frame,NULL);
    rc2 = XtVaCreateManagedWidget("rc",xmRowColumnWidgetClass,frame,NULL);

    /* options */
    pref_osd = XtVaCreateManagedWidget("osd",xmToggleButtonWidgetClass,
				       rc2,NULL);
    pref_ntsc = XtVaCreateManagedWidget("keypad-ntsc",
					xmToggleButtonWidgetClass,
					rc2,NULL);
    pref_partial = XtVaCreateManagedWidget("keypad-partial",
					   xmToggleButtonWidgetClass,
					   rc2,NULL);
    rc3 = XtVaCreateManagedWidget("jpeg", xmRowColumnWidgetClass,
				  rc2,NULL);
    XtVaCreateManagedWidget("label",xmLabelWidgetClass,rc3,NULL);
    pref_quality = XtVaCreateManagedWidget("quality",
					   xmTextWidgetClass,
					   rc3,NULL);

    /* buttons */
    XtAddCallback(pref_dlg,XmNokCallback,pref_done_cb,NULL);
    XtAddCallback(pref_dlg,XmNapplyCallback,pref_done_cb,NULL);
    XtAddCallback(pref_dlg,XmNcancelCallback,pref_done_cb,NULL);
}

/*---------------------------------------------------------------------- */
/* selection & dnd support                                               */

static struct ng_video_buf*
convert_buffer(struct ng_video_buf *in, int out_fmt)
{
    struct ng_video_conv *conv;
    struct ng_convert_handle *ch;
    struct ng_video_fmt ofmt;
    int i;

    /* find converter */
    for (i = 0;;) {
	conv = ng_conv_find_to(out_fmt,&i);
	if (NULL == conv)
	    break;
	if (conv->fmtid_in == in->fmt.fmtid)
	    goto found;
    }
    return NULL;

 found:
    memset(&ofmt,0,sizeof(ofmt));
    ofmt.fmtid  = out_fmt;
    ofmt.width  = in->fmt.width;
    ofmt.height = in->fmt.height;
    ch = ng_convert_alloc(conv,&in->fmt,&ofmt);
    return ng_convert_single(ch,in);
}

static struct ng_video_buf*
scale_rgb_buffer(struct ng_video_buf *in, int scale)
{
    struct ng_video_fmt fmt;
    struct ng_video_buf *buf;
    char *src,*dst;
    unsigned int x,y;

    fmt = in->fmt;
    fmt.width  = in->fmt.width  / scale;
    fmt.height = in->fmt.height / scale;
    while (fmt.width & 0x03)
	fmt.width++;
    fmt.bytesperline = fmt.width * 3;
    buf = ng_malloc_video_buf(&fmt, fmt.width * fmt.height * 3);

    /* scale down */
    dst = buf->data;
    for (y = 0; y < fmt.height; y++) {
	src = in->data + y * scale * in->fmt.bytesperline;
	for (x = 0; x < fmt.width; x++) {
	    dst[0] = src[0];
	    dst[1] = src[1];
	    dst[2] = src[2];
	    dst += 3;
	    src += 3*scale;
	}
    }
    return buf;
}

struct ipc_data {
    struct list_head     list;
    Atom                 atom;
    struct ng_video_buf  *buf;
    char                 *filename;
    Pixmap               pix;
    Pixmap               icon_pixmap;
    Widget               icon_widget;
};
struct list_head ipc_selections;

static void
ipc_iconify(Widget widget, struct ipc_data *ipc)
{
    struct ng_video_buf *small;
    int scale,depth;
    Arg args[4];
    Cardinal n=0;

    /* calc size */
    for (scale = 1;; scale++) {
	if (ipc->buf->fmt.width  / scale < 128 &&
	    ipc->buf->fmt.height / scale < 128)
	    break;
    }

    /* scale down & create pixmap */
    small = scale_rgb_buffer(ipc->buf,scale);
    small = convert_buffer(small, x11_dpy_fmtid);
    ipc->icon_pixmap = x11_create_pixmap(dpy,&vinfo,small);

    /* build DnD icon */
    n = 0;
    depth = DefaultDepthOfScreen(XtScreen(widget));
    XtSetArg(args[n], XmNpixmap, ipc->icon_pixmap); n++;
    XtSetArg(args[n], XmNwidth,  small->fmt.width); n++;
    XtSetArg(args[n], XmNheight, small->fmt.height); n++;
    XtSetArg(args[n], XmNdepth,  depth); n++;
    ipc->icon_widget = XmCreateDragIcon(widget,"dragicon",args,n);

    ng_release_video_buf(small);
}

static struct ipc_data*
ipc_find(Atom selection)
{
    struct list_head   *item;
    struct ipc_data    *ipc;

    list_for_each(item,&ipc_selections) {
	ipc = list_entry(item, struct ipc_data, list);
	if (ipc->atom == selection)
	    return ipc;
    }
    return NULL;
}

static struct ipc_data*
ipc_init(Atom selection)
{
    struct ipc_data *ipc;
    struct ng_video_fmt fmt;
    struct ng_video_buf *buf;

    /* capture a frame and save a copy */
    video_gd_suspend();
    memset(&fmt,0,sizeof(fmt));
    fmt.fmtid  = VIDEO_RGB24;
    fmt.width  = cur_tv_width;
    fmt.height = cur_tv_height;
    buf = ng_grabber_get_image(&fmt);
    buf = ng_filter_single(cur_filter,buf);
    ipc = malloc(sizeof(*ipc));
    memset(ipc,0,sizeof(*ipc));
    ipc->buf = ng_malloc_video_buf(&buf->fmt,buf->size);
    ipc->atom = selection;
    ipc->buf->info = buf->info;
    memcpy(ipc->buf->data,buf->data,buf->size);
    ng_release_video_buf(buf);
    video_gd_restart();

    list_add_tail(&ipc->list,&ipc_selections);
    return ipc;
}

static void
ipc_tmpfile(struct ipc_data *ipc)
{
    static char *base = "motv";
    struct ng_video_buf *buf;
    char *tmpdir;
    int fd;

    if (NULL != ipc->filename)
	return;

    tmpdir = getenv("TMPDIR");
    if (NULL == tmpdir)
	tmpdir="/tmp";
    ipc->filename = malloc(strlen(tmpdir)+strlen(base)+16);
    sprintf(ipc->filename,"%s/%s-XXXXXX",tmpdir,base);
    fd = mkstemp(ipc->filename);

    ipc->buf->refcount++;
    buf = convert_buffer(ipc->buf, VIDEO_JPEG);
    write(fd,buf->data,buf->size);
    ng_release_video_buf(buf);
}

static void
ipc_pixmap(struct ipc_data *ipc)
{
    struct ng_video_buf *buf;

    if (0 != ipc->pix)
	return;

    ipc->buf->refcount++;
    buf = convert_buffer(ipc->buf, x11_dpy_fmtid);
    ipc->pix = x11_create_pixmap(dpy,&vinfo,buf);
    ng_release_video_buf(buf);
    return;
}

static void
ipc_fini(Atom selection)
{
    struct ipc_data *ipc;

    ipc = ipc_find(selection);
    if (NULL == ipc)
	return;

    /* free stuff */
    if (ipc->buf)
	ng_release_video_buf(ipc->buf);
    if (ipc->filename) {
	unlink(ipc->filename);
	free(ipc->filename);
    }
    if (ipc->icon_widget)
	XtDestroyWidget(ipc->icon_widget);
    if (ipc->icon_pixmap)
	XFreePixmap(dpy,ipc->icon_pixmap);
    if (ipc->pix)
	XFreePixmap(dpy,ipc->pix);

    list_del(&ipc->list);
    free(ipc);
}

static Atom ipc_unique_atom(Widget widget)
{
    char id_name[32];
    Atom id;
    int i;

    for (i = 0;; i++) {
	sprintf(id_name,"_MOTV_IMAGE_%lX_%d",XtWindow(widget),i);
	id = XInternAtom(XtDisplay(widget),id_name,False);
	if (NULL == ipc_find(id))
	    break;
    }
    return id;
}

static void
ipc_convert(Widget widget, XtPointer ignore, XtPointer call_data)
{
    XmConvertCallbackStruct *ccs = call_data;
    struct ipc_data *ipc;
    Atom *targs;
    Pixmap *pix;
    unsigned long *ldata;
    unsigned char *cdata;
    char *filename;
    int n;

    if (debug) {
	char *y = !ccs->type      ? NULL : XGetAtomName(dpy,ccs->type);
	char *t = !ccs->target    ? NULL : XGetAtomName(dpy,ccs->target);
	char *s = !ccs->selection ? NULL : XGetAtomName(dpy,ccs->selection);
	fprintf(stderr,"conv: target=%s type=%s selection=%s\n",t,y,s);
	if (y) XFree(y);
	if (t) XFree(t);
	if (s) XFree(s);
    }

    /* tell which formats we can handle */
    if ((ccs->target == XA_TARGETS) ||
	(ccs->target == _MOTIF_CLIPBOARD_TARGETS) ||
	(ccs->target == _MOTIF_DEFERRED_CLIPBOARD_TARGETS) ||
	(ccs->target == _MOTIF_EXPORT_TARGETS)) {
	n = 0;
	targs = (Atom*)XtMalloc(sizeof(Atom)*12);
	if (ccs->target != _MOTIF_CLIPBOARD_TARGETS) {
	    targs[n++] = XA_TARGETS;
	    targs[n++] = MIME_IMAGE_PPM;
	    targs[n++] = XA_PIXMAP;
	    targs[n++] = XA_FOREGROUND;
	    targs[n++] = XA_BACKGROUND;
	    targs[n++] = XA_COLORMAP;
	    targs[n++] = MIME_IMAGE_JPEG;
	    targs[n++] = XA_FILE_NAME;
	    targs[n++] = XA_FILE;
	    targs[n++] = MIME_TEXT_URI_LIST;
	    targs[n++] = _NETSCAPE_URL;
	}
	if (ccs->target == _MOTIF_EXPORT_TARGETS) {
	    /* save away drag'n'drop data */
	    ipc_init(ccs->selection);
	}
	ccs->value  = targs;
	ccs->length = n;
	ccs->type   = XA_ATOM;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;
	return;

    } else if (ccs->target == _MOTIF_SNAPSHOT) {
	/* save away clipboard data */
	n = 0;
	targs = (Atom*)XtMalloc(sizeof(Atom));
	targs[n++] = ipc_unique_atom(widget);
	ipc_init(targs[0]);
	ccs->value  = targs;
	ccs->length = n;
	ccs->type   = XA_ATOM;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;
	return;
    }

    /* find data */
    ipc = ipc_find(ccs->selection);
    if (NULL == ipc) {
	/* shouldn't happen */
	fprintf(stderr,"oops: selection data not found\n");
	ccs->status = XmCONVERT_REFUSE;
	return;
    }

    if (ccs->target == _MOTIF_LOSE_SELECTION ||
	ccs->target == XA_DONE) {
	/* cleanup */
	ipc_fini(ccs->selection);
	ccs->value  = NULL;
	ccs->length = 0;
	ccs->type   = XA_INTEGER;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;
	return;
    }

    /* convert data */
    if (ccs->target == XA_BACKGROUND ||
	ccs->target == XA_FOREGROUND ||
	ccs->target == XA_COLORMAP) {
	n = 0;
	ldata = (Atom*)XtMalloc(sizeof(Atom)*8);
	if (ccs->target == XA_BACKGROUND) {
	    ldata[n++] = WhitePixelOfScreen(XtScreen(widget));
	    ccs->type  = XA_PIXEL;
	}
	if (ccs->target == XA_FOREGROUND) {
	    ldata[n++] = BlackPixelOfScreen(XtScreen(widget));
	    ccs->type  = XA_PIXEL;
	}
	if (ccs->target == XA_COLORMAP) {
	    ldata[n++] = DefaultColormapOfScreen(XtScreen(widget));
	    ccs->type  = XA_COLORMAP;
	}
	ccs->value  = ldata;
	ccs->length = n;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;

    } else if (ccs->target == XA_PIXMAP) {
	/* xfer pixmap */
	ipc_pixmap(ipc);
	pix = (Pixmap*)XtMalloc(sizeof(Pixmap));
	pix[0] = ipc->pix;
	if (debug)
	    fprintf(stderr,"conv: pixmap id is 0x%lx\n",pix[0]);
	ccs->value  = pix;
	ccs->length = 1;
	ccs->type   = XA_DRAWABLE;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;

    } else if (ccs->target == MIME_IMAGE_PPM) {
	cdata = XtMalloc(ipc->buf->size + 32);
	n = sprintf(cdata,"P6\n%d %d\n255\n",
		    ipc->buf->fmt.width,ipc->buf->fmt.height);
	memcpy(cdata+n,ipc->buf->data,ipc->buf->size);
	ccs->value  = cdata;
	ccs->length = n+ipc->buf->size;
	ccs->type   = MIME_IMAGE_PPM;
	ccs->format = 8;
	ccs->status = XmCONVERT_DONE;

    } else if (ccs->target == MIME_IMAGE_JPEG) {
	struct ng_video_buf *buf;
	ipc->buf->refcount++;
	buf = convert_buffer(ipc->buf, VIDEO_JPEG);
	cdata = XtMalloc(buf->size);
	memcpy(cdata,buf->data,buf->size);
	ng_release_video_buf(buf);
	ccs->value  = cdata;
	ccs->length = buf->size;
	ccs->type   = MIME_IMAGE_JPEG;
	ccs->format = 8;
	ccs->status = XmCONVERT_DONE;

    } else if (ccs->target == XA_FILE_NAME       ||
	       ccs->target == XA_FILE            ||
	       ccs->target == XA_STRING          ||
	       ccs->target == MIME_TEXT_URI_LIST ||
	       ccs->target == _NETSCAPE_URL) {
	/* xfer filename (image via tmp file) */
	ipc_tmpfile(ipc);
	if (ccs->target == MIME_TEXT_URI_LIST ||
	    ccs->target == _NETSCAPE_URL) {
	    /* filename => url */
	    filename = XtMalloc(strlen(ipc->filename)+8);
	    sprintf(filename,"file:%s\r\n",ipc->filename);
	    ccs->type = ccs->target;
	    if (debug)
		fprintf(stderr,"conv: tmp url is %s\n",filename);
	} else {
	    filename = XtMalloc(strlen(ipc->filename));
	    strcpy(filename,ipc->filename);
	    ccs->type = XA_STRING;
	    if (debug)
		fprintf(stderr,"conv: tmp file is %s\n",filename);
	}
	ccs->value  = filename;
	ccs->length = strlen(filename);
	ccs->format = 8;
	ccs->status = XmCONVERT_DONE;

    } else {
	/* shouldn't happen */
	fprintf(stderr,"oops: unknown target\n");
	ccs->status = XmCONVERT_REFUSE;
    }
}

static void
ipc_finish(Widget widget, XtPointer ignore, XtPointer call_data)
{
    if (debug)
	fprintf(stderr,"conv: transfer finished\n");
    ipc_fini(_MOTIF_DROP);
}

void IpcAction(Widget widget, XEvent *event, String *argv, Cardinal *argc)
{
    struct    ipc_data *ipc;
    Widget    drag;
    Arg       args[4];
    Cardinal  n=0;

    if (0 == *argc)
	return;
    if (!(f_drv & CAN_CAPTURE)) {
	if (debug)
	    fprintf(stderr,"ipc: can't capture - cancel\n");
	return;
    }

    if (debug)
	fprintf(stderr,"ipc: %s\n",argv[0]);
    if (0 == strcmp(argv[0],"drag")) {
	ipc_fini(_MOTIF_DROP);
	ipc = ipc_init(_MOTIF_DROP);
	ipc_iconify(widget,ipc);
	n = 0;
	XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++;
	XtSetArg(args[n], XmNsourcePixmapIcon, ipc->icon_widget); n++;
	drag = XmeDragSource(tv, NULL, event, args, n);
	XtAddCallback(drag, XmNdragDropFinishCallback, ipc_finish, NULL);
    }
    if (0 == strcmp(argv[0],"primary")) {
#if 0
	ipc_fini(XA_PRIMARY);
	ipc_init(XA_PRIMARY);
	XmePrimarySource(tv,XtLastTimestampProcessed(dpy));
#else
	fprintf(stderr,"FIXME [primary called]\n");
#endif
    }
    if (0 == strcmp(argv[0],"clipboard")) {
	XmeClipboardSource(tv,XmCOPY,XtLastTimestampProcessed(dpy));
    }
}

/*----------------------------------------------------------------------*/

Widget levels_left, levels_right;
XtInputId levels_id;
const struct ng_dsp_driver *levels_dsp;
void *levels_hdsp;

static void
levels_input(XtPointer clientdata, int *src, XtInputId *id)
{
    struct ng_audio_buf *buf;
    int left, right;

    buf = levels_dsp->read(levels_hdsp,0);
    oss_levels(buf,&left,&right);
    XmScaleSetValue(levels_left,left);
    XmScaleSetValue(levels_right,right);
    if (debug > 1)
	fprintf(stderr,"levels: left = %3d, right = %3d\r",left,right);
}

static void
levels_toggle_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmToggleButtonCallbackStruct *tb = call_data;
    struct ng_audio_fmt a;

    if (tb->reason != XmCR_VALUE_CHANGED)
	return;

    if (tb->set  &&  NULL == levels_dsp) {
	/* enable */
	a.fmtid = AUDIO_U8_STEREO;
	a.rate  = 44100;
	levels_dsp = ng_dsp_open(args.dspdev,&a,1,&levels_hdsp);
	if (levels_dsp) {
	    levels_dsp->startrec(levels_hdsp);
	    levels_id  = XtAppAddInput(app_context,levels_dsp->fd(levels_hdsp),
				       (XtPointer)XtInputReadMask,
				       levels_input,NULL);
	    if (debug)
		fprintf(stderr,"levels: started sound monitor\n");
	}
    }
    if (!tb->set  &&  NULL != levels_hdsp) {
	/* disable */
	XtRemoveInput(levels_id);
	levels_dsp->close(levels_hdsp);
	levels_dsp = NULL;
	levels_hdsp = NULL;
	XmScaleSetValue(levels_left,0);
	XmScaleSetValue(levels_right,0);
	if (debug)
	    fprintf(stderr,"levels: stopped sound monitor\n");
    }
}

static void
create_levels(void)
{
    Widget rc;

    levels_shell = XtVaAppCreateShell("levels", "MoTV",
				      topLevelShellWidgetClass,
				      dpy,
				      XtNclientLeader,app_shell,
				      XtNvisual,vinfo.visual,
				      XtNcolormap,colormap,
				      XtNdepth,vinfo.depth,
				      XmNdeleteResponse,XmDO_NOTHING,
				      NULL);
    XtAddEventHandler(levels_shell, (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    XmAddWMProtocolCallback(levels_shell,WM_DELETE_WINDOW,
			    popupdown_cb,levels_shell);
    rc = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, levels_shell,
				 NULL);

    levels_toggle = XtVaCreateManagedWidget("enable",
					    xmToggleButtonWidgetClass,rc,
					    NULL);
    XtAddCallback(levels_toggle,XmNvalueChangedCallback,
		  levels_toggle_cb,NULL);

    levels_left = XtVaCreateManagedWidget("left",xmScaleWidgetClass,rc,
					  NULL);
    levels_right = XtVaCreateManagedWidget("right",xmScaleWidgetClass,rc,
					   NULL);
}

/*----------------------------------------------------------------------*/

struct stderr_handler {
    Widget box;
    XmString str;
    int pipe;
    XtInputId id;
};

static void
stderr_input(XtPointer clientdata, int *src, XtInputId *id)
{
    struct stderr_handler *h = clientdata;
    XmString item;
    Widget label;
    char buf[1024];
    int rc;

    rc = read(h->pipe,buf,sizeof(buf)-1);
    if (rc <= 0) {
	/* Oops */
	XtRemoveInput(h->id);
	close(h->pipe);
	XtDestroyWidget(h->box);
	free(h);
    }
    buf[rc] = 0;
    item = XmStringGenerate(buf, NULL, XmMULTIBYTE_TEXT,NULL);
    h->str = XmStringConcatAndFree(h->str,item);
    label = XmMessageBoxGetChild(h->box,XmDIALOG_MESSAGE_LABEL);
    XtVaSetValues(label,XmNlabelString,h->str,NULL);
    XtManageChild(h->box);
};

static void
stderr_ok_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct stderr_handler *h = clientdata;

    XmStringFree(h->str);
    h->str = XmStringGenerate("", NULL, XmMULTIBYTE_TEXT,NULL);
    XtUnmanageChild(h->box);
}

static void
stderr_close_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct stderr_handler *h = clientdata;

    XmStringFree(h->str);
    h->str = XmStringGenerate("", NULL, XmMULTIBYTE_TEXT,NULL);
}

static void
stderr_init(void)
{
    struct stderr_handler *h;
    int p[2];

    if (debug)
	return;
    h = malloc(sizeof(*h));
    memset(h,0,sizeof(*h));
    h->str = XmStringGenerate("", NULL, XmMULTIBYTE_TEXT,NULL);
    h->box = XmCreateErrorDialog(app_shell,"errbox",NULL,0);
    XtUnmanageChild(XmMessageBoxGetChild(h->box,XmDIALOG_HELP_BUTTON));
    XtUnmanageChild(XmMessageBoxGetChild(h->box,XmDIALOG_CANCEL_BUTTON));
    XtAddCallback(h->box,XmNokCallback,stderr_ok_cb,h);
    XtAddCallback(XtParent(h->box),XmNpopdownCallback,stderr_close_cb,h);
    pipe(p);
    dup2(p[1],2);
    close(p[1]);
    h->pipe = p[0];
    h->id = XtAppAddInput(app_context,h->pipe,(XtPointer)XtInputReadMask,
			  stderr_input,h);
}

/*----------------------------------------------------------------------*/

int
main(int argc, char *argv[])
{
    int            i;
    unsigned long  freq;

    hello_world("motv");
    XtSetLanguageProc(NULL,NULL,NULL);
    app_shell = XtVaAppInitialize(&app_context, "MoTV",
				  opt_desc, opt_count,
				  &argc, argv,
				  fallback_ressources,
				  NULL);
    XtAddEventHandler(app_shell, (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    dpy = XtDisplay(app_shell);
    x11_icons_init(dpy,0);
    init_atoms(dpy);

    /* handle command line args */
    ng_init();
    handle_cmdline_args();

    /* device scan */
    if (args.hwscan) {
	fprintf(stderr,"looking for available devices\n");
#ifdef HAVE_LIBXV
	xv_video_init(-1,1);
#endif
	grabber_scan();
    }

    /* look for a useful visual */
    visual_init("motv","MoTV");

    /* remote display? */
    do_overlay = !args.remote;
    if (do_overlay)
	x11_check_remote();
    v4lconf_init();

    /* x11 stuff */
    XtAppAddActions(app_context,actionTable,
		    sizeof(actionTable)/sizeof(XtActionsRec));
    x11_misc_init(dpy);
    XmAddWMProtocolCallback(app_shell,WM_DELETE_WINDOW,ExitCB,NULL);
    if (debug)
	fprintf(stderr,"main: dga extention...\n");
    xfree_dga_init(dpy);
    if (debug)
	fprintf(stderr,"main: xinerama extention...\n");
    xfree_xinerama_init(dpy);
#ifdef HAVE_LIBXV
    if (debug)
	fprintf(stderr,"main: xvideo extention [video]...\n");
    if (args.xv_video)
	xv_video_init(args.xv_port,0);
    if (debug)
	fprintf(stderr,"main: xvideo extention [image]...\n");
    if (args.xv_image)
	xv_image_init(dpy);
#endif

    /* set hooks (command.c) */
    update_title        = new_title;
    display_message     = new_message;
#if TT
    vtx_message         = display_vtx;
#endif
#ifdef HAVE_ZVBI
    vtx_subtitle        = display_subtitle;
#endif
    set_capture_hook    = do_capture;
    fullscreen_hook     = do_motif_fullscreen;
    attr_notify         = new_attr;
    volume_notify       = new_volume;
    freqtab_notify      = new_freqtab;
    setstation_notify   = new_channel;
    movie_hook          = do_movie_record;
    rec_status          = do_rec_status;
    exit_hook           = do_exit;
    capture_get_hook    = video_gd_suspend;
    capture_rel_hook    = video_gd_restart;
    channel_switch_hook = pixit;

    if (debug)
	fprintf(stderr,"main: init main window...\n");
    tv = video_init(app_shell,&vinfo,xmPrimitiveWidgetClass,
		    args.bpp,args.gl);
    XtAddEventHandler(XtParent(tv),StructureNotifyMask, True,
		      resize_event, NULL);
    if (debug)
	fprintf(stderr,"main: install signal handlers...\n");
    xt_siginit();
    if (NULL == drv) {
	if (debug)
	    fprintf(stderr,"main: open grabber device...\n");
	grabber_init();
    }

    /* create windows */
    XSetIOErrorHandler(x11_ctrl_alt_backspace);
    if (debug)
	fprintf(stderr,"main: checking wm...\n");
    wm_detect(dpy);
    if (debug)
	fprintf(stderr,"main: creating windows ...\n");
    create_onscreen(xmLabelWidgetClass);
    create_vtx();
    create_strwin();
    stderr_init();

    /* read config file + related settings */
    if (debug)
	fprintf(stderr,"main: init frequency tables ...\n");
    freq_init();
    if (args.readconfig) {
	if (debug)
	    fprintf(stderr,"main: read config file ...\n");
	read_config(args.conffile ? args.conffile : NULL, &argc, argv);
    }
    if (0 != strlen(mixerdev)) {
	struct ng_attribute *attr;
	if (debug)
	    fprintf(stderr,"main: open mixer device...\n");
	if (NULL != (attr = ng_mix_init(mixerdev,mixerctl)))
	    add_attrs(attr);
    }

    create_control();
    create_prop();
    create_pref();
    create_levels();
    create_filter_prop();

    init_movie_menus();
    create_scale();
    create_attr_widgets();
    INIT_LIST_HEAD(&ipc_selections);

    xt_vm_randr_input_init(dpy);

    if (debug)
	fprintf(stderr,"main: mapping main window ...\n");
    XtRealizeWidget(app_shell);
    create_pointers(app_shell);
    create_bitmaps(app_shell);
    XDefineCursor(dpy, XtWindow(app_shell), left_ptr);
    if (f_drv & CAN_CAPTURE)
	XtAddCallback(tv,XmNconvertCallback,ipc_convert,NULL);

    XtVaSetValues(app_shell,
		  XtNwidthInc,  WIDTH_INC,
		  XtNheightInc, HEIGHT_INC,
		  XtNminWidth,  WIDTH_INC,
		  XtNminHeight, HEIGHT_INC,
		  NULL);

    /* mouse pointer magic */
    XtAddEventHandler(tv, PointerMotionMask, True, mouse_event, NULL);
    mouse_event(tv,NULL,NULL,NULL);

    /* init hw */
    if (debug)
	fprintf(stderr,"main: initialize hardware ...\n");
    attr_init();
    audio_on();
    audio_init();

    /* build channel list */
    if (args.readconfig) {
	if (debug)
	    fprintf(stderr,"main: parse channels from config file ...\n");
	parse_config(1);
    }
    channel_menu();

    xt_handle_pending(dpy);
    init_overlay();

    set_property(0,NULL,NULL);
    if (optind+1 == argc) {
	do_va_cmd(2,"setstation",argv[optind]);
    } else {
	if ((f_drv & CAN_TUNE) && 0 != (freq = drv->getfreq(h_drv))) {
	    for (i = 0; i < chancount; i++)
		if (chanlist[i].freq == freq*1000/16) {
		    do_va_cmd(2,"setchannel",chanlist[i].name);
		    break;
		}
	}
	if (-1 == cur_channel) {
	    if (count > 0) {
		if (debug)
		    fprintf(stderr,"main: tuning first station\n");
		do_va_cmd(2,"setstation","0");
	    } else {
		if (debug)
		    fprintf(stderr,"main: setting defaults\n");
		set_defaults();
	    }
	} else {
	    if (debug)
		fprintf(stderr,"main: known station tuned, not changing\n");
	}
    }
    XtAddEventHandler(tv,ExposureMask, True, tv_expose_event, NULL);

    if (args.fullscreen) {
	do_motif_fullscreen();
    } else {
	XtAppAddWorkProc(app_context,MyResize,NULL);
    }

    xt_main_loop();
    return 0;
}
xawtv-3.106/x11/mtt.ad000066400000000000000000000047231343350355000144260ustar00rootroot00000000000000! general
mtt.title:				teletext test utility
mtt.deleteResponse:			DO_NOTHING

! fonts
*renderTable:
*renderTable.fontType: FONT_IS_FONTSET
*renderTable.fontName: \
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso10646-1, \
 -misc-fixed-bold-r-normal--13-*-*-*-*-*-iso8859-* \
 -*-*-*-*--13-*-*-*-*-*-*-*,*

! arrange widgets
mtt.form.*.leftAttachment:		ATTACH_FORM
mtt.form.*.rightAttachment:		ATTACH_FORM
mtt.form.tool.topAttachment:		ATTACH_WIDGET
mtt.form.tool.topWidget:		bar
mtt.form.tt.topAttachment:		ATTACH_WIDGET
mtt.form.tt.topWidget:			tool
mtt.form.tt.bottomAttachment:		ATTACH_FORM
mtt.form.tt.background:			black
mtt.form.tt.foreground:			white

! menubar
mtt*bar.file.labelString:		File
mtt*bar.file.mnemonic:			F
mtt*bar.edit.labelString:		Edit
mtt*bar.edit.mnemonic:			E
mtt*bar.go.labelString:			Go to
mtt*bar.go.mnemonic:			G
mtt*bar.subpage.labelString:		Subpage
mtt*bar.subpage.mnemonic:		S
mtt*bar.station.labelString:		Stations
mtt*bar.station.mnemonic:		t
mtt*bar.font.labelString:		Fonts
mtt*bar.font.mnemonic:			o

! toolbar
mtt*tool.orientation:			HORIZONTAL
mtt*tool.?.shadowThickness:		1
mtt*tool.?.labelType:			PIXMAP
mtt*tool.XmSeparator.orientation:	VERTICAL
mtt*tool.XmSeparator.width:		12
mtt*tool.XmSeparator.margin:		3
mtt*tool.100.labelPixmap:		home
mtt*tool.prev.labelPixmap:		prev
mtt*tool.next.labelPixmap:		next
mtt*tool.exit.labelPixmap:		exit

! menu file
mtt*bar*new.labelString:		New window
mtt*bar*new.mnemonic:			N
mtt*bar*new.acceleratorText:		N
mtt*bar*new.accelerator:		N
mtt*bar*save.labelString:		Save as ...
mtt*bar*save.mnemonic:			S
mtt*bar*save.acceleratorText:		S
mtt*bar*save.accelerator:		S
mtt*bar*quit.labelString:		Close
mtt*bar*quit.mnemonic:			C
mtt*bar*quit.acceleratorText:		Q
mtt*bar*quit.accelerator:		Q

! menu edit
mtt*bar*copy.labelString:		Copy
mtt*bar*copy.mnemonic:			C
mtt*bar*copy.acceleratorText:		Ctrl+C
mtt*bar*copy.accelerator:		CtrlC

! menu go
mtt*bar*100.labelString:		Index
mtt*bar*100.mnemonic:			I
mtt*bar*100.acceleratorText:		I
mtt*bar*100.accelerator:		I
mtt*bar*prev.labelString:		Previous page
mtt*bar*prev.mnemonic:			P
mtt*bar*prev.acceleratorText:		PgUp
mtt*bar*prev.accelerator:		Page_Up
mtt*bar*next.labelString:		Next page
mtt*bar*next.mnemonic:			N
mtt*bar*next.acceleratorText:		PgDown
mtt*bar*next.accelerator:		Page_Down

! menu subpage
mtt*bar*s00.labelString:		cycle subpages

! save as dialog
mtt.save_popup.title:			Save File
mtt.save_popup*format.labelString:	Character set:

xawtv-3.106/x11/mtt.c000066400000000000000000000130541343350355000142610ustar00rootroot00000000000000/*
 * mtt - teletext test app.
 *
 * This is just main() for the standalone version, the actual
 * code is in vbi-gui.c (motif) and vbi-tty.c (terminal).
 *
 *   (c) 2002 Gerd Knorr 
 *
 */

#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "icons.h"
#include "atoms.h"
#include "vbi-data.h"
#include "vbi-gui.h"
#include "vbi-tty.h"

#include "grab-ng.h"
#include "channel.h"
#include "frequencies.h"
#include "commands.h"

/* --------------------------------------------------------------------- */

XtAppContext  app_context;
Widget        app_shell;
Display       *dpy;
int           debug;

static String fallback_ressources[] = {
#include "mtt.h"
    NULL
};

struct ARGS {
    char  *device;
    int   help;
    int   tty;
    int   debug;
    int   sim;
} args;

XtResource args_desc[] = {
    /* name, class, type, size, offset, default_type, default_addr */
    {
	/* Strings */
	"device",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,device),
	XtRString, "/dev/vbi0",
    },{
	/* Integer */
	"help",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,help),
	XtRString, "0"
    },{
	"tty",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,tty),
	XtRString, "0"
    },{
	"debug",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,debug),
	XtRString, "0"
    },{
	"sim",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,sim),
	XtRString, "0"
    }
};
const int args_count = XtNumber(args_desc);

XrmOptionDescRec opt_desc[] = {
    { "-c",          "device",      XrmoptionSepArg, NULL },
    { "-device",     "device",      XrmoptionSepArg, NULL },

    { "-tty",        "tty",         XrmoptionNoArg,  "1" },
    { "-sim",        "sim",         XrmoptionNoArg,  "1" },
    { "-debug",      "debug",       XrmoptionNoArg,  "1" },

    { "-h",          "help",        XrmoptionNoArg,  "1" },
    { "-help",       "help",        XrmoptionNoArg,  "1" },
    { "--help",      "help",        XrmoptionNoArg,  "1" },
};
const int opt_count = (sizeof(opt_desc)/sizeof(XrmOptionDescRec));

/* --------------------------------------------------------------------- */

static void
debug_action(Widget widget, XEvent *event,
	     String *params, Cardinal *num_params)
{
    fprintf(stderr,"debug_action: called\n");
}

static XtActionsRec actionTable[] = {
    { "debug", debug_action },
};

/* --------------------------------------------------------------------- */

static void usage(void)
{
    fprintf(stderr,
	    "\n"
	    "mtt -- teletext application\n"
	    "\n"
	    "usage: mtt [ options ]\n"
	    "options:\n"
	    "  -help         print this text\n"
	    "  -debug        enable debug messages\n"
	    "  -device  use vbi device  instead of /dev/vbi0\n"
	    "  -tty          use terminal mode\n"
	    "\n"
	    "--\n"
	    "Gerd Knorr \n");
}

static void vbi_data(XtPointer data, int *fd, XtInputId *iproc)
{
    struct vbi_state *vbi = data;
    vbi_hasdata(vbi);
}

static int main_tty(int argc, char **argv)
{
    char *dev = "/dev/vbi0";
    int debug = 0;
    int sim   = 0;

    argc--;
    argv++;
    for (;argc;) {
	if (0 == strcmp(argv[0],"-c") ||
	    0 == strcmp(argv[0],"-device")) {
	    dev = argv[1];
	    argc -= 2;
	    argv += 2;

	} else if (0 == strcmp(argv[0],"-tty")) {
	    argc -= 1;
	    argv += 1;

	} else if (0 == strcmp(argv[0],"-debug")) {
	    debug = 1;
	    argc -= 1;
	    argv += 1;

	} else if (0 == strcmp(argv[0],"-sim")) {
	    sim   = 1;
	    argc -= 1;
	    argv += 1;

	} else if (0 == strcmp(argv[0],"-h") &&
		   0 == strcmp(argv[0],"-help") &&
		   0 == strcmp(argv[0],"--help")) {
	    usage();
	    exit(0);

	} else
	    break;
    }
    vbi_tty(dev,debug,sim);
    exit(0);
}

int
main(int argc, char **argv)
{
    struct vbi_state *vbi;
    char **av;
    int ac;

    ac = argc;
    av = malloc(sizeof(char*)*(argc+1));
    memcpy(av,argv,sizeof(char*)*(argc+1));

    XtSetLanguageProc(NULL,NULL,NULL);
    XtToolkitInitialize();
    app_context = XtCreateApplicationContext();
    XtAppSetFallbackResources(app_context,fallback_ressources);
    dpy = XtOpenDisplay(app_context, NULL,
			NULL,"mtt",
			opt_desc, opt_count,
			&argc, argv);
    if (NULL == dpy)
	main_tty(ac,av);
    app_shell = XtVaAppCreateShell(NULL,"mtt",
				   applicationShellWidgetClass,dpy,NULL);
    XtAppAddActions(app_context,actionTable,
		    sizeof(actionTable)/sizeof(XtActionsRec));
    x11_icons_init(dpy,0);
    init_atoms(dpy);
    XtGetApplicationResources(app_shell,&args,
			      args_desc,args_count,
			      NULL,0);
    if (args.help) {
	usage();
	exit(1);
    }
    if (args.tty)
	main_tty(ac,av);

    freq_init();
    read_config(NULL, &argc, argv);
    parse_config(1);
    do_va_cmd(2,"setfreqtab",(-1 != chantab)
	      ? chanlist_names[chantab].str : "europe-west");

    vbi = vbi_open(args.device,args.debug,args.sim);
    if (NULL == vbi)
	exit(1);
    if (args.debug)
	vbi_event_handler_add(vbi->dec,~0,vbi_dump_event,vbi);
    XtAppAddInput(app_context, vbi->fd, (XtPointer) XtInputReadMask,
		  vbi_data, vbi);

    vbi_create_widgets(app_shell,vbi);
    XtRealizeWidget(app_shell);
    XtAppMainLoop(app_context);
    return 0;
}
xawtv-3.106/x11/pia.c000066400000000000000000000313551343350355000142320ustar00rootroot00000000000000/*
 * simple movie player
 *
 *  (c) 2002 Gerd Knorr 
 *
 */

#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#ifdef HAVE_LIBXV
# include 
# include 
#endif

#include "grab-ng.h"
#include "blit.h"

/* ------------------------------------------------------------------------ */

int debug = 0;

/* X11 */
static XtAppContext app_context;
static Widget       app_shell;
static Display      *dpy;
static Colormap     colormap;
static Visual       *visual;
static XVisualInfo  vinfo,*vinfo_list;

static Widget simple;
static Dimension swidth,sheight;

static struct blit_state *blit;

/* libng */
static const struct ng_reader      *reader;
static void                        *rhandle;
static const struct ng_dsp_driver  *snd;
static void                        *shandle;
static int                         snd_fd;

static struct ng_video_fmt         cfmt;
static struct ng_video_conv        *conv;
static void                        *chandle;

static struct ng_video_fmt         *vfmt;
static struct ng_audio_fmt         *afmt;
static struct ng_video_buf         *vbuf;
static struct ng_audio_buf         *abuf;

/* ------------------------------------------------------------------------ */

struct ARGS {
    char  *dsp;
    int   slow;
    int   help;
    int   verbose;
    int   debug;
    int   xv;
    int   gl;
    int   max;
    int   audio;
    int   video;
} args;

XtResource args_desc[] = {
    /* name, class, type, size, offset, default_type, default_addr */
    {
	/* Strings */
	"dsp",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,dsp),
	XtRString, NULL,
    },{
	/* Integer */
	"verbose",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,verbose),
	XtRString, "0"
    },{
	"debug",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,debug),
	XtRString, "0"
    },{
	"help",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,help),
	XtRString, "0"
    },{
	"slow",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,slow),
	XtRString, "1"
    },{
	"xv",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,xv),
	XtRString, "1"
    },{
	"gl",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,gl),
	XtRString, "1"
    },{
	"max",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,max),
	XtRString, "0"
    },{
	"audio",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,audio),
	XtRString, "1"
    },{
	"video",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,video),
	XtRString, "1"
    }
};
const int args_count = XtNumber(args_desc);

XrmOptionDescRec opt_desc[] = {
    { "-dsp",        "dsp",         XrmoptionSepArg, NULL },
    { "-slow",       "slow",        XrmoptionSepArg, NULL },

    { "-h",          "help",        XrmoptionNoArg,  "1" },
    { "-help",       "help",        XrmoptionNoArg,  "1" },
    { "--help",      "help",        XrmoptionNoArg,  "1" },

    { "-v",          "verbose",     XrmoptionNoArg,  "1" },
    { "-verbose",    "verbose",     XrmoptionNoArg,  "1" },
    { "-debug",      "debug",       XrmoptionNoArg,  "1" },
    { "-max",        "max",         XrmoptionNoArg,  "1" },

    { "-xv",         "xv",          XrmoptionNoArg,  "1" },
    { "-noxv",       "xv",          XrmoptionNoArg,  "0" },
    { "-gl",         "gl",          XrmoptionNoArg,  "1" },
    { "-nogl",       "gl",          XrmoptionNoArg,  "0" },
    { "-audio",      "audio",       XrmoptionNoArg,  "1" },
    { "-noaudio",    "audio",       XrmoptionNoArg,  "0" },
    { "-video",      "video",       XrmoptionNoArg,  "1" },
    { "-novideo",    "video",       XrmoptionNoArg,  "0" },
};
const int opt_count = (sizeof(opt_desc)/sizeof(XrmOptionDescRec));

/* ------------------------------------------------------------------------ */

static void quit_ac(Widget widget, XEvent *event,
		    String *params, Cardinal *num_params)
{
    exit(0);
}

static void resize_ev(Widget widget, XtPointer client_data,
		      XEvent *event, Boolean *d)
{
    static int first = 1;

    switch(event->type) {
    case MapNotify:
    case ConfigureNotify:
	if (first) {
	    blit = blit_init(simple,&vinfo,args.gl);
	    first = 0;
	}
	XtVaGetValues(widget,XtNheight,&sheight,XtNwidth,&swidth,NULL);
	if (vfmt)
	    blit_resize(blit,swidth,sheight);
	break;
    }
}

static XtActionsRec action_table[] = {
    { "Quit",  quit_ac },
};

static String res[] = {
    "pia.winGravity:		 Static",
    "pia.playback.translations:  #override \\n"
    "       Q:              Quit()    \\n"
    "       Escape:         Quit()",
    "pia.playback.background:    black",
    NULL
};

static void usage(FILE *out, char *prog)
{
    char *h;

    if (NULL != (h = strrchr(prog,'/')))
	prog = h+1;
    fprintf(out,
	    "%s is simple movie player\n"
	    "\n"
	    "usage: %s [ options ] movie\n"
	    "options:\n"
	    "  -h, -help       this text\n"
	    "  -v, -verbose    be verbose\n"
	    "      -debug      enable debug messages\n"
	    "      -dsp   use sound device \n"
#ifdef HAVE_LIBXV
	    "      -noxv       disable Xvideo extention\n"
#endif
#ifdef HAVE_GL
	    "      -nogl       disable OpenGL\n"
#endif
	    "\n",
	    prog,prog);
}

static void sync_info(long long drift, int drops, int frames)
{
    int total = drops + frames;

    fprintf(stderr,"a/v sync: audio drift is %4d ms / "
	    "%d of %d frame(s) [%3.1f%%] dropped \r",
	    (int)((drift)/1000000),drops,total,
	    total ? (float)drops * 100 / total : 0);
}

int main(int argc, char *argv[])
{
    long long start, now, delay, latency = 0, drift = 0;
    struct timeval wait;
    int n, drop, droptotal, framecount, ww, wh;
    unsigned int fmtids[2*VIDEO_FMT_COUNT], i;
    XEvent event;

    app_shell = XtVaAppInitialize(&app_context, "pia",
				  opt_desc, opt_count,
				  &argc, argv,
				  res, NULL);
    XtGetApplicationResources(app_shell,&args,
			      args_desc,args_count,
			      NULL,0);
    if (args.help) {
	usage(stdout,argv[0]);
	exit(1);
    }
    if (args.debug) {
	debug    = args.debug;
	ng_debug = args.debug;
    }

    if (argc < 2) {
	usage(stderr,argv[0]);
	exit(1);
    }
    ng_init();

    /* open file */
    reader = ng_find_reader(argv[1]);
    if (NULL == reader) {
	fprintf(stderr,"can't handle %s\n",argv[1]);
	exit(1);
    }
    rhandle = reader->rd_open(argv[1]);
    if (NULL == rhandle) {
	fprintf(stderr,"opening %s failed\n",argv[1]);
	exit(1);
    }
    vfmt = reader->rd_vfmt(rhandle,NULL,0);
    if (0 == vfmt->width || 0 == vfmt->height)
	vfmt = NULL;
    afmt = reader->rd_afmt(rhandle);

    if (0 == args.video)
	vfmt = NULL;
    if (0 == args.audio)
	afmt = NULL;
    if (1 != args.slow)
	/* no audio for slow motion, will not sync anyway ... */
	afmt = NULL;

    /* init x11 stuff */
    dpy = XtDisplay(app_shell);
    visual = x11_find_visual(XtDisplay(app_shell));
    vinfo.visualid = XVisualIDFromVisual(visual);
    vinfo_list = XGetVisualInfo(dpy, VisualIDMask, &vinfo, &n);
    vinfo = vinfo_list[0];
    XFree(vinfo_list);
    if (visual != DefaultVisualOfScreen(XtScreen(app_shell))) {
	fprintf(stderr,"switching visual (0x%lx)\n",vinfo.visualid);
	colormap = XCreateColormap(dpy,RootWindowOfScreen(XtScreen(app_shell)),
				   vinfo.visual,AllocNone);
	XtDestroyWidget(app_shell);
	app_shell = XtVaAppCreateShell("pia","pia",
				       applicationShellWidgetClass, dpy,
				       XtNvisual,vinfo.visual,
				       XtNcolormap,colormap,
				       XtNdepth, vinfo.depth,
				       NULL);
    } else {
	colormap = DefaultColormapOfScreen(XtScreen(app_shell));
    }
    x11_init_visual(XtDisplay(app_shell),&vinfo);
#if HAVE_LIBXV
    if (args.xv)
	xv_image_init(dpy);
#endif
    XtAppAddActions(app_context,action_table,
		    sizeof(action_table)/sizeof(XtActionsRec));
    XtVaSetValues(app_shell, XtNtitle,argv[1],NULL);

    /* show window */
    ww = 320;
    wh = 32;
    if (vfmt) {
	ww = vfmt->width;
	wh = vfmt->height;
	if (args.max) {
	    int sw = XtScreen(app_shell)->width;
	    int sh = XtScreen(app_shell)->height;
	    if (sw * wh > sh * ww) {
		ww = ww * sh / wh;
		wh = sh;
	    } else {
		wh = wh * sw / ww;
		ww =sw;
	    }
	}
    }
    simple = XtVaCreateManagedWidget("playback",simpleWidgetClass,app_shell,
				     XtNwidth,ww, XtNheight,wh, NULL);
    XtAddEventHandler(simple, StructureNotifyMask, True, resize_ev, NULL);
    XtRealizeWidget(app_shell);
    while (NULL == blit) {
	XFlush(dpy);
	while (True == XCheckMaskEvent(dpy, ~0, &event))
	    XtDispatchEvent(&event);
    }

    /* video setup */
    if (vfmt) {
	blit_get_formats(blit,fmtids,sizeof(fmtids)/sizeof(int));
	vfmt = reader->rd_vfmt(rhandle,fmtids,sizeof(fmtids)/sizeof(int));
	if (0 == vfmt->width || 0 == vfmt->height || VIDEO_NONE == vfmt->fmtid)
	    vfmt = NULL;
    }
    if (vfmt) {
	for (i = 0; i < sizeof(fmtids)/sizeof(int); i++)
	    if (fmtids[i] == vfmt->fmtid)
		break;
	if (i == sizeof(fmtids)/sizeof(int)) {
	    /* blit can't display directly -- have to convert somehow */
	    for (i = 0; i < sizeof(fmtids)/sizeof(int); i++)
		if (NULL != (conv = ng_conv_find_match(vfmt->fmtid,fmtids[i])))
		    break;
	    if (conv) {
		cfmt = *vfmt;
		cfmt.fmtid = conv->fmtid_out;
		cfmt.bytesperline = 0;
		chandle = ng_convert_alloc(conv,vfmt,&cfmt);
		ng_convert_init(chandle);
		if (debug)
		    fprintf(stderr,"pia: conv [%s] => [%s]\n",
			    ng_vfmt_to_desc[vfmt->fmtid],
			    ng_vfmt_to_desc[cfmt.fmtid]);
	    }
	}
    }

    /* audio setup */
    if (afmt) {
	struct ng_audio_fmt f = *afmt;
	snd = ng_dsp_open(args.dsp ? args.dsp : "/dev/dsp", &f,0,&shandle);
	if (NULL == snd)
	    afmt = NULL;
	else {
	    snd_fd  = snd->fd(shandle);
	    latency = snd->latency(shandle);
	    if (debug)
		fprintf(stderr,"a/v sync: audio latency is %lld ms\n",
			latency/1000000);
	}
    }

    /* enter main loop
     *
     * can't use XtAppMainLoop + Input + Timeout handlers here because
     * that doesn't give us usable event scheduling, thus we have our
     * own main loop here ...
     */
    drop = 0;
    droptotal = 0;
    framecount = 0;
    start = 0;
    drift = 0;
    if (afmt) {
	/* fill sound buffer */
	fd_set wr;
	int rc;

	for (;;) {
	    FD_ZERO(&wr);
	    FD_SET(snd_fd,&wr);
	    wait.tv_sec = 0;
	    wait.tv_usec = 0;
	    rc = select(snd_fd+1,NULL,&wr,NULL,&wait);
	    if (1 != rc)
		break;
	    abuf = reader->rd_adata(rhandle);
	    if (NULL == abuf)
		break;
	    if (0 == start)
		start = ng_get_timestamp();
	    drift = abuf->info.ts - (ng_get_timestamp() - start);
	    abuf = snd->write(shandle,abuf);
	    if (NULL != abuf)
		break;
	}
    }
    if (0 == start)
	start = ng_get_timestamp();

    if (debug)
	fprintf(stderr,"a/v sync: audio buffer filled\n");
    for (; vfmt || afmt;) {
	int rc,max;
	fd_set rd,wr;

	/* handle X11 events */
	if (True == XCheckMaskEvent(dpy, ~0, &event)) {
	    XtDispatchEvent(&event);
	    continue;
	}

	/* read media data */
	if (afmt && NULL == abuf) {
	    abuf = reader->rd_adata(rhandle);
	    if (NULL == abuf)
		afmt = NULL; /* EOF */
	    else
		drift = abuf->info.ts - (ng_get_timestamp() - start);
	}
	if (vfmt && NULL == vbuf) {
	    droptotal += drop;
	    vbuf = reader->rd_vdata(rhandle,drop);
	    if (conv)
		vbuf = ng_convert_frame(chandle,NULL,vbuf);
	    if (NULL != vbuf && 1 != args.slow)
		/* ts fixup for slow motion */
		vbuf->info.ts *= args.slow;
	    if (NULL == vbuf)
		vfmt = NULL; /* EOF */
	}

	/* wait for events */
	XFlush(dpy);
	FD_ZERO(&rd);
	FD_ZERO(&wr);
	FD_SET(ConnectionNumber(dpy),&rd);
	max = ConnectionNumber(dpy);
	if (afmt) {
	    FD_SET(snd_fd,&wr);
	    if (snd_fd > max)
		max = snd_fd;
	}
	if (vfmt) {
	    /* check how long we have to wait until the next frame
	     * should be blitted to the screen */
	    now = ng_get_timestamp() - start;
	    if (afmt && latency) {
		/* sync video with audio track */
		now += drift;
		now -= latency;
		if (args.verbose)
		    sync_info(drift-latency,droptotal,framecount);
	    }
	    delay = vbuf->info.ts - now;
	    if (delay < 0) {
		drop = -delay / reader->frame_time(rhandle);
		if (drop) {
		    if (args.verbose)
			sync_info(drift-latency,droptotal,framecount);
		}
		wait.tv_sec  = 0;
		wait.tv_usec = 0;
	    } else {
		drop = 0;
		wait.tv_sec  = delay / 1000000000;
		wait.tv_usec = (delay / 1000) % 1000000;
	    }
	} else {
	    wait.tv_sec  = 1;
	    wait.tv_usec = 0;
	}
	rc = select(max+1,&rd,&wr,NULL,&wait);

	if (afmt && FD_ISSET(snd_fd,&wr)) {
	    /* write audio data */
	    abuf = snd->write(shandle,abuf);
	}
	if (vfmt && 0 == rc) {
	    /* blit video frame */
	    blit_putframe(blit,vbuf);
	    framecount++;
	    vbuf = NULL;
	}
    }
    return 0;
}
xawtv-3.106/x11/propwatch.c000066400000000000000000000347021343350355000154670ustar00rootroot00000000000000/*
 * propwatch.c -- (c) 1997-2003 Gerd Knorr 
 *
 * A tool to monitor window properties of root and application windows.
 * Nice for debugging property-based IPC of X11 programs.
 *
 * see also:
 *   xhost(1), xauth(1), xprop(1), xwd(1)
 *
 */

#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#ifndef TRUE
#define TRUE   1
#define FALSE  0
#endif

/*-------------------------------------------------------------------------*/

struct WATCHLIST {
    Window                 win;
    int                    watch;
    struct WATCHLIST       *next;
    char                   *text;
};

/* WM */
static Atom wm_del_win;
static Atom wm_class;

/*-------------------------------------------------------------------------*/

static Widget              bl,vp;
static struct WATCHLIST    *watchlist = NULL;
static char                **watch_name;
static Atom                *watch_atom;
static int                 watch_count;

static char *watch_default[] = {
    "WM_COMMAND",
};

static String   *str_list;
static int      str_count;

static void AddWatch(Display *dpy, Window win, int i);
static void DeleteWatch(Window win);
static void CheckWindow(Display *dpy, Window win);
static void Update(Display *dpy, Window win, Atom prop);

/*-------------------------------------------------------------------------*/

struct ARGS {
    char  *watch;
    int   verbose;
    int   proplog;
    int   kbdlog;
} args;

XtResource args_desc[] = {
    /* name, class, type, size, offset, default_type, default_addr */
    {
	/* ----- Strings ----- */
	"watch",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,watch),
	XtRString, NULL,
    },{
	/* ----- Integer ----- */
	"verbose",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,verbose),
	XtRString, "0"
    },{
	"proplog",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,proplog),
	XtRString, "0"
    },{
	"kbdlog",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,kbdlog),
	XtRString, "0"
    }
};
const int args_count = XtNumber(args_desc);

XrmOptionDescRec opt_desc[] = {
    { "-watch",      "watch",       XrmoptionSepArg, NULL },
    { "-verbose",    "verbose",     XrmoptionNoArg,  "1" },
    { "-proplog",    "proplog",     XrmoptionNoArg,  "1" },
    { "-kbdlog",     "kbdlog",      XrmoptionNoArg,  "1" },
};
const int opt_count = (sizeof(opt_desc)/sizeof(XrmOptionDescRec));

/*-------------------------------------------------------------------------*/

XtAppContext      app_context;
Widget            app_shell;
Cursor            left_ptr;
Cursor            menu_ptr;

static void QuitAction(Widget, XEvent*, String*, Cardinal*);
static void HookAction(Widget, XEvent*, String*, Cardinal*);

static void ProcessPropertyChange(Display*,XEvent*);
static void ProcessKeyPress(Display*,XEvent*);
static void ProcessClientMessage(Display*,XEvent*);
static void ProcessCreateWindow(Display*,XEvent*);
static void ProcessEvent(Display *dpy, XEvent *event);

/* Actions */
static XtActionsRec actionTable[] = {
    { "Quit", QuitAction },
    { "Hook", HookAction },
};

/*-------------------------------------------------------------------------*/

static int
x11_error_dev_null(Display * dpy, XErrorEvent * event)
{
    if (args.verbose)
	printf("x11 error -- ignored (likely just a race as X11 is async)\n");
    return 0;
}

static void
spy_input(XtPointer client_data, int *src, XtInputId *id)
{
    Display *spy_dpy = client_data;
    XEvent   event;

    while (True == XCheckMaskEvent(spy_dpy, 0xffffffff, &event))
	ProcessEvent(spy_dpy,&event);
}

static void
add_window(Display *dpy, Window win)
{
    Window rroot,parent,*children = NULL;
    int i, n;

    if (NULL == args.watch && XtWindow(app_shell) == win)
	/* don't f*ck up ourself */
	return;

    XSelectInput(dpy, win,
		 (args.kbdlog ? KeyPressMask | KeyReleaseMask : 0) |
		 PropertyChangeMask |
		 SubstructureNotifyMask);

    if (0 != XQueryTree(dpy, win, &rroot, &parent, &children, &n)) {
	for (i = 0; i < n; i++)
	    add_window(dpy,children[i]);
	if (children)
	    XFree(children);
    }

    /* look for properties to show */
    CheckWindow(dpy, win);
}

int
main(int argc, char *argv[])
{
    Screen *scr;
    XColor white,red,dummy;
    int i;
    Window root;
    Display *dpy, *spy_dpy;
    char title[1024];
    XEvent  event;

    /* init X11 */
    app_shell = XtAppInitialize(&app_context, "Propwatch",
				opt_desc, opt_count,
				&argc, argv,
				NULL,
				NULL, 0);
    XtGetApplicationResources(app_shell,&args,
			      args_desc,args_count,
			      NULL,0);

    XtAppAddActions(app_context,actionTable,
		    sizeof(actionTable)/sizeof(XtActionsRec));
    XtOverrideTranslations
	(app_shell,XtParseTranslationTable("WM_PROTOCOLS: Quit()\n"));
    dpy = XtDisplay(app_shell);
    if (NULL != args.watch) {
	if (NULL == (spy_dpy = XOpenDisplay(args.watch))) {
	    fprintf(stderr,"can't open display: %s\n",args.watch);
	    exit(1);
	}
	sprintf(title,"watch on %s - ",args.watch);
    } else {
	spy_dpy = dpy;
	sprintf(title,"watch - ");
    }
    root = DefaultRootWindow(spy_dpy);

    XSetErrorHandler(x11_error_dev_null);

    /* args */
    if (argc > 1) {
	watch_count = argc-1;
	watch_name  = argv+1;
    } else {
	watch_count = sizeof(watch_default)/sizeof(char*);
	watch_name  = watch_default;
    }
    watch_atom  = malloc(sizeof(Atom)*watch_count);

    /* Atoms */
    wm_del_win   = XInternAtom(dpy,"WM_DELETE_WINDOW", FALSE);
    wm_class     = XInternAtom(dpy,"WM_CLASS",         FALSE);
    for (i = 0; i < watch_count; i++) {
	watch_atom[i] = XInternAtom(spy_dpy,watch_name[i],FALSE);
	strcat(title,watch_name[i]);
	if (i < watch_count-1)
	    strcat(title,", ");
    }
    XtVaSetValues(app_shell,XtNtitle,title,NULL);

    /* nice Cursors */
    left_ptr = XCreateFontCursor(dpy,XC_left_ptr);
    menu_ptr = XCreateFontCursor(dpy,XC_right_ptr);
    scr = DefaultScreenOfDisplay(dpy);
    if (DefaultDepthOfScreen(scr) > 1) {
	if (XAllocNamedColor(dpy,DefaultColormapOfScreen(scr),
			     "white",&white,&dummy) &&
	    XAllocNamedColor(dpy,DefaultColormapOfScreen(scr),
			     "red",&red,&dummy)) {
	    XRecolorCursor(dpy,left_ptr,&red,&white);
	    XRecolorCursor(dpy,menu_ptr,&red,&white);
	}
    }

    /* widgets*/
    vp = XtVaCreateManagedWidget("vp",viewportWidgetClass,app_shell,
				 XtNallowHoriz, False,
				 XtNallowVert,  True,
				 XtNwidth,      600,
				 XtNheight,     400,
				 NULL);
    bl = XtVaCreateManagedWidget("box",listWidgetClass,vp,
				 XtNdefaultColumns,1,
				 XtNforceColumns,True,
				 NULL);
    XtOverrideTranslations(bl,XtParseTranslationTable
			   ("Q: Quit()\n"
			    "P: Hook(xprop)\n"));

    /* display main window */
    XtRealizeWidget(app_shell);
    XDefineCursor(dpy,XtWindow(app_shell),left_ptr);
    XSetWMProtocols(dpy,XtWindow(app_shell),&wm_del_win,1);

    add_window(spy_dpy,root);

    /* enter main loop */
    if (spy_dpy != dpy) {
	XtAppAddInput(app_context,ConnectionNumber(spy_dpy),
		      (XtPointer)XtInputReadMask,
		      spy_input,spy_dpy);
    }
    while (TRUE) {
	XtAppNextEvent(app_context,&event);
	if (XtDispatchEvent(&event))
	    continue;
	ProcessEvent(spy_dpy,&event);
    }

    /* keep compiler happy */
    return 0;
}

/*-------------------------------------------------------------------------*/

static int
cmp(const void *a, const void *b)
{
    char **aa = (char**)a;
    char **bb = (char**)b;
    return strcmp(*aa,*bb);
}

static void
RebuildList(void)
{
    static char *empty = "empty";
    int i;
    struct WATCHLIST *this;

    if (str_list)
	free(str_list);
    str_list = malloc(str_count*sizeof(String));
    for (i=0, this=watchlist; this!=NULL; i++, this=this->next)
	str_list[i] = this->text;
    qsort(str_list,str_count,sizeof(char*),cmp);
    XawListChange(bl,str_count ? str_list : &empty,
		  str_count ? str_count : 1,1000,1);
}

void
AddWatch(Display *dpy, Window win, int i)
{
    struct WATCHLIST   *this;

    this = malloc(sizeof(struct WATCHLIST));
    memset(this,0,sizeof(struct WATCHLIST));
    if (watchlist)
	this->next = watchlist;
    watchlist = this;

    this->win   = win;
    this->watch = i;
    str_count++;
    Update(dpy,win,watch_atom[i]);
    RebuildList();
}

void
DeleteWatch(Window win)
{
    struct WATCHLIST *this,*prev = NULL;

    for (this = watchlist; this != NULL;) {
	if (this->win == win) {
	    if (prev)
		prev->next = this->next;
	    else
		watchlist = this->next;
	    this = this->next;
	    str_count--;
	} else {
	    prev = this;
	    this = this->next;
	}
    }
    RebuildList();
}

void
CheckWindow(Display *dpy, Window win)
{
    Atom               type;
    int                format,i;
    unsigned long      nitems,rest;
    unsigned char      *data;

    for (i = 0; i < watch_count; i++) {
	if (Success != XGetWindowProperty
	    (dpy,win,watch_atom[i],
	     0,64,False,AnyPropertyType,
	     &type,&format,&nitems,&rest,&data))
	    continue;
	if (None != type) {
	    AddWatch(dpy,win,i);
	    XFree(data);
	}
    }
}

/*-------------------------------------------------------------------------*/

static char* str_append(char *dest, char *sep, char *quot, char *str)
{
    int size, pos;

    pos   = dest ? strlen(dest)   : 0;
    size  = str  ? strlen(str)    : 0;
    size += sep  ? strlen(sep)    : 0;
    size += quot ? strlen(quot)*2 : 0;
    dest  = realloc(dest,pos+size+1);
    sprintf(dest+pos,"%s%s%s%s",
	    sep  ? sep  : "",
	    quot ? quot : "",
	    str  ? str  : "",
	    quot ? quot : "");
    return dest;
}

static char*
PropertyToString(Display *dpy, Window win, Atom prop)
{
    Atom               type;
    int                format;
    unsigned int       i;
    unsigned long      nitems,rest;
    unsigned char      *cdata;
    unsigned long      *ldata;
    char               window[12],*name;
    char               *buf = NULL;
    char               *sep = NULL;

    if (Success != XGetWindowProperty
	(dpy,win,prop,0,64,False,AnyPropertyType,
	 &type,&format,&nitems,&rest,&cdata))
	return NULL;
    ldata = (unsigned long*)cdata;
    switch (type) {
    case XA_STRING:
	for (i = 0; i < nitems; i += strlen(cdata+i)+1) {
	    buf = str_append(buf,sep,"\"",cdata+i);
	    sep = ", ";
	}
	break;
    case XA_ATOM:
	for (i = 0; i < nitems; i++) {
	    name = XGetAtomName(dpy,ldata[i]);
	    buf = str_append(buf,sep,NULL,name);
	    sep = ", ";
	    if (name)
		XFree(name);
	}
	break;
    default:
	if (32 == format) {
	    for (i = 0; i < nitems; i++) {
		sprintf(window,"0x%x",(unsigned int)ldata[i]);
		buf = str_append(buf,sep,NULL,window);
		sep = ", ";
	    }
	} else {
	    name = XGetAtomName(dpy,type);
	    buf = malloc(40 + (name ? strlen(name) : 4));
	    sprintf(buf,"can't handle: format=%d type=%s",
		    format, name ? name : "NULL");
	    if (name)
		XFree(name);
	}
	break;
    }
    XFree(cdata);
    return buf;
}

void
Update(Display *dpy, Window win, Atom prop)
{
    struct WATCHLIST   *this;
    char               *str;

    for (this = watchlist; this != NULL; this = this->next)
	if (this->win == win && watch_atom[this->watch] == prop)
	    break;
    if (this) {
	if (this->text)
	    free(this->text);
	str = PropertyToString(dpy,win,prop);
	this->text = malloc((str ? strlen(str) : 4) +
			    strlen(watch_name[this->watch]) + 20);
	sprintf(this->text,"0x%08lx: %s: %s",
		this->win, watch_name[this->watch], str ? str : "NULL");
	if (str)
	    free(str);
    }
}

void
ProcessPropertyChange(Display *dpy, XEvent* event)
{
    int                i;
    struct WATCHLIST   *this;
    char               *name = NULL;
    char               *prop = NULL;

    name = XGetAtomName(dpy,event->xproperty.atom);
    for (i = 0; i < watch_count; i++) {
	if (watch_atom[i] == event->xproperty.atom) {
	    for (this = watchlist; this != NULL; this = this->next)
		if (this->win == event->xproperty.window &&
		    watch_atom[this->watch] == event->xproperty.atom)
		    break;
	    if (!this)
		AddWatch(dpy,event->xproperty.window, i);
	    else {
		Update(dpy,event->xproperty.window,event->xproperty.atom);
		XawListChange(bl,str_list,str_count,1000,1);
	    }
	}
    }

    if (args.proplog) {
	prop = PropertyToString(dpy, event->xproperty.window,
				event->xproperty.atom);
	printf("0x%-8lx: PropertyChange: %s: %s\n",
	       event->xproperty.window,
	       name ? name : "NULL",
	       prop ? prop : "NULL");
	if (prop)
	    free(prop);
    }
    if (name)
	XFree(name);
}

void
ProcessClientMessage(Display *dpy, XEvent* event)
{
    fprintf(stderr,"0x%-8lx: ClientMessage\n",
	    event->xclient.window);
}

void
ProcessKeyPress(Display *dpy, XEvent* event)
{
    fprintf(stderr,"0x%-8lx: %s: code=%d sym=%s\n",
	    event->xkey.window,
	    event->type == KeyPress ? "KeyPress" : "KeyRelease",
	    event->xkey.keycode,
	    XKeysymToString(XkbKeycodeToKeysym(dpy,event->xkey.keycode,0,0)));
}

void
ProcessCreateWindow(Display *dpy, XEvent* event)
{
    add_window(dpy,event->xcreatewindow.window);
}

void
ProcessEvent(Display *dpy, XEvent *event)
{
    if (event->type == PropertyNotify) {
	ProcessPropertyChange(dpy,event);

    } else if (event->type == CreateNotify) {
	ProcessCreateWindow(dpy,event);

    } else if (event->type == KeyPress ||
	       event->type == KeyRelease) {
	ProcessKeyPress(dpy,event);

    } else if (event->type == ClientMessage) {
	ProcessClientMessage(dpy,event);

    } else if (event->type == DestroyNotify) {
	DeleteWatch(event->xdestroywindow.window);
    }
}

/*-------------------------------------------------------------------------*/

void
QuitAction(Widget widget, XEvent* event, String* arg, Cardinal* arg_count)
{
    exit(0);
}

void
HookAction(Widget widget, XEvent* event, String* arg, Cardinal* arg_count)
{
    XawListReturnStruct *ret;
    struct WATCHLIST *this;
    char *dname;
    char cmd[256];
    int i;

    /* find window */
    if (0 != strcmp(XtName(widget),"box"))
	return;
    ret = XawListShowCurrent(widget);
    for (i = 0, this = watchlist; this != NULL; i++, this=this->next)
	if (0 == strcmp(ret->string,this->text))
	    break;
    if (NULL == this)
	return;
    if (0 == arg_count)
	return;
    dname = DisplayString(XtDisplay(widget));

    if (0 == strcmp(arg[0],"xprop")) {
	/* dump window properties */
	sprintf(cmd,"xprop -display %s -id 0x%lx",
		args.watch ? args.watch : dname,
		this->win);
	printf("### %s\n",cmd);
	system(cmd);
	printf("### done\n");
    }
}
xawtv-3.106/x11/rootv.c000066400000000000000000000242261343350355000146310ustar00rootroot00000000000000#include "config.h"
#ifndef HAVE_LIBXV
#include "stdio.h"
#include "stdlib.h"
int main(void)
{puts("Compiled without Xvideo extention support, sorry.");exit(0);}
#else
/*
 * put a TV image to the root window - requires Xvideo
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 

#include "vroot.h"
#include "atoms.h"
#include "parseconfig.h"

#define SDIMOF(array)  ((signed int)(sizeof(array)/sizeof(array[0])))

int     port=-1,bye=0,termsig=0,verbose=0;
GC      gc;

XvAdaptorInfo        *ai;
XvEncodingInfo       *ei;
XvAttribute          *at;
XvImageFormatValues  *fo;

static char *reasons[] = {
    "XvStarted",
    "XvStopped",
    "XvBusy",
    "XvPreempted",
    "XvHardError",
};

static char *events[] = {
    "0", "1",
    "KeyPress",
    "KeyRelease",
    "ButtonPress",
    "ButtonRelease",
    "MotionNotify",
    "EnterNotify",
    "LeaveNotify",
    "FocusIn",
    "FocusOut",
    "KeymapNotify",
    "Expose",
    "GraphicsExpose",
    "NoExpose",
    "VisibilityNotify",
    "CreateNotify",
    "DestroyNotify",
    "UnmapNotify",
    "MapNotify",
    "MapRequest",
    "ReparentNotify",
    "ConfigureNotify",
    "ConfigureRequest",
    "GravityNotify",
    "ResizeRequest",
    "CirculateNotify",
    "CirculateRequest",
    "PropertyNotify",
    "SelectionClear",
    "SelectionRequest",
    "SelectionNotify",
    "ColormapNotify",
    "ClientMessage",
    "MappingNotify"
};

static void station_list(FILE *fp)
{
    char filename[100];
    char **list;

    sprintf(filename,"%.*s/%s",(int)sizeof(filename)-8,
	    getenv("HOME"),".xawtv");
    cfg_parse_file(CONFIGFILE);
    cfg_parse_file(filename);

    for (list = cfg_list_sections(); *list != NULL; list++) {
	if (0 == strcmp(*list,"defaults")) continue;
	if (0 == strcmp(*list,"global"))   continue;
	if (0 == strcmp(*list,"launch"))   continue;
	if (0 == strcmp(*list,"eventmap")) continue;
	fprintf(fp,"\t\"%s\" EXEC v4lctl setstation \"%s\"\n",
		*list,*list);
    }
}

static void wm_menu(FILE *fp)
{
    fprintf(fp,"\"TV stations\" MENU\n");
    station_list(fp);
    fprintf(fp,"\"TV stations\" END\n");
}

static void video_blit(Display *dpy, Window win)
{
    XWindowAttributes wts;

    XGetWindowAttributes(dpy, win, &wts);
#if 0
    XClearArea(dpy,win,0,0,0,0,False);
    XvStopVideo(dpy,port,win);
#endif
    XvPutVideo(dpy,port,win,gc,
	       0,0,wts.width,wts.height,
	       0,0,wts.width,wts.height);
    if (verbose)
	fprintf(stderr,"XvPutVideo(win=0x%lx,w=%d,h=%d)\n",
		win,wts.width,wts.height);
}

static void
catch_sig(int signal)
{
    termsig = signal;
    if (verbose)
	fprintf(stderr,"received signal %d [%s]\n",
		termsig,sys_siglist[termsig]);
}

static void usage(FILE *fp)
{
    fprintf(fp,
	    "rootv is a simple TV application.  Uses and requires Xvideo.\n"
	    "Most settings must be tweaked done using some other tool,\n"
	    "v4lctl for example.\n"
	    "\n"
	    "options:\n"
	    "  -help          print this text\n"
	    "  -verbose       be verbose\n"
	    "  -root          put video onto the root window instead of\n"
	    "                 creating a new window.\n"
	    "  -id       put video into the window  instead of\n"
	    "                 creating a new window.\n"
	    "  -station   tune station  (just calls v4lctl)\n"
	    "  -no-mute       don't toggle mute on start/exit.\n"
	    "  -port       use Xvideo port .\n"
	    "  -bg            fork into background.\n"
	    "  -wm            print WindowMaker menu, to set all stations\n"
	    "                 listed in ~/.xawtv using v4lctl.\n"
	    "\n");
}

int
main(int argc, char *argv[])
{
    struct sigaction act,old;
    Display *dpy;
    Screen  *scr;
    Window win = -1;
    XWindowAttributes wts;
    KeySym keysym;
    char c;

    int ver, rel, req, ev, err, dummy;
    int adaptors,attributes;
    int i,bg,newwin,do_mute,have_mute,grab;

    dpy = XOpenDisplay(NULL);
    scr = DefaultScreenOfDisplay(dpy);
    init_atoms(dpy);

    bg = 0;
    do_mute = 1;
    have_mute = 0;
    newwin = 1;

    while (argc > 1) {
	if (0 == strcmp(argv[1],"-wm")) {
	    /* windowmaker menu */
	    wm_menu(stdout);
	    exit(0);
	}
	if (0 == strcmp(argv[1],"-h") ||
	    0 == strcmp(argv[1],"-help") ||
	    0 == strcmp(argv[1],"--help")) {
	    usage(stdout);
	    exit(0);
	}
	if (argc > 2  &&  (0 == strcmp(argv[1],"-id") ||
			   0 == strcmp(argv[1],"-window-id"))) {
	    sscanf(argv[2],"%li",&win);
	    newwin = 0;
	    if (verbose)
		fprintf(stderr,"using window id 0x%lx\n",win);
	    argc-=2;
	    argv+=2;
	} else if (argc > 2 && 0 == strcmp(argv[1],"-port")) {
	    sscanf(argv[2],"%i",&port);
	    argc-=2;
	    argv+=2;
	} else if (argc > 2 && 0 == strcmp(argv[1],"-station")) {
	    if (0 == fork()) {
		execlp("v4lctl","v4lctl","setstation",argv[2],NULL);
		exit(1);
	    } else {
		wait(&dummy);
	    }
	    argc-=2;
	    argv+=2;
	} else if (0 == strcmp(argv[1],"-root")) {
	    win = RootWindowOfScreen(scr);
	    newwin = 0;
	    if (verbose)
		fprintf(stderr,"using root window [0x%lx]\n",win);
	    argc--;
	    argv++;
	} else if (0 == strcmp(argv[1],"-bg")) {
	    bg = 1;
	    argc--;
	    argv++;
	} else if (0 == strcmp(argv[1],"-verbose")) {
	    verbose = 1;
	    argc--;
	    argv++;
	} else if (0 == strcmp(argv[1],"-no-mute")) {
	    do_mute = 0;
	    argc--;
	    argv++;
	} else {
	    fprintf(stderr,"unknown arg: \"%s\"\n",argv[1]);
	    exit(1);
	}
    }

    /* init X11 */
    if (newwin) {
	win = XCreateSimpleWindow(dpy,RootWindowOfScreen(scr),
				  0,0,640,480,1,
				  BlackPixelOfScreen(scr),
				  BlackPixelOfScreen(scr));
	XChangeProperty(dpy, win, WM_PROTOCOLS, XA_ATOM, 32,
			PropModeReplace,
			(unsigned char *) &WM_DELETE_WINDOW, 1);
    }
    XGetWindowAttributes (dpy, win, &wts);
    XSelectInput(dpy, win, wts.your_event_mask |
		 KeyPressMask | StructureNotifyMask | ExposureMask);

    /* query+print Xvideo properties */
    if (Success != XvQueryExtension(dpy,&ver,&rel,&req,&ev,&err)) {
	puts("Server does'nt support Xvideo");
	exit(1);
    }
    if (Success != XvQueryAdaptors(dpy,DefaultRootWindow(dpy),&adaptors,&ai)) {
	puts("Oops: XvQueryAdaptors failed");
	exit(1);
    }
    if (verbose)
	fprintf(stderr,"%d adaptors available.\n",adaptors);
    for (i = 0; i < adaptors; i++) {
	if (verbose)
	    fprintf(stderr,"  port=%ld name=\"%s\"\n",ai[i].base_id,ai[i].name);

	/* video adaptor ? */
	if ((ai[i].type & XvInputMask) &&
	    (ai[i].type & XvVideoMask) &&
	    (port == -1)) {
	    port = ai[i].base_id;
	}
    }
    if (adaptors > 0)
	XvFreeAdaptorInfo(ai);
    if (-1 == port) {
	fprintf(stderr,"no Xvideo port found\n");
	exit(1);
    }

    /* grab Xvideo port */
    grab = 0;
    for (i = 0; !grab && i < 3; i++) {
	switch (XvGrabPort(dpy,port,CurrentTime)) {
	case Success:
	    if (verbose)
		fprintf(stderr,"grabbed Xv port\n");
	    grab=1;
	    break;
	case XvAlreadyGrabbed:
	    if (verbose)
		fprintf(stderr,"Xv port already grabbed\n");
	    sleep(1);
	    break;
	default:
	    fprintf(stderr,"Xv port grab: Huh?\n");
	    exit(1);
	}
    }
    if (!grab) {
	fprintf(stderr,"can't grab Xv port\n");
	exit(1);
    }

    at = XvQueryPortAttributes(dpy,port,&attributes);
    for (i = 0; i < attributes; i++) {
	if (0 == strcmp("XV_MUTE",at[i].name))
	    have_mute = 1;
    }
    gc = XCreateGC(dpy,win,0,NULL);

    /* fork into background, but keep tty */
    if (bg)
	if (fork())
	    exit(0);

    /* catch signals */
    memset(&act,0,sizeof(act));
    sigemptyset(&act.sa_mask);
    act.sa_handler = catch_sig;
    sigaction(SIGINT,&act,&old);
    sigaction(SIGHUP,&act,&old);
    sigaction(SIGTERM,&act,&old);

    /* put video to the window */
    if (newwin)
	XMapWindow(dpy,win);
    if (verbose)
	fprintf(stderr,"starting video\n");
    video_blit(dpy,win);
    if (do_mute && have_mute)
	XvSetPortAttribute(dpy,port,XV_MUTE,0);

    /* receive events */
    XvSelectPortNotify(dpy, port, 1);
    XvSelectVideoNotify(dpy, win, 1);

    /* main loop */
    for (;!bye && !termsig;) {
	int rc;
	fd_set set;
	XEvent event;

	if (False == XCheckMaskEvent(dpy, ~0, &event)) {
	    /* wait for x11 events, make sure that signals are catched */
	    XFlush(dpy);
	    FD_ZERO(&set);
	    FD_SET(ConnectionNumber(dpy),&set);
	    rc = select(ConnectionNumber(dpy)+1,&set,NULL,NULL,NULL);
	    if (-1 == rc)
		if (verbose)
		    perror("... select");
	    continue;
	}

	if (event.type > ev) {
	    /* Xvideo extention event */
	    switch (event.type-ev) {
	    case XvVideoNotify:
	    {
		XvVideoNotifyEvent *xve = (XvVideoNotifyEvent*)&event;
		if (verbose)
		    fprintf(stderr,"XvVideoNotify, reason=%s, exiting\n",
			    reasons[xve->reason]);
#if 0
		bye=1;
#endif
		break;
	    }
	    case XvPortNotify:
	    {
		XvPortNotifyEvent *xpe = (XvPortNotifyEvent*)&event;
		if (verbose)
		    fprintf(stderr,"XvPortNotify: %s=%ld\n",
			    XGetAtomName(dpy,xpe->attribute),xpe->value);
		break;
	    }
	    }
	} else {
	    /* other event */
	    switch (event.type) {
	    case KeyPress:
		c = 0;
		XLookupString (&event.xkey, &c, 1, &keysym, 0);
		if (verbose)
		    fprintf(stderr,"key: %c\n",c);
		switch (c) {
		case 'q':
		case 'Q':
		case 3:   /* ^C  */
		case 27:  /* ESC */
		    bye = 1;
		}
		break;
	    case ClientMessage:
		if (event.xclient.message_type    == WM_PROTOCOLS &&
		    (Atom)event.xclient.data.l[0] == WM_DELETE_WINDOW)
		    bye = 1;
		break;
	    case Expose:
		if (event.xexpose.count)
		    break;
		/* fall througth */
	    case ConfigureNotify:
		video_blit(dpy,win);
		break;
	    default:
		if (verbose) {
		    if (event.type < SDIMOF(events))
			fprintf(stderr,"ev: %s\n",events[event.type]);
		    else
			fprintf(stderr,"ev: #%d\n",event.type);
		}
	    }
	}
    }
    if (verbose && termsig)
	fprintf(stderr,"exiting on signal %d [%s]\n",
		termsig,sys_siglist[termsig]);
    if (do_mute && have_mute)
	XvSetPortAttribute(dpy,port,XV_MUTE,1);
    XvStopVideo(dpy,port,win);
    XvUngrabPort(dpy,port,CurrentTime);
    XClearArea(dpy,win,0,0,0,0,True);
    XCloseDisplay(dpy);
    if (verbose)
	fprintf(stderr,"bye\n");

    /* keep compiler happy */
    exit(0);
}

#endif
xawtv-3.106/x11/rootv.xml000066400000000000000000000007171343350355000152060ustar00rootroot00000000000000

 
 
 
 <_description>
  This hack displays some TV station using
  the Xvideo extention.  Use CNN or MTV as
  screen saver :-)
  (c) Gerd Knorr <kraxel@bytesex.org>
 

xawtv-3.106/x11/toolbox.c000066400000000000000000000275631343350355000151550ustar00rootroot00000000000000/*
 * misc useful X11 functions for UI.  Athena Widgets.
 *
 *  (c) 1998 Gerd Knorr 
 *
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "config.h"
#include "grab-ng.h"
#include "toolbox.h"
#include "wmhooks.h"

extern Display       *dpy;
extern XVisualInfo    vinfo;
extern Colormap       colormap;
extern int stay_on_top;

extern Cursor  menu_ptr;
extern Cursor  left_ptr;

/* ---------------------------------------------------------------------- */
/* simple and handy error rotine                                          */

void
oops(char *msg)
{
    fprintf(stderr,"Oops: %s\n",msg);
    exit(1);
}

/* ---------------------------------------------------------------------- */
/* some menu stuff                                                        */

Widget
add_pulldown_menu(Widget menubar,
		  char *name)
{
    Widget menu,button;

    button = XtVaCreateManagedWidget(name,menuButtonWidgetClass,menubar,NULL);
    menu = XtVaCreatePopupShell("menu",simpleMenuWidgetClass,button,
				XtNvisual,vinfo.visual,
				XtNcolormap,colormap,
				XtNdepth, vinfo.depth,
				NULL);
    return menu;
}

Widget
add_menu_entry(Widget menu, const char *name,
	       XtCallbackProc callback, XtPointer data)
{
    Widget entry;

    entry = XtVaCreateManagedWidget(name,smeBSBObjectClass,menu,NULL);
    if (callback)
	XtAddCallback(entry,XtNcallback,callback,data);
    return entry;
}

Widget
add_menu_sep(Widget menu,char *name)
{
    Widget entry;

    entry = XtVaCreateManagedWidget(name,smeLineObjectClass,menu,NULL);
    return entry;
}

/* ---------------------------------------------------------------------- */
/* right-mouse popupmenu                                                  */

static long sel=-1;

static void
popdown_menu_CB(Widget widget, XtPointer client_data, XtPointer calldata)
{
    if (-1 == sel)
	sel = -2;
    XUngrabPointer(dpy,CurrentTime);
    XtDestroyWidget(widget);
}

static void
select_menu_CB(Widget widget, XtPointer client_data, XtPointer calldata)
{
    sel = (long)client_data;
}

int
popup_menu(Widget parent, const char *title, struct STRTAB *entries)
{
    Widget        menu,line;
    int           x,y,rx,ry,mask;
    Window        root,child;
    XtAppContext  context;
    long          i;

    sel = -1;
    if (!title)
	menu = XtVaCreatePopupShell("menu",simpleMenuWidgetClass,parent,
				    XtNvisual,vinfo.visual,
				    XtNcolormap,colormap,
				    XtNdepth, vinfo.depth,
				    NULL);
    else {
	menu = XtVaCreatePopupShell("menu",simpleMenuWidgetClass,parent,
				    XtNvisual,vinfo.visual,
				    XtNcolormap,colormap,
				    XtNdepth, vinfo.depth,
				    XtNlabel,title,
				    NULL);
	add_menu_sep(menu,"sep");
    }

    for (i = 0; entries[i].str != NULL; i++) {
	if (strlen(entries[i].str) == 0) {
	    add_menu_sep(menu,"sep");
	} else {
	    line = add_menu_entry(menu, entries[i].str,
				  select_menu_CB,
				  (XtPointer)i/*(entries[i].nr)*/);
	    if (entries[i].nr == -1)
		XtVaSetValues(line,XtNsensitive,False,NULL);
	}
    }

    XQueryPointer(dpy,
		  RootWindowOfScreen(XtScreen(menu)),
		  &root, &child,
		  &rx, &ry, &x, &y, &mask);
    XtVaSetValues(menu,
		  XtNx,x-10,
		  XtNy,y-10,
		  NULL);

    XtAddCallback(menu,XtNpopdownCallback,
		  (XtCallbackProc)popdown_menu_CB,(XtPointer)NULL);
    XtPopupSpringLoaded(menu);
    XGrabPointer(dpy, XtWindow(menu), False,
		 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
		 GrabModeAsync, GrabModeAsync, None, None, CurrentTime);

#if 0
    XtVaGetValues(menu,XtNheight,&height,NULL);
    if (y > XtScreen(menu)->height - height) {
	y = XtScreen(menu)->height - height;
	XtVaSetValues(menu,XtNy,y,NULL);
    }
#endif

    XDefineCursor(dpy,XtWindow(menu),menu_ptr);

    context = XtWidgetToApplicationContext (menu);
    while (sel == -1 || XtAppPending(context)) {
	XtAppProcessEvent (context, XtIMAll);
    }
    if (sel == -2)
	sel = -1;
    return sel;
}

void
offscreen_scroll_AC(Widget widget,  XEvent *event,
		    String *params, Cardinal *num_params)
{
#define AUTOJUMP 25
    int       x,y,rx,ry,sy,wy,wh,mask;
    Dimension dwy,dwh;
    Window    root,child;


    XQueryPointer(dpy,RootWindowOfScreen(XtScreen(widget)),
		  &root, &child, &rx, &ry, &x, &y, &mask);
    sy = XtScreen(widget)->height;
    XtVaGetValues(widget,
		  XtNy,      &dwy,
		  XtNheight, &dwh,
		  NULL);
    wy = (signed short)dwy;
    wh = (signed short)dwh;
    if (ry + AUTOJUMP < sy && ry > AUTOJUMP)
	return;
    if (ry <= wy)
	return;
    if (ry >= wy+wh)
	return;

    if (ry + AUTOJUMP >= sy)
	ry -= AUTOJUMP, wy -= AUTOJUMP;
    if (ry <= AUTOJUMP)
	ry += AUTOJUMP, wy += AUTOJUMP;
    XtVaSetValues(widget,
		  XtNy,wy,
		  NULL);
    XWarpPointer(dpy, None, RootWindowOfScreen(XtScreen(widget)),
		 0, 0, 0, 0, rx, ry);
}

/* ---------------------------------------------------------------------- */
/* resource handling                                                      */

char*
get_string_resource(Widget widget, char *name)
{
    struct RESDATA { char *str; } resdata = { NULL };
    XtResource res_desc[] = {{
	NULL,  /* name goes here */
	XtCString,
	XtRString,
	sizeof(char*),
	XtOffset(struct RESDATA*,str),
	XtRString,
	""
    }};

    res_desc[0].resource_name = name;
    XtGetApplicationResources(widget,&resdata,
			      res_desc,XtNumber(res_desc),
			      NULL,0);
    return resdata.str;
}

/* ---------------------------------------------------------------------- */
/* some stuff for doing keyboard scroll with the viewport widget          */

void
kbd_scroll_viewport_AC(Widget widget,  XEvent *event,
		       String *params, Cardinal *num_params)
{
    XtOrientation  ori;
    long           dir, percent;
    Dimension      length = 0;

    if (2 != *num_params) {
	fprintf(stderr,"KbdScroll: wrong number of arguments\n");
	return;
    }

    if (XtClass(widget) != scrollbarWidgetClass) {
	fprintf(stderr,"KbdScroll: not a scrollbar\n");
	return;
    }

    XtVaGetValues(widget,XtNorientation,&ori,NULL);
    XtVaGetValues(widget,(ori == XtorientVertical) ? XtNheight : XtNwidth,
		  &length,NULL);


    if (0 == strcasecmp(params[0],"left") ||
	0 == strcasecmp(params[0],"up")) {
	dir = -1;
    } else if (0 == strcasecmp(params[0],"right") ||
	       0 == strcasecmp(params[0],"down")) {
	dir = 1;
    } else {
	fprintf(stderr,"KbdScroll: what is %s?\n",params[0]);
	return;
    }

    /* secound arg */
    percent = atoi(params[1]);
    if (percent <= 0 || percent > 100) {
	fprintf(stderr,"KbdScroll: invalid value: %s\n",params[1]);
	return;
    }
#if 0
    fprintf(stderr,"KbdScroll: %d %d %d => %d\n",
	    percent,length,dir,(dir*percent*length/100));
#endif
    XtCallCallbacks(widget, XtNscrollProc,
		    (XtPointer)(dir*percent*length/100));
}

void
report_viewport_CB(Widget widget, XtPointer client_data, XtPointer calldata)
{
    Widget w,s;

    w = (Widget)client_data;
    s = w;
    while (s && !XtIsShell(s))
	s = XtParent(s);
    if (s)
	XtInstallAllAccelerators(w,s);
}

/* ---------------------------------------------------------------------- */
/* ask/tell user                                                          */

void
popdown_CB(Widget widget, XtPointer client_data, XtPointer calldata)
{
    Widget cancel;

    cancel = (Widget)client_data;
    XtPopdown(cancel);
}

void
destroy_CB(Widget widget, XtPointer client_data, XtPointer calldata)
{
    Widget cancel;

    cancel = (Widget)client_data;
    XtDestroyWidget(cancel);
}

void
center_under_mouse(Widget shell, int w, int h)
{
    int     x,y,rx,ry,mask,width=0,height=0,nx,ny;
    Window  root,child;

    if (!XtIsShell(shell))
	oops("move_under_mouse: not a shell");

    XQueryPointer(dpy,
		  RootWindowOfScreen(XtScreen(shell)),
		  &root, &child,
		  &rx, &ry, &x, &y, &mask);
    XtVaGetValues(shell,
		  XtNwidth, &width,
		  XtNheight,&height,
		  NULL);
    if (width==0)  width=w;
    if (height==0) height=h;
    nx = rx-(width/2);
    ny = ry-(height/2);
    if (nx < 0) nx = 0;
    if (ny < 0) ny = 0;
    /* TODO: test right & bottom border too */
    XtVaSetValues(shell,
		  XtNx,nx,
		  XtNy,ny,
		  NULL);
}

void
get_user_string(Widget parent, char *title, char *label, char *value,
		XtCallbackProc ok, XtPointer data)
{
    Widget          shell,ask;
    char            *t,*l;

    t = get_string_resource(parent,title);
    l = get_string_resource(parent,label);
    if (strlen(t) == 0) t = title;
    if (strlen(l) == 0) l = label;

    shell = XtVaCreatePopupShell("popup_ask",transientShellWidgetClass,parent,
				 XtNtitle,t,
				 XtNvisual,vinfo.visual,
				 XtNcolormap,colormap,
				 XtNdepth, vinfo.depth,
				 NULL);
    ask = XtVaCreateManagedWidget("ask",dialogWidgetClass,shell,
				  XtNlabel,l,
				  XtNvalue,value ? value : "",
				  NULL);
    XawDialogAddButton(ask,"ok",ok,data);
    XawDialogAddButton(ask,"cancel",
		       (XtCallbackProc)destroy_CB,(XtPointer)shell);
    XtInstallAllAccelerators
	(XtNameToWidget(ask,"value"),shell);

    center_under_mouse(XtParent(ask),200,80);
    XtPopup(XtParent(ask),XtGrabNonexclusive);
    XDefineCursor(dpy,XtWindow(shell),left_ptr);
}

void
tell_user(Widget parent, char *title, char *label)
{
    Widget          shell,tell;
    char            *t,*l;

    t = get_string_resource(parent,title);
    l = get_string_resource(parent,label);
    if (strlen(t) == 0) t = title;
    if (strlen(l) == 0) l = label;

    shell = XtVaCreatePopupShell("popup_tell",transientShellWidgetClass,parent,
				 XtNtitle,t,
				 XtNvisual,vinfo.visual,
				 XtNcolormap,colormap,
				 XtNdepth, vinfo.depth,
				 NULL);
    tell = XtVaCreateManagedWidget("tell",dialogWidgetClass,shell,
				   XtNlabel,l,
				   NULL);
    XawDialogAddButton(tell,"ok",(XtCallbackProc)destroy_CB,
		       (XtPointer)shell);
    XtInstallAllAccelerators(tell,shell);

    center_under_mouse(XtParent(tell),200,80);
    XtPopup(XtParent(tell),XtGrabNonexclusive);
    XDefineCursor(dpy,XtWindow(shell),left_ptr);
}

void
xperror(Widget parent, char *msg)
{
    char text[512];

    sprintf(text,"%s: %s",msg,strerror(errno));
    tell_user(parent,"str_perror_title",text);
}

/* ---------------------------------------------------------------------- */
/* cool 3D-Buttons :-)                                                    */

void
set_shadowWidth_AC(Widget widget,  XEvent *event,
		   String *params, Cardinal *num_params)
{
    int depth;

    if (1 != *num_params) {
	fprintf(stderr,"SetShadowWidth: wrong number of arguments\n");
	return;
    }
    depth = atoi(params[0]);
    XtVaSetValues(widget,"shadowWidth" /* XtNshadowWidth */, depth,NULL);
}


/* ---------------------------------------------------------------------- */
/* some stuff for help                                                    */

void
help_AC(Widget widget,  XEvent *event,
	String *params, Cardinal *num_params)
{
    Widget          shell,help;
    char            *l;

    shell =
	XtVaCreatePopupShell("popup_help",transientShellWidgetClass,widget,
			     XtNvisual,vinfo.visual,
			     XtNcolormap,colormap,
			     XtNdepth, vinfo.depth,
			     NULL);
    help = XtVaCreateManagedWidget("help",dialogWidgetClass,shell,
				   NULL);
    XawDialogAddButton(help,"ok",(XtCallbackProc)destroy_CB,
		       (XtPointer)shell);
    XtInstallAllAccelerators(help,shell);

    l = get_string_resource(widget,"help");
    if (strlen(l) == 0)
	l = "Sorry, no help text available.";

    center_under_mouse(shell,200,100);

    XtVaSetValues(help,XtNlabel,l,NULL);
    XtPopup(shell,XtGrabNonexclusive);
    if (wm_stay_on_top && stay_on_top > 0)
	wm_stay_on_top(dpy,XtWindow(shell),1);

    XDefineCursor(dpy,XtWindow(shell),left_ptr);
}
xawtv-3.106/x11/toolbox.h000066400000000000000000000022131343350355000151430ustar00rootroot00000000000000/* --- Prototypes -------------------------------------------------------- */

void    oops(char *msg);

Widget  add_pulldown_menu(Widget,char*);
Widget  add_menu_entry(Widget, const char*, XtCallbackProc, XtPointer);
Widget  add_menu_sep(Widget menu,char *name);

int popup_menu(Widget, const char*, struct STRTAB*);
void popdown_CB(Widget widget, XtPointer client_data, XtPointer calldata);
void destroy_CB(Widget widget, XtPointer client_data, XtPointer calldata);
void center_under_mouse(Widget shell,int,int);
void offscreen_scroll_AC(Widget widget,  XEvent *event,
			 String *params, Cardinal *num_params);

char* get_string_resource(Widget widget, char *name);

void kbd_scroll_viewport_AC(Widget widget,  XEvent *event,
			    String *params, Cardinal *num_params);
void report_viewport_CB(Widget, XtPointer, XtPointer);

void get_user_string(Widget, char*, char*, char*, XtCallbackProc, XtPointer);
void tell_user(Widget, char*, char*);
void xperror(Widget, char*);

void help_AC(Widget widget,  XEvent *event,
	     String *params, Cardinal *num_params);
void set_shadowWidth_AC(Widget widget,  XEvent *event,
			String *params, Cardinal *num_params);
xawtv-3.106/x11/v4lctl.c000066400000000000000000000041471343350355000146700ustar00rootroot00000000000000/*
 *  (c) 1999 Gerd Knorr 
 *
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "config.h"

#ifdef HAVE_LIBXV
# include 
# include 
# include 
# include "atoms.h"
# include "xv.h"
#endif

#include "grab-ng.h"
#include "channel.h"
#include "frequencies.h"
#include "commands.h"

int debug = 0;
int have_dga = 0;
#ifdef HAVE_LIBXV
Display *dpy;
#endif

/*--- main ---------------------------------------------------------------*/

static void
grabber_init(void)
{
    drv = ng_vid_open(&ng_dev.video,ng_dev.driver,NULL,0,&h_drv);
    if (NULL == drv) {
	fprintf(stderr,"no grabber device available\n");
	exit(1);
    }
    f_drv = drv->capabilities(h_drv);
    add_attrs(drv->list_attrs(h_drv));
}

static void
usage(void)
{
    fprintf(stderr,
	    "\n"
	    "usage: v4lctl [ options ] command\n"
	    "options:\n"
	    "  -v, --debug=n      debug level n, n = [0..2]\n"
	    "  -c, --device=file  use  as video4linux device\n"
	    "  -h, --help         print this text\n"
	    "\n");
}

int main(int argc, char *argv[])
{
    int c;
    int xvideo = 1;

    ng_init();
    for (;;) {
	if (-1 == (c = getopt(argc, argv, "hv:c:D:")))
	    break;
	switch (c) {
	case 'v':
	    ng_debug = debug = atoi(optarg);
	    break;
	case 'c':
	    ng_dev.video = optarg;
	    xvideo = 0;
	    break;
	case 'D':
	    ng_dev.driver = optarg;
	    xvideo = 0;
	    break;
	case 'h':
	default:
	    usage();
	    exit(1);
	}
    }
    if (optind == argc) {
	usage();
	exit(1);
    }

#ifdef HAVE_LIBXV
    if (NULL != getenv("DISPLAY"))
	dpy = XOpenDisplay(NULL);
    if (dpy) {
	init_atoms(dpy);
	if (xvideo)
	    xv_video_init(-1,0);
    }
#endif
    if (NULL == drv)
	grabber_init();
    freq_init();
    read_config(NULL,NULL,NULL);

    attr_init();
    audio_init();
    audio_init();

    parse_config(1);

    do_command(argc-optind,argv+optind);
    drv->close(h_drv);
#ifdef HAVE_LIBXV
    if (dpy)
	XCloseDisplay(dpy);
#endif
    return 0;
}
xawtv-3.106/x11/vbi-gui.c000066400000000000000000000746111343350355000150250ustar00rootroot00000000000000/*
 * vbi-gui  --  motif videotext browser
 *
 *   (c) 2002 Gerd Knorr 
 */

#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "atoms.h"
#include "list.h"
#include "vbi-data.h"
#include "vbi-x11.h"
#include "vbi-gui.h"

#include "grab-ng.h"
#include "channel.h"

static int tt_debug = 1;
static int tt_windows = 0;

struct vbi_selection {
    struct list_head  list;
    Atom              atom;
    struct vbi_page   pg;
    struct vbi_rect   rect;
    Pixmap            pix;
};

static void vbi_new_cb(Widget, XtPointer, XtPointer);
static void vbi_goto_cb(Widget, XtPointer, XtPointer);
static void vbi_subpage_menu(struct vbi_window *vw);
static void selection_pri(struct vbi_window *vw);
static void selection_dnd_start(struct vbi_window *vw, XEvent *event);

/* --------------------------------------------------------------------- */

static void
vbi_fix_head(struct vbi_window *vw, struct vbi_char *ch)
{
    int showno,showsub,red,i;

    showno  = vw->pg.pgno;
    showsub = vw->pg.subno;
    red     = 0;
    if (0 == showno) {
	showno  = vw->pgno;
	showsub = 0;
	red     = 1;
    }
    if (vw->newpage) {
	showno  = vw->newpage;
	showsub = 0;
	red     = 1;
    }

    for (i = 1; i <= 6; i++)
	ch[i].unicode = ' ';
    if (showno >= 0x100)
	ch[1].unicode = '0' + ((showno >> 8) & 0xf);
    if (showno >= 0x10)
	ch[2].unicode = '0' + ((showno >> 4) & 0xf);
    if (showno >= 0x1)
	ch[3].unicode = '0' + ((showno >> 0) & 0xf);
    if (showsub) {
	ch[4].unicode = '/';
	ch[5].unicode = '0' + ((showsub >> 4) & 0xf);
	ch[6].unicode = '0' + ((showsub >> 0) & 0xf);
    }
    if (red) {
	ch[1].foreground = VBI_RED;
	ch[2].foreground = VBI_RED;
	ch[3].foreground = VBI_RED;
    }
}

static void
vbi_check_rectangle(struct vbi_rect *rect)
{
    int h;

    if (rect->x1 > rect->x2)
	h = rect->x1, rect->x1 = rect->x2, rect->x2 = h;
    if (rect->y1 > rect->y2)
	h = rect->y1, rect->y1 = rect->y2, rect->y2 = h;

    if (rect->x1 < 0) rect->x1 = 0;
    if (rect->x2 < 0) rect->x2 = 0;
    if (rect->y1 < 0) rect->y1 = 0;
    if (rect->y2 < 0) rect->y2 = 0;

    if (rect->x1 > 41) rect->x1 = 41;
    if (rect->x2 > 41) rect->x2 = 41;
    if (rect->y1 > 25) rect->y1 = 25;
    if (rect->y2 > 25) rect->y2 = 25;
}

static void
vbi_mark_rectangle(struct vbi_window *vw)
{
    struct vbi_rect rect;
    XGCValues values;
    int x,y,w,h;

    rect = vw->s;
    vbi_check_rectangle(&rect);
    x = vw->w * (rect.x1);
    w = vw->w * (rect.x2 - rect.x1);
    y = vw->h * (rect.y1);
    h = vw->h * (rect.y2 - rect.y1);
    values.function   = GXxor;
    values.foreground = ~0;
    XChangeGC(XtDisplay(vw->tt),vw->gc,GCFunction|GCForeground,&values);
    XFillRectangle(XtDisplay(vw->tt),XtWindow(vw->tt),vw->gc,
		   x,y,w,h);
}

static void
vbi_render_page(struct vbi_window *vw)
{
    struct vbi_char *ch;
    int y;

    vbi_fix_head(vw,vw->pg.text);
    for (y = 0; y < 25; y++) {
	ch = vw->pg.text + 41*y;
	vbi_render_line(vw,XtWindow(vw->tt),ch,y,0,0,41);
    }
    if ((vw->s.x1 || vw->s.x2) &&
	(vw->s.y1 || vw->s.y2))
	vbi_mark_rectangle(vw);
}

static void
vbi_render_head(struct vbi_window *vw, int pgno, int subno)
{
    vbi_page pg;

    memset(&pg,0,sizeof(pg));
    vbi_fetch_vt_page(vw->vbi->dec,&pg,pgno,subno,
		      VBI_WST_LEVEL_1p5,1,0);
    vbi_fix_head(vw,pg.text);
    vbi_render_line(vw,XtWindow(vw->tt),pg.text,0,0,0,41);
}

static void
vbi_newdata(struct vbi_event *ev, void *user)
{
    struct vbi_window *vw = user;

    switch (ev->type) {
    case VBI_EVENT_TTX_PAGE:
	if (vw->pgno  == ev->ev.ttx_page.pgno) {
	    if (vw->subno == ev->ev.ttx_page.subno ||
		vw->subno == VBI_ANY_SUBNO) {
		vbi_fetch_vt_page(vw->vbi->dec,&vw->pg,vw->pgno,vw->subno,
				  VBI_WST_LEVEL_1p5,25,1);
		vbi_render_page(vw);
	    }
	    vbi_subpage_menu(vw);
	} else {
	    vbi_render_head(vw,
			    ev->ev.ttx_page.pgno,
			    ev->ev.ttx_page.subno);
	}
	break;
    case VBI_EVENT_NETWORK:
	XtVaSetValues(vw->shell,XtNtitle,ev->ev.network.name,NULL);
	break;
    }
}

/* --------------------------------------------------------------------- */
/* GUI handling                                                          */

static void
vbi_subpage_menu(struct vbi_window *vw)
{
    WidgetList children,list;
    Cardinal nchildren;
    Widget push;
    vbi_page pg;
    char page[8];
    unsigned int i;

    /* delete children */
    XtVaGetValues(vw->submenu,XtNchildren,&children,
		  XtNnumChildren,&nchildren,NULL);
    if (0 != nchildren) {
	list = malloc(sizeof(Widget*)*nchildren);
	memcpy(list,children,sizeof(Widget*)*nchildren);
	for (i = 0; i < nchildren; i++)
	    XtDestroyWidget(list[i]);
	free(list);
    }

    /* rebuild menu */
    push = XtVaCreateManagedWidget("s00",xmPushButtonWidgetClass,
				   vw->submenu,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_goto_cb,vw);
    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,
			    vw->submenu,NULL);
    if (vw->pg.pgno && vw->pg.subno) {
	XtVaSetValues(vw->subbtn,XtNsensitive,True,NULL);
	for (i = 0; i < VBI_MAX_SUBPAGES; i++) {
	    if (!vbi_fetch_vt_page(vw->vbi->dec,&pg,vw->pg.pgno,i,
				   VBI_WST_LEVEL_1,0,0))
		continue;
	    sprintf(page,"s%02x",i);
	    push = XtVaCreateManagedWidget(page,xmPushButtonWidgetClass,
					   vw->submenu,NULL);
	    XtAddCallback(push,XmNactivateCallback,vbi_goto_cb,vw);
	}
    } else {
	XtVaSetValues(vw->subbtn,XtNsensitive,False,NULL);
    }
}

static void
vbi_setpage(struct vbi_window *vw, int pgno, int subno)
{
    vw->pgno = pgno;
    vw->subno = subno;
    vw->newpage = 0;
    memset(&vw->pg,0,sizeof(struct vbi_page));
    vbi_fetch_vt_page(vw->vbi->dec,&vw->pg,vw->pgno,vw->subno,
		      VBI_WST_LEVEL_1p5,25,1);
    if (XtWindow(vw->tt))
	vbi_render_page(vw);
    vbi_subpage_menu(vw);
}

static void
vbi_expose_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmDrawingAreaCallbackStruct *cd = call_data;
    struct vbi_window *vw = clientdata;

    if (cd->event->xexpose.count > 0)
	return;
    vbi_render_page(vw);
}

static void
vbi_destroy_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct vbi_window *vw = clientdata;

    vbi_event_handler_unregister(vw->vbi->dec,vbi_newdata,vw);
    vbi_render_free_font(widget,vw);
    XFreeGC(XtDisplay(widget),vw->gc);
    free(vw);
    tt_windows--;
    if (0 == tt_windows)
	exit(0);
}

static void
vbi_close_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct vbi_window *vw = clientdata;
    XtDestroyWidget(vw->shell);
}

static void
vbi_new_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct vbi_window *vw = clientdata;
    Widget shell;

    shell = XtVaAppCreateShell("mtt","mtt",applicationShellWidgetClass,
			       XtDisplay(widget),NULL);
    vbi_create_widgets(shell,vw->vbi);
    XtRealizeWidget(shell);
}

static void
vbi_font_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct vbi_window *vw = clientdata;
    char *name = XtName(widget);
    vbi_render_set_font(widget, vw, name);
    XtVaSetValues(vw->tt, XmNwidth,vw->w*41, XmNheight,vw->h*25, NULL);
    XClearWindow(XtDisplay(vw->tt),XtWindow(vw->tt));
}

static void
vbi_goto_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct vbi_window *vw = clientdata;
    int pgno,subno;
    char *name;

    pgno  = vw->pg.pgno;
    subno = vw->pg.subno;
    name = XtName(widget);
    if (0 == strcmp(name,"prev")) {
	pgno  = vbi_calc_page(vw->pgno,-1);
	subno = VBI_ANY_SUBNO;
    } else if (0 == strcmp(name,"next")) {
	pgno  = vbi_calc_page(vw->pgno,+1);
	subno = VBI_ANY_SUBNO;
    } else if (1 == sscanf(name,"s%x",&subno)) {
	/* nothing */
    } else {
	sscanf(name,"%x",&pgno);
	subno = VBI_ANY_SUBNO;
    }
    if (0 == subno)
	subno = VBI_ANY_SUBNO;
    vbi_setpage(vw,pgno,subno);
}

static int
vbi_findpage(struct vbi_page *pg, int px, int py)
{
    int newpage = 0;
    int x;

    if (py == 24) {
	/* navigation line */
	int i = (pg->text[py*41+px].foreground & 7) -1;
	if (i >= 6)
	    i = 0;
	newpage = pg->nav_link[i].pgno;
    } else if (px <= 40 && py <= 23) {
	if (pg->text[py*41+px].unicode >= '0' &&
	    pg->text[py*41+px].unicode <= '9') {
	    /* look for a 3-digit string ... */
	    x = px; newpage = 0;
	    while (pg->text[py*41+x].unicode >= '0' &&
		   pg->text[py*41+x].unicode <= '9' &&
		   x > 0) {
		x--;
	    }
	    x++;
	    while (pg->text[py*41+x].unicode >= '0' &&
		   pg->text[py*41+x].unicode <= '9' &&
		   x < 40) {
		newpage = newpage*16 + pg->text[py*41+x].unicode - '0';
		x++;
	    }

	} else if (pg->text[py*41+px].unicode == '>') {
	    /* next page */
	    newpage = vbi_calc_page(pg->pgno,+1);

	} else if (pg->text[py*41+px].unicode == '<') {
	    /* prev page */
	    newpage = vbi_calc_page(pg->pgno,-1);
	}
    }

    if (newpage < 0x100 || newpage >= 0x999)
	return 0;
    return newpage;
}

static void
vbi_kbd_eh(Widget widget, XtPointer clientdata, XEvent *event, Boolean *cont)
{
    struct vbi_window *vw = clientdata;
    KeySym sym;
    int digit,subno;

    switch (event->type) {
    case KeyPress:
	sym = XkbKeycodeToKeysym(XtDisplay(widget),event->xkey.keycode,0,0);
	digit = -1;
	switch (sym) {
	case XK_0:
	case XK_KP_Insert:
	    digit = 0;
	    break;
	case XK_1:
	case XK_KP_End:
	    digit = 1;
	    break;
	case XK_2:
	case XK_KP_Down:
	    digit = 2;
	    break;
	case XK_3:
	case XK_KP_Next:
	    digit = 3;
	    break;
	case XK_4:
	case XK_KP_Left:
	    digit = 4;
	    break;
	case XK_5:
	case XK_KP_Begin:
	    digit = 5;
	    break;
	case XK_6:
	case XK_KP_Right:
	    digit = 6;
	    break;
	case XK_7:
	case XK_KP_Home:
	    digit = 7;
	    break;
	case XK_8:
	case XK_KP_Up:
	    digit = 8;
	    break;
	case XK_9:
	case XK_KP_Prior:
	    digit = 9;
	    break;
	case XK_space:
	case XK_l:
	    vbi_setpage(vw,vbi_calc_page(vw->pgno,+1),VBI_ANY_SUBNO);
	    break;
	case XK_BackSpace:
	case XK_h:
	    vbi_setpage(vw,vbi_calc_page(vw->pgno,-1),VBI_ANY_SUBNO);
	    break;
	case XK_k:
	    subno = (vw->subno != VBI_ANY_SUBNO) ? vw->subno : vw->pg.subno;
	    subno = vbi_calc_subpage(vw->vbi->dec,vw->pgno,subno,+1);
	    vbi_setpage(vw,vw->pgno,subno);
	    break;
	case XK_j:
	    subno = (vw->subno != VBI_ANY_SUBNO) ? vw->subno : vw->pg.subno;
	    subno = vbi_calc_subpage(vw->vbi->dec,vw->pgno,subno,-1);
	    vbi_setpage(vw,vw->pgno,subno);
	    break;
	}
	if (-1 != digit) {
	    vw->newpage *= 16;
	    vw->newpage += digit;
	    if (vw->newpage >= 0x100)
		vbi_setpage(vw,vw->newpage,VBI_ANY_SUBNO);
	}
	break;
    }
}

static void
vbi_mouse_eh(Widget widget, XtPointer clientdata, XEvent *event, Boolean *cont)
{
    struct vbi_window *vw = clientdata;
    int px,py,newpage;

    switch (event->type) {
    case ButtonPress:
	switch (event->xbutton.button) {
	case 1: /* left mouse button */
	    px = event->xbutton.x / vw->w;
	    py = event->xbutton.y / vw->h;
	    vw->s.x1 = vw->s.x2 = px;
	    vw->s.y1 = vw->s.y2 = py;
	    vw->down = event->xbutton.time;
	    break;
	case 2: /* middle button */
	    selection_dnd_start(vw,event);
	    break;
	}
	break;
    case MotionNotify:
	if (event->xmotion.state & Button1Mask) {
	    vw->s.x2 = event->xbutton.x / vw->w +1;
	    vw->s.y2 = event->xbutton.y / vw->h +1;
	    vbi_render_page(vw);
	}
	break;
    case ButtonRelease:
	switch (event->xbutton.button) {
	case 1: /* left mouse button */
	    px = event->xbutton.x / vw->w;
	    py = event->xbutton.y / vw->h;
	    if (abs(vw->s.x1 - px) < 2  &&  abs(vw->s.y1 - py) < 2  &&
		event->xbutton.time - vw->down < 500) {
		/* mouse click */
		vw->s.x1 = vw->s.x2 = 0;
		vw->s.y1 = vw->s.y2 = 0;
		newpage = vbi_findpage(&vw->pg,px,py);
		if (0 != newpage)
		    vbi_setpage(vw,newpage,VBI_ANY_SUBNO);
		else
		    vbi_render_page(vw);
	    } else {
		/* marked region */
		vw->s.x2 = px +1;
		vw->s.y2 = py +1;
		vbi_render_page(vw);
		selection_pri(vw);
	    }
	    break;
	case 4: /* wheel up */
	    newpage = vbi_calc_page(vw->pgno,-1);
	    vbi_setpage(vw,newpage,VBI_ANY_SUBNO);
	    break;
	case 5: /* wheel down */
	    newpage = vbi_calc_page(vw->pgno,+1);
	    vbi_setpage(vw,newpage,VBI_ANY_SUBNO);
	    break;
	}
	break;
    }
}

/* --------------------------------------------------------------------- */
/* export data                                                           */

static void
export_do_save_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    static struct vbi_rect rect = {
	.x1 =  0,
	.x2 = 41,
	.y1 =  0,
	.y2 = 25,
    };
    XmFileSelectionBoxCallbackStruct *cb = call_data;
    struct vbi_window *vw = clientdata;
    char *filename, *data;
    int len,fh;

    if (cb->reason == XmCR_OK) {
	filename = XmStringUnparse(cb->value,NULL,
				   XmMULTIBYTE_TEXT,XmMULTIBYTE_TEXT,
				   NULL,0,0);
	data = malloc(25*41*8);
	len = vbi_export_txt(data,vw->charset,25*41*8,&vw->pg,&rect,
			     VBI_NOCOLOR);
	fh = open(filename,O_WRONLY | O_CREAT, 0666);
	if (-1 == fh) {
	    fprintf(stderr,"open %s: %s\n",filename,strerror(errno));
	} else {
	    ftruncate(fh,0);
	    write(fh,data,len);
	    close(fh);
	}
	free(data);
    }
    XtUnmanageChild(widget);
}

static void
export_charset_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct vbi_window *vw = clientdata;
    vw->charset = XtName(widget);
}

static void
export_save_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct vbi_window *vw = clientdata;
    Widget help,text=text,menu,option,push;
    Arg args[2];

    if (NULL == vw->savebox) {
	vw->savebox = XmCreateFileSelectionDialog(vw->shell,"save",NULL,0);
	help = XmFileSelectionBoxGetChild(vw->savebox,XmDIALOG_HELP_BUTTON);
	XmFileSelectionBoxGetChild(vw->savebox,XmDIALOG_TEXT);
	XtUnmanageChild(help);

	menu = XmCreatePulldownMenu(vw->savebox,"formatM",NULL,0);
	XtSetArg(args[0],XmNsubMenuId,menu);
	option = XmCreateOptionMenu(vw->savebox,"format",args,1);
	XtManageChild(option);

	vw->charset = nl_langinfo(CODESET);
	push = XtVaCreateManagedWidget(vw->charset,xmPushButtonWidgetClass,
				       menu, NULL);
	XtAddCallback(push,XmNactivateCallback,export_charset_cb,vw);
	if (0 != strcasecmp(vw->charset,"UTF-8")) {
	    push = XtVaCreateManagedWidget("UTF-8",
					   xmPushButtonWidgetClass,menu,NULL);
	    XtAddCallback(push,XmNactivateCallback,export_charset_cb,vw);
	}
	if (0 != strcasecmp(vw->charset,"ISO-8859-1")) {
	    push = XtVaCreateManagedWidget("ISO-8859-1",
					   xmPushButtonWidgetClass,menu,NULL);
	    XtAddCallback(push,XmNactivateCallback,export_charset_cb,vw);
	}
	if (0 != strcasecmp(vw->charset,"US-ASCII")) {
	    push = XtVaCreateManagedWidget("US-ASCII",
					   xmPushButtonWidgetClass,menu,NULL);
	    XtAddCallback(push,XmNactivateCallback,export_charset_cb,vw);
	}
	XtAddCallback(vw->savebox,XmNokCallback,export_do_save_cb,vw);
	XtAddCallback(vw->savebox,XmNcancelCallback,export_do_save_cb,vw);
    }
    XtManageChild(vw->savebox);
}

/* --------------------------------------------------------------------- */
/* selection handling (cut+paste, drag'n'drop)                           */

static struct vbi_selection*
selection_find(struct vbi_window *vw, Atom selection)
{
    struct list_head      *item;
    struct vbi_selection  *sel;

    list_for_each(item,&vw->selections) {
	sel = list_entry(item, struct vbi_selection, list);
	if (sel->atom == selection)
	    return sel;
    }
    return NULL;
}

static void
selection_fini(struct vbi_window *vw, Atom selection)
{
    struct vbi_selection  *sel;

    sel = selection_find(vw,selection);
    if (NULL == sel)
	return;
    if (sel->pix)
	XFreePixmap(XtDisplay(vw->tt),sel->pix);

    list_del(&sel->list);
    free(sel);
}

static void
selection_init(struct vbi_window *vw, Atom selection)
{
    struct vbi_selection  *sel;

    selection_fini(vw,selection);
    sel = malloc(sizeof(*sel));
    memset(sel,0,sizeof(*sel));
    list_add_tail(&sel->list,&vw->selections);
    sel->atom = selection;
    sel->pg   = vw->pg;
    sel->rect = vw->s;
    vbi_check_rectangle(&sel->rect);
    if (0 == sel->rect.x2  &&  0 == sel->rect.y2) {
	sel->rect.x2 = 41;
	sel->rect.y2 = 25;
    }
}

static Atom selection_unique_atom(struct vbi_window *vw)
{
    char id_name[32];
    Atom id;
    int i;

    for (i = 0;; i++) {
	sprintf(id_name,"_VBI_DATA_%lX_%d",XtWindow(vw->tt),i);
	id = XInternAtom(XtDisplay(vw->tt),id_name,False);
	if (NULL == selection_find(vw,id))
	    break;
    }
    return id;
}

static void
selection_convert_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    XmConvertCallbackStruct *ccs = call_data;
    struct vbi_window *vw = clientdata;
    struct vbi_selection *sel;
    Display *dpy = XtDisplay(widget);
    unsigned long *ldata;
    unsigned char *cdata;
    Atom *targs;
    int n;

    if (tt_debug) {
	char *y = !ccs->type      ? NULL : XGetAtomName(dpy,ccs->type);
	char *t = !ccs->target    ? NULL : XGetAtomName(dpy,ccs->target);
	char *s = !ccs->selection ? NULL : XGetAtomName(dpy,ccs->selection);
	fprintf(stderr,"tt: target=%s type=%s selection=%s\n",t,y,s);
	if (y) XFree(y);
	if (t) XFree(t);
	if (s) XFree(s);
    }

    if ((ccs->target == XA_TARGETS) ||
	(ccs->target == _MOTIF_CLIPBOARD_TARGETS) ||
	(ccs->target == _MOTIF_DEFERRED_CLIPBOARD_TARGETS) ||
	(ccs->target == _MOTIF_EXPORT_TARGETS)) {
	/* query convert capabilities */
	n = 0;
	targs = (Atom*)XtMalloc(sizeof(Atom)*32);
	if (ccs->target != _MOTIF_CLIPBOARD_TARGETS) {
	    targs[n++]  = XA_TARGETS;
	    targs[n++]  = XA_PIXMAP;
	    targs[n++]  = XA_COLORMAP;
	    targs[n++]  = XA_FOREGROUND;
	    targs[n++]  = XA_BACKGROUND;
	    targs[n++]  = MIME_TEXT_UTF_8;
	    targs[n++]  = XA_UTF8_STRING;
	    targs[n++]  = MIME_TEXT_ISO8859_1;
	    targs[n++]  = XA_STRING;
	}
	if (ccs->target == _MOTIF_EXPORT_TARGETS) {
	    /* save away drag'n'drop data */
	    selection_init(vw,ccs->selection);
	}
	ccs->value  = targs;
	ccs->length = n;
	ccs->type   = XA_ATOM;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;
	return;

    } else if (ccs->target == _MOTIF_SNAPSHOT) {
	/* save away clipboard data */
	n = 0;
	targs = (Atom*)XtMalloc(sizeof(Atom));
	targs[n++] = selection_unique_atom(vw);
	selection_init(vw,targs[0]);
	ccs->value  = targs;
	ccs->length = n;
	ccs->type   = XA_ATOM;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;
	return;
    }

    /* find data */
    sel = selection_find(vw,ccs->selection);
    if (NULL == sel) {
	/* shouldn't happen */
	fprintf(stderr,"tt: oops: selection data not found\n");
	ccs->status = XmCONVERT_REFUSE;
	return;
    }

    if (ccs->target == _MOTIF_LOSE_SELECTION ||
	ccs->target == XA_DONE) {
	/* cleanup */
	selection_fini(vw,ccs->selection);
	if (XA_PRIMARY == ccs->selection) {
	    /* unmark selection */
	    vw->s.x1 = vw->s.x2 = 0;
	    vw->s.y1 = vw->s.y2 = 0;
	    vbi_render_page(vw);
	}
	ccs->value  = NULL;
	ccs->length = 0;
	ccs->type   = XA_INTEGER;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;
	return;
    }

    /* convert data */
    if (ccs->target == XA_STRING ||
	ccs->target == MIME_TEXT_ISO8859_1) {
	cdata = XtMalloc(25*41*8);
	n = vbi_export_txt(cdata,"ISO8859-1",25*41*8,&sel->pg,&sel->rect,
			   VBI_NOCOLOR);
	ccs->value  = cdata;
	ccs->length = n;
	ccs->type   = XA_STRING;
	ccs->format = 8;
	ccs->status = XmCONVERT_DONE;

    } else if (ccs->target == XA_UTF8_STRING ||
	       ccs->target == MIME_TEXT_UTF_8) {
	cdata = XtMalloc(25*41*8);
	n = vbi_export_txt(cdata,"UTF-8",25*41*8,&sel->pg,&sel->rect,
			   VBI_NOCOLOR);
	ccs->value  = cdata;
	ccs->length = n;
	ccs->type   = XA_STRING;
	ccs->format = 8;
	ccs->status = XmCONVERT_DONE;

    } else if (ccs->target == XA_BACKGROUND ||
	       ccs->target == XA_FOREGROUND ||
	       ccs->target == XA_COLORMAP) {
	n = 0;
	ldata = (Atom*)XtMalloc(sizeof(Atom)*8);
	if (ccs->target == XA_BACKGROUND) {
	    ldata[n++] = WhitePixelOfScreen(XtScreen(widget));
	    ccs->type  = XA_PIXEL;
	}
	if (ccs->target == XA_FOREGROUND) {
	    ldata[n++] = BlackPixelOfScreen(XtScreen(widget));
	    ccs->type  = XA_PIXEL;
	}
	if (ccs->target == XA_COLORMAP) {
	    ldata[n++] = DefaultColormapOfScreen(XtScreen(widget));
	    ccs->type  = XA_COLORMAP;
	}
	ccs->value  = ldata;
	ccs->length = n;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;

    } else if (ccs->target == XA_PIXMAP) {
	/* xfer pixmap */
	if (!sel->pix)
	    sel->pix = vbi_export_pixmap(vw,&sel->pg,&sel->rect);
	if (tt_debug)
	    fprintf(stderr,"tt: pixmap id is 0x%lx\n",sel->pix);
	ldata = (Pixmap*)XtMalloc(sizeof(Pixmap));
	ldata[0] = sel->pix;
	ccs->value  = ldata;
	ccs->length = 1;
	ccs->type   = XA_DRAWABLE;
	ccs->format = 32;
	ccs->status = XmCONVERT_DONE;

    } else {
	/* shouldn't happen */
	fprintf(stderr,"tt: oops: target not found\n");
	ccs->status = XmCONVERT_REFUSE;
    }
}

static void
selection_pri(struct vbi_window *vw)
{
    if (tt_debug)
	fprintf(stderr,"tt: primary\n");

    selection_init(vw,XA_PRIMARY);
    XmePrimarySource(vw->tt,XtLastTimestampProcessed(XtDisplay(vw->tt)));
}

static void
selection_clip_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct vbi_window *vw = clientdata;

    if (tt_debug)
	fprintf(stderr,"tt: clipboard [copy]\n");

    XmeClipboardSource(vw->tt,XmCOPY,
		       XtLastTimestampProcessed(XtDisplay(vw->tt)));
}

static void
selection_dnd_done(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct vbi_window *vw = clientdata;

    if (tt_debug)
	fprintf(stderr,"tt: dnd done\n");
    selection_fini(vw,_MOTIF_DROP);
}

static void
selection_dnd_start(struct vbi_window *vw, XEvent *event)
{
    Widget    drag;
    Arg       args[4];
    Cardinal  n=0;

    if (tt_debug)
	fprintf(stderr,"tt: dnd start\n");
    n = 0;
    XtSetArg(args[n], XmNdragOperations, XmDROP_COPY); n++;
    drag = XmeDragSource(vw->tt, NULL, event, args, n);
    XtAddCallback(drag, XmNdragDropFinishCallback, selection_dnd_done, vw);
}

/* --------------------------------------------------------------------- */

static void vbi_station_cb(Widget widget, XtPointer client, XtPointer call)
{
    struct vbi_state *vbi = client;
    char *name = XtName(widget);
    int i;

    for (i = 0; i < count; i++)
	if (0 == strcmp(channels[i]->name,name))
	    break;
    if (i == count)
	return;
#if 0
    fprintf(stderr,"tune: %.3f MHz [channel %s, station %s]\n",
	    channels[i]->freq / 16.0,
	    channels[i]->cname,
	    channels[i]->name);
#endif

#ifdef linux
#include 
#include "videodev2.h"
    {
	struct v4l2_frequency frequency;

	memset (&frequency, 0, sizeof(frequency));
	frequency.type = V4L2_TUNER_ANALOG_TV;
	frequency.frequency = channels[i]->freq;
	if (-1 == ioctl(vbi->fd, VIDIOC_S_FREQUENCY, &frequency))
	    perror("ioctl VIDIOC_S_FREQUENCY");
    }
#endif

    /* FIXME: should add some BSD code once libzvbi is ported ... */
}

static void vbi_station_menu(Widget menubar, struct vbi_state *vbi)
{
    struct {
	char *name;
	Widget menu;
    } *sub = NULL;
    int subs = 0;

    Widget m,menu,push;
    XmString label;
    int i,j;

    if (0 == count)
	return;

    menu = XmCreatePulldownMenu(menubar,"stationM",NULL,0);
    XtVaCreateManagedWidget("station",xmCascadeButtonWidgetClass,menubar,
			    XmNsubMenuId,menu,NULL);

    for (i = 0; i < count; i++) {
#if 0
	if (channels[i]->key) {
	    if (2 == sscanf(channels[i]->key,
			    "%15[A-Za-z0-9_]+%31[A-Za-z0-9_]",
			    ctrl,key)) {
		sprintf(accel,"%s%s",ctrl,key);
	    } else {
		sprintf(accel,"%s",channels[i]->key);
	    }
	} else {
	    accel[0] = 0;
	}
#endif

	m = menu;
	if (0 != strcmp(channels[i]->group,"main")) {
	    for (j = 0; j < subs; j++)
		if (0 == strcmp(channels[i]->group,sub[j].name))
		    break;
	    if (j == subs) {
		subs++;
		sub = realloc(sub, subs * sizeof(*sub));
		sub[j].name = channels[i]->group;
		sub[j].menu = XmCreatePulldownMenu(menu,
						   channels[i]->group,
						   NULL,0);
		XtVaCreateManagedWidget(channels[i]->group,
					xmCascadeButtonWidgetClass, menu,
					XmNsubMenuId, sub[j].menu,
					NULL);
	    }
	    m = sub[j].menu;
	}

	label = XmStringGenerate(channels[i]->name, NULL, XmMULTIBYTE_TEXT, NULL);
	push = XtVaCreateManagedWidget(channels[i]->name,
				       xmPushButtonWidgetClass,m,
				       XmNlabelString,label,
				       NULL);
	XtAddCallback(push,XmNactivateCallback,vbi_station_cb,vbi);
	XmStringFree(label);
    }
}

static int fntcmp(const void *a, const void *b)
{
    char const * const *aa = a;
    char const * const *bb = b;

    return strcmp(*aa,*bb);
}

static void vbi_xft_font_menu(Widget menu, struct vbi_window *vw)
{
#ifdef HAVE_XFT
    FcPattern   *pattern;
    FcObjectSet *oset;
    FcFontSet   *fset;
    Widget      push;
    XmString    label;
    char        **fonts, *h;
    int         i;

    pattern = FcNameParse(":style=Regular:spacing=100:slant=0:weight=100");
    oset = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_SPACING, FC_SLANT,
			    FC_WEIGHT, NULL);
    fset = FcFontList(NULL, pattern, oset);
    FcPatternDestroy(pattern);
    if (fset) {
	XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,menu,NULL);
	fonts = malloc(sizeof(char*) * fset->nfont);
	for (i = 0; i < fset->nfont; i++)
	    fonts[i] = FcNameUnparse (fset->fonts[i]);
	qsort(fonts,fset->nfont,sizeof(char*),fntcmp);

	for (i = 0; i < fset->nfont; i++) {
	    push = XtVaCreateManagedWidget(fonts[i],xmPushButtonWidgetClass,menu,NULL);
	    h = strchr(fonts[i],':');
	    if (h)
		*h = 0;
	    label = XmStringGenerate(fonts[i], NULL, XmMULTIBYTE_TEXT, NULL);
	    XtVaSetValues(push, XmNlabelString, label, NULL);
	    XmStringFree(label);

	    XtAddCallback(push, XmNactivateCallback, vbi_font_cb, vw);
	}

	for (i = 0; i < fset->nfont; i++)
	    free(fonts[i]);
	free(fonts);
    }
#endif
}

/* --------------------------------------------------------------------- */

void vbi_create_widgets(Widget shell, struct vbi_state *vbi)
{
    Widget form,menubar,tool,menu,push,tt;
    struct vbi_window *vw;
    int i;

    /* form container */
    XtVaSetValues(shell, XmNallowShellResize, True, NULL);
    form = XtVaCreateManagedWidget("form", xmFormWidgetClass, shell,
				   NULL);

    /* menu- & toolbar */
    menubar = XmCreateMenuBar(form,"bar",NULL,0);
    XtManageChild(menubar);
    tool = XtVaCreateManagedWidget("tool",xmRowColumnWidgetClass,form,NULL);

    /* main view */
    tt = XtVaCreateManagedWidget("tt", xmDrawingAreaWidgetClass,form, NULL);
    vw = vbi_render_init(shell,tt,vbi);
    XtVaSetValues(tt,XmNwidth,vw->w*41,XmNheight,vw->h*25,NULL);
    XtAddEventHandler(tt,KeyPressMask,
		      False,vbi_kbd_eh,vw);
    XtAddEventHandler(tt,ButtonPressMask|ButtonReleaseMask|Button1MotionMask,
		      False,vbi_mouse_eh,vw);
    XtAddCallback(tt,XmNexposeCallback,vbi_expose_cb,vw);
    XtAddCallback(tt,XmNdestroyCallback,vbi_destroy_cb,vw);
    XtAddCallback(tt,XmNconvertCallback,selection_convert_cb,vw);
    vbi_event_handler_register(vw->vbi->dec,~0,vbi_newdata,vw);

    /* menu -- file */
    menu = XmCreatePulldownMenu(menubar,"fileM",NULL,0);
    XtVaCreateManagedWidget("file",xmCascadeButtonWidgetClass,menubar,
			    XmNsubMenuId,menu,NULL);
    push = XtVaCreateManagedWidget("new",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_new_cb,vw);
    push = XtVaCreateManagedWidget("save",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,export_save_cb,vw);
    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,menu,NULL);
    push = XtVaCreateManagedWidget("quit",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_close_cb,vw);

    /* menu -- edit */
    menu = XmCreatePulldownMenu(menubar,"editM",NULL,0);
    XtVaCreateManagedWidget("edit",xmCascadeButtonWidgetClass,menubar,
			    XmNsubMenuId,menu,NULL);
    push = XtVaCreateManagedWidget("copy",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,selection_clip_cb,vw);

    /* menu -- go (navigation) */
    menu = XmCreatePulldownMenu(menubar,"goM",NULL,0);
    XtVaCreateManagedWidget("go",xmCascadeButtonWidgetClass,menubar,
			    XmNsubMenuId,menu,NULL);
    push = XtVaCreateManagedWidget("100",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_goto_cb,vw);
    push = XtVaCreateManagedWidget("prev",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_goto_cb,vw);
    push = XtVaCreateManagedWidget("next",xmPushButtonWidgetClass,menu,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_goto_cb,vw);

    /* menu -- subpage */
    vw->submenu = XmCreatePulldownMenu(menubar,"subpageM",NULL,0);
    vw->subbtn  = XtVaCreateManagedWidget("subpage",xmCascadeButtonWidgetClass,
					  menubar,
					  XmNsubMenuId,vw->submenu,NULL);

    /* menu -- stations */
    vbi_station_menu(menubar,vbi);

    /* menu -- fonts */
    menu = XmCreatePulldownMenu(menubar,"fontM",NULL,0);
    XtVaCreateManagedWidget("font",xmCascadeButtonWidgetClass,menubar,
			    XmNsubMenuId,menu,NULL);
    for (i = 0; vbi_fonts[i].label != NULL; i++) {
	push = XtVaCreateManagedWidget(vbi_fonts[i].label,
				       xmPushButtonWidgetClass,menu,NULL);
	XtAddCallback(push,XmNactivateCallback,vbi_font_cb,vw);
    }
    vbi_xft_font_menu(menu,vw);

    /* toolbar */
    push = XtVaCreateManagedWidget("100",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_goto_cb,vw);
    XtAddEventHandler(push,KeyPressMask,False,vbi_kbd_eh,vw);
    push = XtVaCreateManagedWidget("prev",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_goto_cb,vw);
    XtAddEventHandler(push,KeyPressMask,False,vbi_kbd_eh,vw);
    push = XtVaCreateManagedWidget("next",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_goto_cb,vw);
    XtAddEventHandler(push,KeyPressMask,False,vbi_kbd_eh,vw);
    XtVaCreateManagedWidget("sep",xmSeparatorWidgetClass,tool,NULL);
    push = XtVaCreateManagedWidget("exit",xmPushButtonWidgetClass,tool,NULL);
    XtAddCallback(push,XmNactivateCallback,vbi_close_cb,vw);
    XtAddEventHandler(push,KeyPressMask,False,vbi_kbd_eh,vw);

    /* shell stuff */
    XtAddEventHandler(shell, (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
    XmAddWMProtocolCallback(shell,WM_DELETE_WINDOW,vbi_close_cb,vw);

    /* set start page */
    vbi_setpage(vw,0x100,VBI_ANY_SUBNO);
    tt_windows++;
}
xawtv-3.106/x11/vbi-gui.h000066400000000000000000000000761343350355000150240ustar00rootroot00000000000000void vbi_create_widgets(Widget shell, struct vbi_state *vbi);
xawtv-3.106/x11/vbi-x11.c000066400000000000000000000154671343350355000146560ustar00rootroot00000000000000/*
 * vbi-x11  --  render videotext into X11 drawables
 *
 *   (c) 2002 Gerd Knorr 
 */

#include "config.h"

#ifdef HAVE_ZVBI

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 

#include "atoms.h"
#include "list.h"
#include "vbi-data.h"
#include "vbi-x11.h"

/* --------------------------------------------------------------------- */

struct vbi_font vbi_fonts[] = {
    {
	.label = "Teletext 20",
	.xlfd1 = "-*-teletext-medium-r-normal--20-*-*-*-*-*-iso10646-1",
	.xlfd2 = "-*-teletext-medium-r-normal--40-*-*-*-*-*-iso10646-1",
    },{
	.label = "Teletext 10",
	.xlfd1 = "-*-teletext-medium-r-normal--10-*-*-*-*-*-iso10646-1",
	.xlfd2 = "-*-teletext-medium-r-normal--20-*-*-*-*-*-iso10646-1",
    },{
	.label = "Fixed 18",
	.xlfd1 = "-*-fixed-medium-r-normal--18-*-*-*-*-*-iso10646-1",
    },{
	.label = "Fixed 13",
	.xlfd1 = "-misc-fixed-medium-r-semicondensed--13-*-*-*-*-*-iso10646-1",
    },{
	/* end of list */
    }
};

/* --------------------------------------------------------------------- */
/* render teletext pages                                                 */

static int vbi_render_try_font(Widget shell, struct vbi_window *vw,
				struct vbi_font *fnt)
{
    if (NULL == vw->xft_font  &&  NULL != fnt->xlfd1) {
	vw->font1 = XLoadQueryFont(XtDisplay(shell), fnt->xlfd1);
	if (NULL != fnt->xlfd2)
	    vw->font2 = XLoadQueryFont(XtDisplay(shell), fnt->xlfd2);
	if (NULL != vw->font1) {
	    vw->a      = vw->font1->max_bounds.ascent;
	    vw->d      = vw->font1->max_bounds.descent;
	    vw->w      = vw->font1->max_bounds.width;
	    vw->h      = vw->a + vw->d;
	    return 0;
	}
    }
    return 1;
}

void vbi_render_free_font(Widget shell, struct vbi_window *vw)
{
#ifdef HAVE_XFT
    if (NULL != vw->xft_font) {
	XftFontClose(XtDisplay(shell),vw->xft_font);
	vw->xft_font = NULL;
    }
#endif
    if (NULL != vw->font1) {
	XFreeFont(XtDisplay(shell),vw->font1);
	vw->font1 = NULL;
    }
    if (NULL != vw->font2) {
	XFreeFont(XtDisplay(shell),vw->font2);
	vw->font2 = NULL;
    }
}

void vbi_render_set_font(Widget shell, struct vbi_window *vw, char *label)
{
#ifdef HAVE_XFT
    FcPattern  *pattern;
    FcResult   rc;
#endif
    int        i;

    /* free old stuff */
    vbi_render_free_font(shell,vw);

    if (NULL != label) {
	/* try core font */
	for (i = 0; vbi_fonts[i].label != NULL; i++) {
	    if (0 != strcasecmp(label,vbi_fonts[i].label))
		continue;
	    if (0 == vbi_render_try_font(shell, vw, &vbi_fonts[i]))
		return;
	}

#ifdef HAVE_XFT
	/* try xft */
	pattern = FcNameParse(label);
	pattern = XftFontMatch(XtDisplay(shell),
			       XScreenNumberOfScreen(XtScreen(shell)),
			       pattern,&rc);
	vw->xft_font = XftFontOpenPattern(XtDisplay(shell), pattern);
	if (vw->xft_font) {
	    vw->a = vw->xft_font->ascent;
	    vw->d = vw->xft_font->descent;
	    vw->w = vw->xft_font->max_advance_width;
	    vw->h = vw->xft_font->height;
	    return;
	}
#endif
    }

    /* walk through the whole list as fallback */
    for (i = 0; vbi_fonts[i].label != NULL; i++) {
	if (0 == vbi_render_try_font(shell, vw, &vbi_fonts[i]))
	    return;
    }
    fprintf(stderr,"Oops: can't load any font\n");
    exit(1);
}

struct vbi_window*
vbi_render_init(Widget shell, Widget tt, struct vbi_state *vbi)
{
    struct vbi_window *vw;
    XColor color,dummy;
    int i;

    vw = malloc(sizeof(*vw));
    memset(vw,0,sizeof(*vw));

    vw->shell = shell;
    vw->tt    = tt;
    vw->vbi   = vbi;
    vw->gc    = XCreateGC(XtDisplay(shell),
			  RootWindowOfScreen(XtScreen(shell)),
			  0, NULL);

    XtVaGetValues(tt, XtNcolormap, &vw->cmap, NULL);
    for (i = 0; i < 8; i++) {
#ifdef HAVE_XFT
	XftColorAllocName(XtDisplay(shell),
			  DefaultVisualOfScreen(XtScreen(shell)),
			  vw->cmap, vbi_colors[i], &vw->xft_color[i]);
#endif
	XAllocNamedColor(XtDisplay(shell), vw->cmap, vbi_colors[i],
			 &color, &dummy);
	vw->colors[i] = color.pixel;
    }
    vbi_render_set_font(shell,vw,NULL);

    INIT_LIST_HEAD(&vw->selections);
    return vw;
}

void
vbi_render_line(struct vbi_window *vw, Drawable d, struct vbi_char *ch,
		int y, int top, int left, int right)
{
    XGCValues values;
    XChar2b line[42];
    int x1,x2,i,code,sy;
#ifdef HAVE_XFT
    FcChar32 wline[42];
    XftDraw *xft_draw = NULL;
#endif

    for (x1 = left; x1 < right; x1 = x2) {
	for (x2 = x1; x2 < right; x2++) {
	    if (ch[x1].foreground != ch[x2].foreground)
		break;
	    if (ch[x1].background != ch[x2].background)
		break;
	    if (ch[x1].size != ch[x2].size)
		break;
	}
	sy = 1;
	if (vw->font2) {
	    if (ch[x1].size == VBI_DOUBLE_HEIGHT ||
		ch[x1].size == VBI_DOUBLE_SIZE)
		sy = 2;
	    if (ch[x1].size == VBI_DOUBLE_HEIGHT2 ||
		ch[x1].size == VBI_DOUBLE_SIZE2)
		continue;
	}

	for (i = x1; i < x2; i++) {
	    code = ch[i].unicode;
	    if (ch[i].conceal)
		code = ' ';
	    if (ch[i].size == VBI_OVER_TOP       ||
		ch[i].size == VBI_OVER_BOTTOM    ||
		ch[i].size == VBI_DOUBLE_HEIGHT2 ||
		ch[i].size == VBI_DOUBLE_SIZE2)
		code = ' ';
	    line[i-x1].byte1 = (code >> 8) & 0xff;
	    line[i-x1].byte2 =  code       & 0xff;
#ifdef HAVE_XFT
	    wline[i-x1] = code;
#endif
	}

	values.function   = GXcopy;
	values.foreground = vw->colors[ch[x1].background & 7];
	XChangeGC(XtDisplay(vw->tt), vw->gc, GCForeground|GCFunction, &values);
	XFillRectangle(XtDisplay(vw->tt), d,
		       vw->gc, (x1-left)*vw->w, (y-top)*vw->h,
		       vw->w * (x2-x1), vw->h * sy);

	if (vw->xft_font) {
#ifdef HAVE_XFT
	    if (NULL == xft_draw)
		xft_draw = XftDrawCreate(XtDisplay(vw->tt), d,
					 DefaultVisualOfScreen(XtScreen(vw->tt)),
					 vw->cmap);
	    XftDrawString32(xft_draw, &vw->xft_color[ch[x1].foreground & 7],
			    vw->xft_font,
			    (x1-left)*vw->w, vw->a + (y-top+sy-1)*vw->h,
			    wline, x2-x1);
#endif
	} else {
	    values.foreground = vw->colors[ch[x1].foreground & 7];
	    values.font = (1 == sy) ? vw->font1->fid : vw->font2->fid;
	    XChangeGC(XtDisplay(vw->tt), vw->gc, GCForeground|GCFont, &values);
	    XDrawString16(XtDisplay(vw->tt), d, vw->gc,
			  (x1-left)*vw->w, vw->a + (y-top+sy-1)*vw->h,
			  line, x2-x1);
	}
    }
#ifdef HAVE_XFT
    if (NULL != xft_draw)
	XftDrawDestroy(xft_draw);
#endif
}

Pixmap
vbi_export_pixmap(struct vbi_window *vw,
		  struct vbi_page *pg, struct vbi_rect *rect)
{
    Pixmap pix;
    vbi_char *ch;
    int y;

    pix = XCreatePixmap(XtDisplay(vw->tt), XtWindow(vw->tt),
			vw->w * (rect->x2 - rect->x1),
			vw->h * (rect->y2 - rect->y1),
			DefaultDepthOfScreen(XtScreen(vw->tt)));
    for (y = rect->y1; y < rect->y2; y++) {
	ch = vw->pg.text + 41*y;
	vbi_render_line(vw,pix,ch,y,rect->y1,rect->x1,rect->x2);
    }
    return pix;
}

#endif /* HAVE_ZVBI */
xawtv-3.106/x11/vbi-x11.h000066400000000000000000000025611343350355000146520ustar00rootroot00000000000000#ifndef _VBI_X11_H
#define _VBI_X11_H 1

#ifdef HAVE_ZVBI

#ifdef HAVE_XFT
# define _XFT_NO_COMPAT_ 1
# include 
#endif

#include "list.h"

struct vbi_font {
    char *label;
    char *xlfd1;
    char *xlfd2;
};

struct vbi_window {
    Widget            shell,tt,subbtn,submenu;
    Widget            savebox;
    Colormap          cmap;
    GC                gc;
    XFontStruct       *font1,*font2;
    int               w,a,d,h;
    unsigned long     colors[8];

#ifdef HAVE_XFT
    XftFont           *xft_font;
    XftColor          xft_color[8];
#else
    void              *xft_font;
#endif

    struct vbi_state  *vbi;
    struct vbi_page   pg;
    int               pgno,subno;
    char              *charset;

    int               newpage;
    Time              down;
    struct vbi_rect   s;

    struct list_head  selections;
};

extern struct vbi_font vbi_fonts[];

struct vbi_window* vbi_render_init(Widget shell, Widget tt,
				   struct vbi_state *vbi);
void vbi_render_free_font(Widget shell, struct vbi_window *vw);
void vbi_render_set_font(Widget shell, struct vbi_window *vw, char *label);
void vbi_render_line(struct vbi_window *vw, Drawable d, struct vbi_char *ch,
		     int y, int top, int left, int right);
Pixmap vbi_export_pixmap(struct vbi_window *vw,
			 struct vbi_page *pg, struct vbi_rect *rect);

#endif /* HAVE_ZVBI */
#endif /* _VBI_X11_H */
xawtv-3.106/x11/wmhooks.c000066400000000000000000000102551343350355000151440ustar00rootroot00000000000000/*
 * Some WindowManager specific stuff
 *
 */

#include 
#include 
#include 
#include 

#include 
#include 

#include "wmhooks.h"
#include "atoms.h"

/* ------------------------------------------------------------------------ */

void (*wm_stay_on_top)(Display *dpy, Window win, int state) = NULL;
void (*wm_fullscreen)(Display *dpy, Window win, int state) = NULL;

/* ------------------------------------------------------------------------ */

extern int debug;

#define _NET_WM_STATE_REMOVE        0    /* remove/unset property */
#define _NET_WM_STATE_ADD           1    /* add/set property */

static void
netwm_set_state(Display *dpy, Window win, int operation, Atom state)
{
    XEvent e;

    memset(&e,0,sizeof(e));
    e.xclient.type = ClientMessage;
    e.xclient.message_type = _NET_WM_STATE;
    e.xclient.display = dpy;
    e.xclient.window = win;
    e.xclient.format = 32;
    e.xclient.data.l[0] = operation;
    e.xclient.data.l[1] = state;

    XSendEvent(dpy, DefaultRootWindow(dpy), False,
	       SubstructureRedirectMask, &e);
}

static void
netwm_stay_on_top(Display *dpy, Window win, int state)
{
    int op = state ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
    netwm_set_state(dpy,win,op,_NET_WM_STATE_ABOVE);
}

static void
netwm_old_stay_on_top(Display *dpy, Window win, int state)
{
    int op = state ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
    netwm_set_state(dpy,win,op,_NET_WM_STATE_STAYS_ON_TOP);
}

static void
netwm_fullscreen(Display *dpy, Window win, int state)
{
    int op = state ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
    netwm_set_state(dpy,win,op,_NET_WM_STATE_FULLSCREEN);
}

/* ------------------------------------------------------------------------ */

#define WIN_LAYER_NORMAL                 4
#define WIN_LAYER_ONTOP                  6

/* tested with icewm + WindowMaker */
static void
gnome_stay_on_top(Display *dpy, Window win, int state)
{
    XClientMessageEvent  xev;

    if (0 == win)
	return;

    memset(&xev, 0, sizeof(xev));
    xev.type = ClientMessage;
    xev.window = win;
    xev.message_type = _WIN_LAYER;
    xev.format = 32;
    xev.data.l[0] = state ? WIN_LAYER_ONTOP : WIN_LAYER_NORMAL;
    XSendEvent(dpy,DefaultRootWindow(dpy),False,
	       SubstructureNotifyMask,(XEvent*)&xev);
    if (state)
	XRaiseWindow(dpy,win);
}

/* ------------------------------------------------------------------------ */

static int
wm_check_capability(Display *dpy, Window root, Atom list, Atom wanted)
{
    Atom            type;
    int             format;
    unsigned int    i;
    unsigned long   nitems, bytesafter;
    unsigned char   *args;
    unsigned long   *ldata;
    char            *name;
    int             retval = -1;

    if (Success != XGetWindowProperty
	(dpy, root, list, 0, (65536 / sizeof(long)), False,
	 AnyPropertyType, &type, &format, &nitems, &bytesafter, &args))
	return -1;
    if (type != XA_ATOM)
	return -1;
    ldata = (unsigned long*)args;
    for (i = 0; i < nitems; i++) {
	if (ldata[i] == wanted)
	    retval = 0;
	if (debug > 1) {
	    name = XGetAtomName(dpy,ldata[i]);
	    fprintf(stderr,"wm cap: %s\n",name);
	    XFree(name);
	}
    }
    XFree(ldata);
    return retval;
}

void
wm_detect(Display *dpy)
{
    Window root = DefaultRootWindow(dpy);

    /* netwm checks */
    if (NULL == wm_stay_on_top &&
	0 == wm_check_capability(dpy,root,_NET_SUPPORTED,
				 _NET_WM_STATE_ABOVE)) {
	if (debug)
	    fprintf(stderr,"wmhooks: netwm state above\n");
	wm_stay_on_top = netwm_stay_on_top;
    }
    if (NULL == wm_stay_on_top &&
	0 == wm_check_capability(dpy,root,_NET_SUPPORTED,
				 _NET_WM_STATE_STAYS_ON_TOP)) {
	if (debug)
	    fprintf(stderr,"wmhooks: netwm state stays_on_top\n");
	wm_stay_on_top = netwm_old_stay_on_top;
    }
    if (NULL == wm_fullscreen &&
	0 == wm_check_capability(dpy,root,_NET_SUPPORTED,
				 _NET_WM_STATE_FULLSCREEN)) {
	if (debug)
	    fprintf(stderr,"wmhooks: netwm state fullscreen\n");
	wm_fullscreen = netwm_fullscreen;
    }

    /* gnome checks */
    if (NULL == wm_stay_on_top &&
	0 == wm_check_capability(dpy,root,_WIN_PROTOCOLS,_WIN_LAYER)) {
	if (debug)
	    fprintf(stderr,"wmhooks: gnome layer\n");
	wm_stay_on_top = gnome_stay_on_top;
    }
}
xawtv-3.106/x11/wmhooks.h000066400000000000000000000002271343350355000151470ustar00rootroot00000000000000void wm_detect(Display *dpy);
void (*wm_stay_on_top)(Display *dpy, Window win, int state);
void (*wm_fullscreen)(Display *dpy, Window win, int state);
xawtv-3.106/x11/x11.c000066400000000000000000000434741343350355000140770ustar00rootroot00000000000000/*
 * misc x11 functions:  pixmap handling (incl. MIT SHMEM), event
 *                      tracking for the TV widget.
 *
 *  (c) 1998 Gerd Knorr 
 *
 */

#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#ifdef HAVE_LIBXV
# include 
# include 
#endif

#include "grab-ng.h"
#include "capture.h"
#include "channel.h"
#include "x11.h"
#include "xv.h"
#include "commands.h"
#include "blit.h"

#define DEL_TIMER(proc)     XtRemoveTimeOut(proc)
#define ADD_TIMER(proc)     XtAppAddTimeOut(app_context,200,proc,NULL)

extern XtAppContext    app_context;
extern XVisualInfo     vinfo;

/* ------------------------------------------------------------------------ */

Pixmap
x11_capture_pixmap(Display *dpy, XVisualInfo *vinfo, Colormap colormap,
		   unsigned int width, unsigned int height)
{
    struct ng_video_buf *buf;
    struct ng_video_fmt fmt;
    Pixmap pix = 0;

    if (!(f_drv & CAN_CAPTURE))
	return 0;

    memset(&fmt,0,sizeof(fmt));
    fmt.fmtid  = x11_dpy_fmtid;
    fmt.width  = width  ? width  : cur_tv_width;
    fmt.height = height ? height : cur_tv_height;
    if (NULL == (buf = ng_grabber_get_image(&fmt)))
	return 0;
    buf = ng_filter_single(cur_filter,buf);
    pix = x11_create_pixmap(dpy,vinfo,buf);
    ng_release_video_buf(buf);
    return pix;
}

void
x11_label_pixmap(Display *dpy, Colormap colormap, Pixmap pixmap,
		 int height, char *label)
{
    static XFontStruct    *font;
    static XColor          color,dummy;
    XGCValues              values;
    GC                     gc;

    if (!font) {
	font = XLoadQueryFont(dpy,"fixed");
	XAllocNamedColor(dpy,colormap,"yellow",&color,&dummy);
    }
    values.font       = font->fid;
    values.foreground = color.pixel;
    gc = XCreateGC(dpy, pixmap, GCFont | GCForeground, &values);
    XDrawString(dpy,pixmap,gc,5,height-5,label,strlen(label));
    XFreeGC(dpy, gc);
}

static int
x11_error_dev_null(Display * dpy, XErrorEvent * event)
{
    return 0;
}

/* ------------------------------------------------------------------------ */
/* video grabdisplay stuff                                                  */

struct video_handle {
    Widget                win;
    Dimension             width,height;
    XtWorkProcId          work_id;
    int                   suspend;         /* temporarely disabled */
    int                   nw,nh;           /* new size (suspend)   */
    struct ng_video_fmt   best;
    struct blit_state     *blit;

    /* image filtering */
    struct ng_filter      *filter;
    void                  *fhandle;
    struct ng_video_fmt   ffmt;
};
struct video_handle vh;

void video_gd_init(Widget widget, int use_gl)
{
    struct video_handle *h = &vh;

    if (debug)
	fprintf(stderr,"gd: init\n");
    h->win  = widget;
    h->blit = blit_init(h->win,&vinfo, use_gl);
}

static struct ng_video_buf*
video_gd_filter(struct video_handle *h, struct ng_video_buf *buf)
{
    if (NULL != h->filter &&
	(cur_filter      != h->filter ||
	 buf->fmt.fmtid  != h->ffmt.fmtid ||
	 buf->fmt.width  != h->ffmt.width ||
	 buf->fmt.height != h->ffmt.height)) {
	h->filter->fini(h->fhandle);
	h->filter  = NULL;
	h->fhandle = NULL;
	memset(&h->ffmt,0,sizeof(h->ffmt));
    }
    if ((1 << buf->fmt.fmtid) & cur_filter->fmts) {
	if (NULL == h->filter) {
	    h->filter  = cur_filter;
	    h->fhandle = h->filter->init(&buf->fmt);
	    h->ffmt    = buf->fmt;
	}
	buf = cur_filter->frame(h->fhandle,buf);
    }
    return buf;
}

int
video_gd_blitframe(struct video_handle *h, struct ng_video_buf *buf)
{
    if (buf->fmt.width  > cur_tv_width ||
	buf->fmt.height > cur_tv_height) {
	ng_release_video_buf(buf);
	return -1;
    }

    if (cur_filter)
	buf = video_gd_filter(h,buf);
    blit_putframe(h->blit,buf);
    return 0;
}

static Boolean
video_gd_idle(XtPointer data)
{
    struct video_handle *h = data;
    struct ng_video_buf *buf;

    if (!(f_drv & CAN_CAPTURE))
	goto oops;

    buf = ng_grabber_grab_image(0);
    if (NULL != buf) {
	video_gd_blitframe(h,buf);
    } else {
	goto oops;
    }

    if (debug) {
	static long count,lastsec;
	struct timeval  t;
	struct timezone tz;
	gettimeofday(&t,&tz);
	if (t.tv_sec != lastsec) {
	    if (lastsec == t.tv_sec-1)
		fprintf(stderr,"%5ld fps \r", count);
	    lastsec = t.tv_sec;
	    count = 0;
	}
	count++;
    }
    return FALSE;

 oops:
    h->work_id = 0;
    if (f_drv & CAN_CAPTURE)
	drv->stopvideo(h_drv);
    return TRUE;
}

void
video_gd_start(void)
{
    struct video_handle *h = &vh;

    if (debug)
	fprintf(stderr,"gd: start [%d]\n",h->best.fmtid);
    if (0 == h->best.fmtid)
	return;
    if (0 != ng_grabber_setformat(&h->best,0))
	return;
    drv->startvideo(h_drv,-1,2);
//    drv->startvideo(h_drv,-1,4);
    h->work_id = XtAppAddWorkProc(app_context, video_gd_idle, h);
}

void
video_gd_stop(void)
{
    struct video_handle *h = &vh;

    if (debug)
	fprintf(stderr,"gd: stop\n");
    if (h->work_id) {
	drv->stopvideo(h_drv);
	XtRemoveWorkProc(h->work_id);
	h->work_id = 0;
	blit_fini_frame(h->blit);
    }
}

void
video_gd_suspend(void)
{
    struct video_handle *h = &vh;

    h->suspend = 1;
    if (cur_capture != CAPTURE_GRABDISPLAY)
	return;
    do_va_cmd(3, "capture", "off", "temp");
}

void
video_gd_restart(void)
{
    struct video_handle *h = &vh;

    if (!h->suspend)
	return;
    h->suspend = 0;
    if (h->nw && h->nh) {
	video_gd_configure(h->nw,h->nh);
	h->nw = 0;
	h->nh = 0;
    }
    if (cur_capture != CAPTURE_OFF)
	return;
    do_va_cmd(3, "capture", "grab", "temp");
}

void
video_gd_configure(int width, int height)
{
    struct video_handle *h = &vh;
    unsigned int i,fmtids[2*VIDEO_FMT_COUNT];

    if (!(f_drv & CAN_CAPTURE))
	return;

    blit_resize(h->blit,width,height);

    if (h->suspend) {
	if (debug)
	    fprintf(stderr,"gd: delay configure\n");
	h->nw = width;
	h->nh = height;
	return;
    }

    if (debug)
	fprintf(stderr,"gd: config %dx%d win=%lx\n",
		width,height,XtWindow(h->win));

    if (!XtWindow(h->win))
	return;

    cur_tv_width  = width;
    cur_tv_height = height;
    h->best.width   = width;
    h->best.height  = height;
    h->best.bytesperline = 0;
    ng_ratio_fixup(&cur_tv_width,  &cur_tv_height,  NULL, NULL);
    ng_ratio_fixup(&h->best.width, &h->best.height, NULL, NULL);

    if (0 == h->best.fmtid) {
	blit_get_formats(h->blit,fmtids,sizeof(fmtids)/sizeof(int));
	for (i = 0; i < sizeof(fmtids)/sizeof(int); i++) {
	    h->best.fmtid = fmtids[i];
	    if (0 == ng_grabber_setformat(&h->best,0))
		goto done;
	}
	/* failed */
	h->best.fmtid = 0;
    }

 done:
    if (debug)
	fprintf(stderr,"grabdisplay: using \"%s\"\n",
		ng_vfmt_to_desc[h->best.fmtid]);
    if (cur_capture == CAPTURE_GRABDISPLAY) {
	do_va_cmd(2, "capture", "off");
	do_va_cmd(2, "capture", "grab");
    }
}

/* ------------------------------------------------------------------------ */
/* video overlay stuff                                                      */

unsigned int     swidth,sheight;           /* screen  */
static int       x11_overlay_fmtid;

/* window  */
static Widget    video,video_parent;
static int       wx, wy, wmap;
static struct ng_video_fmt wfmt;

static XtIntervalId          overlay_refresh;
static int                   did_refresh, oc_count;
static int                   visibility = VisibilityFullyObscured;
static int                   conf = 1, move = 1;
static int                   overlay_on = 0, overlay_enabled = 0;
static struct OVERLAY_CLIP   oc[256];
static XtWorkProcId          conf_id;

/* ------------------------------------------------------------------------ */

char *event_names[] = {
    "0", "1",
    "KeyPress",
    "KeyRelease",
    "ButtonPress",
    "ButtonRelease",
    "MotionNotify",
    "EnterNotify",
    "LeaveNotify",
    "FocusIn",
    "FocusOut",
    "KeymapNotify",
    "Expose",
    "GraphicsExpose",
    "NoExpose",
    "VisibilityNotify",
    "CreateNotify",
    "DestroyNotify",
    "UnmapNotify",
    "MapNotify",
    "MapRequest",
    "ReparentNotify",
    "ConfigureNotify",
    "ConfigureRequest",
    "GravityNotify",
    "ResizeRequest",
    "CirculateNotify",
    "CirculateRequest",
    "PropertyNotify",
    "SelectionClear",
    "SelectionRequest",
    "SelectionNotify",
    "ColormapNotify",
    "ClientMessage",
    "MappingNotify"
};
const int nevent_names = sizeof(event_names)/sizeof(event_names[0]);

/* ------------------------------------------------------------------------ */

static void
add_clip(int x1, int y1, int x2, int y2)
{
    if (oc[oc_count].x1 != x1 || oc[oc_count].y1 != y1 ||
	oc[oc_count].x2 != x2 || oc[oc_count].y2 != y2) {
	conf = 1;
    }
    oc[oc_count].x1 = x1;
    oc[oc_count].y1 = y1;
    oc[oc_count].x2 = x2;
    oc[oc_count].y2 = y2;
    oc_count++;
}

static void
get_clips(void)
{
    int x1,y1,x2,y2,lastcount;
    Display *dpy;
    XWindowAttributes wts;
    Window root, me, rroot, parent, *children;
    uint nchildren, i;
    void *old_handler = XSetErrorHandler(x11_error_dev_null);

    if (debug > 1)
	fprintf(stderr," getclips");
    lastcount = oc_count;
    oc_count = 0;
    dpy = XtDisplay(video);

    if (wx<0)
	add_clip(0, 0, (uint)(-wx), wfmt.height);
    if (wy<0)
	add_clip(0, 0, wfmt.width, (uint)(-wy));
    if ((wx+wfmt.width) > swidth)
	add_clip(swidth-wx, 0, wfmt.width, wfmt.height);
    if ((wy+wfmt.height) > sheight)
	add_clip(0, sheight-wy, wfmt.width, wfmt.height);

    root=DefaultRootWindow(dpy);
    me = XtWindow(video);
    for (;;) {
	XQueryTree(dpy, me, &rroot, &parent, &children, &nchildren);
	XFree((char *) children);
	/* fprintf(stderr,"me=0x%x, parent=0x%x\n",me,parent); */
	if (root == parent)
	    break;
	me = parent;
    }
    XQueryTree(dpy, root, &rroot, &parent, &children, &nchildren);

    for (i = 0; i < nchildren; i++)
	if (children[i]==me)
	    break;

    for (i++; i (int)wfmt.width) ||
	    (y2 < 0) || (y1 > (int)wfmt.height))
	    continue;

	if (x1<0)      		 x1=0;
	if (y1<0)                y1=0;
	if (x2>(int)wfmt.width)  x2=wfmt.width;
	if (y2>(int)wfmt.height) y2=wfmt.height;
	add_clip(x1, y1, x2, y2);
    }
    XFree((char *) children);

    if (lastcount != oc_count)
	conf = 1;
    XSetErrorHandler(old_handler);
}

static void
refresh_timer(XtPointer clientData, XtIntervalId *id)
{
    Window   win = RootWindowOfScreen(XtScreen(video));
    Display *dpy = XtDisplay(video);
    XSetWindowAttributes xswa;
    unsigned long mask;
    Window   tmp;

    if (!move && wmap && visibility == VisibilityUnobscured) {
	if (debug > 1)
	    fprintf(stderr,"video: refresh skipped\n");
	return;
    }

    if (debug > 1)
	fprintf(stderr,"video: refresh\n");
    overlay_refresh = 0;
    if (wmap && visibility != VisibilityFullyObscured)
	did_refresh = 1;

    xswa.override_redirect = True;
    xswa.backing_store = NotUseful;
    xswa.save_under = False;
    mask = (CWSaveUnder | CWBackingStore| CWOverrideRedirect );
    tmp = XCreateWindow(dpy,win, 0,0, swidth,sheight, 0,
			CopyFromParent, InputOutput, CopyFromParent,
			mask, &xswa);
    XMapWindow(dpy, tmp);
    XUnmapWindow(dpy, tmp);
    XDestroyWindow(dpy, tmp);
    move = 0;
}

static Boolean
configure_delayed(XtPointer data)
{
    if (debug > 1)
	fprintf(stderr,"video: configure delayed");
    if (wmap && visibility != VisibilityFullyObscured) {
	if (visibility == VisibilityPartiallyObscured)
	    get_clips();
	else
	    oc_count = 0;

	if (debug > 1)
	    fprintf(stderr," %s\n",conf ? "yes" : "no");
	if (conf) {
	    overlay_on = 1;
	    if (f_drv & CAN_OVERLAY)
		drv->overlay(h_drv,&wfmt,wx,wy,oc,oc_count,1);
	    if (overlay_refresh)
		DEL_TIMER(overlay_refresh);
	    overlay_refresh = ADD_TIMER(refresh_timer);
	    conf = 0;
	}
    } else {
	if (debug > 1)
	    fprintf(stderr," off\n");
	if (conf && overlay_on) {
	    overlay_on = 0;
	    if (f_drv & CAN_OVERLAY)
		drv->overlay(h_drv,NULL,0,0,NULL,0,0);
	    if (overlay_refresh)
		DEL_TIMER(overlay_refresh);
	    overlay_refresh = ADD_TIMER(refresh_timer);
	    conf = 0;
	}
    }
    conf_id = 0;
    return TRUE;
}

static void
configure_overlay(void)
{
    if (!overlay_enabled)
	return;

#ifdef HAVE_LIBXV
    if (have_xv) {
	if (wfmt.width && wfmt.height)
	    xv_video(XtWindow(video),wfmt.width,wfmt.height,1);
	return;
    }
#endif

    if (0 == conf_id)
	conf_id = XtAppAddWorkProc(app_context,configure_delayed,NULL);
}

void
video_new_size()
{
    Dimension x,y,w,h;

    XtVaGetValues(video_parent, XtNx, &x, XtNy, &y,
		  XtNwidth, &w, XtNheight, &h, NULL);
    wx          = x; if (wx > 32768)          wx          -= 65536;
    wy          = y; if (wy > 32768)          wy          -= 65536;
    wfmt.width  = w; if (wfmt.width > 32768)  wfmt.width  -= 65536;
    wfmt.height = h; if (wfmt.height > 32768) wfmt.height -= 65536;
    wfmt.fmtid  = x11_overlay_fmtid;
    if (debug > 1)
	fprintf(stderr,"video: shell: size %dx%d+%d+%d\n",
		wfmt.width,wfmt.height,wx,wy);

    conf = 1;
    move = 1;
    configure_overlay();
}

/* ------------------------------------------------------------------------ */

static void
video_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d)
{
    if (widget == video_parent) {
	/* shell widget */
	switch(event->type) {
	case ConfigureNotify:
#if 0
	    wx      = event->xconfigure.x;
	    wy      = event->xconfigure.y;
	    wwidth  = event->xconfigure.width;
	    wheight = event->xconfigure.height;
	    if (debug > 1)
		fprintf(stderr,"video: shell: cfg %dx%d+%d+%d\n",
			wwidth,wheight,wx,wy);
#endif
	    video_new_size();
	    break;
	case MapNotify:
	    if (debug > 1)
		fprintf(stderr,"video: shell: map\n");
	    wmap = 1;
	    conf = 1;
	    configure_overlay();
	    break;
	case UnmapNotify:
	    if (debug > 1)
		fprintf(stderr,"video: shell: unmap\n");
	    wmap = 0;
	    conf = 1;
	    configure_overlay();
	    break;
	default:
	    if (debug > 1)
		fprintf(stderr,"video: shell: %s\n",
			event_names[event->type]);
	}
	return;

    } else {
	/* TV widget (+root window) */
	switch(event->type) {
	case Expose:
	    if (event->xvisibility.window == XtWindow(video)) {
		/* tv */
		if (!event->xexpose.count) {
		    if (did_refresh) {
			did_refresh = 0;
			if (debug > 1)
			    fprintf(stderr,"video: tv: last refresh expose\n");
		    } else {
			if (debug > 1)
			    fprintf(stderr,"video: tv: expose\n");
			conf = 1;
			configure_overlay();
		    }
		}
	    }
	    break;
	case VisibilityNotify:
	    if (event->xvisibility.window == XtWindow(video)) {
		/* tv */
		visibility = event->xvisibility.state;
		if (debug > 1)
		    fprintf(stderr,"video: tv: visibility %d%s\n",
			    event->xvisibility.state,
			    did_refresh?" (ignored)":"");
		if (did_refresh) {
		    if (event->xvisibility.state != VisibilityFullyObscured)
			did_refresh = 0;
		} else {
		    conf = 1;
		    configure_overlay();
		}
	    } else {
		/* root */
		if (debug > 1)
		    fprintf(stderr,"video: root: visibility\n");
	    }
	    break;
	case MapNotify:
	case UnmapNotify:
	case ConfigureNotify:
	    if (event->xvisibility.window != XtWindow(video)) {
		if (debug > 1)
		    fprintf(stderr,"video: root: %s%s\n",
			    event_names[event->type],did_refresh?" (ignored)":"");
		if (!did_refresh)
		    configure_overlay();
	    }
	    break;
	default:
	    if (debug > 1)
		fprintf(stderr,"video: tv(+root): %s\n",
			event_names[event->type]);
	    break;
	}
    }
}

void
video_overlay(int state)
{
    if (state) {
	conf = 1;
	overlay_enabled = 1;
	configure_overlay();
    } else {
	if (1 == overlay_enabled) {
#ifdef HAVE_LIBXV
	    if (have_xv) {
		xv_video(XtWindow(video),0,0,0);
	    } else
#endif
	    {
		overlay_on = 0;
		if (f_drv & CAN_OVERLAY)
		    drv->overlay(h_drv,NULL,0,0,NULL,0,0);
		overlay_refresh = ADD_TIMER(refresh_timer);
	    }
	}
	overlay_enabled = 0;
    }
}

Widget
video_init(Widget parent, XVisualInfo *vinfo, WidgetClass class,
	   int args_bpp, int args_gl)
{
    Window root = DefaultRootWindow(XtDisplay(parent));

    swidth  = XtScreen(parent)->width;
    sheight = XtScreen(parent)->height;

    x11_overlay_fmtid = x11_dpy_fmtid;
    if (ImageByteOrder(XtDisplay(parent)) == MSBFirst) {
	/* X-Server is BE */
	switch(args_bpp) {
	case  8: x11_overlay_fmtid = VIDEO_RGB08;    break;
	case 15: x11_overlay_fmtid = VIDEO_RGB15_BE; break;
	case 16: x11_overlay_fmtid = VIDEO_RGB16_BE; break;
	case 24: x11_overlay_fmtid = VIDEO_BGR24;    break;
	case 32: x11_overlay_fmtid = VIDEO_BGR32;    break;
	}
    } else {
	/* X-Server is LE */
	switch(args_bpp) {
	case  8: x11_overlay_fmtid = VIDEO_RGB08;    break;
	case 15: x11_overlay_fmtid = VIDEO_RGB15_LE; break;
	case 16: x11_overlay_fmtid = VIDEO_RGB16_LE; break;
	case 24: x11_overlay_fmtid = VIDEO_BGR24;    break;
	case 32: x11_overlay_fmtid = VIDEO_BGR32;    break;
	}
    }

    video_parent = parent;
    video = XtVaCreateManagedWidget("tv",class,parent,NULL);

    /* Shell widget -- need map, unmap, configure */
    XtAddEventHandler(parent,
		      StructureNotifyMask,
		      True, video_event, NULL);

    if (!have_xv) {
	/* TV Widget -- need visibility, expose */
	XtAddEventHandler(video,
			  VisibilityChangeMask |
			  StructureNotifyMask,
			  False, video_event, NULL);

	/* root window -- need */
	XSelectInput(XtDisplay(video),root,
		     VisibilityChangeMask |
		     SubstructureNotifyMask |
		     StructureNotifyMask);

	XtRegisterDrawable(XtDisplay(video),root,video);
    }

    return video;
}

void
video_close(void)
{
    Window root = DefaultRootWindow(XtDisplay(video));

    if (overlay_refresh)
	DEL_TIMER(overlay_refresh);
    XSelectInput(XtDisplay(video),root,0);
    XtUnregisterDrawable(XtDisplay(video),root);
}
xawtv-3.106/x11/x11.h000066400000000000000000000015201343350355000140660ustar00rootroot00000000000000extern unsigned int  swidth,sheight;
extern char *event_names[];
extern const int nevent_names;

void x11_label_pixmap(Display *dpy, Colormap colormap, Pixmap pixmap,
		      int height, char *label);
Pixmap x11_capture_pixmap(Display *dpy, XVisualInfo *vinfo, Colormap colormap,
			  unsigned int width, unsigned int height);

struct video_handle;
extern struct video_handle vh;
int video_gd_blitframe(struct video_handle *h, struct ng_video_buf *buf);
void video_gd_init(Widget widget, int use_gl);
void video_gd_start(void);
void video_gd_stop(void);
void video_gd_suspend(void);
void video_gd_restart(void);
void video_gd_configure(int width, int height);

void video_new_size(void);
void video_overlay(int state);

Widget video_init(Widget parent, XVisualInfo *vinfo,
		  WidgetClass class, int args_bpp, int args_gl);
void video_close(void);
xawtv-3.106/x11/xawtv-remote.c000066400000000000000000000075631343350355000161270ustar00rootroot00000000000000
/* shameless stolen from netscape :-) */

#include 
#include 
#include 
#include 

#include 
#include 
#include     /* for XmuClientWindow() */

unsigned int debug=0;

static int
x11_error_dev_null(Display * dpy, XErrorEvent * event)
{
    fprintf(stderr,"x11-error\n");
    return 0;
}

static Window
find_window(Display * dpy, Atom atom)
{
    int             n;
    unsigned int    i;
    Window          root = RootWindowOfScreen(DefaultScreenOfDisplay(dpy));
    Window          root2, parent, *kids;
    unsigned int    nkids;
    Window          result = 0;

    if (!XQueryTree(dpy, root, &root2, &parent, &kids, &nkids)) {
	fprintf(stderr, "XQueryTree failed on display %s\n",
		DisplayString(dpy));
	exit(2);
    }

    if (!(kids && nkids)) {
	fprintf(stderr, "root window has no children on display %s\n",
		DisplayString(dpy));
	exit(2);
    }
    for (n = nkids - 1; n >= 0; n--) {
	Atom            type;
	int             format;
	unsigned long   nitems, bytesafter;
	unsigned char  *args = NULL;

	Window          w = XmuClientWindow(dpy, kids[n]);

	XGetWindowProperty(dpy, w, atom,
			   0, (65536 / sizeof(long)),
			   False, XA_STRING,
			   &type, &format, &nitems, &bytesafter,
			   &args);

	if (!args)
	    continue;
	if (debug) {
	    printf("query 0x%08lx: ",w);
	    for (i = 0; i < nitems; i += strlen(args + i) + 1)
		printf("%s ", args + i);
	    printf("\n");
	}
	XFree(args);

	result = w;
#if 0 /* there might be more than window */
	break;
#endif
    }
    return result;
}

static void
pass_cmd(Display *dpy, Atom atom, Window win, int argc, char **argv)
{
    int             i, len;
    char           *pass;

    if (debug)
	printf("ctrl  0x%08lx: ",win);
    for (len = 0, i = 0; i < argc; i++) {
	if (debug)
	    printf("%s ",argv[i]);
	len += strlen(argv[i]) + 1;
    }
    if (debug)
	printf("\n");
    pass = malloc(len);
    pass[0] = 0;
    for (len = 0, i = 0; i < argc; i++)
	strcpy(pass + len, argv[i]),
	    len += strlen(argv[i]) + 1;
    XChangeProperty(dpy, win,
		    atom, XA_STRING,
		    8, PropModeReplace,
		    pass, len);
    free(pass);
}

static void
usage(char *argv0)
{
    char *prog;

    if (NULL != (prog = strrchr(argv0,'/')))
	prog++;
    else
	prog = argv0;

    fprintf(stderr,
"This is a \"remote control\" for xawtv\n"
"usage: %s [ options ] [ command ]\n"
"\n"
"available options:\n"
"    -d display\n"
"        set X11 display\n"
"    -i window ID\n"
"        select xawtv window\n"
"    -v n\n"
"        Set debug level to n, default 0."
"\n"
"available commands (most frequently used ones):\n"
"    setstation  |  | next | prev\n"
"    setchannel  | next | prev\n"
"    capture on | off\n"
"    volume mute | dec | inc | \n"
"    snap [  [  [  ]]]\n"
"\n"
"Check the man-page for a full list and detailed descriptions.\n"
"\n"
	    ,prog);
}

int
main(int argc, char *argv[])
{
    Display  *dpy;
    char     *dpyname = NULL;
    Window   win,id = 0;
    Atom     station,remote;
    int      c;

    for (;;) {
	c = getopt(argc, argv, "hd:i:v:");
	if (c == -1)
	    break;
	switch (c) {
	case 'd':
	    dpyname = optarg;
	    break;
	case 'i':
	    sscanf(optarg,"%li",&id);
	    break;
	case 'v':
	    debug = atoi(optarg);
	    break;
	case 'h':
	default:
	    usage(argv[0]);
	    exit(1);
	}
    }

    if (NULL == (dpy = XOpenDisplay(dpyname))) {
	fprintf(stderr,"can't open display %s\n", dpyname?dpyname:"");
	exit(1);
    }
    XSetErrorHandler(x11_error_dev_null);
    station = XInternAtom(dpy, "_XAWTV_STATION", False);
    remote =  XInternAtom(dpy, "_XAWTV_REMOTE",  False);

    if (0 == (win = find_window(dpy,station)) &&
	0 == id) {
	fprintf(stderr,"xawtv not running\n");
	exit(2);
    }
    if (argc > optind)
	pass_cmd(dpy, remote, (id != 0) ? id : win, argc-optind, argv+optind);

    XCloseDisplay(dpy);
    return 0;
}
xawtv-3.106/x11/xawtv.c000066400000000000000000001433131343350355000146300ustar00rootroot00000000000000/*
 * main.c for xawtv -- a TV application
 *
 *   (c) 1997-2002 Gerd Knorr 
 *
 */

#define _GNU_SOURCE

#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "grab-ng.h"
#include "writefile.h"

#include "sound.h"
#include "channel.h"
#include "commands.h"
#include "frequencies.h"
#include "xv.h"
#include "capture.h"
#include "atoms.h"
#include "xt.h"
#include "x11.h"
#include "toolbox.h"
#include "complete.h"
#include "wmhooks.h"
#include "conf.h"
#include "blit.h"
#include "vbi-data.h"
#include "vbi-x11.h"

#define LABEL_WIDTH         "16"
#define BOOL_WIDTH          "24"

/*--- public variables ----------------------------------------------------*/

static String fallback_ressources[] = {
#include "Xawtv.h"
    NULL
};

Widget            opt_shell, opt_paned, chan_shell, conf_shell, str_shell;
Widget            launch_shell, launch_paned;
Widget            c_freq,c_cap;
Widget            s_bright,s_color,s_hue,s_contrast,s_volume;
Widget            chan_viewport, chan_box;
Pixmap            tv_pix;
struct vbi_window *vtx;

int               have_config = 0;
XtIntervalId      audio_timer;
XtIntervalId      unmute_timer;
int               unmute_pending = 0;
int               debug = 0;
int               window_configured = 0;

char              modename[64];
char              *progname;

XtWorkProcId      rec_work_id;

/* movie params / setup */
Widget            w_movie_status;
Widget            w_movie_driver;

Widget            w_movie_fvideo;
Widget            w_movie_video;
Widget            w_movie_fps;
Widget            w_movie_size;

Widget            w_movie_flabel;
Widget            w_movie_faudio;
Widget            w_movie_audio;
Widget            w_movie_rate;

struct STRTAB     *m_movie_driver;
struct STRTAB     *m_movie_audio;
struct STRTAB     *m_movie_video;

struct ng_writer  *movie_driver  = NULL;
unsigned int      i_movie_driver = 0;
unsigned int      movie_audio    = 0;
unsigned int      movie_video    = 0;
unsigned int      movie_fps      = 12000;
unsigned int      movie_rate     = 44100;

static struct STRTAB m_movie_fps[] = {
    {  2000, " 2.0   fps" },
    {  3000, " 3.0   fps" },
    {  5000, " 5.0   fps" },
    {  8000, " 8.0   fps" },
    { 10000, "10.0   fps" },
    { 12000, "12.0   fps" },
    { 15000, "15.0   fps" },
    { 18000, "18.0   fps" },
    { 20000, "20.0   fps" },
    { 23976, "23.976 fps" },
    { 24000, "24.0   fps" },
    { 25000, "25.0   fps" },
    { 29970, "29.970 fps" },
    { 30000, "30.0   fps" },
    { -1, NULL },
};
static struct STRTAB m_movie_rate[] = {
    {   8000, " 8000" },
    {  11025, "11025" },
    {  22050, "22050" },
    {  44100, "44100" },
    {  48000, "48000" },
    { -1, NULL },
};

struct xaw_attribute {
    struct ng_attribute   *attr;
    Widget                cmd,scroll;
    struct xaw_attribute  *next;
};
static struct xaw_attribute *xaw_attrs;

#define MOVIE_DRIVER  "movie driver"
#define MOVIE_AUDIO   "audio format"
#define MOVIE_VIDEO   "video format"
#define MOVIE_FPS     "frames/sec"
#define MOVIE_RATE    "sample rate"
#define MOVIE_SIZE    "video size"

/* fwd decl */
void change_audio(int mode);
void watch_audio(XtPointer data, XtIntervalId *id);
void unmute_audio(XtPointer data, XtIntervalId *id);

/*-------------------------------------------------------------------------*/

static struct MY_TOPLEVELS {
    char        *name;
    Widget      *shell;
    int         require_tune;
    int         *check;
    int          first;
    int          mapped;
} my_toplevels [] = {
    { "options",  &opt_shell,    0,          },
    { "channels", &chan_shell,   1, &count   },
    { "config",   &conf_shell,   1,          },
    { "streamer", &str_shell,    0,          },
    { "launcher", &launch_shell, 0, &nlaunch }
};
#define TOPLEVELS (sizeof(my_toplevels)/sizeof(struct MY_TOPLEVELS))

struct STRTAB *cmenu = NULL;

struct DO_AC {
    int  argc;
    char *name;
    char *argv[8];
};

/*--- actions -------------------------------------------------------------*/

/* conf.c */
extern void create_confwin(void);
extern void conf_station_switched(void);
extern void conf_list_update(void);

void CloseMainAction(Widget, XEvent*, String*, Cardinal*);
void ScanAction(Widget, XEvent*, String*, Cardinal*);
void ChannelAction(Widget, XEvent*, String*, Cardinal*);
void StayOnTop(Widget, XEvent*, String*, Cardinal*);
void PopupAction(Widget, XEvent*, String*, Cardinal*);
void MuteAction(Widget, XEvent*, String*, Cardinal*);

static XtActionsRec actionTable[] = {
    { "CloseMain",   CloseMainAction  },
    { "Scan",        ScanAction },
    { "Channel",     ChannelAction },
    { "Remote",      RemoteAction },
    { "Zap",         ZapAction },
    { "Complete",    CompleteAction },
    { "Help",        help_AC },
    { "StayOnTop",   StayOnTop },
    { "Launch",      LaunchAction },
    { "Popup",       PopupAction },
    { "Command",     CommandAction },
    { "Autoscroll",  offscreen_scroll_AC },
    { "Ratio",       RatioAction },
#ifdef HAVE_ZVBI
    { "Vtx",         VtxAction },
#endif
    { "Event",       EventAction },
    { "Mute",        MuteAction },
};

static struct STRTAB cap_list[] = {
    {  CAPTURE_OFF,         "off"         },
    {  CAPTURE_OVERLAY,     "overlay"     },
    {  CAPTURE_GRABDISPLAY, "grabdisplay" },
    {  -1, NULL,     },
};

/*--- exit ----------------------------------------------------------------*/

void
PopupAction(Widget widget, XEvent *event,
	    String *params, Cardinal *num_params)
{
    Dimension h;
    unsigned int i;
    int mh;
    if (debug)
	fprintf(stderr,"PopupAction: %s\n",
	        (*num_params > 0) ? params[0] : "-");
    /* which window we are talking about ? */
    if (*num_params > 0) {
	for (i = 0; i < TOPLEVELS; i++) {
	    if (0 == strcasecmp(my_toplevels[i].name,params[0]))
		break;
	}
    } else {
	for (i = 0; i < TOPLEVELS; i++) {
	    if (*(my_toplevels[i].shell) == widget)
		break;
	}
    }
    if (i == TOPLEVELS) {
	fprintf(stderr,"PopupAction: oops: shell widget not found (%s)\n",
		(*num_params > 0) ? params[0] : "-");
	return;
    }

    if (!(f_drv & CAN_TUNE) && my_toplevels[i].require_tune)
	return;


    /* Message from WM ??? */
    if (NULL != event && event->type == ClientMessage) {
	if (debug)
	    fprintf(stderr,"%s: received %s message\n",
		    my_toplevels[i].name,
		    XGetAtomName(dpy,event->xclient.data.l[0]));
	if ((Atom)event->xclient.data.l[0] == WM_DELETE_WINDOW) {
	    /* fall throuth -- popdown window */
	} else {
	    /* whats this ?? */
	    return;
	}
    }

    /* check if window should be displayed */
    if (NULL != my_toplevels[i].check)
	if (0 == *(my_toplevels[i].check))
	    return;

    /* popup/down window */
    if (my_toplevels[i].mapped) {
	XtPopdown(*(my_toplevels[i].shell));
	my_toplevels[i].mapped = 0;
    } else {
	XtPopup(*(my_toplevels[i].shell), XtGrabNone);
	if (wm_stay_on_top && stay_on_top > 0)
	    wm_stay_on_top(dpy,XtWindow(*(my_toplevels[i].shell)),1);
	my_toplevels[i].mapped = 1;
	if (!my_toplevels[i].first) {
	    XSetWMProtocols(XtDisplay(*(my_toplevels[i].shell)),
			    XtWindow(*(my_toplevels[i].shell)),
			    &WM_DELETE_WINDOW, 1);
	    mh = h = 0;
	    XtVaGetValues(*(my_toplevels[i].shell),
			  XtNmaxHeight,&mh,
			  XtNheight,&h,
			  NULL);
	    if (mh > 0 && h > mh) {
		if (debug)
		    fprintf(stderr,"height fixup: %d => %d\n",h,mh);
		XtVaSetValues(*(my_toplevels[i].shell),XtNheight,mh,NULL);
	    }
	    my_toplevels[i].first = 1;
	}
    }
}

void MuteAction(Widget w, XEvent *e, String *s, Cardinal *c)
{
    /*
     * If we're muted because we're changing channels, stay muted. We still do
     * a "volume mute on" command to show the muted msg in the title bar.
     */
    if (unmute_pending) {
        do_va_cmd(3, "volume", "mute", "on");
        unmute_pending = 0;
        return;
    }

    do_va_cmd(2, "volume", "mute"); /* Toggle mute */
}

static void
action_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct DO_AC *ca = clientdata;
    XtCallActionProc(widget,ca->name,NULL,ca->argv,ca->argc);
}

void toolkit_set_label(Widget widget, char *str)
{
    XtVaSetValues(widget,XtNlabel,str,NULL);
}

/*--- videotext ----------------------------------------------------------*/

static void create_vtx(void)
{
    Widget shell,label;

    shell = XtVaCreateWidget("vtx",transientShellWidgetClass,
			     app_shell,
			     XtNoverrideRedirect,True,
			     XtNvisual,vinfo.visual,
			     XtNcolormap,colormap,
			     XtNdepth,vinfo.depth,
			     NULL);
    label = XtVaCreateManagedWidget("label", labelWidgetClass, shell,
				    NULL);
#ifdef HAVE_ZVBI
    vtx = vbi_render_init(shell,label,NULL);
#endif
}

#if TT
static void
display_vtx(struct TEXTELEM *tt)
{
    static Pixel fg, bg;
    static XFontStruct *font;
    static Pixmap pix;
    static GC gc;
    static int first = 1;
    XColor color, dummy;
    XGCValues  values;
    Dimension x,y,w,h,sw,sh;
    int maxwidth,width,height,direction,ascent,descent,lastline,i;
    XCharStruct cs;

    if (NULL == tt) {
	XtPopdown(vtx_shell);
	return;
    }

    if (NULL == font) {
	XtVaGetValues(vtx_label,
		      XtNfont,&font,
		      XtNbackground,&bg,
		      XtNforeground,&fg,
		      NULL);
	values.font = font->fid;
	gc = XCreateGC(dpy, XtWindow(vtx_label), GCFont, &values);
    }

    /* calc size + positions */
    width = 0; height = 0; maxwidth = 0;
    lastline = -1;
    for (i = 0; tt[i].len; i++) {
	XTextExtents(font,tt[i].str,tt[i].len,
		     &direction,&ascent,&descent,&cs);
	if (lastline != tt[i].line) {
	    if (maxwidth < width)
		maxwidth = width;
	    width = 0;
	    height += ascent+descent;
	    lastline = tt[i].line;
	}
	tt[i].x = width;
	tt[i].y = height - descent;
	width += cs.width;
    }
    if (maxwidth < width)
	maxwidth = width;

    /* alloc pixmap + draw text */
    if (pix)
	XFreePixmap(dpy,pix);
    fprintf(stderr,"pix: %dx%d\n",maxwidth, height);
    pix = XCreatePixmap(dpy, RootWindowOfScreen(XtScreen(vtx_label)),
			maxwidth, height,
			DefaultDepthOfScreen(XtScreen(vtx_label)));
    values.foreground = bg;
    values.background = bg;
    XChangeGC(dpy, gc, GCForeground | GCBackground, &values);
    XFillRectangle(dpy,pix,gc,0,0,maxwidth,height);
    for (i = 0; tt[i].len; i++) {
	if (tt[i].fg) {
	    XAllocNamedColor(dpy,colormap,tt[i].fg,
			     &color,&dummy);
	    values.foreground = color.pixel;
	} else {
	    values.foreground = fg;
	}
	if (tt[i].bg) {
	    XAllocNamedColor(dpy,colormap,tt[i].bg,
			     &color,&dummy);
	    values.background = color.pixel;
	} else {
	    values.background = bg;
	}
	XChangeGC(dpy, gc, GCForeground | GCBackground, &values);
	XDrawImageString(dpy,pix,gc,tt[i].x,tt[i].y,tt[i].str,tt[i].len);
    }
    XtVaSetValues(vtx_label,XtNbitmap,pix,XtNlabel,NULL,NULL);

    XtVaGetValues(app_shell,XtNx,&x,XtNy,&y,XtNwidth,&w,XtNheight,&h,NULL);
    XtVaGetValues(vtx_shell,XtNwidth,&sw,XtNheight,&sh,NULL);
    XtVaSetValues(vtx_shell,XtNx,x+(w-sw)/2,XtNy,y+h-10-sh,NULL);
    XtPopup(vtx_shell, XtGrabNone);
    if (wm_stay_on_top && stay_on_top > 0)
	wm_stay_on_top(dpy,XtWindow(vtx_shell),1);

    if (first) {
	first = 0;
	XDefineCursor(dpy, XtWindow(vtx_shell), left_ptr);
	XDefineCursor(dpy, XtWindow(vtx_label), left_ptr);
    }
}
#endif

#ifdef HAVE_ZVBI
static void
display_subtitle(struct vbi_page *pg, struct vbi_rect *rect)
{
    static int first = 1;
    static Pixmap pix;
    Dimension x,y,w,h,sw,sh;

    if (NULL == pg) {
	XtPopdown(vtx->shell);
	return;
    }

    if (pix)
	XFreePixmap(dpy,pix);
    pix = vbi_export_pixmap(vtx,pg,rect);
    XtVaSetValues(vtx->tt,XtNbitmap,pix,XtNlabel,NULL,NULL);

    XtVaGetValues(app_shell,XtNx,&x,XtNy,&y,XtNwidth,&w,XtNheight,&h,NULL);
    XtVaGetValues(vtx->shell,XtNwidth,&sw,XtNheight,&sh,NULL);
    XtVaSetValues(vtx->shell,XtNx,x+(w-sw)/2,XtNy,y+h-10-sh,NULL);
    XtPopup(vtx->shell, XtGrabNone);
    if (wm_stay_on_top && stay_on_top > 0)
	wm_stay_on_top(dpy,XtWindow(vtx->shell),1);

    if (first) {
	first = 0;
	XDefineCursor(dpy, XtWindow(vtx->shell), left_ptr);
	XDefineCursor(dpy, XtWindow(vtx->tt), left_ptr);
    }
}
#endif

/*--- tv -----------------------------------------------------------------*/

static void
resize_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d)
{
    static int width = 0, height = 0;
    char label[64];

    switch(event->type) {
    case ConfigureNotify:
	if (!window_configured) {
	    video_gd_init(tv,args.gl);
	    window_configured = 1;
	}
	if (width  != event->xconfigure.width ||
	    height != event->xconfigure.height) {
	    width  = event->xconfigure.width;
	    height = event->xconfigure.height;
	    video_gd_configure(width, height);
	    XClearWindow(XtDisplay(tv),XtWindow(tv));
	    sprintf(label,"%-" LABEL_WIDTH "s: %dx%d",MOVIE_SIZE,width,height);
	    if (w_movie_size)
		XtVaSetValues(w_movie_size,XtNlabel,label,NULL);
	}
	break;
    }
}

/*------------------------------------------------------------------------*/

/* the RightWay[tm] to set float resources (copyed from Xaw specs) */
static void
set_float(Widget widget, char *name, float value)
{
    Arg   args[1];

    if (sizeof(float) > sizeof(XtArgVal)) {
	/*
	 * If a float is larger than an XtArgVal then pass this
	 * resource value by reference.
	 */
	XtSetArg(args[0], name, &value);
    } else {
	/*
	 * Convince C not to perform an automatic conversion, which
	 * would truncate 0.5 to 0.
	 *
	 * switched from pointer tricks to the union to fix alignment
	 * problems on ia64 (Stephane Eranian )
	 */
	union {
	    XtArgVal xt;
	    float   fp;
	} foo;
	foo.fp = value;
	XtSetArg(args[0], name, foo.xt);
    }
    XtSetValues(widget,args,1);
}

static void
new_freqtab(void)
{
    char label[64];

    if (c_freq) {
	sprintf(label,"%-" LABEL_WIDTH "s: %s","Frequency table",
		chanlists[chantab].name);
	XtVaSetValues(c_freq,XtNlabel,label,NULL);
    }
}

static void
new_attr(struct ng_attribute *attr, int val)
{
    struct xaw_attribute *a;
    char label[64],*olabel;
    const char *valstr;

    for (a = xaw_attrs; NULL != a; a = a->next) {
	if (a->attr->id == attr->id)
	    break;
    }
    if (NULL != a) {
	switch (attr->type) {
	case ATTR_TYPE_CHOICE:
	    XtVaGetValues(a->cmd,XtNlabel,&olabel,NULL);
	    valstr = ng_attr_getstr(attr,val);
	    sprintf(label,"%-" LABEL_WIDTH "." LABEL_WIDTH "s: %s",
		    olabel,valstr ? valstr : "unknown");
	    XtVaSetValues(a->cmd,XtNlabel,label,NULL);
	    break;
	case ATTR_TYPE_BOOL:
	    XtVaGetValues(a->cmd,XtNlabel,&olabel,NULL);
	    sprintf(label,"%-" BOOL_WIDTH "." BOOL_WIDTH "s  %s",
		    olabel,val ? "on" : "off");
	    XtVaSetValues(a->cmd,XtNlabel,label,NULL);
	    break;
	case ATTR_TYPE_INTEGER:
	    set_float(a->scroll,XtNtopOfThumb,
		      (float)(val-attr->min) / (attr->max - attr->min));
	    break;
	}
	return;
    }
}

static void
new_volume(void)
{
    struct ng_attribute *attr;

    attr = ng_attr_byid(attrs,ATTR_ID_VOLUME);
    if (NULL != attr)
	new_attr(attr,cur_attrs[ATTR_ID_VOLUME]);
}

static void
new_channel(void)
{
    set_property(cur_freq,
		 (cur_channel == -1) ? NULL : chanlist[cur_channel].name,
		 (cur_sender == -1)  ? NULL : channels[cur_sender]->name);
    conf_station_switched();

    if (zap_timer) {
	XtRemoveTimeOut(zap_timer);
	zap_timer = 0;
    }
    if (scan_timer) {
	XtRemoveTimeOut(scan_timer);
	scan_timer = 0;
    }
    if (audio_timer) {
	XtRemoveTimeOut(audio_timer);
	audio_timer = 0;
    }
    if (unmute_timer) {
	XtRemoveTimeOut(unmute_timer);
	unmute_timer = 0;
    }
    audio_timer = XtAppAddTimeOut(app_context, 5000, watch_audio, NULL);
    if (unmute_pending)
        unmute_timer = XtAppAddTimeOut(app_context, 800, unmute_audio, NULL);
}

void
watch_audio(XtPointer data, XtIntervalId *id)
{
    if (-1 != cur_sender)
	change_audio(channels[cur_sender]->audio);
    audio_timer = 0;
}

void unmute_audio(XtPointer data, XtIntervalId *id)
{
    if (unmute_pending) {
        audio_on();
        unmute_pending = 0;
    }
    unmute_timer = 0;
}

/*------------------------------------------------------------------------*/

static void
do_capture(int from, int to, int tmp_switch)
{
    static int niced = 0;
    char label[64];

    /* off */
    switch (from) {
    case CAPTURE_OFF:
	XtVaSetValues(tv,XtNbackgroundPixmap,XtUnspecifiedPixmap,NULL);
	if (tv_pix)
	    XFreePixmap(dpy,tv_pix);
	tv_pix = 0;
	break;
    case CAPTURE_GRABDISPLAY:
	video_gd_stop();
	if (!tmp_switch)
	    XClearArea(XtDisplay(tv), XtWindow(tv), 0,0,0,0, True);
	break;
    case CAPTURE_OVERLAY:
	video_overlay(0);
	break;
    }

    /* on */
    switch (to) {
    case CAPTURE_OFF:
	sprintf(label,"%-" LABEL_WIDTH "s: %s","Capture","off");
	if (!tmp_switch) {
	    tv_pix = x11_capture_pixmap(dpy, &vinfo, colormap, 0, 0);
	    if (tv_pix)
		XtVaSetValues(tv,XtNbackgroundPixmap,tv_pix,NULL);
	}
	break;
    case CAPTURE_GRABDISPLAY:
	sprintf(label,"%-" LABEL_WIDTH "s: %s","Capture","grabdisplay");
	if (!niced)
	    nice(niced = 10);
	video_gd_start();
	break;
    case CAPTURE_OVERLAY:
	sprintf(label,"%-" LABEL_WIDTH "s: %s","Capture","overlay");
	video_overlay(1);
	break;
    }
    if (c_cap)
	XtVaSetValues(c_cap,XtNlabel,label,NULL);
}

/* gets called before switching away from a channel */
static void leaving_channel(void)
{
    Pixmap pix;
    struct ng_video_fmt fmt;
    struct ng_video_buf *buf;

    if (!cur_attrs[ATTR_ID_MUTE]) {
        audio_off();
        unmute_pending = 1;
    }

    if (cur_sender == -1)
	return;

    /* save picture settings */
    channels[cur_sender]->color    = cur_attrs[ATTR_ID_COLOR];
    channels[cur_sender]->bright   = cur_attrs[ATTR_ID_BRIGHT];
    channels[cur_sender]->hue      = cur_attrs[ATTR_ID_HUE];
    channels[cur_sender]->contrast = cur_attrs[ATTR_ID_CONTRAST];
    channels[cur_sender]->input    = cur_attrs[ATTR_ID_INPUT];
    channels[cur_sender]->norm     = cur_attrs[ATTR_ID_NORM];

    if (0 == pix_width || 0 == pix_height)
	return;

    /* capture mini picture */
    if (!(f_drv & CAN_CAPTURE))
	return;

    video_gd_suspend();
    memset(&fmt,0,sizeof(fmt));
    fmt.fmtid  = x11_dpy_fmtid;
    fmt.width  = pix_width;
    fmt.height = pix_height;
    if (NULL == (buf = ng_grabber_get_image(&fmt)))
	goto done1;
    buf = ng_filter_single(cur_filter,buf);
    if (0 == (pix = x11_create_pixmap(dpy,&vinfo,buf)))
	goto done2;
    x11_label_pixmap(dpy,colormap,pix,buf->fmt.height,
		     channels[cur_sender]->name);
    XtVaSetValues(channels[cur_sender]->button,
		  XtNbackgroundPixmap,pix,
		  XtNlabel,"",
		  XtNwidth,pix_width,
		  XtNheight,pix_height,
		  NULL);
    if (channels[cur_sender]->pixmap)
	XFreePixmap(dpy,channels[cur_sender]->pixmap);
    channels[cur_sender]->pixmap = pix;

 done2:
    ng_release_video_buf(buf);
 done1:
    video_gd_restart();
}

static void
set_menu_val(Widget widget, char *name, struct STRTAB *tab, int val)
{
    char label[64];
    int i;

    for (i = 0; tab[i].str != NULL; i++) {
	if (tab[i].nr == val)
	    break;
    }
    sprintf(label,"%-15s : %s",name,
	    (tab[i].str != NULL) ? tab[i].str : "invalid");
    XtVaSetValues(widget,XtNlabel,label,NULL);
}

void
ChannelAction(Widget widget, XEvent *event,
	      String *params, Cardinal *num_params)
{
    int i;

    if (!(f_drv & CAN_TUNE))
	return;

    if (0 == count)
	return;
    i = popup_menu(widget,"Stations",cmenu);

    if (i != -1)
	do_va_cmd(2,"setstation",channels[i]->name);
}

static void create_chanwin(void)
{
    if (!(f_drv & CAN_TUNE))
	return;

    chan_shell = XtVaAppCreateShell("Channels", "Xawtv",
				    topLevelShellWidgetClass,
				    dpy,
				    XtNclientLeader,app_shell,
				    XtNvisual,vinfo.visual,
				    XtNcolormap,colormap,
				    XtNdepth,vinfo.depth,
		      XtNheight,XtScreen(app_shell)->height/2,
		      XtNmaxHeight,XtScreen(app_shell)->height-50,
				    NULL);
    XtOverrideTranslations(chan_shell, XtParseTranslationTable
			   ("WM_PROTOCOLS: Popup()"));
    chan_viewport = XtVaCreateManagedWidget("viewport",
					    viewportWidgetClass, chan_shell,
					    XtNallowHoriz, False,
					    XtNallowVert, True,
					    NULL);
    chan_box = XtVaCreateManagedWidget("channelbox",
				       boxWidgetClass, chan_viewport,
				       XtNsensitive, True,
				       NULL);
}

void channel_menu(void); /* FIXME */
void channel_menu(void)
{
    int  i,max,len;
    char str[100];

    if (!(f_drv & CAN_TUNE))
	return;

    if (cmenu)
	free(cmenu);
    cmenu = malloc((count+1)*sizeof(struct STRTAB));
    memset(cmenu,0,(count+1)*sizeof(struct STRTAB));
    for (i = 0, max = 0; i < count; i++) {
	len = strlen(channels[i]->name);
	if (max < len)
	    max = len;
    }
    for (i = 0; i < count; i++) {
	cmenu[i].nr      = i;
	cmenu[i].str     = channels[i]->name;
	if (channels[i]->key) {
	    sprintf(str,"%2d  %-*s  %s",i+1,
		    max+2,channels[i]->name,channels[i]->key);
	} else {
	    sprintf(str,"%2d  %-*s",i+1,max+2,channels[i]->name);
	}
	cmenu[i].str=strdup(str);
    }
    conf_list_update();
    calc_frequencies();
}

void
StayOnTop(Widget widget, XEvent *event,
	  String *params, Cardinal *num_params)
{
    unsigned int i;

    if (!wm_stay_on_top)
	return;

    stay_on_top = stay_on_top ? 0 : 1;
    if (debug)
	fprintf(stderr,"stay_on_top: %d\n",stay_on_top);

    wm_stay_on_top(dpy,XtWindow(app_shell),stay_on_top);
    wm_stay_on_top(dpy,XtWindow(on_shell),stay_on_top);
    for (i = 0; i < TOPLEVELS; i++)
	wm_stay_on_top(dpy,XtWindow(*(my_toplevels[i].shell)),
		       (stay_on_top == -1) ? 0 : stay_on_top);
}

/*--- option window ------------------------------------------------------*/

static void
update_movie_menus(void)
{
    struct list_head *item;
    struct ng_writer *writer;
    Boolean sensitive;
    unsigned int i;

    /* drivers  */
    if (NULL == m_movie_driver) {
	i = 0;
	list_for_each(item,&ng_writers)
	    i++;
	m_movie_driver = malloc(sizeof(struct STRTAB)*(i+1));
	memset(m_movie_driver,0,sizeof(struct STRTAB)*(i+1));
	i = 0;
	list_for_each(item,&ng_writers) {
	    writer = list_entry(item, struct ng_writer, list);
	    m_movie_driver[i].nr  = i;
	    m_movie_driver[i].str = writer->desc;
	    if (NULL == movie_driver ||
		(NULL != mov_driver && 0 == strcasecmp(mov_driver,writer->name))) {
		movie_driver = writer;
		i_movie_driver = i;
	    }
	    i++;
	}
	m_movie_driver[i].nr  = i;
	m_movie_driver[i].str = NULL;
    }

    /* audio formats */
    for (i = 0; NULL != movie_driver->audio[i].name; i++)
	;
    if (m_movie_audio)
	free(m_movie_audio);
    movie_audio = 0;
    m_movie_audio = malloc(sizeof(struct STRTAB)*(i+2));
    memset(m_movie_audio,0,sizeof(struct STRTAB)*(i+2));
    for (i = 0; NULL != movie_driver->audio[i].name; i++) {
	m_movie_audio[i].nr  = i;
	m_movie_audio[i].str = movie_driver->audio[i].desc ?
	    movie_driver->audio[i].desc :
	    ng_afmt_to_desc[movie_driver->audio[i].fmtid];
	if (NULL != mov_audio)
	    if (0 == strcasecmp(mov_audio,movie_driver->audio[i].name))
		movie_audio = i;
    }
    m_movie_audio[i].nr  = i;
    m_movie_audio[i].str = "no sound";

    /* video formats */
    for (i = 0; NULL != movie_driver->video[i].name; i++)
	;
    if (m_movie_video)
	free(m_movie_video);
    movie_video = 0;
    m_movie_video = malloc(sizeof(struct STRTAB)*(i+2));
    memset(m_movie_video,0,sizeof(struct STRTAB)*(i+2));
    for (i = 0; NULL != movie_driver->video[i].name; i++) {
	m_movie_video[i].nr  = i;
	m_movie_video[i].str = movie_driver->video[i].desc ?
	    movie_driver->video[i].desc :
	    ng_vfmt_to_desc[movie_driver->video[i].fmtid];
	if (NULL != mov_video)
	    if (0 == strcasecmp(mov_video,movie_driver->video[i].name))
		movie_video = i;
    }

    /* need audio filename? */
    sensitive = movie_driver->combined ? False : True;
    XtVaSetValues(w_movie_flabel,
		  XtNsensitive,sensitive,
		  NULL);
    XtVaSetValues(w_movie_faudio,
		  XtNsensitive,sensitive,
		  NULL);
}

static void
init_movie_menus(void)
{
    update_movie_menus();

    if (mov_rate)
	do_va_cmd(3,"movie","rate",mov_rate);
    if (mov_fps)
	do_va_cmd(3,"movie","fps",mov_fps);
    set_menu_val(w_movie_driver,MOVIE_DRIVER,m_movie_driver,i_movie_driver);
    set_menu_val(w_movie_audio,MOVIE_AUDIO,m_movie_audio,movie_audio);
    set_menu_val(w_movie_rate,MOVIE_RATE,m_movie_rate,movie_rate);
    set_menu_val(w_movie_video,MOVIE_VIDEO,m_movie_video,movie_video);
    set_menu_val(w_movie_fps,MOVIE_FPS,m_movie_fps,movie_fps);
}

#define PANED_FIX               \
	XtNallowResize, False,  \
	XtNshowGrip,    False,  \
	XtNskipAdjust,  True

struct DO_CMD cmd_fs   = { 1, { "fullscreen",        NULL }};
struct DO_CMD cmd_cap  = { 2, { "capture", "toggle", NULL }};
struct DO_CMD cmd_jpeg = { 2, { "snap",    "jpeg",   NULL }};
struct DO_CMD cmd_ppm  = { 2, { "snap",    "ppm",    NULL }};

struct DO_AC  ac_fs    = { 0, "FullScreen", { NULL }};
struct DO_AC  ac_top   = { 0, "StayOnTop",  { NULL }};

struct DO_AC  ac_avi   = { 1, "Popup",      { "streamer", NULL }};
struct DO_AC  ac_chan  = { 1, "Popup",      { "channels", NULL }};
struct DO_AC  ac_conf  = { 1, "Popup",      { "config",   NULL }};
struct DO_AC  ac_launch = { 1, "Popup",      { "launcher",  NULL }};
struct DO_AC  ac_zap   = { 0, "Zap",        { NULL }};
struct DO_AC  ac_mute  = { 0, "Mute",       { NULL }};

static void
menu_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct ng_attribute *attr;
    long  cd = (long)clientdata;
    int   j;

    switch (cd) {
#if 0
    case 10:
	attr = ng_attr_byid(a_drv,ATTR_ID_NORM);
	if (-1 != (j=popup_menu(widget,"TV Norm",attr->choices)))
	    do_va_cmd(2,"setnorm",ng_attr_getstr(attr,j));
	break;
    case 11:
	attr = ng_attr_byid(a_drv,ATTR_ID_INPUT);
	if (-1 != (j=popup_menu(widget,"Video Source",attr->choices)))
	    do_va_cmd(2,"setinput",ng_attr_getstr(attr,j));
	break;
#endif
    case 12:
	if (-1 != (j=popup_menu(widget,"Freq table",chanlist_names)))
	    do_va_cmd(2,"setfreqtab",chanlist_names[j].str);
	break;
    case 13:
	attr = ng_attr_byid(attrs,ATTR_ID_AUDIO_MODE);
	if (NULL != attr) {
	    int i,mode = attr->read(attr);
	    for (i = 1; attr->choices[i].str != NULL; i++) {
		attr->choices[i].nr =
		    (1 << (i-1)) & mode ? (1 << (i-1)) : -1;
	    }
	    if (-1 != (j=popup_menu(widget,"Audio",attr->choices)))
		change_audio(attr->choices[j].nr);
	}
	break;
    case 14:
	if (-1 != (j=popup_menu(widget,"Capture",cap_list)))
	    do_va_cmd(2,"capture",cap_list[j].str);
	break;

    case 20:
	if (-1 != (j=popup_menu(widget,MOVIE_DRIVER,m_movie_driver))) {
	    int i = 0;
	    struct list_head *item;
	    struct ng_writer *writer = NULL;

	    list_for_each(item,&ng_writers) {
		if (i++ == j)
		    writer = list_entry(item,struct ng_writer, list);
	    }
	    do_va_cmd(3,"movie","driver",writer->name);
	}
	break;
    case 21:
	if (-1 != (j=popup_menu(widget,MOVIE_AUDIO,m_movie_audio)))
	    do_va_cmd(3,"movie","audio",
		      movie_driver->audio[j].name ?
		      movie_driver->audio[j].name :
		      "none");
	break;
    case 22:
	if (-1 != (j=popup_menu(widget,MOVIE_RATE,m_movie_rate)))
	    do_va_cmd(3,"movie","rate",m_movie_rate[j].str);
	break;
    case 23:
	if (-1 != (j=popup_menu(widget,MOVIE_VIDEO,m_movie_video)))
	    do_va_cmd(3,"movie","video",movie_driver->video[j].name);
	break;
    case 24:
	if (-1 != (j=popup_menu(widget,MOVIE_FPS,m_movie_fps)))
	    do_va_cmd(3,"movie","fps",m_movie_fps[j].str);
	break;
    default:
	/* nothing */
	break;
    }
}

static void
jump_scb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct xaw_attribute *a = clientdata;
    struct ng_attribute *attr = a->attr;
    const char *name;
    char val[16];
    int  value,range;

    range = attr->max - attr->min;
    value = (int)(*(float*)call_data * range) + attr->min;
    if (debug)
	fprintf(stderr,"scroll: value is %d\n",value);
    if (value < attr->min)
	value = attr->min;
    if (value > attr->max)
	value = attr->max;
    sprintf(val,"%d",value);

    if (a) {
	name = a->attr->name;
	do_va_cmd(3,"setattr",name,val);
    } else {
	name = XtName(XtParent(widget));
	do_va_cmd(2,name,val);
    }
}

static void
scroll_scb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    long      move = (long)call_data;
    Dimension length;
    float     shown,top1,top2;

    XtVaGetValues(widget,
		  XtNlength,     &length,
		  XtNshown,      &shown,
		  XtNtopOfThumb, &top1,
		  NULL);

    top2 = top1 + (float)move/length/5;
    if (top2 < 0) top2 = 0;
    if (top2 > 1) top2 = 1;
#if 1
    fprintf(stderr,"scroll by %ld\tlength %d\tshown %f\ttop %f => %f\n",
	    move,length,shown,top1,top2);
#endif
    jump_scb(widget,clientdata,&top2);
}

static void
attr_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct xaw_attribute *a = clientdata;
    int j;

    switch (a->attr->type) {
    case ATTR_TYPE_CHOICE:
	j=popup_menu(widget,a->attr->name,a->attr->choices);
	if (-1 != j)
	    do_va_cmd(3,"setattr",a->attr->name,a->attr->choices[j].str);
	break;
    case ATTR_TYPE_BOOL:
	do_va_cmd(3,"setattr",a->attr->name,"toggle");
	break;
    }
}

static void
add_attr_option(Widget paned, struct ng_attribute *attr)
{
    struct xaw_attribute *a;
    Widget p,l;

    a = malloc(sizeof(*a));
    memset(a,0,sizeof(*a));
    a->attr = attr;

    switch (attr->type) {
    case ATTR_TYPE_BOOL:
    case ATTR_TYPE_CHOICE:
	a->cmd = XtVaCreateManagedWidget(attr->name,
					 commandWidgetClass, paned,
					 PANED_FIX,
					 NULL);
	XtAddCallback(a->cmd,XtNcallback,attr_cb,a);
	break;
    case ATTR_TYPE_INTEGER:
	p = XtVaCreateManagedWidget(attr->name,
				    panedWidgetClass, paned,
				    XtNorientation, XtEvertical,
				    PANED_FIX,
				    NULL);
	l = XtVaCreateManagedWidget("l",labelWidgetClass, p,
				    XtNshowGrip, False,
				    NULL);
	a->scroll = XtVaCreateManagedWidget("s",scrollbarWidgetClass,p,
					    PANED_FIX,
					    NULL);
	XtAddCallback(a->scroll, XtNjumpProc,   jump_scb,   a);
	XtAddCallback(a->scroll, XtNscrollProc, scroll_scb, a);
	if (attr->id >= ATTR_ID_COUNT)
	    XtVaSetValues(l,XtNlabel,attr->name,NULL);
	break;
    }
    a->next = xaw_attrs;
    xaw_attrs = a;
}

static void
create_optwin(void)
{
    Widget c;

    opt_shell = XtVaAppCreateShell("Options", "Xawtv",
				   topLevelShellWidgetClass,
				   dpy,
				   XtNclientLeader,app_shell,
				   XtNvisual,vinfo.visual,
				   XtNcolormap,colormap,
				   XtNdepth,vinfo.depth,
				   NULL);
    XtOverrideTranslations(opt_shell, XtParseTranslationTable
			   ("WM_PROTOCOLS: Popup()"));
    opt_paned = XtVaCreateManagedWidget("paned", panedWidgetClass, opt_shell,
					NULL);

    c = XtVaCreateManagedWidget("mute", commandWidgetClass, opt_paned,
				PANED_FIX, NULL);
    XtAddCallback(c, XtNcallback, action_cb, (XtPointer)&ac_mute);

    c = XtVaCreateManagedWidget("fs", commandWidgetClass, opt_paned,
				PANED_FIX, NULL);
    XtAddCallback(c,XtNcallback,command_cb,(XtPointer)&cmd_fs);

    c = XtVaCreateManagedWidget("grabppm", commandWidgetClass, opt_paned,
				PANED_FIX, NULL);
    XtAddCallback(c,XtNcallback,command_cb,(XtPointer)&cmd_ppm);
    c = XtVaCreateManagedWidget("grabjpeg", commandWidgetClass, opt_paned,
				PANED_FIX, NULL);
    XtAddCallback(c,XtNcallback,command_cb,(XtPointer)&cmd_jpeg);
    c = XtVaCreateManagedWidget("recavi", commandWidgetClass, opt_paned,
				PANED_FIX, NULL);
    XtAddCallback(c,XtNcallback,action_cb,(XtPointer)&ac_avi);
    if (f_drv & CAN_TUNE) {
	c = XtVaCreateManagedWidget("chanwin", commandWidgetClass, opt_paned,
				    PANED_FIX, NULL);
	XtAddCallback(c,XtNcallback,action_cb,(XtPointer)&ac_chan);
	c = XtVaCreateManagedWidget("confwin", commandWidgetClass, opt_paned,
				    PANED_FIX, NULL);
	XtAddCallback(c,XtNcallback,action_cb,(XtPointer)&ac_conf);
	c = XtVaCreateManagedWidget("zap", commandWidgetClass, opt_paned,
				    PANED_FIX, NULL);
	XtAddCallback(c,XtNcallback,action_cb,(XtPointer)&ac_zap);
    }
    c = XtVaCreateManagedWidget("launchwin", commandWidgetClass, opt_paned,
				PANED_FIX, NULL);
    XtAddCallback(c,XtNcallback,action_cb,(XtPointer)&ac_launch);
    if (wm_stay_on_top) {
	c = XtVaCreateManagedWidget("top", commandWidgetClass, opt_paned,
				    PANED_FIX, NULL);
	XtAddCallback(c,XtNcallback,action_cb,(XtPointer)&ac_top);
    }
}

static void
create_attr_widgets(void)
{
    struct ng_attribute *attr;
    Widget c;

    /* menus / multiple choice options */
    attr = ng_attr_byid(attrs,ATTR_ID_NORM);
    if (NULL != attr)
	add_attr_option(opt_paned,attr);
    attr = ng_attr_byid(attrs,ATTR_ID_INPUT);
    if (NULL != attr)
	add_attr_option(opt_paned,attr);
    attr = ng_attr_byid(attrs,ATTR_ID_AUDIO_MODE);
    if (NULL != attr)
	add_attr_option(opt_paned,attr);

    if (f_drv & CAN_TUNE) {
	c_freq = XtVaCreateManagedWidget("freq", commandWidgetClass, opt_paned,
					 PANED_FIX, NULL);
	XtAddCallback(c_freq,XtNcallback,menu_cb,(XtPointer)12);
    }
    c_cap = XtVaCreateManagedWidget("cap", commandWidgetClass, opt_paned,
				    PANED_FIX, NULL);
    XtAddCallback(c_cap,XtNcallback,menu_cb,(XtPointer)14);

    for (attr = attrs; attr->name != NULL; attr++) {
	if (attr->id < ATTR_ID_COUNT)
	    continue;
	if (attr->type != ATTR_TYPE_CHOICE)
	    continue;
	add_attr_option(opt_paned,attr);
    }

    /* integer options */
    attr = ng_attr_byid(attrs,ATTR_ID_BRIGHT);
    if (NULL != attr)
	add_attr_option(opt_paned,attr);
    attr = ng_attr_byid(attrs,ATTR_ID_HUE);
    if (NULL != attr)
	add_attr_option(opt_paned,attr);
    attr = ng_attr_byid(attrs,ATTR_ID_CONTRAST);
    if (NULL != attr)
	add_attr_option(opt_paned,attr);
    attr = ng_attr_byid(attrs,ATTR_ID_COLOR);
    if (NULL != attr)
	add_attr_option(opt_paned,attr);
    attr = ng_attr_byid(attrs,ATTR_ID_VOLUME);
    if (NULL != attr)
	add_attr_option(opt_paned,attr);

    for (attr = attrs; attr->name != NULL; attr++) {
	if (attr->id < ATTR_ID_COUNT)
	    continue;
	if (attr->type != ATTR_TYPE_INTEGER)
	    continue;
	add_attr_option(opt_paned,attr);
    }

    /* boolean options */
    for (attr = attrs; attr->name != NULL; attr++) {
	if (attr->id < ATTR_ID_COUNT)
	    continue;
	if (attr->type != ATTR_TYPE_BOOL)
	    continue;
	add_attr_option(opt_paned,attr);
    }

    /* quit */
    c = XtVaCreateManagedWidget("quit", commandWidgetClass, opt_paned,
				PANED_FIX, NULL);
    XtAddCallback(c,XtNcallback,ExitCB,NULL);
}

/*--- avi recording ------------------------------------------------------*/

static void
exec_record(Widget widget, XtPointer client_data, XtPointer calldata)
{
    if (!(f_drv & CAN_CAPTURE)) {
	fprintf(stderr,"grabbing: not supported [try -noxv switch?]\n");
	return;
    }

    if (rec_work_id) {
	do_va_cmd(2,"movie","stop");
    } else {
	do_va_cmd(2,"movie","start");
    }
    return;
}

static void
exec_player_cb(Widget widget, XtPointer client_data, XtPointer calldata)
{
    char *filename;

    XtVaGetValues(w_movie_fvideo,XtNstring,&filename,NULL);
    filename = tilde_expand(filename);
    exec_player(filename);
}

static void
do_movie_record(int argc, char **argv)
{
    char *fvideo,*faudio;
    struct ng_video_fmt video;
    struct ng_audio_fmt audio;
    const struct ng_writer *wr;
    int i;

    /* set parameters */
    if (argc > 1 && 0 == strcasecmp(argv[0],"driver")) {
	struct list_head *item;
	struct ng_writer *writer;
	i = 0;
	list_for_each(item,&ng_writers) {
	    writer = list_entry(item, struct ng_writer, list);
	    if (0 == strcasecmp(argv[1],writer->name)) {
		movie_driver = writer;
		i_movie_driver = i;
	    }
	    i++;
	}

	set_menu_val(w_movie_driver,MOVIE_DRIVER,
		     m_movie_driver,i_movie_driver);
	update_movie_menus();
	set_menu_val(w_movie_audio,MOVIE_AUDIO,
		     m_movie_audio,movie_audio);
	set_menu_val(w_movie_video,MOVIE_VIDEO,
		     m_movie_video,movie_video);
	return;
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"fvideo")) {
	XtVaSetValues(w_movie_fvideo,XtNstring,argv[1],NULL);
	return;
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"faudio")) {
	XtVaSetValues(w_movie_faudio,XtNstring,argv[1],NULL);
	return;
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"audio")) {
	for (i = 0; NULL != movie_driver->audio[i].name; i++) {
	    if (0 == strcasecmp(argv[1],movie_driver->audio[i].name))
		movie_audio = m_movie_audio[i].nr;
	}
	if (0 == strcmp(argv[1],"none"))
	    movie_audio = m_movie_audio[i].nr;
	set_menu_val(w_movie_audio,MOVIE_AUDIO,
		     m_movie_audio,movie_audio);
	return;
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"rate")) {
	for (i = 0; m_movie_rate[i].str != NULL; i++)
	    if (atoi(argv[1]) == m_movie_rate[i].nr)
		movie_rate = m_movie_rate[i].nr;
	set_menu_val(w_movie_rate,MOVIE_RATE,
		     m_movie_rate,movie_rate);
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"video")) {
	for (i = 0; NULL != movie_driver->video[i].name; i++)
	    if (0 == strcasecmp(argv[1],movie_driver->video[i].name))
		movie_video = m_movie_video[i].nr;
	set_menu_val(w_movie_video,MOVIE_VIDEO,
		     m_movie_video,movie_video);
	return;
    }
    if (argc > 1 && 0 == strcasecmp(argv[0],"fps")) {
	for (i = 0; m_movie_fps[i].str != NULL; i++) {
	    int fps = (int)(atof(argv[1]) * 1000 + .5);
	    if (fps == m_movie_fps[i].nr)
		movie_fps = m_movie_fps[i].nr;
	}
	set_menu_val(w_movie_fps,MOVIE_FPS,
		     m_movie_fps,movie_fps);
    }

    /* start */
    if (argc > 0 && 0 == strcasecmp(argv[0],"start")) {
	if (0 != cur_movie)
	    return; /* records already */
	cur_movie = 1;
	movie_blit = (cur_capture == CAPTURE_GRABDISPLAY);
	video_gd_suspend();

	XtVaGetValues(w_movie_fvideo,XtNstring,&fvideo,NULL);
	XtVaGetValues(w_movie_faudio,XtNstring,&faudio,NULL);
	fvideo = tilde_expand(fvideo);
	faudio = tilde_expand(faudio);

	memset(&video,0,sizeof(video));
	memset(&audio,0,sizeof(audio));

	wr = movie_driver;
	video.fmtid  = wr->video[movie_video].fmtid;
	video.width  = cur_tv_width;
	video.height = cur_tv_height;
	if (NULL != wr->audio[movie_audio].name) {
	    audio.fmtid  = wr->audio[movie_audio].fmtid;
	    audio.rate   = movie_rate;
	} else {
	    audio.fmtid  = AUDIO_NONE;
	}

	movie_state = movie_writer_init
	    (fvideo, faudio, wr,
	     &video, wr->video[movie_video].priv, movie_fps,
	     &audio, wr->audio[movie_audio].priv, args.dspdev,
	     args.bufcount,args.parallel);
	if (NULL == movie_state) {
	    /* init failed */
	    video_gd_restart();
	    cur_movie = 0;
	    /* hmm, not the most elegant way to flag an error ... */
	    XtVaSetValues(w_movie_status,XtNlabel,"error [init]",NULL);
	    return;
	}
	if (0 != movie_writer_start(movie_state)) {
	    /* start failed */
	    movie_writer_stop(movie_state);
	    video_gd_restart();
	    cur_movie = 0;
	    /* hmm, not the most elegant way to flag an error ... */
	    XtVaSetValues(w_movie_status,XtNlabel,"error [start]",NULL);
	    return;
	}
	rec_work_id  = XtAppAddWorkProc(app_context,rec_work,NULL);
	XtVaSetValues(w_movie_status,XtNlabel,"recording",NULL);
	return;
    }

    /* stop */
    if (argc > 0 && 0 == strcasecmp(argv[0],"stop")) {
	if (0 == cur_movie)
	    return; /* nothing to stop here */

	movie_writer_stop(movie_state);
	XtRemoveWorkProc(rec_work_id);
	rec_work_id = 0;
	video_gd_restart();
	cur_movie = 0;
	return;
    }
}

static void
do_rec_status(char *message)
{
    XtVaSetValues(w_movie_status,XtNlabel,message,NULL);
}

#define FIX_LEFT_TOP        \
    XtNleft,XawChainLeft,   \
    XtNright,XawChainRight, \
    XtNtop,XawChainTop,     \
    XtNbottom,XawChainTop

static void
create_strwin(void)
{
    Widget form,label,button,text;

    str_shell = XtVaAppCreateShell("Streamer", "Xawtv",
				   topLevelShellWidgetClass,
				   dpy,
				   XtNclientLeader,app_shell,
				   XtNvisual,vinfo.visual,
				   XtNcolormap,colormap,
				   XtNdepth,vinfo.depth,
				   NULL);
    XtOverrideTranslations(str_shell, XtParseTranslationTable
			   ("WM_PROTOCOLS: Popup()"));

    form = XtVaCreateManagedWidget("form", formWidgetClass, str_shell,
				   NULL);

    /* driver */
    button = XtVaCreateManagedWidget("driver", commandWidgetClass, form,
				     FIX_LEFT_TOP,
				     NULL);
    w_movie_driver = button;

    /* movie filename */
    label = XtVaCreateManagedWidget("vlabel", labelWidgetClass, form,
				    FIX_LEFT_TOP,
				    XtNfromVert, button,
				    NULL);
    text = XtVaCreateManagedWidget("vname", asciiTextWidgetClass, form,
				   FIX_LEFT_TOP,
				   XtNfromVert, label,
				   NULL);
    w_movie_fvideo = text;

    /* audio filename */
    label = XtVaCreateManagedWidget("alabel", labelWidgetClass, form,
				    FIX_LEFT_TOP,
				    XtNfromVert, text,
				    NULL);
    w_movie_flabel = label;
    text= XtVaCreateManagedWidget("aname", asciiTextWidgetClass, form,
				  FIX_LEFT_TOP,
				  XtNfromVert, label,
				  NULL);
    w_movie_faudio = text;

    /* audio format */
    button = XtVaCreateManagedWidget("audio", commandWidgetClass, form,
				     FIX_LEFT_TOP,
				     XtNfromVert, text,
				     NULL);
    w_movie_audio = button;
    button = XtVaCreateManagedWidget("rate", commandWidgetClass, form,
				     FIX_LEFT_TOP,
				     XtNfromVert, button,
				     NULL);
    w_movie_rate = button;

    /* video format */
    button = XtVaCreateManagedWidget("video", commandWidgetClass, form,
				     FIX_LEFT_TOP,
				     XtNfromVert, button,
				     NULL);
    w_movie_video = button;
    button = XtVaCreateManagedWidget("fps", commandWidgetClass, form,
				     FIX_LEFT_TOP,
				     XtNfromVert, button,
				     NULL);
    w_movie_fps = button;
    label = XtVaCreateManagedWidget("size", labelWidgetClass, form,
				    FIX_LEFT_TOP,
				    XtNfromVert, button,
				    NULL);
    w_movie_size = label;

    /* status line */
    label = XtVaCreateManagedWidget("status", labelWidgetClass, form,
				    FIX_LEFT_TOP,
				    XtNfromVert, label,
				    XtNlabel,    "",
				    NULL);
    w_movie_status = label;

    /* cmd buttons */
    button = XtVaCreateManagedWidget("streamer", commandWidgetClass, form,
				     FIX_LEFT_TOP,
				     XtNfromVert, label,
				     NULL);
    XtAddCallback(button,XtNcallback,exec_record,NULL);

    button = XtVaCreateManagedWidget("xanim", commandWidgetClass, form,
				     FIX_LEFT_TOP,
				     XtNfromVert, button,
				     NULL);
    XtAddCallback(button,XtNcallback,exec_player_cb,NULL);

#if 0
    label = XtVaCreateManagedWidget("olabel", labelWidgetClass, form,
				    FIX_LEFT_TOP,
				    XtNfromVert,button,
				    NULL);
    str_text = XtVaCreateManagedWidget("output", asciiTextWidgetClass, form,
				       XtNleft,XawChainLeft,
				       XtNright,XawChainRight,
				       XtNtop,XawChainTop,
				       XtNbottom,XawChainBottom,
				       XtNfromVert,label,
				       NULL);
#endif

    XtAddCallback(w_movie_driver,XtNcallback,menu_cb,(XtPointer)20);
    XtAddCallback(w_movie_audio,XtNcallback,menu_cb,(XtPointer)21);
    XtAddCallback(w_movie_rate,XtNcallback,menu_cb,(XtPointer)22);
    XtAddCallback(w_movie_video,XtNcallback,menu_cb,(XtPointer)23);
    XtAddCallback(w_movie_fps,XtNcallback,menu_cb,(XtPointer)24);
}

/*--- launcher window -----------------------------------------------------*/

static void
create_launchwin(void)
{
    launch_shell = XtVaAppCreateShell("Launcher", "Xawtv",
				     topLevelShellWidgetClass,
				     dpy,
				     XtNclientLeader,app_shell,
				     XtNvisual,vinfo.visual,
				     XtNcolormap,colormap,
				     XtNdepth,vinfo.depth,
				     NULL);
    XtOverrideTranslations(launch_shell, XtParseTranslationTable
			   ("WM_PROTOCOLS: Popup()"));
    launch_paned = XtVaCreateManagedWidget("paned", panedWidgetClass,
					  launch_shell, NULL);
}

/*--- main ---------------------------------------------------------------*/

int
main(int argc, char *argv[])
{
    int            i, min_width, min_height;
    unsigned long  freq;

    hello_world("xawtv");
    progname = strdup(argv[0]);

    /* toplevel */
    XtSetLanguageProc(NULL,NULL,NULL);
    app_shell = XtVaAppInitialize(&app_context, "Xawtv",
				  opt_desc, opt_count,
				  &argc, argv,
				  fallback_ressources,
				  NULL);
    dpy = XtDisplay(app_shell);
    init_atoms(dpy);

    /* command line args */
    ng_init();
    handle_cmdline_args();

    /* device scan */
    if (args.hwscan) {
	fprintf(stderr,"looking for available devices\n");
#ifdef HAVE_LIBXV
	xv_video_init(-1,1);
#endif
	grabber_scan();
    }

    /* look for a useful visual */
    visual_init("xawtv","Xawtv");

    /* remote display? */
    do_overlay = !args.remote;
    if (do_overlay)
	x11_check_remote();
    v4lconf_init();

    /* x11 stuff */
    XtAppAddActions(app_context,actionTable,
		    sizeof(actionTable)/sizeof(XtActionsRec));
    x11_misc_init(dpy);
    if (debug)
	fprintf(stderr,"main: dga extention...\n");
    xfree_dga_init(dpy);
    if (debug)
	fprintf(stderr,"main: xinerama extention...\n");
    xfree_xinerama_init(dpy);
#ifdef HAVE_LIBXV
    if (debug)
	fprintf(stderr,"main: xvideo extention [video]...\n");
    if (args.xv_video)
	xv_video_init(args.xv_port,0);
    if (debug)
	fprintf(stderr,"main: xvideo extention [image]...\n");
    if (args.xv_image)
	xv_image_init(dpy);
#endif

    /* set hooks (command.c) */
    update_title        = new_title;
    display_message     = new_message;
#if TT
    vtx_message         = display_vtx;
#endif
#ifdef HAVE_ZVBI
    vtx_subtitle        = display_subtitle;
#endif
    attr_notify         = new_attr;
    volume_notify       = new_volume;
    set_capture_hook    = do_capture;
    fullscreen_hook     = do_fullscreen;
    movie_hook          = do_movie_record;
    rec_status          = do_rec_status;
    exit_hook           = do_exit;
    capture_get_hook    = video_gd_suspend;
    capture_rel_hook    = video_gd_restart;

    if (debug)
	fprintf(stderr,"main: init main window...\n");
    tv = video_init(app_shell, &vinfo, simpleWidgetClass,
		    args.bpp, args.gl);
    XtAddEventHandler(XtParent(tv),StructureNotifyMask, True,
		      resize_event, NULL);
    if (debug)
	fprintf(stderr,"main: install signal handlers...\n");
    xt_siginit();
    if (NULL == drv) {
	if (debug)
	    fprintf(stderr,"main: open grabber device...\n");
	grabber_init();
    }

    if (f_drv & CAN_TUNE) {
	freqtab_notify      = new_freqtab;
	setfreqtab_notify   = new_freqtab;
	setstation_notify   = new_channel;
	channel_switch_hook = leaving_channel;
    } else {
	new_title("Capture");
    }

    /* create windows */
    XSetIOErrorHandler(x11_ctrl_alt_backspace);
    if (debug)
	fprintf(stderr,"main: checking wm...\n");
    wm_detect(dpy);
    if (debug)
	fprintf(stderr,"main: creating windows ...\n");
    create_optwin();
    create_onscreen(labelWidgetClass);
    create_vtx();
    create_chanwin();
    if ((f_drv & CAN_TUNE))
	create_confwin();
    create_strwin();
    create_launchwin();

    /* read config file + related settings */
    if (debug)
	fprintf(stderr,"main: init frequency tables ...\n");
    freq_init();
    if (args.readconfig) {
	if (debug)
	    fprintf(stderr,"main: read config file ...\n");
	read_config(args.conffile ? args.conffile : NULL, &argc, argv);
    }
    if (0 != strlen(mixerdev)) {
	struct ng_attribute *attr;
	if (debug)
	    fprintf(stderr,"main: open mixer device...\n");
	if (NULL != (attr = ng_mix_init(mixerdev,mixerctl)))
	    add_attrs(attr);
    }
    init_movie_menus();
    create_attr_widgets();

    xt_vm_randr_input_init(dpy);

    if (debug)
	fprintf(stderr,"main: mapping main window ...\n");
    XtRealizeWidget(app_shell);
    create_pointers(app_shell);
    create_bitmaps(app_shell);
    XDefineCursor(dpy, XtWindow(app_shell), left_ptr);
    XSetWMProtocols(XtDisplay(app_shell), XtWindow(app_shell),
		    &WM_DELETE_WINDOW, 1);

    drv->get_min_size(h_drv, &min_width, &min_height);
    ng_ratio_fixup2(&min_width, &min_height, NULL, NULL,
                    ng_ratio_x, ng_ratio_y, True);
    min_width  = ((min_width + (WIDTH_INC - 1)) / WIDTH_INC) * WIDTH_INC;
    min_height = ((min_height + (HEIGHT_INC - 1)) / HEIGHT_INC) * HEIGHT_INC;
    if (debug)
	fprintf(stderr,"main: window min size %dx%d\n", min_width, min_height);
    XtVaSetValues(app_shell,
		  XtNwidthInc,  WIDTH_INC,
		  XtNheightInc, HEIGHT_INC,
		  XtNminWidth,  min_width,
		  XtNminHeight, min_height,
		  NULL);
    if (f_drv & CAN_TUNE)
	XtVaSetValues(chan_shell,
		      XtNwidth,pix_width*pix_cols+30,
		      NULL);

    /* mouse pointer magic */
    XtAddEventHandler(tv, PointerMotionMask, True, mouse_event, NULL);
    mouse_event(tv,NULL,NULL,NULL);

    /* init hardware */
    if (debug)
	fprintf(stderr,"main: initialize hardware ...\n");
    attr_init();
    audio_on();
    audio_init();

    /* build channel list */
    if (args.readconfig) {
	if (debug)
	    fprintf(stderr,"main: parse config file ...\n");
	parse_config(f_drv & CAN_TUNE);
    }

    channel_menu();

    while (!window_configured)
        xt_handle_pending(dpy);
    init_overlay();

    set_property(0,NULL,NULL);
    if (optind+1 == argc && (f_drv & CAN_TUNE)) {
	do_va_cmd(2,"setstation",argv[optind]);
    } else if (f_drv & CAN_TUNE) {
	if (0 != (freq = drv->getfreq(h_drv))) {
	    for (i = 0; i < chancount; i++)
		if (chanlist[i].freq == freq*1000/16) {
		    do_va_cmd(2,"setchannel",chanlist[i].name);
		    break;
		}
	}
	if (-1 == cur_channel) {
	    if (count > 0) {
		if (debug)
		    fprintf(stderr,"main: tuning first station\n");
		do_va_cmd(2,"setstation","0");
	    } else {
		if (debug)
		    fprintf(stderr,"main: setting defaults\n");
		set_defaults();
	    }
	} else {
	    if (debug)
		fprintf(stderr,"main: known station tuned, not changing\n");
	}
    }
    XtAddEventHandler(tv,ExposureMask, True, tv_expose_event, NULL);

    if (args.fullscreen) {
	XSync(dpy,False);
	do_fullscreen();
    } else {
	XtAppAddWorkProc(app_context,MyResize,NULL);
    }

    sprintf(modename,"%dx%d, ",
	    XtScreen(app_shell)->width,XtScreen(app_shell)->height);
    strcat(modename,ng_vfmt_to_desc[x11_dpy_fmtid]);
    new_message(modename);
    if (!have_config)
	XtCallActionProc(tv,"Help",NULL,NULL,0);

    xt_main_loop();
    return 0;
}
xawtv-3.106/x11/xpm/000077500000000000000000000000001343350355000141125ustar00rootroot00000000000000xawtv-3.106/x11/xpm/exit.xpm000066400000000000000000000006551343350355000156170ustar00rootroot00000000000000/* XPM */
static char * exit_xpm[] = {
"16 16 3 1",
" 	c gray77",
".	c #000000000000",
"X	c #861782078617",
"                ",
"                ",
"       ..       ",
"       ..X      ",
"    .  ..X .    ",
"   ..X ..X ..   ",
"  ..X  ..X  ..  ",
"  ..X  ..X  ..X ",
"  ..X  ..X  ..X ",
"  ..X   XX  ..X ",
"  ..X       ..X ",
"   ..      ..XX ",
"    ........XX  ",
"     ......XX   ",
"      XXXXXX    ",
"                "};
xawtv-3.106/x11/xpm/home.xpm000066400000000000000000000006641343350355000155760ustar00rootroot00000000000000/* XPM */
static char * home_xpm[] = {
"16 16 3 1",
" 	c #C71BC71BC71B",
".	c #000000000000",
"X	c #861782078617",
"                ",
"       .        ",
"   .. ...       ",
"   ....X..      ",
"   ...XX ..     ",
"   ..XX   ..    ",
"  ..XX     ..   ",
" ...X      ...  ",
"  X.X ...  .XXX ",
"   .X . .X .X   ",
"   .X . .X .X   ",
"   .X . .X .X   ",
"   .X . .X .X   ",
"   .........X   ",
"    XXXXXXXXX   ",
"                "};
xawtv-3.106/x11/xpm/movie.xpm000066400000000000000000000006561343350355000157660ustar00rootroot00000000000000/* XPM */
static char * movie_xpm[] = {
"16 16 3 1",
" 	c gray77",
".	c #000000000000",
"X	c #861782078617",
"                ",
"                ",
"............... ",
". . . . . . . .X",
"...............X",
" X.XXXXXXX.XXXXX",
"  .X      .X    ",
"  .X      .X    ",
"  .X      .X    ",
"  .X      .X    ",
"............... ",
" . . . . . . . X",
"...............X",
" XXXXXXXXXXXXXXX",
"                ",
"                "};
xawtv-3.106/x11/xpm/mute.xpm000066400000000000000000000006551343350355000156200ustar00rootroot00000000000000/* XPM */
static char * mute_xpm[] = {
"16 16 3 1",
" 	c gray77",
".	c #000000000000",
"X	c #861782078617",
"                ",
"         .      ",
"        ..X     ",
"       . .X     ",
"      .  .X .   ",
" .....   .X .X  ",
" .       .X  .X ",
" .       .X  .X ",
" .       .X  .X ",
" .....   .X .XX ",
"  XXXX.  .X .X  ",
"       . .X  X  ",
"        ..X     ",
"         .X     ",
"          X     ",
"                "};
xawtv-3.106/x11/xpm/next.xpm000066400000000000000000000006551343350355000156240ustar00rootroot00000000000000/* XPM */
static char * next_xpm[] = {
"16 16 3 1",
" 	c gray77",
".	c #000000000000",
"X	c #868682828686",
"                ",
"                ",
"        .       ",
"        ..      ",
"        ...     ",
"        ....    ",
"  ...........   ",
"  ............  ",
"  ...........XX ",
"   XXXXX....XX  ",
"        ...XX   ",
"        ..XX    ",
"        .XX     ",
"         X      ",
"                ",
"                "};
xawtv-3.106/x11/xpm/prev.xpm000066400000000000000000000006551343350355000156220ustar00rootroot00000000000000/* XPM */
static char * prev_xpm[] = {
"16 16 3 1",
" 	c gray77",
".	c #000000000000",
"X	c #868682828686",
"                ",
"                ",
"      .         ",
"     ..X        ",
"    ...X        ",
"   ....X        ",
"  ...........   ",
" ............X  ",
"  ...........X  ",
"   ....XXXXXXX  ",
"    ...X        ",
"     ..X        ",
"      .X        ",
"       X        ",
"                ",
"                "};
xawtv-3.106/x11/xpm/snap.xpm000066400000000000000000000006551343350355000156070ustar00rootroot00000000000000/* XPM */
static char * snap_xpm[] = {
"16 16 3 1",
" 	c gray77",
".	c #000000000000",
"o	c #861782078617",
"                ",
"                ",
"                ",
" .............  ",
".  .   ....   . ",
".  .  .    .  .o",
".... .  ..  . .o",
".    . .  . . .o",
".    . .  . . .o",
".    .  ..  . .o",
".     .    .  .o",
".      ....   .o",
" .............oo",
"  ooooooooooooo ",
"                ",
"                "};
xawtv-3.106/x11/xpm/tv.xpm000066400000000000000000000025471343350355000153010ustar00rootroot00000000000000/* XPM */
static char * tv_xpm[] = {
"32 32 9 1",
" 	c none",
".	c #000000000000",
"X	c #861782078617",
"o	c #FFFF82070000",
"O	c #FFFFFFFF0000",
"+	c #0000FFFF0000",
"@	c #0000FFFFFFFF",
"#	c #FFFF00000000",
"$	c #00000000FFFF",
"                                ",
"                                ",
"                                ",
"      ..             ..         ",
"      ..X            ..X        ",
"       X.           .XXX        ",
"         .         .X           ",
"          .       .X            ",
"           .     .X             ",
"            .   .X              ",
"             . .X               ",
"    ......................      ",
"    ......................X     ",
"    ......ooOOO+++@@......XX    ",
"    ...##oooOOO+++@@@$$...XX    ",
"    ..###oooOOO+++@@@$$$..XX    ",
"    ..###oooOOO+++@@@$$$..XX    ",
"    ..###oooOOO+++@@@$$$..XX    ",
"    ..###oooOOO+++@@@$$$..XX    ",
"    ..###oooOOO+++@@@$$$..XX    ",
"    ..###oooOOO+++@@@$$$$.XX    ",
"    ..###oooOOO+++@@@$$$..XX    ",
"    ...##oooOOO+++@@@$$...XX    ",
"    ......ooOOO+++@@......XX    ",
"    ......................XX    ",
"    ......................XX    ",
"     XXXXXXXXXXXXXXXXXXXXXXX    ",
"      XXXXXXXXXXXXXXXXXXXXXX    ",
"                                ",
"                                ",
"                                ",
"                                "};
xawtv-3.106/x11/xt.c000066400000000000000000001541211343350355000141110ustar00rootroot00000000000000/*
 * common X11 stuff (mostly libXt level) moved here from main.c
 *
 *   (c) 1997-2003 Gerd Knorr 
 *
 */

#define _GNU_SOURCE

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#if defined(__linux__)
# include 
#include 
# include "videodev2.h"
#endif

#include "config.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "grab-ng.h"
#include "commands.h"
#include "sound.h"
#include "toolbox.h"
#include "xv.h"
#include "atoms.h"
#include "xt.h"
#include "x11.h"
#include "wmhooks.h"
#include "channel.h"
#include "capture.h"
#include "midictrl.h"
#include "lirc.h"
#include "joystick.h"
#include "vbi-data.h"
#include "blit.h"
#include "parseconfig.h"
#include "event.h"
#include "alsa_stream.h"
#include "get_media_devices.h"

/* jwz */
#include "remote.h"

/*----------------------------------------------------------------------*/

#define ALSA_LATENCY_DEFAULT 30
#define STR(X) __STR(X)
#define __STR(X) #X

XtAppContext      app_context;
Widget            app_shell, tv;
Widget            on_shell;
Display           *dpy;
int               stay_on_top = 0;

XVisualInfo       vinfo;
Colormap          colormap;

int               have_dga   = 0;
int               have_vm    = 0;
int               have_randr = 0;
int               fs = 0;

void              *movie_state;
int               movie_blit;

XtIntervalId      zap_timer,scan_timer;

#ifdef HAVE_LIBXXF86VM
int               vm_count;
XF86VidModeModeInfo **vm_modelines;
XF86VidModeModeLine vm_line;
int                 vm_dot;
#endif
#ifdef HAVE_LIBXINERAMA
XineramaScreenInfo *xinerama;
int                nxinerama;
#endif
#ifdef HAVE_LIBXRANDR
XRRScreenSize      *randr;
int                nrandr;
int                randr_evbase;
#endif
#if defined(HAVE_ALSA)
static char        *alsa_cap;
static char        *alsa_out;
#endif

static Widget on_label;
static XtIntervalId title_timer, on_timer;
static char default_title[256] = "???";

static int zap_start,zap_fast;

/*--- args ----------------------------------------------------------------*/

struct ARGS args;

XtResource args_desc[] = {
    /* name, class, type, size, offset, default_type, default_addr */
    {
	/* Strings */
	"device",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,device),
	XtRString, NULL
    },{
	"driver",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,driver),
	XtRString, NULL
    },{
	"dspdev",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,dspdev),
	XtRString, NULL
    },{
	"vbidev",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,vbidev),
	XtRString, NULL
    },{
	"joydev",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,joydev),
	XtRString, NULL
    },{
	"basename",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,basename),
	XtRString, "snap"
    },{
	"conffile",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,conffile),
	XtRString, NULL
    },{
	"alsa_cap",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,alsa_cap),
	XtRString, NULL
    },{
	"alsa_pb",
	XtCString, XtRString, sizeof(char*),
	XtOffset(struct ARGS*,alsa_pb),
	XtRString, NULL
    },{
	/* Integer */
	"alsa_latency",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,alsa_latency),
	XtRString, STR(ALSA_LATENCY_DEFAULT)
    },{
	/* Integer */
	"debug",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,debug),
	XtRString, "0"
    },{
	"bpp",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,bpp),
	XtRString, "0"
    },{
	"shift",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,shift),
	XtRString, "0"
    },{
	"xvport",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,xv_port),
	XtRString, "0"
    },{
	"parallel",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,parallel),
	XtRString, "1"
    },{
	"bufcount",
	XtCValue, XtRInt, sizeof(int),
	XtOffset(struct ARGS*,bufcount),
	XtRString, "16"
    },{
	/* Boolean */
	"remote",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,remote),
	XtRString, "0"
    },{
	"readconfig",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,readconfig),
	XtRString, "1"
    },{
	"fullscreen",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,fullscreen),
	XtRString, "0"
    },{
	"fbdev",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,fbdev),
	XtRString, "0"
    },{
	"xv",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,xv),
	XtRString, "1"
    },{
	"xvVideo",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,xv_video),
	XtRString, "1"
    },{
	"xvImage",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,xv_image),
	XtRString, "1"
    },{
	"gl",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,gl),
	XtRString, "1"
    },{
	"alsa",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,alsa),
	XtRString, "1"
    },{
	"vidmode",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,vidmode),
	XtRString, "1"
    },{
	"dga",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,dga),
	XtRString, "1"
    },{
	"randr",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,randr),
	XtRString, "1"
    },{
	"help",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,help),
	XtRString, "0"
    },{
	"hwscan",
	XtCBoolean, XtRBoolean, sizeof(int),
	XtOffset(struct ARGS*,hwscan),
	XtRString, "0"
    }
};

const int args_count = XtNumber(args_desc);

XrmOptionDescRec opt_desc[] = {
    { "-c",          "device",      XrmoptionSepArg, NULL },
    { "-device",     "device",      XrmoptionSepArg, NULL },
    { "-D",          "driver",      XrmoptionSepArg, NULL },
    { "-driver",     "driver",      XrmoptionSepArg, NULL },
    { "-C",          "dspdev",      XrmoptionSepArg, NULL },
    { "-dspdev",     "dspdev",      XrmoptionSepArg, NULL },
    { "-vbidev",     "vbidev",      XrmoptionSepArg, NULL },
    { "-joydev",     "joydev",      XrmoptionSepArg, NULL },
    { "-o",          "basename",    XrmoptionSepArg, NULL },
    { "-outfile",    "basename",    XrmoptionSepArg, NULL },
    { "-conffile",   "conffile",    XrmoptionSepArg, NULL },

    { "-v",          "debug",       XrmoptionSepArg, NULL },
    { "-debug",      "debug",       XrmoptionSepArg, NULL },
    { "-b",          "bpp",         XrmoptionSepArg, NULL },
    { "-bpp",        "bpp",         XrmoptionSepArg, NULL },
    { "-shift",      "shift",       XrmoptionSepArg, NULL },
    { "-xvport",     "xvport",      XrmoptionSepArg, NULL },
    { "-parallel",   "parallel",    XrmoptionSepArg, NULL },
    { "-bufcount",   "bufcount",    XrmoptionSepArg, NULL },

    { "-alsa-cap",   "alsa_cap",    XrmoptionSepArg, NULL },
    { "-alsa-pb",    "alsa_pb",     XrmoptionSepArg, NULL },
    { "-alsa-latency", "alsa_latency", XrmoptionSepArg, NULL },

    { "-remote",     "remote",      XrmoptionNoArg,  "1" },
    { "-n",          "readconfig",  XrmoptionNoArg,  "0" },
    { "-noconf",     "readconfig",  XrmoptionNoArg,  "0" },
    { "-f",          "fullscreen",  XrmoptionNoArg,  "1" },
    { "-fullscreen", "fullscreen",  XrmoptionNoArg,  "1" },
    { "-hwscan",     "hwscan",      XrmoptionNoArg,  "1" },
    { "-fb",         "fbdev",       XrmoptionNoArg,  "1" },

    { "-xv",         "xv",          XrmoptionNoArg,  "1" },
    { "-noxv",       "xv",          XrmoptionNoArg,  "0" },
    { "-xv-video",   "xvVideo",     XrmoptionNoArg,  "1" },
    { "-noxv-video", "xvVideo",     XrmoptionNoArg,  "0" },
    { "-xv-image",   "xvImage",     XrmoptionNoArg,  "1" },
    { "-noxv-image", "xvImage",     XrmoptionNoArg,  "0" },
    { "-gl",         "gl",          XrmoptionNoArg,  "1" },
    { "-nogl",       "gl",          XrmoptionNoArg,  "0" },

    { "-alsa",       "alsa",        XrmoptionNoArg,  "1" },
    { "-noalsa",     "alsa",        XrmoptionNoArg,  "0" },

    { "-vm",         "vidmode",     XrmoptionNoArg,  "1" },
    { "-novm",       "vidmode",     XrmoptionNoArg,  "0" },
    { "-dga",        "dga",         XrmoptionNoArg,  "1" },
    { "-nodga",      "dga",         XrmoptionNoArg,  "0" },
    { "-randr",      "randr",       XrmoptionNoArg,  "1" },
    { "-norandr",    "randr",       XrmoptionNoArg,  "0" },

    { "-h",          "help",        XrmoptionNoArg,  "1" },
    { "-help",       "help",        XrmoptionNoArg,  "1" },
    { "--help",      "help",        XrmoptionNoArg,  "1" },
};

const int opt_count = (sizeof(opt_desc)/sizeof(XrmOptionDescRec));
/*----------------------------------------------------------------------*/

Boolean
ExitWP(XtPointer client_data)
{
    /* exit if the application is idle,
     * i.e. all the DestroyCallback's are called.
     */
    exit(0);
}

void
ExitCB(Widget widget, XtPointer client_data, XtPointer calldata)
{
    static int exit_pending = 0;

    if (exit_pending)
	return;

    exit_pending = 1;
    audio_off();
    video_overlay(0);
    video_close();
    do_va_cmd(2,"capture", "off");
    if (fs)
	do_va_cmd(1,"fullscreen");
    XSync(dpy,False);
    drv->close(h_drv);
    XtAppAddWorkProc(app_context,ExitWP, NULL);
    XtDestroyWidget(app_shell);
}

void
do_exit(void)
{
    ExitCB(NULL,NULL,NULL);
}

void
CloseMainAction(Widget widget, XEvent *event,
		String *params, Cardinal *num_params)
{
    if (NULL != event && event->type == ClientMessage) {
	if (debug)
	    fprintf(stderr,"CloseMainAction: received %s message\n",
		    XGetAtomName(dpy,event->xclient.data.l[0]));
	if ((Atom)event->xclient.data.l[0] == WM_DELETE_WINDOW) {
	    /* fall throuth -- popdown window */
	} else {
	    /* whats this ?? */
	    return;
	}
    }
    ExitCB(widget,NULL,NULL);
}

void
RemoteAction(Widget widget, XEvent * event,
	     String * params, Cardinal * num_params)
{
    Atom            type;
    int             format, argc;
    unsigned int    i;
    char            *argv[32];
    unsigned long   nitems, bytesafter;
    unsigned char   *args = NULL;

    if (event->type == PropertyNotify) {
	if (debug > 1)
	    fprintf(stderr,"PropertyNotify %s\n",
		    XGetAtomName(dpy,event->xproperty.atom));
	if (event->xproperty.atom == _XAWTV_REMOTE &&
	    Success == XGetWindowProperty(dpy,
					  event->xproperty.window,
					  event->xproperty.atom,
					  0, (65536 / sizeof(long)),
					  True, XA_STRING,
					  &type, &format, &nitems, &bytesafter,
					  &args) &&
	    nitems != 0) {
	    for (i = 0, argc = 0; i <= nitems; i += strlen(args + i) + 1) {
		if (i == nitems || args[i] == '\0') {
		    argv[argc] = NULL;
		    do_command(argc,argv);
		    argc = 0;
		} else {
		    argv[argc++] = args+i;
		}
	    }
	    XFree(args);
	}
    }
}

static void
zap_timeout(XtPointer client_data, XtIntervalId *id)
{
    static int muted = 0;

    if (zap_fast && !cur_attrs[ATTR_ID_MUTE]) {
	/* mute for fast channel scan */
	muted = 1;
	do_va_cmd(2,"volume","mute","on");
    }
    /* pixit(); */
    do_va_cmd(2,"setstation","next");
    if (cur_sender != zap_start) {
	zap_timer = XtAppAddTimeOut
	    (app_context, zap_fast ? CAP_TIME : ZAP_TIME, zap_timeout,NULL);
    } else {
	if(muted) {
	    /* unmute */
	    muted = 0;
	    do_va_cmd(2,"volume","mute","off");
	}
    }
}

void
ZapAction(Widget widget, XEvent *event,
	  String *params, Cardinal *num_params)
{
    if (!(f_drv & CAN_TUNE))
	return;
    if (zap_timer) {
	XtRemoveTimeOut(zap_timer);
	zap_timer = 0;
#if 0
	strcpy(title,"channel hopping off");
	set_timer_title();
#endif
    } else {
	zap_start = (cur_sender == -1) ? 0 : cur_sender;
	zap_fast = 0;
	if (*num_params > 0) {
	    if (0 == strcasecmp(params[0],"fast"))
		zap_fast = 1;
	}
	if (count)
	    zap_timer = XtAppAddTimeOut
		(app_context, CAP_TIME, zap_timeout,NULL);
    }
}

static void
scan_timeout(XtPointer client_data, XtIntervalId *id)
{
    scan_timer = 0;

    /* check */
    if (!(f_drv & CAN_TUNE))
	return;
    if (drv->is_tuned(h_drv))
	return;

    do_va_cmd(2,"setchannel","next");
    scan_timer = XtAppAddTimeOut
	(app_context, SCAN_TIME, scan_timeout, NULL);
}

void
ScanAction(Widget widget, XEvent *event,
	   String *params, Cardinal *num_params)
{
    if (!(f_drv & CAN_TUNE))
	return;
    if (channel_switch_hook)
	channel_switch_hook();
    do_va_cmd(2,"setchannel","next");
    scan_timer = XtAppAddTimeOut
	(app_context, SCAN_TIME, scan_timeout,NULL);
}

void
RatioAction(Widget widget, XEvent *event,
	    String *params, Cardinal *num_params)
{
    int w,h;

    if (2 != *num_params)
	return;
    w = atoi(params[0]);
    h = atoi(params[1]);
    ng_ratio_x = w;
    ng_ratio_y = h;
    do_va_cmd(2,"capture","off");
    do_va_cmd(2,"capture","on");
}

/*--- onscreen display (fullscreen) --------------------------------------*/

void
create_onscreen(WidgetClass class)
{
    on_shell = XtVaCreateWidget("onscreen",transientShellWidgetClass,
				app_shell,
				XtNoverrideRedirect,True,
				XtNvisual,vinfo.visual,
				XtNcolormap,colormap,
				XtNdepth,vinfo.depth,
				NULL);
    on_label = XtVaCreateManagedWidget("label", class, on_shell,
				       NULL);
}

static void
popdown_onscreen(XtPointer client_data, XtIntervalId *id)
{
    if (debug)
	fprintf(stderr,"osd: hide\n");
    XtPopdown(on_shell);
    on_timer = 0;
}

static void
display_onscreen(char *title)
{
    static int first = 1;
    Dimension x,y;

    if (!fs)
	return;
    if (!use_osd)
	return;

    if (debug)
	fprintf(stderr,"osd: show (%s)\n",title);
    XtVaGetValues(app_shell,XtNx,&x,XtNy,&y,NULL);
    XtVaSetValues(on_shell,XtNx,x+osd_x,XtNy,y+osd_y,NULL);
    toolkit_set_label(on_label,title);
    XtPopup(on_shell, XtGrabNone);
    if (wm_stay_on_top && stay_on_top > 0)
	wm_stay_on_top(dpy,XtWindow(on_shell),1);
    if (on_timer)
	XtRemoveTimeOut(on_timer);
    on_timer = XtAppAddTimeOut
	(app_context, ONSCREEN_TIME, popdown_onscreen,NULL);

    if (first) {
	first = 0;
	XDefineCursor(dpy, XtWindow(on_shell), no_ptr);
	XDefineCursor(dpy, XtWindow(on_label), no_ptr);
    }
}

/*----------------------------------------------------------------------*/

Boolean
rec_work(XtPointer client_data)
{
    struct ng_video_buf *buf;

    if (movie_blit) {
	buf = NULL;
	movie_grab_put_video(movie_state, &buf);
	if (buf)
	    video_gd_blitframe(&vh,buf);
    } else {
	movie_grab_put_video(movie_state, NULL);
    }
    return False;
}

void
exec_done(int signal)
{
    int pid,stat;

    if (debug)
	fprintf(stderr,"got sigchild\n");
    pid = waitpid(-1,&stat,WUNTRACED|WNOHANG);
    if (debug) {
	if (-1 == pid) {
	    perror("waitpid");
	} else if (0 == pid) {
	    fprintf(stderr,"oops: got sigchild and waitpid returns 0 ???\n");
	} else if (WIFEXITED(stat)){
	    fprintf(stderr,"[%d]: normal exit (%d)\n",pid,WEXITSTATUS(stat));
	} else if (WIFSIGNALED(stat)){
	    fprintf(stderr,"[%d]: %s\n",pid,strsignal(WTERMSIG(stat)));
	} else if (WIFSTOPPED(stat)){
	    fprintf(stderr,"[%d]: %s\n",pid,strsignal(WSTOPSIG(stat)));
	}
    }
}

static void
exec_output(XtPointer data, int *fd, XtInputId * iproc)
{
    char buffer[81];
    int len;

    switch (len = read(*fd,buffer,80)) {
    case -1: /* error */
	perror("read pipe");
	/* fall */
    case 0:  /* EOF */
	close(*fd);
	XtRemoveInput(*iproc);
	break;
    default: /* got some bytes */
	buffer[len] = 0;
	fprintf(stderr,"%s",buffer);
	break;
    }
}

int
exec_x11(char **argv)
{
    int p[2],pid,i;

    if (debug) {
	fprintf(stderr,"exec: \"%s\"",argv[0]);
	for (i = 1; argv[i] != NULL; i++)
	    fprintf(stderr,", \"%s\"",argv[i]);
	fprintf(stderr,"\n");
    }
    pipe(p);
    switch (pid = fork()) {
    case -1:
	perror("fork");
	return -1;
    case 0:
	/* child */
	dup2(p[1],1);
	dup2(p[1],2);
	close(p[0]);
	close(p[1]);
	close(ConnectionNumber(dpy));
	execvp(argv[0],argv);
	fprintf(stderr,"exec %s: %s\n",argv[0],strerror(errno));
	exit(1);
    default:
	/* parent */
	close(p[1]);
	XtAppAddInput(app_context, p[0], (XtPointer) XtInputReadMask,
		      exec_output, NULL);
	break;
    }
    return pid;
}

void
exec_player(char *moviefile)
{
    //static char *command = "xanim +f +Sr +Ze -Zr";
    static char *command = "pia";
    char *cmd;
    char **argv;
    int  argc;

    /* go! */
    cmd = malloc(strlen(command)+strlen(moviefile)+5);
    sprintf(cmd,"%s %s",command,moviefile);
    argv = split_cmdline(cmd,&argc);
    exec_x11(argv);
}

void
LaunchAction(Widget widget, XEvent *event,
	    String *params, Cardinal *num_params)
{
    char **argv;
    int  i,argc;

    if (*num_params != 1)
	return;
    for (i = 0; i < nlaunch; i++) {
	if (0 == strcasecmp(params[0],launch[i].name))
	    break;
    }
    if (i == nlaunch)
	return;

    argv = split_cmdline(launch[i].cmdline,&argc);

    switch (fork()) {
    case -1:
	perror("fork");
	break;
    case 0:
	if (debug) {
	    fprintf(stderr,"[%d]: exec ",getpid());
	    for (i = 0; i < argc; i++) {
		fprintf(stderr,"\"%s\" ",argv[i]);
	    }
	    fprintf(stderr,"\n");
	}
	execvp(argv[0],argv);
	fprintf(stderr,"execvp %s: %s",argv[0],strerror(errno));
	exit(1);
	break;
    default:
	break;
    }
}

/*------------------------------------------------------------------------*/

XtSignalId sig_id;

static void termsig_handler(XtPointer data, XtSignalId *id)
{
    ExitCB(NULL,NULL,NULL);
}

static void
termsig(int signal)
{
    if (debug)
	fprintf(stderr,"received signal %d [%s]\n",signal,strsignal(signal));
    XtNoticeSignal(sig_id);
}

static void
segfault(int signal)
{
    fprintf(stderr,"[pid=%d] segfault catched, aborting\n",getpid());
    abort();
}

void
xt_siginit(void)
{
    struct sigaction act,old;

    memset(&act,0,sizeof(act));
    sigemptyset(&act.sa_mask);
    act.sa_handler  = exec_done;
    sigaction(SIGCHLD,&act,&old);

    sig_id = XtAppAddSignal(app_context,termsig_handler,NULL);
    act.sa_handler  = termsig;
    sigaction(SIGINT,&act,&old);
    sigaction(SIGTERM,&act,&old);

    act.sa_handler  = SIG_IGN;
    sigaction(SIGPIPE,&act,&old);

    if (debug) {
	act.sa_handler  = segfault;
	sigaction(SIGSEGV,&act,&old);
	fprintf(stderr,"main thread [pid=%d]\n",getpid());
    }
}

/*----------------------------------------------------------------------*/

static XtIntervalId xscreensaver_timer;

static void
xscreensaver_timefunc(XtPointer clientData, XtIntervalId *id)
{
    static int first = 1;
    int status;
    char *err;

    if (debug)
	fprintf(stderr,"xscreensaver_timefunc\n");
    xscreensaver_timer = 0;
    if (first) {
	xscreensaver_init(dpy);
	first = 0;
    }
    status = xscreensaver_command(dpy,XA_DEACTIVATE,0,debug,&err);
    if (0 != status) {
	if (debug)
	    fprintf(stderr,"xscreensaver_command: %s\n",err);
	return;
    }
    xscreensaver_timer = XtAppAddTimeOut(app_context,60000,
					 xscreensaver_timefunc,NULL);
}

/*----------------------------------------------------------------------*/

#ifdef HAVE_LIBXXF86VM
static void
vidmode_timer(XtPointer clientData, XtIntervalId *id)
{
    do_va_cmd(2,"capture", "on");
}

static void
set_vidmode(XF86VidModeModeInfo *mode)
{
    if (CAPTURE_OVERLAY == cur_capture) {
	do_va_cmd(2,"capture", "off");
	XtAppAddTimeOut(app_context,VIDMODE_DELAY,vidmode_timer,NULL);
    }
    /* usleep(VIDMODE_DELAY*1000); */
    if (debug)
	fprintf(stderr,"switching mode: %d  %d %d %d %d  %d %d %d %d  %d\n",
		mode->dotclock,
		mode->hdisplay,
		mode->hsyncstart,
		mode->hsyncend,
		mode->htotal,
		mode->vdisplay,
		mode->vsyncstart,
		mode->vsyncend,
		mode->vtotal,
		mode->flags);
    XF86VidModeSwitchToMode(dpy,XDefaultScreen(dpy),mode);
    XSync(dpy,False);
}

static void
do_vidmode_modeswitch(int fs_state, int *vp_width, int *vp_height)
{
    static int                  vm_switched;
    static XF86VidModeModeInfo  *vm_current    = NULL;
    static XF86VidModeModeInfo  *vm_fullscreen = NULL;
    int i;

    if (fs_state) {
	/* enter fullscreen mode */
	XF86VidModeGetModeLine(dpy,XDefaultScreen(dpy),&vm_dot,&vm_line);
	XF86VidModeGetAllModeLines(dpy,XDefaultScreen(dpy),
				   &vm_count,&vm_modelines);
	vm_fullscreen = NULL;
	for (i = 0; i < vm_count; i++) {
	    if (fs_width  == vm_modelines[i]->hdisplay &&
		fs_height == vm_modelines[i]->vdisplay &&
		vm_fullscreen == NULL)
		vm_fullscreen = vm_modelines[i];
	    if (vm_line.hdisplay == vm_modelines[i]->hdisplay &&
		vm_line.vdisplay == vm_modelines[i]->vdisplay &&
		vm_current == NULL)
		vm_current = vm_modelines[i];
	}
	if (debug) {
	    fprintf(stderr,"vm: current=%dx%d",
		    vm_current->hdisplay,vm_current->vdisplay);
	    if (vm_fullscreen)
		fprintf(stderr,"fullscreen=%dx%d",
			vm_fullscreen->hdisplay,vm_fullscreen->vdisplay);
	    fprintf(stderr,"\n");
	}
	if (vm_current && vm_fullscreen &&
	    vm_fullscreen->hdisplay != vm_current->hdisplay &&
	    vm_fullscreen->vdisplay != vm_current->vdisplay) {
	    set_vidmode(vm_fullscreen);
	    vm_switched = 1;
	    *vp_width   = vm_fullscreen->hdisplay;
	    *vp_height  = vm_fullscreen->vdisplay;
	} else {
	    vm_switched = 0;
	    *vp_width   = vm_current->hdisplay;
	    *vp_height  = vm_current->vdisplay;
	}
    } else {
	/* leave fullscreen mode */
	if (vm_switched) {
	    set_vidmode(vm_current);
	    vm_switched = 0;
	}
    }
}
#endif

#ifdef HAVE_LIBXRANDR
static void
do_randr_modeswitch(int fs_state, int *vp_width, int *vp_height)
{
    static SizeID normal;
    Window root = RootWindow(dpy, DefaultScreen(dpy));
    XRRScreenConfiguration *sc;
    Rotation rotation;
    SizeID current, new, i;

    sc = XRRGetScreenInfo(dpy, root);
    current = XRRConfigCurrentConfiguration(sc, &rotation);
    new = current;
    if (fs_state) {
	/* enter fullscreen mode */
	normal = current;
	new = current;
	for (i = 0; i < nrandr; i++) {
	    if (randr[i].width  == fs_width &&
		randr[i].height == fs_height) {
		new = i;
		break;
	    }
	}
    } else {
	/* leave fullscreen mode */
	new = normal;
    }

    if (new != current) {
	/* switch mode */
	if (debug)
	    fprintf(stderr, "randr: switch to %dx%d\n",
		    randr[new].width, randr[new].height);
	XRRSetScreenConfig(dpy, sc, root, new, rotation, CurrentTime);
    }
    XRRFreeScreenConfigInfo(sc);

    /* FIXME: change swidth / sheight instead */
    *vp_width  = randr[new].width;
    *vp_height = randr[new].height;
}
#endif

static void
do_modeswitch(int fs_state, int *vp_width, int *vp_height)
{
    *vp_width  = swidth;
    *vp_height = sheight;

#ifdef HAVE_LIBXXF86VM
    if (have_vm)
	do_vidmode_modeswitch(fs_state,vp_width,vp_height);
#endif
#ifdef HAVE_LIBXRANDR
    if (!have_vm && have_randr)
	do_randr_modeswitch(fs_state,vp_width,vp_height);
#endif
}

/*----------------------------------------------------------------------*/

Boolean
MyResize(XtPointer client_data)
{
    /* needed for program-triggered resizes (fullscreen mode) */
    video_new_size();
    return TRUE;
}

static void
do_screensaver(int fs_state)
{
    static int timeout,interval,prefer_blanking,allow_exposures;
#ifdef HAVE_LIBXDPMS
    static BOOL dpms_on;
    CARD16 dpms_state;
    int dpms_dummy;
#endif

    if (fs_state) {
	/* fullscreen on -- disable screensaver */
	XGetScreenSaver(dpy,&timeout,&interval,
			&prefer_blanking,&allow_exposures);
	XSetScreenSaver(dpy,0,0,DefaultBlanking,DefaultExposures);
#ifdef HAVE_LIBXDPMS
	if ((DPMSQueryExtension(dpy, &dpms_dummy, &dpms_dummy)) &&
	    (DPMSCapable(dpy))) {
	    DPMSInfo(dpy, &dpms_state, &dpms_on);
	    DPMSDisable(dpy);
	}
#endif
	xscreensaver_timer = XtAppAddTimeOut(app_context,60000,
					     xscreensaver_timefunc,NULL);
    } else {
	/* fullscreen off -- enable screensaver */
	XSetScreenSaver(dpy,timeout,interval,prefer_blanking,allow_exposures);
#ifdef HAVE_LIBXDPMS
	if ((DPMSQueryExtension(dpy, &dpms_dummy, &dpms_dummy)) &&
	    (DPMSCapable(dpy)) && (dpms_on)) {
		DPMSEnable(dpy);
	}
#endif
	if (xscreensaver_timer)
	    XtRemoveTimeOut(xscreensaver_timer);
    }
}

void
do_fullscreen(void)
{
    static Dimension x,y,w,h;
    static int rpx,rpy;
    static int warp_pointer;

    Window root,child;
    int    wpx,wpy,mask;
    unsigned int vp_width, vp_height;

    if (use_wm_fullscreen && wm_fullscreen) {
	/* full service for us, next to nothing to do */
	fs = !fs;
	if (debug)
	    fprintf(stderr,"fullscreen %s via netwm\n", fs ? "on" : "off");

	do_modeswitch(fs,&vp_width,&vp_height);
	XSync(dpy,False);
	wm_fullscreen(dpy,XtWindow(app_shell),fs);

	if (0 == fs  &&  on_timer) {
	    XtPopdown(on_shell);
	    XtRemoveTimeOut(on_timer);
	    on_timer = 0;
	}
	do_screensaver(fs);
	return;
    }

    if (fs) {
	if (debug)
	    fprintf(stderr,"turning fs off (%dx%d+%d+%d)\n",w,h,x,y);
	do_modeswitch(0,&vp_width,&vp_height);

	if (on_timer) {
	    XtPopdown(on_shell);
	    XtRemoveTimeOut(on_timer);
	    on_timer = 0;
	}

	XtVaSetValues(app_shell,
		      XtNwidthInc, WIDTH_INC,
		      XtNheightInc,HEIGHT_INC,
		      XtNx,        x + fs_xoff,
		      XtNy,        y + fs_yoff,
		      XtNwidth,    w,
		      XtNheight,   h,
		      NULL);

	do_screensaver(0);
	if (warp_pointer)
	    XWarpPointer(dpy, None, RootWindowOfScreen(XtScreen(tv)),
			 0, 0, 0, 0, rpx, rpy);
	fs = 0;
    } else {
	int vp_x, vp_y;

	if (debug)
	    fprintf(stderr,"turning fs on\n");
	XQueryPointer(dpy, RootWindowOfScreen(XtScreen(tv)),
		      &root, &child, &rpx, &rpy, &wpx, &wpy, &mask);

	vp_x = 0;
	vp_y = 0;
	do_modeswitch(1,&vp_width,&vp_height);
	if (vp_width < sheight || vp_width < swidth) {
	    /* move viewpoint, make sure the pointer is in there */
	    warp_pointer = 1;
	    XWarpPointer(dpy, None, RootWindowOfScreen(XtScreen(tv)),
			 0, 0, 0, 0, vp_width/2, vp_height/2);
#ifdef HAVE_LIBXXF86VM
	    XF86VidModeSetViewPort(dpy,XDefaultScreen(dpy),0,0);
#endif
	}
	XtVaGetValues(app_shell,
		      XtNx,          &x,
		      XtNy,          &y,
		      XtNwidth,      &w,
		      XtNheight,     &h,
		      NULL);

#ifdef HAVE_LIBXINERAMA
	if (nxinerama) {
	    /* check which physical screen we are visible on */
	    int i;
	    for (i = 0; i < nxinerama; i++) {
		if (x >= xinerama[i].x_org &&
		    y >= xinerama[i].y_org &&
		    x <  xinerama[i].x_org + xinerama[i].width &&
		    y <  xinerama[i].y_org + xinerama[i].height) {
		    vp_x      = xinerama[i].x_org;
		    vp_y      = xinerama[i].y_org;
		    vp_width  = xinerama[i].width;
		    vp_height = xinerama[i].height;
		    break;
		}
	    }
	}
#endif
	if (debug)
	    fprintf(stderr,"viewport: %dx%d+%d+%d\n",
		    vp_width,vp_height,vp_x,vp_y);

	XtVaSetValues(app_shell,
		      XtNwidthInc,   1,
		      XtNheightInc,  1,
		      NULL);
	XtVaSetValues(app_shell,
		      XtNx,          (vp_x & 0xfffc) + fs_xoff,
		      XtNy,          vp_y            + fs_yoff,
		      XtNwidth,      vp_width,
		      XtNheight,     vp_height,
		      NULL);

	XRaiseWindow(dpy, XtWindow(app_shell));
	do_screensaver(1);
	if (warp_pointer)
	    XWarpPointer(dpy, None, XtWindow(tv), 0, 0, 0, 0, 30, 15);
	fs = 1;
    }
    XtAppAddWorkProc (app_context, MyResize, NULL);
}

/*----------------------------------------------------------------------*/

static void
title_timeout(XtPointer client_data, XtIntervalId *id)
{
    keypad_timeout();
    XtVaSetValues(app_shell,XtNtitle,default_title,NULL);
    title_timer = 0;
}

void
new_title(char *txt)
{
    strcpy(default_title,txt);
    XtVaSetValues(app_shell,
		  XtNtitle,default_title,
		  XtNiconName,default_title,
		  NULL);
    display_onscreen(default_title);

    if (title_timer) {
	XtRemoveTimeOut(title_timer);
	title_timer = 0;
    }
}

void
new_message(char *txt)
{
    XtVaSetValues(app_shell,XtNtitle,txt,NULL);
    display_onscreen(txt);
    if (title_timer)
	XtRemoveTimeOut(title_timer);
    title_timer = XtAppAddTimeOut
	(app_context, TITLE_TIME, title_timeout,NULL);
}

/*
 * mode = -1: check mode (just update the title)
 * mode =  0: set autodetect (and read back result)
 * mode >  0: set some mode
 */
void
change_audio(int mode)
{
    struct ng_attribute *attr;
    const char *mname;
    char label[262];

    attr = ng_attr_byid(attrs,ATTR_ID_AUDIO_MODE);
    if (NULL == attr)
	return;

    if (-1 != mode)
	attr->write(attr,mode);
    if (-1 == mode || 0 == mode)
	mode = attr->read(attr);

    mname = ng_attr_getstr(attr,mode);
    if (NULL == mname)
	mname = "???";

    if (attr_notify)
	attr_notify(attr,mode);

    sprintf(label,"%s (%s)",default_title,mname);
    XtVaSetValues(app_shell,XtNtitle,label,NULL);
}

/*----------------------------------------------------------------------*/

void
CommandAction(Widget widget, XEvent *event,
	      String *params, Cardinal *num_params)
{
    do_command(*num_params,params);
}

void
set_property(int freq, char *channel, char *name)
{
    int  len;
    char line[80];

    len  = sprintf(line,"%.3f",(float)freq/16)+1;
    len += sprintf(line+len,"%s",channel ? channel : "?") +1;
    len += sprintf(line+len,"%s",name    ? name    : "?") +1;
    XChangeProperty(dpy, XtWindow(app_shell),
		    _XAWTV_STATION, XA_STRING,
		    8, PropModeReplace,
		    line, len);
}

void command_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
    struct DO_CMD *cmd = clientdata;
    do_command(cmd->argc,cmd->argv);
}

void tv_expose_event(Widget widget, XtPointer client_data,
		     XEvent *event, Boolean *d)
{
    static GC  gc;
    XGCValues  values;

    switch(event->type) {
    case Expose:
	if (debug)
	    fprintf(stderr,"expose count=%d\n",
		    event->xexpose.count);
	if (0 == event->xexpose.count && CAPTURE_OVERLAY == cur_capture) {
	    if (f_drv & NEEDS_CHROMAKEY) {
		Dimension win_width, win_height;
		if (debug)
		    fprintf(stderr,"expose: chromakey [%dx%d]\n",
			    cur_tv_width, cur_tv_height);
		if (0 == gc) {
		    XColor color;
		    color.red   = (ng_chromakey & 0x00ff0000) >> 8;
		    color.green = (ng_chromakey & 0x0000ff00);
		    color.blue  = (ng_chromakey & 0x000000ff) << 8;
		    XAllocColor(dpy,colormap,&color);
		    values.foreground = color.pixel;
		    gc = XCreateGC(dpy, XtWindow(widget), GCForeground,
				   &values);
		}
		/* draw background for chroma keying */
		XtVaGetValues(widget, XtNwidth, &win_width,
			      XtNheight, &win_height, NULL);
		XFillRectangle(dpy,XtWindow(widget),gc,
			       (win_width  - cur_tv_width)  >> 1,
			       (win_height - cur_tv_height) >> 1,
			       cur_tv_width, cur_tv_height);
	    }
	    if (have_xv) {
		if (debug)
		    fprintf(stderr,"expose: xv reblit\n");
		video_new_size();
	    }
	}
	break;
    }
}

void
FilterAction(Widget widget, XEvent *event,
	      String *params, Cardinal *num_params)
{
    struct list_head *item;
    struct ng_filter *filter;

    cur_filter = NULL;
    if (0 == *num_params)
	return;
    list_for_each(item,&ng_filters) {
	filter = list_entry(item, struct ng_filter, list);
	if (0 == strcasecmp(filter->name,params[0])) {
	    cur_filter = filter;
	    break;
	}
    }
}

/*----------------------------------------------------------------------*/
#ifdef HAVE_LIBXXF86DGA
static int xfree_dga_error_base;
#endif

#ifdef HAVE_LIBXXF86DGA
static int (*orig_xfree_error_handler)(Display *, XErrorEvent *);

static int xfree_dga_error_handler(Display *d, XErrorEvent *e)
{
  if (e->error_code == (xfree_dga_error_base + XF86DGANoDirectVideoMode) ||
      e->error_code == (xfree_dga_error_base + XF86DGAClientNotLocal)) {
    have_dga = 0;
    return 0;
  }
  return orig_xfree_error_handler(d, e);
}
#endif

void
xfree_dga_init(Display *dpy)
{
#ifdef HAVE_LIBXXF86DGA
    int  flags = 0,foo, ma, mi;

    if (!do_overlay)
	return;

    if (args.dga) {
	have_dga = 1;
	orig_xfree_error_handler = XSetErrorHandler(xfree_dga_error_handler);
	if (XF86DGAQueryExtension(dpy,&foo,&xfree_dga_error_base)) {
	    if (!have_dga)
		return;
	    XF86DGAQueryDirectVideo(dpy,XDefaultScreen(dpy),&flags);
	    if (flags & XF86DGADirectPresent) {
		XF86DGAQueryVersion(dpy,&ma,&mi);
		if (debug)
		    fprintf(stderr,"DGA version %d.%d\n",ma,mi);
	    } else {
		have_dga = 0;
	    }
	}
	XSetErrorHandler(orig_xfree_error_handler);
    }
#endif
}

void
xfree_vm_init(Display *dpy)
{
#ifdef HAVE_LIBXXF86VM
    int  foo,bar,i,ma,mi;

    if (!do_overlay)
	return;

    if (args.vidmode) {
	if (XF86VidModeQueryExtension(dpy,&foo,&bar)) {
	    XF86VidModeQueryVersion(dpy,&ma,&mi);
	    if (debug)
		fprintf(stderr,"VidMode  version %d.%d\n",ma,mi);
	    have_vm = 1;
	    XF86VidModeGetAllModeLines(dpy,XDefaultScreen(dpy),
				       &vm_count,&vm_modelines);
	    if (debug) {
		fprintf(stderr,"  available video mode(s):");
		for (i = 0; i < vm_count; i++) {
		    fprintf(stderr," %dx%d",
			    vm_modelines[i]->hdisplay,
			    vm_modelines[i]->vdisplay);
		}
		fprintf(stderr,"\n");
	    }
	}
    }
#endif
}

void
xfree_randr_init(Display *dpy)
{
#ifdef HAVE_LIBXRANDR
    int bar,i;

    if (args.randr) {
	if (XRRQueryExtension(dpy,&randr_evbase,&bar)) {
	    randr = XRRSizes(dpy,DefaultScreen(dpy),&nrandr);
	    if (nrandr > 0) {
		have_randr = 1;
		if (debug) {
		    fprintf(stderr,"xrandr:");
		    for (i = 0; i < nrandr; i++) {
			fprintf(stderr, " %dx%d",
				randr[i].width, randr[i].height);
		    }
		    fprintf(stderr,"\n");
		}
	    }
	}
    }
#endif
}

void
xfree_xinerama_init(Display *dpy)
{
#ifdef HAVE_LIBXINERAMA
    int foo,bar,i;

    if (XineramaQueryExtension(dpy,&foo,&bar) &&
	XineramaIsActive(dpy)) {
	xinerama = XineramaQueryScreens(dpy,&nxinerama);
	for (i = 0; i < nxinerama; i++) {
	    fprintf(stderr,"xinerama %d: %dx%d+%d+%d\n",
		    xinerama[i].screen_number,
		    xinerama[i].width,
		    xinerama[i].height,
		    xinerama[i].x_org,
		    xinerama[i].y_org);
	}
    }
#endif
}

#if defined(HAVE_ALSA)
static void x11_mute_notify(int val)
{
    if (val)
	alsa_thread_stop();
    else if (!alsa_thread_is_running()) {
        if (args.readconfig && args.alsa_latency == ALSA_LATENCY_DEFAULT) {
            int val = cfg_get_int("global", "alsa_latency");
            if (val > 0)
                args.alsa_latency = val;
        }
	alsa_thread_startup(alsa_out, alsa_cap, args.alsa_latency,
			    stderr, debug);
    }
}
#endif

void
grabber_init()
{
    struct ng_video_fmt screen;
    void *base = NULL;

    memset(&screen,0,sizeof(screen));
#ifdef HAVE_LIBXXF86DGA
    if (have_dga) {
	int bar,fred;
	orig_xfree_error_handler = XSetErrorHandler(xfree_dga_error_handler);
	if (!XF86DGAGetVideoLL(dpy,XDefaultScreen(dpy),(void*)&base,
			      &screen.bytesperline,&bar,&fred)) {
	    have_dga = 0;
	    memset(&screen,0,sizeof(screen));	/*  paranoia   */
	    base = NULL;			/*  paranoia   */
	}
	XSync(dpy, 0);
	XSetErrorHandler(orig_xfree_error_handler);
    }
#endif
    if (!do_overlay) {
	if (debug)
	    fprintf(stderr,"x11: remote display (overlay disabled)\n");
	drv = ng_vid_open(&args.device, args.driver, NULL, base, &h_drv);
    } else {
	screen.width  = XtScreen(app_shell)->width;
	screen.height = XtScreen(app_shell)->height;
	screen.fmtid  = x11_dpy_fmtid;
	screen.bytesperline *= ng_vfmt_to_depth[x11_dpy_fmtid]/8;
	if (debug)
	    fprintf(stderr,"x11: %dx%d, %d bit/pixel, %d byte/scanline%s%s\n",
		    screen.width,screen.height,
		    ng_vfmt_to_depth[screen.fmtid],
		    screen.bytesperline,
		    have_dga ? ", DGA"     : "",
		    have_vm  ? ", VidMode" : "");
	drv = ng_vid_open(&args.device, args.driver, &screen, base, &h_drv);
    }
    if (NULL == drv) {
	fprintf(stderr,"no video grabber device available\n");
	exit(1);
    }
    f_drv = drv->capabilities(h_drv);
    add_attrs(drv->list_attrs(h_drv));

#if defined(HAVE_ALSA)
    if (args.alsa) {
	/* Start audio capture thread */
	void *md = discover_media_devices();
	const char *p = strrchr(args.device, '/');
	if (p)
	    p++;
	else
	    p = args.device;

	if (args.alsa_cap)
	    alsa_cap = args.alsa_cap;
	else {
	    p = get_associated_device(md, NULL, MEDIA_SND_CAP,
				      p, MEDIA_V4L_VIDEO);
	    if (p)
		alsa_cap = strdup(p);
	}

	if (args.alsa_pb)
	    alsa_out = args.alsa_pb;
	else
	    alsa_out = "default";

	if (alsa_cap && alsa_out) {
	    fprintf(stderr, "Alsa devices: cap: %s (%s), out: %s\n",
		    alsa_cap, args.device, alsa_out);
	    mute_notify = x11_mute_notify;
	}

	free_media_devices(md);
    }
#endif
}

void
grabber_scan(void)
{
    const struct ng_vid_driver  *driver;
    void *handle;
    struct stat st;
    int n,i,fh,flags;

    for (i = 0; ng_dev.video_scan[i] != NULL; i++) {
	if (-1 == lstat(ng_dev.video_scan[i],&st)) {
	    if (ENOENT == errno)
		continue;
	    fprintf(stderr,"%s: %s\n",ng_dev.video_scan[i],strerror(errno));
	    continue;
	}
	fh = open(ng_dev.video_scan[i],O_RDWR);
	if (-1 == fh) {
	    if (ENODEV == errno)
		continue;
	    fprintf(stderr,"%s: %s\n",ng_dev.video_scan[i],strerror(errno));
	    continue;
	}
	close(fh);

	driver = ng_vid_open(&ng_dev.video_scan[i], args.driver,
			     NULL, NULL, &handle);
	if (NULL == driver) {
	    fprintf(stderr,"%s: initialization failed\n",ng_dev.video_scan[i]);
	    continue;
	}
	flags = driver->capabilities(handle);
	n = fprintf(stderr,"%s: OK",ng_dev.video_scan[i]);
	fprintf(stderr,"%*s[ -device %s ]\n",40-n,"",ng_dev.video_scan[i]);
	fprintf(stderr,"    type : %s\n",driver->name);
	if (driver->get_devname)
	    fprintf(stderr,"    name : %s\n",driver->get_devname(handle));
	fprintf(stderr,"    flags: %s %s %s %s\n",
		(flags & CAN_OVERLAY)     ? "overlay"   : "",
		(flags & CAN_CAPTURE)     ? "capture"   : "",
		(flags & CAN_TUNE)        ? "tuner"     : "",
		(flags & NEEDS_CHROMAKEY) ? "chromakey" : "");
	driver->close(handle);
	fprintf(stderr,"\n");
    }
    exit(0);
}

void
x11_check_remote()
{
#if defined(HAVE_GETNAMEINFO) && defined(HAVE_SOCKADDR_STORAGE)
    int fd = ConnectionNumber(dpy);
    struct sockaddr_storage ss;
    char me[INET6_ADDRSTRLEN+1];
    char peer[INET6_ADDRSTRLEN+1];
    char port[17];
    int length;

    if (debug)
	fprintf(stderr, "check if the X-Server is local ... ");

    /* me */
    length = sizeof(ss);
    if (-1 == getsockname(fd,(struct sockaddr*)&ss,&length)) {
	perror("getsockname");
	return;
    }
    if (debug)
	fprintf(stderr,"*");

    /* catch unix sockets on FreeBSD */
    if (0 == length || ss.ss_family == AF_UNIX) {
	if (debug)
	    fprintf(stderr, " ok (unix socket)\n");
	return;
    }

    getnameinfo((struct sockaddr*)&ss,length,
		me,INET6_ADDRSTRLEN,port,16,
		NI_NUMERICHOST | NI_NUMERICSERV);
    if (debug)
	fprintf(stderr,"*");

    /* peer */
    length = sizeof(ss);
    if (-1 == getpeername(fd,(struct sockaddr*)&ss,&length)) {
	perror("getsockname");
	return;
    }
    if (debug)
	fprintf(stderr,"*");

    getnameinfo((struct sockaddr*)&ss,length,
		peer,INET6_ADDRSTRLEN,port,16,
		NI_NUMERICHOST | NI_NUMERICSERV);
    if (debug)
	fprintf(stderr,"*");

    if (debug)
	fprintf(stderr," ok\nx11 socket: me=%s, server=%s\n",me,peer);
    if (0 != strcmp(me,peer))
	/* different hosts => assume remote display */
	do_overlay = 0;
#endif
    return;
}

void x11_misc_init(Display *dpy)
{
    fcntl(ConnectionNumber(dpy),F_SETFD,FD_CLOEXEC);
}

/*----------------------------------------------------------------------*/

void
visual_init(char *n1, char *n2)
{
    Visual         *visual;
    XVisualInfo    *vinfo_list;
    int            n;

    /* look for a useful visual */
    visual = x11_find_visual(XtDisplay(app_shell));
    vinfo.visualid = XVisualIDFromVisual(visual);
    vinfo_list = XGetVisualInfo(dpy, VisualIDMask, &vinfo, &n);
    vinfo = vinfo_list[0];
    XFree(vinfo_list);
    if (visual != DefaultVisualOfScreen(XtScreen(app_shell))) {
	fprintf(stderr,"switching visual (0x%lx)\n",vinfo.visualid);
	colormap = XCreateColormap(dpy,RootWindowOfScreen(XtScreen(app_shell)),
				   vinfo.visual,AllocNone);
	XtDestroyWidget(app_shell);
	app_shell = XtVaAppCreateShell(n1,n2,
				       applicationShellWidgetClass, dpy,
				       XtNvisual,vinfo.visual,
				       XtNcolormap,colormap,
				       XtNdepth, vinfo.depth,
				       NULL);
    } else {
	colormap = DefaultColormapOfScreen(XtScreen(app_shell));
    }
    x11_init_visual(XtDisplay(app_shell),&vinfo);
}

void
v4lconf_init()
{
    if (!do_overlay)
	return;

    strcpy(ng_v4l_conf,"v4l-conf");
    if (!args.debug)
	strcat(ng_v4l_conf," -q");
    if (args.fbdev)
	strcat(ng_v4l_conf," -f");
    if (args.shift)
	sprintf(ng_v4l_conf+strlen(ng_v4l_conf)," -s %d",args.shift);
    if (args.bpp)
	sprintf(ng_v4l_conf+strlen(ng_v4l_conf)," -b %d",args.bpp);
}

static void
usage(void)
{
    fprintf(stderr,
	    "\n"
	    "usage: xawtv [ options ] [ station ]\n"
	    "options:\n"
	    "  -h  -help           print this text\n"
	    "  -v  -debug n        debug level n, n = [0..2]\n"
	    "      -remote         assume remote display\n"
	    "  -n  -noconf         don't read the config file\n"
	    "  -m  -nomouse        startup with mouse pointer disabled\n"
	    "  -f  -fullscreen     startup in fullscreen mode\n"
#ifdef HAVE_LIBXXF86DGA
	    "      -(no)dga        enable/disable DGA extention\n"
#endif
#ifdef HAVE_LIBXXF86VM
	    "      -(no)vm         enable/disable VidMode extention\n"
#endif
#ifdef HAVE_LIBXRANDR
	    "      -(no)randr      enable/disable Xrandr extention\n"
#endif
#ifdef HAVE_LIBXV
	    "      -(no)xv         enable/disable Xvideo extention altogether\n"
	    "      -(no)xv-video   enable/disable Xvideo extention (for video only,\n"
	    "                      i.e. XvPutVideo() calls)\n"
	    "      -(no)xv-image   enable/disable Xvideo extention (for image scaling\n"
	    "                      only, i.e. XvPutImage() calls)\n"
#endif
#ifdef HAVE_GL
	    "      -(no)gl         enable/disable OpenGL\n"
#endif
#ifdef HAVE_ALSA
	    "      -(no)alsa       enable/disable alsa streaming. Default: enabled\n"
	    "      -(no)alsa-cap   manually specify an alsa capture interface\n"
	    "      -(no)alsa-pb    manually specify an alsa playback interface\n"
	    "      -alsa-latency   manually specify an alsa latency in ms. Default: " STR(ALSA_LATENCY_DEFAULT) "\n"
#endif
	    "  -b  -bpp n          color depth of the display is n (n=24,32)\n"
	    "  -o  -outfile file   filename base for snapshots\n"
	    "  -c  -device file    use  as video4linux device\n"
	    "  -D  -driver name    use  as video4linux driver\n"
	    "  -C  -dspdev file    use  as audio (oss) device\n"
	    "      -vbidev file    use  as vbi device\n"
	    "      -joydev file    use  as joystick device\n"
	    "      -shift x        shift display by x bytes\n"
	    "      -fb             let fb (not X) set up v4l device\n"
	    "      -parallel n     use n compression threads\n"
	    "      -bufcount n     use n video buffers\n"
	    "      -hwscan         print a list of available devices.\n"
	    "station:\n"
	    "  this is one of the stations listed in $HOME/.xawtv\n"
	    "\n"
	    "Check the manual page for a more detailed description.\n"
	    "\n"
	    "--\n"
	    "Gerd Knorr \n");
}

void
hello_world(char *name)
{
    struct utsname uts;

    if (0 == geteuid() && 0 != getuid()) {
	fprintf(stderr,"%s *must not* be installed suid root\n",name);
	exit(1);
    }

    uname(&uts);
    fprintf(stderr,"This is %s-%s, running on %s/%s (%s)\n",
	    name,VERSION,uts.sysname,uts.machine,uts.release);
}

void
handle_cmdline_args(void)
{
    XtGetApplicationResources(app_shell,&args,
			      args_desc,args_count,
			      NULL,0);
    if (args.help) {
	usage();
	exit(0);
    }
    snapbase = args.basename;
    debug    = args.debug;
    ng_debug = args.debug;

    if (0 == args.xv) {
	args.xv_video = 0;
	args.xv_image = 0;
    }
    if (NULL == args.dspdev)
	args.dspdev = ng_dev.dsp;
    if (NULL == args.vbidev)
	args.vbidev = ng_dev.vbi;
    if (args.device || args.driver)
	args.xv_video = 0;
    if (NULL == args.device)
	args.device = "auto";
    if (NULL == args.driver)
	args.driver = ng_dev.driver;
    if (0 != args.xv_port)
	args.xv_video = 1;
}

int
x11_ctrl_alt_backspace(Display *dpy)
{
    fprintf(stderr,"game over\n");
    if (debug)
	abort();
    audio_off();
    video_overlay(0);
    video_close();
    drv->close(h_drv);
    exit(0);
}

/*----------------------------------------------------------------------*/

static int mouse_visible;
static XtIntervalId mouse_timer;

static void
mouse_timeout(XtPointer clientData, XtIntervalId *id)
{
    Widget widget = clientData;
    if (debug > 1)
	fprintf(stderr,"xt: pointer hide\n");
    if (XtWindow(widget))
	XDefineCursor(dpy, XtWindow(widget), no_ptr);
    mouse_visible = 0;
    mouse_timer = 0;
}

void
mouse_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d)
{
    if (!mouse_visible) {
	if (debug > 1)
	    fprintf(stderr,"xt: pointer show\n");
	if (XtWindow(widget))
	    XDefineCursor(dpy, XtWindow(widget), left_ptr);
	mouse_visible = 1;
    }
    if (mouse_timer)
	XtRemoveTimeOut(mouse_timer);
    mouse_timer = XtAppAddTimeOut(app_context, 1000, mouse_timeout,widget);
}

/*----------------------------------------------------------------------*/

#if TT
static char *vtx_colors[8] = { "black", "red", "green", "yellow",
			       "blue", "magenta", "cyan", "white" };
#endif

#ifdef HAVE_ZVBI
static XtInputId x11_vbi_input;
static struct vbi_state *x11_vbi;
static int x11_vbi_page;
char x11_vbi_station[64];

#if 0
static struct TEXTELEM*
vtx_to_tt(struct vt_page *vtp)
{
    static struct TEXTELEM tt[VTX_COUNT];
    int t,x,y,color,lcolor;
    struct fmt_page pg[1];
    struct fmt_char l[W+2];
#define L (l+1)

    t = 0;
    fmt_page(fmt,pg,vtp);
    memset(tt,0,sizeof(tt));
    for (y = 0; y < H; y++) {
	for (x = 0; x < W; x++) {
	    struct fmt_char c = pg->data[y][x];
	    switch (c.ch) {
	    case 0x00:
	    case 0xa0:
		c.ch = ' ';
		break;
	    case 0x7f:
		c.ch = '*';
		break;
	    case BAD_CHAR:
		c.ch = '?';
		break;
	    default:
		if (c.attr & EA_GRAPHIC)
		    c.ch = '#';
		break;
	    }
	    L[x] = c;
	}

	/* delay fg and attr changes as far as possible */
	for (x = 0; x < W; ++x)
	    if (L[x].ch == ' ') {
		L[x].fg = L[x-1].fg;
		L[x].attr = L[x-1].attr;
	    }

	/* move fg and attr changes to prev bg change point */
	for (x = W-1; x >= 0; x--)
	    if (L[x].ch == ' ' && L[x].bg == L[x+1].bg) {
		L[x].fg = L[x+1].fg;
		L[x].attr = L[x+1].attr;
	    }

	/* now render the line */
	lcolor = -1;
	tt[t].line = y;
	tt[t].len  = 0;
	for (x = 0; x < W; x++) {
	    color = (L[x].fg&0x0f) * 10 + (L[x].bg&0x0f);
	    if (color != lcolor) {
		if (-1 != lcolor)
		    if (tt[t].len) {
			t++;
			tt[t].line = y;
		    }
		lcolor = color;
	    }
	    tt[t].str[tt[t].len++] = L[x].ch;
	    tt[t].fg = vtx_colors[L[x].fg&0x0f];
	    tt[t].bg = vtx_colors[L[x].bg&0x0f];
	}
	if (tt[t].len)
	    t++;
    }
    return tt;
}

#define EMPTY_VBI_LINE "                                        "
static struct TEXTELEM*
tt_pick_subtitle(struct TEXTELEM *tt)
{
    int i;

    /* skip header line */
    while (tt->len && 0 == tt->line)
	tt++;
    /* rm empty lines (from top) */
    while (tt->len &&
	   0 == strcmp(tt->str,EMPTY_VBI_LINE))
	tt++;

    if (tt->len) {
	/* seek to end */
	for (i = 0; tt[i].len != 0; i++)
	    ;
	/* rm empty lines (from bottom) */
	while (0 == strcmp(tt[i-1].str,EMPTY_VBI_LINE))
	    i--;
	tt[i].len = 0;
    }

    return tt;
}

static void
dump_tt(struct TEXTELEM *tt)
{
    int i,lastline = 0;

    lastline = tt[0].line;
    for (i = 0; tt[i].len > 0; i++) {
	if (tt[i].line != lastline) {
	    lastline = tt[i].line;
	    fprintf(stderr,"\n");
	}
	fprintf(stderr,"[%s,%s,%d]%s",
		tt[i].fg ? tt[i].fg : "def",
		tt[i].bg ? tt[i].bg : "def",
		tt[i].line,tt[i].str);
    }
    fprintf(stderr,"\n");
}
#endif

static void
x11_vbi_event(struct vbi_event *ev, void *user)
{
    struct vbi_page pg;
    struct vbi_rect rect;

    switch (ev->type) {
    case VBI_EVENT_NETWORK:
	strcpy(x11_vbi_station,ev->ev.network.name);
	break;
    case VBI_EVENT_TTX_PAGE:
	if (ev->ev.ttx_page.pgno == x11_vbi_page) {
	    if (debug)
		fprintf(stderr,"got vtx page %03x\n",ev->ev.ttx_page.pgno);
	    if (vtx_subtitle) {
		vbi_fetch_vt_page(x11_vbi->dec,&pg,
				  ev->ev.ttx_page.pgno,
				  ev->ev.ttx_page.subno,
				  VBI_WST_LEVEL_1p5,25,1);
		vbi_find_subtitle(&pg,&rect);
		if (25 == rect.y1)
		    vtx_subtitle(NULL,NULL);
		else
		    vtx_subtitle(&pg,&rect);
	    }
	}
	break;
    }
}

static void x11_vbi_data(XtPointer data, int *fd, XtInputId *iproc)
{
    struct vbi_state *vbi = data;
    vbi_hasdata(vbi);
}

int
x11_vbi_start(char *device)
{
    if (NULL != x11_vbi)
	return 0;

    if (NULL == device)
	device = ng_dev.vbi;

    x11_vbi = vbi_open(device, debug, 0);
    if (NULL == x11_vbi) {
	fprintf(stderr,"open %s: %s\n",device,strerror(errno));
	return -1;
    }
    vbi_event_handler_add(x11_vbi->dec,~0,x11_vbi_event,x11_vbi);
    x11_vbi_input = XtAppAddInput(app_context,x11_vbi->fd,
				  (XtPointer) XtInputReadMask,
				  x11_vbi_data,x11_vbi);
    if (debug)
	fprintf(stderr,"x11_vbi_start\n");
    return 0;
}

/* try to use the vbi device to see whenever we have a station or not.
 * failing that, fallback to the libng grabber driver. */
int
x11_vbi_tuned(void)
{
#if defined(__linux__)
    struct v4l2_tuner tuner;

    if (NULL == x11_vbi)
	return drv->is_tuned(h_drv);

    memset (&tuner, 0, sizeof(tuner));

    if (-1 != ioctl(x11_vbi->fd, VIDIOC_G_TUNER, &tuner))
	return tuner.signal ? 1 : 0;
#endif
    return drv->is_tuned(h_drv);
}

void
x11_vbi_stop(void)
{
    if (NULL == x11_vbi)
	return;
    XtRemoveInput(x11_vbi_input);
    vbi_event_handler_remove(x11_vbi->dec,x11_vbi_event);
    vbi_close(x11_vbi);
    x11_vbi = NULL;
    if (debug)
	fprintf(stderr,"x11_vbi_stop\n");
}

void
VtxAction(Widget widget, XEvent *event,
	  String *params, Cardinal *num_params)
{
    if (0 == *num_params)
	return;
    if (0 == strcasecmp(params[0],"start")) {
	if (2 >= *num_params)
	    sscanf(params[1],"%x",&x11_vbi_page);
	if (debug)
	    fprintf(stderr,"subtitles page: %x\n",x11_vbi_page);
	x11_vbi_start(args.vbidev);
    }
    if (0 == strcasecmp(params[0],"stop")) {
	x11_vbi_page = 0;
	x11_vbi_stop();
#if TT
	if (vtx_message)
	    vtx_message(NULL);
#endif
#ifdef HAVE_ZVBI
	if (vtx_subtitle)
	    vtx_subtitle(NULL,NULL);
#endif
    }
}
#endif

/* ---------------------------------------------------------------------- */
/* control via lirc / midi / joystick                                     */

static int xt_lirc;

static void
xt_lirc_data(XtPointer data, int *fd, XtInputId *iproc)
{
    if (debug)
	fprintf(stderr,"lirc_input triggered\n");
    if (-1 == lirc_tv_havedata()) {
	fprintf(stderr,"lirc: connection lost\n");
	XtRemoveInput(*iproc);
	close(*fd);
    }
}

int xt_lirc_init(void)
{
    if (-1 != (xt_lirc = lirc_tv_init()))
	XtAppAddInput(app_context,xt_lirc,(XtPointer)XtInputReadMask,
		      xt_lirc_data,NULL);
    return 0;
}

#ifdef HAVE_ALSA
static struct midi_handle xt_midi;

static void
xt_midi_data(XtPointer data, int *fd, XtInputId *iproc)
{
    midi_read(&xt_midi);
    midi_translate(&xt_midi);
}
#endif

int xt_midi_init(char *dev)
{
    if (NULL == dev)
	return -1;

#ifdef HAVE_ALSA
    memset(&xt_midi,0,sizeof(xt_midi));
    if (-1 == midi_open(&xt_midi, "xawtv"))
	return -1;
    midi_connect(&xt_midi,dev);
    XtAppAddInput(app_context,xt_midi.fd,(XtPointer) XtInputReadMask,
		  xt_midi_data,NULL);
    return 0;
#else
    fprintf(stderr,"midi: not compiled in, sorry\n");
    return -1;
#endif
}

static int xt_joystick;

static void
xt_joystick_data(XtPointer data, int *fd, XtInputId *iproc)
{
    joystick_tv_havedata(xt_joystick);
}

int xt_joystick_init(void)
{
    if (-1 != (xt_joystick = joystick_tv_init(args.joydev)))
	XtAppAddInput(app_context,xt_joystick,(XtPointer)XtInputReadMask,
		      xt_joystick_data,NULL);
    return 0;
}

/* ---------------------------------------------------------------------- */

void xt_kbd_init(Widget tv)
{
    char **list,key[32],str[128];

    list = cfg_list_entries("eventmap");
    if (NULL == list)
	return;

    for (; *list != NULL; list++) {
	if (1 != sscanf(*list,"kbd-key-%31s",key))
	    continue;
	sprintf(str,"%s: Event(%s)",key,*list);
	XtOverrideTranslations(tv,XtParseTranslationTable(str));
    }
}

void
EventAction(Widget widget, XEvent *event,
	    String *params, Cardinal *num_params)
{
    if (0 != *num_params)
	event_dispatch(params[0]);
}

/* ---------------------------------------------------------------------- */

Cursor left_ptr;
Cursor menu_ptr;
Cursor qu_ptr;
Cursor no_ptr;

Pixmap bm_yes;
Pixmap bm_no;

static unsigned char bm_yes_data[] = {
    /* -------- -------- */  0x00,
    /* -------- -------- */  0x00,
    /* ------xx xx------ */  0x18,
    /* ----xxxx xxxx---- */  0x3c,
    /* ----xxxx xxxx---- */  0x3c,
    /* ------xx xx------ */  0x18,
    /* -------- -------- */  0x00,
    /* -------- -------- */  0x00
};

static unsigned char bm_no_data[] = { 0,0,0,0, 0,0,0,0 };

void
create_pointers(Widget app_shell)
{
    XColor white,red,dummy;

    left_ptr = XCreateFontCursor(dpy,XC_left_ptr);
    menu_ptr = XCreateFontCursor(dpy,XC_right_ptr);
    qu_ptr   = XCreateFontCursor(dpy,XC_question_arrow);
    if (vinfo.depth > 1) {
	if (XAllocNamedColor(dpy,colormap,"white",&white,&dummy) &&
	    XAllocNamedColor(dpy,colormap,"red",&red,&dummy)) {
	    XRecolorCursor(dpy,left_ptr,&red,&white);
	    XRecolorCursor(dpy,menu_ptr,&red,&white);
	    XRecolorCursor(dpy,qu_ptr,&red,&white);
	}
    }
}

void
create_bitmaps(Widget app_shell)
{
    XColor black, dummy;

    bm_yes = XCreateBitmapFromData(dpy, XtWindow(app_shell),
				   bm_yes_data, 8,8);
    bm_no = XCreateBitmapFromData(dpy, XtWindow(app_shell),
				  bm_no_data, 8,8);

    XAllocNamedColor(dpy,colormap,"black",&black,&dummy);
    no_ptr = XCreatePixmapCursor(dpy, bm_no, bm_no,
				 &black, &black,
				 0, 0);
}

/* ---------------------------------------------------------------------- */

int xt_handle_pending(Display *dpy)
{
    XEvent event;

    if (debug)
	fprintf(stderr,"xt: handle_pending:  start ...\n");
    XFlush(dpy);
    while (True == XCheckMaskEvent(dpy, ~0, &event))
	XtDispatchEvent(&event);
    if (debug)
	fprintf(stderr,"xt: handle_pending:  ... done\n");
    return 0;
}

/* ---------------------------------------------------------------------- */

int xt_vm_randr_input_init(Display *dpy)
{
    /* vidmode / randr */
    if (debug)
	fprintf(stderr,"xt: checking for randr extention ...\n");
    xfree_randr_init(dpy);
    if (debug)
	fprintf(stderr,"xt: checking for vidmode extention ...\n");
    xfree_vm_init(dpy);

    /* input */
    if (debug)
	fprintf(stderr,"xt: checking for lirc ...\n");
    xt_lirc_init();
    if (debug)
	fprintf(stderr,"xt: checking for joystick ...\n");
    xt_joystick_init();
    if (debug)
	fprintf(stderr,"xt: checking for midi ...\n");
    xt_midi_init(midi);
    if (debug)
	fprintf(stderr,"xt: adding kbd hooks ...\n");
    xt_kbd_init(tv);

    return 0;
}

int xt_main_loop()
{
    XEvent event;

    if (debug)
	fprintf(stderr,"xt: enter main event loop... \n");
    signal(SIGHUP,SIG_IGN); /* don't really need a tty ... */

    for (;;) {
	if (XtAppGetExitFlag(app_context))
	    break;
	XtAppNextEvent(app_context, &event);
	if (True == XtDispatchEvent(&event))
	    continue;
    }
    return 0;
}
xawtv-3.106/x11/xt.h000066400000000000000000000136441343350355000141220ustar00rootroot00000000000000#include 
#include 
#ifdef HAVE_LIBXXF86DGA
# include 
# include 
#endif
#ifdef HAVE_LIBXXF86VM
# include 
# include 
#endif
#ifdef HAVE_LIBXINERAMA
# include 
#endif
#ifdef HAVE_LIBXV
# include 
# include 
#endif
#ifdef HAVE_LIBXRANDR
# include 
#endif
#ifdef HAVE_LIBXDPMS
# include 
/* XFree 3.3.x has'nt prototypes for this ... */
Bool   DPMSQueryExtension(Display*, int*, int*);
Bool   DPMSCapable(Display*);
Status DPMSInfo(Display*, CARD16*, BOOL*);
Status DPMSEnable(Display*);
Status DPMSDisable(Display*);
#endif

struct ARGS {
    /* char */
    char *device;
    char *driver;
    char *dspdev;
    char *vbidev;
    char *joydev;
    char *basename;
    char *conffile;
    char *alsa_cap;
    char *alsa_pb;

    /* int */
    int  debug;
    int  bpp;
    int  shift;
    int  xv_port;
    int  parallel;
    int  bufcount;
    int  alsa_latency; /* In ms */

    /* boolean */
    int  remote;
    int  readconfig;
    int  fullscreen;
    int  fbdev;
    int  xv;
    int  xv_video;
    int  xv_image;
    int  gl;
    int  alsa;
    int  vidmode;
    int  dga;
    int  randr;
    int  help;
    int  hwscan;
};

extern struct ARGS args;
extern XtResource args_desc[];
extern XrmOptionDescRec opt_desc[];

extern const int args_count;
extern const int opt_count;

/*----------------------------------------------------------------------*/

extern XtAppContext      app_context;
extern Widget            app_shell, tv;
extern Widget            on_shell;
extern Display           *dpy;
extern int               stay_on_top;

extern XVisualInfo       vinfo;
extern Colormap          colormap;

extern int               have_dga;
extern int               have_vm;
extern int               have_randr;
extern int               fs;

extern void              *movie_state;
extern int               movie_blit;

extern XtIntervalId      zap_timer,scan_timer;

#ifdef HAVE_LIBXXF86VM
extern int               vm_count;
extern XF86VidModeModeInfo **vm_modelines;
#endif
#ifdef HAVE_LIBXINERAMA
extern XineramaScreenInfo *xinerama;
extern int                nxinerama;
#endif
#ifdef HAVE_LIBXRANDR
extern XRRScreenSize      *randr;
extern int                nrandr;
#endif

extern char v4l_conf[128];

#define ZAP_TIME            8000
#define CAP_TIME             100
#define SCAN_TIME            100

#define ONSCREEN_TIME       5000
#define TITLE_TIME          6000
#define WIDTH_INC             32
#define HEIGHT_INC            24
#define VIDMODE_DELAY        100   /* 0.1 sec */

/*----------------------------------------------------------------------*/

/* defined in main.c / motif.c */
void toolkit_set_label(Widget widget, char *str);

/*----------------------------------------------------------------------*/

Boolean ExitWP(XtPointer client_data);
void ExitCB(Widget widget, XtPointer client_data, XtPointer calldata);
void do_exit(void);
void CloseMainAction(Widget widget, XEvent *event,
		     String *params, Cardinal *num_params);
void ZapAction(Widget, XEvent*, String*, Cardinal*);
void ScanAction(Widget, XEvent*, String*, Cardinal*);
void RatioAction(Widget, XEvent*, String*, Cardinal*);
void LaunchAction(Widget, XEvent*, String*, Cardinal*);
void VtxAction(Widget, XEvent*, String*, Cardinal*);
void FilterAction(Widget, XEvent*, String*, Cardinal*);
void EventAction(Widget, XEvent*, String*, Cardinal*);

Boolean MyResize(XtPointer client_data);
void do_fullscreen(void);

void create_onscreen(WidgetClass class);
Boolean rec_work(XtPointer client_data);

void exec_done(int signal);
/* static void exec_output(XtPointer data, int *fd, XtInputId * iproc); */
int exec_x11(char **argv);
void exec_player(char *moviefile);
void xt_siginit(void);

void new_title(char *txt);
void new_message(char *txt);
void change_audio(int mode);
void tv_expose_event(Widget widget, XtPointer client_data,
		     XEvent *event, Boolean *d);

/*----------------------------------------------------------------------*/

struct DO_CMD {
    int   argc;
    char  *argv[8];
};

void command_cb(Widget widget, XtPointer clientdata, XtPointer call_data);

/*----------------------------------------------------------------------*/

void CommandAction(Widget, XEvent*, String*, Cardinal*);
void RemoteAction(Widget, XEvent*, String*, Cardinal*);
void set_property(int freq, char *channel, char *name);

/*----------------------------------------------------------------------*/

void x11_misc_init(Display *dpy);
void xfree_dga_init(Display *dpy);
void xfree_xinerama_init(Display *dpy);
void xfree_vm_init(Display *dpy);
void xfree_randr_init(Display *dpy);

void grabber_init(void);
void grabber_scan(void);
void x11_check_remote(void);
void visual_init(char *n1, char *n2);
void hello_world(char *name);
void handle_cmdline_args(void);
void v4lconf_init(void);
int x11_ctrl_alt_backspace(Display *dpy);

void mouse_event(Widget widget, XtPointer client_data,
		 XEvent *event, Boolean *d);

/*----------------------------------------------------------------------*/

extern char x11_vbi_station[];

int x11_vbi_start(char *device);
int x11_vbi_tuned(void);
void x11_vbi_stop(void);

/*----------------------------------------------------------------------*/

int xt_lirc_init(void);
int xt_midi_init(char *dev);
int xt_joystick_init(void);
void init_icon_window(Widget shell,WidgetClass class);
void xt_kbd_init(Widget tv);

/*----------------------------------------------------------------------*/

void create_pointers(Widget);
void create_bitmaps(Widget);

extern Cursor  left_ptr;
extern Cursor  menu_ptr;
extern Cursor  qu_ptr;
extern Cursor  no_ptr;

extern Pixmap bm_yes;
extern Pixmap bm_no;

/*----------------------------------------------------------------------*/

int xt_handle_pending(Display *dpy);
int xt_vm_randr_input_init(Display *dpy);
int xt_main_loop(void);
xawtv-3.106/x11/xv.c000066400000000000000000000364341343350355000141210ustar00rootroot00000000000000/*
 * (most) Xvideo extention code is here.
 *
 * (c) 2001 Gerd Knorr 
 */

#include "config.h"

#ifdef HAVE_LIBXV

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "grab-ng.h"
#include "commands.h"    /* FIXME: global *drv vars */
#include "atoms.h"
#include "xv.h"

extern Display    *dpy;
int               have_xv;

const struct ng_vid_driver xv_driver;

static int              ver, rel, req, ev, err, grabbed;
static int              adaptors;
static int              attributes;
static XvAdaptorInfo        *ai;
static XvEncodingInfo       *ei;
static XvAttribute          *at;

static int
xv_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y,
	   struct OVERLAY_CLIP *oc, int count, int aspect)
{
    if (debug)
	fprintf(stderr,"Ouch: xv_overlay called\n");
    return 0;
}

/* ********************************************************************* */

struct ENC_MAP {
    int norm;
    int input;
    int encoding;
};

struct xv_handle {
    /* port */
    int                  vi_adaptor;
    XvPortID             vi_port;
    GC                   vi_gc;

    /* attributes */
    int                  nattr;
    struct ng_attribute  *attr;
    Atom xv_encoding;
    Atom xv_freq;
    Atom xv_colorkey;

    /* encoding */
    struct ENC_MAP       *enc_map;
    int                  norm, input, enc;
    int                  encodings;
};

static const struct XVATTR {
    int   id;
    int   type;
    char  *atom;
} xvattr[] = {
    { ATTR_ID_COLOR,    ATTR_TYPE_INTEGER, "XV_COLOR"       },
    { ATTR_ID_COLOR,    ATTR_TYPE_INTEGER, "XV_SATURATION"  },
    { ATTR_ID_HUE,      ATTR_TYPE_INTEGER, "XV_HUE",        },
    { ATTR_ID_BRIGHT,   ATTR_TYPE_INTEGER, "XV_BRIGHTNESS", },
    { ATTR_ID_CONTRAST, ATTR_TYPE_INTEGER, "XV_CONTRAST",   },
    { -1,               ATTR_TYPE_BOOL,    "XV_CHROMA_AGC", },
    { -1,               ATTR_TYPE_BOOL,    "XV_COMBFILTER", },
    { -1,               ATTR_TYPE_BOOL,    "XV_AUTOMUTE",   },
    { -1,               ATTR_TYPE_BOOL,    "XV_LUMA_DECIMATION_FILTER", },
    { -1,               ATTR_TYPE_BOOL,    "XV_AGC_CRUSH",  },
    { -1,               ATTR_TYPE_BOOL,    "XV_VCR_HACK",   },
    { -1,               ATTR_TYPE_BOOL,    "XV_FULL_LUMA_RANGE", },
    { ATTR_ID_MUTE,     ATTR_TYPE_BOOL,    "XV_MUTE",       },
    { -1,               ATTR_TYPE_INTEGER, "XV_BALANCE",    },
    { -1,               ATTR_TYPE_INTEGER, "XV_BASS",       },
    { -1,               ATTR_TYPE_INTEGER, "XV_TREBLE",     },
    { ATTR_ID_VOLUME,   ATTR_TYPE_INTEGER, "XV_VOLUME",     },
    { -1,               -1,                "XV_COLORKEY",   },
    { -1,               -1,                "XV_AUTOPAINT_COLORKEY", },
    { -1,               -1,                "XV_FREQ",       },
    { -1,               -1,                "XV_ENCODING",   },
    { -1,               -1,                "XV_WHITECRUSH_UPPER", },
    { -1,               -1,                "XV_WHITECRUSH_LOWER", },
    { -1,               -1,                "XV_UV_RATIO",   },
    { -1,               -1,                "XV_CORING",     },
    { -1,               -1,                "XV_AUTOPAINT_COLORKEY", },
    { -1,               -1,                "XV_SET_DEFAULTS", },
    { -1,               -1,                "XV_ITURBT_709", },
    {}
};

static int xv_read_attr(struct ng_attribute *attr)
{
    struct xv_handle *h   = attr->handle;
    const XvAttribute *at = attr->priv;
    Atom atom;
    int value = 0;

    if (NULL != at) {
	atom = XInternAtom(dpy, at->name, False);
	XvGetPortAttribute(dpy, h->vi_port,atom,&value);
	if (debug)
	    fprintf(stderr,"xv: get %s: %d\n",at->name,value);

    } else if (attr->id == ATTR_ID_NORM) {
	value = h->norm;

    } else if (attr->id == ATTR_ID_INPUT) {
	value = h->input;

    }
    return value;
}

static void xv_write_attr(struct ng_attribute *attr, int value)
{
    struct xv_handle *h   = attr->handle;
    const XvAttribute *at = attr->priv;
    Atom atom;
    int i;

    if (NULL != at) {
	atom = XInternAtom(dpy, at->name, False);
	XvSetPortAttribute(dpy, h->vi_port,atom,value);
	if (debug)
	    fprintf(stderr,"xv: set %s: %d\n",at->name,value);

    } else if (attr->id == ATTR_ID_NORM || attr->id == ATTR_ID_INPUT) {
	if (attr->id == ATTR_ID_NORM)
	    h->norm  = value;
	if (attr->id == ATTR_ID_INPUT)
	    h->input = value;
	for (i = 0; i < h->encodings; i++) {
	    if (h->enc_map[i].norm  == h->norm &&
		h->enc_map[i].input == h->input) {
		h->enc = i;
		XvSetPortAttribute(dpy,h->vi_port,h->xv_encoding,h->enc);
		break;
	    }
	}
    }
    /* needed for proper timing on the
       "mute - wait - switch - wait - unmute" channel switches */
    XSync(dpy,False);
}

static void
xv_add_attr(struct xv_handle *h, int id, int type,
	    int defval, struct STRTAB *choices, XvAttribute *at)
{
    int i;

    h->attr = realloc(h->attr,(h->nattr+2) * sizeof(struct ng_attribute));
    memset(h->attr+h->nattr,0,sizeof(struct ng_attribute)*2);
    if (at) {
	h->attr[h->nattr].priv    = at;
	for (i = 0; xvattr[i].atom != NULL; i++)
	    if (0 == strcmp(xvattr[i].atom,at->name))
		break;
	if (-1 == xvattr[i].type)
	    /* ignore this one */
	    return;
	if (NULL != xvattr[i].atom) {
	    h->attr[h->nattr].id      = xvattr[i].id;
	    h->attr[h->nattr].type    = xvattr[i].type;
	    h->attr[h->nattr].priv    = at;
	    if (ATTR_TYPE_INTEGER == h->attr[h->nattr].type) {
		h->attr[h->nattr].min = at->min_value;
		h->attr[h->nattr].max = at->max_value;
	    }
	} else {
	    /* unknown */
	    return;
	}
    }

    if (id)
	h->attr[h->nattr].id      = id;
    if (type)
	h->attr[h->nattr].type    = type;
    if (defval)
	h->attr[h->nattr].defval  = defval;
    if (choices)
	h->attr[h->nattr].choices = choices;
    if (h->attr[h->nattr].id < ATTR_ID_COUNT)
	h->attr[h->nattr].name    = ng_attr_to_desc[h->attr[h->nattr].id];

    h->attr[h->nattr].read    = xv_read_attr;
    h->attr[h->nattr].write   = xv_write_attr;
    h->attr[h->nattr].handle  = h;
    h->nattr++;
}

static unsigned long
xv_getfreq(void *handle)
{
    struct xv_handle *h = handle;
    unsigned int freq;

    XvGetPortAttribute(dpy,h->vi_port,h->xv_freq,&freq);
    return freq;
}

static void
xv_setfreq(void *handle, unsigned long freq)
{
    struct xv_handle *h = handle;

    XvSetPortAttribute(dpy,h->vi_port,h->xv_freq,freq);
    XSync(dpy,False);
}

static int
xv_tuned(void *handle)
{
    /* don't know ... */
    return 0;
}

void
xv_video(Window win, int dw, int dh, int on)
{
    struct xv_handle *h = h_drv; /* FIXME */
    int sx,sy,dx,dy;
    int sw,sh;

    if (on) {
	sx = sy = dx = dy = 0;
	sw = dw;
	sh = dh;
	if (-1 != h->enc) {
	    sw = ei[h->enc].width;
	    sh = ei[h->enc].height;
	}
	if (NULL == h->vi_gc)
	    h->vi_gc = XCreateGC(dpy, win, 0, NULL);
	ng_ratio_fixup(&dw,&dh,&dx,&dy);
	if (0 == grabbed)
	    if (Success == XvGrabPort(dpy,h->vi_port,CurrentTime))
		grabbed = 1;
	if (1 == grabbed) {
	    XvPutVideo(dpy,h->vi_port,win,h->vi_gc,
		       sx,sy,sw,sh, dx,dy,dw,dh);
	    if (debug)
		fprintf(stderr,"Xvideo: video: win=0x%lx, "
			"src=%dx%d+%d+%d dst=%dx%d+%d+%d\n",
			win, sw,sh,sx,sy, dw,dh,dx,dy);
	} else {
	    fprintf(stderr,"Xvideo: port %ld busy\n",h->vi_port);
	}
    } else {
	if (grabbed) {
	    XClearArea(dpy,win,0,0,0,0,False);
	    XvStopVideo(dpy,h->vi_port,win);
	    XvUngrabPort(dpy,h->vi_port,CurrentTime);
	    grabbed = 0;
	    if (debug)
		fprintf(stderr,"Xvideo: video off\n");
	}
    }
}

static int
xv_strlist_add(struct STRTAB **tab, char *str)
{
    int i;

    if (NULL == *tab) {
	*tab = malloc(sizeof(struct STRTAB)*2);
	i = 0;
    } else {
	for (i = 0; (*tab)[i].str != NULL; i++)
	    if (0 == strcasecmp((*tab)[i].str,str))
		return (*tab)[i].nr;
	*tab = realloc(*tab,sizeof(struct STRTAB)*(i+2));
    }
    (*tab)[i].nr  = i;
    (*tab)[i].str = strdup(str);
    (*tab)[i+1].nr  = -1;
    (*tab)[i+1].str = NULL;
    return i;
}

static int xv_close(void *handle) { return 0; }

static int xv_flags(void *handle)
{
    struct xv_handle *h = handle;
    int ret = 0;

    ret |= CAN_OVERLAY;
    if (h->xv_freq != None)
	ret |= CAN_TUNE;
    return ret;
}

static struct ng_attribute* xv_attrs(void *handle)
{
    struct xv_handle *h  = handle;
    return h->attr;
}

/* ********************************************************************* */

void xv_video_init(unsigned int port, int hwscan)
{
    struct xv_handle *handle;
    struct STRTAB *norms  = NULL;
    struct STRTAB *inputs = NULL;
    char *h;
    int n, i, vi_port = -1, vi_adaptor = -1;

    if (Success != XvQueryExtension(dpy,&ver,&rel,&req,&ev,&err)) {
	if (debug)
	    fprintf(stderr,"Xvideo: Server has no Xvideo extention support\n");
	return;
    }
    if (Success != XvQueryAdaptors(dpy,DefaultRootWindow(dpy),&adaptors,&ai)) {
	fprintf(stderr,"Xvideo: XvQueryAdaptors failed");
	exit(1);
    }
    if (debug)
	fprintf(stderr,"Xvideo: %d adaptors available.\n",adaptors);
    for (i = 0; i < adaptors; i++) {
	if (debug)
	    fprintf(stderr,"Xvideo: %s:%s%s%s%s%s, ports %ld-%ld\n",
		    ai[i].name,
		    (ai[i].type & XvInputMask)  ? " input"  : "",
		    (ai[i].type & XvOutputMask) ? " output" : "",
		    (ai[i].type & XvVideoMask)  ? " video"  : "",
		    (ai[i].type & XvStillMask)  ? " still"  : "",
		    (ai[i].type & XvImageMask)  ? " image"  : "",
		    ai[i].base_id,
		    ai[i].base_id+ai[i].num_ports-1);
	if (hwscan) {
	    /* just print some info's about the Xvideo port */
	    n = fprintf(stderr,"port %ld-%ld",
			ai[i].base_id,ai[i].base_id+ai[i].num_ports-1);
	    if ((ai[i].type & XvInputMask) &&
		(ai[i].type & XvVideoMask))
		fprintf(stderr,"%*s[ -xvport %ld ]",40-n,"",ai[i].base_id);
	    fprintf(stderr,"\n");
	    if ((ai[i].type & XvInputMask) &&
		(ai[i].type & XvVideoMask))
		fprintf(stderr,"    type : Xvideo, video overlay\n");
	    if ((ai[i].type & XvInputMask) &&
		(ai[i].type & XvImageMask))
		fprintf(stderr,"    type : Xvideo, image scaler\n");
	    fprintf(stderr,"    name : %s\n",ai[i].name);
	    fprintf(stderr,"\n");
	    continue;
	}

	if ((ai[i].type & XvInputMask) &&
	    (ai[i].type & XvVideoMask) &&
	    (vi_port == -1)) {
	    if (0 == port) {
		vi_port = ai[i].base_id;
		vi_adaptor = i;
	    } else if (port >= ai[i].base_id  &&
		       port <  ai[i].base_id+ai[i].num_ports) {
		vi_port = port;
		vi_adaptor = i;
	    } else {
		if (debug)
		    fprintf(stderr,"Xvideo: skipping ports %ld-%ld (configured other: %d)\n",
			    ai[i].base_id, ai[i].base_id+ai[i].num_ports-1, port);
	    }
	}
    }
    if (hwscan)
	return;

    /* *** video port *** */
    if (vi_port == -1) {
	if (debug)
	    fprintf(stderr,"Xvideo: no usable video port found\n");
    } else {
	if (debug)
	    fprintf(stderr,"Xvideo: using port %d for video\n",vi_port);
	handle = malloc(sizeof(struct xv_handle));
	memset(handle,0,sizeof(struct xv_handle));
	handle->vi_port     = vi_port;
	handle->vi_adaptor  = vi_adaptor;
	handle->xv_encoding = None;
	handle->xv_freq     = None;
	handle->xv_colorkey = None;
	handle->enc         = -1;
	handle->norm        = -1;
	handle->input       = -1;

	/* query encoding list */
	if (Success != XvQueryEncodings(dpy, vi_port,
					&handle->encodings, &ei)) {
	    fprintf(stderr,"Oops: XvQueryEncodings failed\n");
	    exit(1);
	}
	handle->enc_map = malloc(sizeof(struct ENC_MAP)*handle->encodings);
	for (i = 0; i < handle->encodings; i++) {
	    if (NULL != (h = strrchr(ei[i].name,'-'))) {
		*(h++) = 0;
		handle->enc_map[i].input = xv_strlist_add(&inputs,h);
	    }
	    handle->enc_map[i].norm = xv_strlist_add(&norms,ei[i].name);
	    handle->enc_map[i].encoding = ei[i].encoding_id;
	}

	/* build atoms */
	at = XvQueryPortAttributes(dpy,vi_port,&attributes);
	for (i = 0; i < attributes; i++) {
	    if (debug)
		fprintf(stderr,"  %s%s%s, %i -> %i\n",
			at[i].name,
			(at[i].flags & XvGettable) ? " get" : "",
			(at[i].flags & XvSettable) ? " set" : "",
			at[i].min_value,at[i].max_value);
	    if (0 == strcmp("XV_ENCODING",at[i].name))
		handle->xv_encoding = XV_ENCODING;
	    if (0 == strcmp("XV_FREQ",at[i].name))
		handle->xv_freq     = XV_FREQ;
#if 0
	    if (0 == strcmp("XV_COLORKEY",at[i].name))
		handle->xv_colorkey = XV_COLORKEY;
#endif
	    xv_add_attr(handle, 0, 0, 0, NULL, at+i);
	}

	if (handle->xv_encoding != None) {
	    if (norms)
		xv_add_attr(handle, ATTR_ID_NORM, ATTR_TYPE_CHOICE,
			    0, norms, NULL);
	    if (inputs)
		xv_add_attr(handle, ATTR_ID_INPUT, ATTR_TYPE_CHOICE,
			    0, inputs, NULL);
	}
#if 0
	if (xv_colorkey != None) {
	    XvGetPortAttribute(dpy,vi_port,xv_colorkey,&xv.colorkey);
	    fprintf(stderr,"Xvideo: colorkey: %x\n",xv.colorkey);
	}
#endif
	have_xv = 1;
	drv   = &xv_driver;
	h_drv = handle;
	f_drv = xv_flags(h_drv);
	add_attrs(xv_attrs(h_drv));
    }
}

/* ********************************************************************* */

#if 0
static Window icon_win;
static int icon_width,icon_height;

static void
icon_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d)
{
    switch (event->type) {
    case Expose:
	if (debug)
	    fprintf(stderr,"icon expose\n");
	xv_video(icon_win, icon_width, icon_height, 1);
	break;
    case MapNotify:
	if (debug)
	    fprintf(stderr,"icon map\n");
	xv_video(icon_win, icon_width, icon_height, 1);
	break;
    case UnmapNotify:
	if (debug)
	    fprintf(stderr,"icon unmap\n");
	break;
    default:
	fprintf(stderr,"icon other\n");
	break;
    }
}

void
init_icon_window(Widget shell,WidgetClass class)
{
    Window root = RootWindowOfScreen(XtScreen(shell));
    Widget widget;
    XIconSize *is;
    int i,count;

    if (XGetIconSizes(XtDisplay(shell),root,&is,&count)) {
	for (i = 0; i < count; i++) {
	    fprintf(stderr,"icon size: min=%dx%d - max=%dx%d - inc=%dx%d\n",
		    is[i].min_width, is[i].min_height,
		    is[i].max_width, is[i].max_height,
		    is[i].width_inc, is[i].height_inc);
	}
	icon_width  = is[0].max_width;
	icon_height = is[0].max_height;
	if (icon_width * 3 > icon_height * 4) {
	    while (icon_width * 3 > icon_height * 4 &&
		   icon_width - is[0].width_inc > is[0].min_width)
		icon_width -= is[0].width_inc;
	} else {
	    while (icon_width * 3 < icon_height * 4 &&
		   icon_height - is[0].height_inc > is[0].min_height)
		icon_height -= is[0].height_inc;
	}
    } else {
	icon_width  = 64;
	icon_height = 48;
    }
    fprintf(stderr,"icon init %dx%d\n",icon_width,icon_height);

    icon_win = XCreateWindow(XtDisplay(shell),root,
			     0,0,icon_width,icon_height,1,
			     CopyFromParent,InputOutput,CopyFromParent,
			     0,NULL);
    widget = XtVaCreateWidget("icon",class,shell,NULL);
    XtRegisterDrawable(XtDisplay(shell),icon_win,widget);
    XtAddEventHandler(widget,StructureNotifyMask | ExposureMask,
		      False,icon_event,NULL);
    XSelectInput(XtDisplay(shell),icon_win,
		 StructureNotifyMask | ExposureMask);
    XtVaSetValues(shell,XtNiconWindow,icon_win,NULL);
}
#endif

/* ********************************************************************* */

const struct ng_vid_driver xv_driver = {
    .name =          "Xvideo",
    .close =         xv_close,

    .capabilities =  xv_flags,
    .list_attrs =    xv_attrs,

    .overlay =       xv_overlay,

    .getfreq =       xv_getfreq,
    .setfreq =       xv_setfreq,
    .is_tuned =      xv_tuned,
};

#else /* HAVE_LIBXV */

int               have_xv = 0;

#endif /* HAVE_LIBXV */
xawtv-3.106/x11/xv.h000066400000000000000000000002331343350355000141120ustar00rootroot00000000000000extern int have_xv;
void xv_video_init(unsigned int port, int hwscan);

#ifdef HAVE_LIBXV
void xv_video(Window win, int width, int height, int on);
#endif
xawtv-3.106/xawtv.spec000066400000000000000000000017041343350355000147240ustar00rootroot00000000000000Name:         xawtv
Group:        Applications/Multimedia
Autoreqprov:  on
Version:      3.106
Release:      0
License:      GPL
Summary:      v4l applications
Source:       http://bytesex.org/xawtv/%{name}_%{version}.tar.gz
Buildroot:    /var/tmp/root.%{name}-%{version}

%description
fixme

%prep
%setup -q

%build
mkdir build
cd build
CFLAGS="$RPM_OPT_FLAGS" ../configure --prefix=/usr/X11R6
make

%install
test "%{buildroot}" != "" && rm -rf "%{buildroot}"
(cd build; make DESTDIR="%{buildroot}" SUID_ROOT="" install)
gzip -v %{buildroot}/usr/X11R6/man/man*/*.[158]
gzip -v %{buildroot}/usr/X11R6/man/*/man*/*.[158]
find %{buildroot} -type f -print	\
	| sed -e 's|%{buildroot}||'	\
	| grep -v -e %{docdir}		\
	| grep -v -e bin/v4l-conf	\
	> filelist

%files -f filelist
%defattr(-,root,root)
%doc COPYING Changes TODO README README.* contrib/frequencies*
%attr(4711,root,root) /usr/X11R6/bin/v4l-conf

%clean
test "%{buildroot}" != "" && rm -rf "%{buildroot}"
xawtv-3.106/xawtv.spec.in000066400000000000000000000017101343350355000153260ustar00rootroot00000000000000Name:         xawtv
Group:        Applications/Multimedia
Autoreqprov:  on
Version:      @VERSION@
Release:      0
License:      GPL
Summary:      v4l applications
Source:       http://bytesex.org/xawtv/%{name}_%{version}.tar.gz
Buildroot:    /var/tmp/root.%{name}-%{version}

%description
fixme

%prep
%setup -q

%build
mkdir build
cd build
CFLAGS="$RPM_OPT_FLAGS" ../configure --prefix=/usr/X11R6
make

%install
test "%{buildroot}" != "" && rm -rf "%{buildroot}"
(cd build; make DESTDIR="%{buildroot}" SUID_ROOT="" install)
gzip -v %{buildroot}/usr/X11R6/man/man*/*.[158]
gzip -v %{buildroot}/usr/X11R6/man/*/man*/*.[158]
find %{buildroot} -type f -print	\
	| sed -e 's|%{buildroot}||'	\
	| grep -v -e %{docdir}		\
	| grep -v -e bin/v4l-conf	\
	> filelist

%files -f filelist
%defattr(-,root,root)
%doc COPYING Changes TODO README README.* contrib/frequencies*
%attr(4711,root,root) /usr/X11R6/bin/v4l-conf

%clean
test "%{buildroot}" != "" && rm -rf "%{buildroot}"