Want more features on Pastebin? Sign Up, it's FREE!
Guest

tvtime-1.0.2-full.patch

By: a guest on May 29th, 2011  |  syntax: C++  |  size: 410.61 KB  |  views: 141  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print  |  QR code  |  clone
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. diff -Nurp tvtime-1.0.2/configure.ac tvtime-1.0.2-custom/configure.ac
  2. --- tvtime-1.0.2/configure.ac   2005-09-14 23:40:44.000000000 +0200
  3. +++ tvtime-1.0.2-custom/configure.ac    2011-05-29 13:07:28.219041386 +0200
  4. @@ -10,12 +10,7 @@ if test x"$host_alias" = x""; then host_
  5.  
  6.  # Check for compilers.
  7.  AC_PROG_CC
  8. -AC_CHECK_PROG(found_cc, "$CC", yes, no)
  9. -test "x$found_cc" = "xyes" || exit 1
  10. -
  11.  AC_PROG_CXX
  12. -AC_CHECK_PROG(found_cxx, "$CXX", yes, no)
  13. -test "x$found_cxx" = "xyes" || exit 1
  14.  
  15.  # Check for libtool.
  16.  AC_PROG_LIBTOOL
  17. @@ -74,18 +69,26 @@ dnl ------------------------------------
  18.  dnl libxml2
  19.  dnl ---------------------------------------------
  20.  dnl Test for libxml2
  21. -
  22.  AC_PATH_PROG(LIBXML2_CONFIG,xml2-config,no)
  23.  if test "$LIBXML2_CONFIG" = "no" ; then
  24.         AC_MSG_ERROR(libxml2 needed and xml2-config not found)
  25.  else
  26.         XML2_LIBS="`$LIBXML2_CONFIG --libs`"
  27.         XML2_FLAG="`$LIBXML2_CONFIG --cflags`"
  28. -       AC_DEFINE(HAVE_LIBXML2,,[LIBXML2 support])     
  29. +       AC_DEFINE(HAVE_LIBXML2,,[LIBXML2 support])
  30.  fi
  31.  AC_SUBST(XML2_LIBS)
  32.  AC_SUBST(XML2_FLAG)
  33.  
  34. +dnl ---------------------------------------------
  35. +dnl libasound2
  36. +dnl ---------------------------------------------
  37. +dnl Test for ALSA
  38. +AM_PATH_ALSA(1.0.9,
  39. +       [ AC_DEFINE(HAVE_ALSA,1,[Define this if you have Alsa (libasound) installed]) ],
  40. +       AC_MSG_RESULT(libasound needed and not found))
  41. +AM_CONDITIONAL(HAVE_ALSA, test x"$no_alsa" != "yes")
  42. +
  43.  
  44.  dnl ---------------------------------------------
  45.  dnl check for gtk+-2.0
  46. @@ -99,6 +102,8 @@ dnl ------------------------------------
  47.  dnl check for X11, Xv and XF86VidModeExtension
  48.  dnl ---------------------------------------------
  49.  AC_PATH_XTRA
  50. +AC_ARG_WITH([xinerama],
  51. +    [AS_HELP_STRING([--without-xinerama], [Disable Xinerama extension support (default: check)])])
  52.  if test x"$no_x" != x"yes"; then
  53.      dnl check for Xshm
  54.      AC_CHECK_LIB([Xext],[XShmCreateImage],
  55. @@ -112,16 +117,18 @@ if test x"$no_x" != x"yes"; then
  56.             X11_LIBS="$X11_LIBS -lXv"],,
  57.             [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])
  58.  
  59. -       dnl check for Xinerama
  60. -       AC_CHECK_LIB([Xinerama],[XineramaQueryScreens],
  61. -           [AC_DEFINE([HAVE_XINERAMA],,[Xinerama support])
  62. -           X11_LIBS="$X11_LIBS -lXinerama"],,
  63. -           [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])
  64. -
  65. -       dnl check for XTest
  66. -        AC_CHECK_LIB([Xtst],[XTestFakeKeyEvent],
  67. -            [AC_DEFINE([HAVE_XTESTEXTENSION],,[XTest support])
  68. -            X11_LIBS="$X11_LIBS -lXtst"],,
  69. +       if test "x$with_xinerama" != "xno"; then
  70. +               dnl check for Xinerama
  71. +               AC_CHECK_LIB([Xinerama],[XineramaQueryScreens],
  72. +                   [AC_DEFINE([HAVE_XINERAMA],,[Xinerama support])
  73. +                   X11_LIBS="$X11_LIBS -lXinerama"],,
  74. +                   [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])
  75. +       fi
  76. +
  77. +       dnl check for XSs
  78. +        AC_CHECK_LIB([Xss],[XScreenSaverSuspend],
  79. +            [AC_DEFINE([HAVE_XSSEXTENSION],,[XSs support])
  80. +            X11_LIBS="$X11_LIBS -lXss"],,
  81.             [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])
  82.  
  83.         dnl check for Xvidmode
  84. diff -Nurp tvtime-1.0.2/configure.ac.orig tvtime-1.0.2-custom/configure.ac.orig
  85. --- tvtime-1.0.2/configure.ac.orig      1970-01-01 01:00:00.000000000 +0100
  86. +++ tvtime-1.0.2-custom/configure.ac.orig       2011-05-29 13:07:28.159040652 +0200
  87. @@ -0,0 +1,244 @@
  88. +# Process this file with autoconf to produce a configure script.
  89. +AC_PREREQ(2.52)
  90. +AC_INIT(tvtime, 1.0.2, http://tvtime.net/)
  91. +AC_CONFIG_SRCDIR([src/tvtime.c])
  92. +AM_INIT_AUTOMAKE(tvtime,1.0.2)
  93. +AM_CONFIG_HEADER(config.h)
  94. +AM_MAINTAINER_MODE
  95. +AC_CANONICAL_HOST
  96. +if test x"$host_alias" = x""; then host_alias="$host"; fi
  97. +
  98. +# Check for compilers.
  99. +AC_PROG_CC
  100. +AC_CHECK_PROG(found_cc, "$CC", yes, no)
  101. +test "x$found_cc" = "xyes" || exit 1
  102. +
  103. +AC_PROG_CXX
  104. +AC_CHECK_PROG(found_cxx, "$CXX", yes, no)
  105. +test "x$found_cxx" = "xyes" || exit 1
  106. +
  107. +# Check for libtool.
  108. +AC_PROG_LIBTOOL
  109. +
  110. +# Checks for header files.
  111. +AC_HEADER_STDC
  112. +AC_CHECK_HEADERS([ctype.h dirent.h errno.h fcntl.h getopt.h langinfo.h math.h netinet/in.h pwd.h signal.h stdint.h stdio.h stdlib.h string.h sys/ioctl.h sys/mman.h sys/resource.h sys/stat.h sys/time.h sys/wait.h sys/types.h unistd.h wordexp.h locale.h])
  113. +
  114. +# Checks for typedefs, structures, and compiler characteristics.
  115. +AC_HEADER_TIME
  116. +
  117. +# Checks for library functions.
  118. +AC_PROG_GCC_TRADITIONAL
  119. +AC_FUNC_MMAP
  120. +AC_CHECK_FUNCS([asprintf atexit fork execlp getopt_long getpriority gettimeofday seteuid memset setreuid setpriority signal sigemptyset sigaction strerror vsscanf wordexp wordfree])
  121. +
  122. +# Check for gettext
  123. +AM_GNU_GETTEXT
  124. +
  125. +dnl ---------------------------------------------
  126. +dnl zlib
  127. +dnl ---------------------------------------------
  128. +dnl Test for libz
  129. +AC_CHECK_LIB(z, gzsetparams,
  130. +        [ AC_CHECK_HEADER(zlib.h,
  131. +          have_zlib=yes
  132. +          ZLIB_LIBS="-lz",)], AC_MSG_ERROR(zlib needed))
  133. +
  134. +AM_CONDITIONAL(HAVE_ZLIB, [test x"$have_zlib" = "xyes"])
  135. +AC_SUBST(ZLIB_LIBS)
  136. +
  137. +
  138. +dnl ---------------------------------------------
  139. +dnl libpng
  140. +dnl ---------------------------------------------
  141. +dnl Test for libpng
  142. +AC_CHECK_LIB(png, png_read_png,
  143. +        [ AC_CHECK_HEADER(png.h,
  144. +          have_libpng=yes
  145. +          PNG_LIBS="-lpng $ZLIB_LIBS -lm",)], AC_MSG_ERROR(libpng needed), "$ZLIB_LIBS" -lm)
  146. +
  147. +AM_CONDITIONAL(HAVE_LIBPNG, [test x"$have_libpng" = "xyes"])
  148. +AC_SUBST(PNG_LIBS)
  149. +
  150. +
  151. +dnl ---------------------------------------------
  152. +dnl freetype
  153. +dnl ---------------------------------------------
  154. +dnl Test for freetype
  155. +AC_PATH_PROG(FREETYPE_CONFIG, freetype-config, no)
  156. +if test "$FREETYPE_CONFIG" = "no" ; then
  157. +  AC_MSG_ERROR(freetype2 needed and freetype-config not found)
  158. +fi
  159. +
  160. +dnl ---------------------------------------------
  161. +dnl libxml2
  162. +dnl ---------------------------------------------
  163. +dnl Test for libxml2
  164. +AC_PATH_PROG(LIBXML2_CONFIG,xml2-config,no)
  165. +if test "$LIBXML2_CONFIG" = "no" ; then
  166. +       AC_MSG_ERROR(libxml2 needed and xml2-config not found)
  167. +else
  168. +       XML2_LIBS="`$LIBXML2_CONFIG --libs`"
  169. +       XML2_FLAG="`$LIBXML2_CONFIG --cflags`"
  170. +       AC_DEFINE(HAVE_LIBXML2,,[LIBXML2 support])
  171. +fi
  172. +AC_SUBST(XML2_LIBS)
  173. +AC_SUBST(XML2_FLAG)
  174. +
  175. +dnl ---------------------------------------------
  176. +dnl libasound2
  177. +dnl ---------------------------------------------
  178. +dnl Test for ALSA
  179. +AM_PATH_ALSA(1.0.9,
  180. +       [ AC_DEFINE(HAVE_ALSA,1,[Define this if you have Alsa (libasound) installed]) ],
  181. +       AC_MSG_RESULT(libasound needed and not found))
  182. +AM_CONDITIONAL(HAVE_ALSA, test x"$no_alsa" != "yes")
  183. +
  184. +
  185. +dnl ---------------------------------------------
  186. +dnl check for gtk+-2.0
  187. +dnl ---------------------------------------------
  188. +dnl PKG_CHECK_MODULES(GTK, gtk+-2.0)
  189. +dnl AC_SUBST(GTK_CFLAGS)
  190. +dnl AC_SUBST(GTK_LIBS)
  191. +
  192. +
  193. +dnl ---------------------------------------------
  194. +dnl check for X11, Xv and XF86VidModeExtension
  195. +dnl ---------------------------------------------
  196. +AC_PATH_XTRA
  197. +AC_ARG_WITH([xinerama],
  198. +    [AS_HELP_STRING([--without-xinerama], [Disable Xinerama extension support (default: check)])])
  199. +if test x"$no_x" != x"yes"; then
  200. +    dnl check for Xshm
  201. +    AC_CHECK_LIB([Xext],[XShmCreateImage],
  202. +       [AC_DEFINE([HAVE_X11],,[X11 support])
  203. +       X11_CFLAGS="$X_CFLAGS"
  204. +       X11_LIBS="$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext"
  205. +
  206. +       dnl check for Xv
  207. +       AC_CHECK_LIB([Xv],[XvShmCreateImage],
  208. +           [AC_DEFINE([HAVE_XV],,[Xv support])
  209. +           X11_LIBS="$X11_LIBS -lXv"],,
  210. +           [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])
  211. +
  212. +       if test "x$with_xinerama" != "xno"; then
  213. +               dnl check for Xinerama
  214. +               AC_CHECK_LIB([Xinerama],[XineramaQueryScreens],
  215. +                   [AC_DEFINE([HAVE_XINERAMA],,[Xinerama support])
  216. +                   X11_LIBS="$X11_LIBS -lXinerama"],,
  217. +                   [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])
  218. +       fi
  219. +
  220. +       dnl check for XTest
  221. +        AC_CHECK_LIB([Xtst],[XTestFakeKeyEvent],
  222. +            [AC_DEFINE([HAVE_XTESTEXTENSION],,[XTest support])
  223. +            X11_LIBS="$X11_LIBS -lXtst"],,
  224. +           [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])
  225. +
  226. +       dnl check for Xvidmode
  227. +       AC_CHECK_LIB([Xxf86vm],[XF86VidModeGetModeLine],
  228. +           [AC_DEFINE([HAVE_XF86VIDMODE],,[XF86VidModeExtension support])
  229. +           X11_LIBS="$X11_LIBS -lXxf86vm"],,
  230. +           [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])],,
  231. +       [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS])
  232. +else
  233. +    AC_MSG_ERROR(X needed and no X libraries or development headers found)
  234. +fi
  235. +AC_SUBST(X11_CFLAGS)
  236. +AC_SUBST(X11_LIBS)
  237. +
  238. +dnl This stuff looked kinda cool in the mpeg2dec source tree.
  239. +
  240. +dnl GCC-specific flags
  241. +if test x"$GCC" = x"yes"; then
  242. +
  243. +    dnl -Wall -Werror moved to the end to not disturb the configure script
  244. +
  245. +    dnl -O3
  246. +    changequote(<<,>>)
  247. +    OPT_CFLAGS=`echo "$CFLAGS"|sed "s/-O[0-9]*//g;"`
  248. +    changequote([,])
  249. +    OPT_CFLAGS="$OPT_CFLAGS -O3"
  250. +    AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS])
  251. +
  252. +    dnl -fomit-frame-pointer
  253. +    OPT_CFLAGS="$CFLAGS -fomit-frame-pointer"
  254. +    AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS])
  255. +
  256. +    dnl -std=gnu99
  257. +    OPT_CFLAGS="$CFLAGS -std=gnu99"
  258. +    AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS])
  259. +
  260. +    dnl arch-specific flags
  261. +    case "$host_alias" in
  262. +    i?86-* | k?-*)
  263. +           AC_DEFINE([ARCH_X86],,[x86 architecture])
  264. +           AC_DEFINE([ARCH_386],,[386 architecture])
  265. +           ARCH_X86=yes
  266. +           ARCH_386=yes
  267. +           OPT_CFLAGS="$CFLAGS"
  268. +           AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]);;
  269. +    x86_64-*)
  270. +            AC_DEFINE([ARCH_X86],,[x86 architecture])
  271. +            AC_DEFINE([ARCH_X86_64],,[x86_64 architecture])
  272. +            ARCH_X86=yes
  273. +            ARCH_X86_64=yes;;
  274. +    ppc-* | powerpc-*)
  275. +           OPT_CFLAGS="$CFLAGS -Wa,-m7400"
  276. +           AC_TRY_CFLAGS([$OPT_CFLAGS],
  277. +           [CFLAGS=$OPT_CFLAGS; AC_DEFINE([ARCH_PPC],,[ppc architecture])]);;
  278. +    sparc-* | sparc64-*)
  279. +           OPT_CFLAGS="$CFLAGS -mcpu=ultrasparc -mvis -Wa,-Av9"
  280. +           AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]);;
  281. +    mips-sgi-irix6.*)  dnl do we need to be that specific ?
  282. +           OPT_CFLAGS="$CFLAGS -mabi=64"
  283. +           AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]);;
  284. +    esac
  285. +elif test x"$CC" = x"tcc"; then
  286. +    dnl TenDRA portability checking compiler
  287. +    CFLAGS="-Xp -Yansi -f`pwd`/include/tendra.h"
  288. +    enable_mlib=no
  289. +    no_x=yes
  290. +    enable_sdl=no
  291. +else
  292. +    dnl non-gcc flags - we probably need exact configuration triplets here.
  293. +    case "$host_alias" in
  294. +    mips-sgi-irix6.*)
  295. +       OPT_CFLAGS="$CFLAGS -64"
  296. +       AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]);;
  297. +    sparc-sun-solaris*)
  298. +       OPT_CFLAGS="$CFLAGS -xCC -fast -xO5"
  299. +       AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]);;
  300. +    esac
  301. +fi
  302. +AM_CONDITIONAL(ARCH_X86, [test "$ARCH_X86" = "yes"])
  303. +AM_CONDITIONAL(ARCH_386, [test "$ARCH_386" = "yes"])
  304. +AM_CONDITIONAL(ARCH_X86_64, [test "$ARCH_X86_64" = "yes"])
  305. +
  306. +dnl Checks for library functions.
  307. +AC_CHECK_FUNCS([memalign])
  308. +AC_TYPE_SIGNAL
  309. +
  310. +dnl Checks for typedefs, structures, and compiler characteristics.
  311. +AC_C_CONST
  312. +AC_C_INLINE
  313. +AC_TYPE_SIZE_T
  314. +AC_C_BIGENDIAN
  315. +AC_C_ATTRIBUTE_ALIGNED
  316. +
  317. +AC_CONFIG_FILES([
  318. +       Makefile
  319. +       docs/Makefile
  320. +       data/Makefile
  321. +       plugins/Makefile
  322. +       src/Makefile
  323. +       intl/Makefile
  324. +       po/Makefile.in
  325. +       m4/Makefile
  326. +       docs/man/Makefile
  327. +       docs/man/de/Makefile
  328. +       docs/man/en/Makefile
  329. +       docs/man/es/Makefile
  330. +])
  331. +AC_OUTPUT
  332. diff -Nurp tvtime-1.0.2/docs/html/default.tvtime.xml tvtime-1.0.2-custom/docs/html/default.tvtime.xml
  333. --- tvtime-1.0.2/docs/html/default.tvtime.xml   2005-09-08 06:06:57.000000000 +0200
  334. +++ tvtime-1.0.2-custom/docs/html/default.tvtime.xml    2011-05-29 13:07:28.139040408 +0200
  335. @@ -116,13 +116,15 @@
  336.    <option name="VBIDevice" value="/dev/vbi0"/>
  337.  
  338.    <!--
  339. -    This sets the mixer device and channel to use.  The format is device
  340. -    name:channel name.  Valid channels are:
  341. +    This sets the mixer device and channel to use.  The format for OSS
  342. +    is device name:channel name.  Valid OSS channels are:
  343.        vol, bass, treble, synth, pcm, speaker, line, mic, cd, mix, pcm2,
  344.        rec, igain, ogain, line1, line2, line3, dig1, dig2, dig3, phin,
  345.        phout, video, radio, monitor
  346. +    The format for ALSA mixer is device/channel (e.g., "default/Line"
  347. +    or "hw:0/CD")
  348.     -->
  349. -  <option name="MixerDevice" value="/dev/mixer:line"/>
  350. +   <option name="MixerDevice" value="default/Line"/>
  351.  
  352.    <!--
  353.      This option enables 16:9 aspect ratio mode by default on startup.
  354. diff -Nurp tvtime-1.0.2/docs/man/en/tvtime.xml.5 tvtime-1.0.2-custom/docs/man/en/tvtime.xml.5
  355. --- tvtime-1.0.2/docs/man/en/tvtime.xml.5       2005-09-08 06:05:35.000000000 +0200
  356. +++ tvtime-1.0.2-custom/docs/man/en/tvtime.xml.5        2011-05-29 13:07:28.139040408 +0200
  357. @@ -234,7 +234,10 @@ This sets which device to use for VBI de
  358.  .TP
  359.  <option name="MixerDevice" value="/dev/mixer:line"/>
  360.  This sets the mixer device and channel to use.  The format is device
  361. -name:channel name.  Valid channels are:
  362. +name:channel name for OSS mixer (e.g., "/dev/mixer:Line") or device/channel
  363. +for ALSA (e.g., "hw:0/CD").
  364. +
  365. +Valid OSS channels are:
  366.  
  367.  .nh
  368.  .IR vol ", " bass ", " treble ", " synth ", " pcm ", " speaker ", "
  369. diff -Nurp tvtime-1.0.2/plugins/greedyh.asm tvtime-1.0.2-custom/plugins/greedyh.asm
  370. --- tvtime-1.0.2/plugins/greedyh.asm    2005-08-14 18:16:43.000000000 +0200
  371. +++ tvtime-1.0.2-custom/plugins/greedyh.asm     2011-05-29 13:07:28.085706424 +0200
  372. @@ -18,7 +18,7 @@
  373.  
  374.  #include "x86-64_macros.inc"
  375.  
  376. -void DScalerFilterGreedyH::FUNCT_NAME(TDeinterlaceInfo* pInfo)
  377. +void FUNCT_NAME(TDeinterlaceInfo* pInfo)
  378.  {
  379.      int64_t i;
  380.      bool InfoIsOdd = (pInfo->PictureHistory[0]->Flags & PICTURE_INTERLACED_ODD) ? 1 : 0;
  381. diff -Nurp tvtime-1.0.2/plugins/tomsmocomp/TomsMoCompAll2.inc tvtime-1.0.2-custom/plugins/tomsmocomp/TomsMoCompAll2.inc
  382. --- tvtime-1.0.2/plugins/tomsmocomp/TomsMoCompAll2.inc  2004-10-20 17:31:05.000000000 +0200
  383. +++ tvtime-1.0.2-custom/plugins/tomsmocomp/TomsMoCompAll2.inc   2011-05-29 13:07:28.085706424 +0200
  384. @@ -5,9 +5,9 @@
  385.  #endif
  386.  
  387.  #ifdef USE_STRANGE_BOB
  388. -#define SEARCH_EFFORT_FUNC(n) DScalerFilterTomsMoComp::SEFUNC(n##_SB)
  389. +#define SEARCH_EFFORT_FUNC(n) SEFUNC(n##_SB)
  390.  #else
  391. -#define SEARCH_EFFORT_FUNC(n) DScalerFilterTomsMoComp::SEFUNC(n)
  392. +#define SEARCH_EFFORT_FUNC(n) SEFUNC(n)
  393.  #endif
  394.  
  395.  int SEARCH_EFFORT_FUNC(0)              // we don't try at all ;-)
  396. diff -Nurp tvtime-1.0.2/plugins/tomsmocomp.cpp tvtime-1.0.2-custom/plugins/tomsmocomp.cpp
  397. --- tvtime-1.0.2/plugins/tomsmocomp.cpp 2004-10-20 19:38:04.000000000 +0200
  398. +++ tvtime-1.0.2-custom/plugins/tomsmocomp.cpp  2011-05-29 13:07:28.089039798 +0200
  399. @@ -31,7 +31,7 @@ public:
  400.  
  401.  #define IS_MMX
  402.  #define SSE_TYPE MMX
  403. -#define FUNCT_NAME DScalerFilterTomsMoComp::filterDScaler_MMX
  404. +#define FUNCT_NAME filterDScaler_MMX
  405.  #include "tomsmocomp/TomsMoCompAll.inc"
  406.  #undef  IS_MMX
  407.  #undef  SSE_TYPE
  408. @@ -39,7 +39,7 @@ public:
  409.  
  410.  #define IS_3DNOW
  411.  #define SSE_TYPE 3DNOW
  412. -#define FUNCT_NAME DScalerFilterTomsMoComp::filterDScaler_3DNOW
  413. +#define FUNCT_NAME filterDScaler_3DNOW
  414.  #include "tomsmocomp/TomsMoCompAll.inc"
  415.  #undef  IS_3DNOW
  416.  #undef  SSE_TYPE
  417. @@ -47,7 +47,7 @@ public:
  418.  
  419.  #define IS_SSE
  420.  #define SSE_TYPE SSE
  421. -#define FUNCT_NAME DScalerFilterTomsMoComp::filterDScaler_SSE
  422. +#define FUNCT_NAME filterDScaler_SSE
  423.  #include "tomsmocomp/TomsMoCompAll.inc"
  424.  #undef  IS_SSE
  425.  #undef  SSE_TYPE
  426. diff -Nurp tvtime-1.0.2/src/commands.c tvtime-1.0.2-custom/src/commands.c
  427. --- tvtime-1.0.2/src/commands.c 2005-11-10 03:39:05.000000000 +0100
  428. +++ tvtime-1.0.2-custom/src/commands.c  2011-05-29 13:07:28.169040774 +0200
  429. @@ -128,6 +128,7 @@ struct commands_s {
  430.      int togglepulldowndetection;
  431.      int togglematte;
  432.      int togglequiet;
  433. +    int changedoverscan;
  434.      int framerate;
  435.      int scan_channels;
  436.      int pause;
  437. @@ -2900,7 +2901,7 @@ void commands_handle( commands_t *cmd, i
  438.      case TVTIME_OVERSCAN_DOWN:
  439.          cmd->overscan = cmd->overscan + ( (tvtime_cmd == TVTIME_OVERSCAN_UP) ? 0.0025 : -0.0025 );
  440.          if( cmd->overscan > 0.4 ) cmd->overscan = 0.4; if( cmd->overscan < 0.0 ) cmd->overscan = 0.0;
  441. -
  442. +        cmd->changedoverscan = 1;
  443.          if( cmd->osd ) {
  444.              char message[ 200 ];
  445.              snprintf( message, sizeof( message ), _("Overscan: %.1f%%"),
  446. @@ -3056,10 +3057,10 @@ void commands_handle( commands_t *cmd, i
  447.          break;
  448.  
  449.      case TVTIME_MIXER_TOGGLE_MUTE:
  450. -        mixer_mute( !mixer_ismute() );
  451. +        mixer->mute( !mixer->ismute() );
  452.  
  453.          if( cmd->osd ) {
  454. -            tvtime_osd_show_data_bar( cmd->osd, _("Volume"), (mixer_get_volume()) & 0xff );
  455. +            tvtime_osd_show_data_bar( cmd->osd, _("Volume"), (mixer->get_volume()) & 0xff );
  456.          }
  457.          break;
  458.  
  459. @@ -3073,9 +3074,9 @@ void commands_handle( commands_t *cmd, i
  460.          /* Check to see if an argument was passed, if so, use it. */
  461.          if (atoi(arg) > 0) {
  462.              int perc = atoi(arg);
  463. -            volume = mixer_set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? perc : -perc ) );
  464. +            volume = mixer->set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? perc : -perc ) );
  465.          } else {
  466. -            volume = mixer_set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? 1 : -1 ) );
  467. +            volume = mixer->set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? 1 : -1 ) );
  468.          }
  469.  
  470.          if( cmd->osd ) {
  471. @@ -3492,6 +3493,7 @@ void commands_next_frame( commands_t *cm
  472.      cmd->togglepulldowndetection = 0;
  473.      cmd->togglematte = 0;
  474.      cmd->togglequiet = 0;
  475. +    cmd->changedoverscan = 0;
  476.      cmd->resizewindow = 0;
  477.      cmd->setdeinterlacer = 0;
  478.      cmd->setfreqtable = 0;
  479. @@ -3539,6 +3541,11 @@ int commands_toggle_aspect( commands_t *
  480.      return cmd->toggleaspect;
  481.  }
  482.  
  483. +int commands_get_changed_overscan( commands_t *cmd )
  484. +{
  485. +    return cmd->changedoverscan;
  486. +}
  487. +
  488.  int commands_toggle_alwaysontop( commands_t *cmd )
  489.  {
  490.      return cmd->togglealwaysontop;
  491. diff -Nurp tvtime-1.0.2/src/commands.c.orig tvtime-1.0.2-custom/src/commands.c.orig
  492. --- tvtime-1.0.2/src/commands.c.orig    1970-01-01 01:00:00.000000000 +0100
  493. +++ tvtime-1.0.2-custom/src/commands.c.orig     2011-05-29 13:07:28.102373294 +0200
  494. @@ -0,0 +1,3771 @@
  495. +/**
  496. + * Copyright (C) 2002 Doug Bell <drbell@users.sourceforge.net>.
  497. + * Copyright (C) 2003 Billy Biggs <vektor@dumbterm.net>.
  498. + *
  499. + * This program is free software; you can redistribute it and/or modify
  500. + * it under the terms of the GNU General Public License as published by
  501. + * the Free Software Foundation; either version 2, or (at your option)
  502. + * any later version.
  503. + *
  504. + * This program is distributed in the hope that it will be useful,
  505. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  506. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  507. + * GNU General Public License for more details.
  508. + *
  509. + * You should have received a copy of the GNU General Public License
  510. + * along with this program; if not, write to the Free Software Foundation,
  511. + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  512. + */
  513. +
  514. +#include <stdio.h>
  515. +#include <stdlib.h>
  516. +#include <string.h>
  517. +#include <unistd.h>
  518. +#include <ctype.h>
  519. +#include <time.h>
  520. +#ifdef HAVE_CONFIG_H
  521. +# include "config.h"
  522. +#endif
  523. +#ifdef ENABLE_NLS
  524. +# define _(string) gettext (string)
  525. +# include "gettext.h"
  526. +#else
  527. +# define _(string) (string)
  528. +#endif
  529. +#include "station.h"
  530. +#include "mixer.h"
  531. +#include "input.h"
  532. +#include "commands.h"
  533. +#include "utils.h"
  534. +#include "xmltv.h"
  535. +#include "tvtimeglyphs.h"
  536. +
  537. +#define NUM_FAVORITES 9
  538. +#define MAX_USER_MENUS 64
  539. +
  540. +/* Maximum number of steps to increment sleeptimer. */
  541. +#define SLEEPTIMER_NUMSTEPS 13
  542. +
  543. +enum menu_type
  544. +{
  545. +    MENU_REDIRECT,
  546. +    MENU_FAVORITES,
  547. +    MENU_USER
  548. +};
  549. +
  550. +typedef struct menu_names_s {
  551. +    const char *name;
  552. +    int menutype;
  553. +    const char *dest;
  554. +} menu_names_t;
  555. +
  556. +static menu_names_t menu_table[] = {
  557. +    { "root", MENU_REDIRECT, "root-tuner" },
  558. +    { "picture", MENU_REDIRECT, "picture-tuner" },
  559. +    { "input", MENU_REDIRECT, "input-ntsc" },
  560. +    { "favorites", MENU_FAVORITES, 0 },
  561. +};
  562. +
  563. +static int tvtime_num_builtin_menus( void )
  564. +{
  565. +    return ( sizeof( menu_table ) / sizeof( menu_names_t ) );
  566. +}
  567. +
  568. +static void set_redirect( const char *menu, const char *dest )
  569. +{
  570. +    int i;
  571. +
  572. +    for( i = 0; i < tvtime_num_builtin_menus(); i++ ) {
  573. +        if( !strcasecmp( menu, menu_table[ i ].name ) ) {
  574. +            menu_table[ i ].dest = dest;
  575. +            return;
  576. +        }
  577. +    }
  578. +}
  579. +
  580. +
  581. +static int sleeptimer_function( int step )
  582. +{
  583. +    if( step < 3 ) {
  584. +       return step * 10;
  585. +    } else {
  586. +       return (step - 2) * 30;
  587. +    }
  588. +}
  589. +
  590. +struct commands_s {
  591. +    config_t *cfg;
  592. +    videoinput_t *vidin;
  593. +    tvtime_osd_t *osd;
  594. +    station_mgr_t *stationmgr;
  595. +    char next_chan_buffer[ 5 ];
  596. +    int frame_counter;
  597. +    int digit_counter;
  598. +    int quit;
  599. +    int sleeptimer;
  600. +    time_t sleeptimer_start;
  601. +
  602. +    xmltv_t *xmltv;
  603. +
  604. +    int picturemode;
  605. +    int brightness;
  606. +    int contrast;
  607. +    int saturation;
  608. +    int hue;
  609. +
  610. +    int boost;
  611. +
  612. +    int displayinfo;
  613. +    int screenshot;
  614. +    char screenshotfile[ 2048 ];
  615. +    int printdebug;
  616. +    int showbars;
  617. +    int showdeinterlacerinfo;
  618. +    int togglefullscreen;
  619. +    int toggleaspect;
  620. +    int togglealwaysontop;
  621. +    int toggledeinterlacer;
  622. +    int togglepulldowndetection;
  623. +    int togglematte;
  624. +    int togglequiet;
  625. +    int framerate;
  626. +    int scan_channels;
  627. +    int pause;
  628. +    int halfsize;
  629. +    int resizewindow;
  630. +    int restarttvtime;
  631. +    int setdeinterlacer;
  632. +    int normset;
  633. +    const char *newnorm;
  634. +    int newinputwidth;
  635. +    char deinterlacer[ 128 ];
  636. +    int setfreqtable;
  637. +    char newfreqtable[ 128 ];
  638. +    int checkfreq;
  639. +    int usexds;
  640. +    int pulldown_alg;
  641. +    char newmatte[ 16 ];
  642. +    char newpos[ 16 ];
  643. +
  644. +    int delay;
  645. +
  646. +    int change_channel;
  647. +    int renumbering;
  648. +    int xmltvupdated;
  649. +    int tunerreset;
  650. +
  651. +    int apply_invert;
  652. +    int apply_mirror;
  653. +    int apply_chroma_kill;
  654. +
  655. +    double overscan;
  656. +
  657. +    vbidata_t *vbi;
  658. +    int capturemode;
  659. +
  660. +    int curfavorite;
  661. +    int numfavorites;
  662. +    int favorites[ NUM_FAVORITES ];
  663. +
  664. +    int menuactive;
  665. +    int curmenu;
  666. +    int curmenupos;
  667. +    int curmenusize;
  668. +    menu_t *curusermenu;
  669. +    menu_t *menus[ MAX_USER_MENUS ];
  670. +};
  671. +
  672. +static void menu_set_value( menu_t *menu, int newval, const char *icon )
  673. +{
  674. +    char string[ 128 ];
  675. +    snprintf( string, sizeof( string ), "%s  %s: %d",
  676. +              icon, _("Current"), newval );
  677. +    menu_set_text( menu, 1, string );
  678. +}
  679. +
  680. +static void update_xmltv_channel( commands_t *cmd )
  681. +{
  682. +    if( cmd->xmltv && cmd->osd ) {
  683. +        if( station_get_current_xmltv_id( cmd->stationmgr ) ) {
  684. +            xmltv_set_channel( cmd->xmltv, station_get_current_xmltv_id( cmd->stationmgr ) );
  685. +        } else {
  686. +            xmltv_set_channel( cmd->xmltv, xmltv_lookup_channel( cmd->xmltv,
  687. +                               station_get_current_channel_name( cmd->stationmgr ) ) );
  688. +        }
  689. +    } else if( cmd->osd ) {
  690. +        tvtime_osd_show_program_info( cmd->osd, 0, 0, 0 );
  691. +        tvtime_osd_set_info_available( cmd->osd, 0 );
  692. +    }
  693. +}
  694. +
  695. +static void display_xmltv_description( commands_t *cmd, const char *title,
  696. +                                       const char *subtitle,
  697. +                                       const char *description,
  698. +                                       const char *next_title )
  699. +{
  700. +    int cur = 0;
  701. +
  702. +    if( title ) {
  703. +        /* Using set_multitext for one line only gives you the truncating. */
  704. +        cur = tvtime_osd_list_set_multitext( cmd->osd, cur, title, 1 );
  705. +    } else {
  706. +        tvtime_osd_list_set_text( cmd->osd, cur++,
  707. +        /* TRANSLATORS: This refers to a TV program, not a computer program. */
  708. +                                  _("No program information available") );
  709. +    }
  710. +
  711. +    if( subtitle && *subtitle ) {
  712. +        cur = tvtime_osd_list_set_multitext( cmd->osd, cur, subtitle, 1 );
  713. +    } else {
  714. +        tvtime_osd_list_set_text( cmd->osd, cur++,
  715. +                                  _("No program information available") );
  716. +    }
  717. +
  718. +    if( description && *description ) {
  719. +        tvtime_osd_list_set_text( cmd->osd, cur++, "" );
  720. +        cur = tvtime_osd_list_set_multitext( cmd->osd, cur, description, 6 );
  721. +    }
  722. +
  723. +    if( next_title && *next_title ) {
  724. +        tvtime_osd_list_set_text( cmd->osd, cur++, "" );
  725. +        cur = tvtime_osd_list_set_multitext( cmd->osd, cur, next_title, 1 );
  726. +    }
  727. +    tvtime_osd_list_set_lines( cmd->osd, cur );
  728. +    tvtime_osd_list_set_hilight( cmd->osd, -1 );
  729. +    tvtime_osd_show_list( cmd->osd, 1, 1 );
  730. +}
  731. +
  732. +static void update_xmltv_display( commands_t *cmd )
  733. +{
  734. +    if( cmd->xmltv && cmd->osd ) {
  735. +        const char *desc;
  736. +        const char *title;
  737. +        time_t timestamp;
  738. +        char start_time[ 50 ];
  739. +        char end_time[ 50 ];
  740. +        char next_title[ 1024 ];
  741. +        char subtitle[ 1024 ];
  742. +
  743. +        timestamp = xmltv_get_start_time( cmd->xmltv );
  744. +        if( timestamp == 0 ) {
  745. +            /* No information available */
  746. +            start_time[0] = '\0';
  747. +            end_time[0] = '\0';
  748. +            subtitle[0] = '\0';
  749. +            title = 0;
  750. +            desc = 0;
  751. +        } else {
  752. +            strftime( start_time, 50, "%H:%M", localtime( &timestamp ) );
  753. +            timestamp = xmltv_get_end_time( cmd->xmltv );
  754. +            strftime( end_time, 50, "%H:%M", localtime( &timestamp ) );
  755. +
  756. +            if( xmltv_get_sub_title( cmd->xmltv ) ) {
  757. +               snprintf( subtitle, sizeof( subtitle ), "%s - %s - %s",
  758. +                         start_time, end_time,
  759. +                         xmltv_get_sub_title( cmd->xmltv ) );
  760. +            } else {
  761. +               snprintf( subtitle, sizeof( subtitle ), "%s - %s",
  762. +                         start_time, end_time );
  763. +            }
  764. +
  765. +            title = xmltv_get_title( cmd->xmltv );
  766. +            desc = xmltv_get_description( cmd->xmltv );
  767. +        }
  768. +
  769. +        if( xmltv_get_next_title( cmd->xmltv ) ) {
  770. +            snprintf( next_title, sizeof( next_title ),
  771. +                      _("Next: %s"), xmltv_get_next_title( cmd->xmltv ) );
  772. +        } else {
  773. +            *next_title = '\0';
  774. +        }
  775. +
  776. +        if( !cmd->displayinfo || cmd->menuactive ) {
  777. +            tvtime_osd_show_program_info( cmd->osd, title, subtitle, next_title );
  778. +            tvtime_osd_set_info_available( cmd->osd, desc && *desc );
  779. +        } else {
  780. +            tvtime_osd_show_program_info( cmd->osd, 0, 0, 0 );
  781. +            display_xmltv_description( cmd, title, subtitle, desc, next_title );
  782. +            tvtime_osd_set_info_available( cmd->osd, 0 );
  783. +        }
  784. +    }
  785. +}
  786. +
  787. +static void update_xmltv_listings( commands_t *cmd )
  788. +{
  789. +    if( cmd->xmltv && cmd->osd && cmd->vidin &&
  790. +        videoinput_has_tuner( cmd->vidin ) &&
  791. +        xmltv_needs_refresh( cmd->xmltv ) ) {
  792. +
  793. +        xmltv_refresh( cmd->xmltv );
  794. +        update_xmltv_display( cmd );
  795. +        cmd->xmltvupdated = 1;
  796. +    }
  797. +}
  798. +
  799. +static void reset_stations_menu( menu_t *menu, int ntsc, int pal, int secam,
  800. +                                 int ntsccable, int active, int signaldetect,
  801. +                                 int scanning, int v4l2, int default_paldk,
  802. +                                 int paldk )
  803. +{
  804. +    char string[ 128 ];
  805. +    int cur;
  806. +
  807. +    /* Start over. */
  808. +    menu_reset_num_lines( menu );
  809. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "root" );
  810. +    cur = 1;
  811. +
  812. +    if( !ntsc ) {
  813. +        snprintf( string, sizeof( string ), TVTIME_ICON_RENUMBERCHANNEL "  %s",
  814. +                  _("Renumber current channel") );
  815. +        menu_set_text( menu, cur, string );
  816. +        menu_set_enter_command( menu, cur, TVTIME_CHANNEL_RENUMBER, "" );
  817. +        cur++;
  818. +    }
  819. +
  820. +    if( active ) {
  821. +        snprintf( string, sizeof( string ), TVTIME_ICON_GENERALTOGGLEON "  %s",
  822. +                  _("Current channel active in list") );
  823. +    } else {
  824. +        snprintf( string, sizeof( string ), TVTIME_ICON_GENERALTOGGLEOFF "  %s",
  825. +                  _("Current channel active in list") );
  826. +    }
  827. +    menu_set_text( menu, cur, string );
  828. +    menu_set_enter_command( menu, cur, TVTIME_CHANNEL_SKIP, "" );
  829. +    cur++;
  830. +
  831. +    if( signaldetect ) {
  832. +        if( scanning ) {
  833. +            snprintf( string, sizeof( string ),
  834. +                      TVTIME_ICON_SCANFORSTATIONS "  %s",
  835. +                      _("Stop channel scan") );
  836. +        } else {
  837. +            snprintf( string, sizeof( string ),
  838. +                      TVTIME_ICON_SCANFORSTATIONS "  %s",
  839. +                      _("Scan channels for signal") );
  840. +        }
  841. +        menu_set_text( menu, cur, string );
  842. +        menu_set_enter_command( menu, cur, TVTIME_CHANNEL_SCAN, "" );
  843. +        cur++;
  844. +    }
  845. +
  846. +    snprintf( string, sizeof( string ), TVTIME_ICON_ALLCHANNELSACTIVE "  %s",
  847. +              _("Reset all channels as active") );
  848. +    menu_set_text( menu, cur, string );
  849. +    menu_set_enter_command( menu, cur, TVTIME_CHANNEL_ACTIVATE_ALL, "" );
  850. +    cur++;
  851. +
  852. +    snprintf( string, sizeof( string ), TVTIME_ICON_FINETUNECHANNEL "  %s",
  853. +              _("Finetune current channel") );
  854. +    menu_set_text( menu, cur, string );
  855. +    menu_set_enter_command( menu, cur, TVTIME_SHOW_MENU, "finetune" );
  856. +    cur++;
  857. +
  858. +    if( ntsccable ) {
  859. +        snprintf( string, sizeof( string ), TVTIME_ICON_CHANGENTSCMODE "  %s",
  860. +                  _("Change NTSC cable mode") );
  861. +        menu_set_text( menu, cur, string );
  862. +        menu_set_enter_command( menu, cur, TVTIME_TOGGLE_NTSC_CABLE_MODE, "" );
  863. +        cur++;
  864. +    } else if( pal || secam ) {
  865. +        snprintf( string, sizeof( string ), TVTIME_ICON_TVLOGO "  %s", pal?
  866. +                  _("Set current channel as SECAM"):
  867. +                  _("Set current channel as PAL") );
  868. +        menu_set_text( menu, cur, string );
  869. +        menu_set_enter_command( menu, cur, TVTIME_TOGGLE_PAL_SECAM, "" );
  870. +        cur++;
  871. +    }
  872. +
  873. +    if( pal && v4l2 ) {
  874. +        const char *amode = "PAL-BG";
  875. +        if( paldk == VIDEOINPUT_PAL_I_AUDIO ) {
  876. +            amode = "PAL-I";
  877. +        } else if( paldk == VIDEOINPUT_PAL_DK_AUDIO ) {
  878. +            amode = "PAL-DK";
  879. +        }
  880. +        snprintf( string, sizeof( string ),
  881. +                  TVTIME_ICON_VIDEOINPUT "  %s (%s)",
  882. +                  _("Switch audio standard"), amode );
  883. +        menu_set_text( menu, cur, string );
  884. +        menu_set_enter_command( menu, cur, TVTIME_TOGGLE_CHANNEL_PAL_DK, "" );
  885. +        cur++;
  886. +    }
  887. +
  888. +    snprintf( string, sizeof( string ), TVTIME_ICON_FREQUENCYTABLESEL "  %s",
  889. +              _("Change frequency table") );
  890. +    menu_set_text( menu, cur, string );
  891. +    menu_set_enter_command( menu, cur, TVTIME_SHOW_MENU, "frequencies" );
  892. +    cur++;
  893. +
  894. +    snprintf( string, sizeof( string ), TVTIME_ICON_STATIONMANAGEMENT "  %s",
  895. +              signaldetect?  _("Disable signal detection"):
  896. +              _("Enable signal detection") );
  897. +    menu_set_text( menu, cur, string );
  898. +    menu_set_enter_command( menu, cur, TVTIME_TOGGLE_SIGNAL_DETECTION, "" );
  899. +    cur++;
  900. +
  901. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  902. +              _("Back") );
  903. +    menu_set_text( menu, cur, string );
  904. +    menu_set_enter_command( menu, cur, TVTIME_SHOW_MENU, "root" );
  905. +}
  906. +
  907. +static void reset_xmltv_languages_menu( menu_t *menu, xmltv_t *xmltv )
  908. +{
  909. +    int num = xmltv_get_num_languages( xmltv );
  910. +    const char *cur = xmltv_get_language( xmltv );
  911. +    char string[ 128 ];
  912. +    int i;
  913. +
  914. +    if( !xmltv ) return;
  915. +
  916. +    menu_reset_num_lines( menu );
  917. +    menu_set_back_command( menu, TVTIME_MENU_EXIT, 0 );
  918. +    snprintf( string, sizeof( string ), "%s  %s",
  919. +              cur? TVTIME_ICON_RADIOOFF : TVTIME_ICON_RADIOON,
  920. +              _("Default language") );
  921. +    menu_set_text( menu, 1, string );
  922. +    menu_set_enter_command( menu, 1, TVTIME_SET_XMLTV_LANGUAGE, "none" );
  923. +
  924. +    for( i = 1; i <= num; i++ ) {
  925. +        const char *code = xmltv_get_language_code( xmltv, i );
  926. +        const char *name = xmltv_get_language_name( xmltv, i );
  927. +        const char *radio;
  928. +
  929. +        if( cur && code && !strncasecmp( cur, code, 2 ) ) {
  930. +            radio = TVTIME_ICON_RADIOON;
  931. +        } else {
  932. +            radio = TVTIME_ICON_RADIOOFF;
  933. +        }
  934. +
  935. +        snprintf( string, sizeof( string ), "%s  %s (%s)",
  936. +                  radio, name? name : _("Unknown language"), code );
  937. +        menu_set_text( menu, i + 1, string );
  938. +        menu_set_enter_command( menu, i + 1,
  939. +                                TVTIME_SET_XMLTV_LANGUAGE, code );
  940. +    }
  941. +
  942. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  943. +              _("Back") );
  944. +    menu_set_text( menu, num + 2, string );
  945. +    menu_set_enter_command( menu, num + 2, TVTIME_MENU_EXIT, 0 );
  946. +}
  947. +
  948. +static void reinit_tuner( commands_t *cmd )
  949. +{
  950. +    /* Setup the tuner if available. */
  951. +    if( cmd->vbi ) {
  952. +        vbidata_reset( cmd->vbi );
  953. +        vbidata_capture_mode( cmd->vbi, cmd->capturemode );
  954. +    }
  955. +
  956. +    set_redirect( "root", "root-notuner" );
  957. +    set_redirect( "picture", "picture-notuner" );
  958. +
  959. +    if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  960. +        int norm;
  961. +
  962. +        set_redirect( "root", "root-tuner" );
  963. +        set_redirect( "picture", "picture-tuner" );
  964. +
  965. +        cmd->tunerreset = 1;
  966. +
  967. +        videoinput_set_tuner_freq( cmd->vidin, station_get_current_frequency( cmd->stationmgr )
  968. +                                   + ((station_get_current_finetune( cmd->stationmgr ) * 1000)/16) );
  969. +        menu_set_value( commands_get_menu( cmd, "finetune" ), station_get_current_finetune( cmd->stationmgr ), TVTIME_ICON_FINETUNECHANNEL );
  970. +        commands_refresh_menu( cmd );
  971. +
  972. +        norm = videoinput_get_norm_number( station_get_current_norm( cmd->stationmgr ) );
  973. +        if( norm >= 0 ) {
  974. +            videoinput_switch_pal_secam( cmd->vidin, norm );
  975. +        }
  976. +        videoinput_set_pal_audio_mode( cmd->vidin,
  977. +                                       station_get_current_audio_norm( cmd->stationmgr ) );
  978. +
  979. +        if( config_get_save_restore_picture( cmd->cfg ) ) {
  980. +            int brightness = station_get_current_brightness( cmd->stationmgr );
  981. +            int contrast = station_get_current_contrast( cmd->stationmgr );
  982. +            int saturation = station_get_current_saturation( cmd->stationmgr );
  983. +            int hue = station_get_current_hue( cmd->stationmgr );
  984. +
  985. +            if( brightness >= 0 ) {
  986. +                videoinput_set_brightness( cmd->vidin, brightness );
  987. +            } else {
  988. +                videoinput_set_brightness( cmd->vidin, cmd->brightness );
  989. +            }
  990. +            if( contrast >= 0 ) {
  991. +                videoinput_set_contrast( cmd->vidin, contrast );
  992. +            } else {
  993. +                videoinput_set_contrast( cmd->vidin, cmd->contrast );
  994. +            }
  995. +            if( saturation >= 0 ) {
  996. +                videoinput_set_saturation( cmd->vidin, saturation );
  997. +            } else {
  998. +                videoinput_set_saturation( cmd->vidin, cmd->saturation );
  999. +            }
  1000. +            if( hue >= 0 ) {
  1001. +                videoinput_set_hue( cmd->vidin, hue );
  1002. +            } else {
  1003. +                videoinput_set_hue( cmd->vidin, cmd->hue );
  1004. +            }
  1005. +        }
  1006. +
  1007. +        if( cmd->osd ) {
  1008. +            char channel_display[ 20 ];
  1009. +            const char *xmltv_name = 0;
  1010. +
  1011. +            snprintf( channel_display, sizeof( channel_display ), "%d",
  1012. +                      station_get_current_id( cmd->stationmgr ) );
  1013. +            update_xmltv_channel( cmd );
  1014. +            if ( cmd->xmltv && !strcmp( station_get_current_channel_name( cmd->stationmgr ), channel_display ) ) {
  1015. +                xmltv_name = xmltv_lookup_channel_name( cmd->xmltv, xmltv_get_channel( cmd->xmltv ) );
  1016. +                if ( xmltv_name ) {
  1017. +                    tvtime_osd_set_channel_name( cmd->osd, xmltv_name );
  1018. +                }
  1019. +            }
  1020. +            if ( !xmltv_name ) {
  1021. +                tvtime_osd_set_channel_name( cmd->osd, station_get_current_channel_name( cmd->stationmgr ) );
  1022. +            }
  1023. +            tvtime_osd_set_norm( cmd->osd, videoinput_get_norm_name( videoinput_get_norm( cmd->vidin ) ) );
  1024. +            tvtime_osd_set_audio_mode( cmd->osd, videoinput_get_audio_mode_name( cmd->vidin, videoinput_get_audio_mode( cmd->vidin ) ) );
  1025. +            tvtime_osd_set_freq_table( cmd->osd, station_get_current_band( cmd->stationmgr ) );
  1026. +            tvtime_osd_set_channel_number( cmd->osd, channel_display );
  1027. +            tvtime_osd_set_network_call( cmd->osd, station_get_current_network_call_letters( cmd->stationmgr ) );
  1028. +            tvtime_osd_set_network_name( cmd->osd, station_get_current_network_name( cmd->stationmgr ) );
  1029. +            tvtime_osd_set_show_name( cmd->osd, "" );
  1030. +            tvtime_osd_set_show_rating( cmd->osd, "" );
  1031. +            tvtime_osd_set_show_start( cmd->osd, "" );
  1032. +            tvtime_osd_set_show_length( cmd->osd, "" );
  1033. +            tvtime_osd_show_info( cmd->osd );
  1034. +
  1035. +            reset_stations_menu( commands_get_menu( cmd, "stations" ),
  1036. +                                 (videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC ||
  1037. +                                  videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC_JP),
  1038. +                                 videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_PAL,
  1039. +                                 videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_SECAM,
  1040. +                                 (!strcasecmp( cmd->newfreqtable, "us-cable" ) ||
  1041. +                                  !strcasecmp( cmd->newfreqtable, "us-cable100" )),
  1042. +                                 station_get_current_active( cmd->stationmgr ), cmd->checkfreq,
  1043. +                                 cmd->scan_channels,
  1044. +                                 videoinput_is_v4l2( cmd->vidin ),
  1045. +                                 station_get_default_audio_norm( cmd->stationmgr ),
  1046. +                                 station_get_current_audio_norm( cmd->stationmgr ) );
  1047. +            commands_refresh_menu( cmd );
  1048. +        }
  1049. +        cmd->frame_counter = 0;
  1050. +    } else if( cmd->osd ) {
  1051. +        tvtime_osd_set_audio_mode( cmd->osd, "" );
  1052. +        tvtime_osd_set_freq_table( cmd->osd, "" );
  1053. +        tvtime_osd_set_channel_number( cmd->osd, "" );
  1054. +        tvtime_osd_set_channel_name( cmd->osd, "" );
  1055. +        tvtime_osd_set_network_call( cmd->osd, "" );
  1056. +        tvtime_osd_set_network_name( cmd->osd, "" );
  1057. +        tvtime_osd_set_show_name( cmd->osd, "" );
  1058. +        tvtime_osd_set_show_rating( cmd->osd, "" );
  1059. +        tvtime_osd_set_show_start( cmd->osd, "" );
  1060. +        tvtime_osd_set_show_length( cmd->osd, "" );
  1061. +        tvtime_osd_show_program_info( cmd->osd, 0, 0, 0 );
  1062. +        tvtime_osd_set_info_available( cmd->osd, 0 );
  1063. +        tvtime_osd_show_info( cmd->osd );
  1064. +        tvtime_osd_clear( cmd->osd );
  1065. +    }
  1066. +
  1067. +    if( config_get_save_restore_picture( cmd->cfg ) && cmd->vidin && !videoinput_has_tuner( cmd->vidin ) ) {
  1068. +        if( cmd->brightness >= 0 ) {
  1069. +            videoinput_set_brightness( cmd->vidin, cmd->brightness );
  1070. +        }
  1071. +        if( cmd->contrast >= 0 ) {
  1072. +            videoinput_set_contrast( cmd->vidin, cmd->contrast );
  1073. +        }
  1074. +        if( cmd->saturation >= 0 ) {
  1075. +            videoinput_set_saturation( cmd->vidin, cmd->saturation );
  1076. +        }
  1077. +        if( cmd->hue >= 0 ) {
  1078. +            videoinput_set_hue( cmd->vidin, cmd->hue );
  1079. +        }
  1080. +    }
  1081. +
  1082. +    if( cmd->vidin ) {
  1083. +        menu_set_value (commands_get_menu (cmd, "brightness"),
  1084. +                        videoinput_get_brightness (cmd->vidin),
  1085. +                        TVTIME_ICON_BRIGHTNESS);
  1086. +        menu_set_value (commands_get_menu (cmd, "contrast"),
  1087. +                        videoinput_get_contrast (cmd->vidin),
  1088. +                        TVTIME_ICON_CONTRAST);
  1089. +        menu_set_value (commands_get_menu (cmd, "saturation"),
  1090. +                        videoinput_get_saturation (cmd->vidin),
  1091. +                        TVTIME_ICON_SATURATION);
  1092. +        menu_set_value (commands_get_menu (cmd, "hue"),
  1093. +                        videoinput_get_hue (cmd->vidin),
  1094. +                        TVTIME_ICON_HUE);
  1095. +    }
  1096. +}
  1097. +
  1098. +static void reset_pal_input_menu( menu_t *menu, videoinput_t *vidin, station_mgr_t *stationmgr )
  1099. +{
  1100. +    char string[ 128 ];
  1101. +    int cur = 2;
  1102. +
  1103. +    snprintf( string, sizeof( string ), TVTIME_ICON_STATIONMANAGEMENT "  %s",
  1104. +              _("Preferred audio mode") );
  1105. +    menu_set_text( menu, cur, string );
  1106. +    menu_set_enter_command( menu, cur, TVTIME_SHOW_MENU, "audiomode" );
  1107. +    cur++;
  1108. +
  1109. +    if( videoinput_is_v4l2( vidin ) ) {
  1110. +        const char *curnorm = "PAL-BG";
  1111. +        int defnorm = station_get_default_audio_norm( stationmgr );
  1112. +        if( defnorm == VIDEOINPUT_PAL_I_AUDIO ) {
  1113. +            curnorm = "PAL-I";
  1114. +        } else if( defnorm == VIDEOINPUT_PAL_DK_AUDIO ) {
  1115. +            curnorm = "PAL-DK";
  1116. +        }
  1117. +        snprintf( string, sizeof( string ),
  1118. +                  TVTIME_ICON_TVPGICON "  %s (%s)",
  1119. +                  _("Change default audio standard"), curnorm );
  1120. +        menu_set_text( menu, cur, string );
  1121. +        menu_set_enter_command( menu, cur, TVTIME_TOGGLE_PAL_DK_AUDIO, "" );
  1122. +        cur++;
  1123. +    }
  1124. +
  1125. +    snprintf( string, sizeof( string ), TVTIME_ICON_STATIONMANAGEMENT "  %s",
  1126. +              _("Audio volume boost") );
  1127. +    menu_set_text( menu, cur, string );
  1128. +    menu_set_enter_command( menu, cur, TVTIME_SHOW_MENU, "audioboost" );
  1129. +    cur++;
  1130. +
  1131. +    snprintf( string, sizeof( string ), TVTIME_ICON_TELEVISIONSTANDARD "  %s",
  1132. +              _("Television standard") );
  1133. +    menu_set_text( menu, cur, string );
  1134. +    menu_set_enter_command( menu, cur, TVTIME_SHOW_MENU, "norm" );
  1135. +    cur++;
  1136. +
  1137. +    snprintf( string, sizeof( string ), TVTIME_ICON_INPUTWIDTH "  %s",
  1138. +              _("Horizontal resolution") );
  1139. +    menu_set_text( menu, cur, string );
  1140. +    menu_set_enter_command( menu, cur, TVTIME_SHOW_MENU, "hres" );
  1141. +    cur++;
  1142. +
  1143. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1144. +              _("Back") );
  1145. +    menu_set_text( menu, cur, string );
  1146. +    menu_set_enter_command( menu, cur, TVTIME_SHOW_MENU, "root" );
  1147. +    cur++;
  1148. +}
  1149. +
  1150. +static void reset_frequency_menu( menu_t *menu, int norm, const char *tablename )
  1151. +{
  1152. +    char string[ 128 ];
  1153. +
  1154. +    if( norm == VIDEOINPUT_NTSC || norm == VIDEOINPUT_PAL_M || norm == VIDEOINPUT_PAL_NC ) {
  1155. +        snprintf( string, sizeof( string ),
  1156. +                  !strcasecmp( tablename, "us-cable" ) ?
  1157. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1158. +                  _("Cable") );
  1159. +        menu_set_text( menu, 1, string );
  1160. +        menu_set_enter_command( menu, 1, TVTIME_SET_FREQUENCY_TABLE, "us-cable" );
  1161. +        menu_set_back_command( menu, TVTIME_SHOW_MENU, "stations" );
  1162. +
  1163. +        snprintf( string, sizeof( string ),
  1164. +                  !strcasecmp( tablename, "us-broadcast" ) ?
  1165. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1166. +                  _("Broadcast") );
  1167. +        menu_set_text( menu, 2, string );
  1168. +        menu_set_enter_command( menu, 2, TVTIME_SET_FREQUENCY_TABLE, "us-broadcast" );
  1169. +
  1170. +        snprintf( string, sizeof( string ),
  1171. +                  !strcasecmp( tablename, "us-cable100" ) ?
  1172. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1173. +                  _("Cable with channels 100+") );
  1174. +        menu_set_text( menu, 3, string );
  1175. +        menu_set_enter_command( menu, 3, TVTIME_SET_FREQUENCY_TABLE, "us-cable100" );
  1176. +
  1177. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1178. +                  _("Back") );
  1179. +        menu_set_text( menu, 4, string );
  1180. +        menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "stations" );
  1181. +    } else if( norm == VIDEOINPUT_NTSC_JP ) {
  1182. +        snprintf( string, sizeof( string ),
  1183. +                  !strcasecmp( tablename, "japan-cable" ) ?
  1184. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1185. +                  _("Cable") );
  1186. +        menu_set_text( menu, 1, string );
  1187. +        menu_set_back_command( menu, TVTIME_SHOW_MENU, "stations" );
  1188. +        menu_set_enter_command( menu, 1, TVTIME_SET_FREQUENCY_TABLE, "japan-cable" );
  1189. +
  1190. +        snprintf( string, sizeof( string ),
  1191. +                  !strcasecmp( tablename, "japan-broadcast" ) ?
  1192. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1193. +                  _("Broadcast") );
  1194. +        menu_set_text( menu, 2, string );
  1195. +        menu_set_enter_command( menu, 2, TVTIME_SET_FREQUENCY_TABLE, "japan-broadcast" );
  1196. +
  1197. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1198. +                  _("Back") );
  1199. +        menu_set_text( menu, 3, string );
  1200. +        menu_set_enter_command( menu, 3, TVTIME_SHOW_MENU, "input" );
  1201. +    } else {
  1202. +        snprintf( string, sizeof( string ),
  1203. +                  !strcasecmp( tablename, "europe" ) ?
  1204. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1205. +                  _("Europe") );
  1206. +        menu_set_text( menu, 1, string );
  1207. +        menu_set_enter_command( menu, 1, TVTIME_SET_FREQUENCY_TABLE, "europe" );
  1208. +        menu_set_back_command( menu, TVTIME_SHOW_MENU, "stations" );
  1209. +
  1210. +        snprintf( string, sizeof( string ),
  1211. +                  !strcasecmp( tablename, "russia" ) ?
  1212. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1213. +                  _("Russia") );
  1214. +        menu_set_text( menu, 2, string );
  1215. +        menu_set_enter_command( menu, 2, TVTIME_SET_FREQUENCY_TABLE, "russia" );
  1216. +
  1217. +        snprintf( string, sizeof( string ),
  1218. +                  !strcasecmp( tablename, "france" ) ?
  1219. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1220. +                  _("France") );
  1221. +        menu_set_text( menu, 3, string );
  1222. +        menu_set_enter_command( menu, 3, TVTIME_SET_FREQUENCY_TABLE, "france" );
  1223. +
  1224. +        snprintf( string, sizeof( string ),
  1225. +                  !strcasecmp( tablename, "australia" ) ?
  1226. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1227. +                  _("Australia") );
  1228. +        menu_set_text( menu, 4, string );
  1229. +        menu_set_enter_command( menu, 4, TVTIME_SET_FREQUENCY_TABLE, "australia" );
  1230. +
  1231. +        snprintf( string, sizeof( string ),
  1232. +                  !strcasecmp( tablename, "australia-optus" ) ?
  1233. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1234. +                  _("Australia (Optus)") );
  1235. +        menu_set_text( menu, 5, string );
  1236. +        menu_set_enter_command( menu, 5, TVTIME_SET_FREQUENCY_TABLE, "australia-optus" );
  1237. +
  1238. +        snprintf( string, sizeof( string ),
  1239. +                  !strcasecmp( tablename, "newzealand" ) ?
  1240. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1241. +                  _("New Zealand") );
  1242. +        menu_set_text( menu, 6, string );
  1243. +        menu_set_enter_command( menu, 6, TVTIME_SET_FREQUENCY_TABLE, "newzealand" );
  1244. +
  1245. +        snprintf( string, sizeof( string ),
  1246. +                  !strcasecmp( tablename, "china-broadcast" ) ?
  1247. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1248. +                  _("China Broadcast") );
  1249. +        menu_set_text( menu, 7, string );
  1250. +        menu_set_enter_command( menu, 7, TVTIME_SET_FREQUENCY_TABLE, "china-broadcast" );
  1251. +        
  1252. +        snprintf( string, sizeof( string ),
  1253. +                  !strcasecmp( tablename, "southafrica" ) ?
  1254. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1255. +                  _("South Africa") );
  1256. +        menu_set_text( menu, 8, string );
  1257. +        menu_set_enter_command( menu, 8, TVTIME_SET_FREQUENCY_TABLE, "southafrica" );
  1258. +
  1259. +        snprintf( string, sizeof( string ),
  1260. +                  !strcasecmp( tablename, "custom" ) ?
  1261. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1262. +                  _("Custom (first run tvtime-scanner)") );
  1263. +        menu_set_text( menu, 9, string );
  1264. +        menu_set_enter_command( menu, 9, TVTIME_SET_FREQUENCY_TABLE, "custom" );
  1265. +
  1266. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1267. +                  _("Back") );
  1268. +        menu_set_text( menu, 10, string );
  1269. +        menu_set_enter_command( menu, 10, TVTIME_SHOW_MENU, "stations" );
  1270. +    }
  1271. +}
  1272. +
  1273. +static void reset_audio_boost_menu( menu_t *menu, int curvol )
  1274. +{
  1275. +    char string[ 128 ];
  1276. +
  1277. +    snprintf( string, sizeof( string ), (curvol == -1) ?
  1278. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1279. +              _("Disabled") );
  1280. +    menu_set_text( menu, 1, string );
  1281. +    menu_set_enter_command( menu, 1, TVTIME_SET_AUDIO_BOOST, "-1" );
  1282. +
  1283. +    snprintf( string, sizeof( string ), (curvol == 50) ?
  1284. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1285. +              _("Quiet") );
  1286. +    menu_set_text( menu, 2, string );
  1287. +    menu_set_enter_command( menu, 2, TVTIME_SET_AUDIO_BOOST, "50" );
  1288. +
  1289. +    snprintf( string, sizeof( string ), (curvol == 90) ?
  1290. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1291. +              _("Medium") );
  1292. +    menu_set_text( menu, 3, string );
  1293. +    menu_set_enter_command( menu, 3, TVTIME_SET_AUDIO_BOOST, "90" );
  1294. +
  1295. +    snprintf( string, sizeof( string ), (curvol == 100) ?
  1296. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1297. +              _("Full") );
  1298. +    menu_set_text( menu, 4, string );
  1299. +    menu_set_enter_command( menu, 4, TVTIME_SET_AUDIO_BOOST, "100" );
  1300. +
  1301. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1302. +              _("Back") );
  1303. +    menu_set_text( menu, 5, string );
  1304. +    menu_set_enter_command( menu, 5, TVTIME_SHOW_MENU, "input" );
  1305. +}
  1306. +
  1307. +static void reset_inputwidth_menu( menu_t *menu, int inputwidth, int maxwidth )
  1308. +{
  1309. +    char string[ 128 ];
  1310. +    int entry_num;
  1311. +
  1312. +    snprintf( string, sizeof( string ),
  1313. +              _("%s  Current: %d pixels"), TVTIME_ICON_INPUTWIDTH, inputwidth );
  1314. +    menu_set_text( menu, 1, string );
  1315. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "input" );
  1316. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "input" );
  1317. +
  1318. +    snprintf( string, sizeof( string ), (inputwidth == 360) ?
  1319. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1320. +              _("Low (360 pixels)") );
  1321. +    menu_set_text( menu, 2, string );
  1322. +    menu_set_enter_command( menu, 2, TVTIME_SET_INPUT_WIDTH, "360" );
  1323. +
  1324. +    snprintf( string, sizeof( string ), (inputwidth == 576) ?
  1325. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1326. +              _("Moderate (576 pixels)") );
  1327. +    menu_set_text( menu, 3, string );
  1328. +    menu_set_enter_command( menu, 3, TVTIME_SET_INPUT_WIDTH, "576" );
  1329. +
  1330. +    snprintf( string, sizeof( string ), (inputwidth == 720) ?
  1331. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1332. +              _("Standard (720 pixels)") );
  1333. +    menu_set_text( menu, 4, string );
  1334. +    menu_set_enter_command( menu, 4, TVTIME_SET_INPUT_WIDTH, "720" );
  1335. +
  1336. +    snprintf( string, sizeof( string ), (inputwidth == 768) ?
  1337. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1338. +              _("High (768 pixels)") );
  1339. +    menu_set_text( menu, 5, string );
  1340. +    menu_set_enter_command( menu, 5, TVTIME_SET_INPUT_WIDTH, "768" );
  1341. +
  1342. +    entry_num = 6;
  1343. +    if( maxwidth > 768 ) {
  1344. +        snprintf( string, sizeof( string ), _("%s  Maximum (%d pixels)"),
  1345. +                  (inputwidth == maxwidth) ?
  1346. +                      TVTIME_ICON_RADIOON : TVTIME_ICON_RADIOOFF, maxwidth );
  1347. +        menu_set_text( menu, entry_num, string );
  1348. +        snprintf( string, sizeof( string ), "%d", maxwidth );
  1349. +        menu_set_enter_command( menu, entry_num,
  1350. +                                TVTIME_SET_INPUT_WIDTH, string );
  1351. +        entry_num++;
  1352. +    }
  1353. +    snprintf( string, sizeof( string ), TVTIME_ICON_RESTART "  %s",
  1354. +              _("Restart with new settings") );
  1355. +    menu_set_text( menu, entry_num, string );
  1356. +    menu_set_enter_command( menu, entry_num, TVTIME_RESTART, "" );
  1357. +    entry_num++;
  1358. +
  1359. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1360. +              _("Back") );
  1361. +    menu_set_text( menu, entry_num, string );
  1362. +    menu_set_enter_command( menu, entry_num, TVTIME_SHOW_MENU, "input" );
  1363. +}
  1364. +
  1365. +static void reset_norm_menu( menu_t *menu, const char *norm )
  1366. +{
  1367. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "input" );
  1368. +
  1369. +    menu_set_text (menu, 1, strcasecmp (norm, "ntsc") == 0 ?
  1370. +                   TVTIME_ICON_RADIOON "  NTSC" :
  1371. +                   TVTIME_ICON_RADIOOFF "  NTSC");
  1372. +    menu_set_enter_command( menu, 1, TVTIME_SET_NORM, "ntsc" );
  1373. +
  1374. +    menu_set_text (menu, 2, strcasecmp (norm, "pal") == 0 ?
  1375. +                   TVTIME_ICON_RADIOON "  PAL" :
  1376. +                   TVTIME_ICON_RADIOOFF "  PAL");
  1377. +    menu_set_enter_command( menu, 2, TVTIME_SET_NORM, "pal" );
  1378. +
  1379. +    menu_set_text (menu, 3, strcasecmp (norm, "secam") == 0 ?
  1380. +                   TVTIME_ICON_RADIOON "  SECAM" :
  1381. +                   TVTIME_ICON_RADIOOFF "  SECAM");
  1382. +    menu_set_enter_command( menu, 3, TVTIME_SET_NORM, "secam" );
  1383. +
  1384. +    menu_set_text (menu, 4, strcasecmp (norm, "pal-nc") == 0 ?
  1385. +                   TVTIME_ICON_RADIOON "  PAL-NC" :
  1386. +                   TVTIME_ICON_RADIOOFF "  PAL-NC");
  1387. +    menu_set_enter_command( menu, 4, TVTIME_SET_NORM, "pal-nc" );
  1388. +
  1389. +    menu_set_text (menu, 5, strcasecmp (norm, "pal-m") == 0 ?
  1390. +                   TVTIME_ICON_RADIOON "  PAL-M" :
  1391. +                   TVTIME_ICON_RADIOOFF "  PAL-M");
  1392. +    menu_set_enter_command( menu, 5, TVTIME_SET_NORM, "pal-m" );
  1393. +
  1394. +    menu_set_text (menu, 6, strcasecmp (norm, "pal-n") == 0 ?
  1395. +                   TVTIME_ICON_RADIOON "  PAL-N" :
  1396. +                   TVTIME_ICON_RADIOOFF "  PAL-N");
  1397. +    menu_set_enter_command( menu, 6, TVTIME_SET_NORM, "pal-n" );
  1398. +
  1399. +    menu_set_text (menu, 7, strcasecmp (norm, "ntsc-jp") == 0 ?
  1400. +                   TVTIME_ICON_RADIOON "  NTSC-JP" :
  1401. +                   TVTIME_ICON_RADIOOFF "  NTSC-JP");
  1402. +    menu_set_enter_command( menu, 7, TVTIME_SET_NORM, "ntsc-jp" );
  1403. +
  1404. +    menu_set_text (menu, 8, strcasecmp (norm, "pal-60") == 0 ?
  1405. +                   TVTIME_ICON_RADIOON "  PAL-60" :
  1406. +                   TVTIME_ICON_RADIOOFF "  PAL-60");
  1407. +    menu_set_enter_command( menu, 8, TVTIME_SET_NORM, "pal-60" );
  1408. +}
  1409. +
  1410. +static void reset_audio_mode_menu( menu_t *menu, int ntsc, int curmode )
  1411. +{
  1412. +    char string[ 128 ];
  1413. +
  1414. +    snprintf( string, sizeof( string ), curmode == VIDEOINPUT_MONO ?
  1415. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1416. +              _("Mono") );
  1417. +    menu_set_text( menu, 1, string );
  1418. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "input" );
  1419. +    menu_set_enter_command( menu, 1, TVTIME_SET_AUDIO_MODE, "mono" );
  1420. +
  1421. +    snprintf( string, sizeof( string ), curmode == VIDEOINPUT_STEREO ?
  1422. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1423. +              _("Stereo") );
  1424. +    menu_set_text( menu, 2, string );
  1425. +    menu_set_enter_command( menu, 2, TVTIME_SET_AUDIO_MODE, "stereo" );
  1426. +
  1427. +    if( ntsc ) {
  1428. +        snprintf( string, sizeof( string ), (curmode == VIDEOINPUT_LANG1 ||
  1429. +                                            curmode == VIDEOINPUT_LANG2) ?
  1430. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1431. +                  _("SAP") );
  1432. +        menu_set_text( menu, 3, string );
  1433. +        menu_set_enter_command( menu, 3, TVTIME_SET_AUDIO_MODE, "sap" );
  1434. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1435. +                  _("Back") );
  1436. +
  1437. +        menu_set_text( menu, 4, string );
  1438. +        menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "input" );
  1439. +    } else {
  1440. +        snprintf( string, sizeof( string ), (curmode == VIDEOINPUT_LANG1) ?
  1441. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1442. +                  _("Primary Language") );
  1443. +        menu_set_text( menu, 3, string );
  1444. +        menu_set_enter_command( menu, 3, TVTIME_SET_AUDIO_MODE, "lang1" );
  1445. +        snprintf( string, sizeof( string ), (curmode == VIDEOINPUT_LANG2) ?
  1446. +                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  1447. +                  _("Secondary Language") );
  1448. +        menu_set_text( menu, 4, string );
  1449. +        menu_set_enter_command( menu, 4, TVTIME_SET_AUDIO_MODE, "lang2" );
  1450. +
  1451. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1452. +                  _("Back") );
  1453. +        menu_set_text( menu, 5, string );
  1454. +        menu_set_enter_command( menu, 5, TVTIME_SHOW_MENU, "input" );
  1455. +    }
  1456. +}
  1457. +
  1458. +static void reset_overscan_menu( menu_t *menu, double overscan )
  1459. +{
  1460. +    char string[ 128 ];
  1461. +
  1462. +    snprintf( string, sizeof( string ), TVTIME_ICON_TVLOGO "  %s: %.1f%%",
  1463. +              _("Current"), overscan * 2.0 * 100.0 );
  1464. +    menu_set_text( menu, 1, string );
  1465. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "output" );
  1466. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "output" );
  1467. +
  1468. +    snprintf( string, sizeof( string ),
  1469. +              TVTIME_ICON_PLUSBUTTON "  %s", _("Increase") );
  1470. +    menu_set_text( menu, 2, string );
  1471. +    menu_set_enter_command( menu, 2, TVTIME_OVERSCAN_UP, "" );
  1472. +
  1473. +    snprintf( string, sizeof( string ),
  1474. +              TVTIME_ICON_MINUSBUTTON "  %s", _("Decrease") );
  1475. +    menu_set_text( menu, 3, string );
  1476. +    menu_set_enter_command( menu, 3, TVTIME_OVERSCAN_DOWN, "" );
  1477. +
  1478. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1479. +              _("Back") );
  1480. +    menu_set_text( menu, 4, string );
  1481. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "output" );
  1482. +}
  1483. +
  1484. +static void reset_filters_menu( menu_t *menu, int apply_invert,
  1485. +                                int apply_mirror, int apply_chroma_kill,
  1486. +                                int isntsc, int apply_pulldown )
  1487. +{
  1488. +    char string[ 128 ];
  1489. +    int cur = 1;
  1490. +
  1491. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "processing" );
  1492. +
  1493. +    if( isntsc ) {
  1494. +        snprintf( string, sizeof( string ), apply_pulldown ?
  1495. +                  TVTIME_ICON_GENERALTOGGLEON "  %s" :
  1496. +                  TVTIME_ICON_GENERALTOGGLEOFF "  %s",
  1497. +                  _("2-3 pulldown inversion") );
  1498. +        menu_set_text( menu, cur, string );
  1499. +        menu_set_enter_command( menu, cur, TVTIME_TOGGLE_PULLDOWN_DETECTION, "" );
  1500. +        cur++;
  1501. +    }
  1502. +
  1503. +    snprintf( string, sizeof( string ), apply_invert ?
  1504. +              TVTIME_ICON_GENERALTOGGLEON "  %s" :
  1505. +              TVTIME_ICON_GENERALTOGGLEOFF "  %s",
  1506. +              _("Colour invert") );
  1507. +    menu_set_text( menu, cur, string );
  1508. +    menu_set_enter_command( menu, cur, TVTIME_TOGGLE_COLOUR_INVERT, "" );
  1509. +    cur++;
  1510. +
  1511. +    snprintf( string, sizeof( string ), apply_mirror ?
  1512. +              TVTIME_ICON_GENERALTOGGLEON "  %s" :
  1513. +              TVTIME_ICON_GENERALTOGGLEOFF "  %s",
  1514. +              _("Mirror") );
  1515. +    menu_set_text( menu, cur, string );
  1516. +    menu_set_enter_command( menu, cur, TVTIME_TOGGLE_MIRROR, "" );
  1517. +    cur++;
  1518. +
  1519. +    snprintf( string, sizeof( string ), apply_chroma_kill ?
  1520. +              TVTIME_ICON_GENERALTOGGLEON "  %s" :
  1521. +              TVTIME_ICON_GENERALTOGGLEOFF "  %s",
  1522. +              _("Chroma killer") );
  1523. +    menu_set_text( menu, cur, string );
  1524. +    menu_set_enter_command( menu, cur, TVTIME_TOGGLE_CHROMA_KILL, "" );
  1525. +    cur++;
  1526. +
  1527. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1528. +              _("Back") );
  1529. +    menu_set_text( menu, cur, string );
  1530. +    menu_set_enter_command( menu, cur, TVTIME_SHOW_MENU, "processing" );
  1531. +}
  1532. +
  1533. +commands_t *commands_new( config_t *cfg, videoinput_t *vidin,
  1534. +                          station_mgr_t *mgr, tvtime_osd_t *osd,
  1535. +                          int fieldtime )
  1536. +{
  1537. +    commands_t *cmd = malloc( sizeof( struct commands_s ) );
  1538. +    char string[ 128 ];
  1539. +    menu_t *menu;
  1540. +    int maxwidth;
  1541. +    int curpos = 0;
  1542. +
  1543. +    if( !cmd ) {
  1544. +        return 0;
  1545. +    }
  1546. +
  1547. +    cmd->cfg = cfg;
  1548. +    cmd->vidin = vidin;
  1549. +    cmd->osd = osd;
  1550. +    cmd->stationmgr = mgr;
  1551. +    memset( cmd->next_chan_buffer, 0, sizeof( cmd->next_chan_buffer ) );
  1552. +    cmd->frame_counter = 0;
  1553. +    cmd->digit_counter = 0;
  1554. +    cmd->quit = 0;
  1555. +    cmd->sleeptimer = 0;
  1556. +    cmd->sleeptimer_start = 0;
  1557. +
  1558. +    if( config_get_xmltv_file( cfg ) && strcasecmp( config_get_xmltv_file( cfg ), "none" ) ) {
  1559. +        if( config_get_xmltv_language( cfg ) && strcasecmp( config_get_xmltv_language( cfg ), "none" ) ) {
  1560. +            cmd->xmltv = xmltv_new( config_get_xmltv_file( cfg ),
  1561. +                                    config_get_xmltv_language( cfg ) );
  1562. +        } else {
  1563. +            cmd->xmltv = xmltv_new( config_get_xmltv_file( cfg ), 0 );
  1564. +        }
  1565. +    } else {
  1566. +        cmd->xmltv = 0;
  1567. +    }
  1568. +
  1569. +    cmd->picturemode = 3;
  1570. +    cmd->brightness = config_get_global_brightness( cfg );
  1571. +    cmd->contrast = config_get_global_contrast( cfg );
  1572. +    cmd->saturation = config_get_global_saturation( cfg );
  1573. +    cmd->hue = config_get_global_hue( cfg );
  1574. +
  1575. +    cmd->displayinfo = 0;
  1576. +    cmd->screenshot = 0;
  1577. +    memset( cmd->screenshotfile, 0, sizeof( cmd->screenshotfile ) );
  1578. +    cmd->printdebug = 0;
  1579. +    cmd->showbars = 0;
  1580. +    cmd->showdeinterlacerinfo = 0;
  1581. +    cmd->togglefullscreen = 0;
  1582. +    cmd->toggleaspect = 0;
  1583. +    cmd->togglealwaysontop = 0;
  1584. +    cmd->toggledeinterlacer = 0;
  1585. +    cmd->togglepulldowndetection = 0;
  1586. +    cmd->togglematte = 0;
  1587. +    cmd->togglequiet = 0;
  1588. +    cmd->framerate = FRAMERATE_FULL;
  1589. +    cmd->scan_channels = 0;
  1590. +    cmd->pause = 0;
  1591. +    cmd->halfsize = 0;
  1592. +    cmd->resizewindow = 0;
  1593. +    cmd->restarttvtime = 0;
  1594. +    cmd->setdeinterlacer = 0;
  1595. +    cmd->normset = 0;
  1596. +    cmd->newnorm = 0;
  1597. +    cmd->newinputwidth = 0;
  1598. +    memset( cmd->deinterlacer, 0, sizeof( cmd->deinterlacer ) );
  1599. +    cmd->setfreqtable = 0;
  1600. +    snprintf( cmd->newfreqtable, sizeof( cmd->newfreqtable ), "%s", config_get_v4l_freq( cfg ) );
  1601. +    cmd->checkfreq = config_get_check_freq_present( cfg );
  1602. +    cmd->usexds = config_get_usexds( cfg );
  1603. +    cmd->pulldown_alg = 0;
  1604. +    memset( cmd->newmatte, 0, sizeof( cmd->newmatte ) );
  1605. +    memset( cmd->newpos, 0, sizeof( cmd->newpos ) );
  1606. +
  1607. +    /* Number of frames to wait for next channel digit. */
  1608. +    cmd->delay = 1000000 / fieldtime;
  1609. +
  1610. +    cmd->change_channel = 0;
  1611. +    cmd->renumbering = 0;
  1612. +    cmd->xmltvupdated = 0;
  1613. +    cmd->tunerreset = 0;
  1614. +
  1615. +    cmd->apply_invert = config_get_invert( cfg );
  1616. +    cmd->apply_mirror = config_get_mirror( cfg );
  1617. +    cmd->apply_chroma_kill = 0;
  1618. +
  1619. +    cmd->boost = config_get_audio_boost( cfg );
  1620. +
  1621. +    cmd->overscan = config_get_overscan( cfg );
  1622. +    if( cmd->overscan > 0.4 ) cmd->overscan = 0.4; if( cmd->overscan < 0.0 ) cmd->overscan = 0.0;
  1623. +
  1624. +    cmd->vbi = 0;
  1625. +    cmd->capturemode = config_get_cc( cfg ) ? CAPTURE_CC1 : CAPTURE_OFF;
  1626. +
  1627. +    cmd->curfavorite = 0;
  1628. +    cmd->numfavorites = 0;
  1629. +    memset( cmd->favorites, 0, sizeof( cmd->favorites ) );
  1630. +
  1631. +    cmd->menuactive = 0;
  1632. +    cmd->curmenu = MENU_FAVORITES;
  1633. +    cmd->curmenupos = 0;
  1634. +    cmd->curmenusize = 0;
  1635. +    cmd->curusermenu = 0;
  1636. +    memset( cmd->menus, 0, sizeof( cmd->menus ) );
  1637. +
  1638. +    if( vidin && videoinput_get_norm( vidin ) != VIDEOINPUT_NTSC &&
  1639. +                 videoinput_get_norm( vidin ) != VIDEOINPUT_NTSC_JP ) {
  1640. +        set_redirect( "input", "input-pal" );
  1641. +    }
  1642. +
  1643. +    if( vidin && (videoinput_get_norm( vidin ) == VIDEOINPUT_PAL ||
  1644. +                  videoinput_get_norm( vidin ) == VIDEOINPUT_SECAM) ) {
  1645. +        if( cmd->checkfreq ) {
  1646. +            set_redirect( "stations", "stations-palsecam-signal" );
  1647. +        } else {
  1648. +            set_redirect( "stations", "stations-palsecam-nosignal" );
  1649. +        }
  1650. +    } else if( vidin && videoinput_get_norm( vidin ) == VIDEOINPUT_NTSC &&
  1651. +               (!strcasecmp( config_get_v4l_freq( cfg ), "us-cable" ) ||
  1652. +                !strcasecmp( config_get_v4l_freq( cfg ), "us-cable100" )) ) {
  1653. +        if( cmd->checkfreq ) {
  1654. +            set_redirect( "stations", "stations-ntsccable-signal" );
  1655. +        } else {
  1656. +            set_redirect( "stations", "stations-ntsccable-nosignal" );
  1657. +        }
  1658. +    }
  1659. +
  1660. +    menu = menu_new( "root-tuner" );
  1661. +    menu_set_back_command( menu, TVTIME_MENU_EXIT, 0 );
  1662. +
  1663. +    menu_set_text( menu, 0, _("Setup") );
  1664. +
  1665. +    snprintf( string, sizeof( string ),
  1666. +              TVTIME_ICON_STATIONMANAGEMENT "  %s", _("Channel management") );
  1667. +    menu_set_text( menu, 1, string );
  1668. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "stations" );
  1669. +
  1670. +    snprintf( string, sizeof( string ),
  1671. +              TVTIME_ICON_INPUTCONF "  %s", _("Input configuration") );
  1672. +    menu_set_text( menu, 2, string );
  1673. +    menu_set_enter_command( menu, 2, TVTIME_SHOW_MENU, "input" );
  1674. +
  1675. +    snprintf( string, sizeof( string ),
  1676. +             TVTIME_ICON_PICTURESETTINGS "  %s", _("Picture settings") );
  1677. +    menu_set_text( menu, 3, string );
  1678. +    menu_set_enter_command( menu, 3, TVTIME_SHOW_MENU, "picture" );
  1679. +
  1680. +    snprintf( string, sizeof( string ),
  1681. +             TVTIME_ICON_VIDEOPROCESSING "  %s", _("Video processing") );
  1682. +    menu_set_text( menu, 4, string );
  1683. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "processing" );
  1684. +
  1685. +    snprintf( string, sizeof( string ),
  1686. +             TVTIME_ICON_OUTPUTCONF "  %s", _("Output configuration") );
  1687. +    menu_set_text( menu, 5, string );
  1688. +    menu_set_enter_command( menu, 5, TVTIME_SHOW_MENU, "output" );
  1689. +
  1690. +    snprintf( string, sizeof( string ),
  1691. +              TVTIME_ICON_EXIT "  %s", _("Exit menu") );
  1692. +    menu_set_text( menu, 6, string );
  1693. +    menu_set_enter_command( menu, 6, TVTIME_MENU_EXIT, 0 );
  1694. +
  1695. +    commands_add_menu( cmd, menu );
  1696. +
  1697. +    menu = menu_new( "root-notuner" );
  1698. +    menu_set_text( menu, 0, _("Setup") );
  1699. +    menu_set_back_command( menu, TVTIME_MENU_EXIT, 0 );
  1700. +
  1701. +    snprintf( string, sizeof( string ),
  1702. +              TVTIME_ICON_INPUTCONF "  %s", _("Input configuration") );
  1703. +    menu_set_text( menu, 1, string );
  1704. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "input" );
  1705. +
  1706. +    snprintf( string, sizeof( string ),
  1707. +              TVTIME_ICON_PICTURESETTINGS "  %s", _("Picture settings") );
  1708. +    menu_set_text( menu, 2, string );
  1709. +    menu_set_enter_command( menu, 2, TVTIME_SHOW_MENU, "picture" );
  1710. +
  1711. +    snprintf( string, sizeof( string ),
  1712. +              TVTIME_ICON_VIDEOPROCESSING "  %s", _("Video processing") );
  1713. +    menu_set_text( menu, 3, string );
  1714. +    menu_set_enter_command( menu, 3, TVTIME_SHOW_MENU, "processing" );
  1715. +
  1716. +    snprintf( string, sizeof( string ),
  1717. +              TVTIME_ICON_OUTPUTCONF "  %s", _("Output configuration") );
  1718. +    menu_set_text( menu, 4, string );
  1719. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "output" );
  1720. +
  1721. +    snprintf( string, sizeof( string ),
  1722. +              TVTIME_ICON_EXIT "  %s", _("Exit menu") );
  1723. +    menu_set_text( menu, 5, string );
  1724. +    menu_set_enter_command( menu, 5, TVTIME_MENU_EXIT, 0 );
  1725. +
  1726. +    commands_add_menu( cmd, menu );
  1727. +
  1728. +    menu = menu_new( "stations" );
  1729. +    snprintf( string, sizeof( string ), "%s - %s",
  1730. +              _("Setup"), _("Channel management") );
  1731. +    menu_set_text( menu, 0, string);
  1732. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "stations" );
  1733. +    commands_add_menu( cmd, menu );
  1734. +    if( vidin ) {
  1735. +        reset_stations_menu( commands_get_menu( cmd, "stations" ),
  1736. +                             (videoinput_get_norm( vidin ) == VIDEOINPUT_NTSC ||
  1737. +                              videoinput_get_norm( vidin ) == VIDEOINPUT_NTSC_JP),
  1738. +                             videoinput_get_norm( vidin ) == VIDEOINPUT_PAL,
  1739. +                             videoinput_get_norm( vidin ) == VIDEOINPUT_SECAM,
  1740. +                             (!strcasecmp( cmd->newfreqtable, "us-cable" ) ||
  1741. +                              !strcasecmp( cmd->newfreqtable, "us-cable100" )),
  1742. +                             station_get_current_active( cmd->stationmgr ),
  1743. +                             cmd->checkfreq, cmd->scan_channels,
  1744. +                             videoinput_is_v4l2( cmd->vidin ),
  1745. +                             station_get_default_audio_norm( cmd->stationmgr ),
  1746. +                             station_get_current_audio_norm( cmd->stationmgr ) );
  1747. +    }
  1748. +
  1749. +    menu = menu_new( "frequencies" );
  1750. +    snprintf( string, sizeof( string ), "%s - %s - %s", _("Setup"),
  1751. +              _("Channel management"), _("Frequency table") );
  1752. +    menu_set_text( menu, 0, string );
  1753. +    commands_add_menu( cmd, menu );
  1754. +    if( vidin ) {
  1755. +        reset_frequency_menu( commands_get_menu( cmd, "frequencies" ),
  1756. +                              videoinput_get_norm( vidin ),
  1757. +                              config_get_v4l_freq( cfg ) );
  1758. +    }
  1759. +
  1760. +    menu = menu_new( "finetune" );
  1761. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "stations" );
  1762. +    snprintf( string, sizeof( string ), "%s - %s - %s", _("Setup"),
  1763. +              _("Channel management"), _("Finetune") );
  1764. +    menu_set_text( menu, 0, string );
  1765. +    snprintf( string, sizeof( string ),
  1766. +              TVTIME_ICON_TVLOGO "  %s: ---", _("Current") );
  1767. +    menu_set_text( menu, 1, string );
  1768. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "stations" );
  1769. +
  1770. +    menu_set_default_cursor( menu, 1 );
  1771. +    snprintf( string, sizeof( string ),
  1772. +              TVTIME_ICON_PLUSBUTTON "  %s", _("Increase") );
  1773. +    menu_set_text( menu, 2, string );
  1774. +    menu_set_enter_command( menu, 2, TVTIME_FINETUNE_UP, "" );
  1775. +
  1776. +    snprintf( string, sizeof( string ),
  1777. +              TVTIME_ICON_MINUSBUTTON "  %s",_("Decrease") );
  1778. +    menu_set_text( menu, 3, string );
  1779. +    menu_set_enter_command( menu, 3, TVTIME_FINETUNE_DOWN, "" );
  1780. +
  1781. +    snprintf( string, sizeof( string ),
  1782. +              TVTIME_ICON_PLAINLEFTARROW "  %s", _("Back") );
  1783. +    menu_set_text( menu, 4, string );
  1784. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "stations" );
  1785. +
  1786. +    commands_add_menu( cmd, menu );
  1787. +
  1788. +    menu = menu_new( "input-ntsc" );
  1789. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "root" );
  1790. +    snprintf( string, sizeof( string ), "%s - %s", _("Setup"),
  1791. +              _("Input configuration") );
  1792. +    menu_set_text( menu, 0, string );
  1793. +    if( vidin ) {
  1794. +        snprintf( string, sizeof( string ), TVTIME_ICON_VIDEOINPUT "  %s: %s",
  1795. +                  _("Change video source"), videoinput_get_input_name( vidin ) );
  1796. +    } else {
  1797. +        snprintf( string, sizeof( string ), TVTIME_ICON_VIDEOINPUT "  %s",
  1798. +                  _("Change video source") );
  1799. +    }
  1800. +    menu_set_text( menu, 1, string );
  1801. +    menu_set_enter_command( menu, 1, TVTIME_TOGGLE_INPUT, "" );
  1802. +
  1803. +    snprintf( string, sizeof( string ), TVTIME_ICON_STATIONMANAGEMENT "  %s",
  1804. +              _("Preferred audio mode") );
  1805. +    menu_set_text( menu, 2, string );
  1806. +    menu_set_enter_command( menu, 2, TVTIME_SHOW_MENU, "audiomode" );
  1807. +
  1808. +    snprintf( string, sizeof( string ), TVTIME_ICON_STATIONMANAGEMENT "  %s",
  1809. +              _("Audio volume boost") );
  1810. +    menu_set_text( menu, 3, string );
  1811. +    menu_set_enter_command( menu, 3, TVTIME_SHOW_MENU, "audioboost" );
  1812. +
  1813. +    snprintf( string, sizeof( string ), TVTIME_ICON_TELEVISIONSTANDARD "  %s",
  1814. +              _("Television standard") );
  1815. +    menu_set_text( menu, 4, string );
  1816. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "norm" );
  1817. +
  1818. +    snprintf( string, sizeof( string ), TVTIME_ICON_INPUTWIDTH "  %s",
  1819. +              _("Horizontal resolution") );
  1820. +    menu_set_text( menu, 5, string );
  1821. +    menu_set_enter_command( menu, 5, TVTIME_SHOW_MENU, "hres" );
  1822. +
  1823. +    snprintf( string, sizeof( string ), TVTIME_ICON_CLOSEDCAPTIONICON "  %s",
  1824. +              _("Toggle closed captions") );
  1825. +    menu_set_text( menu, 6, string );
  1826. +    menu_set_enter_command( menu, 6, TVTIME_TOGGLE_CC, "" );
  1827. +
  1828. +    snprintf( string, sizeof( string ), TVTIME_ICON_TVPGICON "  %s",
  1829. +              _("Toggle XDS decoding") );
  1830. +    menu_set_text( menu, 7, string );
  1831. +    menu_set_enter_command( menu, 7, TVTIME_TOGGLE_XDS, "" );
  1832. +
  1833. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1834. +              _("Back") );
  1835. +    menu_set_text( menu, 8, string );
  1836. +    menu_set_enter_command( menu, 8, TVTIME_SHOW_MENU, "root" );
  1837. +
  1838. +    commands_add_menu( cmd, menu );
  1839. +
  1840. +    menu = menu_new( "input-pal" );
  1841. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "root" );
  1842. +    snprintf( string, sizeof( string ),
  1843. +              "%s - %s", _("Setup"), _("Input configuration") );
  1844. +    menu_set_text (menu, 0, string);
  1845. +    if( vidin ) {
  1846. +        snprintf( string, sizeof( string ), TVTIME_ICON_VIDEOINPUT "  %s: %s",
  1847. +                  _("Change video source"), videoinput_get_input_name( vidin ) );
  1848. +    } else {
  1849. +        snprintf( string, sizeof( string ), TVTIME_ICON_VIDEOINPUT "  %s",
  1850. +                  _("Change video source") );
  1851. +    }
  1852. +    menu_set_text( menu, 1, string );
  1853. +    menu_set_enter_command( menu, 1, TVTIME_TOGGLE_INPUT, "" );
  1854. +    if( vidin ) {
  1855. +        reset_pal_input_menu( menu, vidin, cmd->stationmgr );
  1856. +    }
  1857. +    commands_add_menu( cmd, menu );
  1858. +
  1859. +    menu = menu_new( "hres" );
  1860. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  1861. +              _("Setup"), _("Input configuration"), _("Horizontal resolution") );
  1862. +    menu_set_text( menu, 0, string );
  1863. +    menu_set_default_cursor( menu, 1 );
  1864. +    commands_add_menu( cmd, menu );
  1865. +    maxwidth = cmd->vidin? videoinput_get_maxwidth( cmd->vidin ) : 0;
  1866. +    reset_inputwidth_menu( commands_get_menu( cmd, "hres" ),
  1867. +                           config_get_inputwidth( cfg ), maxwidth);
  1868. +
  1869. +    menu = menu_new( "audiomode" );
  1870. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  1871. +              _("Setup"), _("Input configuration"), _("Preferred audio mode") );
  1872. +    menu_set_text( menu, 0, string );
  1873. +    commands_add_menu( cmd, menu );
  1874. +    if( cmd->vidin ) {
  1875. +        reset_audio_mode_menu( commands_get_menu( cmd, "audiomode" ),
  1876. +                               videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC,
  1877. +                               videoinput_get_audio_mode( cmd->vidin ) );
  1878. +    } else {
  1879. +        reset_audio_mode_menu( commands_get_menu( cmd, "audiomode" ), 0, 0 );
  1880. +    }
  1881. +
  1882. +    menu = menu_new( "audioboost" );
  1883. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  1884. +              _("Setup"), _("Input configuration"), _("Audio volume boost") );
  1885. +    menu_set_text( menu, 0, string );
  1886. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "input" );
  1887. +    commands_add_menu( cmd, menu );
  1888. +    reset_audio_boost_menu( commands_get_menu( cmd, "audioboost" ),
  1889. +                            cmd->boost );
  1890. +
  1891. +    menu = menu_new( "norm" );
  1892. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  1893. +              _("Setup"), _("Input configuration"), _("Television standard") );
  1894. +    menu_set_text( menu, 0, string );
  1895. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "root" );
  1896. +    snprintf( string, sizeof( string ), TVTIME_ICON_RESTART "  %s",
  1897. +              _("Restart with new settings") );
  1898. +    menu_set_text( menu, 9, string );
  1899. +    menu_set_enter_command( menu, 9, TVTIME_RESTART, "" );
  1900. +
  1901. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1902. +              _("Back") );
  1903. +    menu_set_text( menu, 10, string );
  1904. +    menu_set_enter_command( menu, 10, TVTIME_SHOW_MENU, "input" );
  1905. +
  1906. +    if( !strcasecmp( config_get_v4l_norm( cfg ), "pal" ) ) {
  1907. +        cmd->newnorm = "PAL";
  1908. +    } else if( !strcasecmp( config_get_v4l_norm( cfg ), "secam" ) ) {
  1909. +        cmd->newnorm = "SECAM";
  1910. +    } else if( !strcasecmp( config_get_v4l_norm( cfg ), "pal-nc" ) ) {
  1911. +        cmd->newnorm = "PAL-Nc";
  1912. +    } else if( !strcasecmp( config_get_v4l_norm( cfg ), "pal-m" ) ) {
  1913. +        cmd->newnorm = "PAL-M";
  1914. +    } else if( !strcasecmp( config_get_v4l_norm( cfg ), "pal-n" ) ) {
  1915. +        cmd->newnorm = "PAL-N";
  1916. +    } else if( !strcasecmp( config_get_v4l_norm( cfg ), "ntsc-jp" ) ) {
  1917. +        cmd->newnorm = "NTSC-JP";
  1918. +    } else if( !strcasecmp( config_get_v4l_norm( cfg ), "pal-60" ) ) {
  1919. +        cmd->newnorm = "PAL-60";
  1920. +    } else {
  1921. +        cmd->newnorm = "NTSC";
  1922. +    }
  1923. +    reset_norm_menu( menu, cmd->newnorm );
  1924. +    commands_add_menu( cmd, menu );
  1925. +
  1926. +    menu = menu_new( "output" );
  1927. +    snprintf( string, sizeof( string ), "%s - %s",
  1928. +              _("Setup"), _("Output configuration") );
  1929. +    menu_set_text( menu, 0, string );
  1930. +    commands_add_menu( cmd, menu );
  1931. +
  1932. +    menu = menu_new( "matte" );
  1933. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  1934. +              _("Setup"), _("Output configuration"), _("Apply matte") );
  1935. +    menu_set_text( menu, 0, string );
  1936. +    commands_add_menu( cmd, menu );
  1937. +
  1938. +    menu = menu_new( "overscan" );
  1939. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  1940. +              _("Setup"), _("Output configuration"), _("Overscan") );
  1941. +    menu_set_text( menu, 0, string );
  1942. +    commands_add_menu( cmd, menu );
  1943. +    reset_overscan_menu( commands_get_menu( cmd, "overscan" ), cmd->overscan );
  1944. +
  1945. +    menu = menu_new( "fspos" );
  1946. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  1947. +              _("Setup"), _("Output configuration"), _("Fullscreen position") );
  1948. +    menu_set_text( menu, 0, string );
  1949. +    commands_add_menu( cmd, menu );
  1950. +
  1951. +    menu = menu_new( "processing" );
  1952. +    snprintf( string, sizeof( string ), "%s - %s",
  1953. +              _("Setup"), _("Video processing") );
  1954. +    menu_set_text( menu, 0, string );
  1955. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "root" );
  1956. +    snprintf( string, sizeof( string ), TVTIME_ICON_DEINTERLACERCONF "  %s",
  1957. +              _("Deinterlacer configuration") );
  1958. +    menu_set_text( menu, 1, string );
  1959. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "deinterlacer" );
  1960. +
  1961. +    snprintf( string, sizeof( string ), TVTIME_ICON_DEINTERLACERDESC "  %s",
  1962. +              _("Current deinterlacer description") );
  1963. +    menu_set_text( menu, 2, string );
  1964. +    menu_set_enter_command( menu, 2, TVTIME_SHOW_MENU, "deintdescription" );
  1965. +    snprintf( string, sizeof( string ), TVTIME_ICON_ATTEMPTEDFRAMERATE "  %s",
  1966. +              _("Attempted framerate") );
  1967. +    menu_set_text( menu, 3, string );
  1968. +    menu_set_enter_command( menu, 3, TVTIME_SHOW_MENU, "framerate" );
  1969. +    snprintf( string, sizeof( string ), TVTIME_ICON_INPUTFILTERS "  %s",
  1970. +              _("Input filters") );
  1971. +    menu_set_text( menu, 4, string );
  1972. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "filters" );
  1973. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  1974. +              _("Back") );
  1975. +    menu_set_text( menu, 5, string );
  1976. +    menu_set_enter_command( menu, 5, TVTIME_SHOW_MENU, "root" );
  1977. +    commands_add_menu( cmd, menu );
  1978. +
  1979. +    menu = menu_new( "deinterlacer" );
  1980. +
  1981. +    snprintf( string, sizeof( string ), "%s - %s - %s", _("Setup"),
  1982. +              _("Video processing"), _("Deinterlacer configuration") );
  1983. +    menu_set_text( menu, 0, string );
  1984. +    commands_add_menu( cmd, menu );
  1985. +
  1986. +    menu = menu_new( "deintdescription" );
  1987. +    snprintf( string, sizeof( string ), "%s - %s - %s", _("Setup"),
  1988. +              _("Video processing"), _("Deinterlacer description") );
  1989. +    menu_set_text( menu, 0, string );
  1990. +
  1991. +    commands_add_menu( cmd, menu );
  1992. +
  1993. +    menu = menu_new( "framerate" );
  1994. +
  1995. +    snprintf( string, sizeof( string ), "%s - %s - %s", _("Setup"),
  1996. +              _("Video processing"), _("Attempted framerate") );
  1997. +    menu_set_text( menu, 0, string );
  1998. +    commands_add_menu( cmd, menu );
  1999. +
  2000. +    menu = menu_new( "filters" );
  2001. +    snprintf( string, sizeof( string ), "%s - %s - %s", _("Setup"),
  2002. +              _("Video processing"), _("Input filters") );
  2003. +    menu_set_text( menu, 0, string );
  2004. +    commands_add_menu( cmd, menu );
  2005. +    reset_filters_menu( commands_get_menu( cmd, "filters" ),
  2006. +                        cmd->apply_invert, cmd->apply_mirror,
  2007. +                        cmd->apply_chroma_kill,
  2008. +                        cmd->vidin && videoinput_get_height( cmd->vidin ) == 480,
  2009. +                        cmd->pulldown_alg );
  2010. +
  2011. +    menu = menu_new( "picture-notuner" );
  2012. +    snprintf( string, sizeof( string ), "%s - %s", _("Setup"), _("Picture") );
  2013. +    menu_set_text( menu, 0, string );
  2014. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "root" );
  2015. +    snprintf( string, sizeof( string ), TVTIME_ICON_BRIGHTNESS "  %s",
  2016. +              _("Brightness") );
  2017. +    menu_set_text( menu, 1, string );
  2018. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "brightness" );
  2019. +
  2020. +    snprintf( string, sizeof( string ), TVTIME_ICON_CONTRAST "  %s",
  2021. +              _("Contrast") );
  2022. +    menu_set_text( menu, 2, string );
  2023. +    menu_set_enter_command( menu, 2, TVTIME_SHOW_MENU, "contrast" );
  2024. +
  2025. +    snprintf( string, sizeof( string ), TVTIME_ICON_SATURATION "  %s", _("Saturation") );
  2026. +    menu_set_text( menu, 3, string );
  2027. +    menu_set_enter_command( menu, 3, TVTIME_SHOW_MENU, "saturation" );
  2028. +
  2029. +    curpos = 4;
  2030. +    if( cmd->vidin && videoinput_get_height( cmd->vidin ) == 480 &&
  2031. +        videoinput_get_norm( cmd->vidin ) != VIDEOINPUT_PAL_60 ) {
  2032. +        /* Hue only applies to NTSC norms. */
  2033. +        snprintf( string, sizeof( string ), TVTIME_ICON_HUE "  %s", _("Hue") );
  2034. +        menu_set_text( menu, curpos, string );
  2035. +        menu_set_enter_command( menu, curpos, TVTIME_SHOW_MENU, "hue" );
  2036. +        curpos++;
  2037. +    }
  2038. +
  2039. +    if (config_get_save_restore_picture (cfg)) {
  2040. +        snprintf( string, sizeof( string ),
  2041. +                  TVTIME_ICON_SAVEPICTUREGLOBAL "  %s",
  2042. +                  _("Save current settings as defaults") );
  2043. +        menu_set_text( menu, curpos, string );
  2044. +        menu_set_enter_command( menu, curpos, TVTIME_SAVE_PICTURE_GLOBAL, "" );
  2045. +        curpos++;
  2046. +
  2047. +        snprintf( string, sizeof( string ), TVTIME_ICON_RESETTODEFAULTS "  %s",
  2048. +                  _("Reset to global defaults") );
  2049. +        menu_set_text( menu, curpos, string );
  2050. +        menu_set_enter_command( menu, curpos, TVTIME_AUTO_ADJUST_PICT, "" );
  2051. +        curpos++;
  2052. +
  2053. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  2054. +                  _("Back") );
  2055. +        menu_set_text( menu, curpos, string );
  2056. +        menu_set_enter_command( menu, curpos, TVTIME_SHOW_MENU, "root" );
  2057. +        commands_add_menu( cmd, menu );
  2058. +    } else {
  2059. +        snprintf( string, sizeof( string ), TVTIME_ICON_RESETTODEFAULTS "  %s",
  2060. +                  _("Reset to global defaults") );
  2061. +        menu_set_text( menu, curpos, string );
  2062. +        menu_set_enter_command( menu, curpos, TVTIME_AUTO_ADJUST_PICT, "" );
  2063. +        curpos++;
  2064. +
  2065. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  2066. +                  _("Back") );
  2067. +        menu_set_text( menu, curpos, string );
  2068. +        menu_set_enter_command( menu, curpos, TVTIME_SHOW_MENU, "root" );
  2069. +        commands_add_menu( cmd, menu );
  2070. +    }
  2071. +
  2072. +    menu = menu_new( "picture-tuner" );
  2073. +    snprintf( string, sizeof( string ), "%s - %s", _("Setup"), _("Picture") );
  2074. +    menu_set_text( menu, 0, string);
  2075. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "root" );
  2076. +
  2077. +    snprintf( string, sizeof( string ), TVTIME_ICON_BRIGHTNESS "  %s",
  2078. +              _("Brightness") );
  2079. +    menu_set_text( menu, 1, string );
  2080. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "brightness" );
  2081. +
  2082. +    snprintf( string, sizeof( string ), TVTIME_ICON_CONTRAST "  %s",
  2083. +              _("Contrast") );
  2084. +    menu_set_text( menu, 2, string );
  2085. +    menu_set_enter_command( menu, 2, TVTIME_SHOW_MENU, "contrast" );
  2086. +
  2087. +    snprintf( string, sizeof( string ), TVTIME_ICON_SATURATION "  %s", _("Saturation") );
  2088. +    menu_set_text( menu, 3, string );
  2089. +    menu_set_enter_command( menu, 3, TVTIME_SHOW_MENU, "saturation" );
  2090. +
  2091. +    curpos = 4;
  2092. +    if( cmd->vidin && videoinput_get_height( cmd->vidin ) == 480 &&
  2093. +        videoinput_get_norm( cmd->vidin ) != VIDEOINPUT_PAL_60 ) {
  2094. +        snprintf( string, sizeof( string ), TVTIME_ICON_HUE "  %s", _("Hue") );
  2095. +        menu_set_text( menu, curpos, string );
  2096. +        menu_set_enter_command( menu, curpos, TVTIME_SHOW_MENU, "hue" );
  2097. +        curpos++;
  2098. +    }
  2099. +
  2100. +    if( config_get_save_restore_picture( cfg ) ) {
  2101. +        snprintf( string, sizeof( string ),
  2102. +                  TVTIME_ICON_SAVEPICTUREGLOBAL "  %s",
  2103. +                  _("Save current settings as global defaults") );
  2104. +        menu_set_text( menu, curpos, string );
  2105. +        menu_set_enter_command( menu, curpos, TVTIME_SAVE_PICTURE_GLOBAL, "" );
  2106. +        curpos++;
  2107. +
  2108. +        snprintf( string, sizeof( string ),
  2109. +                  TVTIME_ICON_SAVEPICTURECHANNEL "  %s",
  2110. +                  _("Save current settings as channel defaults") );
  2111. +        menu_set_text( menu, curpos, string );
  2112. +        menu_set_enter_command( menu, curpos, TVTIME_SAVE_PICTURE_CHANNEL, "" );
  2113. +        curpos++;
  2114. +
  2115. +        snprintf( string, sizeof( string ), TVTIME_ICON_RESETTODEFAULTS " %s",
  2116. +                  _("Reset to global defaults") );
  2117. +        menu_set_text( menu, curpos, string );
  2118. +        menu_set_enter_command( menu, curpos, TVTIME_AUTO_ADJUST_PICT, "" );
  2119. +        curpos++;
  2120. +
  2121. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  2122. +                  _("Back") );
  2123. +        menu_set_text( menu, curpos, string );
  2124. +        menu_set_enter_command( menu, curpos, TVTIME_SHOW_MENU, "root" );
  2125. +
  2126. +        commands_add_menu( cmd, menu );
  2127. +    } else {
  2128. +        snprintf( string, sizeof( string ), TVTIME_ICON_RESETTODEFAULTS "  %s",
  2129. +                  _("Reset to global defaults") );
  2130. +        menu_set_text( menu, curpos, string );
  2131. +        menu_set_enter_command( menu, curpos, TVTIME_AUTO_ADJUST_PICT, "" );
  2132. +        curpos++;
  2133. +
  2134. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  2135. +                  _("Back") );
  2136. +        menu_set_text( menu, curpos, string );
  2137. +        menu_set_enter_command( menu, curpos, TVTIME_SHOW_MENU, "root" );
  2138. +        curpos++;
  2139. +
  2140. +        commands_add_menu( cmd, menu );
  2141. +    }
  2142. +
  2143. +
  2144. +    menu = menu_new( "brightness" );
  2145. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  2146. +              _("Setup"), _("Picture"), _("Brightness") );
  2147. +    menu_set_text( menu, 0, string );
  2148. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "picture" );
  2149. +    snprintf( string, sizeof( string ), TVTIME_ICON_TVLOGO "  %s: ---",
  2150. +              _("Current") );
  2151. +    menu_set_text( menu, 1, string );
  2152. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "picture" );
  2153. +
  2154. +    menu_set_default_cursor( menu, 1 );
  2155. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLUSBUTTON "  %s",
  2156. +              _("Increase") );
  2157. +    menu_set_text( menu, 2, string );
  2158. +    menu_set_enter_command( menu, 2, TVTIME_BRIGHTNESS_UP, "" );
  2159. +
  2160. +    snprintf( string, sizeof( string ), TVTIME_ICON_MINUSBUTTON "  %s",
  2161. +              _("Decrease") );
  2162. +    menu_set_text( menu, 3, string );
  2163. +    menu_set_enter_command( menu, 3, TVTIME_BRIGHTNESS_DOWN, "" );
  2164. +
  2165. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  2166. +              _("Back") );
  2167. +    menu_set_text( menu, 4, string );
  2168. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "picture" );
  2169. +
  2170. +    commands_add_menu( cmd, menu );
  2171. +    if( vidin ) {
  2172. +        menu_set_value (commands_get_menu (cmd, "brightness"),
  2173. +                        videoinput_get_brightness (cmd->vidin),
  2174. +                        TVTIME_ICON_BRIGHTNESS);
  2175. +    }
  2176. +
  2177. +    menu = menu_new( "contrast" );
  2178. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  2179. +              _("Setup"), _("Picture"), _("Contrast") );
  2180. +    menu_set_text( menu, 0, string );
  2181. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "picture" );
  2182. +    snprintf( string, sizeof( string ), TVTIME_ICON_TVLOGO "  %s: ---",
  2183. +              _("Current") );
  2184. +    menu_set_text( menu, 1, string );
  2185. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "picture" );
  2186. +    menu_set_default_cursor( menu, 1 );
  2187. +
  2188. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLUSBUTTON "  %s",
  2189. +              _("Increase") );
  2190. +    menu_set_text( menu, 2, string );
  2191. +    menu_set_enter_command( menu, 2, TVTIME_CONTRAST_UP, "" );
  2192. +
  2193. +    snprintf( string, sizeof( string ), TVTIME_ICON_MINUSBUTTON "  %s",
  2194. +              _("Decrease") );
  2195. +    menu_set_text( menu, 3, string );
  2196. +    menu_set_enter_command( menu, 3, TVTIME_CONTRAST_DOWN, "" );
  2197. +
  2198. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  2199. +              _("Back") );
  2200. +    menu_set_text( menu, 4, string );
  2201. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "picture" );
  2202. +
  2203. +    commands_add_menu( cmd, menu );
  2204. +    if( vidin ) {
  2205. +        menu_set_value (commands_get_menu( cmd, "contrast" ),
  2206. +                        videoinput_get_contrast( cmd->vidin ),
  2207. +                        TVTIME_ICON_CONTRAST);
  2208. +    }
  2209. +
  2210. +    menu = menu_new( "saturation" );
  2211. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  2212. +              _("Setup"), _("Picture"), _("Saturation") );
  2213. +    menu_set_text( menu, 0, string );
  2214. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "picture" );
  2215. +    snprintf( string, sizeof( string ), TVTIME_ICON_TVLOGO "  %s: ---",
  2216. +              _("Current") );
  2217. +    menu_set_text( menu, 1, string );
  2218. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "picture" );
  2219. +
  2220. +    menu_set_default_cursor( menu, 1 );
  2221. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLUSBUTTON "  %s",
  2222. +              _("Increase") );
  2223. +    menu_set_text( menu, 2, string );
  2224. +    menu_set_enter_command( menu, 2, TVTIME_SATURATION_UP, "" );
  2225. +
  2226. +    snprintf( string, sizeof( string ), TVTIME_ICON_MINUSBUTTON "  %s",
  2227. +              _("Decrease") );
  2228. +    menu_set_text( menu, 3, string );
  2229. +    menu_set_enter_command( menu, 3, TVTIME_SATURATION_DOWN, "" );
  2230. +
  2231. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  2232. +              _("Back") );
  2233. +    menu_set_text( menu, 4, string );
  2234. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "picture" );
  2235. +
  2236. +    commands_add_menu( cmd, menu );
  2237. +    if( vidin ) {
  2238. +        menu_set_value (commands_get_menu (cmd, "saturation" ),
  2239. +                        videoinput_get_saturation (cmd->vidin),
  2240. +                        TVTIME_ICON_SATURATION);
  2241. +    }
  2242. +
  2243. +    menu = menu_new( "hue" );
  2244. +    snprintf( string, sizeof( string ), "%s - %s - %s",
  2245. +              _("Setup"), _("Picture"), _("Hue") );
  2246. +    menu_set_text( menu, 0, string );
  2247. +    menu_set_back_command( menu, TVTIME_SHOW_MENU, "picture" );
  2248. +    snprintf( string, sizeof( string ), TVTIME_ICON_TVLOGO "  %s: ---",
  2249. +              _("Current") );
  2250. +    menu_set_text( menu, 1, string );
  2251. +    menu_set_enter_command( menu, 1, TVTIME_SHOW_MENU, "picture" );
  2252. +    menu_set_default_cursor( menu, 1 );
  2253. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLUSBUTTON "  %s",
  2254. +              _("Increase") );
  2255. +    menu_set_text( menu, 2, string );
  2256. +    menu_set_enter_command( menu, 2, TVTIME_HUE_UP, "" );
  2257. +
  2258. +    snprintf( string, sizeof( string ), TVTIME_ICON_MINUSBUTTON "  %s",
  2259. +              _("Decrease") );
  2260. +    menu_set_text( menu, 3, string );
  2261. +    menu_set_enter_command( menu, 3, TVTIME_HUE_DOWN, "" );
  2262. +
  2263. +    snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  2264. +              _("Back") );
  2265. +    menu_set_text( menu, 4, string );
  2266. +    menu_set_enter_command( menu, 4, TVTIME_SHOW_MENU, "picture" );
  2267. +
  2268. +    commands_add_menu( cmd, menu );
  2269. +    if( vidin ) {
  2270. +        menu_set_value (commands_get_menu (cmd, "hue"),
  2271. +                        videoinput_get_hue (cmd->vidin),
  2272. +                        TVTIME_ICON_HUE);
  2273. +    }
  2274. +
  2275. +    if( cmd->xmltv ) {
  2276. +        menu = menu_new( "xmltv-language" );
  2277. +        snprintf( string, sizeof( string ), "%s",
  2278. +                  _("Preferred XMLTV language") );
  2279. +        menu_set_text( menu, 0, string );
  2280. +        commands_add_menu( cmd, menu );
  2281. +        reset_xmltv_languages_menu( menu, cmd->xmltv );
  2282. +    }
  2283. +
  2284. +    reinit_tuner( cmd );
  2285. +
  2286. +    return cmd;
  2287. +}
  2288. +
  2289. +void commands_delete( commands_t *cmd )
  2290. +{
  2291. +    int i;
  2292. +
  2293. +    for( i = 0; i < MAX_USER_MENUS; i++ ) {
  2294. +        if( cmd->menus[ i ] ) {
  2295. +            menu_delete( cmd->menus[ i ] );
  2296. +        }
  2297. +    }
  2298. +
  2299. +    if( cmd->xmltv ) xmltv_delete( cmd->xmltv );
  2300. +    free( cmd );
  2301. +}
  2302. +
  2303. +static void add_to_favorites( commands_t *cmd, int pos )
  2304. +{
  2305. +    int i;
  2306. +
  2307. +    for( i = 0; i < NUM_FAVORITES; i++ ) {
  2308. +        if( cmd->favorites[ i ] == pos ) return;
  2309. +    }
  2310. +    cmd->favorites[ cmd->curfavorite ] = pos;
  2311. +    cmd->curfavorite = (cmd->curfavorite + 1) % NUM_FAVORITES;
  2312. +    if( cmd->numfavorites < NUM_FAVORITES ) {
  2313. +        cmd->numfavorites++;
  2314. +    }
  2315. +}
  2316. +
  2317. +static void osd_list_audio_modes( tvtime_osd_t *osd, int ntsc, int curmode )
  2318. +{
  2319. +    tvtime_osd_list_set_lines( osd, ntsc ? 4 : 5 );
  2320. +    tvtime_osd_list_set_text( osd, 0, _("Preferred audio mode") );
  2321. +    tvtime_osd_list_set_text( osd, 1, _("Mono") );
  2322. +    tvtime_osd_list_set_text( osd, 2, _("Stereo") );
  2323. +    tvtime_osd_list_set_text( osd, 3, ntsc ?
  2324. +                              _("SAP") : _("Primary Language") );
  2325. +    if( !ntsc ) tvtime_osd_list_set_text( osd, 4, _("Secondary Language") );
  2326. +    if( curmode == VIDEOINPUT_MONO ) {
  2327. +        tvtime_osd_list_set_hilight( osd, 1 );
  2328. +    } else if( curmode == VIDEOINPUT_STEREO ) {
  2329. +        tvtime_osd_list_set_hilight( osd, 2 );
  2330. +    } else if( curmode == VIDEOINPUT_LANG1 || (ntsc && curmode == VIDEOINPUT_LANG2) ) {
  2331. +        tvtime_osd_list_set_hilight( osd, 3 );
  2332. +    } else if( curmode == VIDEOINPUT_LANG2 ) {
  2333. +        tvtime_osd_list_set_hilight( osd, 4 );
  2334. +    }
  2335. +    tvtime_osd_show_list( osd, 1, 0 );
  2336. +}
  2337. +
  2338. +/**
  2339. + * Hardcoded menus.
  2340. + */
  2341. +
  2342. +static void menu_off( commands_t *cmd )
  2343. +{
  2344. +    tvtime_osd_list_hold( cmd->osd, 0 );
  2345. +    tvtime_osd_show_list( cmd->osd, 0, 0 );
  2346. +    cmd->menuactive = 0;
  2347. +}
  2348. +
  2349. +static void menu_enter( commands_t *cmd )
  2350. +{
  2351. +    if( cmd->curmenu == MENU_FAVORITES ) {
  2352. +        if( cmd->curmenupos == cmd->numfavorites ) {
  2353. +            add_to_favorites( cmd, station_get_current_id( cmd->stationmgr ) );
  2354. +        } else {
  2355. +            if( cmd->curmenupos < cmd->numfavorites ) {
  2356. +                station_set( cmd->stationmgr, cmd->favorites[ cmd->curmenupos ] );
  2357. +                cmd->change_channel = 1;
  2358. +            }
  2359. +        }
  2360. +        menu_off( cmd );
  2361. +    } else if( cmd->curmenu == MENU_USER ) {
  2362. +        int command = menu_get_enter_command( cmd->curusermenu, cmd->curmenupos + 1 );
  2363. +        const char *argument = menu_get_enter_argument( cmd->curusermenu, cmd->curmenupos + 1 );
  2364. +
  2365. +        /* I check for MENU_ENTER just to avoid a malicious infinite loop. */
  2366. +        if( command != TVTIME_MENU_ENTER ) {
  2367. +            commands_handle( cmd, command, argument );
  2368. +        }
  2369. +    }
  2370. +}
  2371. +
  2372. +static void menu_back( commands_t *cmd )
  2373. +{
  2374. +    if( cmd->curmenu == MENU_FAVORITES ) {
  2375. +        commands_handle( cmd, TVTIME_SHOW_MENU, "stations" );
  2376. +    } else if( cmd->curmenu == MENU_USER ) {
  2377. +        int command = menu_get_back_command( cmd->curusermenu );
  2378. +        const char *argument = menu_get_back_argument( cmd->curusermenu );
  2379. +
  2380. +        /* I check for MENU_ENTER just to avoid a malicious infinite loop. */
  2381. +        if( command != TVTIME_MENU_ENTER ) {
  2382. +            commands_handle( cmd, command, argument );
  2383. +        }
  2384. +    }
  2385. +}
  2386. +
  2387. +static void display_current_menu( commands_t *cmd )
  2388. +{
  2389. +    int i;
  2390. +
  2391. +    if( cmd->curmenu == MENU_FAVORITES ) {
  2392. +        char string[ 128 ];
  2393. +        tvtime_osd_list_set_lines( cmd->osd, cmd->numfavorites + 3 );
  2394. +        tvtime_osd_list_set_text( cmd->osd, 0, _("Favorites") );
  2395. +        for( i = 0; i < cmd->numfavorites; i++ ) {
  2396. +            char text[ 32 ];
  2397. +            snprintf( text, sizeof (text), "%d", cmd->favorites[ i ] );
  2398. +            tvtime_osd_list_set_text( cmd->osd, i + 1, text );
  2399. +        }
  2400. +        snprintf( string, sizeof( string ), TVTIME_ICON_PLUSBUTTON "  %s",
  2401. +                  _("Add current channel") );
  2402. +        tvtime_osd_list_set_text( cmd->osd, cmd->numfavorites + 1, string );
  2403. +        snprintf( string, sizeof( string ), TVTIME_ICON_EXIT "  %s", _("Exit") );
  2404. +        tvtime_osd_list_set_text( cmd->osd, cmd->numfavorites + 2, string );
  2405. +        cmd->curmenusize = cmd->numfavorites + 2;
  2406. +    } else if( cmd->curmenu == MENU_USER && cmd->curusermenu ) {
  2407. +        tvtime_osd_list_set_lines( cmd->osd, menu_get_num_lines( cmd->curusermenu ) );
  2408. +        for( i = 0; i < menu_get_num_lines( cmd->curusermenu ); i++ ) {
  2409. +            tvtime_osd_list_set_text( cmd->osd, i, menu_get_text( cmd->curusermenu, i ) );
  2410. +        }
  2411. +        cmd->curmenusize = menu_get_num_lines( cmd->curusermenu ) - 1;
  2412. +    }
  2413. +
  2414. +    tvtime_osd_list_set_hilight( cmd->osd, cmd->curmenupos + 1 );
  2415. +    tvtime_osd_show_list( cmd->osd, 1, 0 );
  2416. +    tvtime_osd_list_hold( cmd->osd, 1 );
  2417. +}
  2418. +
  2419. +menu_t *commands_get_menu( commands_t *cmd, const char *menuname )
  2420. +{
  2421. +    int i;
  2422. +
  2423. +    for( i = 0; i < tvtime_num_builtin_menus(); i++ ) {
  2424. +        if( !strcasecmp( menu_table[ i ].name, menuname ) ) {
  2425. +            if( menu_table[ i ].menutype == MENU_REDIRECT ) {
  2426. +                return commands_get_menu( cmd, menu_table[ i ].dest );
  2427. +            } else {
  2428. +                return 0;
  2429. +            }
  2430. +        }
  2431. +    }
  2432. +
  2433. +    for( i = 0; i < MAX_USER_MENUS; i++ ) {
  2434. +        if( !cmd->menus[ i ] ) break;
  2435. +
  2436. +        if( !strcasecmp( menuname, menu_get_name( cmd->menus[ i ] ) ) ) {
  2437. +            return cmd->menus[ i ];
  2438. +            cmd->curusermenu = cmd->menus[ i ];
  2439. +            break;
  2440. +        }
  2441. +    }
  2442. +
  2443. +    return 0;
  2444. +}
  2445. +
  2446. +static int set_menu( commands_t *cmd, const char *menuname )
  2447. +{
  2448. +    int i;
  2449. +
  2450. +    if( !menuname || !*menuname ) {
  2451. +        return 0;
  2452. +    }
  2453. +
  2454. +    cmd->menuactive = 1;
  2455. +    cmd->curusermenu = 0;
  2456. +
  2457. +    for( i = 0; i < tvtime_num_builtin_menus(); i++ ) {
  2458. +        if( !strcasecmp( menu_table[ i ].name, menuname ) ) {
  2459. +            if( menu_table[ i ].menutype == MENU_REDIRECT ) {
  2460. +                return set_menu( cmd, menu_table[ i ].dest );
  2461. +            } else {
  2462. +                cmd->curmenu = menu_table[ i ].menutype;
  2463. +                cmd->curmenupos = 0;
  2464. +                return 1;
  2465. +            }
  2466. +        }
  2467. +    }
  2468. +
  2469. +    cmd->curmenu = MENU_USER;
  2470. +    cmd->curusermenu = 0;
  2471. +
  2472. +    if( menuname && *menuname ) {
  2473. +        for( i = 0; i < MAX_USER_MENUS; i++ ) {
  2474. +            if( !cmd->menus[ i ] ) {
  2475. +                break;
  2476. +            }
  2477. +
  2478. +            if( !strcasecmp( menuname, menu_get_name( cmd->menus[ i ] ) ) ) {
  2479. +                cmd->curusermenu = cmd->menus[ i ];
  2480. +                break;
  2481. +            }
  2482. +        }
  2483. +    }
  2484. +
  2485. +    if( cmd->curusermenu ) {
  2486. +        cmd->curmenupos = menu_get_cursor( cmd->curusermenu );
  2487. +        cmd->curmenusize = menu_get_num_lines( cmd->curusermenu ) - 1;
  2488. +        return 1;
  2489. +    }
  2490. +
  2491. +    cmd->menuactive = 0;
  2492. +    return 0;
  2493. +}
  2494. +
  2495. +void commands_refresh_menu( commands_t *cmd )
  2496. +{
  2497. +    if( cmd->menuactive ) {
  2498. +        if( cmd->curmenu == MENU_USER ) {
  2499. +            const char *curname = menu_get_name( cmd->curusermenu );
  2500. +            int i;
  2501. +
  2502. +            for( i = 0; i < tvtime_num_builtin_menus(); i++ ) {
  2503. +                if( !strncasecmp( menu_table[ i ].name, curname, strlen( menu_table[ i ].name ) ) ) {
  2504. +                    if( menu_table[ i ].menutype == MENU_REDIRECT ) {
  2505. +                        set_menu( cmd, menu_table[ i ].name );
  2506. +                        break;
  2507. +                    }
  2508. +                }
  2509. +            }
  2510. +        }
  2511. +        display_current_menu( cmd );
  2512. +    }
  2513. +}
  2514. +
  2515. +void commands_add_menu( commands_t *cmd, menu_t *menu )
  2516. +{
  2517. +    int i;
  2518. +
  2519. +    for( i = 0; i < MAX_USER_MENUS; i++ ) {
  2520. +        if( !cmd->menus[ i ] ) {
  2521. +            cmd->menus[ i ] = menu;
  2522. +            return;
  2523. +        }
  2524. +    }
  2525. +}
  2526. +
  2527. +void commands_set_station_mgr( commands_t *cmd, station_mgr_t *mgr )
  2528. +{
  2529. +    cmd->stationmgr = mgr;
  2530. +    reinit_tuner( cmd );
  2531. +}
  2532. +
  2533. +void commands_clear_menu_positions( commands_t *cmd )
  2534. +{
  2535. +    int i;
  2536. +
  2537. +    for( i = 0; i < MAX_USER_MENUS; i++ ) {
  2538. +        if( cmd->menus[ i ] ) {
  2539. +            menu_set_cursor( cmd->menus[ i ], menu_get_default_cursor( cmd->menus[ i ] ) );
  2540. +        } else {
  2541. +            return;
  2542. +        }
  2543. +    }
  2544. +}
  2545. +
  2546. +int commands_in_menu( commands_t *cmd )
  2547. +{
  2548. +    return cmd->menuactive;
  2549. +}
  2550. +
  2551. +static void osd_list_xmltv_languages( tvtime_osd_t *osd, commands_t *cmd )
  2552. +{
  2553. +    int num = xmltv_get_num_languages( cmd->xmltv );
  2554. +    const char *cur = xmltv_get_language( cmd->xmltv );
  2555. +    char string[ 128 ];
  2556. +    int i;
  2557. +
  2558. +    if( !cmd->xmltv ) return;
  2559. +
  2560. +    tvtime_osd_list_set_hilight( osd, 1 );
  2561. +    tvtime_osd_list_set_lines( osd, num + 2);
  2562. +    tvtime_osd_list_set_text( osd, 0, _("Preferred XMLTV language") );
  2563. +    tvtime_osd_list_set_text( osd, 1, _("Default language") );
  2564. +    for( i = 1; i <= num; i++ ) {
  2565. +        const char *code = xmltv_get_language_code( cmd->xmltv, i );
  2566. +        const char *name = xmltv_get_language_name( cmd->xmltv, i );
  2567. +        snprintf( string, sizeof( string ), "%s (%s)",
  2568. +                  name? name : _("Unknown language"), code );
  2569. +        tvtime_osd_list_set_text( osd, i + 1, string );
  2570. +        if( cur && code && !strncasecmp( cur, code, 2 ) ) {
  2571. +            tvtime_osd_list_set_hilight( osd, i + 1 );
  2572. +        }
  2573. +    }
  2574. +    tvtime_osd_show_list( osd, 1, 0 );
  2575. +}
  2576. +
  2577. +void commands_handle( commands_t *cmd, int tvtime_cmd, const char *arg )
  2578. +{
  2579. +    time_t now;
  2580. +    int volume;
  2581. +    int key;
  2582. +
  2583. +    if( tvtime_cmd == TVTIME_NOCOMMAND ) return;
  2584. +
  2585. +    if( cmd->menuactive && tvtime_is_menu_command( tvtime_cmd ) ) {
  2586. +        int x, y, line;
  2587. +        switch( tvtime_cmd ) {
  2588. +        case TVTIME_MENU_EXIT:
  2589. +            menu_off( cmd );
  2590. +            break;
  2591. +        case TVTIME_MENU_UP:
  2592. +            cmd->curmenupos = (cmd->curmenupos + cmd->curmenusize - 1) % (cmd->curmenusize);
  2593. +            if( cmd->curusermenu ) menu_set_cursor( cmd->curusermenu, cmd->curmenupos );
  2594. +            display_current_menu( cmd );
  2595. +            break;
  2596. +        case TVTIME_MENU_DOWN:
  2597. +            cmd->curmenupos = (cmd->curmenupos + 1) % (cmd->curmenusize);
  2598. +            if( cmd->curusermenu ) menu_set_cursor( cmd->curusermenu, cmd->curmenupos );
  2599. +            display_current_menu( cmd );
  2600. +            break;
  2601. +        case TVTIME_MENU_BACK: menu_back( cmd ); break;
  2602. +        case TVTIME_MENU_ENTER: menu_enter( cmd ); break;
  2603. +        case TVTIME_SHOW_MENU:
  2604. +            if( set_menu( cmd, arg ) ) {
  2605. +                display_current_menu( cmd );
  2606. +            } else {
  2607. +                menu_off( cmd );
  2608. +            }
  2609. +            break;
  2610. +        case TVTIME_MOUSE_MOVE:
  2611. +            sscanf( arg, "%d %d", &x, &y );
  2612. +            if( cmd->halfsize ) y *= 2;
  2613. +            line = tvtime_osd_list_get_line_pos( cmd->osd, y );
  2614. +            if( line > 0 ) {
  2615. +                cmd->curmenupos = (line - 1);
  2616. +                if( cmd->curusermenu ) menu_set_cursor( cmd->curusermenu, cmd->curmenupos );
  2617. +                display_current_menu( cmd );
  2618. +            }
  2619. +            break;
  2620. +        }
  2621. +        return;
  2622. +    }
  2623. +
  2624. +    switch( tvtime_cmd ) {
  2625. +    case TVTIME_NOOP:
  2626. +        break;
  2627. +
  2628. +    case TVTIME_QUIT:
  2629. +        cmd->quit = 1;
  2630. +        break;
  2631. +
  2632. +    case TVTIME_SHOW_MENU:
  2633. +        if( cmd->osd ) {
  2634. +            commands_clear_menu_positions( cmd );
  2635. +            if( set_menu( cmd, arg ) || set_menu( cmd, "root" ) ) {
  2636. +                display_current_menu( cmd );
  2637. +            }
  2638. +        }
  2639. +        break;
  2640. +
  2641. +    case TVTIME_KEY_EVENT:
  2642. +        key = input_string_to_special_key( arg );
  2643. +        if( !key ) key = arg[ 0 ];
  2644. +        tvtime_cmd = config_key_to_command( cmd->cfg, key );
  2645. +        if( tvtime_cmd != TVTIME_KEY_EVENT ) {
  2646. +            commands_handle( cmd, tvtime_cmd, arg );
  2647. +        }
  2648. +        break;
  2649. +
  2650. +    case TVTIME_UP:
  2651. +        if( cmd->menuactive ) {
  2652. +            commands_handle( cmd, TVTIME_MENU_UP, "" );
  2653. +        } else {
  2654. +            commands_handle( cmd, TVTIME_CHANNEL_INC, "" );
  2655. +        }
  2656. +        break;
  2657. +    case TVTIME_DOWN:
  2658. +        if( cmd->menuactive ) {
  2659. +            commands_handle( cmd, TVTIME_MENU_DOWN, "" );
  2660. +        } else {
  2661. +            commands_handle( cmd, TVTIME_CHANNEL_DEC, "" );
  2662. +        }
  2663. +        break;
  2664. +    case TVTIME_LEFT:
  2665. +        if( cmd->menuactive ) {
  2666. +            commands_handle( cmd, TVTIME_MENU_BACK, "" );
  2667. +        } else {
  2668. +            commands_handle( cmd, TVTIME_MIXER_DOWN, "" );
  2669. +        }
  2670. +        break;
  2671. +    case TVTIME_RIGHT:
  2672. +        if( cmd->menuactive ) {
  2673. +            commands_handle( cmd, TVTIME_MENU_ENTER, "" );
  2674. +        } else {
  2675. +            commands_handle( cmd, TVTIME_MIXER_UP, "" );
  2676. +        }
  2677. +        break;
  2678. +
  2679. +    case TVTIME_SLEEP:
  2680. +        time( &now );
  2681. +        /**
  2682. +         * increment sleeptimer by SLEEPTIMER_STEP if user hits
  2683. +         * button within 5 seconds else turn it off
  2684. +         */
  2685. +        if( cmd->sleeptimer_start && (now > (cmd->sleeptimer_start + 5)) ) {
  2686. +            cmd->sleeptimer = 0;
  2687. +            cmd->sleeptimer_start = 0;
  2688. +        } else if( cmd->sleeptimer > SLEEPTIMER_NUMSTEPS ) {
  2689. +            cmd->sleeptimer = 0;
  2690. +            cmd->sleeptimer_start = 0;
  2691. +        } else {
  2692. +            cmd->sleeptimer++;
  2693. +            cmd->sleeptimer_start = now;
  2694. +        }
  2695. +
  2696. +        if( cmd->osd ) {
  2697. +            char message[ 256 ];
  2698. +
  2699. +            if( cmd->sleeptimer ) {
  2700. +                snprintf( message, sizeof (message), _("Sleep in %d minutes."),
  2701. +                          sleeptimer_function( cmd->sleeptimer ) );
  2702. +            } else {
  2703. +                snprintf( message, sizeof (message), _("Sleep off.") );
  2704. +            }
  2705. +
  2706. +            tvtime_osd_show_message( cmd->osd, message );
  2707. +        }
  2708. +        break;
  2709. +
  2710. +    case TVTIME_SHOW_DEINTERLACER_INFO:
  2711. +        cmd->showdeinterlacerinfo = 1;
  2712. +        break;
  2713. +
  2714. +    case TVTIME_SHOW_STATS:
  2715. +        cmd->printdebug = 1;
  2716. +        break;
  2717. +
  2718. +    case TVTIME_RESTART:
  2719. +        cmd->restarttvtime = 1;
  2720. +        break;
  2721. +
  2722. +    case TVTIME_SCREENSHOT:
  2723. +        if( arg ) {
  2724. +            snprintf( cmd->screenshotfile, sizeof( cmd->screenshotfile ),
  2725. +                      "%s", arg );
  2726. +        } else {
  2727. +            *cmd->screenshotfile = 0;
  2728. +        }
  2729. +        cmd->screenshot = 1;
  2730. +        break;
  2731. +
  2732. +    case TVTIME_TOGGLE_CHANNEL_PAL_DK:
  2733. +        if( cmd->vidin ) {
  2734. +            int new_mode = (station_get_current_audio_norm( cmd->stationmgr ) + 1) % 3;
  2735. +            station_set_current_audio_norm( cmd->stationmgr, new_mode );
  2736. +            videoinput_set_pal_audio_mode( cmd->vidin,
  2737. +                                           station_get_current_audio_norm( cmd->stationmgr ) );
  2738. +            if( cmd->osd ) {
  2739. +                char message[ 128 ];
  2740. +                if( new_mode == VIDEOINPUT_PAL_I_AUDIO ) {
  2741. +                    snprintf( message, sizeof( message ),
  2742. +                              _("Using PAL-I audio decoding for this channel.") );
  2743. +                } else if( new_mode == VIDEOINPUT_PAL_DK_AUDIO ) {
  2744. +                    snprintf( message, sizeof( message ),
  2745. +                              _("Using PAL-DK audio decoding for this channel.") );
  2746. +                } else {
  2747. +                    snprintf( message, sizeof( message ),
  2748. +                              _("Using PAL-BG audio decoding for this channel.") );
  2749. +                }
  2750. +                reset_stations_menu( commands_get_menu( cmd, "stations" ),
  2751. +                                     (videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC ||
  2752. +                                      videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC_JP),
  2753. +                                     videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_PAL,
  2754. +                                     videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_SECAM,
  2755. +                                     (!strcasecmp( cmd->newfreqtable, "us-cable" ) ||
  2756. +                                      !strcasecmp( cmd->newfreqtable, "us-cable100" )),
  2757. +                                     station_get_current_active( cmd->stationmgr ), cmd->checkfreq,
  2758. +                                     cmd->scan_channels,
  2759. +                                     videoinput_is_v4l2( cmd->vidin ),
  2760. +                                     station_get_default_audio_norm( cmd->stationmgr ),
  2761. +                                     station_get_current_audio_norm( cmd->stationmgr ) );
  2762. +                commands_refresh_menu( cmd );
  2763. +                tvtime_osd_show_message( cmd->osd, message );
  2764. +            }
  2765. +        }
  2766. +        break;
  2767. +
  2768. +    case TVTIME_TOGGLE_PAL_DK_AUDIO:
  2769. +        if( cmd->vidin ) {
  2770. +            int dk_default = station_get_default_audio_norm( cmd->stationmgr );
  2771. +            char message[ 128 ];
  2772. +            dk_default = (dk_default + 1) % 3;
  2773. +            station_set_default_audio_norm( cmd->stationmgr, dk_default );
  2774. +            videoinput_set_pal_audio_mode( cmd->vidin,
  2775. +                                           station_get_current_audio_norm( cmd->stationmgr ) );
  2776. +            if( cmd->osd ) {
  2777. +                if( dk_default == VIDEOINPUT_PAL_I_AUDIO ) {
  2778. +                    snprintf( message, sizeof( message ),
  2779. +                              _("Defaulting to PAL-I audio decoding.") );
  2780. +                } else if( dk_default == VIDEOINPUT_PAL_DK_AUDIO ) {
  2781. +                    snprintf( message, sizeof( message ),
  2782. +                              _("Defaulting to PAL-DK audio decoding.") );
  2783. +                } else {
  2784. +                    snprintf( message, sizeof( message ),
  2785. +                              _("Defaulting to PAL-BG audio decoding.") );
  2786. +                }
  2787. +                reset_pal_input_menu( commands_get_menu( cmd, "input-pal" ),
  2788. +                                      cmd->vidin, cmd->stationmgr );
  2789. +                commands_refresh_menu( cmd );
  2790. +                tvtime_osd_show_message( cmd->osd, message );
  2791. +            }
  2792. +        }
  2793. +        break;
  2794. +
  2795. +    case TVTIME_TOGGLE_BARS:
  2796. +        cmd->showbars = !cmd->showbars;
  2797. +        break;
  2798. +
  2799. +    case TVTIME_TOGGLE_FULLSCREEN:
  2800. +        cmd->togglefullscreen = 1;
  2801. +        break;
  2802. +
  2803. +    case TVTIME_TOGGLE_FRAMERATE:
  2804. +        cmd->framerate = (cmd->framerate + 1) % FRAMERATE_MAX;
  2805. +        break;
  2806. +
  2807. +    case TVTIME_CHANNEL_SKIP:
  2808. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  2809. +            station_set_current_active( cmd->stationmgr, !station_get_current_active( cmd->stationmgr ) );
  2810. +            if( cmd->osd ) {
  2811. +                if( station_get_current_active( cmd->stationmgr ) ) {
  2812. +                    tvtime_osd_show_message( cmd->osd,
  2813. +                        _("Channel marked as active in the browse list.") );
  2814. +                } else {
  2815. +                    tvtime_osd_show_message( cmd->osd,
  2816. +                        _("Channel disabled from the browse list.") );
  2817. +                }
  2818. +            }
  2819. +            reset_stations_menu( commands_get_menu( cmd, "stations" ),
  2820. +                                 (videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC ||
  2821. +                                  videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC_JP),
  2822. +                                 videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_PAL,
  2823. +                                 videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_SECAM,
  2824. +                                 (!strcasecmp( cmd->newfreqtable, "us-cable" ) ||
  2825. +                                  !strcasecmp( cmd->newfreqtable, "us-cable100" )),
  2826. +                                 station_get_current_active( cmd->stationmgr ), cmd->checkfreq,
  2827. +                                 cmd->scan_channels,
  2828. +                                 videoinput_is_v4l2( cmd->vidin ),
  2829. +                                 station_get_default_audio_norm( cmd->stationmgr ),
  2830. +                                 station_get_current_audio_norm( cmd->stationmgr ) );
  2831. +            commands_refresh_menu( cmd );
  2832. +            station_writeconfig( cmd->stationmgr );
  2833. +        }
  2834. +        break;
  2835. +
  2836. +    case TVTIME_SET_AUDIO_BOOST:
  2837. +        cmd->boost = atoi( arg );
  2838. +        if( cmd->vidin ) {
  2839. +            videoinput_set_capture_volume( cmd->vidin, cmd->boost );
  2840. +        }
  2841. +        if( cmd->osd ) {
  2842. +            menu_t *boostmenu = commands_get_menu( cmd, "audioboost" );
  2843. +            char message[ 128 ];
  2844. +            reset_audio_boost_menu( boostmenu, cmd->boost );
  2845. +            commands_refresh_menu( cmd );
  2846. +            if( cmd->boost < 0 ) {
  2847. +                snprintf( message, sizeof( message ),
  2848. +                          _("Capture card volume will not be set by tvtime.") );
  2849. +            } else {
  2850. +                snprintf( message, sizeof( message ),
  2851. +                          _("Setting capture card volume to %d%%."),
  2852. +                          cmd->boost );
  2853. +            }
  2854. +            tvtime_osd_show_message( cmd->osd, message );
  2855. +        }
  2856. +        break;
  2857. +
  2858. +    case TVTIME_SET_DEINTERLACER:
  2859. +        cmd->setdeinterlacer = 1;
  2860. +        snprintf( cmd->deinterlacer, sizeof( cmd->deinterlacer ), "%s", arg );
  2861. +        break;
  2862. +
  2863. +    case TVTIME_SET_FREQUENCY_TABLE:
  2864. +        cmd->setfreqtable = 1;
  2865. +        snprintf( cmd->newfreqtable, sizeof( cmd->newfreqtable ), "%s", arg );
  2866. +        if( cmd->vidin ) {
  2867. +            reset_frequency_menu( commands_get_menu( cmd, "frequencies" ),
  2868. +                                  videoinput_get_norm( cmd->vidin ), cmd->newfreqtable );
  2869. +            commands_refresh_menu( cmd );
  2870. +        }
  2871. +        break;
  2872. +
  2873. +    case TVTIME_SET_FRAMERATE:
  2874. +        if( !strcasecmp( arg, "full" ) ) {
  2875. +            cmd->framerate = FRAMERATE_FULL;
  2876. +        } else if( !strcasecmp( arg, "top" ) ) {
  2877. +            cmd->framerate = FRAMERATE_HALF_TFF;
  2878. +        } else {
  2879. +            cmd->framerate = FRAMERATE_HALF_BFF;
  2880. +        }
  2881. +        if( cmd->osd ) {
  2882. +            if( cmd->framerate == FRAMERATE_FULL ) {
  2883. +                tvtime_osd_show_message( cmd->osd,
  2884. +                    _("Processing every input field.") );
  2885. +            } else if( cmd->framerate == FRAMERATE_HALF_TFF ) {
  2886. +                tvtime_osd_show_message( cmd->osd,
  2887. +                    _("Processing every top field.") );
  2888. +            } else {
  2889. +                tvtime_osd_show_message( cmd->osd,
  2890. +                    _("Processing every bottom field.") );
  2891. +            }
  2892. +        }
  2893. +        break;
  2894. +
  2895. +    case TVTIME_SET_INPUT_WIDTH:
  2896. +        cmd->newinputwidth = atoi( arg );
  2897. +        if( cmd->osd ) {
  2898. +            const char *curname = menu_get_name( cmd->curusermenu );
  2899. +            menu_t *sharpmenu = commands_get_menu( cmd, "hres" );
  2900. +            char message[ 128 ];
  2901. +            int maxw = cmd->vidin? videoinput_get_maxwidth( cmd->vidin ) : 0;
  2902. +            reset_inputwidth_menu( sharpmenu, cmd->newinputwidth, maxw );
  2903. +            curname = menu_get_name( cmd->curusermenu );
  2904. +            commands_refresh_menu( cmd );
  2905. +            snprintf( message, sizeof( message ),
  2906. +                      _("Horizontal resolution will be %d pixels on restart."),
  2907. +                      cmd->newinputwidth );
  2908. +            tvtime_osd_show_message( cmd->osd, message );
  2909. +        }
  2910. +        break;
  2911. +
  2912. +    case TVTIME_SET_FULLSCREEN_POSITION:
  2913. +        if( arg ) {
  2914. +            snprintf( cmd->newpos, sizeof( cmd->newpos ), "%s", arg );
  2915. +        }
  2916. +        break;
  2917. +
  2918. +    case TVTIME_SET_MATTE:
  2919. +        if( arg ) {
  2920. +            snprintf( cmd->newmatte, sizeof( cmd->newmatte ), "%s", arg );
  2921. +        }
  2922. +        break;
  2923. +
  2924. +    case TVTIME_SET_STATION:
  2925. +        if( arg ) {
  2926. +            if( isdigit( arg[ 0 ] ) ) {
  2927. +                station_set( cmd->stationmgr, atoi( arg ) );
  2928. +            } else {
  2929. +                station_set_by_name( cmd->stationmgr, arg );
  2930. +            }
  2931. +            cmd->change_channel = 1;
  2932. +        }
  2933. +        break;
  2934. +
  2935. +    case TVTIME_SET_NORM:
  2936. +        if( !arg || !*arg ) {
  2937. +            cmd->newnorm = "NTSC";
  2938. +        } else if( !strcasecmp( arg, "pal" ) ) {
  2939. +            cmd->newnorm = "PAL";
  2940. +        } else if( !strcasecmp( arg, "secam" ) ) {
  2941. +            cmd->newnorm = "SECAM";
  2942. +        } else if( !strcasecmp( arg, "pal-nc" ) ) {
  2943. +            cmd->newnorm = "PAL-Nc";
  2944. +        } else if( !strcasecmp( arg, "pal-m" ) ) {
  2945. +            cmd->newnorm = "PAL-M";
  2946. +        } else if( !strcasecmp( arg, "pal-n" ) ) {
  2947. +            cmd->newnorm = "PAL-N";
  2948. +        } else if( !strcasecmp( arg, "ntsc-jp" ) ) {
  2949. +            cmd->newnorm = "NTSC-JP";
  2950. +        } else if( !strcasecmp( arg, "pal-60" ) ) {
  2951. +            cmd->newnorm = "PAL-60";
  2952. +        } else {
  2953. +            cmd->newnorm = "NTSC";
  2954. +        }
  2955. +        cmd->normset = 1;
  2956. +
  2957. +        if( cmd->osd ) {
  2958. +            menu_t *normmenu = commands_get_menu( cmd, "norm" );
  2959. +            char message[ 128 ];
  2960. +            reset_norm_menu( normmenu, cmd->newnorm );
  2961. +            commands_refresh_menu( cmd );
  2962. +            snprintf( message, sizeof (message),
  2963. +                      _("Television standard will be %s on restart."),
  2964. +                      cmd->newnorm );
  2965. +            tvtime_osd_show_message( cmd->osd, message );
  2966. +        }
  2967. +        break;
  2968. +
  2969. +    case TVTIME_SET_XMLTV_LANGUAGE:
  2970. +        if( cmd->xmltv && arg ) {
  2971. +            if( isdigit( arg[ 0 ] ) ) {
  2972. +                xmltv_select_language( cmd->xmltv, atoi( arg ) );
  2973. +            } else if( !strcasecmp( arg, "none" ) ) {
  2974. +                xmltv_set_language( cmd->xmltv, 0 );
  2975. +            } else {
  2976. +                xmltv_set_language( cmd->xmltv, arg );
  2977. +            }
  2978. +            update_xmltv_listings( cmd );
  2979. +
  2980. +            if( cmd->osd ) {
  2981. +                char message[ 128 ];
  2982. +                menu_t *langmenu = commands_get_menu( cmd, "xmltv-language" );
  2983. +                int i = xmltv_get_langnum( cmd->xmltv );
  2984. +                const char *code = xmltv_get_language_code( cmd->xmltv, i );
  2985. +                const char *name = xmltv_get_language_name( cmd->xmltv, i );
  2986. +
  2987. +                reset_xmltv_languages_menu( langmenu, cmd->xmltv );
  2988. +                commands_refresh_menu( cmd );
  2989. +                if( !code ) {
  2990. +                    snprintf( message, sizeof( message ),
  2991. +                              _("Using default language for XMLTV data.") );
  2992. +                } else if( !name ) {
  2993. +                    snprintf( message, sizeof( message ),
  2994. +                              _("Using unknown language (%s) for XMLTV data."),
  2995. +                              code );
  2996. +                } else {
  2997. +                    snprintf( message, sizeof( message ),
  2998. +                              _("XMLTV language set to %s (%s)."),
  2999. +                              name, code );
  3000. +                }
  3001. +                tvtime_osd_show_message( cmd->osd, message );
  3002. +            }
  3003. +
  3004. +            config_save( cmd->cfg, "XMLTVLanguage", arg );
  3005. +        }
  3006. +        break;
  3007. +
  3008. +    case TVTIME_TOGGLE_ASPECT:
  3009. +        cmd->toggleaspect = 1;
  3010. +        break;
  3011. +
  3012. +    case TVTIME_TOGGLE_ALWAYSONTOP:
  3013. +        cmd->togglealwaysontop = 1;
  3014. +        break;
  3015. +
  3016. +    case TVTIME_CHANNEL_SAVE_TUNING:
  3017. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3018. +            char freq[ 32 ];
  3019. +            int pos;
  3020. +
  3021. +            snprintf( freq, sizeof( freq ), "%f", ((double) videoinput_get_tuner_freq( cmd->vidin )) / 1000.0 );
  3022. +            pos = station_add( cmd->stationmgr, 0, "Custom", freq, 0 );
  3023. +            station_writeconfig( cmd->stationmgr );
  3024. +            station_set( cmd->stationmgr, pos );
  3025. +            cmd->change_channel = 1;
  3026. +        }
  3027. +        break;
  3028. +
  3029. +    case TVTIME_CHANNEL_ACTIVATE_ALL:
  3030. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3031. +            if( cmd->osd ) {
  3032. +                tvtime_osd_show_message( cmd->osd,
  3033. +                                         _("All channels re-activated.") );
  3034. +            }
  3035. +            station_activate_all_channels( cmd->stationmgr );
  3036. +            station_writeconfig( cmd->stationmgr );
  3037. +        }
  3038. +        break;
  3039. +
  3040. +    case TVTIME_CHANNEL_RENUMBER:
  3041. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3042. +            /* If we're scanning and suddenly want to renumber, stop scanning. */
  3043. +            if( cmd->scan_channels ) {
  3044. +                commands_handle( cmd, TVTIME_CHANNEL_SCAN, 0 );
  3045. +            }
  3046. +
  3047. +            /* Accept input of the destination channel. */
  3048. +            if( cmd->digit_counter == 0 ) memset( cmd->next_chan_buffer, 0, 5 );
  3049. +            cmd->frame_counter = cmd->delay;
  3050. +            cmd->renumbering = 1;
  3051. +            if( cmd->osd ) {
  3052. +                char message[ 256 ];
  3053. +                snprintf( message, sizeof( message ),
  3054. +                          _("Remapping %d.  Enter new channel number."),
  3055. +                          station_get_current_id( cmd->stationmgr ) );
  3056. +                tvtime_osd_set_hold_message( cmd->osd, message, 0 );
  3057. +            }
  3058. +        }
  3059. +        break;
  3060. +
  3061. +    case TVTIME_CHANNEL_SCAN:
  3062. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3063. +            if( !cmd->checkfreq ) {
  3064. +                if( cmd->osd ) {
  3065. +                    tvtime_osd_show_message( cmd->osd,
  3066. +                      _("Scanner unavailable with signal checking disabled.") );
  3067. +                }
  3068. +            } else {
  3069. +                cmd->scan_channels = !cmd->scan_channels;
  3070. +
  3071. +                if( cmd->scan_channels && cmd->renumbering ) {
  3072. +                    memset( cmd->next_chan_buffer, 0, 5 );
  3073. +                    cmd->digit_counter = 0;
  3074. +                    cmd->frame_counter = 0;
  3075. +                    if( cmd->osd ) tvtime_osd_set_hold_message( cmd->osd, "", 0 );
  3076. +                    cmd->renumbering = 0;
  3077. +                }
  3078. +
  3079. +                if( cmd->osd ) {
  3080. +                    reset_stations_menu( commands_get_menu( cmd, "stations" ),
  3081. +                                         (videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC ||
  3082. +                                          videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC_JP),
  3083. +                                         videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_PAL,
  3084. +                                         videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_SECAM,
  3085. +                                         (!strcasecmp( cmd->newfreqtable, "us-cable" ) ||
  3086. +                                          !strcasecmp( cmd->newfreqtable, "us-cable100" )),
  3087. +                                         station_get_current_active( cmd->stationmgr ), cmd->checkfreq,
  3088. +                                         cmd->scan_channels,
  3089. +                                         videoinput_is_v4l2( cmd->vidin ),
  3090. +                                         station_get_default_audio_norm( cmd->stationmgr ),
  3091. +                                         station_get_current_audio_norm( cmd->stationmgr ) );
  3092. +                    commands_refresh_menu( cmd );
  3093. +
  3094. +                    if( cmd->scan_channels ) {
  3095. +                        tvtime_osd_set_hold_message( cmd->osd,
  3096. +                            _("Scanning for channels being broadcast."), 0 );
  3097. +                    } else {
  3098. +                        /* Nuke the hold message, and make sure we show nothing (hack). */
  3099. +                        tvtime_osd_set_hold_message( cmd->osd, "", 0 );
  3100. +                        tvtime_osd_show_message( cmd->osd, " " );
  3101. +                    }
  3102. +                    tvtime_osd_show_info( cmd->osd );
  3103. +                }
  3104. +            }
  3105. +        }
  3106. +        break;
  3107. +
  3108. +    case TVTIME_TOGGLE_CC:
  3109. +        if( cmd->vbi ) {
  3110. +            vbidata_capture_mode( cmd->vbi, cmd->capturemode ? CAPTURE_OFF : CAPTURE_CC1 );
  3111. +            if( cmd->capturemode ) {
  3112. +                if( cmd->osd ) {
  3113. +                    tvtime_osd_show_message( cmd->osd,
  3114. +                        _("Closed captions disabled.") );
  3115. +                }
  3116. +                cmd->capturemode = CAPTURE_OFF;
  3117. +            } else {
  3118. +                if( cmd->osd ) {
  3119. +                    tvtime_osd_show_message( cmd->osd,
  3120. +                        _("Closed captions enabled.") );
  3121. +                }
  3122. +                cmd->capturemode = CAPTURE_CC1;
  3123. +            }
  3124. +            if( cmd->capturemode ) {
  3125. +                config_save( cmd->cfg, "ShowCC", "1" );
  3126. +            } else {
  3127. +                config_save( cmd->cfg, "ShowCC", "0" );
  3128. +            }
  3129. +        } else {
  3130. +            if( cmd->osd ) {
  3131. +                tvtime_osd_show_message( cmd->osd,
  3132. +                    _("No VBI device configured for CC decoding.") );
  3133. +            }
  3134. +        }
  3135. +        break;
  3136. +
  3137. +    case TVTIME_TOGGLE_PAL_SECAM:
  3138. +        videoinput_toggle_pal_secam( cmd->vidin );
  3139. +        if( videoinput_has_tuner( cmd->vidin ) ) {
  3140. +            station_set_current_norm( cmd->stationmgr, videoinput_get_norm_name( videoinput_get_norm( cmd->vidin ) ) );
  3141. +            station_writeconfig( cmd->stationmgr );
  3142. +        }
  3143. +        if( cmd->osd ) {
  3144. +            char message[ 128 ];
  3145. +            tvtime_osd_set_norm( cmd->osd, videoinput_get_norm_name( videoinput_get_norm( cmd->vidin ) ) );
  3146. +            tvtime_osd_show_info( cmd->osd );
  3147. +            snprintf( message, sizeof( message ),
  3148. +                      _("Colour decoding for this channel set to %s."),
  3149. +                      videoinput_get_norm_name( videoinput_get_norm( cmd->vidin ) ) );
  3150. +            tvtime_osd_show_message( cmd->osd, message );
  3151. +
  3152. +            reset_stations_menu( commands_get_menu( cmd, "stations" ),
  3153. +                                 (videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC ||
  3154. +                                  videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC_JP),
  3155. +                                 videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_PAL,
  3156. +                                 videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_SECAM,
  3157. +                                 (!strcasecmp( cmd->newfreqtable, "us-cable" ) ||
  3158. +                                  !strcasecmp( cmd->newfreqtable, "us-cable100" )),
  3159. +                                 station_get_current_active( cmd->stationmgr ), cmd->checkfreq,
  3160. +                                 cmd->scan_channels,
  3161. +                                 videoinput_is_v4l2( cmd->vidin ),
  3162. +                                 station_get_default_audio_norm( cmd->stationmgr ),
  3163. +                                 station_get_current_audio_norm( cmd->stationmgr ) );
  3164. +            commands_refresh_menu( cmd );
  3165. +        }
  3166. +
  3167. +        break;
  3168. +
  3169. +    case TVTIME_DISPLAY_MESSAGE:
  3170. +        if( cmd->osd && arg ) tvtime_osd_show_message( cmd->osd, arg );
  3171. +        break;
  3172. +
  3173. +    case TVTIME_DISPLAY_INFO:
  3174. +        cmd->displayinfo = !cmd->displayinfo;
  3175. +        if( cmd->osd ) {
  3176. +            if( cmd->xmltv && cmd->vidin &&
  3177. +                videoinput_has_tuner( cmd->vidin ) ) {
  3178. +                update_xmltv_display( cmd );
  3179. +            }
  3180. +            if( cmd->displayinfo ) {
  3181. +                tvtime_osd_hold( cmd->osd, 1 );
  3182. +                tvtime_osd_show_info( cmd->osd );
  3183. +            } else {
  3184. +                tvtime_osd_hold( cmd->osd, 0 );
  3185. +                tvtime_osd_clear( cmd->osd );
  3186. +            }
  3187. +        }
  3188. +        break;
  3189. +
  3190. +    case TVTIME_RUN_COMMAND:
  3191. +        if( arg ) {
  3192. +            char commandline[ 256 ];
  3193. +            snprintf( commandline, sizeof (commandline), "%s &", arg );
  3194. +            if( cmd->osd ) {
  3195. +                char message[ 256 ];
  3196. +                snprintf( message, sizeof (message), _("Running: %s"), arg );
  3197. +                tvtime_osd_show_message( cmd->osd, message );
  3198. +            }
  3199. +            system( commandline );
  3200. +        }
  3201. +        break;
  3202. +
  3203. +    case TVTIME_TOGGLE_CREDITS:
  3204. +        break;
  3205. +
  3206. +    case TVTIME_SET_AUDIO_MODE:
  3207. +        if( cmd->vidin ) {
  3208. +            if( !strcasecmp( arg, "mono" ) ) {
  3209. +                videoinput_set_audio_mode( cmd->vidin, VIDEOINPUT_MONO );
  3210. +            } else if( !strcasecmp( arg, "stereo" ) ) {
  3211. +                videoinput_set_audio_mode( cmd->vidin, VIDEOINPUT_STEREO );
  3212. +            } else if( !strcasecmp( arg, "sap" ) || !strcasecmp( arg, "lang1" ) ) {
  3213. +                videoinput_set_audio_mode( cmd->vidin, VIDEOINPUT_LANG1 );
  3214. +            } else {
  3215. +                videoinput_set_audio_mode( cmd->vidin, VIDEOINPUT_LANG2 );
  3216. +            }
  3217. +            if( cmd->osd ) {
  3218. +                if( !cmd->menuactive ) {
  3219. +                    osd_list_audio_modes( cmd->osd, videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC,
  3220. +                                          videoinput_get_audio_mode( cmd->vidin ) );
  3221. +                }
  3222. +                tvtime_osd_set_audio_mode( cmd->osd, videoinput_get_audio_mode_name( cmd->vidin, videoinput_get_audio_mode( cmd->vidin ) ) );
  3223. +                tvtime_osd_show_info( cmd->osd );
  3224. +                reset_audio_mode_menu( commands_get_menu( cmd, "audiomode" ),
  3225. +                                       videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC,
  3226. +                                       videoinput_get_audio_mode( cmd->vidin ) );
  3227. +                commands_refresh_menu( cmd );
  3228. +            }
  3229. +        }
  3230. +        break;
  3231. +
  3232. +    case TVTIME_TOGGLE_AUDIO_MODE:
  3233. +        if( cmd->vidin ) {
  3234. +            videoinput_set_audio_mode( cmd->vidin, videoinput_get_audio_mode( cmd->vidin ) << 1 );
  3235. +            if( cmd->osd ) {
  3236. +                osd_list_audio_modes( cmd->osd, videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC,
  3237. +                                      videoinput_get_audio_mode( cmd->vidin ) );
  3238. +                tvtime_osd_set_audio_mode( cmd->osd, videoinput_get_audio_mode_name( cmd->vidin, videoinput_get_audio_mode( cmd->vidin ) ) );
  3239. +                tvtime_osd_show_info( cmd->osd );
  3240. +                reset_audio_mode_menu( commands_get_menu( cmd, "audiomode" ),
  3241. +                                       videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC,
  3242. +                                       videoinput_get_audio_mode( cmd->vidin ) );
  3243. +                commands_refresh_menu( cmd );
  3244. +            }
  3245. +        }
  3246. +        break;
  3247. +
  3248. +    case TVTIME_TOGGLE_DEINTERLACER:
  3249. +        cmd->toggledeinterlacer = 1;
  3250. +        break;
  3251. +
  3252. +    case TVTIME_TOGGLE_PULLDOWN_DETECTION:
  3253. +        cmd->togglepulldowndetection = 1;
  3254. +        break;
  3255. +
  3256. +    case TVTIME_TOGGLE_SIGNAL_DETECTION:
  3257. +        cmd->checkfreq = !cmd->checkfreq;
  3258. +        if( !cmd->checkfreq && cmd->scan_channels ) {
  3259. +            commands_handle( cmd, TVTIME_CHANNEL_SCAN, 0 );
  3260. +        }
  3261. +        if( cmd->osd ) {
  3262. +            reset_stations_menu( commands_get_menu( cmd, "stations" ),
  3263. +                                 (videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC ||
  3264. +                                  videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_NTSC_JP),
  3265. +                                 videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_PAL,
  3266. +                                 videoinput_get_norm( cmd->vidin ) == VIDEOINPUT_SECAM,
  3267. +                                 (!strcasecmp( cmd->newfreqtable, "us-cable" ) ||
  3268. +                                  !strcasecmp( cmd->newfreqtable, "us-cable100" )),
  3269. +                                 station_get_current_active( cmd->stationmgr ), cmd->checkfreq,
  3270. +                                 cmd->scan_channels,
  3271. +                                 videoinput_is_v4l2( cmd->vidin ),
  3272. +                                 station_get_default_audio_norm( cmd->stationmgr ),
  3273. +                                 station_get_current_audio_norm( cmd->stationmgr ) );
  3274. +            if( cmd->checkfreq ) {
  3275. +                tvtime_osd_show_message( cmd->osd,
  3276. +                    _("Signal detection enabled.") );
  3277. +            } else {
  3278. +                tvtime_osd_show_message( cmd->osd,
  3279. +                    _("Signal detection disabled.") );
  3280. +            }
  3281. +            commands_refresh_menu( cmd );
  3282. +        }
  3283. +        break;
  3284. +
  3285. +    case TVTIME_TOGGLE_XDS:
  3286. +        if( cmd->vidin && videoinput_get_height( cmd->vidin ) == 480 && cmd->vbi ) {
  3287. +            cmd->usexds = !cmd->usexds;
  3288. +            vbidata_capture_xds( cmd->vbi, cmd->usexds );
  3289. +            if( cmd->osd ) {
  3290. +                if( cmd->usexds ) {
  3291. +                    tvtime_osd_show_message( cmd->osd,
  3292. +                        _("XDS decoding enabled.") );
  3293. +                } else {
  3294. +                    tvtime_osd_show_message( cmd->osd,
  3295. +                        _("XDS decoding disabled.") );
  3296. +                }
  3297. +            }
  3298. +        }
  3299. +        break;
  3300. +
  3301. +    case TVTIME_CHANNEL_CHAR:
  3302. +        if( arg && isdigit( arg[ 0 ] ) && cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3303. +
  3304. +            /* If we're scanning and the user hits a key, stop scanning. */
  3305. +            if( cmd->scan_channels ) {
  3306. +                commands_handle( cmd, TVTIME_CHANNEL_SCAN, 0 );
  3307. +            }
  3308. +
  3309. +            /* Decode the input char from commands.  */
  3310. +            if( cmd->digit_counter == 0 ) memset( cmd->next_chan_buffer, 0, 5 );
  3311. +            cmd->next_chan_buffer[ cmd->digit_counter ] = arg[ 0 ];
  3312. +            cmd->digit_counter++;
  3313. +            cmd->frame_counter = cmd->delay;
  3314. +
  3315. +            /**
  3316. +             * Send an enter command if we type more
  3317. +             * digits than there are channels.
  3318. +             */
  3319. +            if( cmd->digit_counter > 0 && (station_get_max_position( cmd->stationmgr ) < 10) ) {
  3320. +                commands_handle( cmd, TVTIME_ENTER, 0 );
  3321. +            } else if( cmd->digit_counter > 1 && (station_get_max_position( cmd->stationmgr ) < 100) ) {
  3322. +                commands_handle( cmd, TVTIME_ENTER, 0 );
  3323. +            } else if( cmd->digit_counter > 2 ) {
  3324. +                commands_handle( cmd, TVTIME_ENTER, 0 );
  3325. +            }
  3326. +        }
  3327. +        break;
  3328. +
  3329. +    case TVTIME_TOGGLE_COLOUR_INVERT:
  3330. +        cmd->apply_invert = !cmd->apply_invert;
  3331. +        if( cmd->osd ) {
  3332. +            reset_filters_menu( commands_get_menu( cmd, "filters" ),
  3333. +                                cmd->apply_invert, cmd->apply_mirror,
  3334. +                                cmd->apply_chroma_kill,
  3335. +                                cmd->vidin && videoinput_get_height( cmd->vidin ) == 480,
  3336. +                                cmd->pulldown_alg );
  3337. +            commands_refresh_menu( cmd );
  3338. +
  3339. +            if( cmd->apply_invert ) {
  3340. +                tvtime_osd_show_message( cmd->osd, _("Colour invert enabled.") );
  3341. +            } else {
  3342. +                tvtime_osd_show_message( cmd->osd, _("Colour invert disabled.") );
  3343. +            }
  3344. +        }
  3345. +        if( cmd->apply_invert ) {
  3346. +            config_save( cmd->cfg, "ColourInvert", "1" );
  3347. +        } else {
  3348. +            config_save( cmd->cfg, "ColourInvert", "0" );
  3349. +        }
  3350. +        break;
  3351. +
  3352. +    case TVTIME_TOGGLE_MIRROR:
  3353. +        cmd->apply_mirror = !cmd->apply_mirror;
  3354. +        if( cmd->osd ) {
  3355. +            reset_filters_menu( commands_get_menu( cmd, "filters" ),
  3356. +                                cmd->apply_invert, cmd->apply_mirror,
  3357. +                                cmd->apply_chroma_kill,
  3358. +                                cmd->vidin && videoinput_get_height( cmd->vidin ) == 480,
  3359. +                                cmd->pulldown_alg );
  3360. +            commands_refresh_menu( cmd );
  3361. +
  3362. +            if( cmd->apply_mirror ) {
  3363. +                tvtime_osd_show_message( cmd->osd, _("Mirror enabled.") );
  3364. +            } else {
  3365. +                tvtime_osd_show_message( cmd->osd, _("Mirror disabled.") );
  3366. +            }
  3367. +        }
  3368. +        if( cmd->apply_mirror ) {
  3369. +            config_save( cmd->cfg, "MirrorInput", "1" );
  3370. +        } else {
  3371. +            config_save( cmd->cfg, "MirrorInput", "0" );
  3372. +        }
  3373. +        break;
  3374. +
  3375. +    case TVTIME_TOGGLE_CHROMA_KILL:
  3376. +        cmd->apply_chroma_kill = !cmd->apply_chroma_kill;
  3377. +        if( cmd->osd ) {
  3378. +            reset_filters_menu( commands_get_menu( cmd, "filters" ),
  3379. +                                cmd->apply_invert, cmd->apply_mirror,
  3380. +                                cmd->apply_chroma_kill,
  3381. +                                cmd->vidin && videoinput_get_height( cmd->vidin ) == 480,
  3382. +                                cmd->pulldown_alg );
  3383. +            commands_refresh_menu( cmd );
  3384. +
  3385. +            if( cmd->apply_chroma_kill ) {
  3386. +                tvtime_osd_show_message( cmd->osd, _("Chroma kill enabled.") );
  3387. +            } else {
  3388. +                tvtime_osd_show_message( cmd->osd, _("Chroma kill disabled.") );
  3389. +            }
  3390. +        }
  3391. +        break;
  3392. +
  3393. +    case TVTIME_OVERSCAN_UP:
  3394. +    case TVTIME_OVERSCAN_DOWN:
  3395. +        cmd->overscan = cmd->overscan + ( (tvtime_cmd == TVTIME_OVERSCAN_UP) ? 0.0025 : -0.0025 );
  3396. +        if( cmd->overscan > 0.4 ) cmd->overscan = 0.4; if( cmd->overscan < 0.0 ) cmd->overscan = 0.0;
  3397. +
  3398. +        if( cmd->osd ) {
  3399. +            char message[ 200 ];
  3400. +            snprintf( message, sizeof( message ), _("Overscan: %.1f%%"),
  3401. +                      cmd->overscan * 2.0 * 100.0 );
  3402. +            tvtime_osd_show_message( cmd->osd, message );
  3403. +            reset_overscan_menu( commands_get_menu( cmd, "overscan" ), cmd->overscan );
  3404. +            commands_refresh_menu( cmd );
  3405. +        }
  3406. +        break;
  3407. +
  3408. +    case TVTIME_AUTO_ADJUST_PICT:
  3409. +        if( cmd->vidin ) {
  3410. +            if( cmd->brightness >= 0 ) {
  3411. +                videoinput_set_brightness( cmd->vidin, cmd->brightness );
  3412. +            } else {
  3413. +                videoinput_set_brightness( cmd->vidin, 50 );
  3414. +            }
  3415. +            if( cmd->contrast >= 0 ) {
  3416. +                videoinput_set_contrast( cmd->vidin, cmd->contrast );
  3417. +            } else {
  3418. +                videoinput_set_contrast( cmd->vidin, 50 );
  3419. +            }
  3420. +            if( cmd->saturation >= 0 ) {
  3421. +                videoinput_set_saturation( cmd->vidin, cmd->saturation );
  3422. +            } else {
  3423. +                videoinput_set_saturation( cmd->vidin, 50 );
  3424. +            }
  3425. +            if( cmd->hue >= 0 ) {
  3426. +                videoinput_set_hue( cmd->vidin, cmd->hue );
  3427. +            } else {
  3428. +                videoinput_set_hue( cmd->vidin, 50 );
  3429. +            }
  3430. +            if( cmd->osd ) {
  3431. +                tvtime_osd_show_message( cmd->osd,
  3432. +                    _("Picture settings reset to defaults.") );
  3433. +                menu_set_value( commands_get_menu( cmd, "brightness" ),
  3434. +                                videoinput_get_brightness( cmd->vidin ),
  3435. +                                TVTIME_ICON_BRIGHTNESS );
  3436. +                menu_set_value( commands_get_menu( cmd, "contrast" ),
  3437. +                                videoinput_get_brightness( cmd->vidin ),
  3438. +                                TVTIME_ICON_CONTRAST );
  3439. +                menu_set_value( commands_get_menu( cmd, "saturation" ),
  3440. +                                videoinput_get_brightness( cmd->vidin ),
  3441. +                                TVTIME_ICON_SATURATION );
  3442. +                menu_set_value( commands_get_menu( cmd, "hue" ),
  3443. +                                videoinput_get_brightness( cmd->vidin ),
  3444. +                                TVTIME_ICON_HUE );
  3445. +            }
  3446. +        }
  3447. +        break;
  3448. +
  3449. +    case TVTIME_AUTO_ADJUST_WINDOW:
  3450. +        cmd->resizewindow = 1;
  3451. +        break;
  3452. +
  3453. +    case TVTIME_TOGGLE_NTSC_CABLE_MODE:
  3454. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3455. +            station_toggle_us_cable_mode( cmd->stationmgr );
  3456. +            if( station_get_us_cable_mode( cmd->stationmgr ) == NTSC_CABLE_MODE_STANDARD ) {
  3457. +                config_save( cmd->cfg, "NTSCCableMode", "Nominal" );
  3458. +                if( cmd->osd ) {
  3459. +                    tvtime_osd_show_message( cmd->osd,
  3460. +                        _("Using nominal NTSC cable frequencies.") );
  3461. +                }
  3462. +            } else if( station_get_us_cable_mode( cmd->stationmgr ) == NTSC_CABLE_MODE_IRC ) {
  3463. +                config_save( cmd->cfg, "NTSCCableMode", "IRC" );
  3464. +                if( cmd->osd ) {
  3465. +                    tvtime_osd_show_message( cmd->osd,
  3466. +                        _("Using IRC cable frequencies.") );
  3467. +                }
  3468. +            } else if( station_get_us_cable_mode( cmd->stationmgr ) == NTSC_CABLE_MODE_HRC ) {
  3469. +                config_save( cmd->cfg, "NTSCCableMode", "HRC" );
  3470. +                if( cmd->osd ) {
  3471. +                    tvtime_osd_show_message( cmd->osd,
  3472. +                        _("Using HRC cable frequencies.") );
  3473. +                }
  3474. +            }
  3475. +            cmd->change_channel = 1;
  3476. +        }
  3477. +        break;
  3478. +
  3479. +    case TVTIME_FINETUNE_DOWN:
  3480. +    case TVTIME_FINETUNE_UP:
  3481. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3482. +            station_set_current_finetune( cmd->stationmgr, station_get_current_finetune( cmd->stationmgr )
  3483. +                                          + (tvtime_cmd == TVTIME_FINETUNE_UP ? 1 : -1) );
  3484. +            videoinput_set_tuner_freq( cmd->vidin, station_get_current_frequency( cmd->stationmgr )
  3485. +                                       + ((station_get_current_finetune( cmd->stationmgr ) * 1000)/16) );
  3486. +
  3487. +            if( cmd->vbi ) {
  3488. +                vbidata_reset( cmd->vbi );
  3489. +                vbidata_capture_mode( cmd->vbi, cmd->capturemode );
  3490. +            }
  3491. +
  3492. +            if( cmd->osd ) {
  3493. +                menu_set_value (commands_get_menu (cmd, "finetune"),
  3494. +                                station_get_current_finetune (cmd->stationmgr),
  3495. +                                TVTIME_ICON_FINETUNECHANNEL);
  3496. +                commands_refresh_menu( cmd );
  3497. +                tvtime_osd_show_data_bar_centered( cmd->osd, _("Finetune"),
  3498. +                                                   station_get_current_finetune( cmd->stationmgr ) );
  3499. +            }
  3500. +        } else if( cmd->osd ) {
  3501. +            tvtime_osd_show_info( cmd->osd );
  3502. +        }
  3503. +        break;
  3504. +
  3505. +    case TVTIME_CHANNEL_INC:
  3506. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3507. +
  3508. +            /**
  3509. +             * If we're scanning and the user hits a key, stop scanning.
  3510. +             * arg will be 0 if the scanner has called us.
  3511. +             */
  3512. +            if( cmd->scan_channels && arg ) {
  3513. +                commands_handle( cmd, TVTIME_CHANNEL_SCAN, 0 );
  3514. +            }
  3515. +
  3516. +            station_inc( cmd->stationmgr );
  3517. +            cmd->change_channel = 1;
  3518. +        } else if( cmd->osd ) {
  3519. +            tvtime_osd_show_info( cmd->osd );
  3520. +        }
  3521. +        break;
  3522. +    case TVTIME_CHANNEL_DEC:
  3523. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3524. +
  3525. +            /* If we're scanning and the user hits a key, stop scanning. */
  3526. +            if( cmd->scan_channels ) {
  3527. +                commands_handle( cmd, TVTIME_CHANNEL_SCAN, 0 );
  3528. +            }
  3529. +
  3530. +            station_dec( cmd->stationmgr );
  3531. +            cmd->change_channel = 1;
  3532. +        } else if( cmd->osd ) {
  3533. +            tvtime_osd_show_info( cmd->osd );
  3534. +        }
  3535. +        break;
  3536. +
  3537. +    case TVTIME_CHANNEL_PREV:
  3538. +        if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3539. +
  3540. +            /* If we're scanning and the user hits a key, stop scanning. */
  3541. +            if( cmd->scan_channels ) {
  3542. +                commands_handle( cmd, TVTIME_CHANNEL_SCAN, 0 );
  3543. +            }
  3544. +
  3545. +            station_prev( cmd->stationmgr );
  3546. +            cmd->change_channel = 1;
  3547. +        } else if( cmd->osd ) {
  3548. +            tvtime_osd_show_info( cmd->osd );
  3549. +        }
  3550. +        break;
  3551. +
  3552. +    case TVTIME_MIXER_TOGGLE_MUTE:
  3553. +        mixer->mute( !mixer->ismute() );
  3554. +
  3555. +        if( cmd->osd ) {
  3556. +            tvtime_osd_show_data_bar( cmd->osd, _("Volume"), (mixer->get_volume()) & 0xff );
  3557. +        }
  3558. +        break;
  3559. +
  3560. +    case TVTIME_MIXER_UP:
  3561. +    case TVTIME_MIXER_DOWN:
  3562. +
  3563. +        /* If the user hits the volume control, drop us out of mute mode. */
  3564. +        if( cmd->vidin && videoinput_get_muted( cmd->vidin ) ) {
  3565. +            commands_handle( cmd, TVTIME_TOGGLE_MUTE, 0 );
  3566. +        }
  3567. +        /* Check to see if an argument was passed, if so, use it. */
  3568. +        if (atoi(arg) > 0) {
  3569. +            int perc = atoi(arg);
  3570. +            volume = mixer->set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? perc : -perc ) );
  3571. +        } else {
  3572. +            volume = mixer->set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? 1 : -1 ) );
  3573. +        }
  3574. +
  3575. +        if( cmd->osd ) {
  3576. +            tvtime_osd_show_data_bar( cmd->osd, _("Volume"), volume & 0xff );
  3577. +        }
  3578. +        break;
  3579. +
  3580. +    case TVTIME_TOGGLE_MUTE:
  3581. +        if( cmd->vidin ) {
  3582. +            videoinput_mute( cmd->vidin, !videoinput_get_muted( cmd->vidin ) );
  3583. +            if( cmd->osd ) {
  3584. +                tvtime_osd_volume_muted( cmd->osd, videoinput_get_muted( cmd->vidin ) );
  3585. +            }
  3586. +        }
  3587. +        break;
  3588. +
  3589. +    case TVTIME_TOGGLE_INPUT:
  3590. +        if( cmd->vidin ) {
  3591. +            cmd->frame_counter = 0;
  3592. +
  3593. +            if( cmd->renumbering ) {
  3594. +                memset( cmd->next_chan_buffer, 0, sizeof( cmd->next_chan_buffer ) );
  3595. +                commands_handle( cmd, TVTIME_ENTER, 0 );
  3596. +            }
  3597. +
  3598. +            if( cmd->scan_channels ) {
  3599. +                commands_handle( cmd, TVTIME_CHANNEL_SCAN, 0 );
  3600. +            }
  3601. +
  3602. +            videoinput_set_input_num( cmd->vidin, ( videoinput_get_input_num( cmd->vidin ) + 1 ) % videoinput_get_num_inputs( cmd->vidin ) );
  3603. +            reinit_tuner( cmd );
  3604. +
  3605. +            if( cmd->osd ) {
  3606. +                char string[ 128 ];
  3607. +                snprintf( string, sizeof( string ),
  3608. +                          TVTIME_ICON_VIDEOINPUT "  %s: %s",
  3609. +                          _("Change video source"),
  3610. +                          videoinput_get_input_name( cmd->vidin ) );
  3611. +                menu_set_text( commands_get_menu( cmd, "input" ), 1, string );
  3612. +                commands_refresh_menu( cmd );
  3613. +                tvtime_osd_set_input( cmd->osd, videoinput_get_input_name( cmd->vidin ) );
  3614. +                tvtime_osd_show_info( cmd->osd );
  3615. +            }
  3616. +        }
  3617. +        break;
  3618. +
  3619. +    case TVTIME_SET_INPUT:
  3620. +        if( cmd->vidin ) {
  3621. +            cmd->frame_counter = 0;
  3622. +
  3623. +            if( cmd->renumbering ) {
  3624. +                memset( cmd->next_chan_buffer, 0, sizeof( cmd->next_chan_buffer ) );
  3625. +                commands_handle( cmd, TVTIME_ENTER, 0 );
  3626. +            }
  3627. +
  3628. +            if( cmd->scan_channels ) {
  3629. +                commands_handle( cmd, TVTIME_CHANNEL_SCAN, 0 );
  3630. +            }
  3631. +
  3632. +            videoinput_set_input_num( cmd->vidin, atoi( arg ) % videoinput_get_num_inputs( cmd->vidin ) );
  3633. +            reinit_tuner( cmd );
  3634. +
  3635. +            if( cmd->osd ) {
  3636. +                char string[ 128 ];
  3637. +                snprintf( string, sizeof( string ),
  3638. +                          TVTIME_ICON_VIDEOINPUT "  %s: %s",
  3639. +                          _("Change video source"),
  3640. +                          videoinput_get_input_name( cmd->vidin ) );
  3641. +                menu_set_text( commands_get_menu( cmd, "input" ), 1, string );
  3642. +                commands_refresh_menu( cmd );
  3643. +                tvtime_osd_set_input( cmd->osd, videoinput_get_input_name( cmd->vidin ) );
  3644. +                tvtime_osd_show_info( cmd->osd );
  3645. +            }
  3646. +        }
  3647. +        break;
  3648. +
  3649. +    case TVTIME_HUE_UP:
  3650. +    case TVTIME_HUE_DOWN:
  3651. +        if( cmd->vidin ) {
  3652. +            videoinput_set_hue_relative( cmd->vidin, (tvtime_cmd == TVTIME_HUE_UP) ? 1 : -1 );
  3653. +            if( cmd->osd ) {
  3654. +                int hue = videoinput_get_hue( cmd->vidin );
  3655. +                tvtime_osd_show_data_bar( cmd->osd, _("Hue"), hue );
  3656. +                menu_set_value (commands_get_menu (cmd, "hue"), hue,
  3657. +                                TVTIME_ICON_HUE);
  3658. +                commands_refresh_menu( cmd );
  3659. +            }
  3660. +        }
  3661. +        break;
  3662. +
  3663. +    case TVTIME_BRIGHTNESS_UP:
  3664. +    case TVTIME_BRIGHTNESS_DOWN:
  3665. +        if( cmd->vidin ) {
  3666. +            videoinput_set_brightness_relative( cmd->vidin, (tvtime_cmd == TVTIME_BRIGHTNESS_UP) ? 1 : -1 );
  3667. +            if( cmd->osd ) {
  3668. +                int brightness = videoinput_get_brightness( cmd->vidin );
  3669. +                tvtime_osd_show_data_bar( cmd->osd, _("Brightness"), brightness );
  3670. +                menu_set_value (commands_get_menu (cmd, "brightness"),
  3671. +                                brightness, TVTIME_ICON_BRIGHTNESS);
  3672. +                commands_refresh_menu( cmd );
  3673. +            }
  3674. +        }
  3675. +        break;
  3676. +
  3677. +    case TVTIME_CONTRAST_UP:
  3678. +    case TVTIME_CONTRAST_DOWN:
  3679. +        if( cmd->vidin ) {
  3680. +            videoinput_set_contrast_relative( cmd->vidin, (tvtime_cmd == TVTIME_CONTRAST_UP) ? 1 : -1 );
  3681. +            if( cmd->osd ) {
  3682. +                int contrast = videoinput_get_contrast( cmd->vidin );
  3683. +                tvtime_osd_show_data_bar( cmd->osd, _("Contrast"), contrast );
  3684. +                menu_set_value (commands_get_menu (cmd, "contrast"),
  3685. +                                contrast, TVTIME_ICON_CONTRAST);
  3686. +                commands_refresh_menu( cmd );
  3687. +            }
  3688. +        }
  3689. +        break;
  3690. +
  3691. +    case TVTIME_SATURATION_UP:
  3692. +    case TVTIME_SATURATION_DOWN:
  3693. +        if( cmd->vidin ) {
  3694. +            videoinput_set_saturation_relative( cmd->vidin, (tvtime_cmd == TVTIME_SATURATION_UP) ? 1 : -1 );
  3695. +            if( cmd->osd ) {
  3696. +                int saturation = videoinput_get_saturation( cmd->vidin );
  3697. +                tvtime_osd_show_data_bar( cmd->osd, _("Saturation"), saturation );
  3698. +                menu_set_value (commands_get_menu (cmd, "saturation"),
  3699. +                                saturation, TVTIME_ICON_SATURATION);
  3700. +                commands_refresh_menu( cmd );
  3701. +            }
  3702. +        }
  3703. +        break;
  3704. +
  3705. +    case TVTIME_PICTURE:
  3706. +        cmd->picturemode = (cmd->picturemode + 1) % 4;
  3707. +        if( cmd->osd && cmd->vidin ) {
  3708. +            if( cmd->picturemode == 0 ) {
  3709. +                int cur = videoinput_get_brightness( cmd->vidin );
  3710. +                tvtime_osd_show_data_bar( cmd->osd, _("Brightness"), cur );
  3711. +            } else if( cmd->picturemode == 1 ) {
  3712. +                int cur = videoinput_get_contrast( cmd->vidin );
  3713. +                tvtime_osd_show_data_bar( cmd->osd, _("Contrast"), cur );
  3714. +            } else if( cmd->picturemode == 2 ) {
  3715. +                int cur = videoinput_get_saturation( cmd->vidin );
  3716. +                tvtime_osd_show_data_bar( cmd->osd, _("Saturation"), cur );
  3717. +            } else if( cmd->picturemode == 3 ) {
  3718. +                int cur = videoinput_get_hue( cmd->vidin );
  3719. +                tvtime_osd_show_data_bar( cmd->osd, _("Hue"), cur );
  3720. +            }
  3721. +        }
  3722. +        break;
  3723. +
  3724. +    case TVTIME_PICTURE_UP:
  3725. +        if( cmd->picturemode == 0 ) {
  3726. +            commands_handle( cmd, TVTIME_BRIGHTNESS_UP, "" );
  3727. +        } else if( cmd->picturemode == 1 ) {
  3728. +            commands_handle( cmd, TVTIME_CONTRAST_UP, "" );
  3729. +        } else if( cmd->picturemode == 2 ) {
  3730. +            commands_handle( cmd, TVTIME_SATURATION_UP, "" );
  3731. +        } else if( cmd->picturemode == 3 ) {
  3732. +            commands_handle( cmd, TVTIME_HUE_UP, "" );
  3733. +        }
  3734. +        break;
  3735. +
  3736. +    case TVTIME_PICTURE_DOWN:
  3737. +        if( cmd->picturemode == 0 ) {
  3738. +            commands_handle( cmd, TVTIME_BRIGHTNESS_DOWN, "" );
  3739. +        } else if( cmd->picturemode == 1 ) {
  3740. +            commands_handle( cmd, TVTIME_CONTRAST_DOWN, "" );
  3741. +        } else if( cmd->picturemode == 2 ) {
  3742. +            commands_handle( cmd, TVTIME_SATURATION_DOWN, "" );
  3743. +        } else if( cmd->picturemode == 3 ) {
  3744. +            commands_handle( cmd, TVTIME_HUE_DOWN, "" );
  3745. +        }
  3746. +        break;
  3747. +
  3748. +    case TVTIME_SAVE_PICTURE_GLOBAL:
  3749. +        if( cmd->vidin && config_get_save_restore_picture( cmd->cfg ) ) {
  3750. +            cmd->brightness = videoinput_get_brightness( cmd->vidin );
  3751. +            cmd->contrast = videoinput_get_contrast( cmd->vidin );
  3752. +            cmd->saturation = videoinput_get_saturation( cmd->vidin );
  3753. +            cmd->hue = videoinput_get_hue( cmd->vidin );
  3754. +            if( cmd->osd ) {
  3755. +                tvtime_osd_show_message( cmd->osd,
  3756. +                    _("Saved current picture settings as global defaults.\n") );
  3757. +            }
  3758. +        }
  3759. +        break;
  3760. +    case TVTIME_SAVE_PICTURE_CHANNEL:
  3761. +        if( cmd->stationmgr && cmd->vidin && config_get_save_restore_picture( cmd->cfg ) ) {
  3762. +            station_set_current_brightness( cmd->stationmgr, videoinput_get_brightness( cmd->vidin ) );
  3763. +            station_set_current_contrast( cmd->stationmgr, videoinput_get_contrast( cmd->vidin ) );
  3764. +            station_set_current_saturation( cmd->stationmgr, videoinput_get_saturation( cmd->vidin ) );
  3765. +            station_set_current_hue( cmd->stationmgr, videoinput_get_hue( cmd->vidin ) );
  3766. +            if( cmd->osd ) {
  3767. +                char message[ 128 ];
  3768. +                snprintf( message, sizeof (message),
  3769. +                          _("Saved current picture settings on channel %d.\n"),
  3770. +                         station_get_current_id( cmd->stationmgr ) );
  3771. +                tvtime_osd_show_message( cmd->osd, message );
  3772. +            }
  3773. +        }
  3774. +        break;
  3775. +
  3776. +    case TVTIME_ENTER:
  3777. +        if( cmd->next_chan_buffer[ 0 ] ) {
  3778. +            if( cmd->renumbering ) {
  3779. +                station_remap( cmd->stationmgr, atoi( cmd->next_chan_buffer ) );
  3780. +                station_writeconfig( cmd->stationmgr );
  3781. +                cmd->renumbering = 0;
  3782. +                if( cmd->osd ) tvtime_osd_set_hold_message( cmd->osd, "", 0 );
  3783. +            }
  3784. +            if( station_set( cmd->stationmgr, atoi( cmd->next_chan_buffer ) ) ) {
  3785. +                cmd->change_channel = 1;
  3786. +            } else {
  3787. +                snprintf( cmd->next_chan_buffer, sizeof( cmd->next_chan_buffer ),
  3788. +                          "%d", station_get_current_id( cmd->stationmgr ) );
  3789. +                if( cmd->osd ) {
  3790. +                    tvtime_osd_set_channel_number( cmd->osd, cmd->next_chan_buffer );
  3791. +                    tvtime_osd_show_info( cmd->osd );
  3792. +                }
  3793. +            }
  3794. +        } else {
  3795. +            if( cmd->renumbering ) {
  3796. +                cmd->renumbering = 0;
  3797. +                if( cmd->osd ) tvtime_osd_set_hold_message( cmd->osd, "", 0 );
  3798. +            }
  3799. +            snprintf( cmd->next_chan_buffer, sizeof( cmd->next_chan_buffer ),
  3800. +                      "%d", station_get_current_id( cmd->stationmgr ) );
  3801. +            if( cmd->osd ) {
  3802. +                if( cmd->vidin && videoinput_has_tuner( cmd->vidin ) ) {
  3803. +                    tvtime_osd_set_channel_number( cmd->osd,
  3804. +                                                   cmd->next_chan_buffer );
  3805. +                }
  3806. +                commands_handle( cmd, TVTIME_DISPLAY_INFO, "" );
  3807. +            }
  3808. +        }
  3809. +        cmd->frame_counter = 0;
  3810. +        break;
  3811. +
  3812. +    case TVTIME_CHANNEL_1:
  3813. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "1" );
  3814. +        break;
  3815. +
  3816. +    case TVTIME_CHANNEL_2:
  3817. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "2" );
  3818. +        break;
  3819. +
  3820. +    case TVTIME_CHANNEL_3:
  3821. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "3" );
  3822. +        break;
  3823. +
  3824. +    case TVTIME_CHANNEL_4:
  3825. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "4" );
  3826. +        break;
  3827. +
  3828. +    case TVTIME_CHANNEL_5:
  3829. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "5" );
  3830. +        break;
  3831. +
  3832. +    case TVTIME_CHANNEL_6:
  3833. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "6" );
  3834. +        break;
  3835. +
  3836. +    case TVTIME_CHANNEL_7:
  3837. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "7" );
  3838. +        break;
  3839. +
  3840. +    case TVTIME_CHANNEL_8:
  3841. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "8" );
  3842. +        break;
  3843. +
  3844. +    case TVTIME_CHANNEL_9:
  3845. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "9" );
  3846. +        break;
  3847. +
  3848. +    case TVTIME_CHANNEL_0:
  3849. +        commands_handle( cmd, TVTIME_CHANNEL_CHAR, "0" );
  3850. +        break;
  3851. +
  3852. +    case TVTIME_TOGGLE_PAUSE:
  3853. +        cmd->pause = !(cmd->pause);
  3854. +        if( cmd->osd ) {
  3855. +            tvtime_osd_show_message( cmd->osd,
  3856. +                  cmd->pause ? _("Paused.") : _("Resumed.") );
  3857. +        }
  3858. +        break;
  3859. +
  3860. +    case TVTIME_TOGGLE_MATTE:
  3861. +        cmd->togglematte = 1;
  3862. +        break;
  3863. +
  3864. +    case TVTIME_TOGGLE_QUIET_SCREENSHOTS:
  3865. +        cmd->togglequiet = 1;
  3866. +        break;
  3867. +
  3868. +    case TVTIME_TOGGLE_XMLTV_LANGUAGE:
  3869. +        if( cmd->xmltv ) {
  3870. +            const char *lang;
  3871. +            int i = xmltv_get_langnum( cmd->xmltv ) + 1;
  3872. +            if( i > xmltv_get_num_languages( cmd->xmltv ) ) i = 0;
  3873. +            xmltv_select_language( cmd->xmltv, i );
  3874. +            update_xmltv_listings( cmd );
  3875. +            if( cmd->osd ) {
  3876. +                menu_t *langmenu = commands_get_menu( cmd, "xmltv-language" );
  3877. +                reset_xmltv_languages_menu( langmenu, cmd->xmltv );
  3878. +                if( !cmd->menuactive ) {
  3879. +                    osd_list_xmltv_languages( cmd->osd, cmd );
  3880. +                } else {
  3881. +                    commands_refresh_menu( cmd );
  3882. +                }
  3883. +            }
  3884. +            if( cmd->osd && !cmd->menuactive ) {
  3885. +                osd_list_xmltv_languages( cmd->osd, cmd );
  3886. +            }
  3887. +            lang = xmltv_get_language( cmd->xmltv );
  3888. +            config_save( cmd->cfg, "XMLTVLanguage", lang? lang : "none" );
  3889. +        }
  3890. +        break;
  3891. +    }
  3892. +}
  3893. +
  3894. +void commands_next_frame( commands_t *cmd )
  3895. +{
  3896. +    cmd->tunerreset = 0;
  3897. +
  3898. +    /* Decrement the frame counter if user is typing digits */
  3899. +    if( cmd->frame_counter > 0 ) {
  3900. +        cmd->frame_counter--;
  3901. +        if( cmd->frame_counter == 0 ) {
  3902. +            /* Switch to the next channel if the countdown expires. */
  3903. +            commands_handle( cmd, TVTIME_ENTER, 0 );
  3904. +        }
  3905. +    }
  3906. +
  3907. +    if( cmd->frame_counter == 0 ) {
  3908. +        memset( cmd->next_chan_buffer, 0, 5 );
  3909. +        cmd->digit_counter = 0;
  3910. +        if( cmd->renumbering ) {
  3911. +            if( cmd->osd ) tvtime_osd_set_hold_message( cmd->osd, "", 0 );
  3912. +            cmd->renumbering = 0;
  3913. +        }
  3914. +    }
  3915. +
  3916. +    if( cmd->frame_counter > 0 && !(cmd->frame_counter % 5)) {
  3917. +        char input_text[6];
  3918. +
  3919. +        strcpy( input_text, cmd->next_chan_buffer );
  3920. +        if( !(cmd->frame_counter % 10) ) {
  3921. +            strcat( input_text, "_" );
  3922. +        } else {
  3923. +            strcat( input_text, " " );
  3924. +        }
  3925. +        if( cmd->osd ) {
  3926. +            tvtime_osd_set_channel_number( cmd->osd, input_text );
  3927. +            tvtime_osd_show_info( cmd->osd );
  3928. +        }
  3929. +    }
  3930. +
  3931. +    if( cmd->change_channel ) {
  3932. +        char number[ 6 ];
  3933. +        reinit_tuner( cmd );
  3934. +        cmd->change_channel = 0;
  3935. +        snprintf( number, 4, "%d",
  3936. +                  station_get_current_id( cmd->stationmgr ) );
  3937. +        config_save( cmd->cfg, "Channel", number );
  3938. +    }
  3939. +
  3940. +    cmd->xmltvupdated = 0;
  3941. +    update_xmltv_listings( cmd );
  3942. +    if( cmd->vbi ) {
  3943. +        if( *(vbidata_get_network_name( cmd->vbi )) ) {
  3944. +            /* If the network name has changed, save it to the config file. */
  3945. +            if( strcmp( station_get_current_network_name( cmd->stationmgr ),
  3946. +                        vbidata_get_network_name( cmd->vbi ) ) ) {
  3947. +                station_set_current_network_name( cmd->stationmgr,
  3948. +                                                  vbidata_get_network_name( cmd->vbi ) );
  3949. +                station_writeconfig( cmd->stationmgr );
  3950. +            }
  3951. +
  3952. +            if( cmd->osd ) {
  3953. +                tvtime_osd_set_network_name( cmd->osd, station_get_current_network_name( cmd->stationmgr ) );
  3954. +            }
  3955. +        }
  3956. +
  3957. +        if( *(vbidata_get_network_call_letters( cmd->vbi )) ) {
  3958. +            /* If the call letters have changed, save them to the config file. */
  3959. +            if( strcmp( station_get_current_network_call_letters( cmd->stationmgr ),
  3960. +                        vbidata_get_network_call_letters( cmd->vbi ) ) ) {
  3961. +                station_set_current_network_call_letters( cmd->stationmgr,
  3962. +                                                          vbidata_get_network_call_letters( cmd->vbi ) );
  3963. +                station_writeconfig( cmd->stationmgr );
  3964. +            }
  3965. +
  3966. +            if( cmd->osd ) {
  3967. +                tvtime_osd_set_network_call( cmd->osd, station_get_current_network_call_letters( cmd->stationmgr ) );
  3968. +            }
  3969. +        }
  3970. +
  3971. +        if( cmd->osd ) {
  3972. +            tvtime_osd_set_show_name( cmd->osd, vbidata_get_program_name( cmd->vbi ) );
  3973. +            tvtime_osd_set_show_rating( cmd->osd, vbidata_get_program_rating( cmd->vbi ) );
  3974. +            tvtime_osd_set_show_start( cmd->osd, vbidata_get_program_start_time( cmd->vbi ) );
  3975. +            tvtime_osd_set_show_length( cmd->osd, vbidata_get_program_length( cmd->vbi ) );
  3976. +        }
  3977. +    }
  3978. +
  3979. +    cmd->printdebug = 0;
  3980. +    cmd->showdeinterlacerinfo = 0;
  3981. +    cmd->screenshot = 0;
  3982. +    cmd->togglefullscreen = 0;
  3983. +    cmd->toggleaspect = 0;
  3984. +    cmd->togglealwaysontop = 0;
  3985. +    cmd->toggledeinterlacer = 0;
  3986. +    cmd->togglepulldowndetection = 0;
  3987. +    cmd->togglematte = 0;
  3988. +    cmd->togglequiet = 0;
  3989. +    cmd->resizewindow = 0;
  3990. +    cmd->setdeinterlacer = 0;
  3991. +    cmd->setfreqtable = 0;
  3992. +    memset( cmd->newmatte, 0, sizeof( cmd->newmatte ) );
  3993. +    memset( cmd->newpos, 0, sizeof( cmd->newpos ) );
  3994. +}
  3995. +
  3996. +int commands_quit( commands_t *cmd )
  3997. +{
  3998. +    return cmd->quit;
  3999. +}
  4000. +
  4001. +int commands_print_debug( commands_t *cmd )
  4002. +{
  4003. +    return cmd->printdebug;
  4004. +}
  4005. +
  4006. +int commands_show_bars( commands_t *cmd )
  4007. +{
  4008. +    return cmd->showbars;
  4009. +}
  4010. +
  4011. +int commands_take_screenshot( commands_t *cmd )
  4012. +{
  4013. +    return cmd->screenshot;
  4014. +}
  4015. +
  4016. +const char *commands_screenshot_filename( commands_t *cmd )
  4017. +{
  4018. +    return cmd->screenshotfile;
  4019. +}
  4020. +
  4021. +int commands_toggle_fullscreen( commands_t *cmd )
  4022. +{
  4023. +    return cmd->togglefullscreen;
  4024. +}
  4025. +
  4026. +int commands_get_framerate( commands_t *cmd )
  4027. +{
  4028. +    return cmd->framerate;
  4029. +}
  4030. +
  4031. +int commands_toggle_aspect( commands_t *cmd )
  4032. +{
  4033. +    return cmd->toggleaspect;
  4034. +}
  4035. +
  4036. +int commands_toggle_alwaysontop( commands_t *cmd )
  4037. +{
  4038. +    return cmd->togglealwaysontop;
  4039. +}
  4040. +
  4041. +int commands_toggle_deinterlacer( commands_t *cmd )
  4042. +{
  4043. +    return cmd->toggledeinterlacer;
  4044. +}
  4045. +
  4046. +int commands_toggle_pulldown_detection( commands_t *cmd )
  4047. +{
  4048. +    return cmd->togglepulldowndetection;
  4049. +}
  4050. +
  4051. +int commands_toggle_matte( commands_t *cmd )
  4052. +{
  4053. +    return cmd->togglematte;
  4054. +}
  4055. +
  4056. +int commands_toggle_quiet_screenshots( commands_t *cmd )
  4057. +{
  4058. +    return cmd->togglequiet;
  4059. +}
  4060. +
  4061. +void commands_set_vbidata( commands_t *cmd, vbidata_t *vbi )
  4062. +{
  4063. +    cmd->vbi = vbi;
  4064. +}
  4065. +
  4066. +int commands_scan_channels( commands_t *cmd )
  4067. +{
  4068. +    return cmd->scan_channels;
  4069. +}
  4070. +
  4071. +int commands_pause( commands_t *cmd )
  4072. +{
  4073. +    return cmd->pause;
  4074. +}
  4075. +
  4076. +int commands_apply_colour_invert( commands_t *cmd )
  4077. +{
  4078. +    return cmd->apply_invert;
  4079. +}
  4080. +
  4081. +int commands_apply_mirror( commands_t *cmd )
  4082. +{
  4083. +    return cmd->apply_mirror;
  4084. +}
  4085. +
  4086. +int commands_apply_chroma_kill( commands_t *cmd )
  4087. +{
  4088. +    return cmd->apply_chroma_kill;
  4089. +}
  4090. +
  4091. +double commands_get_overscan( commands_t *cmd )
  4092. +{
  4093. +    return cmd->overscan;
  4094. +}
  4095. +
  4096. +int commands_resize_window( commands_t *cmd )
  4097. +{
  4098. +    return cmd->resizewindow;
  4099. +}
  4100. +
  4101. +void commands_set_framerate( commands_t *cmd, int framerate )
  4102. +{
  4103. +    cmd->framerate = framerate % FRAMERATE_MAX;
  4104. +}
  4105. +
  4106. +int commands_show_deinterlacer_info( commands_t *cmd )
  4107. +{
  4108. +    return cmd->showdeinterlacerinfo;
  4109. +}
  4110. +
  4111. +int commands_restart_tvtime( commands_t *cmd )
  4112. +{
  4113. +    return cmd->restarttvtime;
  4114. +}
  4115. +
  4116. +const char *commands_get_new_norm( commands_t *cmd )
  4117. +{
  4118. +    if( cmd->normset ) {
  4119. +        return cmd->newnorm;
  4120. +    } else {
  4121. +        return 0;
  4122. +    }
  4123. +}
  4124. +
  4125. +int commands_set_deinterlacer( commands_t *cmd )
  4126. +{
  4127. +    return cmd->setdeinterlacer;
  4128. +}
  4129. +
  4130. +const char *commands_get_new_deinterlacer( commands_t *cmd )
  4131. +{
  4132. +    return cmd->deinterlacer;
  4133. +}
  4134. +
  4135. +int commands_menu_active( commands_t *cmd )
  4136. +{
  4137. +    return cmd->menuactive;
  4138. +}
  4139. +
  4140. +void commands_set_half_size( commands_t *cmd, int halfsize )
  4141. +{
  4142. +    cmd->halfsize = halfsize;
  4143. +}
  4144. +
  4145. +int commands_get_new_input_width( commands_t *cmd )
  4146. +{
  4147. +    return cmd->newinputwidth;
  4148. +}
  4149. +
  4150. +int commands_get_global_brightness( commands_t *cmd )
  4151. +{
  4152. +    return cmd->brightness;
  4153. +}
  4154. +
  4155. +int commands_get_global_contrast( commands_t *cmd )
  4156. +{
  4157. +    return cmd->contrast;
  4158. +}
  4159. +
  4160. +int commands_get_global_saturation( commands_t *cmd )
  4161. +{
  4162. +    return cmd->saturation;
  4163. +}
  4164. +
  4165. +int commands_get_global_hue( commands_t *cmd )
  4166. +{
  4167. +    return cmd->hue;
  4168. +}
  4169. +
  4170. +int commands_set_freq_table( commands_t *cmd )
  4171. +{
  4172. +    return cmd->setfreqtable;
  4173. +}
  4174. +
  4175. +const char *commands_get_new_freq_table( commands_t *cmd )
  4176. +{
  4177. +    return cmd->newfreqtable;
  4178. +}
  4179. +
  4180. +int commands_check_freq_present( commands_t *cmd )
  4181. +{
  4182. +    return cmd->checkfreq;
  4183. +}
  4184. +
  4185. +int commands_sleeptimer( commands_t *cmd )
  4186. +{
  4187. +    return cmd->sleeptimer;
  4188. +}
  4189. +
  4190. +int commands_sleeptimer_do_shutdown( commands_t *cmd )
  4191. +{
  4192. +    time_t now;
  4193. +
  4194. +    time( &now );
  4195. +
  4196. +    return (now >= ((sleeptimer_function( cmd->sleeptimer ) * 60) + cmd->sleeptimer_start));
  4197. +}
  4198. +
  4199. +void commands_set_pulldown_alg( commands_t *cmd, int pulldown_alg )
  4200. +{
  4201. +    cmd->pulldown_alg = pulldown_alg;
  4202. +    reset_filters_menu( commands_get_menu( cmd, "filters" ),
  4203. +                        cmd->apply_invert, cmd->apply_mirror,
  4204. +                        cmd->apply_chroma_kill,
  4205. +                        cmd->vidin && videoinput_get_height( cmd->vidin ) == 480,
  4206. +                        cmd->pulldown_alg );
  4207. +    commands_refresh_menu( cmd );
  4208. +}
  4209. +
  4210. +const char *commands_get_matte_mode( commands_t *cmd )
  4211. +{
  4212. +    if( *cmd->newmatte ) {
  4213. +        return cmd->newmatte;
  4214. +    } else {
  4215. +        return 0;
  4216. +    }
  4217. +}
  4218. +
  4219. +const char *commands_get_fs_pos( commands_t *cmd )
  4220. +{
  4221. +    if( *cmd->newpos ) {
  4222. +        return cmd->newpos;
  4223. +    } else {
  4224. +        return 0;
  4225. +    }
  4226. +}
  4227. +
  4228. +int commands_get_audio_boost( commands_t *cmd )
  4229. +{
  4230. +    return cmd->boost;
  4231. +}
  4232. +
  4233. +int commands_xmltv_updated( commands_t *cmd )
  4234. +{
  4235. +    return cmd->xmltvupdated;
  4236. +}
  4237. +
  4238. +int commands_tuner_reset( commands_t *cmd )
  4239. +{
  4240. +    return cmd->tunerreset;
  4241. +}
  4242. +
  4243. +const char *commands_get_xmltv_title( commands_t *cmd )
  4244. +{
  4245. +    if( cmd->xmltv ) {
  4246. +        return xmltv_get_title( cmd->xmltv );
  4247. +    } else {
  4248. +        return 0;
  4249. +    }
  4250. +}
  4251. +
  4252. +void commands_get_menu_bounding_box( commands_t *cmd, int *x, int *y,
  4253. +                                     int *width, int *height )
  4254. +{
  4255. +    if( cmd->osd ) {
  4256. +        tvtime_osd_list_get_bounding_box( cmd->osd, x, y, width, height );
  4257. +        if( cmd->halfsize ) {
  4258. +            *y /= 2;
  4259. +            *height /= 2;
  4260. +        }
  4261. +    } else {
  4262. +        *x = *y = *width = *height = 0;
  4263. +    }
  4264. +}
  4265. +
  4266. diff -Nurp tvtime-1.0.2/src/commands.h tvtime-1.0.2-custom/src/commands.h
  4267. --- tvtime-1.0.2/src/commands.h 2004-10-28 02:50:24.000000000 +0200
  4268. +++ tvtime-1.0.2-custom/src/commands.h  2011-05-29 13:07:28.169040774 +0200
  4269. @@ -64,6 +64,7 @@ void commands_set_pulldown_alg( commands
  4270.  int commands_quit( commands_t *cmd );
  4271.  int commands_toggle_fullscreen( commands_t *cmd );
  4272.  int commands_toggle_aspect( commands_t *cmd );
  4273. +int commands_get_changed_overscan( commands_t *cmd );
  4274.  int commands_toggle_deinterlacer( commands_t *cmd );
  4275.  int commands_toggle_pulldown_detection( commands_t *cmd );
  4276.  int commands_toggle_matte( commands_t *cmd );
  4277. diff -Nurp tvtime-1.0.2/src/cpu_accel.c tvtime-1.0.2-custom/src/cpu_accel.c
  4278. --- tvtime-1.0.2/src/cpu_accel.c        2004-04-04 18:48:37.000000000 +0200
  4279. +++ tvtime-1.0.2-custom/src/cpu_accel.c 2011-05-29 13:07:28.149040530 +0200
  4280. @@ -35,7 +35,7 @@ static inline uint32_t arch_accel (void)
  4281.      int AMD;
  4282.      uint32_t caps;
  4283.  
  4284. -#ifndef PIC
  4285. +#if !defined(__PIC__) || defined(__x86_64__)
  4286.  #define cpuid(op,eax,ebx,ecx,edx)      \
  4287.      __asm__ ("cpuid"                   \
  4288.              : "=a" (eax),              \
  4289. diff -Nurp tvtime-1.0.2/src/Makefile.am tvtime-1.0.2-custom/src/Makefile.am
  4290. --- tvtime-1.0.2/src/Makefile.am        2005-02-08 06:00:16.000000000 +0100
  4291. +++ tvtime-1.0.2-custom/src/Makefile.am 2011-05-29 13:42:33.649601355 +0200
  4292. @@ -29,6 +29,11 @@ OPT_CFLAGS = -Wall -pedantic -I. -DDATAD
  4293.         -DCONFDIR="\"$(pkgsysconfdir)\"" -DFIFODIR="\"$(tmpdir)\"" \
  4294.         -D_LARGEFILE64_SOURCE -DLOCALEDIR="\"$(localedir)\""
  4295.  
  4296. +if HAVE_ALSA
  4297. +ALSA_SRCS =    mixer-alsa.c
  4298. +else
  4299. +ALSA_SRCS =
  4300. +endif
  4301.  COMMON_SRCS = mixer.c videoinput.c rtctimer.c leetft.c osdtools.c tvtimeconf.c \
  4302.         pngoutput.c tvtimeosd.c input.c cpu_accel.c speedy.c pnginput.c \
  4303.         deinterlace.c videotools.c attributes.h deinterlace.h leetft.h \
  4304. @@ -40,7 +45,7 @@ COMMON_SRCS = mixer.c videoinput.c rtcti
  4305.         utils.h utils.c pulldown.h pulldown.c hashtable.h hashtable.c \
  4306.         cpuinfo.h cpuinfo.c videodev.h videodev2.h menu.c menu.h \
  4307.         outputfilter.h outputfilter.c xmltv.h xmltv.c gettext.h tvtimeglyphs.h \
  4308. -       copyfunctions.h copyfunctions.c
  4309. +       copyfunctions.h copyfunctions.c mixer-oss.c $(ALSA_SRCS)
  4310.  
  4311.  if ARCH_X86
  4312.  DSCALER_SRCS = $(top_srcdir)/plugins/dscalerapi.h \
  4313. @@ -74,10 +79,10 @@ bin_PROGRAMS = tvtime tvtime-command tvt
  4314.  
  4315.  tvtime_SOURCES = $(COMMON_SRCS) $(OUTPUT_SRCS) $(PLUGIN_SRCS) tvtime.c
  4316.  tvtime_CFLAGS = $(TTF_CFLAGS) $(PNG_CFLAGS) $(OPT_CFLAGS) \
  4317. -       $(PLUGIN_CFLAGS) $(X11_CFLAGS) $(XML2_FLAG) \
  4318. +       $(PLUGIN_CFLAGS) $(X11_CFLAGS) $(XML2_FLAG) $(ALSA_CFLAGS) \
  4319.         $(FONT_CFLAGS) $(AM_CFLAGS)
  4320.  tvtime_LDFLAGS  = $(TTF_LIBS) $(ZLIB_LIBS) $(PNG_LIBS) \
  4321. -       $(X11_LIBS) $(XML2_LIBS) -lm -lstdc++
  4322. +       $(X11_LIBS) $(XML2_LIBS) $(ALSA_LIBS) -lm -lsupc++
  4323.  
  4324.  tvtime_command_SOURCES = utils.h utils.c tvtimeconf.h tvtimeconf.c \
  4325.         tvtime-command.c
  4326. @@ -90,6 +95,6 @@ tvtime_configure_LDFLAGS  = $(ZLIB_LIBS)
  4327.  tvtime_scanner_SOURCES = utils.h utils.c videoinput.h videoinput.c \
  4328.         tvtimeconf.h tvtimeconf.c station.h station.c tvtime-scanner.c \
  4329.         mixer.h mixer.c
  4330. -tvtime_scanner_CFLAGS = $(OPT_CFLAGS) $(XML2_FLAG) $(AM_CFLAGS)
  4331. -tvtime_scanner_LDFLAGS  = $(ZLIB_LIBS) $(XML2_LIBS)
  4332. +tvtime_scanner_CFLAGS = $(OPT_CFLAGS) $(XML2_FLAG) $(ALSA_CFLAGS) $(AM_CFLAGS)
  4333. +tvtime_scanner_LDFLAGS  = $(ZLIB_LIBS) $(XML2_LIBS) $(ALSA_LIBS)
  4334.  
  4335. diff -Nurp tvtime-1.0.2/src/mixer-alsa.c tvtime-1.0.2-custom/src/mixer-alsa.c
  4336. --- tvtime-1.0.2/src/mixer-alsa.c       1970-01-01 01:00:00.000000000 +0100
  4337. +++ tvtime-1.0.2-custom/src/mixer-alsa.c        2011-05-29 13:07:28.122373538 +0200
  4338. @@ -0,0 +1,240 @@
  4339. +/**
  4340. + * Copyright (C) 2006 Philipp Hahn <pmhahn@users.sourceforge.net>
  4341. + *
  4342. + * This program is free software; you can redistribute it and/or modify
  4343. + * it under the terms of the GNU General Public License as published by
  4344. + * the Free Software Foundation; either version 2, or (at your option)
  4345. + * any later version.
  4346. + *
  4347. + * This program is distributed in the hope that it will be useful,
  4348. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4349. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4350. + * GNU General Public License for more details.
  4351. + *
  4352. + * You should have received a copy of the GNU General Public License
  4353. + * along with this program; if not, write to the Free Software Foundation,
  4354. + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  4355. + */
  4356. +
  4357. +#include <stdio.h>
  4358. +#include <sys/types.h>
  4359. +#include <string.h>
  4360. +#include <math.h>
  4361. +#include <alsa/asoundlib.h>
  4362. +#include "utils.h"
  4363. +#include "mixer.h"
  4364. +
  4365. +static const char alsa_core_devnames[] = "default";
  4366. +static char *card, *channel;
  4367. +static int muted = 0;
  4368. +static int mutecount = 0;
  4369. +static snd_mixer_t *handle = NULL;
  4370. +static snd_mixer_elem_t *elem = NULL;
  4371. +
  4372. +static long alsa_min, alsa_max, alsa_vol;
  4373. +
  4374. +static void alsa_open_mixer( void )
  4375. +{
  4376. +    int err;
  4377. +    static snd_mixer_selem_id_t *sid = NULL;
  4378. +    if ((err = snd_mixer_open (&handle, 0)) < 0) {
  4379. +        fprintf(stderr, "mixer: open error: %s\n", snd_strerror(err));
  4380. +        return;
  4381. +    }
  4382. +    if ((err = snd_mixer_attach (handle, card)) < 0) {
  4383. +        fprintf(stderr, "mixer: attach error: %s\n", snd_strerror(err));
  4384. +        goto error;
  4385. +    }
  4386. +    if ((err = snd_mixer_selem_register (handle, NULL, NULL)) < 0) {
  4387. +        fprintf(stderr, "mixer: register error: %s\n", snd_strerror(err));
  4388. +        goto error;
  4389. +    }
  4390. +    if ((err = snd_mixer_load (handle)) < 0) {
  4391. +        fprintf(stderr, "mixer: load error: %s\n", snd_strerror(err));
  4392. +        goto error;
  4393. +    }
  4394. +    snd_mixer_selem_id_malloc(&sid);
  4395. +    if (sid == NULL)
  4396. +        goto error;
  4397. +    snd_mixer_selem_id_set_name(sid, channel);
  4398. +    if (!(elem = snd_mixer_find_selem(handle, sid))) {
  4399. +        fprintf(stderr, "mixer: find error: %s\n", snd_strerror(err));
  4400. +        goto error;
  4401. +    }
  4402. +    if (!snd_mixer_selem_has_playback_volume(elem)) {
  4403. +        fprintf(stderr, "mixer: no playback\n");
  4404. +        goto error;
  4405. +    }
  4406. +    snd_mixer_selem_get_playback_volume_range(elem, &alsa_min, &alsa_max);
  4407. +    if ((alsa_max - alsa_min) <= 0) {
  4408. +        fprintf(stderr, "mixer: no valid playback range\n");
  4409. +        goto error;
  4410. +    }
  4411. +    snd_mixer_selem_id_free(sid);
  4412. +    return;
  4413. +
  4414. +error:
  4415. +    if (sid)
  4416. +        snd_mixer_selem_id_free(sid);
  4417. +    if (handle) {
  4418. +        snd_mixer_close(handle);
  4419. +        handle = NULL;
  4420. +    }
  4421. +    return;
  4422. +}
  4423. +
  4424. +/* Volume saved to file */
  4425. +static int alsa_get_unmute_volume( void )
  4426. +{
  4427. +    long val;
  4428. +    assert (elem);
  4429. +
  4430. +    if (snd_mixer_selem_is_playback_mono(elem)) {
  4431. +        snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &val);
  4432. +        return val;
  4433. +    } else {
  4434. +        int c, n = 0;
  4435. +        long sum = 0;
  4436. +        for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
  4437. +            if (snd_mixer_selem_has_playback_channel(elem, c)) {
  4438. +                snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &val);
  4439. +                sum += val;
  4440. +                n++;
  4441. +            }
  4442. +        }
  4443. +        if (! n) {
  4444. +            return 0;
  4445. +        }
  4446. +
  4447. +        val = sum / n;
  4448. +        sum = (long)((double)(alsa_vol * (alsa_max - alsa_min)) / 100. + 0.5);
  4449. +
  4450. +        if (sum != val) {
  4451. +           alsa_vol = (long)(((val * 100.) / (alsa_max - alsa_min)) + 0.5);
  4452. +        }
  4453. +        return alsa_vol;
  4454. +    }
  4455. +}
  4456. +
  4457. +static int alsa_get_volume( void )
  4458. +{
  4459. +    if (muted)
  4460. +        return 0;
  4461. +    else
  4462. +        return alsa_get_unmute_volume();
  4463. +}
  4464. +
  4465. +static int alsa_set_volume( int percentdiff )
  4466. +{
  4467. +    long volume;
  4468. +
  4469. +    alsa_get_volume();
  4470. +
  4471. +    alsa_vol += percentdiff;
  4472. +    if( alsa_vol > 100 ) alsa_vol = 100;
  4473. +    if( alsa_vol < 0 ) alsa_vol = 0;
  4474. +
  4475. +    volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + 0.5);
  4476. +
  4477. +    snd_mixer_selem_set_playback_volume_all(elem, volume + alsa_min);
  4478. +    snd_mixer_selem_set_playback_switch_all(elem, 1);
  4479. +    muted = 0;
  4480. +    mutecount = 0;
  4481. +
  4482. +    return alsa_vol;
  4483. +}
  4484. +
  4485. +static void alsa_mute( int mute )
  4486. +{
  4487. +    /**
  4488. +     * Make sure that if multiple users mute the card,
  4489. +     * we only honour the last one.
  4490. +     */
  4491. +    if( !mute && mutecount ) mutecount--;
  4492. +    if( mutecount ) return;
  4493. +
  4494. +    if( mute ) {
  4495. +        mutecount++;
  4496. +        muted = 1;
  4497. +        if (snd_mixer_selem_has_playback_switch(elem))
  4498. +            snd_mixer_selem_set_playback_switch_all(elem, 0);
  4499. +        else
  4500. +            fprintf(stderr, "mixer: mute not implemented\n");
  4501. +    } else {
  4502. +        muted = 0;
  4503. +        if (snd_mixer_selem_has_playback_switch(elem))
  4504. +            snd_mixer_selem_set_playback_switch_all(elem, 1);
  4505. +        else
  4506. +            fprintf(stderr, "mixer: mute not implemented\n");
  4507. +    }
  4508. +}
  4509. +
  4510. +static int alsa_ismute( void )
  4511. +{
  4512. +    return muted;
  4513. +}
  4514. +
  4515. +static int alsa_set_device( const char *devname )
  4516. +{
  4517. +    int i;
  4518. +
  4519. +    if (card) free(card);
  4520. +    card = strdup( devname );
  4521. +    if( !card ) return -1;
  4522. +
  4523. +    i = strcspn( card, "/" );
  4524. +    if( i == strlen( card ) ) {
  4525. +        channel = "Line";
  4526. +    } else {
  4527. +        card[i] = 0;
  4528. +        channel = card + i + 1;
  4529. +    }
  4530. +    alsa_open_mixer();
  4531. +    if (!handle) {
  4532. +        fprintf( stderr, "mixer: Can't open mixer %s, "
  4533. +                 "mixer volume and mute unavailable.\n", card );
  4534. +        return -1;
  4535. +    }
  4536. +    return 0;
  4537. +}
  4538. +
  4539. +static void alsa_set_state( int ismuted, int unmute_volume )
  4540. +{
  4541. +    /**
  4542. +     * 1. we come back unmuted: Don't touch anything
  4543. +     * 2. we don't have a saved volume: Don't touch anything
  4544. +     * 3. we come back muted and we have a saved volume:
  4545. +     *    - if tvtime muted it, unmute to old volume
  4546. +     *    - if user did it, remember that we're muted and old volume
  4547. +     */
  4548. +    if( alsa_get_volume() == 0 && unmute_volume > 0 ) {
  4549. +        snd_mixer_selem_set_playback_volume_all(elem, unmute_volume);
  4550. +        muted = 1;
  4551. +
  4552. +        if( !ismuted ) {
  4553. +            alsa_mute( 0 );
  4554. +        }
  4555. +    }
  4556. +}
  4557. +
  4558. +static void alsa_close_device( void )
  4559. +{
  4560. +    elem = NULL;
  4561. +    if (handle)
  4562. +        snd_mixer_close(handle);
  4563. +    handle = NULL;
  4564. +    muted = 0;
  4565. +    mutecount = 0;
  4566. +}
  4567. +
  4568. +struct mixer alsa_mixer = {
  4569. +    .set_device = alsa_set_device,
  4570. +    .set_state = alsa_set_state,
  4571. +    .get_volume = alsa_get_volume,
  4572. +    .get_unmute_volume = alsa_get_unmute_volume,
  4573. +    .set_volume = alsa_set_volume,
  4574. +    .mute = alsa_mute,
  4575. +    .ismute = alsa_ismute,
  4576. +    .close_device = alsa_close_device,
  4577. +};
  4578. +// vim: ts=4 sw=4 et foldmethod=marker
  4579. diff -Nurp tvtime-1.0.2/src/mixer.c tvtime-1.0.2-custom/src/mixer.c
  4580. --- tvtime-1.0.2/src/mixer.c    2004-10-29 04:15:23.000000000 +0200
  4581. +++ tvtime-1.0.2-custom/src/mixer.c     2011-05-29 13:07:28.125706912 +0200
  4582. @@ -19,230 +19,104 @@
  4583.   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  4584.   */
  4585.  
  4586. -#include <stdio.h>
  4587. -#include <fcntl.h>
  4588. -#include <unistd.h>
  4589. -#include <sys/types.h>
  4590. -#include <sys/stat.h>
  4591. -#include <sys/ioctl.h>
  4592. -#include <sys/soundcard.h>
  4593. -#include <sys/mman.h>
  4594. -#include <string.h>
  4595. -#include "utils.h"
  4596.  #include "mixer.h"
  4597.  
  4598. -static char *mixer_device = "/dev/mixer";
  4599. -static int saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
  4600. -static int mixer_channel = SOUND_MIXER_LINE;
  4601. -static int mixer_dev_mask = 1 << SOUND_MIXER_LINE;
  4602. -static int muted = 0;
  4603. -static int mutecount = 0;
  4604. -static int fd = -1;
  4605. -
  4606. -int mixer_get_volume( void )
  4607. -{
  4608. -    int v, cmd, devs;
  4609. -    int curvol = 0;
  4610. -
  4611. -    if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
  4612. -    if( fd != -1 ) {
  4613. -
  4614. -        ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  4615. -        if( devs & mixer_dev_mask ) {
  4616. -            cmd = MIXER_READ( mixer_channel );
  4617. -        } else {
  4618. -            return curvol;
  4619. -        }
  4620. -
  4621. -        ioctl( fd, cmd, &v );
  4622. -        curvol = ( v & 0xFF00 ) >> 8;
  4623. -    }
  4624. -
  4625. -    return curvol;
  4626. +/**
  4627. + * Sets the mixer device and channel.
  4628. + */
  4629. +static int null_set_device( const char *devname )
  4630. +{
  4631. +    return 0;
  4632.  }
  4633.  
  4634. -int mixer_get_unmute_volume( void )
  4635. +/**
  4636. + * Sets the initial state of the mixer device.
  4637. + */
  4638. +static void null_set_state( int ismuted, int unmute_volume )
  4639.  {
  4640. -    if( muted ) {
  4641. -        return saved_volume;
  4642. -    } else {
  4643. -        int v, cmd, devs;
  4644. -
  4645. -        if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
  4646. -        if( fd != -1 ) {
  4647. -
  4648. -            ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  4649. -            if( devs & mixer_dev_mask ) {
  4650. -                cmd = MIXER_READ( mixer_channel );
  4651. -            } else {
  4652. -                return -1;
  4653. -            }
  4654. -
  4655. -            ioctl( fd, cmd, &v );
  4656. -            return v;
  4657. -        }
  4658. -    }
  4659. -
  4660. -    return -1;
  4661.  }
  4662.  
  4663. -int mixer_set_volume( int percentdiff )
  4664. +/**
  4665. + * Returns the current volume setting.
  4666. + */
  4667. +static int null_get_volume( void )
  4668.  {
  4669. -    int v, cmd, devs, levelpercentage;
  4670. -
  4671. -    levelpercentage = mixer_get_volume();
  4672. -
  4673. -    levelpercentage += percentdiff;
  4674. -    if( levelpercentage > 100 ) levelpercentage = 100;
  4675. -    if( levelpercentage < 0 ) levelpercentage = 0;
  4676. -
  4677. -    if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
  4678. -    if( fd != -1 ) {
  4679. -        ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  4680. -        if( devs & mixer_dev_mask ) {
  4681. -            cmd = MIXER_WRITE( mixer_channel );
  4682. -        } else {
  4683. -            return 0;
  4684. -        }
  4685. -
  4686. -        v = ( levelpercentage << 8 ) | levelpercentage;
  4687. -        ioctl( fd, cmd, &v );
  4688. -        muted = 0;
  4689. -        mutecount = 0;
  4690. -        return v;
  4691. -    }
  4692. -
  4693.      return 0;
  4694.  }
  4695.  
  4696. -void mixer_mute( int mute )
  4697. +/**
  4698. + * Returns the volume that would be used to restore the unmute state.
  4699. + */
  4700. +static int null_get_unmute_volume( void )
  4701.  {
  4702. -    int v, cmd, devs;
  4703. -
  4704. -    /**
  4705. -     * Make sure that if multiple users mute the card,
  4706. -     * we only honour the last one.
  4707. -     */
  4708. -    if( !mute && mutecount ) mutecount--;
  4709. -    if( mutecount ) return;
  4710. -
  4711. -    if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
  4712. -
  4713. -    if( mute ) {
  4714. -        mutecount++;
  4715. -        if( fd != -1 ) {
  4716. -
  4717. -            /* Save volume */
  4718. -            ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  4719. -            if( devs & mixer_dev_mask ) {
  4720. -                cmd = MIXER_READ( mixer_channel );
  4721. -            } else {
  4722. -                return;
  4723. -            }
  4724. -
  4725. -            ioctl( fd,cmd,&v );
  4726. -            saved_volume = v;
  4727. -
  4728. -            /* Now set volume to 0 */
  4729. -            ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  4730. -            if( devs & mixer_dev_mask ) {
  4731. -                cmd = MIXER_WRITE( mixer_channel );
  4732. -            } else {
  4733. -                return;
  4734. -            }
  4735. -
  4736. -            v = 0;
  4737. -            ioctl( fd, cmd, &v );
  4738. -
  4739. -            muted = 1;
  4740. -            return;
  4741. -        }
  4742. -    } else {
  4743. -        if( fd != -1 ) {
  4744. -            ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  4745. -            if( devs & mixer_dev_mask ) {
  4746. -                cmd = MIXER_WRITE( mixer_channel );
  4747. -            } else {
  4748. -                return;
  4749. -            }
  4750. -
  4751. -            v = saved_volume;
  4752. -            ioctl( fd, cmd, &v );
  4753. -            muted = 0;
  4754. -            return;
  4755. -        }
  4756. -    }
  4757. +    return 0;
  4758.  }
  4759.  
  4760. -int mixer_ismute( void )
  4761. +/**
  4762. + * Tunes the relative volume.
  4763. + */
  4764. +static int null_set_volume( int percentdiff )
  4765.  {
  4766. -    return muted;
  4767. +    return 0;
  4768.  }
  4769.  
  4770. -static char *oss_core_devnames[] = SOUND_DEVICE_NAMES;
  4771. -
  4772. -void mixer_set_device( const char *devname )
  4773. +/**
  4774. + * Sets the mute state.
  4775. + */
  4776. +static void null_mute( int mute )
  4777.  {
  4778. -    const char *channame;
  4779. -    int found = 0;
  4780. -    int i;
  4781. -
  4782. -    mixer_device = strdup( devname );
  4783. -    if( !mixer_device ) return;
  4784. -
  4785. -    i = strcspn( mixer_device, ":" );
  4786. -    if( i == strlen( mixer_device ) ) {
  4787. -        channame = "line";
  4788. -    } else {
  4789. -        mixer_device[ i ] = 0;
  4790. -        channame = mixer_device + i + 1;
  4791. -    }
  4792. -    if( !file_is_openable_for_read( mixer_device ) ) {
  4793. -        fprintf( stderr, "mixer: Can't open device %s, "
  4794. -                 "mixer volume and mute unavailable.\n", mixer_device );
  4795. -    }
  4796. -
  4797. -    mixer_channel = SOUND_MIXER_LINE;
  4798. -    for( i = 0; i < SOUND_MIXER_NRDEVICES; i++ ) {
  4799. -        if( !strcasecmp( channame, oss_core_devnames[ i ] ) ) {
  4800. -            mixer_channel = i;
  4801. -            found = 1;
  4802. -            break;
  4803. -        }
  4804. -    }
  4805. -    if( !found ) {
  4806. -        fprintf( stderr, "mixer: No such mixer channel '%s', using channel 'line'.\n", channame );
  4807. -    }
  4808. -    mixer_dev_mask = 1 << mixer_channel;
  4809.  }
  4810.  
  4811. -void mixer_set_state( int ismuted, int unmute_volume )
  4812. +/**
  4813. + * Returns true if the mixer is muted.
  4814. + */
  4815. +static int null_ismute( void )
  4816.  {
  4817. -    /**
  4818. -     * 1. we come back unmuted: Don't touch anything
  4819. -     * 2. we don't have a saved volume: Don't touch anything
  4820. -     * 3. we come back muted and we have a saved volume:
  4821. -     *    - if tvtime muted it, unmute to old volume
  4822. -     *    - if user did it, remember that we're muted and old volume
  4823. -     */
  4824. -    if( mixer_get_volume() == 0 && unmute_volume > 0 ) {
  4825. -        saved_volume = unmute_volume;
  4826. -        muted = 1;
  4827. -
  4828. -        if( !ismuted ) {
  4829. -            mixer_mute( 0 );
  4830. -        }
  4831. -    }
  4832. +    return 0;
  4833.  }
  4834.  
  4835. -void mixer_close_device( void )
  4836. +/**
  4837. + * Closes the mixer device if it is open.
  4838. + */
  4839. +static void null_close_device( void )
  4840.  {
  4841. -    if( fd >= 0 ) close( fd );
  4842. -    saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
  4843. -    mixer_channel = SOUND_MIXER_LINE;
  4844. -    mixer_dev_mask = 1 << SOUND_MIXER_LINE;
  4845. -    muted = 0;
  4846. -    mutecount = 0;
  4847. -    fd = -1;
  4848.  }
  4849.  
  4850. +/* The null device, which always works. */
  4851. +static struct mixer null_mixer = {
  4852. +    .set_device = null_set_device,
  4853. +    .set_state = null_set_state,
  4854. +    .get_volume = null_get_volume,
  4855. +    .get_unmute_volume = null_get_unmute_volume,
  4856. +    .set_volume = null_set_volume,
  4857. +    .mute = null_mute,
  4858. +    .ismute = null_ismute,
  4859. +    .close_device = null_close_device,
  4860. +};
  4861. +
  4862. +/* List of all available access methods.
  4863. + * Uses weak symbols: NULL is not linked in. */
  4864. +static struct mixer *mixers[] = {
  4865. +    &alsa_mixer,
  4866. +    &oss_mixer,
  4867. +    &null_mixer /* LAST */
  4868. +};
  4869. +/* The actual access method. */
  4870. +struct mixer *mixer = &null_mixer;
  4871. +
  4872. +/**
  4873. + * Sets the mixer device and channel.
  4874. + * Try each access method until one succeeds.
  4875. + */
  4876. +void mixer_set_device( const char *devname )
  4877. +{
  4878. +    int i;
  4879. +    mixer->close_device();
  4880. +    for (i = 0; i < sizeof(mixers)/sizeof(mixers[0]); i++) {
  4881. +        mixer = mixers[i];
  4882. +        if (!mixer)
  4883. +            continue;
  4884. +        if (mixer->set_device(devname) == 0)
  4885. +            break;
  4886. +    }
  4887. +}
  4888. diff -Nurp tvtime-1.0.2/src/mixer.h tvtime-1.0.2-custom/src/mixer.h
  4889. --- tvtime-1.0.2/src/mixer.h    2004-08-27 03:18:49.000000000 +0200
  4890. +++ tvtime-1.0.2-custom/src/mixer.h     2011-05-29 13:07:28.129040286 +0200
  4891. @@ -27,45 +27,58 @@ extern "C" {
  4892.  #endif
  4893.  
  4894.  /**
  4895. - * Sets the mixer device and channel.  The device name is of the form
  4896. - * devicename:channelname.  The default is /dev/mixer:line.
  4897. + * Sets the mixer device and channel.
  4898. + * All interfaces are scanned until one succeeds.
  4899.   */
  4900.  void mixer_set_device( const char *devname );
  4901.  
  4902. +struct mixer {
  4903. +/**
  4904. + * Sets the mixer device and channel.
  4905. + */
  4906. +int (* set_device)( const char *devname );
  4907. +
  4908.  /**
  4909.   * Sets the initial state of the mixer device.
  4910.   */
  4911. -void mixer_set_state( int ismuted, int unmute_volume );
  4912. +void (* set_state)( int ismuted, int unmute_volume );
  4913.  
  4914.  /**
  4915.   * Returns the current volume setting.
  4916.   */
  4917. -int mixer_get_volume( void );
  4918. +int (* get_volume)( void );
  4919.  
  4920.  /**
  4921.   * Returns the volume that would be used to restore the unmute state.
  4922.   */
  4923. -int mixer_get_unmute_volume( void );
  4924. +int (* get_unmute_volume)( void );
  4925.  
  4926.  /**
  4927.   * Tunes the relative volume.
  4928.   */
  4929. -int mixer_set_volume( int percentdiff );
  4930. +int (* set_volume)( int percentdiff );
  4931.  
  4932.  /**
  4933.   * Sets the mute state.
  4934.   */
  4935. -void mixer_mute( int mute );
  4936. +void (* mute)( int mute );
  4937.  
  4938.  /**
  4939.   * Returns true if the mixer is muted.
  4940.   */
  4941. -int mixer_ismute( void );
  4942. +int (* ismute)( void );
  4943.  
  4944.  /**
  4945.   * Closes the mixer device if it is open.
  4946.   */
  4947. -void mixer_close_device( void );
  4948. +void (* close_device)( void );
  4949. +};
  4950. +
  4951. +#pragma weak alsa_mixer
  4952. +extern struct mixer alsa_mixer;
  4953. +#pragma weak oss_mixer
  4954. +extern struct mixer oss_mixer;
  4955. +extern struct mixer *mixer;
  4956.  
  4957.  #ifdef __cplusplus
  4958.  };
  4959. diff -Nurp tvtime-1.0.2/src/mixer-oss.c tvtime-1.0.2-custom/src/mixer-oss.c
  4960. --- tvtime-1.0.2/src/mixer-oss.c        1970-01-01 01:00:00.000000000 +0100
  4961. +++ tvtime-1.0.2-custom/src/mixer-oss.c 2011-05-29 13:07:28.129040286 +0200
  4962. @@ -0,0 +1,261 @@
  4963. +/**
  4964. + * Copyright (C) 2002, 2003 Doug Bell <drbell@users.sourceforge.net>
  4965. + *
  4966. + * Some mixer routines from mplayer, http://mplayer.sourceforge.net.
  4967. + * Copyright (C) 2000-2002. by A'rpi/ESP-team & others
  4968. + *
  4969. + * This program is free software; you can redistribute it and/or modify
  4970. + * it under the terms of the GNU General Public License as published by
  4971. + * the Free Software Foundation; either version 2, or (at your option)
  4972. + * any later version.
  4973. + *
  4974. + * This program is distributed in the hope that it will be useful,
  4975. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4976. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4977. + * GNU General Public License for more details.
  4978. + *
  4979. + * You should have received a copy of the GNU General Public License
  4980. + * along with this program; if not, write to the Free Software Foundation,
  4981. + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  4982. + */
  4983. +
  4984. +#include <stdio.h>
  4985. +#include <fcntl.h>
  4986. +#include <unistd.h>
  4987. +#include <sys/types.h>
  4988. +#include <sys/stat.h>
  4989. +#include <sys/ioctl.h>
  4990. +#include <sys/soundcard.h>
  4991. +#include <sys/mman.h>
  4992. +#include <string.h>
  4993. +#include "utils.h"
  4994. +#include "mixer.h"
  4995. +
  4996. +static char *mixer_device = "/dev/mixer";
  4997. +static int saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
  4998. +static int mixer_channel = SOUND_MIXER_LINE;
  4999. +static int mixer_dev_mask = 1 << SOUND_MIXER_LINE;
  5000. +static int muted = 0;
  5001. +static int mutecount = 0;
  5002. +static int fd = -1;
  5003. +
  5004. +static int oss_get_volume( void )
  5005. +{
  5006. +    int v, cmd, devs;
  5007. +    int curvol = 0;
  5008. +
  5009. +    if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
  5010. +    if( fd != -1 ) {
  5011. +
  5012. +        ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  5013. +        if( devs & mixer_dev_mask ) {
  5014. +            cmd = MIXER_READ( mixer_channel );
  5015. +        } else {
  5016. +            return curvol;
  5017. +        }
  5018. +
  5019. +        ioctl( fd, cmd, &v );
  5020. +        curvol = ( v & 0xFF00 ) >> 8;
  5021. +    }
  5022. +
  5023. +    return curvol;
  5024. +}
  5025. +
  5026. +static int oss_get_unmute_volume( void )
  5027. +{
  5028. +    if( muted ) {
  5029. +        return saved_volume;
  5030. +    } else {
  5031. +        int v, cmd, devs;
  5032. +
  5033. +        if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
  5034. +        if( fd != -1 ) {
  5035. +
  5036. +            ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  5037. +            if( devs & mixer_dev_mask ) {
  5038. +                cmd = MIXER_READ( mixer_channel );
  5039. +            } else {
  5040. +                return -1;
  5041. +            }
  5042. +
  5043. +            ioctl( fd, cmd, &v );
  5044. +            return v;
  5045. +        }
  5046. +    }
  5047. +
  5048. +    return -1;
  5049. +}
  5050. +
  5051. +static int oss_set_volume( int percentdiff )
  5052. +{
  5053. +    int v, cmd, devs, levelpercentage;
  5054. +
  5055. +    levelpercentage = oss_get_volume();
  5056. +
  5057. +    levelpercentage += percentdiff;
  5058. +    if( levelpercentage > 100 ) levelpercentage = 100;
  5059. +    if( levelpercentage < 0 ) levelpercentage = 0;
  5060. +
  5061. +    if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
  5062. +    if( fd != -1 ) {
  5063. +        ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  5064. +        if( devs & mixer_dev_mask ) {
  5065. +            cmd = MIXER_WRITE( mixer_channel );
  5066. +        } else {
  5067. +            return 0;
  5068. +        }
  5069. +
  5070. +        v = ( levelpercentage << 8 ) | levelpercentage;
  5071. +        ioctl( fd, cmd, &v );
  5072. +        muted = 0;
  5073. +        mutecount = 0;
  5074. +        return v;
  5075. +    }
  5076. +
  5077. +    return 0;
  5078. +}
  5079. +
  5080. +static void oss_mute( int mute )
  5081. +{
  5082. +    int v, cmd, devs;
  5083. +
  5084. +    /**
  5085. +     * Make sure that if multiple users mute the card,
  5086. +     * we only honour the last one.
  5087. +     */
  5088. +    if( !mute && mutecount ) mutecount--;
  5089. +    if( mutecount ) return;
  5090. +
  5091. +    if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
  5092. +
  5093. +    if( mute ) {
  5094. +        mutecount++;
  5095. +        if( fd != -1 ) {
  5096. +
  5097. +            /* Save volume */
  5098. +            ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  5099. +            if( devs & mixer_dev_mask ) {
  5100. +                cmd = MIXER_READ( mixer_channel );
  5101. +            } else {
  5102. +                return;
  5103. +            }
  5104. +
  5105. +            ioctl( fd,cmd,&v );
  5106. +            saved_volume = v;
  5107. +
  5108. +            /* Now set volume to 0 */
  5109. +            ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  5110. +            if( devs & mixer_dev_mask ) {
  5111. +                cmd = MIXER_WRITE( mixer_channel );
  5112. +            } else {
  5113. +                return;
  5114. +            }
  5115. +
  5116. +            v = 0;
  5117. +            ioctl( fd, cmd, &v );
  5118. +
  5119. +            muted = 1;
  5120. +            return;
  5121. +        }
  5122. +    } else {
  5123. +        if( fd != -1 ) {
  5124. +            ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
  5125. +            if( devs & mixer_dev_mask ) {
  5126. +                cmd = MIXER_WRITE( mixer_channel );
  5127. +            } else {
  5128. +                return;
  5129. +            }
  5130. +
  5131. +            v = saved_volume;
  5132. +            ioctl( fd, cmd, &v );
  5133. +            muted = 0;
  5134. +            return;
  5135. +        }
  5136. +    }
  5137. +}
  5138. +
  5139. +static int oss_ismute( void )
  5140. +{
  5141. +    return muted;
  5142. +}
  5143. +
  5144. +static char *oss_core_devnames[] = SOUND_DEVICE_NAMES;
  5145. +
  5146. +static int oss_set_device( const char *devname )
  5147. +{
  5148. +    const char *channame;
  5149. +    int found = 0;
  5150. +    int i;
  5151. +
  5152. +    mixer_device = strdup( devname );
  5153. +    if( !mixer_device ) return -1;
  5154. +
  5155. +    i = strcspn( mixer_device, ":" );
  5156. +    if( i == strlen( mixer_device ) ) {
  5157. +        channame = "line";
  5158. +    } else {
  5159. +        mixer_device[ i ] = 0;
  5160. +        channame = mixer_device + i + 1;
  5161. +    }
  5162. +    if( !file_is_openable_for_read( mixer_device ) ) {
  5163. +        fprintf( stderr, "mixer: Can't open device %s, "
  5164. +                 "mixer volume and mute unavailable.\n", mixer_device );
  5165. +        return -1;
  5166. +    }
  5167. +
  5168. +    mixer_channel = SOUND_MIXER_LINE;
  5169. +    for( i = 0; i < SOUND_MIXER_NRDEVICES; i++ ) {
  5170. +        if( !strcasecmp( channame, oss_core_devnames[ i ] ) ) {
  5171. +            mixer_channel = i;
  5172. +            found = 1;
  5173. +            break;
  5174. +        }
  5175. +    }
  5176. +    if( !found ) {
  5177. +        fprintf( stderr, "mixer: No such mixer channel '%s', using channel 'line'.\n", channame );
  5178. +        return -1;
  5179. +    }
  5180. +    mixer_dev_mask = 1 << mixer_channel;
  5181. +    return 0;
  5182. +}
  5183. +
  5184. +static void oss_set_state( int ismuted, int unmute_volume )
  5185. +{
  5186. +    /**
  5187. +     * 1. we come back unmuted: Don't touch anything
  5188. +     * 2. we don't have a saved volume: Don't touch anything
  5189. +     * 3. we come back muted and we have a saved volume:
  5190. +     *    - if tvtime muted it, unmute to old volume
  5191. +     *    - if user did it, remember that we're muted and old volume
  5192. +     */
  5193. +    if( oss_get_volume() == 0 && unmute_volume > 0 ) {
  5194. +        saved_volume = unmute_volume;
  5195. +        muted = 1;
  5196. +
  5197. +        if( !ismuted ) {
  5198. +            oss_mute( 0 );
  5199. +        }
  5200. +    }
  5201. +}
  5202. +
  5203. +static void oss_close_device( void )
  5204. +{
  5205. +    if( fd >= 0 ) close( fd );
  5206. +    saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
  5207. +    mixer_channel = SOUND_MIXER_LINE;
  5208. +    mixer_dev_mask = 1 << SOUND_MIXER_LINE;
  5209. +    muted = 0;
  5210. +    mutecount = 0;
  5211. +    fd = -1;
  5212. +}
  5213. +
  5214. +struct mixer oss_mixer = {
  5215. +    .set_device = oss_set_device,
  5216. +    .set_state = oss_set_state,
  5217. +    .get_volume = oss_get_volume,
  5218. +    .get_unmute_volume = oss_get_unmute_volume,
  5219. +    .set_volume = oss_set_volume,
  5220. +    .mute = oss_mute,
  5221. +    .ismute = oss_ismute,
  5222. +    .close_device = oss_close_device,
  5223. +};
  5224. diff -Nurp tvtime-1.0.2/src/tvtime.c tvtime-1.0.2-custom/src/tvtime.c
  5225. --- tvtime-1.0.2/src/tvtime.c   2005-09-08 04:55:54.000000000 +0200
  5226. +++ tvtime-1.0.2-custom/src/tvtime.c    2011-05-29 13:07:28.172374148 +0200
  5227. @@ -1062,84 +1062,55 @@ static void build_matte_menu( menu_t *me
  5228.      char string[ 128 ];
  5229.  
  5230.      menu_set_back_command( menu, TVTIME_SHOW_MENU, "output" );
  5231. -    if( sixteennine ) {
  5232. -        snprintf( string, sizeof( string ), (mode == 0) ?
  5233. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5234. -                  _("16:9 + Overscan") );
  5235. -        menu_set_text( menu, 1, string );
  5236. -        menu_set_enter_command( menu, 1, TVTIME_SET_MATTE, "16:9" );
  5237. -        snprintf( string, sizeof( string ), (mode == 1) ?
  5238. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5239. -                  _("1.85:1") );
  5240. -        menu_set_text( menu, 2, string );
  5241. -        menu_set_enter_command( menu, 2, TVTIME_SET_MATTE, "1.85:1" );
  5242. -        snprintf( string, sizeof( string ), (mode == 2) ?
  5243. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5244. -                  _("2.35:1") );
  5245. -        menu_set_text( menu, 3, string );
  5246. -        menu_set_enter_command( menu, 3, TVTIME_SET_MATTE, "2.35:1" );
  5247. -        snprintf( string, sizeof( string ), (mode == 3) ?
  5248. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5249. -                  _("4:3 centre") );
  5250. -        menu_set_text( menu, 4, string );
  5251. -        menu_set_enter_command( menu, 4, TVTIME_SET_MATTE, "4:3" );
  5252. -        snprintf( string, sizeof( string ), (mode == 4) ?
  5253. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5254. -                  _("16:10") );
  5255. -        menu_set_text( menu, 5, string );
  5256. -        menu_set_enter_command( menu, 5, TVTIME_SET_MATTE, "16:10" );
  5257. -    } else {
  5258. -        snprintf( string, sizeof( string ), (mode == 0) ?
  5259. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5260. -                  _("4:3 + Overscan") );
  5261. -        menu_set_text( menu, 1, string );
  5262. -        menu_set_enter_command( menu, 1, TVTIME_SET_MATTE, "4:3" );
  5263. -        snprintf( string, sizeof( string ), (mode == 1) ?
  5264. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5265. -                  _("16:9") );
  5266. -        menu_set_text( menu, 2, string );
  5267. -        menu_set_enter_command( menu, 2, TVTIME_SET_MATTE, "16:9" );
  5268. -        snprintf( string, sizeof( string ), (mode == 2) ?
  5269. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5270. -                  _("16:10") );
  5271. -        menu_set_text( menu, 3, string );
  5272. -        menu_set_enter_command( menu, 3, TVTIME_SET_MATTE, "16:10" );
  5273. -        snprintf( string, sizeof( string ), (mode == 3) ?
  5274. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5275. -                  _("1.85:1") );
  5276. -        menu_set_text( menu, 4, string );
  5277. -        menu_set_enter_command( menu, 4, TVTIME_SET_MATTE, "1.85:1" );
  5278. -        snprintf( string, sizeof( string ), (mode == 4) ?
  5279. -                  TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5280. -                  _("2.35:1") );
  5281. -        menu_set_text( menu, 5, string );
  5282. -        menu_set_enter_command( menu, 5, TVTIME_SET_MATTE, "2.35:1" );
  5283. -    }
  5284. +
  5285. +    snprintf( string, sizeof( string ), (mode == 0) ?
  5286. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5287. +              _("4:3") );
  5288. +    menu_set_text( menu, 1, string );
  5289. +    menu_set_enter_command( menu, 1, TVTIME_SET_MATTE, "4:3" );
  5290. +    snprintf( string, sizeof( string ), (mode == 1) ?
  5291. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5292. +              _("16:10") );
  5293. +    menu_set_text( menu, 2, string );
  5294. +    menu_set_enter_command( menu, 2, TVTIME_SET_MATTE, "16:10" );
  5295. +    snprintf( string, sizeof( string ), (mode == 2) ?
  5296. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5297. +              _("16:9") );
  5298. +    menu_set_text( menu, 3, string );
  5299. +    menu_set_enter_command( menu, 3, TVTIME_SET_MATTE, "16:9" );      
  5300. +    snprintf( string, sizeof( string ), (mode == 3) ?
  5301. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5302. +              _("1.85:1") );
  5303. +    menu_set_text( menu, 4, string );
  5304. +    menu_set_enter_command( menu, 4, TVTIME_SET_MATTE, "1.85:1" );
  5305. +    snprintf( string, sizeof( string ), (mode == 4) ?
  5306. +              TVTIME_ICON_RADIOON "  %s" : TVTIME_ICON_RADIOOFF "  %s",
  5307. +              _("2.35:1") );
  5308. +    menu_set_text( menu, 5, string );
  5309. +    menu_set_enter_command( menu, 5, TVTIME_SET_MATTE, "2.35:1" );
  5310. +
  5311.  
  5312.      snprintf( string, sizeof( string ), TVTIME_ICON_PLAINLEFTARROW "  %s",
  5313.                _("Back") );
  5314.      menu_set_text( menu, 6, string );
  5315.      menu_set_enter_command( menu, 6, TVTIME_SHOW_MENU, "output" );
  5316.  }
  5317. -
  5318. +
  5319.  static void osd_list_matte( tvtime_osd_t *osd, int mode, int sixteennine )
  5320.  {
  5321.      tvtime_osd_list_set_lines( osd, 6 );
  5322.      if( sixteennine ) {
  5323.          tvtime_osd_list_set_text( osd, 0, _("Matte setting (Anamorphic input)") );
  5324. -        tvtime_osd_list_set_text( osd, 1, _("16:9 + Overscan") );
  5325. -        tvtime_osd_list_set_text( osd, 2, "1.85:1" );
  5326. -        tvtime_osd_list_set_text( osd, 3, "2.35:1" );
  5327. -        tvtime_osd_list_set_text( osd, 4, _("4:3 centre") );
  5328. -        tvtime_osd_list_set_text( osd, 5, "16:10" );
  5329. +
  5330.      } else {
  5331.          tvtime_osd_list_set_text( osd, 0, _("Matte setting (4:3 input)") );
  5332. -        tvtime_osd_list_set_text( osd, 1, _("4:3 + Overscan") );
  5333. -        tvtime_osd_list_set_text( osd, 2, "16:9" );
  5334. -        tvtime_osd_list_set_text( osd, 3, "16:10" );
  5335. -        tvtime_osd_list_set_text( osd, 4, "1.85:1" );
  5336. -        tvtime_osd_list_set_text( osd, 5, "2.35:1" );
  5337.      }
  5338. +    tvtime_osd_list_set_text( osd, 1, "4:3" );
  5339. +    tvtime_osd_list_set_text( osd, 2, "16:10" );
  5340. +    tvtime_osd_list_set_text( osd, 3, "16:9" );
  5341. +    tvtime_osd_list_set_text( osd, 4, "1.85:1" );
  5342. +    tvtime_osd_list_set_text( osd, 5, "2.35:1" );
  5343. +
  5344.      tvtime_osd_list_set_hilight( osd, mode + 1 );
  5345.      tvtime_osd_show_list( osd, 1, 0 );
  5346.  }
  5347. @@ -1204,6 +1175,7 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5348.      int matte_y = 0;
  5349.      int matte_h = 0;
  5350.      int matte_mode = 0;
  5351. +    int matte_changed = 0;
  5352.      int restarttvtime = 0;
  5353.      int return_value = 0;
  5354.      int last_current_id = -1;
  5355. @@ -1241,6 +1213,7 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5356.      output = get_xv_output();
  5357.  
  5358.      sixteennine = config_get_aspect( ct );
  5359. +    matte_mode = config_get_matte( ct );
  5360.  
  5361.      if( !output || !output->init( config_get_geometry( ct ),
  5362.                                    sixteennine, config_get_square_pixels( ct ),
  5363. @@ -1441,7 +1414,7 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5364.  
  5365.      /* Set the mixer device. */
  5366.      mixer_set_device( config_get_mixer_device( ct ) );
  5367. -    mixer_set_state( config_get_muted( ct ), config_get_unmute_volume( ct ) );
  5368. +    mixer->set_state( config_get_muted( ct ), config_get_unmute_volume( ct ) );
  5369.  
  5370.      /* Setup OSD stuff. */
  5371.      pixel_aspect = ( (double) width ) /
  5372. @@ -1594,6 +1567,15 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5373.      build_fspos_menu( commands_get_menu( commands, "fspos" ),
  5374.                        config_get_fullscreen_position( ct ) );
  5375.  
  5376. +    matte_changed = 1;
  5377. +    double matte = 4.0/3.0;
  5378. +    
  5379. +    /* initialize with safe values until matte is calculated later in the loop. */        
  5380. +    matte_x = 0;
  5381. +    matte_y = 0;
  5382. +    matte_w = width;
  5383. +    matte_h = height;
  5384. +
  5385.      /* Initialize our timestamps. */
  5386.      for(;;) {
  5387.          const char *fifo_args = 0;
  5388. @@ -1607,31 +1589,19 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5389.          int exposed = output->is_exposed();
  5390.          int current_id;
  5391.  
  5392. +
  5393.          if( vidin && videoinput_has_tuner( vidin ) ) {
  5394.              current_id = station_get_current_id( stationmgr );
  5395.          } else {
  5396.              current_id = 0;
  5397.          }
  5398. -
  5399. -        if( matte_mode ) {
  5400. +            /* Since the matte/overscan calculations changed these could probably
  5401. +               be the same variables, but we'll leave it like this for now. */
  5402.              output_x = matte_x;
  5403.              output_w = matte_w;
  5404.              output_y = matte_y;
  5405.              output_h = matte_h;
  5406. -        } else {
  5407. -            output_x = (int) ((((double) width) *
  5408. -                               commands_get_overscan( commands )) + 0.5);
  5409. -            output_w = (int) ((((double) width) -
  5410. -                               (((double) width) *
  5411. -                                commands_get_overscan( commands ) * 2.0)) +
  5412. -                              0.5);
  5413. -            output_y = (int) ((((double) height) *
  5414. -                               commands_get_overscan( commands )) + 0.5);
  5415. -            output_h = (int) ((((double) height) -
  5416. -                               (((double) height) *
  5417. -                                commands_get_overscan( commands ) * 2.0)) +
  5418. -                              0.5);
  5419. -        }
  5420. +        
  5421.  
  5422.          if( fifo ) {
  5423.              int cmd;
  5424. @@ -1766,11 +1736,14 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5425.                                 quiet_screenshots );
  5426.              commands_refresh_menu( commands );
  5427.          }
  5428. +
  5429. +        
  5430.          if( commands_toggle_aspect( commands ) ) {
  5431. -            matte_mode = 0;
  5432. -            output->set_matte( 0, 0 );
  5433.              if( output->toggle_aspect() ) {
  5434.                  sixteennine = 1;
  5435. +                /* Matte is now always applied so we change it to 16:9 mode too so that
  5436. +                   nothing other than overscan is cropped. */
  5437. +                matte_mode = 2;
  5438.                  if( osd ) {
  5439.                      tvtime_osd_show_message( osd,
  5440.                            _("16:9 display mode active.") );
  5441. @@ -1780,6 +1753,7 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5442.                      ( ( (double) height ) * (16.0 / 9.0) );
  5443.              } else {
  5444.                  sixteennine = 0;
  5445. +                matte_mode = 0;
  5446.                  if( osd ) {
  5447.                      tvtime_osd_show_message( osd,
  5448.                            _("4:3 display mode active.") );
  5449. @@ -1800,9 +1774,7 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5450.                                 output->is_alwaysontop_supported(),
  5451.                                 output->is_overscan_supported(),
  5452.                                 quiet_screenshots );
  5453. -            build_matte_menu( commands_get_menu( commands, "matte" ),
  5454. -                              matte_mode, sixteennine );
  5455. -            commands_refresh_menu( commands );
  5456. +            matte_changed = 1;
  5457.          }
  5458.          if( commands_get_fs_pos( commands ) ) {
  5459.              const char *fspos = commands_get_fs_pos( commands );
  5460. @@ -1839,84 +1811,92 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5461.              }
  5462.              commands_refresh_menu( commands );
  5463.          }
  5464. +
  5465. +        /* Overscan has been changed so it is calculated and applied with the matte.
  5466. +           So changing it now generated this event so that we can tell it to redo the matte. */
  5467. +       if( commands_get_changed_overscan( commands ) ) {
  5468. +            matte_changed = 1;
  5469. +        }
  5470.          if( commands_toggle_matte( commands ) ||
  5471.              commands_get_matte_mode( commands ) ) {
  5472. -            double matte = 4.0 / 3.0;
  5473. -            int sqwidth = sixteennine ?
  5474. -                ((height * 16) / 9) : ((height * 4) / 3);
  5475. -            int sqheight = sixteennine ?
  5476. -                ((width * 9) / 16) : ((width * 3) / 4);
  5477.  
  5478. -            matte_x = 0;
  5479. -            matte_w = width;
  5480.              if( commands_toggle_matte( commands ) ) {
  5481.                  matte_mode = (matte_mode + 1) % 5;
  5482.              } else {
  5483. -                if( !strcmp( commands_get_matte_mode( commands ), "16:9" ) ) {
  5484. -                    matte_mode = sixteennine ? 0 : 1;
  5485. -                } else if( !strcmp( commands_get_matte_mode( commands ),
  5486. -                                    "16:10" ) ) {
  5487. -                    matte_mode = sixteennine ? 4 : 2;
  5488. +                if( !strcmp( commands_get_matte_mode( commands ), "16:10" ) ) {
  5489. +                    matte_mode = 1;
  5490. +               } else if( !strcmp( commands_get_matte_mode( commands ),
  5491. +                                    "16:9" ) ) {
  5492. +                    matte_mode = 2;
  5493.                  } else if( !strcmp( commands_get_matte_mode( commands ),
  5494.                                      "1.85:1" ) ) {
  5495. -                    matte_mode = sixteennine ? 1 : 3;
  5496. +                    matte_mode = 3;
  5497.                  } else if( !strcmp( commands_get_matte_mode( commands ),
  5498.                                      "2.35:1" ) ) {
  5499. -                    matte_mode = sixteennine ? 2 : 4;
  5500. +                    matte_mode = 4;
  5501.                  } else {
  5502. -                    matte_mode = sixteennine ? 3 : 0;
  5503. +                    matte_mode = 0;
  5504.                  }
  5505.              }
  5506. -
  5507. -            if( sixteennine ) {
  5508. -                if( matte_mode == 0 ) {
  5509. -                    matte = 16.0 / 9.0;
  5510. -                } else if( matte_mode == 1 ) {
  5511. -                    matte = 1.85;
  5512. -                } else if( matte_mode == 2 ) {
  5513. -                    matte = 2.35;
  5514. -                } else if( matte_mode == 3 ) {
  5515. -                    matte = 4.0 / 3.0;
  5516. -                    matte_w = (int) (((double) sqheight * matte) + 0.5);
  5517. -                    matte_x = (width - matte_w) / 2;
  5518. -                    /* We're cropping the sides off so we add overscan to avoid mess
  5519. -                     * at the top of the screen. */
  5520. -                    matte_y = commands_get_overscan( commands ) * height / 2;
  5521. -                    matte_h = height - matte_y;
  5522. -                    output->set_matte( (matte_h * 4) / 3, matte_h );
  5523. -                } else if( matte_mode == 4 ) {
  5524. -                    matte = 1.6;
  5525. -                    matte_w = (int) (((double) sqheight * matte) + 0.5);
  5526. -                    matte_x = (width - matte_w) / 2;
  5527. -                    /* We're cropping the sides off so we add overscan to avoid mess
  5528. -                     * at the top of the screen. */
  5529. -                    matte_y = commands_get_overscan( commands ) * height / 2;
  5530. -                    matte_h = height - matte_y;
  5531. -                    output->set_matte( (matte_h * 16) / 10, matte_h );
  5532. -                }
  5533. -            } else {
  5534. -                if( matte_mode == 1 ) {
  5535. -                    matte = 16.0 / 9.0;
  5536. -                } else if( matte_mode == 2 ) {
  5537. -                    matte = 1.6;
  5538. -                } else if( matte_mode == 3 ) {
  5539. -                    matte = 1.85;
  5540. -                } else if( matte_mode == 4 ) {
  5541. -                    matte = 2.35;
  5542. -                }
  5543. -            }
  5544. -            if( !matte_x ) {
  5545. -                matte_h = (int) ((((double) sqwidth)/matte) + 0.5);
  5546. -                matte_y = (height - matte_h) / 2;
  5547. -                output->set_matte( sqwidth, matte_h );
  5548. -            }
  5549.              if( osd && !commands_menu_active( commands ) ) {
  5550.                  osd_list_matte( osd, matte_mode, sixteennine );
  5551.              }
  5552.              build_matte_menu( commands_get_menu( commands, "matte" ),
  5553.                                matte_mode, sixteennine );
  5554.              commands_refresh_menu( commands );
  5555. +            matte_changed = 1;
  5556.          }
  5557. +        if (matte_changed) {
  5558. +            matte_changed = 0;
  5559. +
  5560. +            /* start with overscan then apply matte */
  5561. +            matte_x = (int) ((((double) width) *
  5562. +                               commands_get_overscan( commands )) + 0.5);
  5563. +            matte_w = (int) ((((double) width) -
  5564. +                               (((double) width) *
  5565. +                                commands_get_overscan( commands ) * 2.0)) +
  5566. +                              0.5);
  5567. +            matte_y = (int) ((((double) height) *
  5568. +                               commands_get_overscan( commands )) + 0.5);
  5569. +            matte_h = (int) ((((double) height) -
  5570. +                               (((double) height) *
  5571. +                                commands_get_overscan( commands ) * 2.0)) +
  5572. +                              0.5);
  5573. +
  5574. +            int sqwidth = sixteennine ?
  5575. +                ((matte_h * 16) / 9) : ((matte_h * 4) / 3);
  5576. +            int sqheight = sixteennine ?
  5577. +                ((matte_w * 9) / 16) : ((matte_w * 3) / 4);
  5578. +
  5579. +            if( matte_mode == 0 ) {
  5580. +                matte = 4.0 / 3.0;
  5581. +                config_save( ct, "Matte", "4:3" );
  5582. +            } else if( matte_mode == 1 ) {
  5583. +                matte = 1.6;
  5584. +                config_save( ct, "Matte", "16:10" );
  5585. +            } else if( matte_mode == 2 ) {
  5586. +                matte = 16.0/9.0;
  5587. +                config_save( ct, "Matte", "16:9" );
  5588. +            } else if( matte_mode == 3 ) {
  5589. +                matte = 1.85;                    
  5590. +                config_save( ct, "Matte", "1.85:1" );
  5591. +            } else if( matte_mode == 4 ) {
  5592. +                matte = 2.35;
  5593. +                config_save( ct, "Matte", "2.35:1" );
  5594. +            }
  5595. +
  5596. +            if( sixteennine && matte < (16.0/9.0) )
  5597. +            {
  5598. +                matte_w = (int) (((double) sqheight * matte) + 0.5);
  5599. +                matte_x = (width - matte_w) / 2;                  
  5600. +                output->set_matte( matte_w, sqheight );
  5601. +            } else {
  5602. +                matte_h = (int) ((((double) sqwidth)/matte) + 0.5);
  5603. +                matte_y = (height - matte_h) / 2;
  5604. +                output->set_matte( sqwidth, matte_h );
  5605. +            }
  5606. +        }
  5607. +
  5608.          if( commands_toggle_pulldown_detection( commands ) ) {
  5609.              if( height == 480 ) {
  5610.                  tvtime->pulldown_alg =
  5611. @@ -2565,14 +2545,14 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5612.      snprintf( number, 4, "%d", quiet_screenshots );
  5613.      config_save( ct, "QuietScreenshots", number );
  5614.  
  5615. -    snprintf( number, 6, "%d", mixer_get_unmute_volume() );
  5616. +    snprintf( number, 6, "%d", mixer->get_unmute_volume() );
  5617.      config_save( ct, "UnmuteVolume", number );
  5618.  
  5619. -    snprintf( number, 4, "%d", mixer_ismute() );
  5620. +    snprintf( number, 4, "%d", mixer->ismute() );
  5621.      config_save( ct, "Muted", number );
  5622.  
  5623.      if( config_get_mute_on_exit( ct ) ) {
  5624. -        mixer_mute( 1 );
  5625. +        mixer->mute( 1 );
  5626.      }
  5627.  
  5628.      if( vidin ) {
  5629. @@ -2619,7 +2599,7 @@ int tvtime_main( rtctimer_t *rtctimer, i
  5630.      if( osd ) {
  5631.          tvtime_osd_delete( osd );
  5632.      }
  5633. -    mixer_close_device();
  5634. +    mixer->close_device();
  5635.  
  5636.      /* Free temporary memory. */
  5637.      free( colourbars );
  5638. diff -Nurp tvtime-1.0.2/src/tvtimeconf.c tvtime-1.0.2-custom/src/tvtimeconf.c
  5639. --- tvtime-1.0.2/src/tvtimeconf.c       2005-09-08 06:07:56.000000000 +0200
  5640. +++ tvtime-1.0.2-custom/src/tvtimeconf.c        2011-05-29 13:07:28.179040896 +0200
  5641. @@ -56,6 +56,7 @@ struct config_s
  5642.      char *geometry;
  5643.      int verbose;
  5644.      int aspect;
  5645. +    int matte;
  5646.      int squarepixels;
  5647.      int debug;
  5648.      int fullscreen;
  5649. @@ -290,6 +291,22 @@ static void parse_option( config_t *ct,
  5650.              ct->aspect = atoi( curval );
  5651.          }
  5652.  
  5653. +        if( !xmlStrcasecmp( name, BAD_CAST "Matte" ) ) {            
  5654. +            if(!strcmp( curval, "4:3")) {
  5655. +                ct->matte = 0;
  5656. +            } else if(!strcmp( curval, "16:10")) {
  5657. +                ct->matte = 1;
  5658. +            } else if(!strcmp( curval, "16:9")) {
  5659. +                ct->matte = 2;
  5660. +            } else if(!strcmp( curval, "1.85:1")) {
  5661. +                ct->matte = 3;
  5662. +            } else if(!strcmp( curval, "2.35:1")) {
  5663. +                ct->matte = 4;
  5664. +            }
  5665. +            /* No valid matte if found ct->matte will be -1 and config_get_matte will choose
  5666. +               a default based on the aspect ratio. */
  5667. +        }
  5668. +
  5669.          if( !xmlStrcasecmp( name, BAD_CAST "DebugMode" ) ) {
  5670.              ct->debug = atoi( curval );
  5671.          }
  5672. @@ -629,9 +646,11 @@ static void print_usage( char **argv )
  5673.      lfputs( _("  -l, --xmltvlanguage=LANG   Use XMLTV data in given language, if available.\n"), stderr );
  5674.      lfputs( _("  -v, --verbose              Print debugging messages to stderr.\n"), stderr );
  5675.      lfputs( _("  -X, --display=DISPLAY      Use the given X display to connect to.\n"), stderr );
  5676. -    lfputs( _("  -x, --mixer=DEVICE[:CH]    The mixer device and channel to control.\n"
  5677. -              "                             (defaults to /dev/mixer:line)\n\n"
  5678. -              "                             Valid channels are:\n"
  5679. +    lfputs( _("  -x, --mixer=<DEVICE[:CH]>|<DEVICE/CH>\n"
  5680. +              "                             The mixer device and channel to control. The first\n"
  5681. +              "                             variant sets the OSS mixer the second one ALSA.\n"
  5682. +              "                             (defaults to default/Line)\n\n"
  5683. +              "                             Valid channels for OSS are:\n"
  5684.                "                                 vol, bass, treble, synth, pcm, speaker, line,\n"
  5685.                "                                 mic, cd, mix, pcm2, rec, igain, ogain, line1,\n"
  5686.                "                                 line2, line3, dig1, dig2, dig3, phin, phout,\n"
  5687. @@ -677,9 +696,11 @@ static void print_config_usage( char **a
  5688.      lfputs( _("  -R, --priority=PRI         Sets the process priority to run tvtime at.\n"), stderr );
  5689.      lfputs( _("  -t, --xmltv=FILE           Read XMLTV listings from the given file.\n"), stderr );
  5690.      lfputs( _("  -l, --xmltvlanguage=LANG   Use XMLTV data in given language, if available.\n"), stderr );
  5691. -    lfputs( _("  -x, --mixer=DEVICE[:CH]    The mixer device and channel to control.\n"
  5692. -              "                             (defaults to /dev/mixer:line)\n\n"
  5693. -              "                             Valid channels are:\n"
  5694. +    lfputs( _("  -x, --mixer=<DEVICE[:CH]>|<DEVICE/CH>\n"
  5695. +              "                             The mixer device and channel to control. The first\n"
  5696. +              "                             variant sets the OSS mixer the second one ALSA.\n"
  5697. +              "                             (defaults to default/Line)\n\n"
  5698. +              "                             Valid channels for OSS are:\n"
  5699.                "                                 vol, bass, treble, synth, pcm, speaker, line,\n"
  5700.                "                                 mic, cd, mix, pcm2, rec, igain, ogain, line1,\n"
  5701.                "                                 line2, line3, dig1, dig2, dig3, phin, phout,\n"
  5702. @@ -712,6 +733,7 @@ config_t *config_new( void )
  5703.      ct->geometry = strdup( "0x576" );
  5704.      ct->verbose = 0;
  5705.      ct->aspect = 0;
  5706. +    ct->matte = -1;
  5707.      ct->squarepixels = 1;
  5708.      ct->debug = 0;
  5709.      ct->fullscreen = 0;
  5710. @@ -764,7 +786,7 @@ config_t *config_new( void )
  5711.  
  5712.      ct->uid = getuid();
  5713.  
  5714. -    ct->mixerdev = strdup( "/dev/mixer:line" );
  5715. +    ct->mixerdev = strdup( "default/Line" );
  5716.  
  5717.      ct->deinterlace_method = strdup( "GreedyH" );
  5718.      ct->check_freq_present = 1;
  5719. @@ -807,6 +829,10 @@ config_t *config_new( void )
  5720.      ct->keymap[ 'a' ] = TVTIME_TOGGLE_ASPECT;
  5721.      ct->keymap[ 'f' ] = TVTIME_TOGGLE_FULLSCREEN;
  5722.      ct->keymap[ 'i' ] = TVTIME_TOGGLE_INPUT;
  5723. +    ct->keymap[ 'a' ] = TVTIME_TOGGLE_ASPECT;
  5724. +    ct->keymap[ I_INSERT ] = TVTIME_TOGGLE_MATTE;
  5725. +    ct->keymap[ ',' ] = TVTIME_OVERSCAN_DOWN;
  5726. +    ct->keymap[ '.' ] = TVTIME_OVERSCAN_DOWN;
  5727.      ct->keymap[ 's' ] = TVTIME_SCREENSHOT;
  5728.      ct->keymap[ ',' ] = TVTIME_MIXER_TOGGLE_MUTE;
  5729.      ct->keymap[ 'e' ] = TVTIME_TOGGLE_AUDIO_MODE;
  5730. @@ -1451,6 +1477,13 @@ int config_get_aspect( config_t *ct )
  5731.      return ct->aspect;
  5732.  }
  5733.  
  5734. +int config_get_matte( config_t *ct )
  5735. +{
  5736. +    /* If matte is not set then default to 0 for normal or 2 for widescreen. */
  5737. +    if (ct->matte == -1) return ct->aspect * 2;
  5738. +    return ct->matte;
  5739. +}
  5740. +
  5741.  int config_get_start_channel( config_t *ct )
  5742.  {
  5743.      return ct->start_channel;
  5744. diff -Nurp tvtime-1.0.2/src/tvtimeconf.c.orig tvtime-1.0.2-custom/src/tvtimeconf.c.orig
  5745. --- tvtime-1.0.2/src/tvtimeconf.c.orig  1970-01-01 01:00:00.000000000 +0100
  5746. +++ tvtime-1.0.2-custom/src/tvtimeconf.c.orig   2011-05-29 13:07:28.142373782 +0200
  5747. @@ -0,0 +1,1667 @@
  5748. +/**
  5749. + * Copyright (C) 2002, 2003 Doug Bell <drbell@users.sourceforge.net>
  5750. + * Copyright (C) 2003 Alexander Belov <asbel@mail.ru>
  5751. + *
  5752. + * This program is free software; you can redistribute it and/or modify
  5753. + * it under the terms of the GNU General Public License as published by
  5754. + * the Free Software Foundation; either version 2, or (at your option)
  5755. + * any later version.
  5756. + *
  5757. + * This program is distributed in the hope that it will be useful,
  5758. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5759. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  5760. + * GNU General Public License for more details.
  5761. + *
  5762. + * You should have received a copy of the GNU General Public License
  5763. + * along with this program; if not, write to the Free Software Foundation,
  5764. + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  5765. + */
  5766. +
  5767. +#define _GNU_SOURCE
  5768. +#include <stdlib.h>
  5769. +#include <stdio.h>
  5770. +#include <string.h>
  5771. +#include <getopt.h>
  5772. +#include <sys/types.h>
  5773. +#include <sys/stat.h>
  5774. +#include <fcntl.h>
  5775. +#include <ctype.h>
  5776. +#include <unistd.h>
  5777. +#include <dirent.h>
  5778. +#include <langinfo.h>
  5779. +#include <locale.h>
  5780. +#include <pwd.h>
  5781. +#include <errno.h>
  5782. +#include <libxml/parser.h>
  5783. +#include <math.h>
  5784. +#ifdef HAVE_CONFIG_H
  5785. +# include "config.h"
  5786. +#endif
  5787. +#ifdef ENABLE_NLS
  5788. +# define _(string) gettext (string)
  5789. +# include "gettext.h"
  5790. +#else
  5791. +# define _(string) string
  5792. +#endif
  5793. +#include "tvtimeconf.h"
  5794. +#include "input.h"
  5795. +#include "station.h"
  5796. +#include "utils.h"
  5797. +
  5798. +#define MAX_KEYSYMS 350
  5799. +#define MAX_BUTTONS 15
  5800. +
  5801. +struct config_s
  5802. +{
  5803. +    char *geometry;
  5804. +    int verbose;
  5805. +    int aspect;
  5806. +    int squarepixels;
  5807. +    int debug;
  5808. +    int fullscreen;
  5809. +    int alwaysontop;
  5810. +    int priority;
  5811. +    int ntsc_mode;
  5812. +    int send_fields;
  5813. +    int fspos;
  5814. +    int picsaverestore;
  5815. +    int brightness;
  5816. +    int contrast;
  5817. +    int saturation;
  5818. +    int hue;
  5819. +    int invert;
  5820. +    int cc;
  5821. +    int mirror;
  5822. +    int boost;
  5823. +    int quiet_screenshots;
  5824. +    int unmute_volume;
  5825. +    int muted;
  5826. +    int mute_on_exit;
  5827. +    int show_taglines;
  5828. +
  5829. +    int keymap[ 8 * MAX_KEYSYMS ];
  5830. +    char *keymap_arg[ 8 * MAX_KEYSYMS ];
  5831. +    int keymapmenu[ 8 * MAX_KEYSYMS ];
  5832. +    char *keymapmenu_arg[ 8 * MAX_KEYSYMS ];
  5833. +    int buttonmap[ MAX_BUTTONS ];
  5834. +    char *buttonmap_arg[ MAX_BUTTONS ];
  5835. +    int buttonmapmenu[ MAX_BUTTONS ];
  5836. +    char *buttonmapmenu_arg[ MAX_BUTTONS ];
  5837. +
  5838. +    int inputwidth;
  5839. +    int inputnum;
  5840. +    char *v4ldev;
  5841. +    char *norm;
  5842. +    char *freq;
  5843. +    char *ssdir;
  5844. +    char *timeformat;
  5845. +    char *audiomode;
  5846. +    char *xmltvfile;
  5847. +    char *xmltvlanguage;
  5848. +    unsigned int channel_text_rgb;
  5849. +    unsigned int other_text_rgb;
  5850. +
  5851. +    uid_t uid;
  5852. +
  5853. +    char *mixerdev;
  5854. +
  5855. +    char *deinterlace_method;
  5856. +    int check_freq_present;
  5857. +
  5858. +    int use_xds;
  5859. +    char *vbidev;
  5860. +
  5861. +    int start_channel;
  5862. +    int prev_channel;
  5863. +    int framerate;
  5864. +    int slave_mode;
  5865. +
  5866. +    double overscan;
  5867. +
  5868. +    char *config_filename;
  5869. +    xmlDocPtr doc;
  5870. +};
  5871. +
  5872. +static unsigned int parse_colour( const char *str )
  5873. +{
  5874. +    unsigned int a, r, g, b;
  5875. +    int ret;
  5876. +    
  5877. +    if( !str || !*str ) return 0;
  5878. +
  5879. +    if( strlen( str ) == 1 ) return (unsigned int)atoi( str );
  5880. +
  5881. +    if( str[0] == '0' && str[1] == 'x' ) {
  5882. +        ret = sscanf( str, "0x%x", &a );
  5883. +    } else {
  5884. +        ret = sscanf( str, "%u %u %u %u", &a, &r, &g, &b );
  5885. +    }
  5886. +
  5887. +    if( ret == 1 ) {
  5888. +        return a;
  5889. +    } else if( ret == 2 ) {
  5890. +        return 0xff000000 | ( (a & 0xff) << 8 ) | (r & 0xff);
  5891. +    } else if( ret == 3 ) {
  5892. +        return 0xff000000 | ( (a & 0xff) << 16 ) | ( (r & 0xff) << 8 ) | ( g & 0xff);
  5893. +    } else if( ret == 4 ) {
  5894. +        return ( (a & 0xff) << 24 ) | ( (r & 0xff) << 16 ) | ( ( g & 0xff) << 8 ) | (b & 0xff);
  5895. +    }
  5896. +
  5897. +    return 0;
  5898. +}
  5899. +
  5900. +static xmlNodePtr find_option( xmlNodePtr node, const char *optname )
  5901. +{
  5902. +    while( node ) {
  5903. +        if( !xmlStrcasecmp( node->name, BAD_CAST "option" ) ) {
  5904. +            xmlChar *name = xmlGetProp( node, BAD_CAST "name" );
  5905. +
  5906. +            if( name && !xmlStrcasecmp( name, BAD_CAST optname ) ) {
  5907. +                xmlFree( name );
  5908. +                return node;
  5909. +            }
  5910. +            if( name ) xmlFree( name );
  5911. +        }
  5912. +
  5913. +        node = node->next;
  5914. +    }
  5915. +
  5916. +    return 0;
  5917. +}
  5918. +
  5919. +static void parse_option( config_t *ct, xmlNodePtr node )
  5920. +{
  5921. +    xmlChar *name;
  5922. +    xmlChar *value;
  5923. +
  5924. +    name = xmlGetProp( node, BAD_CAST "name" );
  5925. +    value = xmlGetProp( node, BAD_CAST "value" );
  5926. +
  5927. +    if( name && value ) {
  5928. +        char *curval = (char *) value;
  5929. +
  5930. +        if( !xmlStrcasecmp( name, BAD_CAST "WindowGeometry" ) ) {
  5931. +            if( ct->geometry ) free( ct->geometry );
  5932. +            ct->geometry = strdup( curval );
  5933. +        }
  5934. +
  5935. +        if( !xmlStrcasecmp( name, BAD_CAST "InputWidth" ) ) {
  5936. +            ct->inputwidth = atoi( curval );
  5937. +        }
  5938. +
  5939. +        if( !xmlStrcasecmp( name, BAD_CAST "Verbose" ) ) {
  5940. +            ct->verbose = atoi( curval );
  5941. +        }
  5942. +
  5943. +        if( !xmlStrcasecmp( name, BAD_CAST "SaveAndRestorePictureSettings" ) ) {
  5944. +            ct->picsaverestore = atoi( curval );
  5945. +        }
  5946. +
  5947. +        if( !xmlStrcasecmp( name, BAD_CAST "DefaultBrightness" ) ) {
  5948. +            ct->brightness = atoi( curval );
  5949. +        }
  5950. +
  5951. +        if( !xmlStrcasecmp( name, BAD_CAST "DefaultContrast" ) ) {
  5952. +            ct->contrast = atoi( curval );
  5953. +        }
  5954. +
  5955. +        if( !xmlStrcasecmp( name, BAD_CAST "DefaultColour" ) ) {
  5956. +            ct->saturation = atoi( curval );
  5957. +        }
  5958. +
  5959. +        if( !xmlStrcasecmp( name, BAD_CAST "DefaultSaturation" ) ) {
  5960. +            ct->saturation = atoi( curval );
  5961. +        }
  5962. +
  5963. +        if( !xmlStrcasecmp( name, BAD_CAST "DefaultHue" ) ) {
  5964. +            ct->hue = atoi( curval );
  5965. +        }
  5966. +
  5967. +        if( !xmlStrcasecmp( name, BAD_CAST "ColourInvert" ) ) {
  5968. +            ct->invert = atoi( curval );
  5969. +        }
  5970. +
  5971. +        if( !xmlStrcasecmp( name, BAD_CAST "MirrorInput" ) ) {
  5972. +            ct->mirror = atoi( curval );
  5973. +        }
  5974. +
  5975. +        if( !xmlStrcasecmp( name, BAD_CAST "AudioBoost" ) ) {
  5976. +            ct->boost = atoi( curval );
  5977. +        }
  5978. +
  5979. +        if( !xmlStrcasecmp( name, BAD_CAST "QuietScreenshots" ) ) {
  5980. +            ct->quiet_screenshots = atoi( curval );
  5981. +        }
  5982. +
  5983. +        if( !xmlStrcasecmp( name, BAD_CAST "UnmuteVolume" ) ) {
  5984. +            ct->unmute_volume = atoi( curval );
  5985. +        }
  5986. +
  5987. +        if( !xmlStrcasecmp( name, BAD_CAST "Muted" ) ) {
  5988. +            ct->muted = atoi( curval );
  5989. +        }
  5990. +
  5991. +        if( !xmlStrcasecmp( name, BAD_CAST "MuteOnExit" ) ) {
  5992. +            ct->mute_on_exit = atoi( curval );
  5993. +        }
  5994. +
  5995. +        if( !xmlStrcasecmp( name, BAD_CAST "ShowTaglines" ) ) {
  5996. +            ct->show_taglines = atoi( curval );
  5997. +        }
  5998. +
  5999. +        if( !xmlStrcasecmp( name, BAD_CAST "ShowCC" ) ) {
  6000. +            ct->cc = atoi( curval );
  6001. +        }
  6002. +
  6003. +        if( !xmlStrcasecmp( name, BAD_CAST "DFBSendFields" ) ) {
  6004. +            ct->send_fields = atoi( curval );
  6005. +        }
  6006. +
  6007. +        if( !xmlStrcasecmp( name, BAD_CAST "AudioMode" ) ) {
  6008. +            if( ct->audiomode ) free( ct->audiomode );
  6009. +            ct->audiomode = strdup( curval );
  6010. +        }
  6011. +
  6012. +        if( !xmlStrcasecmp( name, BAD_CAST "XMLTVFile" ) ) {
  6013. +            if( ct->xmltvfile ) free( ct->xmltvfile );
  6014. +            ct->xmltvfile = expand_user_path( curval );
  6015. +        }
  6016. +
  6017. +        if( !xmlStrcasecmp( name, BAD_CAST "XMLTVLanguage" ) ) {
  6018. +            if( ct->xmltvlanguage ) free( ct->xmltvlanguage );
  6019. +            ct->xmltvlanguage = strdup( curval );
  6020. +        }
  6021. +
  6022. +        if( !xmlStrcasecmp( name, BAD_CAST "FullscreenPosition" ) ) {
  6023. +            if( tolower( curval[ 0 ] ) == 't' ) {
  6024. +                ct->fspos = 1;
  6025. +            } else if( tolower( curval[ 0 ] ) == 'b' ) {
  6026. +                ct->fspos = 2;
  6027. +            } else {
  6028. +                ct->fspos = 0;
  6029. +            }
  6030. +        }
  6031. +
  6032. +        if( !xmlStrcasecmp( name, BAD_CAST "SquarePixels" ) ) {
  6033. +            ct->squarepixels = atoi( curval );
  6034. +        }
  6035. +
  6036. +        if( !xmlStrcasecmp( name, BAD_CAST "Widescreen" ) ) {
  6037. +            ct->aspect = atoi( curval );
  6038. +        }
  6039. +
  6040. +        if( !xmlStrcasecmp( name, BAD_CAST "DebugMode" ) ) {
  6041. +            ct->debug = atoi( curval );
  6042. +        }
  6043. +
  6044. +        if( !xmlStrcasecmp( name, BAD_CAST "V4LDevice" ) ) {
  6045. +            if( ct->v4ldev ) free( ct->v4ldev );
  6046. +            ct->v4ldev = strdup( curval );
  6047. +        }
  6048. +
  6049. +        if( !xmlStrcasecmp( name, BAD_CAST "VBIDevice" ) ) {
  6050. +            if( ct->vbidev ) free( ct->vbidev );
  6051. +            ct->vbidev = strdup( curval );
  6052. +        }
  6053. +
  6054. +        if( !xmlStrcasecmp( name, BAD_CAST "V4LInput" ) ) {
  6055. +            ct->inputnum = atoi( curval );
  6056. +        }
  6057. +
  6058. +        if( !xmlStrcasecmp( name, BAD_CAST "UseXDS" ) ) {
  6059. +            ct->use_xds = atoi( curval );
  6060. +        }
  6061. +
  6062. +        if( !xmlStrcasecmp( name, BAD_CAST "ProcessPriority" ) ) {
  6063. +            ct->priority = atoi( curval );
  6064. +        }
  6065. +
  6066. +        if( !xmlStrcasecmp( name, BAD_CAST "Fullscreen" ) ) {
  6067. +            ct->fullscreen = atoi( curval );
  6068. +        }
  6069. +
  6070. +        if( !xmlStrcasecmp( name, BAD_CAST "AlwaysOnTop" ) ) {
  6071. +            ct->alwaysontop = atoi( curval );
  6072. +        }
  6073. +
  6074. +        if( !xmlStrcasecmp( name, BAD_CAST "FramerateMode" ) ) {
  6075. +            ct->framerate = atoi( curval );
  6076. +        }
  6077. +
  6078. +        if( !xmlStrcasecmp( name, BAD_CAST "Norm" ) ) {
  6079. +            if( ct->norm ) free( ct->norm );
  6080. +            ct->norm = strdup( curval );
  6081. +        }
  6082. +
  6083. +        if( !xmlStrcasecmp( name, BAD_CAST "Frequencies" ) ) {
  6084. +            if( ct->freq ) free( ct->freq );
  6085. +            ct->freq = strdup( curval );
  6086. +        }
  6087. +
  6088. +        if( !xmlStrcasecmp( name, BAD_CAST "TimeFormat" ) ) {
  6089. +            if( ct->timeformat ) free( ct->timeformat );
  6090. +            ct->timeformat = strdup( curval );
  6091. +        }
  6092. +
  6093. +        if( !xmlStrcasecmp( name, BAD_CAST "ScreenShotDir" ) ) {
  6094. +            if( ct->ssdir ) free( ct->ssdir );
  6095. +            ct->ssdir = expand_user_path( curval );
  6096. +        }
  6097. +
  6098. +        if( !xmlStrcasecmp( name, BAD_CAST "ChannelTextFG" ) ) {
  6099. +            ct->channel_text_rgb = parse_colour( curval );
  6100. +        }
  6101. +
  6102. +        if( !xmlStrcasecmp( name, BAD_CAST "OtherTextFG" ) ) {
  6103. +            ct->other_text_rgb = parse_colour( curval );
  6104. +        }
  6105. +
  6106. +        if( !xmlStrcasecmp( name, BAD_CAST "PrevChannel" ) ) {
  6107. +            ct->prev_channel = atoi( curval );
  6108. +        }
  6109. +
  6110. +        if( !xmlStrcasecmp( name, BAD_CAST "Channel" ) ) {
  6111. +            ct->start_channel = atoi( curval );
  6112. +        }
  6113. +
  6114. +        if( !xmlStrcasecmp( name, BAD_CAST "NTSCCableMode" ) ) {
  6115. +            if( !xmlStrcasecmp( value, BAD_CAST "IRC" ) ) {
  6116. +                ct->ntsc_mode = NTSC_CABLE_MODE_IRC;
  6117. +            } else if( !xmlStrcasecmp( value, BAD_CAST "HRC" ) ) {
  6118. +                ct->ntsc_mode = NTSC_CABLE_MODE_HRC;
  6119. +            } else {
  6120. +                ct->ntsc_mode = NTSC_CABLE_MODE_STANDARD;
  6121. +            }
  6122. +        }
  6123. +
  6124. +        if( !xmlStrcasecmp( name, BAD_CAST "DeinterlaceMethod" ) ) {
  6125. +            if( ct->deinterlace_method ) free( ct->deinterlace_method );
  6126. +            ct->deinterlace_method = strdup( curval );
  6127. +        }
  6128. +
  6129. +        if( !xmlStrcasecmp( name, BAD_CAST "CheckForSignal" ) ) {
  6130. +            ct->check_freq_present = atoi( curval );
  6131. +        }
  6132. +
  6133. +        if( !xmlStrcasecmp( name, BAD_CAST "Overscan" ) ) {
  6134. +            char prevloc[ 256 ];
  6135. +
  6136. +            /* Make sure floating point numbers are always written to
  6137. +             * the config file in "C" locale format.
  6138. +             */
  6139. +            strncpy( prevloc, setlocale( LC_NUMERIC, NULL ), sizeof prevloc );
  6140. +            setlocale( LC_NUMERIC, "C" );
  6141. +            ct->overscan = ( atof( curval ) / 2.0 ) / 100.0;
  6142. +            if( !isnormal( ct->overscan ) ) {
  6143. +                ct->overscan = 0.0;
  6144. +            }
  6145. +            setlocale( LC_NUMERIC, prevloc );
  6146. +        }
  6147. +
  6148. +        if( !xmlStrcasecmp( name, BAD_CAST "MixerDevice" ) ) {
  6149. +            if( ct->mixerdev ) free( ct->mixerdev );
  6150. +            ct->mixerdev = strdup( curval );
  6151. +        }
  6152. +    }
  6153. +
  6154. +    if( name ) xmlFree( name );
  6155. +    if( value ) xmlFree( value );
  6156. +}
  6157. +
  6158. +static void parse_bind( config_t *ct, xmlNodePtr node )
  6159. +{
  6160. +    xmlChar *command = xmlGetProp( node, BAD_CAST "command" );
  6161. +    xmlChar *arg = xmlGetProp( node, BAD_CAST "argument" );
  6162. +
  6163. +    if( command ) {
  6164. +        xmlNodePtr binding = node->xmlChildrenNode;
  6165. +
  6166. +        while( binding ) {
  6167. +            if( !xmlStrcasecmp( binding->name, BAD_CAST "keyboard" ) ) {
  6168. +                xmlChar *key = xmlGetProp( binding, BAD_CAST "key" );
  6169. +
  6170. +                if( key ) {
  6171. +                    int keycode, command_id;
  6172. +
  6173. +                    keycode = input_string_to_special_key( (const char *) key );
  6174. +                    if( !keycode ) {
  6175. +                        keycode = (*key);
  6176. +                    }
  6177. +
  6178. +                    command_id = tvtime_string_to_command( (const char *) command );
  6179. +                    if( tvtime_is_menu_command( command_id ) ) {
  6180. +                        ct->keymapmenu[ keycode ] = command_id;
  6181. +                        if( arg ) ct->keymapmenu_arg[ keycode ] = strdup( (const char *) arg );
  6182. +                    } else if( command_id != TVTIME_NOCOMMAND ) {
  6183. +                        ct->keymap[ keycode ] = command_id;
  6184. +                        if( arg ) ct->keymap_arg[ keycode ] = strdup( (const char *) arg );
  6185. +                    }
  6186. +                }
  6187. +            } else if( !xmlStrcasecmp( binding->name, BAD_CAST "mouse" ) ) {
  6188. +                xmlChar *button = xmlGetProp( binding, BAD_CAST "button" );
  6189. +                if( button ) {
  6190. +                    int id = atoi( (const char *) button );
  6191. +                    if( (id > 0) && (id < MAX_BUTTONS) ) {
  6192. +                        int command_id = tvtime_string_to_command( (const char *) command );
  6193. +                        if( tvtime_is_menu_command( command_id ) ) {
  6194. +                            ct->buttonmapmenu[ id ] = command_id;
  6195. +                            if( arg ) ct->buttonmapmenu_arg[ id ] = strdup( (const char *) arg );
  6196. +                        } else {
  6197. +                            ct->buttonmap[ id ] = command_id;
  6198. +                            if( arg ) ct->buttonmap_arg[ id ] = strdup( (const char *) arg );
  6199. +                        }
  6200. +                    }
  6201. +                    xmlFree( button );
  6202. +                }
  6203. +            }
  6204. +            binding = binding->next;
  6205. +        }
  6206. +
  6207. +        xmlFree( command );
  6208. +    }
  6209. +    if( arg ) xmlFree( arg );
  6210. +}
  6211. +
  6212. +static int conf_xml_parse( config_t *ct, char *configFile )
  6213. +{
  6214. +    xmlDocPtr doc;
  6215. +    xmlNodePtr top, node;
  6216. +
  6217. +    doc = xmlParseFile( configFile );
  6218. +    if( !doc ) {
  6219. +        lfprintf( stderr, _("Error parsing configuration file %s.\n"),
  6220. +                  configFile );
  6221. +        return 0;
  6222. +    }
  6223. +
  6224. +    top = xmlDocGetRootElement( doc );
  6225. +    if( !top ) {
  6226. +        lfprintf( stderr, _("No XML root element found in %s.\n"),
  6227. +                  configFile );
  6228. +        xmlFreeDoc( doc );
  6229. +        return 0;
  6230. +    }
  6231. +
  6232. +    if( xmlStrcasecmp( top->name, BAD_CAST "tvtime" ) ) {
  6233. +        lfprintf( stderr,
  6234. +                  _("%s is not a tvtime configuration file.\n"),
  6235. +                  configFile );
  6236. +        xmlFreeDoc( doc );
  6237. +        return 0;
  6238. +    }
  6239. +
  6240. +    node = top->xmlChildrenNode;
  6241. +    while( node ) {
  6242. +        if( !xmlIsBlankNode( node ) ) {
  6243. +            if( !xmlStrcasecmp( node->name, BAD_CAST "option" ) ) {
  6244. +                parse_option( ct, node );
  6245. +            } else if( !xmlStrcasecmp( node->name, BAD_CAST "bind" ) ) {
  6246. +                parse_bind( ct, node );
  6247. +            }
  6248. +        }
  6249. +        node = node->next;
  6250. +    }
  6251. +
  6252. +    xmlFreeDoc( doc );
  6253. +    return 1;
  6254. +}
  6255. +
  6256. +/* Attempt to parse the file for key elements and create them if they don't exist */
  6257. +static xmlDocPtr configsave_open( const char *config_filename )
  6258. +{
  6259. +    xmlDocPtr doc;
  6260. +    xmlNodePtr top;
  6261. +    int create_file = 0;
  6262. +
  6263. +    doc = xmlParseFile( config_filename );
  6264. +    if( !doc ) {
  6265. +        if( file_is_openable_for_read( config_filename ) ) {
  6266. +            lfputs( _("Config file cannot be parsed. "
  6267. +                      "Settings will not be saved.\n"), stderr );
  6268. +            return 0;
  6269. +        } else {
  6270. +            /* Config file doesn't exist, create a new one. */
  6271. +            doc = xmlNewDoc( BAD_CAST "1.0" );
  6272. +            if( !doc ) {
  6273. +                lfputs( _("Could not create new config file.\n"), stderr );
  6274. +                return 0;
  6275. +            }
  6276. +            create_file = 1;
  6277. +        }
  6278. +    }
  6279. +
  6280. +    top = xmlDocGetRootElement( doc );
  6281. +    if( !top ) {
  6282. +        /* Set the DTD */
  6283. +        xmlDtdPtr dtd;
  6284. +        dtd = xmlNewDtd( doc, BAD_CAST "tvtime",
  6285. +                         BAD_CAST "-//tvtime//DTD tvtime 1.0//EN",
  6286. +                         BAD_CAST "http://tvtime.sourceforge.net/DTD/tvtime1.dtd" );
  6287. +        doc->intSubset = dtd;
  6288. +        if( !doc->children ) {
  6289. +            xmlAddChild( (xmlNodePtr) doc, (xmlNodePtr) dtd );
  6290. +        } else {
  6291. +            xmlAddPrevSibling( doc->children, (xmlNodePtr) dtd );
  6292. +        }
  6293. +
  6294. +        /* Create the root node */
  6295. +        top = xmlNewDocNode( doc, 0, BAD_CAST "tvtime", 0 );
  6296. +        if( !top ) {
  6297. +            lfputs( _("Error creating configuration file.\n"), stderr );
  6298. +            xmlFreeDoc( doc );
  6299. +            return 0;
  6300. +        } else {
  6301. +            xmlDocSetRootElement( doc, top );
  6302. +            xmlNewProp( top, BAD_CAST "xmlns",
  6303. +                        BAD_CAST "http://tvtime.sourceforge.net/DTD/" );
  6304. +        }
  6305. +    }
  6306. +
  6307. +    if( xmlStrcasecmp( top->name, BAD_CAST "tvtime" ) ) {
  6308. +        lfprintf( stderr, _("%s is not a tvtime configuration file.\n"),
  6309. +                  config_filename );
  6310. +        xmlFreeDoc( doc );
  6311. +        return 0;
  6312. +    }
  6313. +
  6314. +    xmlKeepBlanksDefault( 0 );
  6315. +    xmlSaveFormatFile( config_filename, doc, 1 );
  6316. +    if( create_file ) {
  6317. +        if( chown( config_filename, getuid(), getgid() ) < 0 ) {
  6318. +            lfprintf( stderr, _("Cannot change owner of %s: %s.\n"),
  6319. +                      config_filename, strerror( errno ) );
  6320. +        }
  6321. +    }
  6322. +    return doc;
  6323. +}
  6324. +
  6325. +static void print_copyright( void )
  6326. +{
  6327. +    lfputs (_("\n"
  6328. +              "tvtime is free software, written by Billy Biggs, Doug Bell and many\n"
  6329. +              "others.  For details and copying conditions, please see our website\n"
  6330. +              "at http://tvtime.net/\n"
  6331. +              "\n"
  6332. +              "tvtime is Copyright (C) 2001, 2002, 2003 by Billy Biggs, Doug Bell,\n"
  6333. +              "Alexander S. Belov, and Achim Schneider.\n"), stderr );
  6334. +}
  6335. +
  6336. +static void print_usage( char **argv )
  6337. +{
  6338. +    lfprintf( stderr, _("usage: %s [OPTION]...\n\n"), argv[ 0 ] );
  6339. +    lfputs( _("  -a, --widescreen           16:9 mode.\n"), stderr );
  6340. +    lfputs( _("  -A, --nowidescreen         4:3 mode.\n"), stderr );
  6341. +    lfputs( _("  -b, --vbidevice=DEVICE     VBI device (defaults to /dev/vbi0).\n"), stderr );
  6342. +    lfputs( _("  -c, --channel=CHANNEL      Tune to the specified channel on startup.\n"), stderr );
  6343. +    lfputs( _("  -d, --device=DEVICE        video4linux device (defaults to /dev/video0).\n"), stderr );
  6344. +    lfputs( _("  -f, --frequencies=NAME     The frequency table to use for the tuner.\n"
  6345. +              "                             (defaults to us-cable).\n\n"
  6346. +              "                             Valid values are:\n"
  6347. +              "                                 us-cable\n"
  6348. +              "                                 us-cable100\n"
  6349. +              "                                 us-broadcast\n"
  6350. +              "                                 china-broadcast\n"
  6351. +              "                                 southafrica\n"
  6352. +              "                                 japan-cable\n"
  6353. +              "                                 japan-broadcast\n"
  6354. +              "                                 europe\n"
  6355. +              "                                 australia\n"
  6356. +              "                                 australia-optus\n"
  6357. +              "                                 newzealand\n"
  6358. +              "                                 france\n"
  6359. +              "                                 russia\n"
  6360. +              "                                 custom (first run tvtime-scanner)\n\n"), stderr );
  6361. +    lfputs( _("  -F, --configfile=FILE      Additional config file to load settings from.\n"), stderr );
  6362. +    lfputs( _("  -h, --help                 Show this help message.\n"), stderr );
  6363. +    lfputs( _("  -g, --geometry=GEOMETRY    Sets the output window size.\n"), stderr );
  6364. +    lfputs( _("  -i, --input=INPUTNUM       video4linux input number (defaults to 0).\n"), stderr );
  6365. +    lfputs( _("  -I, --inputwidth=SAMPLING  Horizontal resolution of input\n"
  6366. +              "                             (defaults to 720 pixels).\n"), stderr );
  6367. +    lfputs( _("  -k, --slave                Disables input handling in tvtime (slave mode).\n"), stderr );
  6368. +    lfputs( _("  -m, --fullscreen           Start tvtime in fullscreen mode.\n"), stderr );
  6369. +    lfputs( _("  -M, --window               Start tvtime in window mode.\n"), stderr );
  6370. +    lfputs( _("  -n, --norm=NORM            The norm to use for the input.  tvtime supports:\n"
  6371. +              "                             NTSC, NTSC-JP, SECAM, PAL, PAL-Nc, PAL-M,\n"
  6372. +              "                             PAL-N or PAL-60 (defaults to NTSC).\n"), stderr );
  6373. +    lfputs( _("  -s, --showdrops            Print stats on frame drops (for debugging).\n"), stderr );
  6374. +    lfputs( _("  -S, --saveoptions          Save command line options to the config file.\n"), stderr );
  6375. +    lfputs( _("  -t, --xmltv=FILE           Read XMLTV listings from the given file.\n"), stderr );
  6376. +    lfputs( _("  -l, --xmltvlanguage=LANG   Use XMLTV data in given language, if available.\n"), stderr );
  6377. +    lfputs( _("  -v, --verbose              Print debugging messages to stderr.\n"), stderr );
  6378. +    lfputs( _("  -X, --display=DISPLAY      Use the given X display to connect to.\n"), stderr );
  6379. +    lfputs( _("  -x, --mixer=<DEVICE[:CH]>|<DEVICE/CH>\n"
  6380. +              "                             The mixer device and channel to control. The first\n"
  6381. +              "                             variant sets the OSS mixer the second one ALSA.\n"
  6382. +              "                             (defaults to default/Line)\n\n"
  6383. +              "                             Valid channels for OSS are:\n"
  6384. +              "                                 vol, bass, treble, synth, pcm, speaker, line,\n"
  6385. +              "                                 mic, cd, mix, pcm2, rec, igain, ogain, line1,\n"
  6386. +              "                                 line2, line3, dig1, dig2, dig3, phin, phout,\n"
  6387. +              "                                 video, radio, monitor\n"), stderr );
  6388. +}
  6389. +
  6390. +static void print_config_usage( char **argv )
  6391. +{
  6392. +    lfprintf( stderr, _("usage: %s [OPTION]...\n\n"), argv[ 0 ] );
  6393. +    lfputs( _("  -a, --widescreen           16:9 mode.\n"), stderr );
  6394. +    lfputs( _("  -A, --nowidescreen         4:3 mode.\n"), stderr );
  6395. +    lfputs( _("  -b, --vbidevice=DEVICE     VBI device (defaults to /dev/vbi0).\n"), stderr );
  6396. +    lfputs( _("  -c, --channel=CHANNEL      Tune to the specified channel on startup.\n"), stderr );
  6397. +    lfputs( _("  -d, --device=DEVICE        video4linux device (defaults to /dev/video0).\n"), stderr );
  6398. +    lfputs( _("  -f, --frequencies=NAME     The frequency table to use for the tuner.\n"
  6399. +              "                             (defaults to us-cable).\n\n"
  6400. +              "                             Valid values are:\n"
  6401. +              "                                 us-cable\n"
  6402. +              "                                 us-cable100\n"
  6403. +              "                                 us-broadcast\n"
  6404. +              "                                 china-broadcast\n"
  6405. +              "                                 southafrica\n"
  6406. +              "                                 japan-cable\n"
  6407. +              "                                 japan-broadcast\n"
  6408. +              "                                 europe\n"
  6409. +              "                                 australia\n"
  6410. +              "                                 australia-optus\n"
  6411. +              "                                 newzealand\n"
  6412. +              "                                 france\n"
  6413. +              "                                 russia\n"
  6414. +              "                                 custom (first run tvtime-scanner)\n\n"), stderr );
  6415. +    lfputs( _("  -F, --configfile=FILE      Additional config file to load settings from.\n"), stderr );
  6416. +    lfputs( _("  -h, --help                 Show this help message.\n"), stderr );
  6417. +    lfputs( _("  -g, --geometry=GEOMETRY    Sets the output window size.\n"), stderr );
  6418. +    lfputs( _("  -i, --input=INPUTNUM       video4linux input number (defaults to 0).\n"), stderr );
  6419. +    lfputs( _("  -I, --inputwidth=SAMPLING  Horizontal resolution of input\n"
  6420. +              "                             (defaults to 720 pixels).\n"), stderr );
  6421. +    lfputs( _("  -m, --fullscreen           Start tvtime in fullscreen mode.\n"), stderr );
  6422. +    lfputs( _("  -M, --window               Start tvtime in window mode.\n"), stderr );
  6423. +    lfputs( _("  -n, --norm=NORM            The norm to use for the input.  tvtime supports:\n"
  6424. +              "                             NTSC, NTSC-JP, SECAM, PAL, PAL-Nc, PAL-M,\n"
  6425. +              "                             PAL-N or PAL-60 (defaults to NTSC).\n"), stderr );
  6426. +    lfputs( _("  -R, --priority=PRI         Sets the process priority to run tvtime at.\n"), stderr );
  6427. +    lfputs( _("  -t, --xmltv=FILE           Read XMLTV listings from the given file.\n"), stderr );
  6428. +    lfputs( _("  -l, --xmltvlanguage=LANG   Use XMLTV data in given language, if available.\n"), stderr );
  6429. +    lfputs( _("  -x, --mixer=<DEVICE[:CH]>|<DEVICE/CH>\n"
  6430. +              "                             The mixer device and channel to control. The first\n"
  6431. +              "                             variant sets the OSS mixer the second one ALSA.\n"
  6432. +              "                             (defaults to default/Line)\n\n"
  6433. +              "                             Valid channels for OSS are:\n"
  6434. +              "                                 vol, bass, treble, synth, pcm, speaker, line,\n"
  6435. +              "                                 mic, cd, mix, pcm2, rec, igain, ogain, line1,\n"
  6436. +              "                                 line2, line3, dig1, dig2, dig3, phin, phout,\n"
  6437. +              "                                 video, radio, monitor\n"), stderr );
  6438. +}
  6439. +
  6440. +static void print_scanner_usage( char **argv )
  6441. +{
  6442. +    lfprintf( stderr, _("usage: %s [OPTION]...\n\n"), argv[ 0 ]);
  6443. +    lfputs( _("  -d, --device=DEVICE        video4linux device (defaults to /dev/video0).\n"), stderr );
  6444. +    lfputs( _("  -F, --configfile=FILE      Additional config file to load settings from.\n"), stderr );
  6445. +    lfputs( _("  -h, --help                 Show this help message.\n"), stderr );
  6446. +    lfputs( _("  -i, --input=INPUTNUM       video4linux input number (defaults to 0).\n"), stderr );
  6447. +    lfputs( _("  -n, --norm=NORM            The norm to use for the input.  tvtime supports:\n"
  6448. +              "                             NTSC, NTSC-JP, SECAM, PAL, PAL-Nc, PAL-M,\n"
  6449. +              "                             PAL-N or PAL-60 (defaults to NTSC).\n"), stderr );
  6450. +}
  6451. +
  6452. +config_t *config_new( void )
  6453. +{
  6454. +    char *temp_dirname;
  6455. +    char *base;
  6456. +
  6457. +    config_t *ct = malloc( sizeof( config_t ) );
  6458. +    if( !ct ) {
  6459. +        return 0;
  6460. +    }
  6461. +
  6462. +    /* Default settings. */
  6463. +    ct->geometry = strdup( "0x576" );
  6464. +    ct->verbose = 0;
  6465. +    ct->aspect = 0;
  6466. +    ct->squarepixels = 1;
  6467. +    ct->debug = 0;
  6468. +    ct->fullscreen = 0;
  6469. +    ct->alwaysontop = 0;
  6470. +    ct->priority = -10;
  6471. +    ct->ntsc_mode = 0;
  6472. +    ct->send_fields = 0;
  6473. +    ct->fspos = 0;
  6474. +    ct->picsaverestore = 1;
  6475. +    ct->brightness = -1;
  6476. +    ct->contrast = -1;
  6477. +    ct->saturation = -1;
  6478. +    ct->hue = -1;
  6479. +    ct->invert = 0;
  6480. +    ct->cc = 0;
  6481. +    ct->mirror = 0;
  6482. +    ct->boost = -1;
  6483. +    ct->quiet_screenshots = 0;
  6484. +    ct->unmute_volume = -1;
  6485. +    ct->muted = 0;
  6486. +    ct->mute_on_exit = 0;
  6487. +    ct->show_taglines = 1;
  6488. +
  6489. +    memset( ct->keymap, 0, sizeof( ct->keymap ) );
  6490. +    memset( ct->keymap_arg, 0, sizeof( ct->keymap_arg ) );
  6491. +    memset( ct->keymapmenu, 0, sizeof( ct->keymapmenu ) );
  6492. +    memset( ct->keymapmenu_arg, 0, sizeof( ct->keymapmenu_arg ) );
  6493. +    memset( ct->buttonmap, 0, sizeof( ct->buttonmap ) );
  6494. +    memset( ct->buttonmap_arg, 0, sizeof( ct->buttonmap_arg ) );
  6495. +    memset( ct->buttonmapmenu, 0, sizeof( ct->buttonmapmenu ) );
  6496. +    memset( ct->buttonmapmenu_arg, 0, sizeof( ct->buttonmapmenu_arg ) );
  6497. +
  6498. +    ct->inputwidth = 720;
  6499. +    ct->inputnum = 0;
  6500. +    ct->v4ldev = strdup( "/dev/video0" );
  6501. +    ct->norm = strdup( "ntsc" );
  6502. +    ct->freq = strdup( "us-cable" );
  6503. +    temp_dirname = getenv( "HOME" );
  6504. +    if( temp_dirname ) {
  6505. +        ct->ssdir = strdup( temp_dirname );
  6506. +    } else {
  6507. +        ct->ssdir = 0;
  6508. +    }
  6509. +    ct->audiomode = strdup( "stereo" );
  6510. +    ct->xmltvfile = strdup( "none" );
  6511. +    ct->xmltvlanguage = strdup( "none" );
  6512. +    ct->timeformat = strdup( "%X" );
  6513. +    ct->channel_text_rgb = 0xffffff00; /* opaque yellow */
  6514. +    ct->other_text_rgb = 0xfff5deb3;   /* opaque wheat */
  6515. +
  6516. +    ct->uid = getuid();
  6517. +
  6518. +    ct->mixerdev = strdup( "default/Line" );
  6519. +
  6520. +    ct->deinterlace_method = strdup( "GreedyH" );
  6521. +    ct->check_freq_present = 1;
  6522. +
  6523. +    ct->use_xds = 0;
  6524. +    ct->vbidev = strdup( "/dev/vbi0" );
  6525. +
  6526. +    ct->start_channel = 1;
  6527. +    ct->prev_channel = 1;
  6528. +    ct->framerate = FRAMERATE_FULL;
  6529. +    ct->slave_mode = 0;
  6530. +
  6531. +    ct->overscan = 0.0;
  6532. +
  6533. +    ct->config_filename = 0;
  6534. +    ct->doc = 0;
  6535. +
  6536. +    /* Default key bindings. */
  6537. +    ct->keymap[ 0 ] = TVTIME_NOCOMMAND;
  6538. +    ct->keymap[ I_ESCAPE ] = TVTIME_QUIT;
  6539. +    ct->keymap[ 'q' ] = TVTIME_QUIT;
  6540. +    ct->keymap[ I_UP ] = TVTIME_UP;
  6541. +    ct->keymap[ I_DOWN ] = TVTIME_DOWN;
  6542. +    ct->keymap[ I_LEFT ] = TVTIME_LEFT;
  6543. +    ct->keymap[ I_RIGHT ] = TVTIME_RIGHT;
  6544. +    ct->keymap[ I_BACKSPACE ] = TVTIME_CHANNEL_PREV;
  6545. +    ct->keymap[ 'c' ] = TVTIME_TOGGLE_CC;
  6546. +    ct->keymap[ 'm' ] = TVTIME_TOGGLE_MUTE;
  6547. +    ct->keymap[ '-' ] = TVTIME_MIXER_DOWN;
  6548. +    ct->keymap[ '+' ] = TVTIME_MIXER_UP;
  6549. +    ct->keymap[ ' ' ] = TVTIME_AUTO_ADJUST_PICT;
  6550. +    ct->keymap[ I_ENTER ] = TVTIME_ENTER;
  6551. +    ct->keymap[ I_F1 ] = TVTIME_SHOW_MENU;
  6552. +    ct->keymap[ 'h' ] = TVTIME_SHOW_MENU;
  6553. +    ct->keymap[ '\t' ] = TVTIME_SHOW_MENU;
  6554. +    ct->keymap[ I_F5 ] = TVTIME_PICTURE;
  6555. +    ct->keymap[ I_F6 ] = TVTIME_PICTURE_DOWN;
  6556. +    ct->keymap[ I_F7 ] = TVTIME_PICTURE_UP;
  6557. +    ct->keymap[ 'd' ] = TVTIME_SHOW_STATS;
  6558. +    ct->keymap[ 'a' ] = TVTIME_TOGGLE_ASPECT;
  6559. +    ct->keymap[ 'f' ] = TVTIME_TOGGLE_FULLSCREEN;
  6560. +    ct->keymap[ 'i' ] = TVTIME_TOGGLE_INPUT;
  6561. +    ct->keymap[ 's' ] = TVTIME_SCREENSHOT;
  6562. +    ct->keymap[ ',' ] = TVTIME_MIXER_TOGGLE_MUTE;
  6563. +    ct->keymap[ 'e' ] = TVTIME_TOGGLE_AUDIO_MODE;
  6564. +    ct->keymap[ '/' ] = TVTIME_AUTO_ADJUST_WINDOW;
  6565. +    ct->keymap[ 'v' ] = TVTIME_TOGGLE_ALWAYSONTOP;
  6566. +    ct->keymap[ '0' ] = TVTIME_CHANNEL_0;
  6567. +    ct->keymap[ '1' ] = TVTIME_CHANNEL_1;
  6568. +    ct->keymap[ '2' ] = TVTIME_CHANNEL_2;
  6569. +    ct->keymap[ '3' ] = TVTIME_CHANNEL_3;
  6570. +    ct->keymap[ '4' ] = TVTIME_CHANNEL_4;
  6571. +    ct->keymap[ '5' ] = TVTIME_CHANNEL_5;
  6572. +    ct->keymap[ '6' ] = TVTIME_CHANNEL_6;
  6573. +    ct->keymap[ '7' ] = TVTIME_CHANNEL_7;
  6574. +    ct->keymap[ '8' ] = TVTIME_CHANNEL_8;
  6575. +    ct->keymap[ '9' ] = TVTIME_CHANNEL_9;
  6576. +
  6577. +    ct->buttonmap[ 1 ] = TVTIME_DISPLAY_INFO;
  6578. +    ct->buttonmap[ 2 ] = TVTIME_TOGGLE_MUTE;
  6579. +    ct->buttonmap[ 3 ] = TVTIME_SHOW_MENU;
  6580. +    ct->buttonmap[ 4 ] = TVTIME_CHANNEL_INC;
  6581. +    ct->buttonmap[ 5 ] = TVTIME_CHANNEL_DEC;
  6582. +
  6583. +    /* Menu keys. */
  6584. +    ct->keymapmenu[ I_UP ] = TVTIME_MENU_UP;
  6585. +    ct->keymapmenu[ I_DOWN ] = TVTIME_MENU_DOWN;
  6586. +    ct->keymapmenu[ I_LEFT ] = TVTIME_MENU_BACK;
  6587. +    ct->keymapmenu[ I_RIGHT ] = TVTIME_MENU_ENTER;
  6588. +    ct->keymapmenu[ I_ENTER ] = TVTIME_MENU_ENTER;
  6589. +    ct->keymapmenu[ I_F1 ] = TVTIME_MENU_EXIT;
  6590. +    ct->keymapmenu[ '\t' ] = TVTIME_MENU_EXIT;
  6591. +    ct->keymapmenu[ 'q' ] = TVTIME_MENU_EXIT;
  6592. +    ct->keymapmenu[ I_ESCAPE ] = TVTIME_MENU_EXIT;
  6593. +    ct->buttonmapmenu[ 1 ] = TVTIME_MENU_ENTER;
  6594. +    ct->buttonmapmenu[ 3 ] = TVTIME_MENU_ENTER;
  6595. +    ct->buttonmapmenu[ 4 ] = TVTIME_MENU_UP;
  6596. +    ct->buttonmapmenu[ 5 ] = TVTIME_MENU_DOWN;
  6597. +
  6598. +    /* Make the ~/.tvtime directory every time on startup, to be safe. */
  6599. +    if( asprintf( &temp_dirname, "%s/.tvtime", getenv( "HOME" ) ) < 0 ) {
  6600. +        /* FIXME: Clean up ?? */
  6601. +        return 0;
  6602. +    }
  6603. +    mkdir_and_force_owner( temp_dirname, ct->uid, getgid() );
  6604. +    free( temp_dirname );
  6605. +
  6606. +    /* First read in global settings. */
  6607. +    asprintf( &base, "%s/tvtime.xml", CONFDIR );
  6608. +    if( file_is_openable_for_read( base ) ) {
  6609. +        lfprintf( stderr, _("Reading configuration from %s\n"), base );
  6610. +        conf_xml_parse( ct, base );
  6611. +    }
  6612. +    free( base );
  6613. +
  6614. +    /* Then read in local settings. */
  6615. +    asprintf( &base, "%s/.tvtime/tvtime.xml", getenv( "HOME" ) );
  6616. +    ct->config_filename = strdup( base );
  6617. +    if( file_is_openable_for_read( base ) ) {
  6618. +        lfprintf( stderr, _("Reading configuration from %s\n"), base );
  6619. +        conf_xml_parse( ct, base );
  6620. +    }
  6621. +    free( base );
  6622. +
  6623. +    return ct;
  6624. +}
  6625. +
  6626. +int config_parse_tvtime_command_line( config_t *ct, int argc, char **argv )
  6627. +{
  6628. +    static struct option long_options[] = {
  6629. +        { "help", 0, 0, 'h' },
  6630. +        { "verbose", 0, 0, 'v' },
  6631. +        { "geometry", 1, 0, 'g' },
  6632. +        { "saveoptions", 0, 0, 'S' },
  6633. +        { "inputwidth", 1, 0, 'I' },
  6634. +        { "driver", 1, 0, 'D' },
  6635. +        { "input", 1, 0, 'i' },
  6636. +        { "channel", 1, 0, 'c' },
  6637. +        { "configfile", 1, 0, 'F' },
  6638. +        { "norm", 1, 0, 'n' },
  6639. +        { "frequencies", 1, 0, 'f' },
  6640. +        { "vbidevice", 1, 0, 'b' },
  6641. +        { "device", 1, 0, 'd' },
  6642. +        { "mixer", 1, 0, 'x' },
  6643. +        { "showdrops", 0, 0, 's' },
  6644. +        { "fullscreen", 0, 0, 'm' },
  6645. +        { "window", 0, 0, 'M' },
  6646. +        { "slave", 0, 0, 'k' },
  6647. +        { "widescreen", 0, 0, 'a' },
  6648. +        { "nowidescreen", 0, 0, 'A' },
  6649. +        { "xmltv", 1, 0, 't' },
  6650. +        { "xmltvlanguage", 1, 0, 'l' },
  6651. +        { "display", 1, 0, 'X' },
  6652. +        { "version", 0, 0, 'Q' },
  6653. +        { 0, 0, 0, 0 }
  6654. +    };
  6655. +    int option_index = 0;
  6656. +    int saveoptions = 0;
  6657. +    int filename_specified = 0;
  6658. +    int c;
  6659. +
  6660. +    if( argc ) {
  6661. +        while( (c = getopt_long( argc, argv, "aAhkmMsSvF:r:g:I:d:b:i:c:n:D:f:x:X:t:l:Qg:",
  6662. +                long_options, &option_index )) != -1 ) {
  6663. +            switch( c ) {
  6664. +            case 'a': ct->aspect = 1; break;
  6665. +            case 'A': ct->aspect = 0; break;
  6666. +            case 'k': ct->slave_mode = 1; break;
  6667. +            case 'm': ct->fullscreen = 1; break;
  6668. +            case 'M': ct->fullscreen = 0; break;
  6669. +            case 's': ct->debug = 1; break;
  6670. +            case 'S': saveoptions = 1; break;
  6671. +            case 'v': ct->verbose = 1; break;
  6672. +            case 't': if( ct->xmltvfile ) { free( ct->xmltvfile ); }
  6673. +                      ct->xmltvfile = expand_user_path( optarg ); break;
  6674. +            case 'l': if( ct->xmltvlanguage ) { free( ct->xmltvlanguage ); }
  6675. +                      ct->xmltvlanguage = strdup( optarg ); break;
  6676. +            case 'F': if( ct->config_filename ) free( ct->config_filename );
  6677. +                      filename_specified = 1;
  6678. +                      ct->config_filename = expand_user_path( optarg );
  6679. +                      if( ct->config_filename ) {
  6680. +                          lfprintf
  6681. +                              ( stderr,
  6682. +                                _("Reading configuration from %s\n"),
  6683. +                                ct->config_filename );
  6684. +                          conf_xml_parse( ct, ct->config_filename );
  6685. +                      }
  6686. +                      break;
  6687. +            case 'x': if( ct->mixerdev ) { free( ct->mixerdev ); }
  6688. +                      ct->mixerdev = strdup( optarg ); break;
  6689. +            case 'X': setenv( "DISPLAY", optarg, 1 ); break;
  6690. +            case 'g': if( ct->geometry ) { free( ct->geometry ); }
  6691. +                      ct->geometry = strdup( optarg ); break;
  6692. +            case 'I': ct->inputwidth = atoi( optarg ); break;
  6693. +            case 'd': free( ct->v4ldev ); ct->v4ldev = strdup( optarg ); break;
  6694. +            case 'b': free( ct->vbidev ); ct->vbidev = strdup( optarg ); break;
  6695. +            case 'i': ct->inputnum = atoi( optarg ); break;
  6696. +            case 'c': ct->prev_channel = ct->start_channel;
  6697. +                      ct->start_channel = atoi( optarg ); break;
  6698. +            case 'n': free( ct->norm ); ct->norm = strdup( optarg ); break;
  6699. +            case 'f': free( ct->freq ); ct->freq = strdup( optarg ); break;
  6700. +            case 'Q': print_copyright(); return 0;
  6701. +            default:
  6702. +                print_usage( argv );
  6703. +                return 0;
  6704. +            }
  6705. +        }
  6706. +    }
  6707. +
  6708. +    if( !filename_specified ) {
  6709. +        char *fifofile = get_tvtime_fifo_filename( config_get_uid( ct ) );
  6710. +        int fifofd;
  6711. +
  6712. +        if( !fifofile ) {
  6713. +            lfprintf( stderr, _("%s: Cannot allocate memory.\n"), argv[ 0 ] );
  6714. +            return 0;
  6715. +        }
  6716. +
  6717. +        fifofd = open( fifofile, O_WRONLY | O_NONBLOCK );
  6718. +        if( fifofd >= 0 ) {
  6719. +            lfprintf( stderr,
  6720. +                      _("Cannot run two instances of tvtime with the same configuration.\n") );
  6721. +            return 0;
  6722. +        }
  6723. +        close( fifofd );
  6724. +    }
  6725. +
  6726. +
  6727. +    ct->doc = configsave_open( ct->config_filename );
  6728. +
  6729. +    if( ct->doc && saveoptions ) {
  6730. +        char tempstring[ 32 ];
  6731. +        lfputs( _("Saving command line options.\n"), stderr );
  6732. +
  6733. +        /**
  6734. +         * Options that aren't specified on the command line
  6735. +         * will match the config file anyway, so save everything that
  6736. +         * you can save on the command line.
  6737. +         */
  6738. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->aspect );
  6739. +        config_save( ct, "Widescreen", tempstring );
  6740. +
  6741. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->fullscreen );
  6742. +        config_save( ct, "Fullscreen", tempstring );
  6743. +
  6744. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->verbose );
  6745. +        config_save( ct, "Verbose", tempstring );
  6746. +
  6747. +        config_save( ct, "WindowGeometry", ct->geometry );
  6748. +
  6749. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->inputwidth );
  6750. +        config_save( ct, "InputWidth", tempstring );
  6751. +
  6752. +        config_save( ct, "V4LDevice", ct->v4ldev );
  6753. +        config_save( ct, "VBIDevice", ct->vbidev );
  6754. +
  6755. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->inputnum );
  6756. +        config_save( ct, "V4LInput", tempstring );
  6757. +
  6758. +        config_save( ct, "Norm", ct->norm );
  6759. +        config_save( ct, "Frequencies", ct->freq );
  6760. +
  6761. +        config_save( ct, "MixerDevice", ct->mixerdev );
  6762. +
  6763. +        config_save( ct, "XMLTVFile", ct->xmltvfile );
  6764. +        config_save( ct, "XMLTVLanguage", ct->xmltvlanguage );
  6765. +    }
  6766. +
  6767. +    return 1;
  6768. +}
  6769. +
  6770. +int config_parse_tvtime_config_command_line( config_t *ct, int argc, char **argv )
  6771. +{
  6772. +    static struct option long_options[] = {
  6773. +        { "help", 0, 0, 'h' },
  6774. +        { "geometry", 1, 0, 'g' },
  6775. +        { "inputwidth", 1, 0, 'I' },
  6776. +        { "driver", 1, 0, 'D' },
  6777. +        { "input", 2, 0, 'i' },
  6778. +        { "channel", 1, 0, 'c' },
  6779. +        { "configfile", 1, 0, 'F' },
  6780. +        { "norm", 2, 0, 'n' },
  6781. +        { "frequencies", 2, 0, 'f' },
  6782. +        { "vbidevice", 2, 0, 'b' },
  6783. +        { "device", 2, 0, 'd' },
  6784. +        { "mixer", 1, 0, 'x' },
  6785. +        { "fullscreen", 0, 0, 'm' },
  6786. +        { "window", 0, 0, 'M' },
  6787. +        { "widescreen", 0, 0, 'a' },
  6788. +        { "nowidescreen", 0, 0, 'A' },
  6789. +        { "xmltv", 2, 0, 't' },
  6790. +        { "xmltvlanguage", 2, 0, 'l' },
  6791. +        { "priority", 2, 0, 'R' },
  6792. +        { 0, 0, 0, 0 }
  6793. +    };
  6794. +    int option_index = 0;
  6795. +    int filename_specified = 0;
  6796. +    int c;
  6797. +
  6798. +    if( argc == 1 ) {
  6799. +        print_config_usage( argv );
  6800. +        return 0;
  6801. +    }
  6802. +
  6803. +    while( (c = getopt_long( argc, argv, "aAhmMF:g:I:d:b:i:c:n:D:f:x:t:l:R:",
  6804. +            long_options, &option_index )) != -1 ) {
  6805. +        switch( c ) {
  6806. +        case 'a': ct->aspect = 1; break;
  6807. +        case 'A': ct->aspect = 0; break;
  6808. +        case 'm': ct->fullscreen = 1; break;
  6809. +        case 'M': ct->fullscreen = 0; break;
  6810. +        case 'F': if( ct->config_filename ) free( ct->config_filename );
  6811. +                  filename_specified = 1;
  6812. +                  ct->config_filename = expand_user_path( optarg );
  6813. +                  if( ct->config_filename ) {
  6814. +                      lfprintf( stderr,
  6815. +                                _("Reading configuration from %s\n"),
  6816. +                                ct->config_filename );
  6817. +                      conf_xml_parse( ct, ct->config_filename );
  6818. +                  }
  6819. +                  break;
  6820. +        case 'x': if( ct->mixerdev ) { free( ct->mixerdev ); }
  6821. +                  ct->mixerdev = strdup( optarg ); break;
  6822. +        case 'g': if( ct->geometry ) { free( ct->geometry ); }
  6823. +                  ct->geometry = strdup( optarg ); break;
  6824. +        case 'I': ct->inputwidth = atoi( optarg ); break;
  6825. +        case 'd': if( !optarg ) {
  6826. +                      fprintf( stdout, "V4LDevice:%s\n",
  6827. +                               config_get_v4l_device( ct ) );
  6828. +                  } else {
  6829. +                      free( ct->v4ldev );
  6830. +                      ct->v4ldev = strdup( optarg );
  6831. +                  }
  6832. +                  break;
  6833. +        case 'b': if( !optarg ) {
  6834. +                      fprintf( stdout, "VBIDevice:%s\n",
  6835. +                               config_get_vbi_device( ct ) );
  6836. +                  } else {
  6837. +                      free( ct->vbidev );
  6838. +                      ct->vbidev = strdup( optarg );
  6839. +                  }
  6840. +                  break;
  6841. +        case 'i': if( !optarg ) {
  6842. +                      fprintf( stdout, "V4LInput:%d\n",
  6843. +                               config_get_inputnum( ct ) );
  6844. +                  } else {
  6845. +                      ct->inputnum = atoi( optarg );
  6846. +                  }
  6847. +                  break;
  6848. +        case 'c': ct->prev_channel = ct->start_channel;
  6849. +                  ct->start_channel = atoi( optarg ); break;
  6850. +        case 't': if( !optarg ) {
  6851. +                      fprintf( stdout, "XMLTVFile:%s\n",
  6852. +                               config_get_xmltv_file( ct ) );
  6853. +                  } else {
  6854. +                      if( ct->xmltvfile ) free( ct->xmltvfile );
  6855. +                      ct->xmltvfile = expand_user_path( optarg );
  6856. +                  }
  6857. +                  break;
  6858. +        case 'l': if( !optarg ) {
  6859. +                      fprintf( stdout, "XMLTVLanguage:%s\n",
  6860. +                               config_get_xmltv_language( ct ) );
  6861. +                  } else {
  6862. +                      if( ct->xmltvlanguage ) free( ct->xmltvlanguage );
  6863. +                      ct->xmltvlanguage = strdup( optarg );
  6864. +                  }
  6865. +                  break;
  6866. +        case 'n': if( !optarg ) {
  6867. +                      fprintf( stdout, "Norm:%s\n", config_get_v4l_norm( ct ) );
  6868. +                  } else {
  6869. +                      free( ct->norm );
  6870. +                      ct->norm = strdup( optarg );
  6871. +                  }
  6872. +                  break;
  6873. +        case 'f': if( !optarg ) {
  6874. +                      fprintf( stdout, "Frequencies:%s\n",
  6875. +                               config_get_v4l_freq( ct ) );
  6876. +                  } else {
  6877. +                      free( ct->freq );
  6878. +                      ct->freq = strdup( optarg );
  6879. +                  }
  6880. +                  break;
  6881. +        case 'R': if( !optarg ) {
  6882. +                      fprintf( stdout, "Priority:%d\n",
  6883. +                               config_get_priority( ct ) );
  6884. +                  } else {
  6885. +                      ct->priority = atoi( optarg );
  6886. +                  }
  6887. +                  break;
  6888. +        default:
  6889. +            print_config_usage( argv );
  6890. +            return 0;
  6891. +        }
  6892. +    }
  6893. +
  6894. +    if( !filename_specified ) {
  6895. +        char *fifofile = get_tvtime_fifo_filename( config_get_uid( ct ) );
  6896. +        int fifofd;
  6897. +
  6898. +        if( !fifofile ) {
  6899. +            lfprintf( stderr, _("%s: Cannot allocate memory.\n"), argv[ 0 ] );
  6900. +            return 0;
  6901. +        }
  6902. +
  6903. +        fifofd = open( fifofile, O_WRONLY | O_NONBLOCK );
  6904. +        if( fifofd >= 0 ) {
  6905. +            lfprintf( stderr,
  6906. +                      _("Cannot update configuration while tvtime running.\n") );
  6907. +            return 0;
  6908. +        }
  6909. +        close( fifofd );
  6910. +    }
  6911. +
  6912. +    ct->doc = configsave_open( ct->config_filename );
  6913. +
  6914. +    if( ct->doc ) {
  6915. +        char tempstring[ 32 ];
  6916. +
  6917. +        /**
  6918. +         * Options that aren't specified on the command line
  6919. +         * will match the config file anyway, so save everything that
  6920. +         * you can save on the command line.
  6921. +         */
  6922. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->aspect );
  6923. +        config_save( ct, "Widescreen", tempstring );
  6924. +
  6925. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->fullscreen );
  6926. +        config_save( ct, "Fullscreen", tempstring );
  6927. +
  6928. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->verbose );
  6929. +        config_save( ct, "Verbose", tempstring );
  6930. +
  6931. +        config_save( ct, "WindowGeometry", ct->geometry );
  6932. +
  6933. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->inputwidth );
  6934. +        config_save( ct, "InputWidth", tempstring );
  6935. +
  6936. +        config_save( ct, "V4LDevice", ct->v4ldev );
  6937. +
  6938. +        config_save( ct, "VBIDevice", ct->vbidev );
  6939. +
  6940. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->inputnum );
  6941. +        config_save( ct, "V4LInput", tempstring );
  6942. +
  6943. +        config_save( ct, "Norm", ct->norm );
  6944. +        config_save( ct, "Frequencies", ct->freq );
  6945. +
  6946. +        config_save( ct, "MixerDevice", ct->mixerdev );
  6947. +
  6948. +        config_save( ct, "XMLTVFile", ct->xmltvfile );
  6949. +        config_save( ct, "XMLTVLanguage", ct->xmltvlanguage );
  6950. +
  6951. +        snprintf( tempstring, sizeof( tempstring ), "%d", ct->priority );
  6952. +        config_save( ct, "ProcessPriority", tempstring );
  6953. +    }
  6954. +
  6955. +    return 1;
  6956. +}
  6957. +
  6958. +int config_parse_tvtime_scanner_command_line( config_t *ct, int argc,
  6959. +                                              char **argv )
  6960. +{
  6961. +    static struct option long_options[] = {
  6962. +        { "help", 0, 0, 'h' },
  6963. +        { "height", 1, 0, 'H' },
  6964. +        { "input", 1, 0, 'i' },
  6965. +        { "configfile", 1, 0, 'F' },
  6966. +        { "norm", 1, 0, 'n' },
  6967. +        { "device", 1, 0, 'd' },
  6968. +        { 0, 0, 0, 0 }
  6969. +    };
  6970. +    int option_index = 0;
  6971. +    int c;
  6972. +
  6973. +    while( (c = getopt_long( argc, argv, "hF:d:i:n:",
  6974. +            long_options, &option_index )) != -1 ) {
  6975. +        switch( c ) {
  6976. +        case 'F': if( ct->config_filename ) free( ct->config_filename );
  6977. +                  ct->config_filename = expand_user_path( optarg );
  6978. +                  if( ct->config_filename ) {
  6979. +                      lfprintf( stderr,
  6980. +                                _("Reading configuration from %s\n"),
  6981. +                                ct->config_filename );
  6982. +                      conf_xml_parse( ct, ct->config_filename );
  6983. +                  }
  6984. +                  break;
  6985. +        case 'd': free( ct->v4ldev ); ct->v4ldev = strdup( optarg ); break;
  6986. +        case 'i': ct->inputnum = atoi( optarg ); break;
  6987. +        case 'n': free( ct->norm ); ct->norm = strdup( optarg ); break;
  6988. +        default:
  6989. +            print_scanner_usage( argv );
  6990. +            return 0;
  6991. +        }
  6992. +    }
  6993. +
  6994. +    return 1;
  6995. +}
  6996. +
  6997. +
  6998. +
  6999. +void config_free_data( config_t *ct )
  7000. +{
  7001. +    if( ct->doc ) xmlFreeDoc( ct->doc );
  7002. +    if( ct->geometry ) free( ct->geometry );
  7003. +    if( ct->v4ldev ) free( ct->v4ldev );
  7004. +    if( ct->norm ) free( ct->norm );
  7005. +    if( ct->freq ) free( ct->freq );
  7006. +    if( ct->ssdir ) free( ct->ssdir );
  7007. +    if( ct->audiomode ) free( ct->audiomode );
  7008. +    if( ct->xmltvfile ) free( ct->xmltvfile );
  7009. +    if( ct->xmltvlanguage ) free( ct->xmltvlanguage );
  7010. +    if( ct->timeformat ) free( ct->timeformat );
  7011. +    if( ct->mixerdev ) free( ct->mixerdev );
  7012. +    if( ct->vbidev ) free( ct->vbidev );
  7013. +    if( ct->config_filename ) free( ct->config_filename );
  7014. +    if( ct->deinterlace_method ) free( ct->deinterlace_method );
  7015. +}
  7016. +
  7017. +void config_delete( config_t *ct )
  7018. +{
  7019. +    int i;
  7020. +
  7021. +    for( i = 0; i < 8 * MAX_KEYSYMS; i++ ) {
  7022. +        if( ct->keymap_arg[ i ] ) free( ct->keymap_arg[ i ] );
  7023. +        if( ct->keymapmenu_arg[ i ] ) free( ct->keymapmenu_arg[ i ] );
  7024. +    }
  7025. +
  7026. +    for( i = 0; i < MAX_BUTTONS; i++ ) {
  7027. +        if( ct->buttonmap_arg[ i ] ) free( ct->buttonmap_arg[ i ] );
  7028. +        if( ct->buttonmapmenu_arg[ i ] ) free( ct->buttonmapmenu_arg[ i ] );
  7029. +    }
  7030. +
  7031. +    config_free_data( ct );
  7032. +    free( ct );
  7033. +}
  7034. +
  7035. +void config_save( config_t *ct, const char *name, const char *value )
  7036. +{
  7037. +    xmlNodePtr top, node;
  7038. +
  7039. +    if( !ct->doc ) return;
  7040. +
  7041. +    top = xmlDocGetRootElement( ct->doc );
  7042. +    if( !top ) {
  7043. +        return;
  7044. +    }
  7045. +
  7046. +    node = find_option( top->xmlChildrenNode, name );
  7047. +    if( !node ) {
  7048. +        node = xmlNewTextChild( top, 0, BAD_CAST "option", 0 );
  7049. +        xmlNewProp( node, BAD_CAST "name", BAD_CAST name );
  7050. +        xmlNewProp( node, BAD_CAST "value", BAD_CAST value );
  7051. +    } else {
  7052. +        xmlSetProp( node, BAD_CAST "value", BAD_CAST value );
  7053. +    }
  7054. +
  7055. +    xmlKeepBlanksDefault( 0 );
  7056. +    xmlSaveFormatFile( ct->config_filename, ct->doc, 1 );
  7057. +}
  7058. +
  7059. +int config_key_to_command( config_t *ct, int key )
  7060. +{
  7061. +    if( key ) {
  7062. +        if( ct->keymap[ MAX_KEYSYMS*((key & 0x70000)>>16) + (key & 0x1ff) ] ) {
  7063. +            return ct->keymap[ MAX_KEYSYMS*((key & 0x70000)>>16) + (key & 0x1ff) ];
  7064. +        }
  7065. +
  7066. +        if( isalnum( key & 0x1ff ) ) {
  7067. +            return TVTIME_CHANNEL_CHAR;
  7068. +        }
  7069. +    }
  7070. +        
  7071. +    return TVTIME_NOCOMMAND;
  7072. +}
  7073. +
  7074. +const char *config_key_to_command_argument( config_t *ct, int key )
  7075. +{
  7076. +    if( key ) {
  7077. +        if( ct->keymap_arg[ MAX_KEYSYMS*((key & 0x70000)>>16) + (key & 0x1ff) ] ) {
  7078. +            return ct->keymap_arg[ MAX_KEYSYMS*((key & 0x70000)>>16) + (key & 0x1ff) ];
  7079. +        }
  7080. +    }
  7081. +    return 0;
  7082. +}
  7083. +
  7084. +int config_key_to_menu_command( config_t *ct, int key )
  7085. +{
  7086. +    if( key ) {
  7087. +        int cmd;
  7088. +
  7089. +        if( ct->keymapmenu[ MAX_KEYSYMS*((key & 0x70000)>>16) + (key & 0x1ff) ] ) {
  7090. +            return ct->keymapmenu[ MAX_KEYSYMS*((key & 0x70000)>>16) + (key & 0x1ff) ];
  7091. +        }
  7092. +
  7093. +        /* Fall back to standard commands. */
  7094. +        cmd = config_key_to_command( ct, key );
  7095. +        if( cmd != TVTIME_NOCOMMAND ) {
  7096. +            return cmd;
  7097. +        }
  7098. +
  7099. +        if( isalnum( key & 0x1ff ) ) {
  7100. +            return TVTIME_CHANNEL_CHAR;
  7101. +        }
  7102. +    }
  7103. +        
  7104. +    return TVTIME_NOCOMMAND;
  7105. +}
  7106. +
  7107. +const char *config_key_to_menu_command_argument( config_t *ct, int key )
  7108. +{
  7109. +    if( key ) {
  7110. +        if( ct->keymapmenu_arg[ MAX_KEYSYMS*((key & 0x70000)>>16) + (key & 0x1ff) ] ) {
  7111. +            return ct->keymapmenu_arg[ MAX_KEYSYMS*((key & 0x70000)>>16) + (key & 0x1ff) ];
  7112. +        }
  7113. +
  7114. +        return config_key_to_command_argument( ct, key );
  7115. +    }
  7116. +
  7117. +    return 0;
  7118. +}
  7119. +
  7120. +int config_command_to_key( config_t *ct, int command )
  7121. +{
  7122. +    int i;
  7123. +
  7124. +    for( i = 0; i < 8 * MAX_KEYSYMS; i++ ) {
  7125. +        if( ct->keymap[ i ] == command ) return i;
  7126. +    }
  7127. +
  7128. +    return 0;
  7129. +}
  7130. +
  7131. +int config_button_to_command( config_t *ct, int button )
  7132. +{
  7133. +    if( button < 0 || button >= MAX_BUTTONS ) {
  7134. +        return 0;
  7135. +    } else {
  7136. +        return ct->buttonmap[ button ];
  7137. +    }
  7138. +}
  7139. +
  7140. +const char *config_button_to_command_argument( config_t *ct, int button )
  7141. +{
  7142. +    if( button < 0 || button >= MAX_BUTTONS ) {
  7143. +        return 0;
  7144. +    } else {
  7145. +        return ct->buttonmap_arg[ button ];
  7146. +    }
  7147. +}
  7148. +
  7149. +int config_button_to_menu_command( config_t *ct, int button )
  7150. +{
  7151. +    if( button < 0 || button >= MAX_BUTTONS ) {
  7152. +        return 0;
  7153. +    } else {
  7154. +        if( ct->buttonmapmenu[ button ] ) {
  7155. +            return ct->buttonmapmenu[ button ];
  7156. +        } else {
  7157. +            return ct->buttonmap[ button ];
  7158. +        }
  7159. +    }
  7160. +}
  7161. +
  7162. +const char *config_button_to_menu_command_argument( config_t *ct, int button )
  7163. +{
  7164. +    if( button < 0 || button >= MAX_BUTTONS ) {
  7165. +        return 0;
  7166. +    } else {
  7167. +        if( ct->buttonmapmenu_arg[ button ] ) {
  7168. +            return ct->buttonmapmenu_arg[ button ];
  7169. +        } else {
  7170. +            return ct->buttonmap_arg[ button ];
  7171. +        }
  7172. +    }
  7173. +}
  7174. +
  7175. +int config_get_verbose( config_t *ct )
  7176. +{
  7177. +    return ct->verbose;
  7178. +}
  7179. +
  7180. +int config_get_send_fields( config_t *ct )
  7181. +{
  7182. +    return ct->send_fields;
  7183. +}
  7184. +
  7185. +int config_get_debug( config_t *ct )
  7186. +{
  7187. +    return ct->debug;
  7188. +}
  7189. +
  7190. +const char *config_get_geometry( config_t *ct )
  7191. +{
  7192. +    return ct->geometry;
  7193. +}
  7194. +
  7195. +int config_get_inputwidth( config_t *ct )
  7196. +{
  7197. +    return ct->inputwidth;
  7198. +}
  7199. +
  7200. +int config_get_aspect( config_t *ct )
  7201. +{
  7202. +    return ct->aspect;
  7203. +}
  7204. +
  7205. +int config_get_start_channel( config_t *ct )
  7206. +{
  7207. +    return ct->start_channel;
  7208. +}
  7209. +
  7210. +int config_get_prev_channel( config_t *ct )
  7211. +{
  7212. +    return ct->prev_channel;
  7213. +}
  7214. +
  7215. +int config_get_inputnum( config_t *ct )
  7216. +{
  7217. +    return ct->inputnum;
  7218. +}
  7219. +
  7220. +const char *config_get_deinterlace_method( config_t *ct )
  7221. +{
  7222. +    return ct->deinterlace_method;
  7223. +}
  7224. +
  7225. +const char *config_get_v4l_device( config_t *ct )
  7226. +{
  7227. +    return ct->v4ldev;
  7228. +}
  7229. +
  7230. +const char *config_get_v4l_norm( config_t *ct )
  7231. +{
  7232. +    return ct->norm;
  7233. +}
  7234. +
  7235. +int config_get_fullscreen( config_t *ct )
  7236. +{
  7237. +    return ct->fullscreen;
  7238. +}
  7239. +
  7240. +int config_get_alwaysontop( config_t *ct )
  7241. +{
  7242. +    return ct->alwaysontop;
  7243. +}
  7244. +
  7245. +int config_get_priority( config_t *ct )
  7246. +{
  7247. +    return ct->priority;
  7248. +}
  7249. +
  7250. +const char *config_get_v4l_freq( config_t *ct )
  7251. +{
  7252. +    return ct->freq;
  7253. +}
  7254. +
  7255. +const char *config_get_vbi_device( config_t *ct )
  7256. +{
  7257. +    return ct->vbidev;
  7258. +}
  7259. +
  7260. +const char *config_get_timeformat( config_t *ct )
  7261. +{
  7262. +    return ct->timeformat;
  7263. +}
  7264. +
  7265. +unsigned int config_get_channel_text_rgb( config_t *ct )
  7266. +{
  7267. +    return ct->channel_text_rgb;
  7268. +}
  7269. +
  7270. +unsigned int config_get_other_text_rgb( config_t *ct )
  7271. +{
  7272. +    return ct->other_text_rgb;
  7273. +}
  7274. +
  7275. +uid_t config_get_uid( config_t *ct )
  7276. +{
  7277. +    return ct->uid;
  7278. +}
  7279. +
  7280. +int config_get_usexds( config_t *ct )
  7281. +{
  7282. +    return ct->use_xds;
  7283. +}
  7284. +
  7285. +int config_get_check_freq_present( config_t *ct )
  7286. +{
  7287. +    return ct->check_freq_present;
  7288. +}
  7289. +
  7290. +double config_get_overscan( config_t *ct )
  7291. +{
  7292. +    return ct->overscan;
  7293. +}
  7294. +
  7295. +int config_get_ntsc_cable_mode( config_t *ct )
  7296. +{
  7297. +    return ct->ntsc_mode;
  7298. +}
  7299. +
  7300. +const char *config_get_screenshot_dir( config_t *ct )
  7301. +{
  7302. +    return ct->ssdir;
  7303. +}
  7304. +
  7305. +int config_get_framerate_mode( config_t *ct )
  7306. +{
  7307. +    return ct->framerate;
  7308. +}
  7309. +
  7310. +int config_get_slave_mode( config_t *ct )
  7311. +{
  7312. +    return ct->slave_mode;
  7313. +}
  7314. +
  7315. +const char *config_get_mixer_device( config_t *ct )
  7316. +{
  7317. +    return ct->mixerdev;
  7318. +}
  7319. +
  7320. +int config_get_fullscreen_position( config_t *ct )
  7321. +{
  7322. +    return ct->fspos;
  7323. +}
  7324. +
  7325. +int config_get_save_restore_picture( config_t *ct )
  7326. +{
  7327. +    return ct->picsaverestore;
  7328. +}
  7329. +
  7330. +int config_get_global_brightness( config_t *ct )
  7331. +{
  7332. +    return ct->brightness;
  7333. +}
  7334. +
  7335. +int config_get_global_contrast( config_t *ct )
  7336. +{
  7337. +    return ct->contrast;
  7338. +}
  7339. +
  7340. +int config_get_global_saturation( config_t *ct )
  7341. +{
  7342. +    return ct->saturation;
  7343. +}
  7344. +
  7345. +int config_get_global_hue( config_t *ct )
  7346. +{
  7347. +    return ct->hue;
  7348. +}
  7349. +
  7350. +const char *config_get_audio_mode( config_t *ct )
  7351. +{
  7352. +    return ct->audiomode;
  7353. +}
  7354. +
  7355. +const char *config_get_xmltv_file( config_t *ct )
  7356. +{
  7357. +    return ct->xmltvfile;
  7358. +}
  7359. +
  7360. +const char *config_get_xmltv_language( config_t *ct )
  7361. +{
  7362. +    return ct->xmltvlanguage;
  7363. +}
  7364. +
  7365. +int config_get_invert( config_t *ct )
  7366. +{
  7367. +    return ct->invert;
  7368. +}
  7369. +
  7370. +int config_get_cc( config_t *ct )
  7371. +{
  7372. +    return ct->cc;
  7373. +}
  7374. +
  7375. +int config_get_mirror( config_t *ct )
  7376. +{
  7377. +    return ct->mirror;
  7378. +}
  7379. +
  7380. +int config_get_audio_boost( config_t *ct )
  7381. +{
  7382. +    return ct->boost;
  7383. +}
  7384. +
  7385. +int config_get_quiet_screenshots( config_t *ct )
  7386. +{
  7387. +    return ct->quiet_screenshots;
  7388. +}
  7389. +
  7390. +int config_get_unmute_volume( config_t *ct )
  7391. +{
  7392. +    return ct->unmute_volume;
  7393. +}
  7394. +
  7395. +int config_get_muted( config_t *ct )
  7396. +{
  7397. +    return ct->muted;
  7398. +}
  7399. +
  7400. +int config_get_mute_on_exit( config_t *ct )
  7401. +{
  7402. +    return ct->mute_on_exit;
  7403. +}
  7404. +
  7405. +int config_get_show_taglines( config_t *ct )
  7406. +{
  7407. +    return ct->show_taglines;
  7408. +}
  7409. +
  7410. +int config_get_square_pixels( config_t *ct )
  7411. +{
  7412. +    return ct->squarepixels;
  7413. +}
  7414. +
  7415. diff -Nurp tvtime-1.0.2/src/tvtimeconf.h tvtime-1.0.2-custom/src/tvtimeconf.h
  7416. --- tvtime-1.0.2/src/tvtimeconf.h       2005-08-14 19:00:11.000000000 +0200
  7417. +++ tvtime-1.0.2-custom/src/tvtimeconf.h        2011-05-29 13:07:28.179040896 +0200
  7418. @@ -151,6 +151,7 @@ int config_get_debug( config_t *ct );
  7419.  const char *config_get_geometry( config_t *ct );
  7420.  int config_get_inputwidth( config_t *ct );
  7421.  int config_get_aspect( config_t *ct );
  7422. +int config_get_matte( config_t *ct );
  7423.  int config_get_inputnum( config_t *ct );
  7424.  const char *config_get_v4l_device( config_t *ct );
  7425.  const char *config_get_v4l_norm( config_t *ct );
  7426. diff -Nurp tvtime-1.0.2/src/videodev2.h tvtime-1.0.2-custom/src/videodev2.h
  7427. --- tvtime-1.0.2/src/videodev2.h        2005-01-17 03:36:40.000000000 +0100
  7428. +++ tvtime-1.0.2-custom/src/videodev2.h 2011-05-29 13:07:28.215708012 +0200
  7429. @@ -16,7 +16,6 @@
  7430.  #ifdef __KERNEL__
  7431.  #include <linux/time.h> /* need struct timeval */
  7432.  #endif
  7433. -#include <linux/compiler.h> /* need __user */
  7434.  
  7435.  /* for kernel versions 2.4.26 and below: */
  7436.  #ifndef __user
  7437. diff -Nurp tvtime-1.0.2/src/videoinput.c tvtime-1.0.2-custom/src/videoinput.c
  7438. --- tvtime-1.0.2/src/videoinput.c       2005-09-08 05:13:37.000000000 +0200
  7439. +++ tvtime-1.0.2-custom/src/videoinput.c        2011-05-29 13:07:28.232374882 +0200
  7440. @@ -376,7 +376,9 @@ uint8_t *videoinput_next_frame( videoinp
  7441.  
  7442.          wait_for_frame_v4l2( vidin );
  7443.  
  7444. +        videoinput_get_aspect( vidin );
  7445.          cur_buf.type = vidin->capbuffers[ 0 ].vidbuf.type;
  7446. +        cur_buf.memory = vidin->capbuffers[ 0 ].vidbuf.memory;
  7447.          if( ioctl( vidin->grab_fd, VIDIOC_DQBUF, &cur_buf ) < 0 ) {
  7448.              /* some drivers return EIO when there is no signal */
  7449.              if( errno != EIO ) {
  7450. @@ -1148,6 +1150,22 @@ void videoinput_set_saturation_relative(
  7451.      }
  7452.  }
  7453.  
  7454. +float videoinput_get_aspect( videoinput_t *vidin )
  7455. +{
  7456. +    float aspect = 1.0;
  7457. +
  7458. +    if( vidin->isv4l2 ) {
  7459. +        struct v4l2_cropcap cropcap;
  7460. +        /* on success 0 is returned */
  7461. +        if( !ioctl( vidin->grab_fd, VIDIOC_CROPCAP, &cropcap ) ) {
  7462. +            aspect = (float)cropcap.pixelaspect.numerator / (float)cropcap.pixelaspect.denominator;
  7463. +            fprintf( stderr, "videoinput: Aspect ratio: %f\n", aspect);        
  7464. +        }
  7465. +    }
  7466. +  
  7467. +    return aspect;
  7468. +}
  7469. +
  7470.  static void videoinput_do_mute( videoinput_t *vidin, int mute )
  7471.  {
  7472.      if( vidin->hasaudio && mute != vidin->hw_muted ) {
  7473. @@ -1269,7 +1287,7 @@ void videoinput_set_tuner_freq( videoinp
  7474.          }
  7475.  
  7476.          vidin->change_muted = 1;
  7477. -        mixer_mute( 1 );
  7478. +        mixer->mute( 1 );
  7479.          videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
  7480.          vidin->cur_tuner_state = TUNER_STATE_SIGNAL_DETECTED;
  7481.          vidin->signal_acquire_wait = SIGNAL_ACQUIRE_DELAY;
  7482. @@ -1620,7 +1638,7 @@ int videoinput_check_for_signal( videoin
  7483.              if( vidin->change_muted ) {
  7484.                  vidin->change_muted = 0;
  7485.                  videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
  7486. -                mixer_mute( 0 );
  7487. +                mixer->mute( 0 );
  7488.              }
  7489.              break;
  7490.          }
  7491. @@ -1631,7 +1649,7 @@ int videoinput_check_for_signal( videoin
  7492.              vidin->cur_tuner_state = TUNER_STATE_SIGNAL_LOST;
  7493.              vidin->signal_recover_wait = SIGNAL_RECOVER_DELAY;
  7494.              vidin->change_muted = 1;
  7495. -            mixer_mute( 1 );
  7496. +            mixer->mute( 1 );
  7497.              videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
  7498.          case TUNER_STATE_SIGNAL_LOST:
  7499.              if( vidin->signal_recover_wait ) {
  7500. diff -Nurp tvtime-1.0.2/src/videoinput.c.orig tvtime-1.0.2-custom/src/videoinput.c.orig
  7501. --- tvtime-1.0.2/src/videoinput.c.orig  1970-01-01 01:00:00.000000000 +0100
  7502. +++ tvtime-1.0.2-custom/src/videoinput.c.orig   2011-05-29 13:07:28.185707644 +0200
  7503. @@ -0,0 +1,1812 @@
  7504. +/**
  7505. + * Copyright (C) 2001, 2002, 2003  Billy Biggs <vektor@dumbterm.net>.
  7506. + *
  7507. + * Uses hacky bttv detection code from xawtv:
  7508. + *   (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
  7509. + *
  7510. + * This program is free software; you can redistribute it and/or modify
  7511. + * it under the terms of the GNU General Public License as published by
  7512. + * the Free Software Foundation; either version 2, or (at your option)
  7513. + * any later version.
  7514. + *
  7515. + * This program is distributed in the hope that it will be useful,
  7516. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7517. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  7518. + * GNU General Public License for more details.
  7519. + *
  7520. + * You should have received a copy of the GNU General Public License
  7521. + * along with this program; if not, write to the Free Software Foundation,
  7522. + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  7523. + */
  7524. +
  7525. +#include <stdio.h>
  7526. +#include <stdlib.h>
  7527. +#include <stdint.h>
  7528. +#include <sys/types.h>
  7529. +#include <sys/stat.h>
  7530. +#include <sys/ioctl.h>
  7531. +#include <sys/mman.h>
  7532. +#include <sys/time.h>
  7533. +#include <unistd.h>
  7534. +#include <string.h>
  7535. +#include <fcntl.h>
  7536. +#include <errno.h>
  7537. +#include <signal.h>
  7538. +#ifdef HAVE_CONFIG_H
  7539. +# include "config.h"
  7540. +#endif
  7541. +#include "videodev.h"
  7542. +#include "videodev2.h"
  7543. +#include "videoinput.h"
  7544. +#include "mixer.h"
  7545. +
  7546. +/**
  7547. + * How long to wait when we lose a signal, or acquire a signal.
  7548. + */
  7549. +#define SIGNAL_RECOVER_DELAY 2
  7550. +#define SIGNAL_ACQUIRE_DELAY 2
  7551. +
  7552. +/**
  7553. + * How many seconds to wait before deciding it's a driver problem.
  7554. + */
  7555. +#define SYNC_TIMEOUT 3
  7556. +
  7557. +/**
  7558. + * Maximum number of capture buffers we allow.
  7559. + */
  7560. +#define MAX_CAPTURE_BUFFERS 16
  7561. +
  7562. +const char *videoinput_get_norm_name( int norm )
  7563. +{
  7564. +    if( norm == VIDEOINPUT_NTSC ) {
  7565. +        return "NTSC";
  7566. +    } else if( norm == VIDEOINPUT_PAL ) {
  7567. +        return "PAL";
  7568. +    } else if( norm == VIDEOINPUT_SECAM ) {
  7569. +        return "SECAM";
  7570. +    } else if( norm == VIDEOINPUT_PAL_NC ) {
  7571. +        return "PAL-NC";
  7572. +    } else if( norm == VIDEOINPUT_PAL_M ) {
  7573. +        return "PAL-M";
  7574. +    } else if( norm == VIDEOINPUT_PAL_N ) {
  7575. +        return "PAL-N";
  7576. +    } else if( norm == VIDEOINPUT_NTSC_JP ) {
  7577. +        return "NTSC-JP";
  7578. +    } else if( norm == VIDEOINPUT_PAL_60 ) {
  7579. +        return "PAL-60";
  7580. +    } else {
  7581. +        return "ERROR";
  7582. +    }
  7583. +}
  7584. +
  7585. +static v4l2_std_id videoinput_get_v4l2_norm( int norm )
  7586. +{
  7587. +    if( norm == VIDEOINPUT_NTSC ) {
  7588. +        return V4L2_STD_NTSC_M;
  7589. +    } else if( norm == VIDEOINPUT_PAL ) {
  7590. +        return V4L2_STD_PAL;
  7591. +    } else if( norm == VIDEOINPUT_SECAM ) {
  7592. +        return V4L2_STD_SECAM;
  7593. +    } else if( norm == VIDEOINPUT_PAL_NC ) {
  7594. +        return V4L2_STD_PAL_Nc;
  7595. +    } else if( norm == VIDEOINPUT_PAL_M ) {
  7596. +        return V4L2_STD_PAL_M;
  7597. +    } else if( norm == VIDEOINPUT_PAL_N ) {
  7598. +        return V4L2_STD_PAL_N;
  7599. +    } else if( norm == VIDEOINPUT_NTSC_JP ) {
  7600. +        return V4L2_STD_NTSC_M_JP;
  7601. +    } else if( norm == VIDEOINPUT_PAL_60 ) {
  7602. +        return V4L2_STD_PAL_60;
  7603. +    } else {
  7604. +        return 0;
  7605. +    }
  7606. +}
  7607. +
  7608. +static int videoinput_get_v4l1_norm( int norm )
  7609. +{
  7610. +    if( norm == VIDEOINPUT_NTSC ) {
  7611. +        return VIDEO_MODE_NTSC;
  7612. +    } else if( norm == VIDEOINPUT_PAL ) {
  7613. +        return VIDEO_MODE_PAL;
  7614. +    } else if( norm == VIDEOINPUT_SECAM ) {
  7615. +        return VIDEO_MODE_SECAM;
  7616. +    } else if( norm == VIDEOINPUT_PAL_NC ) {
  7617. +        return 3;
  7618. +    } else if( norm == VIDEOINPUT_PAL_M ) {
  7619. +        return 4;
  7620. +    } else if( norm == VIDEOINPUT_PAL_N ) {
  7621. +        return 5;
  7622. +    } else if( norm == VIDEOINPUT_NTSC_JP ) {
  7623. +        return 6;
  7624. +    } else {
  7625. +        return 0;
  7626. +    }
  7627. +}
  7628. +
  7629. +static int videoinput_get_audmode_v4l2( int mode )
  7630. +{
  7631. +    if( mode == VIDEOINPUT_MONO ) {
  7632. +        return V4L2_TUNER_MODE_MONO;
  7633. +    } else if( mode == VIDEOINPUT_STEREO ) {
  7634. +        return V4L2_TUNER_MODE_STEREO;
  7635. +    } else if( mode == VIDEOINPUT_LANG1 ) {
  7636. +        return V4L2_TUNER_MODE_LANG1;
  7637. +    } else if( mode == VIDEOINPUT_LANG2 ) {
  7638. +        return V4L2_TUNER_MODE_LANG2;
  7639. +    }
  7640. +    return V4L2_TUNER_MODE_MONO;
  7641. +}
  7642. +
  7643. +int videoinput_get_norm_number( const char *name )
  7644. +{
  7645. +    int i;
  7646. +
  7647. +    for( i = 0; i < VIDEOINPUT_PAL_60 + 1; i++ ) {
  7648. +        if( !strcasecmp( name, videoinput_get_norm_name( i ) ) ) {
  7649. +            return i;
  7650. +        }
  7651. +    }
  7652. +
  7653. +    return -1;
  7654. +}
  7655. +
  7656. +static int videoinput_get_norm_height( int norm )
  7657. +{
  7658. +    if( norm == VIDEOINPUT_NTSC || norm == VIDEOINPUT_NTSC_JP || norm == VIDEOINPUT_PAL_M || norm == VIDEOINPUT_PAL_60 ) {
  7659. +        return 480;
  7660. +    } else {
  7661. +        return 576;
  7662. +    }
  7663. +}
  7664. +
  7665. +int videoinput_get_time_per_field( int norm )
  7666. +{
  7667. +    if( norm == VIDEOINPUT_NTSC || norm == VIDEOINPUT_NTSC_JP || norm == VIDEOINPUT_PAL_M || norm == VIDEOINPUT_PAL_60 ) {
  7668. +        return 16683;
  7669. +    } else {
  7670. +        return 20000;
  7671. +    }
  7672. +}
  7673. +
  7674. +typedef struct capture_buffer_s
  7675. +{
  7676. +    struct v4l2_buffer vidbuf;
  7677. +    uint8_t *data;
  7678. +    int length;
  7679. +    int free;
  7680. +} capture_buffer_t;
  7681. +
  7682. +struct videoinput_s
  7683. +{
  7684. +    int verbose;
  7685. +    int grab_fd;
  7686. +    char drivername[ 64 ];
  7687. +    char shortdriver[ 64 ];
  7688. +
  7689. +    int numinputs;
  7690. +    int curinput;
  7691. +    char inputname[ 32 ];
  7692. +
  7693. +    int width;
  7694. +    int height;
  7695. +    int maxwidth;
  7696. +    int norm;
  7697. +    int volume;
  7698. +    int amode;
  7699. +
  7700. +    int isbttv;
  7701. +    int isv4l2;
  7702. +    int isuyvy;
  7703. +
  7704. +    int curframe;
  7705. +    int numframes;
  7706. +
  7707. +    int hasaudio;
  7708. +    int audiomode;
  7709. +    int change_muted;
  7710. +    int user_muted;
  7711. +    int hw_muted;
  7712. +
  7713. +    int hastuner;
  7714. +    int numtuners;
  7715. +    int tunerid;
  7716. +    int tunerlow;
  7717. +
  7718. +    int cur_tuner_state;
  7719. +    int signal_recover_wait;
  7720. +    int signal_acquire_wait;
  7721. +
  7722. +    int frames_since_start;
  7723. +
  7724. +    /* V4L2 capture state. */
  7725. +    capture_buffer_t capbuffers[ MAX_CAPTURE_BUFFERS ];
  7726. +    int is_streaming;
  7727. +
  7728. +    /* V4L1 mmap-mode state. */
  7729. +    int have_mmap;
  7730. +    uint8_t *map;
  7731. +    struct video_mmap *grab_buf;
  7732. +    struct video_mbuf gb_buffers;
  7733. +
  7734. +    /* V4L1 read-mode state. */
  7735. +    int grab_size;
  7736. +    uint8_t *grab_data;
  7737. +};
  7738. +
  7739. +const char *videoinput_get_audio_mode_name( videoinput_t *vidin, int mode )
  7740. +{
  7741. +    if( mode == VIDEO_SOUND_MONO ) {
  7742. +        return "Mono";
  7743. +    } else if( mode == VIDEO_SOUND_STEREO ) {
  7744. +        return "Stereo";
  7745. +    } else if( vidin->norm == VIDEOINPUT_NTSC ) {
  7746. +        if( mode == VIDEO_SOUND_LANG2 ) {
  7747. +            return "SAP";
  7748. +        }
  7749. +    } else {
  7750. +        if( mode == VIDEO_SOUND_LANG1 ) {
  7751. +            return "Language 1";
  7752. +        } else if( mode == VIDEO_SOUND_LANG2 ) {
  7753. +            return "Language 2";
  7754. +        }
  7755. +    }
  7756. +
  7757. +    return "ERROR";
  7758. +}
  7759. +
  7760. +static void videoinput_start_capture_v4l2( videoinput_t *vidin )
  7761. +{
  7762. +    if( !vidin->is_streaming ) {
  7763. +        if( ioctl( vidin->grab_fd, VIDIOC_STREAMON, &vidin->capbuffers[ 0 ].vidbuf.type ) < 0 ) {
  7764. +            fprintf( stderr, "videoinput: Driver refuses to start streaming: %s.\n",
  7765. +                     strerror( errno ) );
  7766. +        }
  7767. +        vidin->is_streaming = 1;
  7768. +        vidin->frames_since_start = 0;
  7769. +    }
  7770. +}
  7771. +
  7772. +static void videoinput_stop_capture_v4l2( videoinput_t *vidin )
  7773. +{
  7774. +    if( vidin->is_streaming ) {
  7775. +        if( ioctl( vidin->grab_fd, VIDIOC_STREAMOFF, &vidin->capbuffers[ 0 ].vidbuf.type ) < 0 ) {
  7776. +            fprintf( stderr, "videoinput: Driver refuses to stop streaming: %s.\n",
  7777. +                     strerror( errno ) );
  7778. +        }
  7779. +        vidin->is_streaming = 0;
  7780. +    }
  7781. +}
  7782. +
  7783. +static int alarms;
  7784. +
  7785. +static void sigalarm( int signal )
  7786. +{
  7787. +    alarms++;
  7788. +}
  7789. +
  7790. +static void siginit( void )
  7791. +{
  7792. +    struct sigaction act, old;
  7793. +
  7794. +    memset( &act, 0, sizeof( act ) );
  7795. +    act.sa_handler = sigalarm;
  7796. +    sigemptyset( &act.sa_mask );
  7797. +    sigaction( SIGALRM, &act, &old );
  7798. +}
  7799. +
  7800. +static void free_frame( videoinput_t *vidin, int frameid )
  7801. +{
  7802. +    if( vidin->isv4l2 ) {
  7803. +        if( ioctl( vidin->grab_fd, VIDIOC_QBUF, &vidin->capbuffers[ frameid ].vidbuf ) < 0 ) {
  7804. +            fprintf( stderr, "videoinput: Can't free frame %d: %s\n",
  7805. +                     frameid, strerror( errno ) );
  7806. +        }
  7807. +        vidin->capbuffers[ frameid ].free = 1;
  7808. +    } else {
  7809. +        if( ioctl( vidin->grab_fd, VIDIOCMCAPTURE, vidin->grab_buf + frameid ) < 0 ) {
  7810. +            fprintf( stderr, "videoinput: Can't free frame %d: %s\n",
  7811. +                     frameid, strerror( errno ) );
  7812. +        }
  7813. +    }
  7814. +}
  7815. +
  7816. +void videoinput_free_frame( videoinput_t *vidin, int frameid )
  7817. +{
  7818. +    if( vidin->isv4l2 || vidin->have_mmap ) {
  7819. +        free_frame( vidin, frameid );
  7820. +    }
  7821. +}
  7822. +
  7823. +static void videoinput_free_all_frames( videoinput_t *vidin )
  7824. +{
  7825. +    int i;
  7826. +
  7827. +    for( i = 0; i < vidin->numframes; i++ ) {
  7828. +        free_frame( vidin, i );
  7829. +    }
  7830. +    vidin->curframe = 0;
  7831. +}
  7832. +
  7833. +static void wait_for_frame_v4l1( videoinput_t *vidin, int frameid )
  7834. +{
  7835. +    alarms = 0;
  7836. +    alarm( SYNC_TIMEOUT );
  7837. +    if( ioctl( vidin->grab_fd, VIDIOCSYNC, vidin->grab_buf + frameid ) < 0 ) {
  7838. +        fprintf( stderr, "videoinput: Can't wait for frame %d: %s\n",
  7839. +                 frameid, strerror( errno ) );
  7840. +    }
  7841. +    if( alarms ) {
  7842. +        fprintf( stderr, "\n"
  7843. +      "    Your capture card driver: %s\n"
  7844. +      "    is taking too long to provide frames to tvtime.  This could be due\n"
  7845. +      "    either to a broken capture card, a signal that has become unstable\n"
  7846. +      "    or very noisy, or a driver misconfiguration.\n"
  7847. +      "\n"
  7848. +      "    Please report this on our bugs page: " PACKAGE_BUGREPORT "\n\n",
  7849. +           vidin->drivername );
  7850. +    }
  7851. +    alarm( 0 );
  7852. +}
  7853. +
  7854. +static void wait_for_frame_v4l2( videoinput_t * vidin )
  7855. +{
  7856. +    struct timeval timeout;
  7857. +    fd_set rdset;
  7858. +    int n;
  7859. +
  7860. +    FD_ZERO( &rdset );
  7861. +    FD_SET( vidin->grab_fd, &rdset );
  7862. +
  7863. +    timeout.tv_sec = SYNC_TIMEOUT;
  7864. +    timeout.tv_usec = 0;
  7865. +
  7866. +    n = select( vidin->grab_fd + 1, &rdset, 0, 0, &timeout );
  7867. +    if( n == -1 ) {
  7868. +        fprintf( stderr, "videoinput: Error waiting for frame: %s\n",
  7869. +                 strerror( errno ) );
  7870. +    } else if( n == 0 ) {
  7871. +        sigalarm( 0 );
  7872. +    }
  7873. +}
  7874. +
  7875. +uint8_t *videoinput_next_frame( videoinput_t *vidin, int *frameid )
  7876. +{
  7877. +    if( vidin->isv4l2 ) {
  7878. +        struct v4l2_buffer cur_buf;
  7879. +
  7880. +        wait_for_frame_v4l2( vidin );
  7881. +
  7882. +        videoinput_get_aspect( vidin );
  7883. +        cur_buf.type = vidin->capbuffers[ 0 ].vidbuf.type;
  7884. +        if( ioctl( vidin->grab_fd, VIDIOC_DQBUF, &cur_buf ) < 0 ) {
  7885. +            /* some drivers return EIO when there is no signal */
  7886. +            if( errno != EIO ) {
  7887. +                fprintf( stderr, "videoinput: Can't read frame. Error was: %s (%d).\n",
  7888. +                         strerror( errno ), vidin->frames_since_start );
  7889. +            }
  7890. +            /* We must now restart capture. */
  7891. +            videoinput_stop_capture_v4l2( vidin );
  7892. +            videoinput_free_all_frames( vidin );
  7893. +            videoinput_start_capture_v4l2( vidin );
  7894. +            *frameid = -1;
  7895. +            return 0;
  7896. +        }
  7897. +        vidin->frames_since_start++;
  7898. +        vidin->capbuffers[ cur_buf.index ].free = 0;
  7899. +        *frameid = cur_buf.index;
  7900. +        return vidin->capbuffers[ cur_buf.index ].data;
  7901. +    } else {
  7902. +        if( vidin->have_mmap ) {
  7903. +            uint8_t *cur;
  7904. +            wait_for_frame_v4l1( vidin, vidin->curframe );
  7905. +            cur = vidin->map + vidin->gb_buffers.offsets[ vidin->curframe ];
  7906. +            *frameid = vidin->curframe;
  7907. +            vidin->curframe = ( vidin->curframe + 1 ) % vidin->numframes;
  7908. +            return cur;
  7909. +        } else {
  7910. +            int rc = read( vidin->grab_fd, vidin->grab_data, vidin->grab_size );
  7911. +            if( vidin->grab_size != rc ) {
  7912. +                fprintf( stderr, "videoinput: Can't read frame. Returned %d, error: %s.\n",
  7913. +                         rc, strerror( errno ) );
  7914. +                return 0;
  7915. +            } else {
  7916. +                return vidin->grab_data;
  7917. +            }
  7918. +        }
  7919. +    }
  7920. +}
  7921. +
  7922. +int videoinput_buffer_invalid( videoinput_t *vidin, int frameid )
  7923. +{
  7924. +    if( !vidin->isv4l2 ) {
  7925. +        return 0;
  7926. +    } else {
  7927. +        return vidin->capbuffers[ frameid ].free;
  7928. +    }
  7929. +}
  7930. +
  7931. +videoinput_t *videoinput_new( const char *v4l_device, int capwidth,
  7932. +                              int volume, int norm, int verbose, char *error_string )
  7933. +{
  7934. +    videoinput_t *vidin = malloc( sizeof( videoinput_t ) );
  7935. +    struct video_capability caps_v4l1;
  7936. +    struct v4l2_capability caps_v4l2;
  7937. +    struct video_picture grab_pict;
  7938. +    struct video_window grab_win;
  7939. +    int i;
  7940. +
  7941. +    if( capwidth & 1 ) {
  7942. +        capwidth -= 1;
  7943. +        if( verbose ) {
  7944. +            fprintf( stderr, "videoinput: Odd values for input width not allowed, "
  7945. +                             "using %d instead.\n", capwidth );
  7946. +        }
  7947. +    }
  7948. +
  7949. +    if( !vidin ) {
  7950. +        fprintf( stderr, "videoinput: Cannot allocate memory.\n" );
  7951. +        sprintf( error_string, "%s", strerror( ENOMEM ) );
  7952. +        return 0;
  7953. +    }
  7954. +
  7955. +    siginit();
  7956. +
  7957. +    vidin->curframe = 0;
  7958. +    vidin->verbose = verbose;
  7959. +    vidin->norm = norm;
  7960. +    vidin->volume = volume;
  7961. +    vidin->amode = 0;
  7962. +    vidin->height = videoinput_get_norm_height( norm );
  7963. +    vidin->cur_tuner_state = TUNER_STATE_NO_SIGNAL;
  7964. +
  7965. +    vidin->hastuner = 0;
  7966. +    vidin->numtuners = 0;
  7967. +    vidin->tunerid = 0;
  7968. +    vidin->tunerlow = 0;
  7969. +
  7970. +    vidin->isv4l2 = 0;
  7971. +    vidin->isbttv = 0;
  7972. +    vidin->isuyvy = 0;
  7973. +
  7974. +    vidin->signal_recover_wait = 0;
  7975. +    vidin->signal_acquire_wait = 0;
  7976. +    vidin->change_muted = 1;
  7977. +    vidin->user_muted = 0;
  7978. +    vidin->hw_muted = 1;
  7979. +    vidin->hasaudio = 1;
  7980. +    vidin->audiomode = 0;
  7981. +    vidin->curinput = 0;
  7982. +    vidin->have_mmap = 0;
  7983. +    vidin->is_streaming = 0;
  7984. +
  7985. +    memset( vidin->inputname, 0, sizeof( vidin->inputname ) );
  7986. +    memset( vidin->drivername, 0, sizeof( vidin->drivername ) );
  7987. +    memset( vidin->shortdriver, 0, sizeof( vidin->shortdriver ) );
  7988. +
  7989. +    /* First, open the device. */
  7990. +    vidin->grab_fd = open( v4l_device, O_RDWR );
  7991. +    if( vidin->grab_fd < 0 ) {
  7992. +        fprintf( stderr, "videoinput: Cannot open capture device %s: %s\n",
  7993. +                 v4l_device, strerror( errno ) );
  7994. +        sprintf( error_string, "%s", strerror( errno ) );
  7995. +        free( vidin );
  7996. +        return 0;
  7997. +    }
  7998. +
  7999. +    /**
  8000. +     * Next, ask for its capabilities.  This will also confirm it's a V4L2
  8001. +     * device.
  8002. +     */
  8003. +    if( ioctl( vidin->grab_fd, VIDIOC_QUERYCAP, &caps_v4l2 ) < 0 ) {
  8004. +        /* Can't get V4L2 capabilities, maybe this is a V4L1 device? */
  8005. +        if( ioctl( vidin->grab_fd, VIDIOCGCAP, &caps_v4l1 ) < 0 ) {
  8006. +            fprintf( stderr, "videoinput: %s is not a video4linux device.\n",
  8007. +                     v4l_device );
  8008. +            sprintf( error_string, "Not a video4linux device" );
  8009. +            close( vidin->grab_fd );
  8010. +            free( vidin );
  8011. +            return 0;
  8012. +        } else if( vidin->verbose ) {
  8013. +            fprintf( stderr, "videoinput: Using video4linux driver '%s'.\n"
  8014. +                             "videoinput: Card type is %x, audio %d.\n",
  8015. +                     caps_v4l1.name, caps_v4l1.type, caps_v4l1.audios );
  8016. +        }
  8017. +        snprintf( vidin->drivername, sizeof( vidin->drivername ),
  8018. +                  "%s", caps_v4l1.name );
  8019. +        snprintf( vidin->shortdriver, sizeof( vidin->shortdriver ),
  8020. +                  "%s", caps_v4l1.name );
  8021. +    } else {
  8022. +        if( vidin->verbose ) {
  8023. +            fprintf( stderr, "videoinput: Using video4linux2 driver '%s', card '%s' (bus %s).\n"
  8024. +                             "videoinput: Version is %u, capabilities %x.\n",
  8025. +                     caps_v4l2.driver, caps_v4l2.card, caps_v4l2.bus_info,
  8026. +                     caps_v4l2.version, caps_v4l2.capabilities );
  8027. +        }
  8028. +        vidin->isv4l2 = 1;
  8029. +        snprintf( vidin->drivername, sizeof( vidin->drivername ),
  8030. +                  "%s [%s/%s/%u]",
  8031. +                  caps_v4l2.driver, caps_v4l2.card,
  8032. +                  caps_v4l2.bus_info, caps_v4l2.version );
  8033. +        snprintf( vidin->shortdriver, sizeof( vidin->shortdriver ),
  8034. +                  "%s", caps_v4l2.driver );
  8035. +    }
  8036. +
  8037. +    if( vidin->isv4l2 ) {
  8038. +        struct v4l2_input in;
  8039. +
  8040. +        vidin->numinputs = 0;
  8041. +        in.index = vidin->numinputs;
  8042. +
  8043. +        /**
  8044. +         * We have to enumerate all of the inputs just to know how many
  8045. +         * there are.
  8046. +         */
  8047. +        while( ioctl( vidin->grab_fd, VIDIOC_ENUMINPUT, &in ) >= 0 ) {
  8048. +            vidin->numinputs++;
  8049. +            in.index = vidin->numinputs;
  8050. +        }
  8051. +
  8052. +        if( !vidin->numinputs ) {
  8053. +            fprintf( stderr, "videoinput: No inputs available on "
  8054. +                     "video4linux2 device '%s'.\n", v4l_device );
  8055. +            sprintf( error_string, "No inputs available" );
  8056. +            close( vidin->grab_fd );
  8057. +            free( vidin );
  8058. +            return 0;
  8059. +        }
  8060. +    } else {
  8061. +        /* The capabilities should tell us how many inputs this card has. */
  8062. +        vidin->numinputs = caps_v4l1.channels;
  8063. +        if( vidin->numinputs == 0 ) {
  8064. +            fprintf( stderr, "videoinput: No inputs available on "
  8065. +                     "video4linux device '%s'.\n", v4l_device );
  8066. +            sprintf( error_string, "No inputs available" );
  8067. +            close( vidin->grab_fd );
  8068. +            free( vidin );
  8069. +            return 0;
  8070. +        }
  8071. +    }
  8072. +
  8073. +    /* Check if this is a bttv-based card.  Code taken from xawtv. */
  8074. +#define BTTV_VERSION            _IOR('v' , BASE_VIDIOCPRIVATE+6, int)
  8075. +    /* dirty hack time / v4l design flaw -- works with bttv only
  8076. +     * this adds support for a few less common PAL versions */
  8077. +    if( !(ioctl( vidin->grab_fd, BTTV_VERSION, &i ) < 0) ) {
  8078. +        vidin->isbttv = 1;
  8079. +    }
  8080. +#undef BTTV_VERSION
  8081. +
  8082. +    if( !vidin->isv4l2 ) {
  8083. +        if( !vidin->isbttv && norm > VIDEOINPUT_SECAM ) {
  8084. +            fprintf( stderr, "videoinput: Capture card '%s' does not seem to use the bttv driver.\n"
  8085. +                             "videoinput: The norm %s is only supported in V4L1 for bttv-supported cards.\n",
  8086. +                     v4l_device, videoinput_get_norm_name( norm ) );
  8087. +            sprintf( error_string, "%s unsupported by %s", videoinput_get_norm_name( norm ), vidin->shortdriver );
  8088. +            close( vidin->grab_fd );
  8089. +            free( vidin );
  8090. +            return 0;
  8091. +        }
  8092. +
  8093. +        if( norm > VIDEOINPUT_NTSC_JP ) {
  8094. +            fprintf( stderr, "videoinput: Detected only a V4L1 driver.  The PAL-60 norm\n"
  8095. +                             "videoinput: is only available if driver supports V4L2.\n" );
  8096. +            sprintf( error_string, "%s unsupported by %s", videoinput_get_norm_name( norm ), vidin->shortdriver );
  8097. +            close( vidin->grab_fd );
  8098. +            free( vidin );
  8099. +            return 0;
  8100. +        }
  8101. +    }
  8102. +
  8103. +    /* On initialization, set to input 0.  This is just to start things up. */
  8104. +    videoinput_set_input_num( vidin, 0 );
  8105. +
  8106. +    /* Test for audio support. */
  8107. +    if( !vidin->isv4l2 ) {
  8108. +        struct video_audio audio;
  8109. +
  8110. +        if( ( ioctl( vidin->grab_fd, VIDIOCGAUDIO, &audio ) < 0 ) && vidin->verbose ) {
  8111. +            vidin->hasaudio = 0;
  8112. +            fprintf( stderr, "videoinput: No audio capability detected (asked for audio, got '%s').\n",
  8113. +                     strerror( errno ) );
  8114. +        } else if( verbose ) {
  8115. +            fprintf( stderr, "videoinput: Audio supports " );
  8116. +            if( audio.flags & VIDEO_AUDIO_MUTE ) {
  8117. +                fprintf( stderr, "Mute " );
  8118. +            } else if( audio.flags & VIDEO_AUDIO_MUTABLE ) {
  8119. +                fprintf( stderr, "Mutable " );
  8120. +            } else if( audio.flags & VIDEO_AUDIO_VOLUME ) {
  8121. +                fprintf( stderr, "Volume " );
  8122. +            } else if( audio.flags & VIDEO_AUDIO_BASS ) {
  8123. +                fprintf( stderr, "Bass " );
  8124. +            } else if( audio.flags & VIDEO_AUDIO_TREBLE ) {
  8125. +                fprintf( stderr, "Treble " );
  8126. +            }
  8127. +            fprintf( stderr, "\n" );
  8128. +        }
  8129. +    }
  8130. +
  8131. +    /* Set to stereo by default. */
  8132. +    videoinput_set_audio_mode( vidin, VIDEO_SOUND_STEREO );
  8133. +
  8134. +    /**
  8135. +     * Once we're here, we've set the hardware norm.  Now confirm that
  8136. +     * our width is acceptable by again asking what the capabilities
  8137. +     * are.
  8138. +     */
  8139. +    if( vidin->isv4l2 ) {
  8140. +        struct v4l2_format imgformat;
  8141. +
  8142. +        imgformat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  8143. +        memset( &(imgformat.fmt.pix), 0, sizeof( struct v4l2_pix_format ) );
  8144. +        imgformat.fmt.pix.width = capwidth;
  8145. +        imgformat.fmt.pix.height = vidin->height;
  8146. +        imgformat.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  8147. +        imgformat.fmt.pix.field = V4L2_FIELD_INTERLACED;
  8148. +
  8149. +        if( ioctl( vidin->grab_fd, VIDIOC_S_FMT, &imgformat ) < 0 ) {
  8150. +            /* Try for UYVY instead. */
  8151. +            imgformat.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
  8152. +            if( ioctl( vidin->grab_fd, VIDIOC_S_FMT, &imgformat ) < 0 ) {
  8153. +
  8154. +                fprintf( stderr, "\n"
  8155. +     "    Your capture card driver: %s\n"
  8156. +     "    does not support studio-quality colour images required by tvtime.\n"
  8157. +     "    This is a hardware limitation of some cards including many\n"
  8158. +     "    low-quality webcams.  Please select a different video device to use\n"
  8159. +     "    with the command line option --device.\n"
  8160. +     "\n"
  8161. +     "    Message from the card was: %s\n\n",
  8162. +                    vidin->drivername, strerror( errno ) );
  8163. +
  8164. +                sprintf( error_string, "%s: %s", vidin->shortdriver, strerror( errno ) );
  8165. +                close( vidin->grab_fd );
  8166. +                free( vidin );
  8167. +                return 0;
  8168. +            }
  8169. +            vidin->isuyvy = 1;
  8170. +        }
  8171. +
  8172. +        if( vidin->height != imgformat.fmt.pix.height ) {
  8173. +                fprintf( stderr, "\n"
  8174. +    "    Your capture card driver: %s\n"
  8175. +    "    does not support full size studio-quality images required by tvtime.\n"
  8176. +    "    This is true for many low-quality webcams.  Please select a\n"
  8177. +    "    different video device for tvtime to use with the command line\n"
  8178. +    "    option --device.\n\n", vidin->drivername );
  8179. +            sprintf( error_string, "Frames too short from %s", vidin->shortdriver );
  8180. +            close( vidin->grab_fd );
  8181. +            free( vidin );
  8182. +            return 0;
  8183. +        }
  8184. +
  8185. +        if( capwidth != imgformat.fmt.pix.width && verbose ) {
  8186. +            fprintf( stderr, "videoinput: Width %d too high, using %d "
  8187. +                             "instead as suggested by the driver.\n",
  8188. +                     capwidth, imgformat.fmt.pix.width );
  8189. +        }
  8190. +        vidin->width = imgformat.fmt.pix.width;
  8191. +
  8192. +        /* Query the maximum input width - I wish there was a nicer way */
  8193. +        imgformat.fmt.pix.width = 10000;
  8194. +        if( ioctl( vidin->grab_fd, VIDIOC_TRY_FMT, &imgformat ) < 0 ) {
  8195. +            vidin->maxwidth = 768;
  8196. +            if( verbose ) {
  8197. +                fprintf( stderr, "videoinput: Your capture card driver does "
  8198. +                                 "not implement the TRY_FMT query.\n"
  8199. +                                 "Setting maximum input width to 768.\n" );
  8200. +            }
  8201. +        } else {
  8202. +            vidin->maxwidth = imgformat.fmt.pix.width;
  8203. +            if( verbose ) {
  8204. +                fprintf( stderr, "videoinput: Maximum input width: %d "
  8205. +                                 "pixels.\n", vidin->maxwidth );
  8206. +            }
  8207. +        }
  8208. +
  8209. +    } else {
  8210. +        if( ioctl( vidin->grab_fd, VIDIOCGCAP, &caps_v4l1 ) < 0 ) {
  8211. +            fprintf( stderr, "videoinput: video4linux device '%s' refuses "
  8212. +                     "to provide set capability information, giving up.\n",
  8213. +                     v4l_device );
  8214. +            sprintf( error_string, "%s: %s", vidin->shortdriver, strerror( errno ) );
  8215. +            close( vidin->grab_fd );
  8216. +            free( vidin );
  8217. +            return 0;
  8218. +        }
  8219. +        vidin->maxwidth = caps_v4l1.maxwidth;
  8220. +        if( verbose ) {
  8221. +            fprintf( stderr, "videoinput: Maximum input width: %d pixels.\n",
  8222. +                     vidin->maxwidth );
  8223. +        }
  8224. +        if( capwidth > caps_v4l1.maxwidth ) {
  8225. +            if( verbose ) {
  8226. +                fprintf( stderr, "videoinput: Width %d too high, using %d "
  8227. +                                 "instead as suggested by the driver.\n",
  8228. +                         capwidth, caps_v4l1.maxwidth );
  8229. +            }
  8230. +            capwidth = caps_v4l1.maxwidth;
  8231. +        }
  8232. +        if( capwidth < caps_v4l1.minwidth ) {
  8233. +            if( verbose ) {
  8234. +                fprintf( stderr, "videoinput: Width %d too low, using %d "
  8235. +                                 "instead as suggested by the driver.\n",
  8236. +                         capwidth, caps_v4l1.minwidth );
  8237. +            }
  8238. +            capwidth = caps_v4l1.minwidth;
  8239. +        }
  8240. +        vidin->width = capwidth;
  8241. +
  8242. +
  8243. +        /* Set the format using the SPICT ioctl. */
  8244. +        if( ioctl( vidin->grab_fd, VIDIOCGPICT, &grab_pict ) < 0 ) {
  8245. +            fprintf( stderr, "videoinput: Can't get image information from the card, unable to "
  8246. +                     "process the output: %s.\n", strerror( errno ) );
  8247. +            fprintf( stderr, "videoinput: Please post a bug report to " PACKAGE_BUGREPORT
  8248. +                     " indicating your capture card, driver, and the error message above.\n" );
  8249. +            sprintf( error_string, "%s: %s", vidin->shortdriver, strerror( errno ) );
  8250. +            close( vidin->grab_fd );
  8251. +            free( vidin );
  8252. +            return 0;
  8253. +        }
  8254. +
  8255. +        grab_pict.depth = 16;
  8256. +        grab_pict.palette = VIDEO_PALETTE_YUV422;
  8257. +        if( ioctl( vidin->grab_fd, VIDIOCSPICT, &grab_pict ) < 0 ) {
  8258. +            /* Try for UYVY instead. */
  8259. +            grab_pict.palette = VIDEO_PALETTE_UYVY;
  8260. +            if( ioctl( vidin->grab_fd, VIDIOCSPICT, &grab_pict ) < 0 ) {
  8261. +                fprintf( stderr, "\n"
  8262. +     "    Your capture card driver: %s\n"
  8263. +     "    does not support studio-quality colour images required by tvtime.\n"
  8264. +     "    This is a hardware limitation of some cards including many\n"
  8265. +     "    low-quality webcams.  Please select a different video device to use\n"
  8266. +     "    with the command line option --device.\n"
  8267. +     "\n"
  8268. +     "    Message from the card was: %s\n\n",
  8269. +                    vidin->drivername, strerror( errno ) );
  8270. +                sprintf( error_string, "Format unsupported by %s", vidin->shortdriver );
  8271. +                close( vidin->grab_fd );
  8272. +                free( vidin );
  8273. +                return 0;
  8274. +            }
  8275. +            vidin->isuyvy = 1;
  8276. +        }
  8277. +        if( vidin->verbose ) {
  8278. +            fprintf( stderr, "videoinput: Brightness %d, hue %d, colour %d, contrast %d\n"
  8279. +                             "videoinput: Whiteness %d, depth %d, palette %d.\n",
  8280. +                     grab_pict.brightness, grab_pict.hue, grab_pict.colour, grab_pict.contrast,
  8281. +                     grab_pict.whiteness, grab_pict.depth, grab_pict.palette );
  8282. +        }
  8283. +
  8284. +        /* Set and get the window settings. */
  8285. +        memset( &grab_win, 0, sizeof( struct video_window ) );
  8286. +        grab_win.width = vidin->width;
  8287. +        grab_win.height = vidin->height;
  8288. +        if( ioctl( vidin->grab_fd, VIDIOCSWIN, &grab_win ) < 0 ) {
  8289. +            fprintf( stderr, "videoinput: Failed to set the V4L window size (capture width and height): %s\n",
  8290. +                     strerror( errno ) );
  8291. +            sprintf( error_string, "%s: %s", vidin->shortdriver, strerror( errno ) );
  8292. +            close( vidin->grab_fd );
  8293. +            free( vidin );
  8294. +            return 0;
  8295. +        }
  8296. +    }
  8297. +
  8298. +    if( vidin->isv4l2 ) {
  8299. +        struct v4l2_requestbuffers req;
  8300. +
  8301. +        /**
  8302. +         * Ask Video Device for Buffers
  8303. +         */
  8304. +        req.count = 4;
  8305. +        req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  8306. +        req.memory = V4L2_MEMORY_MMAP;
  8307. +
  8308. +        if( ioctl( vidin->grab_fd, VIDIOC_REQBUFS, &req ) < 0 ) {
  8309. +            fprintf( stderr, "videoinput: Card failed to allocate capture buffers: %s\n",
  8310. +                     strerror( errno ) );
  8311. +            sprintf( error_string, "%s: %s", vidin->shortdriver, strerror( errno ) );
  8312. +            close( vidin->grab_fd );
  8313. +            free( vidin );
  8314. +            return 0;
  8315. +        }
  8316. +        vidin->numframes = req.count;
  8317. +
  8318. +        if( vidin->numframes < 1 ) {
  8319. +            fprintf( stderr, "videoinput: No capture buffers available from card.\n" );
  8320. +            sprintf( error_string, "%s: No capture buffers", vidin->shortdriver );
  8321. +            close( vidin->grab_fd );
  8322. +            free( vidin );
  8323. +            return 0;
  8324. +        } else if( vidin->numframes > 4 ) {
  8325. +            /* If we got more frames than we asked for, limit to 4 for now. */
  8326. +            if( vidin->verbose ) {
  8327. +                fprintf( stderr, "videoinput: Capture card provides %d buffers, but we only need 4.\n",
  8328. +                         vidin->numframes );
  8329. +            }
  8330. +            vidin->numframes = 4;
  8331. +        }
  8332. +
  8333. +        /**
  8334. +         * Query each buffer and map it to the video device
  8335. +         */
  8336. +        for( i = 0; i < vidin->numframes; i++ ) {
  8337. +            struct v4l2_buffer *vidbuf = &(vidin->capbuffers[ i ].vidbuf);
  8338. +
  8339. +            vidbuf->index = i;
  8340. +            vidbuf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  8341. +            vidbuf->memory = V4L2_MEMORY_MMAP;
  8342. +            if( ioctl( vidin->grab_fd, VIDIOC_QUERYBUF, vidbuf ) < 0 ) {
  8343. +                fprintf( stderr, "videoinput: Can't get information about buffer %d: %s.\n",
  8344. +                         i, strerror( errno ) );
  8345. +                sprintf( error_string, "%s: %s", vidin->shortdriver, strerror( errno ) );
  8346. +                close( vidin->grab_fd );
  8347. +                free( vidin );
  8348. +                return 0;
  8349. +            }
  8350. +
  8351. +            vidin->capbuffers[ i ].data = mmap( 0, vidbuf->length,
  8352. +                                                PROT_READ | PROT_WRITE,
  8353. +                                                MAP_SHARED, vidin->grab_fd,
  8354. +                                                vidbuf->m.offset );
  8355. +            if( vidin->capbuffers[ i ].data == MAP_FAILED ) {
  8356. +                fprintf( stderr, "videoinput: Can't map buffer %d: %s.\n",
  8357. +                         i, strerror( errno ) );
  8358. +                sprintf( error_string, "%s: %s", vidin->shortdriver, strerror( errno ) );
  8359. +                close( vidin->grab_fd );
  8360. +                free( vidin );
  8361. +                return 0;
  8362. +            }
  8363. +            vidin->capbuffers[ i ].length = vidbuf->length;
  8364. +        }
  8365. +        videoinput_free_all_frames( vidin );
  8366. +
  8367. +        /**
  8368. +         * Tell video stream to begin capture.
  8369. +         */
  8370. +        videoinput_start_capture_v4l2( vidin );
  8371. +
  8372. +        return vidin;
  8373. +    } else {
  8374. +        /* Try to set up mmap-based capture. */
  8375. +        if( ioctl( vidin->grab_fd, VIDIOCGMBUF, &(vidin->gb_buffers) ) < 0 ) {
  8376. +            fprintf( stderr, "videoinput: Can't get capture buffer properties.  No mmap support?\n"
  8377. +                     "Please post a bug report about this to " PACKAGE_BUGREPORT "\n"
  8378. +                     "with your card, driver and this error message: %s.\n", strerror( errno ) );
  8379. +            fprintf( stderr, "videoinput: Will try to fall back to (untested) read()-based capture..\n" );
  8380. +        } else {
  8381. +            /* If we got more frames than we asked for, limit to 4 for now. */
  8382. +            if( vidin->gb_buffers.frames > 4 ) {
  8383. +                if( vidin->verbose ) {
  8384. +                    fprintf( stderr, "videoinput: Capture card provides %d buffers, but we only need 4.\n",
  8385. +                             vidin->gb_buffers.frames );
  8386. +                }
  8387. +                vidin->numframes = 4;
  8388. +            } else {
  8389. +                vidin->numframes = vidin->gb_buffers.frames;
  8390. +            }
  8391. +
  8392. +            vidin->grab_buf = malloc( sizeof( struct video_mmap ) *
  8393. +                                      vidin->numframes );
  8394. +            if( !vidin->grab_buf ) {
  8395. +                fprintf( stderr, "videoinput: Can't allocate memory.\n" );
  8396. +                sprintf( error_string, "%s", strerror( ENOMEM ) );
  8397. +                close( vidin->grab_fd );
  8398. +                free( vidin );
  8399. +                return 0;
  8400. +            }
  8401. +
  8402. +            /* Setup mmap capture buffers. */
  8403. +            for( i = 0; i < vidin->numframes; i++ ) {
  8404. +                if( vidin->isuyvy ) {
  8405. +                    vidin->grab_buf[ i ].format = VIDEO_PALETTE_UYVY;
  8406. +                } else {
  8407. +                    vidin->grab_buf[ i ].format = VIDEO_PALETTE_YUV422;
  8408. +                }
  8409. +                vidin->grab_buf[ i ].frame = i;
  8410. +                vidin->grab_buf[ i ].width = vidin->width;
  8411. +                vidin->grab_buf[ i ].height = vidin->height;
  8412. +            }
  8413. +
  8414. +            vidin->map = mmap( 0, vidin->gb_buffers.size, PROT_READ|PROT_WRITE,
  8415. +                               MAP_SHARED, vidin->grab_fd, 0 );
  8416. +            if( vidin->map != MAP_FAILED ) {
  8417. +                vidin->have_mmap = 1;
  8418. +                videoinput_free_all_frames( vidin );
  8419. +                return vidin;
  8420. +            } else {
  8421. +                fprintf( stderr, "videoinput: mmap() failed.  Will try to fall back to "
  8422. +                        "(untested) read()-based capture..\n" );
  8423. +            }
  8424. +        }
  8425. +
  8426. +        /* Fallback to read(). THIS CODE IS UNTESTED. IS THIS EVEN FINISHED? */
  8427. +        if( vidin->verbose ) {
  8428. +            fprintf( stderr, "videoinput: No mmap support available, using read().\n" );
  8429. +        }
  8430. +
  8431. +        vidin->have_mmap = 0;
  8432. +        vidin->grab_size = (capwidth * vidin->height * 2);
  8433. +        vidin->grab_data = malloc( vidin->grab_size );
  8434. +        vidin->numframes = 2;
  8435. +
  8436. +        return vidin;
  8437. +    }
  8438. +}
  8439. +
  8440. +void videoinput_delete( videoinput_t *vidin )
  8441. +{
  8442. +    /* Mute audio on exit. */
  8443. +    videoinput_mute( vidin, 1 );
  8444. +
  8445. +    if( vidin->isv4l2 ) {
  8446. +        int i;
  8447. +
  8448. +        videoinput_stop_capture_v4l2( vidin );
  8449. +        videoinput_free_all_frames( vidin );
  8450. +
  8451. +        for( i = 0; i < vidin->numframes; i++ ) {
  8452. +            munmap( vidin->capbuffers[ i ].data, vidin->capbuffers[ i ].length );
  8453. +        }
  8454. +    } else {
  8455. +        if( vidin->have_mmap ) {
  8456. +            munmap( vidin->map, vidin->gb_buffers.size );
  8457. +            free( vidin->grab_buf );
  8458. +        } else {
  8459. +            free( vidin->grab_data );
  8460. +        }
  8461. +    }
  8462. +
  8463. +    close( vidin->grab_fd );
  8464. +    free( vidin );
  8465. +}
  8466. +
  8467. +static double videoinput_get_control_v4l2( videoinput_t *vidin, uint32_t id )
  8468. +{
  8469. +    struct v4l2_queryctrl query;
  8470. +
  8471. +    query.id = id;
  8472. +    if( ioctl( vidin->grab_fd, VIDIOC_QUERYCTRL, &query ) >= 0 && !(query.flags & V4L2_CTRL_FLAG_DISABLED) ) {
  8473. +        struct v4l2_control control;
  8474. +        control.id = id;
  8475. +        if( ioctl( vidin->grab_fd, VIDIOC_G_CTRL, &control ) >= 0 ) {
  8476. +            return (((double) (control.value - query.minimum)) / ((double) (query.maximum - query.minimum)));
  8477. +        }
  8478. +    }
  8479. +    return 0.0;
  8480. +}
  8481. +
  8482. +static void videoinput_set_control_v4l2( videoinput_t *vidin, uint32_t id, double val )
  8483. +{
  8484. +    struct v4l2_queryctrl query;
  8485. +
  8486. +    query.id = id;
  8487. +    if( ioctl( vidin->grab_fd, VIDIOC_QUERYCTRL, &query ) >= 0 && !(query.flags & V4L2_CTRL_FLAG_DISABLED) ) {
  8488. +        struct v4l2_control control;
  8489. +        control.id = id;
  8490. +        control.value = query.minimum + ((int) ((val * ((double) (query.maximum - query.minimum))) + 0.5));
  8491. +        ioctl( vidin->grab_fd, VIDIOC_S_CTRL, &control );
  8492. +    }
  8493. +}
  8494. +
  8495. +int videoinput_get_hue( videoinput_t *vidin )
  8496. +{
  8497. +    if( vidin->isv4l2 ) {
  8498. +        return (int) ((videoinput_get_control_v4l2( vidin, V4L2_CID_HUE ) * 100.0) + 0.5);
  8499. +    } else {
  8500. +        struct video_picture grab_pict;
  8501. +
  8502. +        if( ioctl( vidin->grab_fd, VIDIOCGPICT, &grab_pict ) >= 0 ) {
  8503. +            return (int) ((((double) grab_pict.hue / 65535.0) * 100.0) + 0.5);
  8504. +        }
  8505. +    }
  8506. +
  8507. +    return 0;
  8508. +}
  8509. +
  8510. +void videoinput_set_hue( videoinput_t *vidin, int newhue )
  8511. +{
  8512. +    if( newhue > 100 ) newhue = 100;
  8513. +    if( newhue <   0 ) newhue = 50;
  8514. +
  8515. +    if( vidin->isv4l2 ) {
  8516. +        videoinput_set_control_v4l2( vidin, V4L2_CID_HUE, ((double) newhue) / 100.0 );
  8517. +    } else {
  8518. +        struct video_picture grab_pict;
  8519. +
  8520. +        if( ioctl( vidin->grab_fd, VIDIOCGPICT, &grab_pict ) >= 0 ) {
  8521. +            grab_pict.hue = (int) (((((double) newhue) / 100.0) * 65535.0) + 0.5);
  8522. +            ioctl( vidin->grab_fd, VIDIOCSPICT, &grab_pict );
  8523. +        }
  8524. +    }
  8525. +}
  8526. +
  8527. +void videoinput_set_hue_relative( videoinput_t *vidin, int offset )
  8528. +{
  8529. +    int hue = videoinput_get_hue( vidin );
  8530. +    if( hue + offset >= 0 ) {
  8531. +        videoinput_set_hue( vidin, hue + offset );
  8532. +    }
  8533. +}
  8534. +
  8535. +int videoinput_get_brightness( videoinput_t *vidin )
  8536. +{
  8537. +    if( vidin->isv4l2 ) {
  8538. +        return (int) ((videoinput_get_control_v4l2( vidin, V4L2_CID_BRIGHTNESS ) * 100.0) + 0.5);
  8539. +    } else {
  8540. +        struct video_picture grab_pict;
  8541. +
  8542. +        if( ioctl( vidin->grab_fd, VIDIOCGPICT, &grab_pict ) >= 0 ) {
  8543. +            return (int) ((((double) grab_pict.brightness / 65535.0) * 100.0) + 0.5);
  8544. +        }
  8545. +    }
  8546. +
  8547. +    return 0;
  8548. +}
  8549. +
  8550. +void videoinput_set_brightness( videoinput_t *vidin, int newbright )
  8551. +{
  8552. +    if( newbright > 100 ) newbright = 100;
  8553. +    if( newbright <   0 ) newbright = 50;
  8554. +
  8555. +    if( vidin->isv4l2 ) {
  8556. +        videoinput_set_control_v4l2( vidin, V4L2_CID_BRIGHTNESS, ((double) newbright) / 100.0 );
  8557. +    } else {
  8558. +        struct video_picture grab_pict;
  8559. +
  8560. +        if( ioctl( vidin->grab_fd, VIDIOCGPICT, &grab_pict ) >= 0 ) {
  8561. +            grab_pict.brightness = (int) (((((double) newbright) / 100.0) * 65535.0) + 0.5);
  8562. +            ioctl( vidin->grab_fd, VIDIOCSPICT, &grab_pict );
  8563. +        }
  8564. +    }
  8565. +}
  8566. +
  8567. +void videoinput_set_brightness_relative( videoinput_t *vidin, int offset )
  8568. +{
  8569. +    int brightness = videoinput_get_brightness( vidin );
  8570. +    if( brightness + offset >= 0 ) {
  8571. +        videoinput_set_brightness( vidin, brightness + offset );
  8572. +    }
  8573. +}
  8574. +
  8575. +int videoinput_get_contrast( videoinput_t *vidin )
  8576. +{
  8577. +    if( vidin->isv4l2 ) {
  8578. +        return (int) ((videoinput_get_control_v4l2( vidin, V4L2_CID_CONTRAST ) * 100.0) + 0.5);
  8579. +    } else {
  8580. +        struct video_picture grab_pict;
  8581. +
  8582. +        if( ioctl( vidin->grab_fd, VIDIOCGPICT, &grab_pict ) >= 0 ) {
  8583. +            return (int) ((((double) grab_pict.contrast / 65535.0) * 100.0) + 0.5);
  8584. +        }
  8585. +    }
  8586. +
  8587. +    return 0;
  8588. +}
  8589. +
  8590. +void videoinput_set_contrast( videoinput_t *vidin, int newcont )
  8591. +{
  8592. +    if( newcont > 100 ) newcont = 100;
  8593. +    if( newcont <   0 ) newcont = 50;
  8594. +
  8595. +    if( vidin->isv4l2 ) {
  8596. +        videoinput_set_control_v4l2( vidin, V4L2_CID_CONTRAST, ((double) newcont) / 100.0 );
  8597. +    } else {
  8598. +        struct video_picture grab_pict;
  8599. +
  8600. +        if( ioctl( vidin->grab_fd, VIDIOCGPICT, &grab_pict ) >= 0 ) {
  8601. +            grab_pict.contrast = (int) (((((double) newcont) / 100.0) * 65535.0) + 0.5);
  8602. +            ioctl( vidin->grab_fd, VIDIOCSPICT, &grab_pict );
  8603. +        }
  8604. +    }
  8605. +}
  8606. +
  8607. +void videoinput_set_contrast_relative( videoinput_t *vidin, int offset )
  8608. +{
  8609. +    int contrast = videoinput_get_contrast( vidin );
  8610. +    if( contrast + offset >= 0 ) {
  8611. +        videoinput_set_contrast( vidin, contrast + offset );
  8612. +    }
  8613. +}
  8614. +
  8615. +int videoinput_get_saturation( videoinput_t *vidin )
  8616. +{
  8617. +    if( vidin->isv4l2 ) {
  8618. +        return (int) ((videoinput_get_control_v4l2( vidin, V4L2_CID_SATURATION ) * 100.0) + 0.5);
  8619. +    } else {
  8620. +        struct video_picture grab_pict;
  8621. +
  8622. +        if( ioctl( vidin->grab_fd, VIDIOCGPICT, &grab_pict ) >= 0 ) {
  8623. +            return (int) ((((double) grab_pict.colour / 65535.0) * 100.0) + 0.5);
  8624. +        }
  8625. +    }
  8626. +
  8627. +    return 0;
  8628. +}
  8629. +
  8630. +void videoinput_set_saturation( videoinput_t *vidin, int newsaturation )
  8631. +{
  8632. +    if( newsaturation > 100 ) newsaturation = 100;
  8633. +    if( newsaturation <   0 ) newsaturation = 50;
  8634. +
  8635. +    if( vidin->isv4l2 ) {
  8636. +        videoinput_set_control_v4l2( vidin, V4L2_CID_SATURATION, ((double) newsaturation) / 100.0 );
  8637. +    } else {
  8638. +        struct video_picture grab_pict;
  8639. +
  8640. +        if( ioctl( vidin->grab_fd, VIDIOCGPICT, &grab_pict ) >= 0 ) {
  8641. +            grab_pict.colour = (int) (((((double) newsaturation) / 100.0) * 65535.0) + 0.5);
  8642. +            ioctl( vidin->grab_fd, VIDIOCSPICT, &grab_pict );
  8643. +        }
  8644. +    }
  8645. +}
  8646. +
  8647. +void videoinput_set_saturation_relative( videoinput_t *vidin, int offset )
  8648. +{
  8649. +    int saturation = videoinput_get_saturation( vidin );
  8650. +    if( saturation + offset >= 0 ) {
  8651. +        videoinput_set_saturation( vidin, saturation + offset );
  8652. +    }
  8653. +}
  8654. +
  8655. +float videoinput_get_aspect( videoinput_t *vidin )
  8656. +{
  8657. +    float aspect = 1.0;
  8658. +
  8659. +    if( vidin->isv4l2 ) {
  8660. +        struct v4l2_cropcap cropcap;
  8661. +        /* on success 0 is returned */
  8662. +        if( !ioctl( vidin->grab_fd, VIDIOC_CROPCAP, &cropcap ) ) {
  8663. +            aspect = (float)cropcap.pixelaspect.numerator / (float)cropcap.pixelaspect.denominator;
  8664. +            fprintf( stderr, "videoinput: Aspect ratio: %f\n", aspect);        
  8665. +        }
  8666. +    }
  8667. +  
  8668. +    return aspect;
  8669. +}
  8670. +
  8671. +static void videoinput_do_mute( videoinput_t *vidin, int mute )
  8672. +{
  8673. +    if( vidin->hasaudio && mute != vidin->hw_muted ) {
  8674. +        if( vidin->isv4l2 ) {
  8675. +            struct v4l2_control control;
  8676. +
  8677. +            control.id = V4L2_CID_AUDIO_MUTE;
  8678. +            control.value = mute ? 1 : 0;
  8679. +
  8680. +            if( ioctl( vidin->grab_fd, VIDIOC_S_CTRL, &control ) < 0 ) {
  8681. +                fprintf( stderr, "videoinput: Can't mute card.  Post a bug report with your\n"
  8682. +                                 "videoinput: driver info to " PACKAGE_BUGREPORT "\n" );
  8683. +                fprintf( stderr, "videoinput: Include this error: '%s'\n", strerror( errno ) );
  8684. +            }
  8685. +
  8686. +            if( !mute && vidin->volume > 0 ) {
  8687. +                videoinput_set_control_v4l2( vidin, V4L2_CID_AUDIO_VOLUME, ((double) vidin->volume) / 100.0 );
  8688. +            }
  8689. +        } else {
  8690. +            struct video_audio audio;
  8691. +
  8692. +            if( ioctl( vidin->grab_fd, VIDIOCGAUDIO, &audio ) < 0 ) {
  8693. +                fprintf( stderr, "videoinput: Audio state query failed (got '%s').\n",
  8694. +                         strerror( errno ) );
  8695. +            } else {
  8696. +                if( mute ) {
  8697. +                    audio.flags |= VIDEO_AUDIO_MUTE;
  8698. +                } else {
  8699. +                    audio.flags &= ~VIDEO_AUDIO_MUTE;
  8700. +                }
  8701. +                if( vidin->volume > 0 ) {
  8702. +                    audio.volume = (vidin->volume * 65535) / 100;
  8703. +                }
  8704. +
  8705. +                if( ioctl( vidin->grab_fd, VIDIOCSAUDIO, &audio ) < 0 ) {
  8706. +                    fprintf( stderr, "videoinput: Can't set audio settings.  I have no idea what "
  8707. +                             "might cause this.  Post a bug report with your driver info to "
  8708. +                             PACKAGE_BUGREPORT "\n" );
  8709. +                    fprintf( stderr, "videoinput: Include this error: '%s'\n", strerror( errno ) );
  8710. +                }
  8711. +            }
  8712. +        }
  8713. +        vidin->hw_muted = mute;
  8714. +    }
  8715. +}
  8716. +
  8717. +void videoinput_set_audio_mode( videoinput_t *vidin, int mode )
  8718. +{
  8719. +    if( mode == VIDEOINPUT_LANG1 && vidin->norm == VIDEOINPUT_NTSC ) {
  8720. +        mode = VIDEOINPUT_LANG2;
  8721. +    }
  8722. +
  8723. +    if( mode > VIDEOINPUT_LANG2 ) {
  8724. +        mode = VIDEOINPUT_MONO;
  8725. +    }
  8726. +
  8727. +    if( vidin->audiomode != mode ) {
  8728. +        if( vidin->isv4l2 ) {
  8729. +            if( vidin->hastuner ) {
  8730. +                struct v4l2_tuner tuner;
  8731. +
  8732. +                memset( &tuner, 0, sizeof( struct v4l2_tuner ) );
  8733. +                tuner.index = vidin->tunerid;
  8734. +                tuner.audmode = videoinput_get_audmode_v4l2( mode );
  8735. +                if( ioctl( vidin->grab_fd, VIDIOC_S_TUNER, &tuner ) < 0 ) {
  8736. +                    fprintf( stderr, "videoinput: Can't set tuner audio mode: %s\n",
  8737. +                             strerror( errno ) );
  8738. +                } else {
  8739. +                    vidin->audiomode = mode;
  8740. +                }
  8741. +            }
  8742. +        } else {
  8743. +            struct video_audio audio;
  8744. +
  8745. +            if( ioctl( vidin->grab_fd, VIDIOCGAUDIO, &audio ) < 0 ) {
  8746. +                if( vidin->verbose ) {
  8747. +                    fprintf( stderr, "videoinput: Audio state query failed (got '%s').\n",
  8748. +                             strerror( errno ) );
  8749. +                }
  8750. +            } else {
  8751. +                int was_muted = (audio.flags & VIDEO_AUDIO_MUTE);
  8752. +
  8753. +                /* Set the mode. */
  8754. +                audio.mode = mode;
  8755. +                if( ioctl( vidin->grab_fd, VIDIOCSAUDIO, &audio ) < 0 ) {
  8756. +                    fprintf( stderr, "videoinput: Can't set audio mode setting.  I have no idea what "
  8757. +                             "might cause this.  Post a bug report with your driver info to "
  8758. +                             PACKAGE_BUGREPORT "\n" );
  8759. +                    fprintf( stderr, "videoinput: Include this error: '%s'\n", strerror( errno ) );
  8760. +                } else {
  8761. +                    vidin->audiomode = mode;
  8762. +                }
  8763. +
  8764. +                if( was_muted & !(audio.flags & VIDEO_AUDIO_MUTE) ) {
  8765. +                    /* Stupid card dropped the mute state, have to go back to being muted. */
  8766. +                    vidin->hw_muted = 0;
  8767. +                    videoinput_do_mute( vidin, 1 );
  8768. +                }
  8769. +            }
  8770. +        }
  8771. +    }
  8772. +}
  8773. +
  8774. +/* freqKHz is in KHz (duh) */
  8775. +void videoinput_set_tuner_freq( videoinput_t *vidin, int freqKHz )
  8776. +{
  8777. +    unsigned long frequency = freqKHz;
  8778. +
  8779. +    if( videoinput_has_tuner( vidin ) ) {
  8780. +        if( frequency < 0 ) {
  8781. +            /* Ignore bogus frequencies. */
  8782. +            return;
  8783. +        }
  8784. +
  8785. +        frequency *= 16;
  8786. +
  8787. +        if( !vidin->tunerlow ) {
  8788. +            frequency /= 1000; /* switch to MHz */
  8789. +        }
  8790. +
  8791. +        vidin->change_muted = 1;
  8792. +        mixer->mute( 1 );
  8793. +        videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
  8794. +        vidin->cur_tuner_state = TUNER_STATE_SIGNAL_DETECTED;
  8795. +        vidin->signal_acquire_wait = SIGNAL_ACQUIRE_DELAY;
  8796. +        vidin->signal_recover_wait = 0;
  8797. +
  8798. +        if( vidin->isv4l2 ) {
  8799. +            struct v4l2_frequency freqinfo;
  8800. +            int wasstreaming = vidin->is_streaming;
  8801. +
  8802. +            memset( &freqinfo, 0, sizeof( struct v4l2_frequency ) );
  8803. +            freqinfo.tuner = vidin->tunerid;
  8804. +            freqinfo.type = V4L2_TUNER_ANALOG_TV;
  8805. +            freqinfo.frequency = frequency;
  8806. +
  8807. +            videoinput_stop_capture_v4l2( vidin );
  8808. +            if( ioctl( vidin->grab_fd, VIDIOC_S_FREQUENCY, &freqinfo ) < 0 ) {
  8809. +                fprintf( stderr, "videoinput: Tuner present, but our request to change to\n"
  8810. +                         "videoinput: frequency %d failed with this error: %s.\n", freqKHz, strerror( errno ) );
  8811. +                fprintf( stderr, "videoinput: Please file a bug report at " PACKAGE_BUGREPORT "\n" );
  8812. +            }
  8813. +            if( wasstreaming ) {
  8814. +                videoinput_free_all_frames( vidin );
  8815. +                videoinput_start_capture_v4l2( vidin );
  8816. +            }
  8817. +        } else {
  8818. +            if( ioctl( vidin->grab_fd, VIDIOCSFREQ, &frequency ) < 0 ) {
  8819. +                fprintf( stderr, "videoinput: Tuner present, but our request to change "
  8820. +                                 "to frequency %d failed with this error: %s.\n", freqKHz, strerror( errno ) );
  8821. +                fprintf( stderr, "videoinput: Please file a bug report at " PACKAGE_BUGREPORT "\n" );
  8822. +            }
  8823. +        }
  8824. +    }
  8825. +}
  8826. +
  8827. +int videoinput_get_tuner_freq( videoinput_t *vidin )
  8828. +{
  8829. +    if( vidin->hastuner ) {
  8830. +        unsigned long frequency;
  8831. +
  8832. +        if( vidin->isv4l2 ) {
  8833. +            struct v4l2_frequency freqinfo;
  8834. +
  8835. +            freqinfo.tuner = vidin->tunerid;
  8836. +            freqinfo.type = V4L2_TUNER_ANALOG_TV;
  8837. +
  8838. +            if( ioctl( vidin->grab_fd, VIDIOC_G_FREQUENCY, &freqinfo ) < 0 ) {
  8839. +                fprintf( stderr, "videoinput: Tuner refuses to tell us the current frequency: %s\n",
  8840. +                         strerror( errno ) );
  8841. +                fprintf( stderr, "videoinput: Please file a bug report at " PACKAGE_BUGREPORT "\n" );
  8842. +                return 0;
  8843. +            }
  8844. +            frequency = freqinfo.frequency;
  8845. +        } else {
  8846. +            if( ioctl( vidin->grab_fd, VIDIOCGFREQ, &frequency ) < 0 ) {
  8847. +                fprintf( stderr, "videoinput: Tuner refuses to tell us the current frequency: %s\n",
  8848. +                         strerror( errno ) );
  8849. +                fprintf( stderr, "videoinput: Please file a bug report at " PACKAGE_BUGREPORT "\n" );
  8850. +                return 0;
  8851. +            }
  8852. +        }
  8853. +
  8854. +        if( !vidin->tunerlow ) {
  8855. +            frequency *= 1000; /* switch from MHz to KHz */
  8856. +        }
  8857. +
  8858. +        return frequency / 16;
  8859. +    }
  8860. +    return 0;
  8861. +}
  8862. +
  8863. +int videoinput_freq_present( videoinput_t *vidin )
  8864. +{
  8865. +    if( videoinput_has_tuner( vidin ) ) {
  8866. +        if( vidin->isv4l2 ) {
  8867. +            struct v4l2_tuner tuner;
  8868. +
  8869. +            tuner.index = vidin->tunerid;
  8870. +            if( ioctl( vidin->grab_fd, VIDIOC_G_TUNER, &tuner ) < 0 ) {
  8871. +                if( vidin->verbose ) {
  8872. +                    fprintf( stderr, "videoinput: Cannot detect signal from tuner: %s\n",
  8873. +                             strerror( errno ) );
  8874. +                }
  8875. +            } else if( !tuner.signal ) {
  8876. +                return 0;
  8877. +            }
  8878. +        } else {
  8879. +            struct video_tuner tuner;
  8880. +
  8881. +            if( ioctl( vidin->grab_fd, VIDIOCGTUNER, &tuner ) < 0 ) {
  8882. +                if( vidin->verbose ) {
  8883. +                    fprintf( stderr, "videoinput: Cannot detect signal from tuner: %s\n",
  8884. +                             strerror( errno ) );
  8885. +                }
  8886. +            } else if( !tuner.signal ) {
  8887. +                return 0;
  8888. +            }
  8889. +        }
  8890. +    }
  8891. +    return 1;
  8892. +}
  8893. +
  8894. +/**
  8895. + * Finds an appropriate tuner.
  8896. + */
  8897. +static void videoinput_find_and_set_tuner( videoinput_t *vidin )
  8898. +{
  8899. +    if( vidin->isv4l2 ) {
  8900. +        struct v4l2_tuner tuner;
  8901. +
  8902. +        tuner.index = vidin->tunerid;
  8903. +        if( ioctl( vidin->grab_fd, VIDIOC_G_TUNER, &tuner ) < 0 ) {
  8904. +            fprintf( stderr, "videoinput: Can't get tuner info: %s\n",
  8905. +                     strerror( errno ) );
  8906. +        } else {
  8907. +            vidin->tunerlow = (tuner.capability & V4L2_TUNER_CAP_LOW) ? 1 : 0;
  8908. +        }
  8909. +    } else {
  8910. +        struct video_tuner tuner;
  8911. +        int tuner_number = -1;
  8912. +        int found = 0;
  8913. +        int i;
  8914. +
  8915. +        for( i = 0; i < vidin->numtuners; i++ ) {
  8916. +            tuner.tuner = i;
  8917. +
  8918. +            if( ioctl( vidin->grab_fd, VIDIOCGTUNER, &tuner ) >= 0 ) {
  8919. +                if( ((vidin->norm == VIDEOINPUT_PAL || vidin->norm == VIDEOINPUT_PAL_NC || vidin->norm == VIDEOINPUT_PAL_N) && tuner.flags & VIDEO_TUNER_PAL) ||
  8920. +                    (vidin->norm == VIDEOINPUT_SECAM && tuner.flags & VIDEO_TUNER_SECAM) ||
  8921. +                    ((vidin->norm == VIDEOINPUT_NTSC || vidin->norm == VIDEOINPUT_NTSC_JP || vidin->norm == VIDEOINPUT_PAL_M) && tuner.flags & VIDEO_TUNER_NTSC) ) {
  8922. +                    found = 1;
  8923. +                    tuner_number = i;
  8924. +                    break;
  8925. +                }
  8926. +            }
  8927. +        }
  8928. +
  8929. +        if( found ) {
  8930. +            int mustchange = 0;
  8931. +
  8932. +            tuner.tuner = tuner_number;
  8933. +
  8934. +            if( vidin->norm == VIDEOINPUT_PAL || vidin->norm == VIDEOINPUT_PAL_NC || vidin->norm == VIDEOINPUT_PAL_N ) {
  8935. +                if( tuner.mode != VIDEO_MODE_PAL ) {
  8936. +                    mustchange = 1;
  8937. +                    tuner.mode = VIDEO_MODE_PAL;
  8938. +                }
  8939. +            } else if( vidin->norm == VIDEOINPUT_SECAM ) {
  8940. +                if( tuner.mode != VIDEO_MODE_SECAM ) {
  8941. +                    mustchange = 1;
  8942. +                    tuner.mode = VIDEO_MODE_SECAM;
  8943. +                }
  8944. +            } else {
  8945. +                if( tuner.mode != VIDEO_MODE_NTSC ) {
  8946. +                    mustchange = 1;
  8947. +                    tuner.mode = VIDEO_MODE_NTSC;
  8948. +                }
  8949. +            }
  8950. +
  8951. +            if( mustchange ) {
  8952. +                struct video_channel grab_chan;
  8953. +
  8954. +                if( ioctl( vidin->grab_fd, VIDIOCSTUNER, &tuner ) < 0 ) {
  8955. +                    fprintf( stderr, "videoinput: Tuner is not in the correct mode, and we can't set it.\n"
  8956. +                             "            Please file a bug report at " PACKAGE_BUGREPORT "\n"
  8957. +                             "            indicating your card, driver and this error message: %s.\n",
  8958. +                             strerror( errno ) );
  8959. +                }
  8960. +
  8961. +                /**
  8962. +                 * After setting the tuner, we need to re-set the norm on our channel.
  8963. +                 * Doing this fixes PAL-M, at least with the bttv driver in 2.4.20.
  8964. +                 * I am not happy with this, as I haven't seen it documented anywhere.
  8965. +                 * Please correct me if I'm wrong.
  8966. +                 */
  8967. +                grab_chan.channel = vidin->curinput;
  8968. +                grab_chan.norm = videoinput_get_v4l1_norm( vidin->norm );
  8969. +
  8970. +                if( ioctl( vidin->grab_fd, VIDIOCSCHAN, &grab_chan ) < 0 ) {
  8971. +                    fprintf( stderr, "videoinput: Card refuses to re-set the channel.\n"
  8972. +                             "Please post a bug report to " PACKAGE_BUGREPORT "\n"
  8973. +                             "indicating your card, driver, and this error message: %s.\n", strerror( errno ) );
  8974. +                } else {
  8975. +                    vidin->numtuners = grab_chan.tuners;
  8976. +                }
  8977. +            }
  8978. +        }
  8979. +
  8980. +        if( vidin->numtuners > 0 ) {
  8981. +            tuner.tuner = tuner_number;
  8982. +
  8983. +            if( ioctl( vidin->grab_fd, VIDIOCGTUNER, &tuner ) < 0 ) {
  8984. +                fprintf( stderr, "videoinput: Input indicates that tuners are available, but "
  8985. +                         "driver refuses to give information about them.\n"
  8986. +                         "videoinput: Please file a bug report at " PACKAGE_BUGREPORT
  8987. +                         " and indicate that card and driver you have.\n" );
  8988. +                fprintf( stderr, "videoinput: Also include this error: '%s'\n", strerror( errno ) );
  8989. +                return;
  8990. +            }
  8991. +
  8992. +            if( vidin->verbose ) {
  8993. +                fprintf( stderr, "videoinput: Tuner %s (",
  8994. +                          tuner.name );
  8995. +
  8996. +                switch (tuner.mode) {
  8997. +                case VIDEO_MODE_PAL: fprintf( stderr, "PAL" ); break;
  8998. +                case VIDEO_MODE_NTSC: fprintf( stderr, "NTSC" ); break;
  8999. +                case VIDEO_MODE_SECAM: fprintf( stderr, "SECAM" ); break;
  9000. +                case VIDEO_MODE_AUTO: fprintf( stderr, "AUTO" ); break;
  9001. +                default: fprintf( stderr, "UNDEFINED" ); break;
  9002. +                }
  9003. +
  9004. +                fprintf( stderr, "), flags: " );
  9005. +
  9006. +                if( tuner.flags & VIDEO_TUNER_PAL ) fprintf( stderr, "PAL " );
  9007. +                if( tuner.flags & VIDEO_TUNER_NTSC ) fprintf( stderr, "NTSC " );
  9008. +                if( tuner.flags & VIDEO_TUNER_SECAM ) fprintf( stderr, "SECAM " );
  9009. +                if( tuner.flags & VIDEO_TUNER_LOW ) fprintf( stderr, "LOW " );
  9010. +                if( tuner.flags & VIDEO_TUNER_NORM ) fprintf( stderr, "NORM " );
  9011. +                if( tuner.flags & VIDEO_TUNER_STEREO_ON ) fprintf( stderr, "STEREO_ON " );
  9012. +                if( tuner.flags & VIDEO_TUNER_RDS_ON ) fprintf( stderr, "RDS_ON " );
  9013. +                if( tuner.flags & VIDEO_TUNER_MBS_ON ) fprintf( stderr, "MBS_ON" );
  9014. +                fprintf( stderr, "\n" );
  9015. +            }
  9016. +
  9017. +            vidin->tunerlow = (tuner.flags & VIDEO_TUNER_LOW) ? 1 : 0;
  9018. +            vidin->hastuner = 1;
  9019. +        }
  9020. +    }
  9021. +}
  9022. +
  9023. +
  9024. +void videoinput_set_input_num( videoinput_t *vidin, int inputnum )
  9025. +{
  9026. +    if( vidin->isv4l2 ) {
  9027. +        v4l2_std_id std;
  9028. +        int index = inputnum;
  9029. +        int wasstreaming = vidin->is_streaming;
  9030. +
  9031. +        videoinput_stop_capture_v4l2( vidin );
  9032. +
  9033. +        if( ioctl( vidin->grab_fd, VIDIOC_S_INPUT, &index ) < 0 ) {
  9034. +            fprintf( stderr, "videoinput: Card refuses to set its input.\n"
  9035. +                     "Please post a bug report to " PACKAGE_BUGREPORT "\n"
  9036. +                     "indicating your card, driver, and this error message: %s.\n",
  9037. +                     strerror( errno ) );
  9038. +        } else {
  9039. +            struct v4l2_input input;
  9040. +
  9041. +            if( ioctl( vidin->grab_fd, VIDIOC_G_INPUT, &input.index ) < 0 ) {
  9042. +                fprintf( stderr, "videoinput: Driver won't tell us its input: %s\n",
  9043. +                         strerror( errno ) );
  9044. +            } else if( input.index != inputnum ) {
  9045. +                fprintf( stderr, "videoinput: Driver refuses to switch to input %d.\n",
  9046. +                         inputnum );
  9047. +                inputnum = input.index;
  9048. +            }
  9049. +            vidin->curinput = inputnum;
  9050. +
  9051. +            if( ioctl( vidin->grab_fd, VIDIOC_ENUMINPUT, &input ) < 0 ) {
  9052. +                fprintf( stderr, "videoinput: Driver won't tell us input info: %s\n",
  9053. +                         strerror( errno ) );
  9054. +            } else {
  9055. +                snprintf( vidin->inputname, sizeof( vidin->inputname ), "%s", input.name );
  9056. +                vidin->hastuner = input.type == V4L2_INPUT_TYPE_TUNER;
  9057. +                vidin->tunerid = input.tuner;
  9058. +            }
  9059. +        }
  9060. +
  9061. +        if( ioctl( vidin->grab_fd, VIDIOC_G_STD, &std ) < 0 ) {
  9062. +            fprintf( stderr, "videoinput: Driver won't tell us its norm: %s\n",
  9063. +                     strerror( errno ) );
  9064. +        } else {
  9065. +            std = videoinput_get_v4l2_norm( vidin->norm );
  9066. +            if( std == V4L2_STD_PAL ) {
  9067. +                if( vidin->amode == VIDEOINPUT_PAL_DK_AUDIO ) {
  9068. +                    std = V4L2_STD_PAL_DK;
  9069. +                } else if( vidin->amode == VIDEOINPUT_PAL_I_AUDIO ) {
  9070. +                    std = V4L2_STD_PAL_I;
  9071. +                }
  9072. +            }
  9073. +            if( ioctl( vidin->grab_fd, VIDIOC_S_STD, &std ) < 0 ) {
  9074. +                fprintf( stderr, "videoinput: Driver refuses to set norm: %s\n",
  9075. +                         strerror( errno ) );
  9076. +            }
  9077. +        }
  9078. +
  9079. +        if( wasstreaming ) {
  9080. +            videoinput_free_all_frames( vidin );
  9081. +            videoinput_start_capture_v4l2( vidin );
  9082. +        }
  9083. +    } else {
  9084. +        if( inputnum >= vidin->numinputs ) {
  9085. +            fprintf( stderr, "videoinput: Requested input number %d not valid, "
  9086. +                     "max is %d.\n", inputnum, vidin->numinputs );
  9087. +        } else {
  9088. +            struct video_channel grab_chan;
  9089. +
  9090. +            grab_chan.channel = inputnum;
  9091. +            if( ioctl( vidin->grab_fd, VIDIOCGCHAN, &grab_chan ) < 0 ) {
  9092. +                fprintf( stderr, "videoinput: Card refuses to give information on its current input.\n"
  9093. +                         "Please post a bug report to " PACKAGE_BUGREPORT "\n"
  9094. +                         "indicating your card, driver, and this error message: %s.\n", strerror( errno ) );
  9095. +            } else {
  9096. +                grab_chan.channel = inputnum;
  9097. +                grab_chan.norm = videoinput_get_v4l1_norm( vidin->norm );
  9098. +
  9099. +                if( ioctl( vidin->grab_fd, VIDIOCSCHAN, &grab_chan ) < 0 ) {
  9100. +                    fprintf( stderr, "videoinput: Card refuses to set the channel.\n"
  9101. +                             "Please post a bug report to " PACKAGE_BUGREPORT "\n"
  9102. +                             "indicating your card, driver, and this error message: %s.\n", strerror( errno ) );
  9103. +                }
  9104. +
  9105. +                vidin->curinput = inputnum;
  9106. +                if( ioctl( vidin->grab_fd, VIDIOCGCHAN, &grab_chan ) < 0 ) {
  9107. +                    fprintf( stderr, "videoinput: Card refuses to give information on its current input.\n"
  9108. +                             "Please post a bug report to " PACKAGE_BUGREPORT "\n"
  9109. +                             "indicating your card, driver, and this error message: %s.\n", strerror( errno ) );
  9110. +                } else {
  9111. +                    snprintf( vidin->inputname, sizeof( vidin->inputname ), "%s", grab_chan.name );
  9112. +                    vidin->numtuners = grab_chan.tuners;
  9113. +                    vidin->hastuner = (vidin->numtuners > 0);
  9114. +                }
  9115. +            }
  9116. +        }
  9117. +    }
  9118. +
  9119. +    /* Once we've set the input, go look for a tuner. */
  9120. +    videoinput_find_and_set_tuner( vidin );
  9121. +}
  9122. +
  9123. +int videoinput_check_for_signal( videoinput_t *vidin, int check_freq_present )
  9124. +{
  9125. +    if( videoinput_freq_present( vidin ) || !check_freq_present ) {
  9126. +        switch( vidin->cur_tuner_state ) {
  9127. +        case TUNER_STATE_NO_SIGNAL:
  9128. +        case TUNER_STATE_SIGNAL_LOST:
  9129. +            vidin->cur_tuner_state = TUNER_STATE_SIGNAL_DETECTED;
  9130. +            vidin->signal_acquire_wait = SIGNAL_ACQUIRE_DELAY;
  9131. +            vidin->signal_recover_wait = 0;
  9132. +        case TUNER_STATE_SIGNAL_DETECTED:
  9133. +            if( vidin->signal_acquire_wait ) {
  9134. +                vidin->signal_acquire_wait--;
  9135. +                break;
  9136. +            } else {
  9137. +                vidin->cur_tuner_state = TUNER_STATE_HAS_SIGNAL;
  9138. +            }
  9139. +        default:
  9140. +            if( vidin->change_muted ) {
  9141. +                vidin->change_muted = 0;
  9142. +                videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
  9143. +                mixer->mute( 0 );
  9144. +            }
  9145. +            break;
  9146. +        }
  9147. +    } else {
  9148. +        switch( vidin->cur_tuner_state ) {
  9149. +        case TUNER_STATE_HAS_SIGNAL:
  9150. +        case TUNER_STATE_SIGNAL_DETECTED:
  9151. +            vidin->cur_tuner_state = TUNER_STATE_SIGNAL_LOST;
  9152. +            vidin->signal_recover_wait = SIGNAL_RECOVER_DELAY;
  9153. +            vidin->change_muted = 1;
  9154. +            mixer->mute( 1 );
  9155. +            videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
  9156. +        case TUNER_STATE_SIGNAL_LOST:
  9157. +            if( vidin->signal_recover_wait ) {
  9158. +                vidin->signal_recover_wait--;
  9159. +                break;
  9160. +            } else {
  9161. +                vidin->cur_tuner_state = TUNER_STATE_NO_SIGNAL;
  9162. +            }
  9163. +        default: break;
  9164. +        }
  9165. +    }
  9166. +
  9167. +    return vidin->cur_tuner_state;
  9168. +}
  9169. +
  9170. +void videoinput_toggle_pal_secam( videoinput_t *vidin )
  9171. +{
  9172. +    if( vidin->norm == VIDEOINPUT_PAL ) {
  9173. +        vidin->norm = VIDEOINPUT_SECAM;
  9174. +    } else {
  9175. +        vidin->norm = VIDEOINPUT_PAL;
  9176. +    }
  9177. +    videoinput_set_input_num( vidin, videoinput_get_input_num( vidin ) );
  9178. +}
  9179. +
  9180. +void videoinput_switch_pal_secam( videoinput_t *vidin, int norm )
  9181. +{
  9182. +    if( norm != vidin->norm && (norm == VIDEOINPUT_PAL || norm == VIDEOINPUT_SECAM) ) {
  9183. +        vidin->norm = norm;
  9184. +        videoinput_set_input_num( vidin, videoinput_get_input_num( vidin ) );
  9185. +    }
  9186. +}
  9187. +
  9188. +void videoinput_mute( videoinput_t *vidin, int mute )
  9189. +{
  9190. +    vidin->user_muted = mute;
  9191. +    videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
  9192. +}
  9193. +
  9194. +int videoinput_get_muted( videoinput_t *vidin )
  9195. +{
  9196. +    return vidin->user_muted;
  9197. +}
  9198. +
  9199. +int videoinput_get_audio_mode( videoinput_t *vidin )
  9200. +{
  9201. +    if( !vidin->audiomode || vidin->audiomode > VIDEO_SOUND_LANG2 ) {
  9202. +        return VIDEO_SOUND_MONO;
  9203. +    } else {
  9204. +        return vidin->audiomode;
  9205. +    }
  9206. +}
  9207. +
  9208. +void videoinput_set_pal_audio_mode( videoinput_t *vidin, int amode )
  9209. +{
  9210. +    if( amode != vidin->amode && vidin->norm == VIDEOINPUT_PAL ) {
  9211. +        vidin->amode = amode;
  9212. +        videoinput_set_input_num( vidin, videoinput_get_input_num( vidin ) );
  9213. +    }
  9214. +}
  9215. +
  9216. +int videoinput_get_pal_audio_mode( videoinput_t *vidin )
  9217. +{
  9218. +    if( !vidin ) return 0;
  9219. +    return vidin->amode;
  9220. +}
  9221. +
  9222. +int videoinput_has_tuner( videoinput_t *vidin )
  9223. +{
  9224. +    return vidin->hastuner;
  9225. +}
  9226. +
  9227. +int videoinput_get_width( videoinput_t *vidin )
  9228. +{
  9229. +    return vidin->width;
  9230. +}
  9231. +
  9232. +int videoinput_get_height( videoinput_t *vidin )
  9233. +{
  9234. +    return vidin->height;
  9235. +}
  9236. +
  9237. +int videoinput_get_maxwidth( videoinput_t *vidin )
  9238. +{
  9239. +    return vidin->maxwidth;
  9240. +}
  9241. +
  9242. +int videoinput_get_norm( videoinput_t *vidin )
  9243. +{
  9244. +    return vidin->norm;
  9245. +}
  9246. +
  9247. +int videoinput_get_numframes( videoinput_t *vidin )
  9248. +{
  9249. +    return vidin->numframes;
  9250. +}
  9251. +
  9252. +int videoinput_get_num_inputs( videoinput_t *vidin )
  9253. +{
  9254. +    return vidin->numinputs;
  9255. +}
  9256. +
  9257. +int videoinput_is_bttv( videoinput_t *vidin )
  9258. +{
  9259. +    return vidin->isbttv;
  9260. +}
  9261. +
  9262. +int videoinput_is_uyvy( videoinput_t *vidin )
  9263. +{
  9264. +    return vidin->isuyvy;
  9265. +}
  9266. +
  9267. +int videoinput_is_v4l2( videoinput_t *vidin )
  9268. +{
  9269. +    return vidin->isv4l2;
  9270. +}
  9271. +
  9272. +int videoinput_get_input_num( videoinput_t *vidin )
  9273. +{
  9274. +    return vidin->curinput;
  9275. +}
  9276. +
  9277. +const char *videoinput_get_input_name( videoinput_t *vidin )
  9278. +{
  9279. +    return vidin->inputname;
  9280. +}
  9281. +
  9282. +const char *videoinput_get_driver_name( videoinput_t *vidin )
  9283. +{
  9284. +    return vidin->drivername;
  9285. +}
  9286. +
  9287. +void videoinput_set_capture_volume( videoinput_t *vidin, int volume )
  9288. +{
  9289. +    vidin->volume = volume;
  9290. +    if( vidin->volume >= 0 ) {
  9291. +        if( vidin->isv4l2 ) {
  9292. +            videoinput_set_control_v4l2( vidin, V4L2_CID_AUDIO_VOLUME,
  9293. +                                         ((double) vidin->volume) / 100.0 );
  9294. +        } else {
  9295. +            struct video_audio audio;
  9296. +
  9297. +            if( ioctl( vidin->grab_fd, VIDIOCGAUDIO, &audio ) < 0 ) {
  9298. +                fprintf( stderr, "videoinput: Audio state query failed (got '%s').\n",
  9299. +                         strerror( errno ) );
  9300. +            } else {
  9301. +                if( vidin->volume > 0 ) {
  9302. +                    audio.volume = (vidin->volume * 65535) / 100;
  9303. +                }
  9304. +
  9305. +                if( ioctl( vidin->grab_fd, VIDIOCSAUDIO, &audio ) < 0 ) {
  9306. +                    fprintf( stderr, "videoinput: Can't set audio settings.  I have no idea what "
  9307. +                             "might cause this.  Post a bug report with your driver info to "
  9308. +                             PACKAGE_BUGREPORT "\n" );
  9309. +                    fprintf( stderr, "videoinput: Include this error: '%s'\n", strerror( errno ) );
  9310. +                }
  9311. +            }
  9312. +        }
  9313. +    }
  9314. +}
  9315. +
  9316. diff -Nurp tvtime-1.0.2/src/videoinput.h tvtime-1.0.2-custom/src/videoinput.h
  9317. --- tvtime-1.0.2/src/videoinput.h       2005-09-08 04:55:10.000000000 +0200
  9318. +++ tvtime-1.0.2-custom/src/videoinput.h        2011-05-29 13:07:28.185707644 +0200
  9319. @@ -71,6 +71,8 @@ typedef struct videoinput_s videoinput_t
  9320.  #define VIDEOINPUT_LANG1   4
  9321.  #define VIDEOINPUT_LANG2   8
  9322.  
  9323. +float videoinput_get_aspect( videoinput_t *vidin );
  9324. +
  9325.  /**
  9326.   * Possible PAL audio modes, for the cx88 driver that cannot autodetect.
  9327.   */
  9328. diff -Nurp tvtime-1.0.2/src/xcommon.c tvtime-1.0.2-custom/src/xcommon.c
  9329. --- tvtime-1.0.2/src/xcommon.c  2005-08-14 19:36:52.000000000 +0200
  9330. +++ tvtime-1.0.2-custom/src/xcommon.c   2011-05-29 13:07:28.245708378 +0200
  9331. @@ -25,6 +25,7 @@
  9332.  #include <stdio.h>
  9333.  #include <stdlib.h>
  9334.  #include <string.h>
  9335. +#include <unistd.h>
  9336.  
  9337.  #if defined(__FreeBSD__)
  9338.  #include <machine/param.h>
  9339. @@ -45,8 +46,8 @@
  9340.  #include <X11/keysym.h>
  9341.  #include <X11/cursorfont.h>
  9342.  #include <X11/extensions/XShm.h>
  9343. -#ifdef HAVE_XTESTEXTENSION
  9344. -#include <X11/extensions/XTest.h>
  9345. +#ifdef HAVE_XSSEXTENSION
  9346. +#include <X11/extensions/scrnsaver.h>
  9347.  #endif
  9348.  
  9349.  #include "xfullscreen.h"
  9350. @@ -67,7 +68,7 @@ static Window wm_window;
  9351.  static Window fs_window;
  9352.  static Window output_window;
  9353.  static GC gc;
  9354. -static int have_xtest;
  9355. +static int have_xss;
  9356.  static int output_width, output_height;
  9357.  static int output_aspect;
  9358.  static int output_on_root;
  9359. @@ -106,10 +107,7 @@ static Atom wm_protocols;
  9360.  static Atom wm_delete_window;
  9361.  static Atom xawtv_station;
  9362.  static Atom xawtv_remote;
  9363. -
  9364. -#ifdef HAVE_XTESTEXTENSION
  9365. -static KeyCode kc_shift_l; /* Fake key to send. */
  9366. -#endif
  9367. +static Atom net_wm_pid;
  9368.  
  9369.  static area_t video_area;
  9370.  static area_t window_area;
  9371. @@ -150,11 +148,12 @@ static void load_atoms( Display *dpy )
  9372.          "WM_PROTOCOLS",
  9373.          "WM_DELETE_WINDOW",
  9374.          "_XAWTV_STATION",
  9375. -        "_XAWTV_REMOTE"
  9376. +        "_XAWTV_REMOTE",
  9377. +        "_NET_WM_PID"
  9378.      };
  9379. -    Atom atoms_return[ 17 ];
  9380. +    Atom atoms_return[ 18 ];
  9381.  
  9382. -    XInternAtoms( display, atom_names, 17, False, atoms_return );
  9383. +    XInternAtoms( display, atom_names, 18, False, atoms_return );
  9384.      net_supporting_wm_check = atoms_return[ 0 ];
  9385.      net_supported = atoms_return[ 1 ];
  9386.      net_wm_name = atoms_return[ 2 ];
  9387. @@ -172,6 +171,7 @@ static void load_atoms( Display *dpy )
  9388.      wm_delete_window = atoms_return[ 14 ];
  9389.      xawtv_station = atoms_return[ 15 ];
  9390.      xawtv_remote = atoms_return[ 16 ];
  9391. +    net_wm_pid = atoms_return[ 17 ];
  9392.  }
  9393.  
  9394.  static uint32_t icon_colours[256];
  9395. @@ -248,12 +248,12 @@ static void x11_wait_mapped( Display *dp
  9396.      } while ( (event.type != MapNotify) || (event.xmap.event != win) );
  9397.  }
  9398.  
  9399. -static int have_xtestextention( void )
  9400. +static int have_xssextention( void )
  9401.  {  
  9402. -#ifdef HAVE_XTESTEXTENSION
  9403. -    int dummy1, dummy2, dummy3, dummy4;
  9404. +#ifdef HAVE_XSSEXTENSION
  9405. +    int dummy1, dummy2;
  9406.    
  9407. -    return (XTestQueryExtension( display, &dummy1, &dummy2, &dummy3, &dummy4 ) == True);
  9408. +    return (XScreenSaverQueryExtension( display, &dummy1, &dummy2 ) == True);
  9409.  #endif
  9410.      return 0;
  9411.  }
  9412. @@ -843,7 +843,7 @@ int xcommon_open_display( const char *us
  9413.      output_aspect = aspect;
  9414.      output_height = 576;
  9415.  
  9416. -    have_xtest = 0;
  9417. +    have_xss = 0;
  9418.      output_on_root = 0;
  9419.      has_ewmh_state_fullscreen = 0;
  9420.      has_ewmh_state_above = 0;
  9421. @@ -927,13 +927,16 @@ int xcommon_open_display( const char *us
  9422.          xfullscreen_print_summary( xf );
  9423.      }
  9424.  
  9425. -#ifdef HAVE_XTESTEXTENSION
  9426. -    kc_shift_l = XKeysymToKeycode( display, XK_Shift_L );
  9427. -#endif
  9428. -    have_xtest = have_xtestextention();
  9429. -    if( have_xtest && xcommon_verbose ) {
  9430. -        fprintf( stderr, "xcommon: Have XTest, will use it to ping the screensaver.\n" );
  9431. +    have_xss = have_xssextention();
  9432. +    if( have_xss && xcommon_verbose ) {
  9433. +        fprintf( stderr, "xcommon: Have XSS, will use it to disable the screensaver.\n" );
  9434. +    }
  9435. +
  9436. +#ifdef HAVE_XSSEXTENSION
  9437. +    if ( have_xss ) {
  9438. +        XScreenSaverSuspend( display, True );
  9439.      }
  9440. +#endif
  9441.  
  9442.      /* Initially, get the best width for our height. */
  9443.      output_width = xv_get_width_for_height( output_height );
  9444. @@ -1017,6 +1020,16 @@ int xcommon_open_display( const char *us
  9445.              free( data );
  9446.          }
  9447.      }
  9448. +    
  9449. +    /* Set _NET_WM_PID */
  9450. +    {
  9451. +        if( xcommon_verbose ) {
  9452. +            fprintf( stderr, "xcommon: try to set _NET_WM_PID" );
  9453. +        }
  9454. +        pid_t mypid = getpid();
  9455. +        XChangeProperty(display, wm_window, net_wm_pid, cardinal, 32,
  9456. +                        PropModeReplace, (const unsigned char*) &mypid, 1);
  9457. +    }
  9458.  
  9459.      if( check_for_EWMH_wm( display, &wmname ) ) {
  9460.          if( xcommon_verbose ) {
  9461. @@ -1112,15 +1125,7 @@ void xcommon_ping_screensaver( void )
  9462.      gettimeofday( &curtime, 0 );
  9463.      if( timediff( &curtime, &last_ping_time ) > SCREENSAVER_PING_TIME ) {
  9464.          last_ping_time = curtime;
  9465. -#ifdef HAVE_XTESTEXTENSION
  9466. -        if( have_xtest ) {
  9467. -            XTestFakeKeyEvent( display, kc_shift_l, True, CurrentTime );
  9468. -            XTestFakeKeyEvent( display, kc_shift_l, False, CurrentTime );
  9469. -        } else
  9470. -#endif
  9471. -        {
  9472. -            XResetScreenSaver( display );
  9473. -        }
  9474. +        XResetScreenSaver( display );
  9475.      }
  9476.  }
  9477.  
  9478. @@ -1715,6 +1720,11 @@ void xcommon_poll_events( input_t *in )
  9479.  
  9480.  void xcommon_close_display( void )
  9481.  {
  9482. +#ifdef HAVE_XSSEXTENSION
  9483. +    if ( have_xss ) {
  9484. +        XScreenSaverSuspend( display, False );
  9485. +    }
  9486. +#endif
  9487.      XDestroyWindow( display, output_window );
  9488.      XDestroyWindow( display, wm_window );
  9489.      XDestroyWindow( display, fs_window );
  9490. diff -Nurp tvtime-1.0.2/src/xcommon.c.orig tvtime-1.0.2-custom/src/xcommon.c.orig
  9491. --- tvtime-1.0.2/src/xcommon.c.orig     1970-01-01 01:00:00.000000000 +0100
  9492. +++ tvtime-1.0.2-custom/src/xcommon.c.orig      2011-05-29 13:07:28.202374516 +0200
  9493. @@ -0,0 +1,1840 @@
  9494. +/**
  9495. + * Copyright (C) 2001, 2002, 2003 Billy Biggs <vektor@dumbterm.net>.
  9496. + *
  9497. + * Common routines for X output drivers.  Uses EWMH code and lots of
  9498. + * help from:
  9499. + *
  9500. + * Ogle - A video player
  9501. + * Copyright (C) 2001, 2002 Björn Englund, Håkan Hjort
  9502. + *
  9503. + * This program is free software; you can redistribute it and/or modify
  9504. + * it under the terms of the GNU General Public License as published by
  9505. + * the Free Software Foundation; either version 2 of the License, or
  9506. + * (at your option) any later version.
  9507. + *
  9508. + * This program is distributed in the hope that it will be useful,
  9509. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9510. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9511. + * GNU General Public License for more details.
  9512. + *
  9513. + * You should have received a copy of the GNU General Public License
  9514. + * along with this program; if not, write to the Free Software
  9515. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  9516. + */
  9517. +
  9518. +#include <stdio.h>
  9519. +#include <stdlib.h>
  9520. +#include <string.h>
  9521. +
  9522. +#if defined(__FreeBSD__)
  9523. +#include <machine/param.h>
  9524. +#endif
  9525. +#include <sys/types.h>
  9526. +#include <sys/ipc.h>
  9527. +#include <sys/shm.h>
  9528. +#include <sys/time.h>
  9529. +
  9530. +#ifdef HAVE_CONFIG_H
  9531. +# include "config.h"
  9532. +#endif
  9533. +
  9534. +#include <X11/X.h>
  9535. +#include <X11/Xatom.h>
  9536. +#include <X11/Xlib.h>
  9537. +#include <X11/Xutil.h>
  9538. +#include <X11/keysym.h>
  9539. +#include <X11/cursorfont.h>
  9540. +#include <X11/extensions/XShm.h>
  9541. +#ifdef HAVE_XSSEXTENSION
  9542. +#include <X11/extensions/scrnsaver.h>
  9543. +#endif
  9544. +
  9545. +#include "xfullscreen.h"
  9546. +#include "speedy.h"
  9547. +#include "utils.h"
  9548. +#include "xcommon.h"
  9549. +
  9550. +/* Every 30 seconds, ping the screensaver. */
  9551. +#define SCREENSAVER_PING_TIME (30 * 1000 * 1000)
  9552. +
  9553. +/* Useful. */
  9554. +#define MIN(x,y)((x)<(y)?(x):(y))
  9555. +#define MAX(x,y)((x)>(y)?(x):(y))
  9556. +
  9557. +static Display *display;
  9558. +static int screen;
  9559. +static Window wm_window;
  9560. +static Window fs_window;
  9561. +static Window output_window;
  9562. +static GC gc;
  9563. +static int have_xss;
  9564. +static int output_width, output_height;
  9565. +static int output_aspect;
  9566. +static int output_on_root;
  9567. +static int has_ewmh_state_fullscreen;
  9568. +static int has_ewmh_state_above;
  9569. +static int has_ewmh_state_below;
  9570. +static Cursor nocursor;
  9571. +static int output_fullscreen;
  9572. +static int xcommon_verbose;
  9573. +static int xcommon_exposed;
  9574. +static int xcommon_colourkey;
  9575. +static int motion_timeout;
  9576. +static int fullscreen_position;
  9577. +static int matte_width;
  9578. +static int matte_height;
  9579. +static int alwaysontop;
  9580. +static int has_focus;
  9581. +static int wm_is_metacity;
  9582. +static int use_square_pixels;
  9583. +static xfullscreen_t *xf;
  9584. +
  9585. +static Atom net_supporting_wm_check;
  9586. +static Atom net_supported;
  9587. +static Atom net_wm_name;
  9588. +static Atom net_wm_state;
  9589. +static Atom net_wm_state_above;
  9590. +static Atom net_wm_state_below;
  9591. +static Atom net_wm_state_fullscreen;
  9592. +static Atom net_wm_user_time;
  9593. +static Atom net_wm_icon;
  9594. +static Atom net_active_window;
  9595. +static Atom utf8_string;
  9596. +static Atom cardinal;
  9597. +static Atom kwm_keep_on_top;
  9598. +static Atom wm_protocols;
  9599. +static Atom wm_delete_window;
  9600. +static Atom xawtv_station;
  9601. +static Atom xawtv_remote;
  9602. +
  9603. +static area_t video_area;
  9604. +static area_t window_area;
  9605. +static area_t scale_area;
  9606. +
  9607. +static Time lastpresstime = 0;
  9608. +static Time lastreleasetime = 0;
  9609. +static Time last_server_time = 0;
  9610. +
  9611. +static int timediff( struct timeval *large, struct timeval *small )
  9612. +{
  9613. +    return (   ( ( large->tv_sec * 1000 * 1000 ) + large->tv_usec )
  9614. +             - ( ( small->tv_sec * 1000 * 1000 ) + small->tv_usec ) );
  9615. +}
  9616. +
  9617. +/**
  9618. + * Cache every atom we need in xcommon.  This minimizes round trips
  9619. + * to the server.  The number of atoms and their position is hardcoded,
  9620. + * but it's small.  Making this look pretty I think would be too
  9621. + * annoying to be worth it.
  9622. + */
  9623. +static void load_atoms( Display *dpy )
  9624. +{
  9625. +    static char *atom_names[] = {
  9626. +        "_NET_SUPPORTING_WM_CHECK",
  9627. +        "_NET_SUPPORTED",
  9628. +        "_NET_WM_NAME",
  9629. +        "_NET_WM_STATE",
  9630. +        "_NET_WM_STATE_ABOVE",
  9631. +        "_NET_WM_STATE_BELOW",
  9632. +        "_NET_WM_STATE_FULLSCREEN",
  9633. +        "_NET_WM_USER_TIME",
  9634. +        "_NET_WM_ICON",
  9635. +        "_NET_ACTIVE_WINDOW",
  9636. +        "UTF8_STRING",
  9637. +        "CARDINAL",
  9638. +        "KWM_KEEP_ON_TOP",
  9639. +        "WM_PROTOCOLS",
  9640. +        "WM_DELETE_WINDOW",
  9641. +        "_XAWTV_STATION",
  9642. +        "_XAWTV_REMOTE"
  9643. +    };
  9644. +    Atom atoms_return[ 17 ];
  9645. +
  9646. +    XInternAtoms( display, atom_names, 17, False, atoms_return );
  9647. +    net_supporting_wm_check = atoms_return[ 0 ];
  9648. +    net_supported = atoms_return[ 1 ];
  9649. +    net_wm_name = atoms_return[ 2 ];
  9650. +    net_wm_state = atoms_return[ 3 ];
  9651. +    net_wm_state_above = atoms_return[ 4 ];
  9652. +    net_wm_state_below = atoms_return[ 5 ];
  9653. +    net_wm_state_fullscreen = atoms_return[ 6 ];
  9654. +    net_wm_user_time = atoms_return[ 7 ];
  9655. +    net_wm_icon = atoms_return[ 8 ];
  9656. +    net_active_window = atoms_return[ 9 ];
  9657. +    utf8_string = atoms_return[ 10 ];
  9658. +    cardinal = atoms_return[ 11 ];
  9659. +    kwm_keep_on_top = atoms_return[ 12 ];
  9660. +    wm_protocols = atoms_return[ 13 ];
  9661. +    wm_delete_window = atoms_return[ 14 ];
  9662. +    xawtv_station = atoms_return[ 15 ];
  9663. +    xawtv_remote = atoms_return[ 16 ];
  9664. +}
  9665. +
  9666. +static uint32_t icon_colours[256];
  9667. +static int colours_loaded = 0;
  9668. +
  9669. +static const char *tvtime_icon =
  9670. +"                                "
  9671. +"                                "
  9672. +"                                "
  9673. +"                                "
  9674. +"    %@@@@@@@++..........%       "
  9675. +"    ..####=##=##=####..#*&      "
  9676. +"    ++@%@@@@@+++++..+...%&&     "
  9677. +"    ..%%%@@@+++....#+.+.%$&$    "
  9678. +"    +.@%@@++++...###....%&$&    "
  9679. +"    ++@@@@+++..#.#...++.%$&&    "
  9680. +"    +.@@+++....#.##...+.%&$&    "
  9681. +"    ++@@+++...#.##..+.++%$$&    "
  9682. +"    ++++++...###.#..+++.%&$&    "
  9683. +"    ++++...#.#.#....++++*$$$    "
  9684. +"    ++@....###.#...++++.*$$&    "
  9685. +"    +++..#.#.#...+++@+++*$$$    "
  9686. +"    @@+.##.#.#...+++@+++%$&$    "
  9687. +"    +++.#.##...+++@@@+++*$$$    "
  9688. +"    @@.##.#....++@@@%+@+*$$$    "
  9689. +"    @@+#.#...++++@@@%+++*&$$    "
  9690. +"    @@++....+++@@@%%@+@+-$$&    "
  9691. +"    ++++....+++@@%%-%+++*$$     "
  9692. +"    @++.+......#...+++++%$$     "
  9693. +"      +.++++......#..+@+*$&     "
  9694. +"          ...+++++...+++%$      "
  9695. +"               ...++@+++*       "
  9696. +"                                "
  9697. +"                                "
  9698. +"                                "
  9699. +"                                "
  9700. +"                                "
  9701. +"                                " ;
  9702. +
  9703. +static void load_icon( uint32_t *data )
  9704. +{
  9705. +    int i;
  9706. +
  9707. +    if( !colours_loaded ) {
  9708. +        colours_loaded = 1;
  9709. +        icon_colours[ ' ' ] = 0x00000000;
  9710. +        icon_colours[ '.' ] = 0xffcccccc;
  9711. +        icon_colours[ '+' ] = 0xffb2b2b2;
  9712. +        icon_colours[ '@' ] = 0xff999999;
  9713. +        icon_colours[ '#' ] = 0xffe5e5e5;
  9714. +        icon_colours[ '$' ] = 0xff4c4c4c;
  9715. +        icon_colours[ '%' ] = 0xff7f7f7f;
  9716. +        icon_colours[ '&' ] = 0xff333333;
  9717. +        icon_colours[ '*' ] = 0xff666666;
  9718. +        icon_colours[ '=' ] = 0xffffffff;
  9719. +        icon_colours[ '-' ] = 0xff007f7f;
  9720. +    }
  9721. +
  9722. +    *data++ = 32;
  9723. +    *data++ = 32;
  9724. +    for( i = 0; i < 32 * 32; i++ ) {
  9725. +        *data++ = icon_colours[ (int) tvtime_icon[ i ] ];
  9726. +    }
  9727. +}
  9728. +
  9729. +/**
  9730. + * Called after mapping a window - waits until the window is mapped.
  9731. + */
  9732. +static void x11_wait_mapped( Display *dpy, Window win )
  9733. +{
  9734. +    XEvent event;
  9735. +    do {
  9736. +        XMaskEvent( dpy, StructureNotifyMask, &event );
  9737. +    } while ( (event.type != MapNotify) || (event.xmap.event != win) );
  9738. +}
  9739. +
  9740. +static int have_xssextention( void )
  9741. +{  
  9742. +#ifdef HAVE_XSSEXTENSION
  9743. +    int dummy1, dummy2;
  9744. +  
  9745. +    return (XScreenSaverQueryExtension( display, &dummy1, &dummy2 ) == True);
  9746. +#endif
  9747. +    return 0;
  9748. +}
  9749. +
  9750. +static int calculate_gcd( int x, int y )
  9751. +{
  9752. +    if( y > x ) return calculate_gcd( y, x );
  9753. +    if( y < 0 ) return calculate_gcd( -y, 0 );
  9754. +
  9755. +    while( y ) {
  9756. +        int tmp = y;
  9757. +        y = x % y;
  9758. +        x = tmp;
  9759. +    }
  9760. +
  9761. +    return x;
  9762. +}
  9763. +
  9764. +static void simplify_fraction( int *n, int *d )
  9765. +{
  9766. +    int gcd = calculate_gcd( *n, *d );
  9767. +    *n /= gcd;
  9768. +    *d /= gcd;
  9769. +}
  9770. +
  9771. +/*
  9772. + * Integer division always truncates in C -- it rounds down.
  9773. + *
  9774. + * To compensate for this, we round up if
  9775. + *   n mod d > d/2
  9776. + * To avoid adding another truncation error, I multiply
  9777. + * this condition by two:
  9778. + *   2 * (n mod d) > d
  9779. + * And use the property that this evaluates to 1 if true to round up.
  9780. + */
  9781. +static int rounded_int_division( int n, int d )
  9782. +{
  9783. +    simplify_fraction( &n, &d );
  9784. +    return ( n/d + (2 * (n%d) > d) );
  9785. +}
  9786. +
  9787. +/*
  9788. + * Returns the aspect ratio (4:3 or 16:9) for our output,
  9789. + * and corrected for rectangular pixels.
  9790. + */
  9791. +static void xv_get_output_aspect( int *px_widthratio, int *px_heightratio )
  9792. +{
  9793. +    int metric_widthratio = output_aspect ? 16 : 4;
  9794. +    int metric_heightratio = output_aspect ? 9 : 3;
  9795. +    int sar_frac_w, sar_frac_h;
  9796. +
  9797. +    if( matte_height ) {
  9798. +        metric_heightratio = matte_height;
  9799. +        metric_widthratio = matte_width;
  9800. +    }
  9801. +
  9802. +    if( use_square_pixels ) {
  9803. +        sar_frac_w = sar_frac_h = 1;
  9804. +    } else {
  9805. +        xfullscreen_get_pixel_aspect( xf, &sar_frac_w, &sar_frac_h );
  9806. +    }
  9807. +
  9808. +    if( xcommon_verbose ) {
  9809. +        fprintf( stderr, "xcommon: Pixel aspect ratio %d:%d.\n",
  9810. +                 sar_frac_w, sar_frac_h );
  9811. +    }
  9812. +
  9813. +    /* PX_RATIO = METRIC_RATIO / SAR_FRAC = METRIC_RATIO * (1 / SAR_FRAC) */
  9814. +    *px_widthratio = metric_widthratio * sar_frac_h;
  9815. +    *px_heightratio = metric_heightratio * sar_frac_w;
  9816. +    simplify_fraction( px_widthratio, px_heightratio );
  9817. +}
  9818. +
  9819. +static int xv_get_width_for_height( int window_height )
  9820. +{
  9821. +    int n, d;
  9822. +
  9823. +    xv_get_output_aspect( &n, &d );
  9824. +    return rounded_int_division( window_height * n, d );
  9825. +}
  9826. +
  9827. +static int xv_get_height_for_width( int window_width )
  9828. +{
  9829. +    int n, d;
  9830. +
  9831. +    xv_get_output_aspect( &d, &n );
  9832. +    return rounded_int_division( window_width * n, d );
  9833. +}
  9834. +
  9835. +static void x11_northwest_gravity( Display *dpy, Window win )
  9836. +{
  9837. +    XSizeHints hints;
  9838. +    hints.flags = PWinGravity;
  9839. +    hints.win_gravity = NorthWestGravity;
  9840. +    XSetWMNormalHints( dpy, win, &hints );
  9841. +}
  9842. +
  9843. +static void x11_grab_fullscreen_input( Display *dpy, Window win )
  9844. +{
  9845. +    int tries = 10;
  9846. +    int result = -1;
  9847. +
  9848. +    while( tries && result != GrabSuccess ) {
  9849. +        result = XGrabPointer( dpy, win, True, 0, GrabModeAsync, GrabModeAsync,
  9850. +                               win, None, CurrentTime );
  9851. +        tries--;
  9852. +    }
  9853. +    XGrabKeyboard( dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime );
  9854. +    XSync( dpy, False );
  9855. +}
  9856. +
  9857. +static void x11_ungrab_fullscreen_input( Display *dpy )
  9858. +{
  9859. +    XUngrabPointer( dpy, CurrentTime );
  9860. +    XUngrabKeyboard( dpy, CurrentTime );
  9861. +}
  9862. +
  9863. +/* Used for error handling. */
  9864. +static unsigned long req_serial;
  9865. +static int (*prev_xerrhandler)( Display *dpy, XErrorEvent *ev );
  9866. +
  9867. +static int xprop_errorhandler( Display *dpy, XErrorEvent *ev )
  9868. +{
  9869. +    if( ev->serial == req_serial ) {
  9870. +        /* this is an error to the XGetWindowProperty request
  9871. +         * most probable the window specified by the property
  9872. +         * _NET_SUPPORTING_WM_CHECK on the root window no longer exists
  9873. +         */
  9874. +        fprintf( stderr, "xprop_errhandler: error in XGetWindowProperty\n" );
  9875. +        return 0;
  9876. +    } else {
  9877. +        /* if we get another error we should handle it,
  9878. +         * so we give it to the previous errorhandler
  9879. +         */
  9880. +        fprintf( stderr, "xprop_errhandler: unexpected error\n" );
  9881. +        return prev_xerrhandler( dpy, ev );
  9882. +    }
  9883. +}
  9884. +
  9885. +/**
  9886. + * Returns the window name for an Extended Window Manager Hints (EWMH)
  9887. + * compliant window manager.  Sets the name to "unknown" if no name is
  9888. + * set (non-compliant by the spec, but worth handling).
  9889. + */
  9890. +static void get_window_manager_name( Display *dpy, Window wm_window, char **wm_name_return )
  9891. +{
  9892. +    Atom type_return;
  9893. +    int format_return;
  9894. +    unsigned long bytes_after_return;
  9895. +    unsigned long nitems_return;
  9896. +    unsigned char *prop_return = 0;
  9897. +
  9898. +    if( XGetWindowProperty( dpy, wm_window, net_wm_name, 0,
  9899. +                            4, False, XA_STRING,
  9900. +                            &type_return, &format_return,
  9901. +                            &nitems_return, &bytes_after_return,
  9902. +                            &prop_return ) != Success ) {
  9903. +        fprintf( stderr, "xcommon: Can't get window manager name "
  9904. +                         "property (WM not compliant).\n" );
  9905. +        *wm_name_return = strdup( "unknown" );
  9906. +        return;
  9907. +    }
  9908. +    
  9909. +    if( type_return == None ) {
  9910. +        fprintf( stderr, "xcommon: No window manager name "
  9911. +                         "property found (WM not compliant).\n" );
  9912. +        *wm_name_return = strdup( "unknown" );
  9913. +        XFree( prop_return );
  9914. +        return;
  9915. +    }
  9916. +
  9917. +    if( type_return != XA_STRING ) {
  9918. +        XFree( prop_return );
  9919. +
  9920. +        if( type_return == utf8_string ) {
  9921. +            if( XGetWindowProperty( dpy, wm_window, net_wm_name, 0,
  9922. +                                    4, False, utf8_string,
  9923. +                                    &type_return, &format_return,
  9924. +                                    &nitems_return,
  9925. +                                    &bytes_after_return,
  9926. +                                    &prop_return ) != Success ) {
  9927. +                fprintf( stderr, "wm_name: Can't get window "
  9928. +                                 "manager name property "
  9929. +                                 "(WM not compliant).\n" );
  9930. +                *wm_name_return = strdup( "unknown" );
  9931. +                return;
  9932. +            }
  9933. +
  9934. +            if( format_return == 8 ) {
  9935. +                *wm_name_return = strdup( (char *) prop_return );
  9936. +            }
  9937. +            XFree( prop_return );
  9938. +        } else {
  9939. +            fprintf( stderr, "xcommon: Window manager name not "
  9940. +                             "ASCII or UTF8, giving up.\n" );
  9941. +            *wm_name_return = strdup( "unknown" );
  9942. +            return;
  9943. +        }
  9944. +    } else {
  9945. +        if( format_return == 8 ) {
  9946. +            *wm_name_return = strdup( (char *) prop_return );
  9947. +        }
  9948. +        XFree( prop_return );
  9949. +    }
  9950. +}
  9951. +
  9952. +/**
  9953. + * returns 1 if a window manager compliant to the
  9954. + * Extended Window Manager Hints (EWMH) spec is running.
  9955. + * (version 1.2)
  9956. + * Oterhwise returns 0.
  9957. + */
  9958. +static int check_for_EWMH_wm( Display *dpy, char **wm_name_return )
  9959. +{
  9960. +    Atom type_return;
  9961. +    int format_return;
  9962. +    unsigned long nitems_return;
  9963. +    unsigned long bytes_after_return;
  9964. +    unsigned char *prop_return = 0;
  9965. +
  9966. +    if( XGetWindowProperty( dpy, DefaultRootWindow( dpy ), net_supporting_wm_check, 0,
  9967. +                            1, False, XA_WINDOW,
  9968. +                            &type_return, &format_return, &nitems_return,
  9969. +                            &bytes_after_return, &prop_return ) != Success ) {
  9970. +        fprintf( stderr, "xcommon: Can't get window property to check for EWMH.\n" );
  9971. +        return 0;
  9972. +    }
  9973. +  
  9974. +    if( type_return == None ) {
  9975. +        fprintf( stderr, "xcommon: No window properties found for EWMH.\n" );
  9976. +        return 0;
  9977. +    }
  9978. +
  9979. +    if( type_return != XA_WINDOW ) {
  9980. +        fprintf( stderr, "xcommon: Can't get window property for EWMH.\n" );
  9981. +        if( prop_return ) XFree( prop_return );
  9982. +        return 0;
  9983. +    }
  9984. +
  9985. +    if( format_return == 32 && nitems_return == 1 && bytes_after_return == 0 ) {
  9986. +        Window win_id = *( (long *) prop_return );
  9987. +        int status;
  9988. +
  9989. +        XFree( prop_return );
  9990. +        prop_return = 0;
  9991. +
  9992. +        /* Make sure we don't have any unhandled errors. */
  9993. +        XSync( dpy, False );
  9994. +
  9995. +        /* Set error handler so we can check if XGetWindowProperty failed. */
  9996. +        prev_xerrhandler = XSetErrorHandler( xprop_errorhandler );
  9997. +
  9998. +        /* get the serial of the XGetWindowProperty request */
  9999. +        req_serial = NextRequest( dpy );
  10000. +
  10001. +        /* try to get property
  10002. +         * this can fail if we have a property with the win_id on the
  10003. +         * root window, but the win_id is no longer valid.
  10004. +         * This is to check for a stale window manager
  10005. +         */
  10006. +        status = XGetWindowProperty( dpy, win_id, net_supporting_wm_check, 0,
  10007. +                                     1, False, XA_WINDOW,
  10008. +                                     &type_return, &format_return, &nitems_return,
  10009. +                                     &bytes_after_return, &prop_return );
  10010. +
  10011. +        /* make sure XGetWindowProperty has been processed and any errors
  10012. +           have been returned to us */
  10013. +        XSync( dpy, False );
  10014. +
  10015. +        /* revert to the previous xerrorhandler */
  10016. +        XSetErrorHandler( prev_xerrhandler );
  10017. +
  10018. +        if( status != Success || type_return == None ) {
  10019. +            fprintf( stderr, "xcommon: EWMH check failed on child window, "
  10020. +                             "stale window manager property on root?\n" );
  10021. +            return 0;
  10022. +        }
  10023. +
  10024. +        if( type_return == XA_CARDINAL ) {
  10025. +            /* Hack for old and busted metacity. */
  10026. +            /* Allow this atom to be a CARDINAL. */
  10027. +            XGetWindowProperty( dpy, win_id, net_supporting_wm_check, 0,
  10028. +                                1, False, XA_CARDINAL,
  10029. +                                &type_return, &format_return, &nitems_return,
  10030. +                                &bytes_after_return, &prop_return );
  10031. +        } else if( type_return != XA_WINDOW ) {
  10032. +            fprintf( stderr, "didn't return XA_WINDOW?\n" );
  10033. +            fprintf( stderr, "xcommon: EWMH check failed on child window, "
  10034. +                             "stale window manager property on root?\n" );
  10035. +            if( prop_return ) {
  10036. +                XFree( prop_return );
  10037. +            }
  10038. +            return 0;
  10039. +        }
  10040. +
  10041. +        if( format_return == 32 && nitems_return == 1 && bytes_after_return == 0 ) {
  10042. +            if( win_id == *( (long *) prop_return ) ) {
  10043. +                /* We have successfully detected a EWMH compliant Window Manager. */
  10044. +                XFree( prop_return );
  10045. +
  10046. +                /* Get the name of the wm */
  10047. +                get_window_manager_name( dpy, win_id, wm_name_return );
  10048. +                return 1;
  10049. +            }
  10050. +            XFree( prop_return );
  10051. +            return 0;
  10052. +        } else if( prop_return ) {
  10053. +            XFree( prop_return );
  10054. +        }
  10055. +    } else if( prop_return ) {
  10056. +        XFree( prop_return );
  10057. +    }
  10058. +
  10059. +    return 0;
  10060. +}
  10061. +
  10062. +/**
  10063. + * Returns 1 if a window manager compliant to the Extended Window
  10064. + * Manager Hints (EWMH) specification supports the
  10065. + * _NET_WM_STATE_FULLSCREEN window state.  Otherwise, returns 0.
  10066. + */
  10067. +static int check_for_state_fullscreen( Display *dpy )
  10068. +{
  10069. +    Atom type_return;
  10070. +    int format_return;
  10071. +    unsigned long nitems_return;
  10072. +    unsigned long bytes_after_return;
  10073. +    unsigned char *prop_return = 0;
  10074. +    int nr_items = 40;
  10075. +    int item_offset = 0;
  10076. +    int supports_net_wm_state = 0;
  10077. +    int supports_net_wm_state_fullscreen = 0;
  10078. +
  10079. +    do {
  10080. +        if( XGetWindowProperty( dpy, DefaultRootWindow( dpy ), net_supported,
  10081. +                                item_offset, nr_items, False, XA_ATOM,
  10082. +                                &type_return, &format_return, &nitems_return,
  10083. +                                &bytes_after_return, &prop_return) != Success ) {
  10084. +            if( xcommon_verbose ) {
  10085. +                fprintf( stderr, "xcommon: Can't check the fullscreen property (WM not compliant).\n" );
  10086. +            }
  10087. +            return 0;
  10088. +        }
  10089. +    
  10090. +        if( type_return == None ) {
  10091. +            if( xcommon_verbose ) {
  10092. +                fprintf( stderr, "xcommon: No property for fullscreen support (WM not compliant).\n" );
  10093. +            }
  10094. +            return 0;
  10095. +        }
  10096. +
  10097. +        if( type_return != XA_ATOM ) {
  10098. +            if( xcommon_verbose ) {
  10099. +                fprintf( stderr, "xcommon: Broken property for fullscreen support (WM not compliant).\n");
  10100. +            }
  10101. +            if( prop_return ) XFree( prop_return );
  10102. +            return 0;
  10103. +        } else {
  10104. +            if( format_return == 32 ) {
  10105. +                int n;
  10106. +
  10107. +                for( n = 0; n < nitems_return; n++ ) {
  10108. +                    if( ((long *) prop_return)[ n ] == net_wm_state ) {
  10109. +                        supports_net_wm_state = 1;
  10110. +                    } else if( ((long *) prop_return)[ n ] == net_wm_state_fullscreen ) {
  10111. +                        supports_net_wm_state_fullscreen = 1;
  10112. +                    }
  10113. +
  10114. +                    if( supports_net_wm_state && supports_net_wm_state_fullscreen ) {
  10115. +                        XFree( prop_return );
  10116. +                        return 1;
  10117. +                    }
  10118. +                }
  10119. +
  10120. +                XFree( prop_return );
  10121. +            } else {
  10122. +                XFree( prop_return );
  10123. +                return 0;
  10124. +            }
  10125. +        }
  10126. +
  10127. +        item_offset += nr_items;
  10128. +    } while( bytes_after_return > 0 );
  10129. +
  10130. +    return 0;
  10131. +}
  10132. +
  10133. +/**
  10134. + * Returns 1 if a window manager compliant to the Extended Window
  10135. + * Manager Hints (EWMH) specification supports the _NET_WM_STATE_ABOVE
  10136. + * window state.  Otherwise, returns 0.
  10137. + */
  10138. +static int check_for_state_above( Display *dpy )
  10139. +{
  10140. +    Atom type_return;
  10141. +    int format_return;
  10142. +    unsigned long nitems_return;
  10143. +    unsigned long bytes_after_return;
  10144. +    unsigned char *prop_return = 0;
  10145. +    int nr_items = 40;
  10146. +    int item_offset = 0;
  10147. +    int supports_net_wm_state = 0;
  10148. +    int supports_net_wm_state_above = 0;
  10149. +
  10150. +    do {
  10151. +        if( XGetWindowProperty( dpy, DefaultRootWindow( dpy ), net_supported,
  10152. +                                item_offset, nr_items, False, XA_ATOM,
  10153. +                                &type_return, &format_return, &nitems_return,
  10154. +                                &bytes_after_return, &prop_return) != Success ) {
  10155. +            if( xcommon_verbose ) {
  10156. +                fprintf( stderr, "xcommon: Can't check the above property (WM not compliant).\n" );
  10157. +            }
  10158. +            return 0;
  10159. +        }
  10160. +    
  10161. +        if( type_return == None ) {
  10162. +            if( xcommon_verbose ) {
  10163. +                fprintf( stderr, "xcommon: No property for above support (WM not compliant).\n" );
  10164. +            }
  10165. +            return 0;
  10166. +        }
  10167. +
  10168. +        if( type_return != XA_ATOM ) {
  10169. +            if( xcommon_verbose ) {
  10170. +                fprintf( stderr, "xcommon: Broken property for above support (WM not compliant).\n");
  10171. +            }
  10172. +            if( prop_return ) XFree( prop_return );
  10173. +            return 0;
  10174. +        } else {
  10175. +            if( format_return == 32 ) {
  10176. +                int n;
  10177. +
  10178. +                for( n = 0; n < nitems_return; n++ ) {
  10179. +                    if( ((long *) prop_return)[ n ] == net_wm_state ) {
  10180. +                        supports_net_wm_state = 1;
  10181. +                    } else if( ((long *) prop_return)[ n ] == net_wm_state_above ) {
  10182. +                        supports_net_wm_state_above = 1;
  10183. +                    }
  10184. +
  10185. +                    if( supports_net_wm_state && supports_net_wm_state_above ) {
  10186. +                        XFree( prop_return );
  10187. +                        return 1;
  10188. +                    }
  10189. +                }
  10190. +
  10191. +                XFree( prop_return );
  10192. +            } else {
  10193. +                XFree( prop_return );
  10194. +                return 0;
  10195. +            }
  10196. +        }
  10197. +
  10198. +        item_offset += nr_items;
  10199. +    } while( bytes_after_return > 0 );
  10200. +
  10201. +    return 0;
  10202. +}
  10203. +
  10204. +/**
  10205. + * Returns 1 if a window manager compliant to the Extended Window
  10206. + * Manager Hints (EWMH) specification supports the _NET_WM_STATE_BELOW
  10207. + * window state.  Otherwise, returns 0.
  10208. + */
  10209. +static int check_for_state_below( Display *dpy )
  10210. +{
  10211. +    Atom type_return;
  10212. +    int format_return;
  10213. +    unsigned long nitems_return;
  10214. +    unsigned long bytes_after_return;
  10215. +    unsigned char *prop_return = 0;
  10216. +    int nr_items = 40;
  10217. +    int item_offset = 0;
  10218. +    int supports_net_wm_state = 0;
  10219. +    int supports_net_wm_state_below = 0;
  10220. +
  10221. +    do {
  10222. +        if( XGetWindowProperty( dpy, DefaultRootWindow( dpy ), net_supported,
  10223. +                                item_offset, nr_items, False, XA_ATOM,
  10224. +                                &type_return, &format_return, &nitems_return,
  10225. +                                &bytes_after_return, &prop_return) != Success ) {
  10226. +            if( xcommon_verbose ) {
  10227. +                fprintf( stderr, "xcommon: Can't check the below property (WM not compliant).\n" );
  10228. +            }
  10229. +            return 0;
  10230. +        }
  10231. +    
  10232. +        if( type_return == None ) {
  10233. +            if( xcommon_verbose ) {
  10234. +                fprintf( stderr, "xcommon: No property for below support (WM not compliant).\n" );
  10235. +            }
  10236. +            return 0;
  10237. +        }
  10238. +
  10239. +        if( type_return != XA_ATOM ) {
  10240. +            if( xcommon_verbose ) {
  10241. +                fprintf( stderr, "xcommon: Broken property for below support (WM not compliant).\n");
  10242. +            }
  10243. +            if( prop_return ) XFree( prop_return );
  10244. +            return 0;
  10245. +        } else {
  10246. +            if( format_return == 32 ) {
  10247. +                int n;
  10248. +
  10249. +                for( n = 0; n < nitems_return; n++ ) {
  10250. +                    if( ((long *) prop_return)[ n ] == net_wm_state ) {
  10251. +                        supports_net_wm_state = 1;
  10252. +                    } else if( ((long *) prop_return)[ n ] == net_wm_state_below ) {
  10253. +                        supports_net_wm_state_below = 1;
  10254. +                    }
  10255. +
  10256. +                    if( supports_net_wm_state && supports_net_wm_state_below ) {
  10257. +                        XFree( prop_return );
  10258. +                        return 1;
  10259. +                    }
  10260. +                }
  10261. +
  10262. +                XFree( prop_return );
  10263. +            } else {
  10264. +                XFree( prop_return );
  10265. +                return 0;
  10266. +            }
  10267. +        }
  10268. +
  10269. +        item_offset += nr_items;
  10270. +    } while( bytes_after_return > 0 );
  10271. +
  10272. +    return 0;
  10273. +}
  10274. +
  10275. +
  10276. +/**
  10277. + * Some math:
  10278. + *
  10279. + * pixel size = pw/ph
  10280. + * screen size = sw/sh
  10281. + * resolution = rw/rh
  10282. + *
  10283. + * sw = pw*rw   therefore pw = sw / rw
  10284. + * sh = ph*rh   therefore ph = sh / rh
  10285. + */
  10286. +
  10287. +static void calculate_video_area( void )
  10288. +{
  10289. +    int curwidth, curheight;
  10290. +
  10291. +    curwidth = output_width;
  10292. +    curheight = xv_get_height_for_width( curwidth );
  10293. +    if( curheight > output_height ) {
  10294. +        curheight = output_height;
  10295. +        curwidth = xv_get_width_for_height( curheight );
  10296. +    }
  10297. +
  10298. +    video_area.x = ( output_width - curwidth ) / 2;
  10299. +    video_area.y = ( output_height - curheight ) / 2;
  10300. +    if( output_fullscreen ) {
  10301. +        if( fullscreen_position == 1 ) {
  10302. +            video_area.y = 0;
  10303. +        } else if( fullscreen_position == 2 ) {
  10304. +            video_area.y = output_height - curheight;
  10305. +        }
  10306. +    }
  10307. +    video_area.width = curwidth;
  10308. +    video_area.height = curheight;
  10309. +
  10310. +    if( xcommon_verbose ) {
  10311. +        fprintf( stderr, "xcommon: Displaying in a %dx%d window inside %dx%d space.\n",
  10312. +                 curwidth, curheight, output_width, output_height );
  10313. +    }
  10314. +}
  10315. +
  10316. +
  10317. +int xcommon_open_display( const char *user_geometry, int aspect, int verbose )
  10318. +{
  10319. +    Pixmap curs_pix;
  10320. +    XEvent xev;
  10321. +    XSizeHints hint;
  10322. +    XClassHint classhint;
  10323. +    XColor curs_col;
  10324. +    XSetWindowAttributes xswa;
  10325. +    const char *hello = "tvtime";
  10326. +    unsigned long mask;
  10327. +    char *wmname = 0;
  10328. +    int wx, wy;
  10329. +    unsigned int ww, wh;
  10330. +    int gflags;
  10331. +
  10332. +    output_aspect = aspect;
  10333. +    output_height = 576;
  10334. +
  10335. +    have_xss = 0;
  10336. +    output_on_root = 0;
  10337. +    has_ewmh_state_fullscreen = 0;
  10338. +    has_ewmh_state_above = 0;
  10339. +    has_ewmh_state_below = 0;
  10340. +    output_fullscreen = 0;
  10341. +    xcommon_verbose = verbose;
  10342. +    xcommon_exposed = 0;
  10343. +    xcommon_colourkey = 0;
  10344. +    motion_timeout = 0;
  10345. +    fullscreen_position = 0;
  10346. +    matte_width = 0;
  10347. +    matte_height = 0;
  10348. +    alwaysontop = 0;
  10349. +    has_focus = 0;
  10350. +    wm_is_metacity = 0;
  10351. +
  10352. +    display = XOpenDisplay( 0 );
  10353. +    if( !display ) {
  10354. +        if( getenv( "DISPLAY" ) ) {
  10355. +            fprintf( stderr, "xcommon: Cannot open display '%s'.\n", getenv( "DISPLAY" ) );
  10356. +        } else {
  10357. +            fprintf( stderr, "xcommon: No DISPLAY set, so no output possible!\n" );
  10358. +        }
  10359. +        return 0;
  10360. +    }
  10361. +
  10362. +    if( xcommon_verbose ) {
  10363. +        fprintf( stderr, "xcommon: Display %s, vendor %s, ",
  10364. +        DisplayString( display ), ServerVendor( display ) );
  10365. +
  10366. +        if( strstr( ServerVendor( display ), "XFree86" ) ) {
  10367. +            int vendrel = VendorRelease( display );
  10368. +
  10369. +            fprintf( stderr, "XFree86 " );
  10370. +            if( vendrel < 336 ) {
  10371. +                /*
  10372. +                 * vendrel was set incorrectly for 3.3.4 and 3.3.5, so handle
  10373. +                 * those cases here.
  10374. +                 */
  10375. +                fprintf( stderr, "%d.%d.%d", vendrel / 100, (vendrel / 10) % 10, vendrel % 10);
  10376. +            } else if( vendrel < 3900 ) {
  10377. +                /* 3.3.x versions, other than the exceptions handled above */
  10378. +                fprintf( stderr, "%d.%d", vendrel / 1000, (vendrel / 100) % 10);
  10379. +                if (((vendrel / 10) % 10) || (vendrel % 10)) {
  10380. +                    fprintf( stderr, ".%d", (vendrel / 10) % 10);
  10381. +                    if (vendrel % 10) {
  10382. +                        fprintf( stderr, ".%d", vendrel % 10);
  10383. +                    }
  10384. +                }
  10385. +            } else if( vendrel < 40000000 ) {
  10386. +                /* 4.0.x versions */
  10387. +                fprintf( stderr, "%d.%d", vendrel / 1000, (vendrel / 10) % 10);
  10388. +                if( vendrel % 10 ) {
  10389. +                    fprintf( stderr, ".%d", vendrel % 10 );
  10390. +                }
  10391. +            } else {
  10392. +                /* post-4.0.x */
  10393. +                fprintf( stderr, "%d.%d.%d", vendrel / 10000000, (vendrel / 100000) % 100, (vendrel / 1000) % 100);
  10394. +                if( vendrel % 1000 ) {
  10395. +                    fprintf( stderr, ".%d", vendrel % 1000);
  10396. +                }
  10397. +            }
  10398. +            fprintf( stderr, "\n" );
  10399. +        } else {
  10400. +            fprintf( stderr, "vendor release %d\n", VendorRelease( display ) );
  10401. +        }
  10402. +    }
  10403. +
  10404. +    load_atoms( display );
  10405. +
  10406. +    screen = DefaultScreen( display );
  10407. +
  10408. +    xf = xfullscreen_new( display, screen, verbose );
  10409. +    if( !xf ) {
  10410. +        fprintf( stderr, "xcommon: Can't initialize fullscreen information object.\n" );
  10411. +        XCloseDisplay( display );
  10412. +        return 0;
  10413. +    }
  10414. +
  10415. +    if( xcommon_verbose ) {
  10416. +        xfullscreen_print_summary( xf );
  10417. +    }
  10418. +
  10419. +    have_xss = have_xssextention();
  10420. +    if( have_xss && xcommon_verbose ) {
  10421. +        fprintf( stderr, "xcommon: Have XSS, will use it to disable the screensaver.\n" );
  10422. +    }
  10423. +
  10424. +#ifdef HAVE_XSSEXTENSION
  10425. +    if ( have_xss ) {
  10426. +        XScreenSaverSuspend( display, True );
  10427. +    }
  10428. +#endif
  10429. +
  10430. +    /* Initially, get the best width for our height. */
  10431. +    output_width = xv_get_width_for_height( output_height );
  10432. +
  10433. +    window_area.x = 0;
  10434. +    window_area.y = 0;
  10435. +    window_area.width = output_width;
  10436. +    window_area.height = output_height;
  10437. +
  10438. +    xswa.override_redirect = False;
  10439. +    xswa.backing_store = NotUseful;
  10440. +    xswa.save_under = False;
  10441. +    xswa.background_pixel = BlackPixel( display, screen );
  10442. +    xswa.event_mask = ButtonPressMask | ButtonReleaseMask |
  10443. +                      StructureNotifyMask | KeyPressMask | PointerMotionMask |
  10444. +                      VisibilityChangeMask | FocusChangeMask |
  10445. +                      PropertyChangeMask | ExposureMask;
  10446. +
  10447. +    mask = (CWBackPixel | CWSaveUnder | CWBackingStore | CWEventMask);
  10448. +
  10449. +    gflags = XParseGeometry( user_geometry, &wx, &wy, &ww, &wh );
  10450. +    if( !(gflags & WidthValue) ) {
  10451. +        ww = output_width;
  10452. +    }
  10453. +    if( !(gflags & HeightValue) ) {
  10454. +        wh = output_height;
  10455. +    } else if( ww == 0 ) {
  10456. +        ww = xv_get_width_for_height( wh );
  10457. +    }
  10458. +
  10459. +    window_area.width = ww;
  10460. +    window_area.height = wh;
  10461. +    output_width = ww;
  10462. +    output_height = wh;
  10463. +
  10464. +    wm_window = XCreateWindow( display, RootWindow( display, screen ), 0, 0,
  10465. +                               ww, wh, 0, CopyFromParent, InputOutput,
  10466. +                               CopyFromParent, mask, &xswa);
  10467. +
  10468. +    output_window = XCreateWindow( display, wm_window, 0, 0,
  10469. +                                   ww, wh, 0, CopyFromParent, InputOutput,
  10470. +                                   CopyFromParent, mask, &xswa);
  10471. +
  10472. +    xswa.override_redirect = True;
  10473. +    xswa.border_pixel = 0;
  10474. +
  10475. +    mask = (CWBackPixel | CWOverrideRedirect | CWEventMask);
  10476. +
  10477. +    fs_window = XCreateWindow( display, RootWindow( display, screen ), 0, 0,
  10478. +                               output_width, output_height, 0,
  10479. +                               CopyFromParent, InputOutput, CopyFromParent,
  10480. +                               mask, &xswa );
  10481. +
  10482. +    /* Tell KDE to keep the fullscreen window on top. */
  10483. +    {
  10484. +        XEvent ev;
  10485. +        long mask;
  10486. +
  10487. +        memset( &ev, 0, sizeof( ev ) );
  10488. +        ev.xclient.type = ClientMessage;
  10489. +        ev.xclient.window = DefaultRootWindow( display );
  10490. +        ev.xclient.message_type = kwm_keep_on_top;
  10491. +        ev.xclient.format = 32;
  10492. +        ev.xclient.data.l[ 0 ] = fs_window;
  10493. +        ev.xclient.data.l[ 1 ] = CurrentTime;
  10494. +        mask = SubstructureRedirectMask;
  10495. +        XSendEvent( display, DefaultRootWindow( display ), False, mask, &ev );
  10496. +    }
  10497. +
  10498. +    /* Set the icon on the window. */
  10499. +    {
  10500. +        uint32_t *data = malloc( 1026 * 4 );
  10501. +        if( data ) {
  10502. +            load_icon( data );
  10503. +            XChangeProperty( display, wm_window, net_wm_icon, cardinal, 32,
  10504. +                             PropModeReplace,
  10505. +                             (const unsigned char*) data, 1026 );
  10506. +            XChangeProperty( display, fs_window, net_wm_icon, cardinal, 32,
  10507. +                             PropModeReplace, (const unsigned char*) data,
  10508. +                             1026 );
  10509. +            free( data );
  10510. +        }
  10511. +    }
  10512. +
  10513. +    if( check_for_EWMH_wm( display, &wmname ) ) {
  10514. +        if( xcommon_verbose ) {
  10515. +            fprintf( stderr, "xcommon: Window manager is %s and is EWMH compliant.\n", wmname );
  10516. +        }
  10517. +
  10518. +        if( !strcasecmp( wmname, "metacity" ) ) {
  10519. +            if( xcommon_verbose ) {
  10520. +                fprintf( stderr, "xcommon: You are using metacity.  Disabling aspect ratio hints\n"
  10521. +                                 "xcommon: since most deployed versions of metacity are still broken.\n" );
  10522. +            }
  10523. +            wm_is_metacity = 1;
  10524. +        }
  10525. +        free( wmname );
  10526. +
  10527. +
  10528. +        /**
  10529. +         * If we have an EWMH compliant window manager, check for
  10530. +         * fullscreen, above and below states.
  10531. +         */
  10532. +        has_ewmh_state_fullscreen = check_for_state_fullscreen( display );
  10533. +        if( has_ewmh_state_fullscreen && xcommon_verbose ) {
  10534. +            fprintf( stderr, "xcommon: Using EWMH state fullscreen property.\n" );
  10535. +        }
  10536. +        has_ewmh_state_above = check_for_state_above( display );
  10537. +        if( has_ewmh_state_above && xcommon_verbose ) {
  10538. +            fprintf( stderr, "xcommon: Using EWMH state above property.\n" );
  10539. +        }
  10540. +        has_ewmh_state_below = check_for_state_below( display );
  10541. +        if( has_ewmh_state_below && xcommon_verbose ) {
  10542. +            fprintf( stderr, "xcommon: Using EWMH state below property.\n" );
  10543. +        }
  10544. +    } else if( xcommon_verbose ) {
  10545. +        fprintf( stderr, "xcommon: Window manager is not EWMH compliant.\n" );
  10546. +    }
  10547. +
  10548. +    gc = DefaultGC( display, screen );
  10549. +
  10550. +    hint.width = output_width;
  10551. +    hint.height = output_height;
  10552. +    hint.flags = PSize;
  10553. +
  10554. +    XSetStandardProperties( display, wm_window, hello, hello, None, 0, 0, &hint );
  10555. +
  10556. +    /* The class hint is useful for window managers like WindowMaker. */
  10557. +    classhint.res_class = "tvtime";
  10558. +    classhint.res_name = "TVWindow";
  10559. +    XSetClassHint( display, wm_window, &classhint );
  10560. +    classhint.res_name = "TVFullscreen";
  10561. +    XSetClassHint( display, fs_window, &classhint );
  10562. +
  10563. +    /* collaborate with the window manager for close requests */
  10564. +    XSetWMProtocols( display, wm_window, &wm_delete_window, 1 );
  10565. +
  10566. +    calculate_video_area();
  10567. +
  10568. +    XMapWindow( display, output_window );
  10569. +    XMapWindow( display, wm_window );
  10570. +
  10571. +    /* FIXME: Do I need to wait for the window to be mapped? */
  10572. +    /* x11_wait_mapped( display, wm_window ); */
  10573. +
  10574. +    /* Wait for map. */
  10575. +    XMaskEvent( display, StructureNotifyMask, &xev );
  10576. +
  10577. +    /* Create a 1 pixel cursor to use in full screen mode */
  10578. +    curs_pix = XCreatePixmap( display, output_window, 1, 1, 1 );
  10579. +    curs_col.pixel = 0;
  10580. +    curs_col.red = 0;
  10581. +    curs_col.green = 0;
  10582. +    curs_col.blue = 0;
  10583. +    curs_col.flags = 0;
  10584. +    curs_col.pad = 0;
  10585. +    nocursor = XCreatePixmapCursor( display, curs_pix, curs_pix, &curs_col, &curs_col, 1, 1 );
  10586. +    XDefineCursor( display, output_window, nocursor );
  10587. +    XSetIconName( display, wm_window, "tvtime" );
  10588. +
  10589. +    return 1;
  10590. +}
  10591. +
  10592. +static struct timeval last_ping_time;
  10593. +static int time_initialized = 0;
  10594. +
  10595. +void xcommon_ping_screensaver( void )
  10596. +{
  10597. +    struct timeval curtime;
  10598. +
  10599. +    if( !time_initialized ) {
  10600. +        gettimeofday( &last_ping_time, 0 );
  10601. +        time_initialized = 1;
  10602. +    }
  10603. +
  10604. +    gettimeofday( &curtime, 0 );
  10605. +    if( timediff( &curtime, &last_ping_time ) > SCREENSAVER_PING_TIME ) {
  10606. +        last_ping_time = curtime;
  10607. +        XResetScreenSaver( display );
  10608. +    }
  10609. +}
  10610. +
  10611. +void xcommon_frame_drawn( void )
  10612. +{
  10613. +    if( motion_timeout ) {
  10614. +        motion_timeout--;
  10615. +        if( !motion_timeout ) {
  10616. +            XDefineCursor( display, output_window, nocursor );
  10617. +        }
  10618. +    }
  10619. +}
  10620. +
  10621. +void xcommon_set_window_position( int x, int y )
  10622. +{
  10623. +    if( output_fullscreen ) {
  10624. +        xcommon_toggle_fullscreen( 0, 0 );
  10625. +    }
  10626. +
  10627. +    if( xcommon_verbose ) {
  10628. +        fprintf( stderr, "xcommon: Target window position %d,%d.\n", x, y );
  10629. +    }
  10630. +
  10631. +    x11_northwest_gravity( display, wm_window );
  10632. +    XMoveWindow( display, wm_window, x, y );
  10633. +}
  10634. +
  10635. +void xcommon_set_window_height( int window_height )
  10636. +{
  10637. +    XWindowChanges win_changes;
  10638. +    int window_width;
  10639. +
  10640. +    if( output_fullscreen ) {
  10641. +        xcommon_toggle_fullscreen( 0, 0 );
  10642. +    }
  10643. +
  10644. +    window_width = xv_get_width_for_height( window_height );
  10645. +
  10646. +    if( xcommon_verbose ) {
  10647. +        fprintf( stderr, "xcommon: Target window size %dx%d.\n", window_width, window_height );
  10648. +    }
  10649. +
  10650. +    win_changes.width = window_width;
  10651. +    win_changes.height = window_height;
  10652. +
  10653. +    XReconfigureWMWindow( display, wm_window, 0,
  10654. +                          CWWidth | CWHeight, &win_changes );
  10655. +}
  10656. +
  10657. +void xcommon_clear_screen( void )
  10658. +{
  10659. +    XSetForeground( display, gc, BlackPixel( display, screen ) );
  10660. +    XClearWindow( display, output_window );
  10661. +    XSetForeground( display, gc, xcommon_colourkey );
  10662. +    XFillRectangle( display, output_window, gc, video_area.x, video_area.y,
  10663. +                    video_area.width, video_area.height );
  10664. +    /* This is how to draw text.
  10665. +    XSetForeground( display, gc, WhitePixel( display, screen ) );
  10666. +    XDrawString( display, output_window, gc,
  10667. +                 video_area.x + (video_area.width/3),
  10668. +                 video_area.y + (video_area.height/3),
  10669. +                 text, strlen( text ) );
  10670. +     */
  10671. +    XSync( display, False );
  10672. +}
  10673. +
  10674. +void xcommon_clear_area( int x, int y, int w, int h )
  10675. +{
  10676. +    int dx, dy, dw, dh;
  10677. +
  10678. +    /* First fill the new area to black. */
  10679. +    XSetForeground( display, gc, BlackPixel( display, screen ) );
  10680. +    XFillRectangle( display, output_window, gc, x, y, w, h );
  10681. +
  10682. +    /**
  10683. +     * Only fill the intersection of the video area and the exposed
  10684. +     * area with the colour key.
  10685. +     */
  10686. +    dx = MAX( x, video_area.x );
  10687. +    dy = MAX( y, video_area.y );
  10688. +    dw = MIN( x + w, video_area.x + video_area.width ) - dx;
  10689. +    dh = MIN( y + h, video_area.y + video_area.height ) - dy;
  10690. +    if( dx >= 0 && dy >= 0 && dw >= 0 && dh >= 0 ) {
  10691. +        XSetForeground( display, gc, xcommon_colourkey );
  10692. +        XFillRectangle( display, output_window, gc, dx, dy, dw, dh );
  10693. +    }
  10694. +}
  10695. +
  10696. +/**
  10697. + * Called after unmapping a window - waits until the window is unmapped.
  10698. + */
  10699. +static void x11_wait_unmapped( Display *dpy, Window win )
  10700. +{
  10701. +    XEvent event;
  10702. +    do {
  10703. +        XMaskEvent( dpy, StructureNotifyMask, &event );
  10704. +    } while ( (event.type != UnmapNotify) || (event.xunmap.event != win) );
  10705. +}
  10706. +
  10707. +int xcommon_toggle_alwaysontop( void )
  10708. +{
  10709. +    if( has_ewmh_state_above ) {
  10710. +        XEvent ev;
  10711. +
  10712. +        alwaysontop = !alwaysontop;
  10713. +
  10714. +        ev.type = ClientMessage;
  10715. +        ev.xclient.window = wm_window;
  10716. +        ev.xclient.message_type = net_wm_state;
  10717. +        ev.xclient.format = 32;
  10718. +        ev.xclient.data.l[ 0 ] = alwaysontop ? 1 : 0;
  10719. +        ev.xclient.data.l[ 1 ] = net_wm_state_above;
  10720. +        ev.xclient.data.l[ 2 ] = 0;
  10721. +
  10722. +        XSendEvent( display, DefaultRootWindow( display ), False,
  10723. +                    SubstructureNotifyMask|SubstructureRedirectMask, &ev );
  10724. +    }
  10725. +
  10726. +    return alwaysontop;
  10727. +}
  10728. +
  10729. +static void xcommon_activate_window( void )
  10730. +{
  10731. +    XEvent ev;
  10732. +
  10733. +    ev.type = ClientMessage;
  10734. +    ev.xclient.window = wm_window;
  10735. +    ev.xclient.message_type = net_active_window;
  10736. +    ev.xclient.format = 32;
  10737. +    ev.xclient.data.l[ 0 ] = 1;
  10738. +    ev.xclient.data.l[ 1 ] = last_server_time;
  10739. +    ev.xclient.data.l[ 2 ] = 0;
  10740. +
  10741. +    XSendEvent( display, DefaultRootWindow( display ), False,
  10742. +                SubstructureNotifyMask|SubstructureRedirectMask, &ev );
  10743. +}
  10744. +
  10745. +int xcommon_toggle_fullscreen( int fullscreen_width, int fullscreen_height )
  10746. +{
  10747. +    output_fullscreen = !output_fullscreen;
  10748. +    if( output_fullscreen ) {
  10749. +        int x, y, w, h;
  10750. +
  10751. +        xfullscreen_update( xf );
  10752. +        xfullscreen_get_position( xf, window_area.x, window_area.y,
  10753. +                                  window_area.width, window_area.height,
  10754. +                                  &x, &y, &w, &h );
  10755. +
  10756. +        output_width = w;
  10757. +        output_height = h;
  10758. +
  10759. +        window_area.x = x;
  10760. +        window_area.y = y;
  10761. +        window_area.width = w;
  10762. +        window_area.height = h;
  10763. +
  10764. +        if( has_ewmh_state_fullscreen ) {
  10765. +            XEvent ev;
  10766. +
  10767. +            ev.type = ClientMessage;
  10768. +            ev.xclient.display = display;
  10769. +            ev.xclient.window = wm_window;
  10770. +            ev.xclient.message_type = net_wm_state;
  10771. +            ev.xclient.format = 32;
  10772. +            ev.xclient.data.l[ 0 ] = 1;
  10773. +            ev.xclient.data.l[ 1 ] = net_wm_state_fullscreen;
  10774. +            ev.xclient.data.l[ 2 ] = 0;
  10775. +            ev.xclient.data.l[ 3 ] = 0;
  10776. +            ev.xclient.data.l[ 4 ] = 0;
  10777. +
  10778. +            XSendEvent( display, DefaultRootWindow( display ), False,
  10779. +                        SubstructureNotifyMask | SubstructureRedirectMask,
  10780. +                        &ev );
  10781. +
  10782. +            /* When we go fullscreen, explicitly ask to get focus. */
  10783. +            xcommon_activate_window();
  10784. +        } else {
  10785. +            /* Show our fullscreen window. */
  10786. +            XMoveResizeWindow( display, fs_window, x, y, w, h );
  10787. +            XMapRaised( display, fs_window );
  10788. +            x11_wait_mapped( display, fs_window );
  10789. +            XRaiseWindow( display, fs_window );
  10790. +
  10791. +            /* Since we just mapped the window and got our
  10792. +             * Map event, we mark this here. */
  10793. +            xcommon_exposed = 1;
  10794. +
  10795. +            XReparentWindow( display, output_window, fs_window, 0, 0);
  10796. +
  10797. +            /* Grab the pointer, grab input focus, then ungrab. */
  10798. +            x11_grab_fullscreen_input( display, fs_window );
  10799. +            XSetInputFocus( display, fs_window, RevertToPointerRoot, CurrentTime );
  10800. +            x11_ungrab_fullscreen_input( display );
  10801. +        }
  10802. +    } else {
  10803. +        XWindowAttributes attrs;
  10804. +
  10805. +        XGetWindowAttributes( display, wm_window, &attrs );
  10806. +
  10807. +        output_width = attrs.width;
  10808. +        output_height = attrs.height;
  10809. +        window_area.width = attrs.width;
  10810. +        window_area.height = attrs.height;
  10811. +
  10812. +        if( has_ewmh_state_fullscreen ) {
  10813. +            XEvent ev;
  10814. +
  10815. +            ev.type = ClientMessage;
  10816. +            ev.xclient.display = display;
  10817. +            ev.xclient.window = wm_window;
  10818. +            ev.xclient.message_type = net_wm_state;
  10819. +            ev.xclient.format = 32;
  10820. +            ev.xclient.data.l[ 0 ] = 0;
  10821. +            ev.xclient.data.l[ 1 ] = net_wm_state_fullscreen;
  10822. +            ev.xclient.data.l[ 2 ] = 0;
  10823. +            ev.xclient.data.l[ 3 ] = 0;
  10824. +            ev.xclient.data.l[ 4 ] = 0;
  10825. +
  10826. +            XSendEvent( display, DefaultRootWindow( display ), False,
  10827. +                        SubstructureNotifyMask | SubstructureRedirectMask,
  10828. +                        &ev );
  10829. +        } else {
  10830. +            XReparentWindow( display, output_window, wm_window, 0, 0 );
  10831. +            XUnmapWindow( display, fs_window );
  10832. +            x11_wait_unmapped( display, fs_window );
  10833. +        }
  10834. +    }
  10835. +    XResizeWindow( display, output_window, output_width, output_height );
  10836. +    calculate_video_area();
  10837. +    xcommon_clear_screen();
  10838. +    XFlush( display );
  10839. +    XSync( display, False );
  10840. +
  10841. +    return output_fullscreen;
  10842. +}
  10843. +
  10844. +int xcommon_toggle_root( int fullscreen_width, int fullscreen_height )
  10845. +{
  10846. +    return 0;
  10847. +}
  10848. +
  10849. +int xcommon_toggle_aspect( void )
  10850. +{
  10851. +    output_aspect = !output_aspect;
  10852. +    calculate_video_area();
  10853. +    xcommon_clear_screen();
  10854. +    return output_aspect;
  10855. +}
  10856. +
  10857. +void xcommon_update_server_time( unsigned long timestamp )
  10858. +{
  10859. +    if( !timestamp ) {
  10860. +        /**
  10861. +         * Get the current timestamp by causing an event to be generated
  10862. +         * by the X server.  This is only a single round-trip to the
  10863. +         * X server.  Inspired by kapplication::updateUserTimestamp().
  10864. +         */
  10865. +        unsigned char data[ 1 ];
  10866. +        Window w = XCreateSimpleWindow( display, DefaultRootWindow( display ),
  10867. +                                        0, 0, 1, 1, 0, 0, 0 );
  10868. +        XEvent ev;
  10869. +        XSelectInput( display, w, PropertyChangeMask );
  10870. +        XChangeProperty( display, w, XA_ATOM, XA_ATOM, 8,
  10871. +                         PropModeAppend, data, 1 );
  10872. +        XWindowEvent( display, w, PropertyChangeMask, &ev );
  10873. +        timestamp = ev.xproperty.time;
  10874. +        XDestroyWindow( display, w );
  10875. +    }
  10876. +
  10877. +    last_server_time = timestamp;
  10878. +    XChangeProperty( display, wm_window, net_wm_user_time, XA_CARDINAL, 32,
  10879. +                     PropModeReplace, (unsigned char *) &timestamp, 1 );
  10880. +}
  10881. +
  10882. +void xcommon_poll_events( input_t *in )
  10883. +{
  10884. +    XEvent event;
  10885. +    int reconfigure = 0;
  10886. +    int reconfwidth = 0;
  10887. +    int reconfheight = 0;
  10888. +    int getfocus = 0;
  10889. +    int motion = 0;
  10890. +    int motion_x = 0;
  10891. +    int motion_y = 0;
  10892. +    int bx = -1;
  10893. +    int by = -1;
  10894. +    int bw = -1;
  10895. +    int bh = -1;
  10896. +
  10897. +    while( XPending( display ) ) {
  10898. +        KeySym mykey;
  10899. +        char mykey_string;
  10900. +        int arg = 0;
  10901. +
  10902. +        XNextEvent( display, &event );
  10903. +
  10904. +        switch( event.type ) {
  10905. +        case ClientMessage:
  10906. +            /* X sucks this way.  Thanks to walken for help on this one. */
  10907. +            if( ( event.xclient.message_type == wm_protocols ) && ( event.xclient.format == 32 ) &&
  10908. +                ( event.xclient.data.l[ 0 ] == wm_delete_window ) ) {
  10909. +                input_callback( in, I_QUIT, 0 );
  10910. +            }
  10911. +            break;
  10912. +
  10913. +        case Expose:
  10914. +            if( bx < 0 ) {
  10915. +                bx = event.xexpose.x;
  10916. +                by = event.xexpose.y;
  10917. +                bw = event.xexpose.width;
  10918. +                bh = event.xexpose.height;
  10919. +            } else {
  10920. +                int dx, dy, dw, dh;
  10921. +                int cx, cy, cw, ch;
  10922. +                cx = event.xexpose.x;
  10923. +                cy = event.xexpose.y;
  10924. +                cw = event.xexpose.width;
  10925. +                ch = event.xexpose.height;
  10926. +                dx = MIN(bx, cx);
  10927. +                dy = MIN(by, cy);
  10928. +                dw = MAX(bx + bw, cx + cw) - dx;
  10929. +                dh = MAX(by + bh, cy + ch) - dy;
  10930. +                bx = dx;
  10931. +                by = dy;
  10932. +                bw = dw;
  10933. +                bh = dh;
  10934. +            }
  10935. +            break;
  10936. +        case DestroyNotify:
  10937. +            if( event.xdestroywindow.window != wm_window ) {
  10938. +                break;
  10939. +            }
  10940. +            input_callback( in, I_QUIT, 0 );
  10941. +            break;
  10942. +        case MotionNotify:
  10943. +            if( event.xmotion.x >= video_area.x && event.xmotion.x < (video_area.x + video_area.width) &&
  10944. +                event.xmotion.y >= video_area.y && event.xmotion.y < (video_area.y + video_area.height) &&
  10945. +                video_area.width && video_area.height ) {
  10946. +
  10947. +                int videox = event.xmotion.x - video_area.x;
  10948. +                int videoy = event.xmotion.y - video_area.y;
  10949. +                int imagex = scale_area.x + ((scale_area.width * videox) / video_area.width);
  10950. +                int imagey = scale_area.y + ((scale_area.height * videoy) / video_area.height);
  10951. +
  10952. +                motion = 1;
  10953. +                motion_x = imagex;
  10954. +                motion_y = imagey;
  10955. +            }
  10956. +            XUndefineCursor( display, output_window );
  10957. +            motion_timeout = 30;
  10958. +            break;
  10959. +        case EnterNotify:
  10960. +            getfocus = 1;
  10961. +            break;
  10962. +        case FocusIn:
  10963. +            has_focus = 1;
  10964. +            break;
  10965. +        case FocusOut:
  10966. +            has_focus = 0;
  10967. +            break;
  10968. +        case MapNotify:
  10969. +            if( !output_on_root ) {
  10970. +                xcommon_exposed = 1;
  10971. +                xcommon_clear_screen();
  10972. +                if( xcommon_verbose ) {
  10973. +                    fprintf( stderr, "xcommon: Received a map, marking window as visible (%lu).\n",
  10974. +                             event.xany.serial );
  10975. +                }
  10976. +            }
  10977. +            break;
  10978. +        case UnmapNotify:
  10979. +            if( !output_on_root ) {
  10980. +                xcommon_exposed = 0;
  10981. +                if( xcommon_verbose ) {
  10982. +                    fprintf( stderr, "xcommon: Received an unmap, marking window as hidden (%lu).\n",
  10983. +                             event.xany.serial );
  10984. +                }
  10985. +            }
  10986. +            break;
  10987. +        case VisibilityNotify:
  10988. +            if( !output_on_root ) {
  10989. +                if( event.xvisibility.state == VisibilityFullyObscured ) {
  10990. +                    if( xcommon_exposed ) {
  10991. +                        xcommon_exposed = 0;
  10992. +                        if( xcommon_verbose ) {
  10993. +                            fprintf( stderr, "xcommon: Window fully obscured, marking window as hidden (%lu).\n",
  10994. +                                     event.xany.serial );
  10995. +                        }
  10996. +                    }
  10997. +                } else if( !xcommon_exposed ) {
  10998. +                    xcommon_exposed = 1;
  10999. +                    xcommon_clear_screen();
  11000. +                    if( xcommon_verbose ) {
  11001. +                        fprintf( stderr, "xcommon: Window made visible, marking window as visible (%lu).\n",
  11002. +                                 event.xany.serial );
  11003. +                    }
  11004. +                }
  11005. +            }
  11006. +            break;
  11007. +        case ConfigureNotify:
  11008. +            if( event.xconfigure.window == wm_window ) {
  11009. +                if( event.xconfigure.send_event == False ) {
  11010. +                    int gx, gy;
  11011. +                    Window dw;
  11012. +
  11013. +                    if( XTranslateCoordinates( display, wm_window,
  11014. +                                               DefaultRootWindow( display ),
  11015. +                                               0, 0, &gx, &gy, &dw) == True) {
  11016. +                        window_area.x = gx;
  11017. +                        window_area.y = gy;
  11018. +                    }
  11019. +                } else {
  11020. +                    window_area.x = event.xconfigure.x;
  11021. +                    window_area.y = event.xconfigure.y;
  11022. +                }
  11023. +                window_area.width = event.xconfigure.width;
  11024. +                window_area.height = event.xconfigure.height;
  11025. +            }
  11026. +            reconfwidth = event.xconfigure.width;
  11027. +            reconfheight = event.xconfigure.height;
  11028. +            if( reconfwidth != output_width || reconfheight != output_height ) {
  11029. +                reconfigure = 1;
  11030. +            }
  11031. +            break;
  11032. +        case PropertyNotify:
  11033. +            if( event.xproperty.atom == xawtv_remote ) {
  11034. +                Atom type_return;
  11035. +                int format_return;
  11036. +                unsigned long bytes_after_return;
  11037. +                unsigned long nitems_return;
  11038. +                unsigned char *prop_return = 0;
  11039. +                char *argv[ 32 ];
  11040. +                if( XGetWindowProperty( display, event.xproperty.window,
  11041. +                                        event.xproperty.atom, 0, 65536,
  11042. +                                        True, XA_STRING, &type_return,
  11043. +                                        &format_return, &nitems_return,
  11044. +                                        &bytes_after_return,
  11045. +                                        &prop_return ) == Success ) {
  11046. +                    if( nitems_return > 0 ) {
  11047. +                        int arg = 0;
  11048. +                        int i;
  11049. +                        for( i = 0; i < nitems_return && *(prop_return + i); i += strlen( ((char *) prop_return) + i ) + 1 ) {
  11050. +                            argv[ arg++ ] = ((char *) prop_return) + i;
  11051. +                        }
  11052. +                        argv[ arg ] = 0;
  11053. +                        input_xawtv_command( in, arg, argv );
  11054. +                        XFree( prop_return );
  11055. +                    }
  11056. +                }
  11057. +            }
  11058. +            break;
  11059. +        case KeyPress:
  11060. +            xcommon_update_server_time( event.xkey.time );
  11061. +            /* if( event.xkey.state & ShiftMask ) arg |= I_SHIFT; */
  11062. +            /* this alternate approach allows handling of keys like '<' and '>' -- mrallen */
  11063. +            if( event.xkey.state & ShiftMask ) {
  11064. +                mykey = XKeycodeToKeysym( display, event.xkey.keycode, 1 );
  11065. +            } else {
  11066. +                mykey = XKeycodeToKeysym( display, event.xkey.keycode, 0 );
  11067. +            }
  11068. +            if( event.xkey.state & ControlMask ) arg |= I_CTRL;
  11069. +            if( event.xkey.state & Mod1Mask ) arg |= I_META;
  11070. +
  11071. +            if( mykey >= XK_a && mykey <= XK_z ) {
  11072. +                arg |= mykey - XK_a + 'a';
  11073. +            } else if( mykey >= XK_A && mykey <= XK_Z ) {
  11074. +                arg |= mykey - XK_A + 'a';
  11075. +            } else if( mykey >= XK_0 && mykey <= XK_9 ) {
  11076. +                arg |= mykey - XK_0 + '0';
  11077. +            } else {
  11078. +                XLookupString( &event.xkey, &mykey_string, 1, 0, 0 );
  11079. +                arg |= mykey_string;
  11080. +            }
  11081. +
  11082. +            switch( mykey ) {
  11083. +            case XK_Escape: arg |= I_ESCAPE; break;
  11084. +
  11085. +            case XK_Home:      arg |= I_HOME; break;
  11086. +            case XK_End:       arg |= I_END; break;
  11087. +            case XK_Left:      arg |= I_LEFT; break;
  11088. +            case XK_Up:        arg |= I_UP; break;
  11089. +            case XK_Right:     arg |= I_RIGHT; break;
  11090. +            case XK_Down:      arg |= I_DOWN; break;
  11091. +            case XK_Page_Up:   arg |= I_PGUP; break;
  11092. +            case XK_Page_Down: arg |= I_PGDN; break;
  11093. +            case XK_Insert:    arg |= I_INSERT; break;
  11094. +
  11095. +            case XK_F1: arg |= I_F1; break;
  11096. +            case XK_F2: arg |= I_F2; break;
  11097. +            case XK_F3: arg |= I_F3; break;
  11098. +            case XK_F4: arg |= I_F4; break;
  11099. +            case XK_F5: arg |= I_F5; break;
  11100. +            case XK_F6: arg |= I_F6; break;
  11101. +            case XK_F7: arg |= I_F7; break;
  11102. +            case XK_F8: arg |= I_F8; break;
  11103. +            case XK_F9: arg |= I_F9; break;
  11104. +            case XK_F10: arg |= I_F10; break;
  11105. +            case XK_F11: arg |= I_F11; break;
  11106. +            case XK_F12: arg |= I_F12; break;
  11107. +
  11108. +            case XK_KP_Enter: arg |= I_ENTER; break;
  11109. +            case XK_KP_0: arg |= '0'; break;
  11110. +            case XK_KP_1: arg |= '1'; break;
  11111. +            case XK_KP_2: arg |= '2'; break;
  11112. +            case XK_KP_3: arg |= '3'; break;
  11113. +            case XK_KP_4: arg |= '4'; break;
  11114. +            case XK_KP_5: arg |= '5'; break;
  11115. +            case XK_KP_6: arg |= '6'; break;
  11116. +            case XK_KP_7: arg |= '7'; break;
  11117. +            case XK_KP_8: arg |= '8'; break;
  11118. +            case XK_KP_9: arg |= '9'; break;
  11119. +            case XK_KP_Multiply: arg |= '*'; break;
  11120. +            case XK_KP_Subtract: arg |= '-'; break;
  11121. +            case XK_KP_Add: arg |= '+'; break;
  11122. +            case XK_KP_Divide: arg |= '/'; break;
  11123. +
  11124. +            case XK_KP_Insert: arg |= '0'; break;
  11125. +            case XK_KP_End: arg |= '1'; break;
  11126. +            case XK_KP_Down: arg |= '2'; break;
  11127. +            case XK_KP_Next: arg |= '3'; break;
  11128. +            case XK_KP_Left: arg |= '4'; break;
  11129. +            case XK_KP_Begin: arg |= '5'; break;
  11130. +            case XK_KP_Right: arg |= '6'; break;
  11131. +            case XK_KP_Home: arg |= '7'; break;
  11132. +            case XK_KP_Up: arg |= '8'; break;
  11133. +            case XK_KP_Prior: arg |= '9'; break;
  11134. +
  11135. +            default: break;
  11136. +            }
  11137. +            input_callback( in, I_KEYDOWN, arg );
  11138. +            break;
  11139. +        case ButtonPress:
  11140. +            xcommon_update_server_time( event.xbutton.time );
  11141. +            if( event.xbutton.time != lastpresstime ) {
  11142. +                input_callback( in, I_BUTTONPRESS, event.xbutton.button );
  11143. +                lastpresstime = event.xbutton.time;
  11144. +            }
  11145. +            getfocus = 1;
  11146. +            break;
  11147. +        case ButtonRelease:
  11148. +            xcommon_update_server_time( event.xbutton.time );
  11149. +            if( event.xbutton.time != lastreleasetime ) {
  11150. +                input_callback( in, I_BUTTONRELEASE, event.xbutton.button );
  11151. +                lastreleasetime = event.xbutton.time;
  11152. +            }
  11153. +            getfocus = 1;
  11154. +            break;
  11155. +        default: break;
  11156. +        }
  11157. +    }
  11158. +
  11159. +    if( motion ) {
  11160. +        input_callback( in, I_MOUSEMOVE, ((motion_x & 0xffff) << 16 | (motion_y & 0xffff)) );
  11161. +    }
  11162. +
  11163. +    if( getfocus ) {
  11164. +        XSetInputFocus( display, wm_window, RevertToPointerRoot, CurrentTime );
  11165. +    }
  11166. +
  11167. +    if( !has_ewmh_state_fullscreen && output_fullscreen ) {
  11168. +        /**
  11169. +         * We used to check if we still have focus too.
  11170. +         * Let's ignore that for now and see how well this
  11171. +         * works.
  11172. +         */
  11173. +        if( !xcommon_exposed /* || !has_focus */ ) {
  11174. +            /**
  11175. +             * Switch back to windowed mode if we have lost
  11176. +             * input focus or window visibility.
  11177. +             */
  11178. +            xcommon_toggle_fullscreen( 0, 0 );
  11179. +        }
  11180. +    }
  11181. +
  11182. +    if( bx >= 0 ) {
  11183. +        xcommon_clear_area( bx, by, bw, bh );
  11184. +    }
  11185. +
  11186. +    if( reconfigure ) {
  11187. +        if( !output_on_root && !output_fullscreen ) {
  11188. +            output_width = reconfwidth;
  11189. +            output_height = reconfheight;
  11190. +            XResizeWindow( display, output_window,
  11191. +                           output_width, output_height );
  11192. +        }
  11193. +
  11194. +        calculate_video_area();
  11195. +        xcommon_clear_screen();
  11196. +        XSync( display, False );
  11197. +    }
  11198. +}
  11199. +
  11200. +void xcommon_close_display( void )
  11201. +{
  11202. +#ifdef HAVE_XSSEXTENSION
  11203. +    if ( have_xss ) {
  11204. +        XScreenSaverSuspend( display, False );
  11205. +    }
  11206. +#endif
  11207. +    XDestroyWindow( display, output_window );
  11208. +    XDestroyWindow( display, wm_window );
  11209. +    XDestroyWindow( display, fs_window );
  11210. +    XCloseDisplay( display );
  11211. +    xfullscreen_delete( xf );
  11212. +}
  11213. +
  11214. +static char *old_caption = 0;
  11215. +
  11216. +void xcommon_set_window_caption( const char *caption )
  11217. +{
  11218. +    if( !old_caption || strcmp( caption, old_caption ) ) {
  11219. +        if( old_caption ) free( old_caption );
  11220. +        old_caption = strdup( caption );
  11221. +        XStoreName( display, wm_window, caption );
  11222. +        XChangeProperty( display, wm_window, net_wm_name, utf8_string, 8,
  11223. +                         PropModeReplace, (const unsigned char *) caption,
  11224. +                         strlen( caption ) );
  11225. +    }
  11226. +}
  11227. +
  11228. +Display *xcommon_get_display( void )
  11229. +{
  11230. +    return display;
  11231. +}
  11232. +
  11233. +Window xcommon_get_output_window( void )
  11234. +{
  11235. +    return output_window;
  11236. +}
  11237. +
  11238. +GC xcommon_get_gc( void )
  11239. +{
  11240. +    return gc;
  11241. +}
  11242. +
  11243. +int xcommon_is_fullscreen( void )
  11244. +{
  11245. +    return output_fullscreen;
  11246. +}
  11247. +
  11248. +int xcommon_is_alwaysontop( void )
  11249. +{
  11250. +    return alwaysontop;
  11251. +}
  11252. +
  11253. +int xcommon_is_fullscreen_supported( void )
  11254. +{
  11255. +    return 1;
  11256. +}
  11257. +
  11258. +int xcommon_is_alwaysontop_supported( void )
  11259. +{
  11260. +    return has_ewmh_state_above;
  11261. +}
  11262. +
  11263. +area_t xcommon_get_video_area( void )
  11264. +{
  11265. +    return video_area;
  11266. +}
  11267. +
  11268. +int xcommon_is_exposed( void )
  11269. +{
  11270. +    return xcommon_exposed;
  11271. +}
  11272. +
  11273. +void xcommon_set_colourkey( int colourkey )
  11274. +{
  11275. +    xcommon_colourkey = colourkey;
  11276. +}
  11277. +
  11278. +int xcommon_get_visible_width( void )
  11279. +{
  11280. +    return video_area.width;
  11281. +}
  11282. +
  11283. +int xcommon_get_visible_height( void )
  11284. +{
  11285. +    return video_area.height;
  11286. +}
  11287. +
  11288. +area_t xcommon_get_window_area( void )
  11289. +{
  11290. +    return window_area;
  11291. +}
  11292. +
  11293. +void xcommon_set_fullscreen_position( int pos )
  11294. +{
  11295. +    fullscreen_position = pos;
  11296. +    calculate_video_area();
  11297. +    xcommon_clear_screen();
  11298. +}
  11299. +
  11300. +void xcommon_set_matte( int width, int height )
  11301. +{
  11302. +    matte_width = width;
  11303. +    matte_height = height;
  11304. +    calculate_video_area();
  11305. +    xcommon_clear_screen();
  11306. +    XSync( display, False );
  11307. +}
  11308. +
  11309. +void xcommon_set_video_scale( area_t scalearea )
  11310. +{
  11311. +    scale_area = scalearea;
  11312. +}
  11313. +
  11314. +void xcommon_update_xawtv_station( int frequency, int channel_id,
  11315. +                                   const char *channel_name )
  11316. +{
  11317. +    char data[ 1024 ];
  11318. +    int length;
  11319. +
  11320. +    length  = sprintf( data, "%.3f", ((float) frequency) / 1000.0 ) + 1;
  11321. +    length += sprintf( data + length, "%d", channel_id ) + 1;
  11322. +    length += sprintf( data + length, "%s", channel_name ) + 1;
  11323. +
  11324. +    XChangeProperty( display, wm_window, xawtv_station,
  11325. +                     XA_STRING, 8, PropModeReplace,
  11326. +                     (unsigned char *) data, length );
  11327. +}
  11328. +
  11329. +void xcommon_set_square_pixel_mode( int squarepixel )
  11330. +{
  11331. +    use_square_pixels = squarepixel;
  11332. +}
  11333. +
  11334. diff -Nurp tvtime-1.0.2/src/xfullscreen.c tvtime-1.0.2-custom/src/xfullscreen.c
  11335. --- tvtime-1.0.2/src/xfullscreen.c      2004-10-14 02:12:02.000000000 +0200
  11336. +++ tvtime-1.0.2-custom/src/xfullscreen.c       2011-05-29 13:07:28.195707767 +0200
  11337. @@ -263,6 +263,10 @@ void xfullscreen_get_position( xfullscre
  11338.          int max_area = -1;
  11339.          int i;
  11340.  
  11341. +        *x = xf->heads[ 0 ].x;
  11342. +        *y = xf->heads[ 0 ].y;
  11343. +        *w = xf->heads[ 0 ].w;
  11344. +        *h = xf->heads[ 0 ].h;
  11345.          for( i = 0; i < xf->nheads; i++ ) {
  11346.              int head_x1 = xf->heads[ i ].x;
  11347.              int head_x2 = xf->heads[ i ].x + xf->heads[ i ].w - 1;
  11348. diff -Nurp tvtime-1.0.2/src/xmltv.c tvtime-1.0.2-custom/src/xmltv.c
  11349. --- tvtime-1.0.2/src/xmltv.c    2004-09-26 18:40:01.000000000 +0200
  11350. +++ tvtime-1.0.2-custom/src/xmltv.c     2011-05-29 13:07:28.229041508 +0200
  11351. @@ -118,9 +118,9 @@ const int num_timezones = sizeof( date_m
  11352.  typedef struct {
  11353.      const char *code;
  11354.      const char *name;
  11355. -} locale_t;
  11356. +} tv_locale_t;
  11357.  
  11358. -static locale_t locale_table[] = {
  11359. +static tv_locale_t locale_table[] = {
  11360.      {"AA", "Afar"},           {"AB", "Abkhazian"},      {"AF", "Afrikaans"},
  11361.      {"AM", "Amharic"},        {"AR", "Arabic"},         {"AS", "Assamese"},
  11362.      {"AY", "Aymara"},         {"AZ", "Azerbaijani"},    {"BA", "Bashkir"},
  11363. @@ -168,7 +168,7 @@ static locale_t locale_table[] = {
  11364.      {"XH", "Xhosa"},          {"YO", "Yoruba"},         {"ZH", "Chinese"},
  11365.      {"ZU", "Zulu"} };
  11366.  
  11367. -const int num_locales = sizeof( locale_table ) / sizeof( locale_t );
  11368. +const int num_locales = sizeof( locale_table ) / sizeof( tv_locale_t );
  11369.  
  11370.  /**
  11371.   * Timezone parsing code based loosely on the algorithm in
  11372. diff -Nurp tvtime-1.0.2/src/xvoutput.c tvtime-1.0.2-custom/src/xvoutput.c
  11373. --- tvtime-1.0.2/src/xvoutput.c 2005-08-14 19:35:50.000000000 +0200
  11374. +++ tvtime-1.0.2-custom/src/xvoutput.c  2011-05-29 13:07:28.189041018 +0200
  11375. @@ -233,7 +233,7 @@ static int xv_alloc_frame( void )
  11376.  {
  11377.      int size;
  11378.      uint8_t *alloc;
  11379. -
  11380. +    
  11381.      size = input_width * input_height * 2;
  11382.      if( use_shm ) {
  11383.          alloc = create_shm( size );
clone this paste RAW Paste Data