diff -ruN vdr-1.5.14/CONTRIBUTORS vdr-1.5.15/CONTRIBUTORS
--- vdr-1.5.14/CONTRIBUTORS	2008-01-26 16:20:41.000000000 +0100
+++ vdr-1.5.15/CONTRIBUTORS	2008-02-16 17:12:21.000000000 +0100
@@ -86,6 +86,7 @@
  for implementing the 'CurrentChannel' setup parameter
  for fixing setting the OSD size in the 'Confirm' interface call
  for fixing handling improper buffer lengths in the EIT parser
+ for a patch that was used to implement StopSectionHandler()
 
 Dave Chapman <dave@dchapman.com>
  for implementing support for the teletext PID
@@ -1039,6 +1040,9 @@
  for some fixes to PLUGINS.html
  for fixing handling CONFDIR
  for updating the Makefile of the skincurses plugin
+ for suggesting to limit the length of the recording name in timers created via
+ SVDRP in case VDR is run with --vfat, in order to avoid names that are too long
+ for Windows
 
 Ralf Klueber <ralf.klueber@vodafone.com>
  for reporting a bug in cutting a recording if there is only a single editing mark
@@ -1158,6 +1162,7 @@
  for a patch that was used to fix handling small PES packets that caused subtitles
  to be displayed late in live mode
  for a patch that was used to implement handling of DVB-S2
+ for reporting an invalid access in the section handler when ending VDR
 
 Richard Robson <richard_robson@beeb.net>
  for reporting freezing replay if a timer starts while in Transfer Mode from the
@@ -1447,6 +1452,8 @@
  an example ~cMyReceiver() in PLUGINS.html (thanks to Marco Schlüßler).
  for fixing checking compatibility mode for old subtitles plugin
  for a patch that was used to implement handling of DVB-S2
+ for fixing setting the date in the channel display of the classic and sttng skins,
+ to avoid unnecessary OSD access
 
 Jürgen Schmitz <j.schmitz@web.de>
  for reporting a bug in displaying the current channel when switching via the SVDRP
@@ -1612,6 +1619,8 @@
  it in a context sensitive manner
  for reporting a loss of the date display in the "classic" skin's main menu
  for reporting a missing setting of lastFreeMB in cMenuMain::Update()
+ for suggesting to ignore "repeat" and "release" keys in the time search entry mode
+ during replay, to avoid inadvertently leaving it in case a key is pressed too long
 
 Dino Ravnic <dino.ravnic@fer.hr>
  for fixing some characters in the iso8859-2 font file
@@ -1664,6 +1673,8 @@
 Walter Koch <koch@u32.de>
  for adding channels for DVB-T Düsseldorf and Köln (Germany) to channels.cont.terr
  for fixing some missing '-' in the German OSD texts
+ for suggesting to display the free disk space also in the title of the "Recordings"
+ menu
 
 Rolf Groppe <rolf@groppe.de>
  for suggesting to fall back to 'stereo' when switching channels in case the user
@@ -1678,6 +1689,8 @@
  for removing an unnecessary #include from osd.c
  for reporting a problem with with numerical input to switch channels if Up, Down,
  Channel+ or Channel- is pressed
+ for pointing out a possible problem with asprintf() if the return value is not
+ checked
 
 Chad Flynt <hoochster@sofnet.com>
  for suggestions and experiments regarding the buffer reserve in cTransfer
@@ -1736,6 +1749,7 @@
  for fixing the link to the GPL2 at http://www.gnu.org in vdr.c
  for making the "Play" key start replay of the selected recording in the Recordings
  menu
+ for adding missing #include <limits.h> to epg.c and menuitems.h
 
 Steffen Beyer <cpunk@reactor.de>
  for fixing setting the colored button help after deleting a recording in case the next
@@ -1782,6 +1796,7 @@
  for adding a sleep in cDvbPlayer::Action() in case there is no data to send to the
  device, which avoids a busy loop on very fast machines
  for fixing a possible crash when loading an invalid XPM file
+ for suggesting to speed up anti-aliased font rendering by caching the blend indexes
 
 Matthias Lenk <matthias.lenk@amd.com>
  for reporting an out-of-bounds memory access with audio language ids
@@ -1954,6 +1969,8 @@
  for pointing out that plugins from cRemote::PutMacro() and cRemote::CallPlugin()
  need to be handled separately
  for making cTimeMs use the monotonic clock
+ for implementing the cStatus, cDevice and cPlayer functions for setting subtitle
+ tracks in plugins
 
 Marcel Schaeben <mts280@gmx.de>
  for his "Easy Input" patch
@@ -2270,3 +2287,15 @@
 
 Winfried Koehler <w_koehl@gmx.de>
  for fixing finding new transponders
+
+Hans-Werner Hilse <hilse@web.de>
+ for adding the command line option --userdump to enable core dumps in case VDR
+ is run as root with option -u
+
+Mikko Matilainen <mikkom@iki.fi>
+ for reporting a possible crash if the Info key is pressed after deleting the
+ currently replayed recording
+
+Benedikt Elser <elser@in.tum.de>
+ for a patch that was used to add cStatus::TimerChange() to inform plugins about
+ changes to the list of timers
diff -ruN vdr-1.5.14/HISTORY vdr-1.5.15/HISTORY
--- vdr-1.5.14/HISTORY	2008-01-27 15:40:11.000000000 +0100
+++ vdr-1.5.15/HISTORY	2008-02-17 15:29:24.000000000 +0100
@@ -5465,7 +5465,7 @@
 - Fixed a new[]/delete mismatch in cMenuEditStrItem::LeaveEditMode() (thanks to
   Udo Richter).
 - Implemented sending all frames to devices that can handle them in fast forward
-  trick speeds (thansk to Timo Eskola).
+  trick speeds (thanks to Timo Eskola).
 - Updated the Hungarian language texts (thanks to Thomas Günther).
 - Fixed description of DeviceSetAvailableTrack() and cReceiver(), and added an
   example ~cMyReceiver() in PLUGINS.html (thanks to Marco Schlüßler).
@@ -5578,3 +5578,68 @@
 - Removed switching to the next higher or lower channel if the current channel
   is not available, in order to allow staying on an encrypted channel that takes
   a while for the CAM to start decrypting.
+
+2008-02-17: Version 1.5.15
+
+- Updated the Italian OSD texts (thanks to Diego Pierotto).
+- Added option -i to the pictures plugin's pic2mpg to ignore unknown file types.
+- Revoked the switch to the "multiproto" driver in order to make a new stable
+  version before making this big switch and forcing all users to install a
+  driver that is not yet in the kernel source. The removed code will reappear
+  in version 1.7.0.
+  Note that you may need to switch back to an older version of your channels.conf
+  file if you have already used version 1.5.14, because it introduced new parameters.
+- Added the new command line option --userdump to enable core dumps in case VDR
+  is run as root with option -u (thanks to Hans-Werner Hilse).
+- Speeded up anti-aliased font rendering by caching the blend indexes (based on
+  a suggestion by Martin Wache).
+- Fixed setting the OSD area in the pictures plugin.
+- Ignoring "repeat" and "release" keys in the time search entry mode during replay,
+  to avoid inadvertently leaving it in case a key is pressed too long (suggested
+  by Andreas Brugger).
+- Improved sending all frames to devices that can handle them in fast forward
+  trick speeds, including subtitles (thanks to Timo Eskola).
+- The section handler is now stopped before the device is destroyed, to avoid
+  accessing file handles after they have become invalid (thanks to Reinhard
+  Nissl for reporting an invalid access when ending VDR, and to Deti Fliegl for
+  a patch that was used to implement StopSectionHandler()).
+- Fixed setting the date in the channel display of the classic and sttng skins,
+  to avoid unnecessary OSD access (thanks to Marco Schlüßler).
+- The free disk space is now also displayed in the title of the "Recordings"
+  menu (suggested by Walter Koch).
+- Changed the message "Upcoming VPS recording!" to "Upcoming recording!" because
+  it applies to non-VPS recordings as well.
+- Fixed a loss of a timer's 'recording' flag after modifying it via MODT.
+- Fixed detecting directories in cFileNameList::Load().
+- Running the thread that removes deleted recordings at a low priority to (maybe)
+  avoid stuttering replay in case the thread is run during replay.
+- Limiting the length of the recording name in timers in case VDR is run with
+  --vfat, in order to avoid names that are too long for Windows (suggested by Rolf
+  Ahrenberg).
+- Using cString::sprintf() instead of asprintf() (thanks to Wolfgang Rohdewald
+  for pointing out a possible problem if the return value is not checked).
+  Plugin authors may want to consider doing the same. For convenience there is now
+  an additional version of cString::sprintf() that accepts a va_list parameter.
+- When deleting the recording that is currently replayed, the replay is now
+  stopped immediately (thanks to Mikko Matilainen for reporting a possible crash
+  if the Info key is pressed after deleting the currently replayed recording).
+- Updated the Russian OSD texts (thanks to Oleg Roitburd).
+- When determining the amount of free disk space, any deleted (but not yet removed)
+  recordings on different file systems (that are mounted under the video directory)
+  are no longer taken into account.
+- When running out of disk space during a recording, only such deleted or old
+  recordings are removed, that actually are on the video directory file system(s).
+  This prevents VDR from accidentally deleting recordings on other file systems,
+  which would not add any free space to the video directory.
+- Implemented the cStatus, cDevice and cPlayer functions for setting subtitle tracks
+  in plugins (thanks to Petri Hintukainen).
+- Added cStatus::TimerChange() to inform plugins about changes to the list of timers
+  (based on a patch from Benedikt Elser).
+- Added new cStatus functions to the 'status' plugin.
+- Added missing #include <limits.h> to epg.c and menuitems.h (thanks to Ville Skyttä).
+- The new function cSkin::SetScrollbar() can be implemented by skins to display
+  a scrollbar in every list menu. The 'classic' and 'sttng' skins have been
+  changed accordingly, as well as the 'skincurses' plugin.
+- Introduced 'operator const void * ()' in cString to catch cases where operator*()
+  should be used.
+- Fixed calculating the scrollbar sizes in the skins.
diff -ruN vdr-1.5.14/INSTALL vdr-1.5.15/INSTALL
--- vdr-1.5.14/INSTALL	2007-10-13 15:01:06.000000000 +0200
+++ vdr-1.5.15/INSTALL	2008-02-10 15:23:58.000000000 +0100
@@ -1,7 +1,7 @@
 Installation of the Video Disk Recorder
 ---------------------------------------
 
-Version 1.5
+Version 1.6
 -----------
 
 Compiling and running the program:
diff -ruN vdr-1.5.14/MANUAL vdr-1.5.15/MANUAL
--- vdr-1.5.14/MANUAL	2007-11-25 16:25:13.000000000 +0100
+++ vdr-1.5.15/MANUAL	2008-02-10 15:23:48.000000000 +0100
@@ -1,7 +1,7 @@
 Video Disk Recorder User's Manual
 ---------------------------------
 
-Version 1.4
+Version 1.6
 -----------
 
 * Remote Control Keys
diff -ruN vdr-1.5.14/Make.config.template vdr-1.5.15/Make.config.template
--- vdr-1.5.14/Make.config.template	2008-01-13 13:54:09.000000000 +0100
+++ vdr-1.5.15/Make.config.template	2008-01-13 13:54:09.000000000 +0100
@@ -19,7 +19,7 @@
 ifdef PLUGIN
 CFLAGS   += -fPIC
 CXXFLAGS += -fPIC
-endif 
+endif
 
 ### The directory environment:
 
diff -ruN vdr-1.5.14/PLUGINS/src/hello/po/it_IT.po vdr-1.5.15/PLUGINS/src/hello/po/it_IT.po
--- vdr-1.5.14/PLUGINS/src/hello/po/it_IT.po	2008-01-19 13:17:35.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/hello/po/it_IT.po	2008-02-17 14:45:16.000000000 +0100
@@ -1,36 +1,34 @@
 # VDR plugin language source file.
 # Copyright (C) 2007 Klaus Schmidinger <kls@cadsoft.de>
 # This file is distributed under the same license as the VDR package.
-# Alberto Carraro <bertocar@tin.it>, 2001
-# Antonio Ospite <ospite@studenti.unina.it>, 2003
-# Sean Carlos <seanc@libero.it>, 2005
+# Diego Pierotto <vdr-italian@tiscali.it>, 2008
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
 "POT-Creation-Date: 2007-10-13 11:52+0200\n"
-"PO-Revision-Date: 2007-08-11 12:34+0200\n"
-"Last-Translator: Sean Carlos <seanc@libero.it>\n"
-"Language-Team: <vdr@linuxtv.org>\n"
+"PO-Revision-Date: 2008-01-27 20:11+0100\n"
+"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
+"Language-Team:  <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 msgid "A friendly greeting"
-msgstr ""
+msgstr "Un saluto cordiale"
 
 msgid "Hello"
-msgstr ""
+msgstr "Ciao"
 
 msgid "Greeting time (s)"
-msgstr ""
+msgstr "Tempo saluto (s)"
 
 msgid "Use alternate greeting"
-msgstr ""
+msgstr "Utilizza saluto alternativo"
 
 msgid "Howdy folks!"
-msgstr ""
+msgstr "Come state gente!"
 
 msgid "Hello world!"
-msgstr ""
+msgstr "Ciao mondo!"
diff -ruN vdr-1.5.14/PLUGINS/src/pictures/HISTORY vdr-1.5.15/PLUGINS/src/pictures/HISTORY
--- vdr-1.5.14/PLUGINS/src/pictures/HISTORY	2008-01-19 12:36:41.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/pictures/HISTORY	2008-02-17 14:47:12.000000000 +0100
@@ -10,3 +10,17 @@
 - Fixed the Play function (when used from a directory in the pictures menu
   it always started with the next directory).
 - Added Finnish texts (thanks to Rolf Ahrenberg <rahrenbe@cc.hut.fi>).
+
+2008-01-27: Version 0.0.3
+
+- Added French texts (thanks to Patrice Staudt <ipatrice.staudt@laposte.net>).
+
+2008-02-02: Version 0.0.4
+
+- Added option -i to pic2mpg to ignore unknown file types.
+
+2008-02-17: Version 0.0.5
+
+- Fixed setting the OSD area.
+- Introduced 'operator const void * ()' in cString to catch cases where operator*()
+  should be used.
diff -ruN vdr-1.5.14/PLUGINS/src/pictures/entry.c vdr-1.5.15/PLUGINS/src/pictures/entry.c
--- vdr-1.5.14/PLUGINS/src/pictures/entry.c	2008-01-18 16:49:51.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/pictures/entry.c	2008-02-17 14:42:34.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: entry.c 1.2 2008/01/18 15:49:51 kls Exp $
+ * $Id: entry.c 1.3 2008/02/17 13:42:34 kls Exp $
  */
 
 #include "entry.h"
@@ -37,7 +37,7 @@
 
 cString cPictureEntry::Path(void) const
 {
-  return parent ? AddDirectory(parent->Path(), name) : name;
+  return parent ? *AddDirectory(parent->Path(), name) : name;
 }
 
 void cPictureEntry::Load(void) const
diff -ruN vdr-1.5.14/PLUGINS/src/pictures/pic2mpg vdr-1.5.15/PLUGINS/src/pictures/pic2mpg
--- vdr-1.5.14/PLUGINS/src/pictures/pic2mpg	2008-01-13 12:09:12.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/pictures/pic2mpg	2008-02-02 12:34:43.000000000 +0100
@@ -7,7 +7,7 @@
 #
 # See the README file for copyright information and how to reach the author.
 #
-# $Id: pic2mpg 1.1 2008/01/13 11:09:12 kls Exp $
+# $Id: pic2mpg 1.2 2008/02/02 11:34:43 kls Exp $
 
 ## TODO implement HDTV (1920 x 1080)
 
@@ -20,20 +20,22 @@
        $0 [options] picture-file mpeg-file
 
 Options: -a             Aspect ratio 4:3 (default is 16:9)
-         -h             print Help
          -f             Force conversion
+         -h             print Help
+         -i             Ignore unknown file types
          -n             NTSC (default is PAL)
          -v num         Verbose (0=none, 1=list files, 2=detailed)
          -x percent     X overscan in percent
          -y percent     Y overscan in percent
 };
 
-getopts("ahfnv:x:y:") || die $Usage;
+getopts("afhinv:x:y:") || die $Usage;
 
 die $Usage if $opt_h;
 
 $Aspect    = $opt_a;
 $Force     = $opt_f;
+$Ignore    = $opt_i;
 $NTSC      = $opt_n;
 $Verbose   = $opt_v;
 $OverscanX = $opt_x;
@@ -142,7 +144,10 @@
 {
   my ($Pict, $Mpeg) = @_;
   (my $Type) = $Pict =~ /\.([^\.]*)$/;
-  die "unknown file type '$Type': '$Pict'\n" unless defined $PNMCONV{$Type};
+  if (!defined $PNMCONV{$Type}) {
+     return if ($Ignore);
+     die "unknown file type '$Type': '$Pict'\n";
+     }
   my ($w, $h) = imgsize($Pict);
   print "image size is $w x $h\n" if ($Detailed);
   if ($w / $h <= $ScreenRatio) {
diff -ruN vdr-1.5.14/PLUGINS/src/pictures/pictures.c vdr-1.5.15/PLUGINS/src/pictures/pictures.c
--- vdr-1.5.14/PLUGINS/src/pictures/pictures.c	2008-01-19 12:20:03.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/pictures/pictures.c	2008-02-09 13:15:52.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: pictures.c 1.2 2008/01/19 11:20:03 kls Exp $
+ * $Id: pictures.c 1.5 2008/02/09 12:15:52 kls Exp $
  */
 
 #include <getopt.h>
@@ -11,7 +11,7 @@
 #include "menu.h"
 #include "player.h"
 
-static const char *VERSION       = "0.0.2";
+static const char *VERSION       = "0.0.5";
 static const char *DESCRIPTION   = trNOOP("A simple picture viewer");
 static const char *MAINMENUENTRY = trNOOP("Pictures");
 
diff -ruN vdr-1.5.14/PLUGINS/src/pictures/player.c vdr-1.5.15/PLUGINS/src/pictures/player.c
--- vdr-1.5.14/PLUGINS/src/pictures/player.c	2008-01-19 12:01:58.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/pictures/player.c	2008-02-09 13:13:10.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: player.c 1.2 2008/01/19 11:01:58 kls Exp $
+ * $Id: player.c 1.3 2008/02/09 12:13:10 kls Exp $
  */
 
 #include "player.h"
@@ -173,11 +173,11 @@
   int h = 2 * Font->Height();
   if (!osd) {
      osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - h, OSD_LEVEL_SUBTITLES);
-     tArea Areas[] = { { 0, 0, w, h, 8 } };
+     tArea Areas[] = { { 0, 0, w - 1, h - 1, 8 } };
      if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
      else {
-        tArea Areas[] = { { 0, 0, w, h, 4 } };
+        tArea Areas[] = { { 0, 0, w - 1, h - 1, 4 } };
         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
         }
      }
diff -ruN vdr-1.5.14/PLUGINS/src/pictures/po/fr_FR.po vdr-1.5.15/PLUGINS/src/pictures/po/fr_FR.po
--- vdr-1.5.14/PLUGINS/src/pictures/po/fr_FR.po	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/pictures/po/fr_FR.po	2008-02-17 14:45:20.000000000 +0100
@@ -0,0 +1,32 @@
+# VDR plugin language source file.
+# Copyright (C) 2008 Klaus Schmidinger <kls@cadsoft.de>
+# This file is distributed under the same license as the VDR package.
+# Patrice Staudt <patrice.staudt@laposte.net>, 2008."
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pictures 0.0.1\n"
+"Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
+"POT-Creation-Date: 2008-01-12 17:38+0100\n"
+"PO-Revision-Date: 2008-01-12 17:41+0100\n"
+"Last-Translator: Patrice Staudt <patrice.staudt@laposte.net>\n"
+"Language-Team: France\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgid "Pictures"
+msgstr "Images"
+
+msgid "A simple picture viewer"
+msgstr "Un simple visualiseur d'images"
+
+msgid "Picture directory"
+msgstr "Dossier des images"
+
+msgid "Slide show delay (s)"
+msgstr "Pause entre deux images (s)"
+
+msgid "No picture directory has been defined!"
+msgstr "Aucun dossier n'est définit!"
diff -ruN vdr-1.5.14/PLUGINS/src/pictures/po/it_IT.po vdr-1.5.15/PLUGINS/src/pictures/po/it_IT.po
--- vdr-1.5.14/PLUGINS/src/pictures/po/it_IT.po	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/pictures/po/it_IT.po	2008-02-17 14:45:20.000000000 +0100
@@ -0,0 +1,32 @@
+# VDR plugin language source file.
+# Copyright (C) 2008 Klaus Schmidinger <kls@cadsoft.de>
+# This file is distributed under the same license as the VDR package.
+# Diego Pierotto <vdr-italian@tiscali.it>, 2008
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pictures 0.0.1\n"
+"Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
+"POT-Creation-Date: 2008-01-12 17:38+0100\n"
+"PO-Revision-Date: 2008-01-27 20:22+0100\n"
+"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
+"Language-Team: Italian\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgid "Pictures"
+msgstr "Immagini"
+
+msgid "A simple picture viewer"
+msgstr "Un semplice visualizzatore immagini"
+
+msgid "Picture directory"
+msgstr "Directory immagini"
+
+msgid "Slide show delay (s)"
+msgstr "Ritardo diapositive (s)"
+
+msgid "No picture directory has been defined!"
+msgstr "Nessuna directory immagini impostata!"
diff -ruN vdr-1.5.14/PLUGINS/src/skincurses/HISTORY vdr-1.5.15/PLUGINS/src/skincurses/HISTORY
--- vdr-1.5.14/PLUGINS/src/skincurses/HISTORY	2008-01-19 12:42:41.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/skincurses/HISTORY	2008-02-17 15:28:26.000000000 +0100
@@ -65,3 +65,8 @@
 2008-01-19:
 
 - Updated the Makefile of the skincurses plugin (thanks to Rolf Ahrenberg).
+
+2008-02-15: Version 0.1.5
+
+- Using cString::sprintf() instead of asprintf().
+- Implemented cSkinCursesDisplayMenu::SetScrollbar().
diff -ruN vdr-1.5.14/PLUGINS/src/skincurses/po/it_IT.po vdr-1.5.15/PLUGINS/src/skincurses/po/it_IT.po
--- vdr-1.5.14/PLUGINS/src/skincurses/po/it_IT.po	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.15/PLUGINS/src/skincurses/po/it_IT.po	2008-02-17 15:19:08.000000000 +0100
@@ -0,0 +1,28 @@
+# VDR plugin language source file.
+# Copyright (C) 2007 Klaus Schmidinger <kls@cadsoft.de>
+# This file is distributed under the same license as the VDR package.
+# Diego Pierotto <vdr-italian@tiscali.it>, 2008
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: VDR 1.5.7\n"
+"Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
+"POT-Creation-Date: 2007-08-15 16:04+0200\n"
+"PO-Revision-Date: 2008-01-27 20:35+0100\n"
+"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
+"Language-Team:  <vdr@linuxtv.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "A text only skin"
+msgstr "Una interfaccia solo testo"
+
+msgid "Key$Mute"
+msgstr "Muto"
+
+msgid "Volume "
+msgstr "Volume "
+
+msgid "Text mode"
+msgstr "Modalità testo"
diff -ruN vdr-1.5.14/PLUGINS/src/skincurses/skincurses.c vdr-1.5.15/PLUGINS/src/skincurses/skincurses.c
--- vdr-1.5.14/PLUGINS/src/skincurses/skincurses.c	2007-08-26 22:16:59.000000000 +0200
+++ vdr-1.5.15/PLUGINS/src/skincurses/skincurses.c	2008-02-17 15:28:19.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: skincurses.c 1.18 2007/08/26 20:16:59 kls Exp $
+ * $Id: skincurses.c 1.20 2008/02/17 14:28:19 kls Exp $
  */
 
 #include <ncurses.h>
@@ -11,7 +11,7 @@
 #include <vdr/plugin.h>
 #include <vdr/skins.h>
 
-static const char *VERSION        = "0.1.4";
+static const char *VERSION        = "0.1.5";
 static const char *DESCRIPTION    = trNOOP("A text only skin");
 static const char *MAINMENUENTRY  = NULL;
 
@@ -166,7 +166,7 @@
      }
   SetColor(ColorFg, ColorBg);
   wmove(window, y, x); // ncurses wants 'y' before 'x'!
-  waddnstr(window, s, ScOsdWidth - x);
+  waddnstr(window, s, Width ? Width : ScOsdWidth - x);
 }
 
 void cCursesOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
@@ -261,7 +261,8 @@
 class cSkinCursesDisplayMenu : public cSkinDisplayMenu {
 private:
   cOsd *osd;
-  void SetScrollbar(void);
+  void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown);
+  void SetTextScrollbar(void);
 public:
   cSkinCursesDisplayMenu(void);
   virtual ~cSkinCursesDisplayMenu();
@@ -272,6 +273,7 @@
   virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
   virtual void SetMessage(eMessageType Type, const char *Text);
   virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable);
+  virtual void SetScrollbar(int Total, int Offset);
   virtual void SetEvent(const cEvent *Event);
   virtual void SetRecording(const cRecording *Recording);
   virtual void SetText(const char *Text, bool FixedFont);
@@ -290,25 +292,31 @@
   delete osd;
 }
 
-void cSkinCursesDisplayMenu::SetScrollbar(void)
+void cSkinCursesDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown)
 {
-  if (textScroller.CanScroll()) {
-     int yt = textScroller.Top();
-     int yb = yt + textScroller.Height() - 1;
+  if (Total > 0 && Total > Shown) {
+     int yt = Top;
+     int yb = yt + Height - 1;
      int st = yt;
      int sb = yb;
-     int tt = st + (sb - st) * textScroller.Offset() / textScroller.Total();
-     int tb = tt + (sb - st) * textScroller.Shown() / textScroller.Total();
+     int tt = st + (sb - st + 1) * Offset / Total;
+     int tb = tt + (sb - st + 1) * Shown / Total;
      int xl = ScOsdWidth - 1;
-     osd->DrawRectangle(xl, st, xl, sb, clrCyan);
-     osd->DrawRectangle(xl, tt, xl, tb, clrWhite);
+     osd->DrawRectangle(xl, st, xl, sb, clrWhite);
+     osd->DrawRectangle(xl, tt, xl, tb, clrCyan);
      }
 }
 
+void cSkinCursesDisplayMenu::SetTextScrollbar(void)
+{
+  if (textScroller.CanScroll())
+     DrawScrollbar(textScroller.Total(), textScroller.Offset(), textScroller.Shown(), textScroller.Top(), textScroller.Height(), textScroller.CanScrollUp(), textScroller.CanScrollDown());
+}
+
 void cSkinCursesDisplayMenu::Scroll(bool Up, bool Page)
 {
   cSkinDisplayMenu::Scroll(Up, Page);
-  SetScrollbar();
+  SetTextScrollbar();
 }
 
 int cSkinCursesDisplayMenu::MaxItems(void)
@@ -366,12 +374,17 @@
       const char *s = GetTabbedText(Text, i);
       if (s) {
          int xt = Tab(i) / 12;// Tab() is in "pixel" - see also skins.c!!!
-         osd->DrawText(xt, y, s, ColorFg, ColorBg, &Font, ScOsdWidth - xt);
+         osd->DrawText(xt, y, s, ColorFg, ColorBg, &Font, ScOsdWidth - 2 - xt);
          }
       if (!Tab(i + 1))
          break;
       }
-  SetEditableWidth(ScOsdWidth - Tab(1) / 12); // Tab() is in "pixel" - see also skins.c!!!
+  SetEditableWidth(ScOsdWidth - 2 - Tab(1) / 12); // Tab() is in "pixel" - see also skins.c!!!
+}
+
+void cSkinCursesDisplayMenu::SetScrollbar(int Total, int Offset)
+{
+  DrawScrollbar(Total, Offset, MaxItems(), 2, MaxItems(), Offset > 0, Offset + MaxItems() < Total);
 }
 
 void cSkinCursesDisplayMenu::SetEvent(const cEvent *Event)
@@ -384,10 +397,8 @@
   snprintf(t, sizeof(t), "%s  %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
   ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
   if (Event->Vps() && Event->Vps() != Event->StartTime()) {
-     char *buffer;
-     asprintf(&buffer, " VPS: %s", *Event->GetVpsString());
+     cString buffer = cString::sprintf(" VPS: %s", *Event->GetVpsString());
      osd->DrawText(ScOsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font);
-     free(buffer);
      }
   y += ts.Height();
   y += 1;
@@ -400,7 +411,7 @@
   y += 1;
   if (!isempty(Event->Description())) {
      textScroller.Set(osd, 0, y, ScOsdWidth - 2, ScOsdHeight - y - 2, Event->Description(), &Font, clrCyan, clrBackground);
-     SetScrollbar();
+     SetTextScrollbar();
      }
 }
 
@@ -428,14 +439,14 @@
   y += 1;
   if (!isempty(Info->Description())) {
      textScroller.Set(osd, 0, y, ScOsdWidth - 2, ScOsdHeight - y - 2, Info->Description(), &Font, clrCyan, clrBackground);
-     SetScrollbar();
+     SetTextScrollbar();
      }
 }
 
 void cSkinCursesDisplayMenu::SetText(const char *Text, bool FixedFont)
 {
   textScroller.Set(osd, 0, 2, ScOsdWidth - 2, ScOsdHeight - 4, Text, &Font, clrWhite, clrBackground);
-  SetScrollbar();
+  SetTextScrollbar();
 }
 
 void cSkinCursesDisplayMenu::Flush(void)
diff -ruN vdr-1.5.14/PLUGINS/src/status/HISTORY vdr-1.5.15/PLUGINS/src/status/HISTORY
--- vdr-1.5.14/PLUGINS/src/status/HISTORY	2007-08-15 15:19:52.000000000 +0200
+++ vdr-1.5.15/PLUGINS/src/status/HISTORY	2008-02-16 15:27:58.000000000 +0100
@@ -40,3 +40,7 @@
 
 - Moved the "all" target in the Makefile before the "Implicit rules",
   so that a plain "make" will compile everything.
+
+2008-02-16: Version 0.3.0
+
+- Added new cStatus functions.
diff -ruN vdr-1.5.14/PLUGINS/src/status/status.c vdr-1.5.15/PLUGINS/src/status/status.c
--- vdr-1.5.14/PLUGINS/src/status/status.c	2007-08-15 15:19:44.000000000 +0200
+++ vdr-1.5.15/PLUGINS/src/status/status.c	2008-02-16 16:41:05.000000000 +0100
@@ -3,13 +3,13 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: status.c 1.9 2007/08/15 13:19:44 kls Exp $
+ * $Id: status.c 1.10 2008/02/16 15:41:05 kls Exp $
  */
 
 #include <vdr/plugin.h>
 #include <vdr/status.h>
 
-static const char *VERSION        = "0.2.1";
+static const char *VERSION        = "0.3.0";
 static const char *DESCRIPTION    = "Status monitor test";
 static const char *MAINMENUENTRY  = NULL;
 
@@ -17,20 +17,30 @@
 
 class cStatusTest : public cStatus {
 protected:
+  virtual void TimerChange(const cTimer *Timer, eTimerChange Change);
   virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber);
   virtual void Recording(const cDevice *Device, const char *Name, const char *FileName, bool On);
   virtual void Replaying(const cControl *Control, const char *Name, const char *FileName, bool On);
   virtual void SetVolume(int Volume, bool Absolute);
+  virtual void SetAudioTrack(int Index, const char * const *Tracks);
+  virtual void SetAudioChannel(int AudioChannel);
+  virtual void SetSubtitleTrack(int Index, const char * const *Tracks);
   virtual void OsdClear(void);
   virtual void OsdTitle(const char *Title);
   virtual void OsdStatusMessage(const char *Message);
   virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue);
+  virtual void OsdItem(const char *Text, int Index);
   virtual void OsdCurrentItem(const char *Text);
   virtual void OsdTextItem(const char *Text, bool Scroll);
   virtual void OsdChannel(const char *Text);
   virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle);
   };
 
+void cStatusTest::TimerChange(const cTimer *Timer, eTimerChange Change)
+{
+  dsyslog("status: cStatusTest::TimerChange  %s %d", Timer ? *Timer->ToText(true) : "-", Change);
+}
+
 void cStatusTest::ChannelSwitch(const cDevice *Device, int ChannelNumber)
 {
   dsyslog("status: cStatusTest::ChannelSwitch  %d %d", Device->CardIndex(), ChannelNumber);
@@ -51,6 +61,21 @@
   dsyslog("status: cStatusTest::SetVolume  %d %d", Volume, Absolute);
 }
 
+void cStatusTest::SetAudioTrack(int Index, const char * const *Tracks)
+{
+  dsyslog("status: cStatusTest::SetAudioTrack  %d %s", Index, Tracks[Index]);
+}
+
+void cStatusTest::SetAudioChannel(int AudioChannel)
+{
+  dsyslog("status: cStatusTest::SetAudioChannel  %d", AudioChannel);
+}
+
+void cStatusTest::SetSubtitleTrack(int Index, const char * const *Tracks)
+{
+  dsyslog("status: cStatusTest::SetSubtitleTrack  %d %s", Index, Tracks[Index]);
+}
+
 void cStatusTest::OsdClear(void)
 {
   dsyslog("status: cStatusTest::OsdClear");
@@ -71,6 +96,11 @@
   dsyslog("status: cStatusTest::OsdHelpKeys %s - %s - %s - %s", Red, Green, Yellow, Blue);
 }
 
+void cStatusTest::OsdItem(const char *Text, int Index)
+{
+  //dsyslog("status: cStatusTest::OsdItem  %s %d", Text, Index);
+}
+
 void cStatusTest::OsdCurrentItem(const char *Text)
 {
   dsyslog("status: cStatusTest::OsdCurrentItem %s", Text);
diff -ruN vdr-1.5.14/PLUGINS.html vdr-1.5.15/PLUGINS.html
--- vdr-1.5.14/PLUGINS.html	2008-01-13 15:47:03.000000000 +0100
+++ vdr-1.5.15/PLUGINS.html	2008-02-10 15:22:21.000000000 +0100
@@ -6,27 +6,14 @@
 
 <center><h1>The VDR Plugin System</h1></center>
 
-<center><b>Version 1.5.8</b></center>
+<center><b>Version 1.6</b></center>
 <p>
 <center>
-Copyright &copy; 2006 Klaus Schmidinger<br>
+Copyright &copy; 2008 Klaus Schmidinger<br>
 <a href="mailto:kls@cadsoft.de">kls@cadsoft.de</a><br>
 <a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
 </center>
 <p>
-<!--X1.5.7--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
-Important modifications introduced in version 1.5.7 are marked like this.
-<!--X1.5.7--></td></tr></table>
-<!--X1.5.8--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
-Important modifications introduced in version 1.5.8 are marked like this.
-<!--X1.5.8--></td></tr></table>
-<!--X1.5.10--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
-Important modifications introduced in version 1.5.10 are marked like this.
-<!--X1.5.10--></td></tr></table>
-<!--X1.5.13--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
-Important modifications introduced in version 1.5.13 are marked like this.
-<!--X1.5.13--></td></tr></table>
-<p>
 VDR provides an easy to use plugin interface that allows additional functionality
 to be added to the program by implementing a dynamically loadable library file.
 This interface allows programmers to develop additional functionality for VDR completely
@@ -59,9 +46,7 @@
 <li><a href="#Command line help">Command line help</a>
 <li><a href="#Getting started">Getting started</a>
 <li><a href="#Shutting down">Shutting down</a>
-<!--X1.5.13--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
 <li><a href="#Logging">Logging</a>
-<!--X1.5.13--></td></tr></table>
 <li><a href="#Main menu entry">Main menu entry</a>
 <li><a href="#User interaction">User interaction</a>
 <li><a href="#Housekeeping">Housekeeping</a>
@@ -543,7 +528,6 @@
 returned <i>true</i>. The <tt>Stop()</tt> functions are called in the reverse order
 as the <a href="#Getting started"><tt>Start()</tt></a> functions were called.
 
-<!--X1.5.13--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
 <a name="Logging"><hr><h2>Logging</h2>
 
 If the plugin should print log messages, you can use <tt>dsyslog()</tt>, <tt>isyslog()</tt> or <tt>esyslog()</tt>.<br>
@@ -561,7 +545,6 @@
 
 Note that the log messages will be given as provided, the plugin's name will not
 automatically be added, so make shure your log messages are obvious enough.
-<!--X1.5.13--></td></tr></table>
 
 <a name="Main menu entry"><hr><h2>Main menu entry</h2>
 
@@ -929,7 +912,6 @@
 
 <center><i><b>Welcome to Babylon!</b></i></center><p>
 
-<!--X1.5.7--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
 If a plugin displays texts to the user, it should prepare for internationalization
 of these texts. All that is necessary for this is to mark every text that is
 presented to the user as translatable, as in
@@ -940,12 +922,10 @@
 
 The text given here must be the English version, and the returned pointer is either
 a translated version (if available) or the original string.
-<!--X1.5.8--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
 Texts are searched for in the domain registered for this plugin.
 If a plugin wants to make use of texts defined by the core VDR code, it can use
 the special <tt>trVDR()</tt> macro to mark these texts without having them
 appear in its own translation file.
-<!--X1.5.8--></td></tr></table>
 <p>
 Sometimes texts are stored in an array, in which case they need to be marked
 differently, using the trNOOP() macro. The actual translation is then done
@@ -973,7 +953,6 @@
 and are defined in <tt>VDR/tools.h</tt>.
 Most of the time a plugin doesn't need to care about this, but when it comes to
 handling individual characters these functions may come in handy.
-<!--X1.5.7--></td></tr></table>
 
 <a name="Custom services"><hr><h2>Custom services</h2>
 
@@ -1349,9 +1328,7 @@
 available audio tracks by calling
 
 <p><table><tr><td bgcolor=#F0F0F0><pre>
-<!--X1.5.10--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
 bool DeviceSetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, const char *Description = NULL)
-<!--X1.5.10--></td></tr></table>
 </pre></td></tr></table><p>
 
 See <tt>device.h</tt> for details about the parameters for track handling.
@@ -1477,19 +1454,15 @@
   };
 
 cMyReceiver::cMyReceiver(int Pid)
-<!--X1.5.10--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
 :cReceiver(tChannelID(), -1, Pid)
-<!--X1.5.10--></td></tr></table>
 {
 }
 
-<!--X1.5.10--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%><pre>
 cMyReceiver::~cMyReceiver()
 {
   cReceiver::Detach();
   ...
 }
-<!--X1.5.10--></pre></td></tr></table>
 
 void cMyReceiver::Activate(bool On)
 {
@@ -1851,9 +1824,7 @@
 virtual bool CanReplay(void) const;
 virtual bool SetPlayMode(ePlayMode PlayMode);
 virtual int64_t GetSTC(void);
-<!--X1.5.10--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
 virtual bool HasIBPTrickSpeed(void);
-<!--X1.5.10--></td></tr></table>
 virtual void TrickSpeed(int Speed);
 virtual void Clear(void);
 virtual void Play(void);
@@ -1881,9 +1852,7 @@
 
 <p><table><tr><td bgcolor=#F0F0F0><pre>
 virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
-<!--X1.5.10--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
 virtual void CloseFilter(int Handle);
-<!--X1.5.10--></td></tr></table>
 </pre></td></tr></table><p>
 
 which must open and close a file handle that delivers section data for the given
diff -ruN vdr-1.5.14/UPDATE-1.2.0 vdr-1.5.15/UPDATE-1.2.0
--- vdr-1.5.14/UPDATE-1.2.0	2003-05-30 15:46:54.000000000 +0200
+++ vdr-1.5.15/UPDATE-1.2.0	2003-05-30 15:46:54.000000000 +0200
@@ -1,7 +1,7 @@
 This is a summary of the changes in VDR 1.2.0 since the last stable
 version 1.0.4. It only contains things that are of actual importance
 to the user and doesn't mention the many fixes and improvements that
-have been made "behind the scenes". 
+have been made "behind the scenes".
 
 See the file HISTORY for a detailed list of all changes.
 
diff -ruN vdr-1.5.14/UPDATE-1.6.0 vdr-1.5.15/UPDATE-1.6.0
--- vdr-1.5.14/UPDATE-1.6.0	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.15/UPDATE-1.6.0	2008-02-17 15:34:34.000000000 +0100
@@ -0,0 +1,142 @@
+This is a summary of the changes in VDR 1.6.0 since the last stable
+version 1.4.7. It only contains things that are of actual importance
+to the user and doesn't mention the many fixes and improvements that
+have been made "behind the scenes".
+
+See the file HISTORY for a detailed list of all changes.
+
+Subtitles:
+
+- Implemented handling DVB subtitles.
+- The new setup option "DVB/Subtitle languages" can be used to define the
+  preferred languages for subtitles.
+- The new setup option "DVB/Subtitle offset" can be used to shift the location
+  of the subtitles in the vertical direction.
+- The new setup options "DVB/Subtitle foreground/background transparency"
+  define an additional level of transparency for the foreground and background
+  color of subtitles.
+
+UTF-8 support:
+
+- VDR now fully supports UTF-8.
+- The actual character encoding on a given system will be determined from the
+  environment. On a system that uses, for instance, ISO8859-1, VDR will encode
+  everything in that code (as far as possible).
+
+Plugins:
+
+- The new remote control key "Subtitles" can be used to bring up the list
+  of available subtitles.
+- Plugins can now implement the new function WakeupTime() to request VDR to wake
+  up at a particular time.
+
+Remote control:
+
+- The "Play" key now starts replay of the selected recording in the Recordings
+  menu
+- The kInfo key is now propagated to any open menu, so that it can react to it
+  in a context sensitive manner. If there is no menu open it will show the info
+  of the current broadcast or replay.
+
+OSD:
+
+- The OSD now uses Freetype fonts.
+- If the OSD device in use has at least 8bpp bitmap depth and this is also
+  used by the current skin, Freetype fonts are displayed "anti-aliased".
+  The new setup parameter "OSD/Anti-alias" can be used to turn this off.
+- Changed the parameter "OSD font" to "Default font" in "Setup/OSD".
+- There can now be more than one OSD at the same time. At any given time,
+  however, only one of them can be active (and thus visible). This is to
+  allow displaying things like subtitles in an easy way. A cOsd therefore
+  now has a "Level", and only the OSD with the smallest level will be
+  displayed. The level 0 OSD is special, and there can only be one with
+  this level. If there is more than one OSD with a particular level, only
+  the one that was created first will be displayed.
+  Plugins that provide an OSD need to adjust their cOsdProvider::CreateOsd()
+  function to hand through the Level.
+- Skins can now have scrollbars in all list menus.
+
+Channels:
+
+- The new Setup parameter "Channel entry timeout" can be used to customize the time
+  since the last keypress until a numerically entered channel number is considered
+  complete, and the channel is switched (suggested by Helmut Auer). Setting this
+  parameter to 0 turns off the automatic channel switching, and the user will
+  have to confirm the entry by pressing the "Ok" key.
+
+Recordings:
+
+- The info.vdr file now also stores the name of the channel.
+- When deleting the recording that is currently replayed, the replay is now
+  stopped immediately.
+- When determining the amount of free disk space, any deleted (but not yet removed)
+  recordings on different file systems (that are mounted under the video directory)
+  are no longer taken into account.
+- When running out of disk space during a recording, only such deleted or old
+  recordings are removed, that actually are on the video directory file system(s).
+  This prevents VDR from accidentally deleting recordings on other file systems,
+  which would not add any free space to the video directory.
+
+SVDRP:
+
+- The new SVDRP command REMO can be used to turn VDR's remote control off and
+  on in case other programs need to be controlled.
+- Improved performance of the SVDRP commands LSTC and CHAN when used with a
+  channel name.
+- The SVDRP command LSTC can now list the channels with group separators if the
+  option ':groups' is given.
+- Enhanced the SVDRP command CLRE to allow clearing the EPG data of a particular
+  channel.
+
+Conditional Access:
+
+- It is now automatically detected which CAM can actually decrypt a channel.
+- CAMs can now be dynamically assigned to the various devices, provided the
+  hardware in use implements such a possibility.
+- Improved handling of the CAM menu.
+- Several encrypted channels on the same transponder can now be decrypted
+  simultaneously with one CAM, if the CAM supports this.
+- Ca values in the range 0...F in channels.conf can still be used to assign a channel
+  to a particular device, but this will no longer work with encrypted channels because
+  without valid CA ids VDR can't decide which CAM slot to use. However, since VDR now
+  automatically determines which CAM can decrypt which channel, setting fixed
+  channel/device relations should no longer be necessary.
+  IF AN ENCRYPTED CHANNEL CAN'T BE DECRYPTED AND YOU HAVE A CA VALUE IN THE RANGE
+  0...F FOR THAT CHANNEL, SET IT TO 0 (FTA) AND TUNE TO THE CHANNEL AGAIN.
+- Removed switching to the next higher or lower channel if the current channel
+  is not available, in order to allow staying on an encrypted channel that takes
+  a while for the CAM to start decrypting.
+
+Internationalization:
+
+- Internationalization is now done with 'gettext'.
+  See README.i18n for information on how to create new or maintain existing
+  translations.
+- The parameter OSDLanguage in 'setup.conf' is now a string and holds the locale
+  code of the selected OSD language (e.g. en_US). If Setup.OSDLanguage is not
+  set to a particular locale that is found in VDR's locale directory, the
+  locale as defined in the system environment is used by default.
+- The new option --localedir can be used to set the locale directory at runtime.
+- Added Turkish language texts.
+- Added Ukrainian language texts.
+
+Misc:
+
+- Improved shutdown handling.
+- The HUP signal now forces a restart of VDR.
+- All logging now goes to LOG_ERR, because some systems split error, info and
+  debug messages into separate files, which repeatedly caused extra efforts to
+  find out when incomplete log excerpts were attached to problem reports in
+  the past.
+- The new setup option "Miscellaneous/Emergency exit" can be used to turn off
+  the automatic restart of VDR in case a recording fails for some reason.
+- The new plugin "pictures" implements a simple picture viewer.
+  See PLUGINS/src/pictures/README for details.
+- Added the new command line option --userdump to enable core dumps in case VDR
+  is run as root with option -u.
+- The free disk space is now also displayed in the title of the "Recordings"
+  menu.
+- Changed the message "Upcoming VPS recording!" to "Upcoming recording!" because
+  it applies to non-VPS recordings as well.
+- Limiting the length of the recording name in timers in case VDR is run with
+  --vfat, in order to avoid names that are too long for Windows.
diff -ruN vdr-1.5.14/channels.c vdr-1.5.15/channels.c
--- vdr-1.5.14/channels.c	2008-01-27 14:59:53.000000000 +0100
+++ vdr-1.5.15/channels.c	2008-02-10 16:45:38.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: channels.c 1.56 2008/01/27 13:59:53 kls Exp $
+ * $Id: channels.c 1.59 2008/02/10 15:45:38 kls Exp $
  */
 
 #include "channels.h"
@@ -18,117 +18,70 @@
 // format characters in order to allow any number of blanks after a numeric
 // value!
 
-// -- Channel Parameter Maps -------------------------------------------------
+// --- Channel Parameter Maps ------------------------------------------------
 
 const tChannelParameterMap InversionValues[] = {
-  {   0, DVBFE_INVERSION_OFF, trNOOP("off") },
-  {   1, DVBFE_INVERSION_ON,  trNOOP("on") },
-  { 999, DVBFE_INVERSION_AUTO },
+  {   0, INVERSION_OFF },
+  {   1, INVERSION_ON },
+  { 999, INVERSION_AUTO },
   { -1 }
   };
 
 const tChannelParameterMap BandwidthValues[] = {
-  {   5, DVBFE_BANDWIDTH_5_MHZ, "5 MHz" },
-  {   6, DVBFE_BANDWIDTH_6_MHZ, "6 MHz" },
-  {   7, DVBFE_BANDWIDTH_7_MHZ, "7 MHz" },
-  {   8, DVBFE_BANDWIDTH_8_MHZ, "8 MHz" },
-  { 999, DVBFE_BANDWIDTH_AUTO },
+  {   6, BANDWIDTH_6_MHZ },
+  {   7, BANDWIDTH_7_MHZ },
+  {   8, BANDWIDTH_8_MHZ },
+  { 999, BANDWIDTH_AUTO },
   { -1 }
   };
 
 const tChannelParameterMap CoderateValues[] = {
-  {   0, DVBFE_FEC_NONE, trNOOP("none") },
-  {  12, DVBFE_FEC_1_2,  "1/2" },
-  {  13, DVBFE_FEC_1_3,  "1/3" },
-  {  14, DVBFE_FEC_1_4,  "1/4" },
-  {  23, DVBFE_FEC_2_3,  "2/3" },
-  {  25, DVBFE_FEC_2_5,  "2/5" },
-  {  34, DVBFE_FEC_3_4,  "3/4" },
-  {  35, DVBFE_FEC_3_5,  "3/5" },
-  {  45, DVBFE_FEC_4_5,  "4/5" },
-  {  56, DVBFE_FEC_5_6,  "5/6" },
-  {  67, DVBFE_FEC_6_7,  "6/7" },
-  {  78, DVBFE_FEC_7_8,  "7/8" },
-  {  89, DVBFE_FEC_8_9,  "8/9" },
-  { 910, DVBFE_FEC_9_10, "9/10" },
-  { 999, DVBFE_FEC_AUTO },
+  {   0, FEC_NONE },
+  {  12, FEC_1_2 },
+  {  23, FEC_2_3 },
+  {  34, FEC_3_4 },
+  {  45, FEC_4_5 },
+  {  56, FEC_5_6 },
+  {  67, FEC_6_7 },
+  {  78, FEC_7_8 },
+  {  89, FEC_8_9 },
+  { 999, FEC_AUTO },
   { -1 }
   };
 
 const tChannelParameterMap ModulationValues[] = {
-  {   0, DVBFE_MOD_NONE,    trNOOP("none") },
-  {   4, DVBFE_MOD_QAM4,    "QAM4" },
-  {  16, DVBFE_MOD_QAM16,   "QAM16" },
-  {  32, DVBFE_MOD_QAM32,   "QAM32" },
-  {  64, DVBFE_MOD_QAM64,   "QAM64" },
-  { 128, DVBFE_MOD_QAM128,  "QAM128" },
-  { 256, DVBFE_MOD_QAM256,  "QAM256" },
-  { 512, DVBFE_MOD_QAM512,  "QAM512" },
-  {1024, DVBFE_MOD_QAM1024, "QAM1024" },
-  {   1, DVBFE_MOD_BPSK,    "BPSK" },
-  {   2, DVBFE_MOD_QPSK,    "QPSK" },
-  {   3, DVBFE_MOD_OQPSK,   "OQPSK" },
-  {   5, DVBFE_MOD_8PSK,    "8PSK" },
-  {   6, DVBFE_MOD_16APSK,  "16APSK" },
-  {   7, DVBFE_MOD_32APSK,  "32APSK" },
-  {   8, DVBFE_MOD_OFDM,    "OFDM" },
-  {   9, DVBFE_MOD_COFDM,   "COFDM" },
-  {  10, DVBFE_MOD_VSB8,    "VSB8" },
-  {  11, DVBFE_MOD_VSB16,   "VSB16" },
-  { 998, DVBFE_MOD_QAMAUTO, "QAMAUTO" },
-  { 999, DVBFE_MOD_AUTO },
-  { -1 }
-  };
-
-const tChannelParameterMap SystemValues[] = {
-  {   0, DVBFE_DELSYS_DVBS,  "DVB-S" },
-  {   1, DVBFE_DELSYS_DVBS2, "DVB-S2" },
+  {   0, QPSK },
+  {  16, QAM_16 },
+  {  32, QAM_32 },
+  {  64, QAM_64 },
+  { 128, QAM_128 },
+  { 256, QAM_256 },
+  { 999, QAM_AUTO },
   { -1 }
   };
 
 const tChannelParameterMap TransmissionValues[] = {
-  {   2, DVBFE_TRANSMISSION_MODE_2K, "2K" },
-  {   4, DVBFE_TRANSMISSION_MODE_4K, "4K" },
-  {   8, DVBFE_TRANSMISSION_MODE_8K, "8K" },
-  { 999, DVBFE_TRANSMISSION_MODE_AUTO },
+  {   2, TRANSMISSION_MODE_2K },
+  {   8, TRANSMISSION_MODE_8K },
+  { 999, TRANSMISSION_MODE_AUTO },
   { -1 }
   };
 
 const tChannelParameterMap GuardValues[] = {
-  {   4, DVBFE_GUARD_INTERVAL_1_4,  "1/4" },
-  {   8, DVBFE_GUARD_INTERVAL_1_8,  "1/8" },
-  {  16, DVBFE_GUARD_INTERVAL_1_16, "1/16" },
-  {  32, DVBFE_GUARD_INTERVAL_1_32, "1/32" },
-  { 999, DVBFE_GUARD_INTERVAL_AUTO },
+  {   4, GUARD_INTERVAL_1_4 },
+  {   8, GUARD_INTERVAL_1_8 },
+  {  16, GUARD_INTERVAL_1_16 },
+  {  32, GUARD_INTERVAL_1_32 },
+  { 999, GUARD_INTERVAL_AUTO },
   { -1 }
   };
 
 const tChannelParameterMap HierarchyValues[] = {
-  {   0, DVBFE_HIERARCHY_OFF, trNOOP("off") },
-  {   1, DVBFE_HIERARCHY_ON,  trNOOP("on") },
-  { 999, DVBFE_HIERARCHY_AUTO },
-  { -1 }
-  };
-
-const tChannelParameterMap AlphaValues[] = {
-  {   0, 0 },
-  {   1, DVBFE_ALPHA_1 },
-  {   2, DVBFE_ALPHA_2 },
-  {   4, DVBFE_ALPHA_4 },
-  { -1 }
-  };
-
-const tChannelParameterMap PriorityValues[] = {
-  {   0, DVBFE_STREAM_PRIORITY_HP, trNOOP("high") },
-  {   1, DVBFE_STREAM_PRIORITY_LP, trNOOP("low") },
-  { -1 }
-  };
-
-const tChannelParameterMap RollOffValues[] = {
-  {   0, DVBFE_ROLLOFF_UNKNOWN },
-  {  20, DVBFE_ROLLOFF_20, "0.20" },
-  {  25, DVBFE_ROLLOFF_25, "0.25" },
-  {  35, DVBFE_ROLLOFF_35, "0.35" },
+  {   0, HIERARCHY_NONE },
+  {   1, HIERARCHY_1 },
+  {   2, HIERARCHY_2 },
+  {   4, HIERARCHY_4 },
+  { 999, HIERARCHY_AUTO },
   { -1 }
   };
 
@@ -154,14 +107,11 @@
   return -1;
 }
 
-int MapToUser(int Value, const tChannelParameterMap *Map, const char **String)
+int MapToUser(int Value, const tChannelParameterMap *Map)
 {
   int n = DriverIndex(Value, Map);
-  if (n >= 0) {
-     if (String)
-        *String = tr(Map[n].userString);
+  if (n >= 0)
      return Map[n].userValue;
-     }
   return -1;
 }
 
@@ -173,7 +123,7 @@
   return -1;
 }
 
-// -- tChannelID -------------------------------------------------------------
+// --- tChannelID ------------------------------------------------------------
 
 const tChannelID tChannelID::InvalidID;
 
@@ -208,7 +158,7 @@
   return *this;
 }
 
-// -- cChannel ---------------------------------------------------------------
+// --- cChannel --------------------------------------------------------------
 
 cChannel::cChannel(void)
 {
@@ -217,18 +167,14 @@
   provider = strdup("");
   portalName = strdup("");
   memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__);
-  inversion    = DVBFE_INVERSION_AUTO;
-  bandwidth    = DVBFE_BANDWIDTH_AUTO;
-  coderateH    = DVBFE_FEC_AUTO;
-  coderateL    = DVBFE_FEC_AUTO;
-  modulation   = DVBFE_MOD_AUTO;
-  system       = DVBFE_DELSYS_DVBS;
-  transmission = DVBFE_TRANSMISSION_MODE_AUTO;
-  guard        = DVBFE_GUARD_INTERVAL_AUTO;
-  hierarchy    = DVBFE_HIERARCHY_AUTO;
-  alpha        = 0;
-  priority     = DVBFE_STREAM_PRIORITY_HP;
-  rollOff      = DVBFE_ROLLOFF_UNKNOWN;
+  inversion    = INVERSION_AUTO;
+  bandwidth    = BANDWIDTH_AUTO;
+  coderateH    = FEC_AUTO;
+  coderateL    = FEC_AUTO;
+  modulation   = QAM_AUTO;
+  transmission = TRANSMISSION_MODE_AUTO;
+  guard        = GUARD_INTERVAL_AUTO;
+  hierarchy    = HIERARCHY_AUTO;
   modification = CHANNELMOD_NONE;
   schedule     = NULL;
   linkChannels = NULL;
@@ -331,17 +277,13 @@
      coderateH    = Channel->coderateH;
      coderateL    = Channel->coderateL;
      modulation   = Channel->modulation;
-     system       = Channel->system;
      transmission = Channel->transmission;
      guard        = Channel->guard;
      hierarchy    = Channel->hierarchy;
-     alpha        = Channel->alpha;
-     priority     = Channel->priority;
-     rollOff      = Channel->rollOff;
      }
 }
 
-bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation, int System, int RollOff)
+bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH)
 {
   // Workarounds for broadcaster stupidity:
   // Some providers broadcast the transponder frequency of their channels with two different
@@ -355,22 +297,19 @@
   if (abs(srate - Srate) <= 1)
      Srate = srate;
 
-  if (source != Source || frequency != Frequency || polarization != Polarization || srate != Srate || coderateH != CoderateH || modulation != Modulation || system != System || rollOff != RollOff) {
-     cString OldParameters = ParametersToString();
+  if (source != Source || frequency != Frequency || polarization != Polarization || srate != Srate || coderateH != CoderateH) {
+     if (Number()) {
+        dsyslog("changing transponder data of channel %d from %s:%d:%c:%d:%d to %s:%d:%c:%d:%d", Number(), *cSource::ToString(source), frequency, polarization, srate, coderateH, *cSource::ToString(Source), Frequency, Polarization, Srate, CoderateH);
+        modification |= CHANNELMOD_TRANSP;
+        Channels.SetModified();
+        }
      source = Source;
      frequency = Frequency;
      polarization = Polarization;
      srate = Srate;
      coderateH = CoderateH;
-     modulation = Modulation;
-     system = System;
-     rollOff = RollOff;
+     modulation = QPSK;
      schedule = NULL;
-     if (Number()) {
-        dsyslog("changing transponder data of channel %d from %d:%s:%s:%d to %d:%s:%s:%d", Number(), frequency, *OldParameters, *cSource::ToString(source), srate, Frequency, *ParametersToString(), *cSource::ToString(Source), Srate);
-        modification |= CHANNELMOD_TRANSP;
-        Channels.SetModified();
-        }
      }
   return true;
 }
@@ -378,26 +317,29 @@
 bool cChannel::SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH)
 {
   if (source != Source || frequency != Frequency || modulation != Modulation || srate != Srate || coderateH != CoderateH) {
-     cString OldParameters = ParametersToString();
+     if (Number()) {
+        dsyslog("changing transponder data of channel %d from %s:%d:%d:%d:%d to %s:%d:%d:%d:%d", Number(), *cSource::ToString(source), frequency, modulation, srate, coderateH, *cSource::ToString(Source), Frequency, Modulation, Srate, CoderateH);
+        modification |= CHANNELMOD_TRANSP;
+        Channels.SetModified();
+        }
      source = Source;
      frequency = Frequency;
      modulation = Modulation;
      srate = Srate;
      coderateH = CoderateH;
      schedule = NULL;
-     if (Number()) {
-        dsyslog("changing transponder data of channel %d from %d:%s:%s:%d to %d:%s:%s:%d", Number(), frequency, *OldParameters, *cSource::ToString(source), srate, Frequency, *ParametersToString(), *cSource::ToString(Source), Srate);
-        modification |= CHANNELMOD_TRANSP;
-        Channels.SetModified();
-        }
      }
   return true;
 }
 
-bool cChannel::SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CoderateH, int CoderateL, int Guard, int Transmission, int Alpha, int Priority)
+bool cChannel::SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CoderateH, int CoderateL, int Guard, int Transmission)
 {
-  if (source != Source || frequency != Frequency || bandwidth != Bandwidth || modulation != Modulation || hierarchy != Hierarchy || coderateH != CoderateH || coderateL != CoderateL || guard != Guard || transmission != Transmission || alpha != Alpha || priority != Priority) {
-     cString OldParameters = ParametersToString();
+  if (source != Source || frequency != Frequency || bandwidth != Bandwidth || modulation != Modulation || hierarchy != Hierarchy || coderateH != CoderateH || coderateL != CoderateL || guard != Guard || transmission != Transmission) {
+     if (Number()) {
+        dsyslog("changing transponder data of channel %d from %s:%d:%d:%d:%d:%d:%d:%d:%d to %s:%d:%d:%d:%d:%d:%d:%d:%d", Number(), *cSource::ToString(source), frequency, bandwidth, modulation, hierarchy, coderateH, coderateL, guard, transmission, *cSource::ToString(Source), Frequency, Bandwidth, Modulation, Hierarchy, CoderateH, CoderateL, Guard, Transmission);
+        modification |= CHANNELMOD_TRANSP;
+        Channels.SetModified();
+        }
      source = Source;
      frequency = Frequency;
      bandwidth = Bandwidth;
@@ -407,14 +349,7 @@
      coderateL = CoderateL;
      guard = Guard;
      transmission = Transmission;
-     alpha = Alpha;
-     priority = Priority;
      schedule = NULL;
-     if (Number()) {
-        dsyslog("changing transponder data of channel %d from %d:%s:%s to %d:%s:%s", Number(), frequency, *OldParameters, *cSource::ToString(source), Frequency, *ParametersToString(), *cSource::ToString(Source));
-        modification |= CHANNELMOD_TRANSP;
-        Channels.SetModified();
-        }
      }
   return true;
 }
@@ -662,17 +597,13 @@
   char *q = buffer;
   *q = 0;
   ST(" S ")  q += sprintf(q, "%c", polarization);
-  ST("  T")  q += PrintParameter(q, 'A', MapToUser(alpha, AlphaValues));
-  ST("  T")  q += PrintParameter(q, 'B', MapToUser(bandwidth, BandwidthValues));
+  ST("CST")  q += PrintParameter(q, 'I', MapToUser(inversion, InversionValues));
   ST("CST")  q += PrintParameter(q, 'C', MapToUser(coderateH, CoderateValues));
   ST("  T")  q += PrintParameter(q, 'D', MapToUser(coderateL, CoderateValues));
-  ST("  T")  q += PrintParameter(q, 'G', MapToUser(guard, GuardValues));
-  ST("CST")  q += PrintParameter(q, 'I', MapToUser(inversion, InversionValues));
-  ST("CST")  q += PrintParameter(q, 'M', MapToUser(modulation, ModulationValues));
-  ST(" S ")  q += PrintParameter(q, 'O', MapToUser(rollOff, RollOffValues));
-  ST("  T")  q += PrintParameter(q, 'P', MapToUser(priority, PriorityValues));
-  ST(" S ")  q += PrintParameter(q, 'S', MapToUser(system, SystemValues));
+  ST("C T")  q += PrintParameter(q, 'M', MapToUser(modulation, ModulationValues));
+  ST("  T")  q += PrintParameter(q, 'B', MapToUser(bandwidth, BandwidthValues));
   ST("  T")  q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues));
+  ST("  T")  q += PrintParameter(q, 'G', MapToUser(guard, GuardValues));
   ST("  T")  q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues));
   return buffer;
 }
@@ -697,7 +628,6 @@
 {
   while (s && *s) {
         switch (toupper(*s)) {
-          case 'A': s = ParseParameter(s, alpha, AlphaValues); break;
           case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break;
           case 'C': s = ParseParameter(s, coderateH, CoderateValues); break;
           case 'D': s = ParseParameter(s, coderateL, CoderateValues); break;
@@ -706,11 +636,7 @@
           case 'I': s = ParseParameter(s, inversion, InversionValues); break;
           case 'L': polarization = *s++; break;
           case 'M': s = ParseParameter(s, modulation, ModulationValues); break;
-          case 'Z':// for compatibility with the original DVB-S2 patch - may be removed in future versions
-          case 'O': s = ParseParameter(s, rollOff, RollOffValues); break;
-          case 'P': s = ParseParameter(s, priority, PriorityValues); break;
           case 'R': polarization = *s++; break;
-          case 'S': s = ParseParameter(s, system, SystemValues); break;
           case 'T': s = ParseParameter(s, transmission, TransmissionValues); break;
           case 'V': polarization = *s++; break;
           case 'Y': s = ParseParameter(s, hierarchy, HierarchyValues); break;
@@ -732,12 +658,12 @@
      q += sprintf(q, ";%s", Channel->provider);
   *q = 0;
   strreplace(FullName, ':', '|');
-  char *buffer;
+  cString buffer;
   if (Channel->groupSep) {
      if (Channel->number)
-        asprintf(&buffer, ":@%d %s\n", Channel->number, FullName);
+        buffer = cString::sprintf(":@%d %s\n", Channel->number, FullName);
      else
-        asprintf(&buffer, ":%s\n", FullName);
+        buffer = cString::sprintf(":%s\n", FullName);
      }
   else {
      char vpidbuf[32];
@@ -759,9 +685,9 @@
      q = caidbuf;
      q += IntArrayToString(q, Channel->caids, 16);
      *q = 0;
-     asprintf(&buffer, "%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->ParametersToString(), *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
+     buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->ParametersToString(), *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
      }
-  return cString(buffer, true);
+  return buffer;
 }
 
 cString cChannel::ToText(void) const
@@ -924,7 +850,7 @@
   return fprintf(f, "%s", *ToText()) > 0;
 }
 
-// -- cChannelSorter ---------------------------------------------------------
+// --- cChannelSorter --------------------------------------------------------
 
 class cChannelSorter : public cListObject {
 public:
@@ -940,7 +866,7 @@
     }
   };
 
-// -- cChannels --------------------------------------------------------------
+// --- cChannels -------------------------------------------------------------
 
 cChannels Channels;
 
diff -ruN vdr-1.5.14/channels.h vdr-1.5.15/channels.h
--- vdr-1.5.14/channels.h	2008-01-26 17:04:26.000000000 +0100
+++ vdr-1.5.15/channels.h	2008-02-08 14:48:31.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: channels.h 1.46 2008/01/26 16:04:26 kls Exp $
+ * $Id: channels.h 1.47 2008/02/08 13:48:31 kls Exp $
  */
 
 #ifndef __CHANNELS_H
@@ -50,10 +50,10 @@
 struct tChannelParameterMap {
   int userValue;
   int driverValue;
-  const char *userString;
   };
 
-int MapToUser(int Value, const tChannelParameterMap *Map, const char **String = NULL);
+//XXX into cChannel???
+int MapToUser(int Value, const tChannelParameterMap *Map);
 int MapToDriver(int Value, const tChannelParameterMap *Map);
 int UserIndex(int Value, const tChannelParameterMap *Map);
 int DriverIndex(int Value, const tChannelParameterMap *Map);
@@ -62,13 +62,9 @@
 extern const tChannelParameterMap BandwidthValues[];
 extern const tChannelParameterMap CoderateValues[];
 extern const tChannelParameterMap ModulationValues[];
-extern const tChannelParameterMap SystemValues[];
 extern const tChannelParameterMap TransmissionValues[];
 extern const tChannelParameterMap GuardValues[];
 extern const tChannelParameterMap HierarchyValues[];
-extern const tChannelParameterMap AlphaValues[];
-extern const tChannelParameterMap PriorityValues[];
-extern const tChannelParameterMap RollOffValues[];
 
 struct tChannelID {
 private:
@@ -144,13 +140,9 @@
   int coderateH;
   int coderateL;
   int modulation;
-  int system;
   int transmission;
   int guard;
   int hierarchy;
-  int alpha;
-  int priority;
-  int rollOff;
   int __EndData__;
   int modification;
   mutable const cSchedule *schedule;
@@ -202,13 +194,9 @@
   int CoderateH(void) const { return coderateH; }
   int CoderateL(void) const { return coderateL; }
   int Modulation(void) const { return modulation; }
-  int System(void) const { return system; }
   int Transmission(void) const { return transmission; }
   int Guard(void) const { return guard; }
   int Hierarchy(void) const { return hierarchy; }
-  int Alpha(void) const { return alpha; }
-  int Priority(void) const { return priority; }
-  int RollOff(void) const { return rollOff; }
   const cLinkChannels* LinkChannels(void) const { return linkChannels; }
   const cChannel *RefChannel(void) const { return refChannel; }
   bool IsCable(void) const { return cSource::IsCable(source); }
@@ -218,9 +206,9 @@
   bool HasTimer(void) const;
   int Modification(int Mask = CHANNELMOD_ALL);
   void CopyTransponderData(const cChannel *Channel);
-  bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation, int System, int RollOff);
+  bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH);
   bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH);
-  bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission, int Alpha, int Priority);
+  bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission);
   void SetId(int Nid, int Tid, int Sid, int Rid = 0);
   void SetName(const char *Name, const char *ShortName, const char *Provider);
   void SetPortalName(const char *PortalName);
diff -ruN vdr-1.5.14/config.c vdr-1.5.15/config.c
--- vdr-1.5.14/config.c	2007-11-25 14:46:27.000000000 +0100
+++ vdr-1.5.15/config.c	2008-02-17 14:39:00.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.c 1.158 2007/11/25 13:46:27 kls Exp $
+ * $Id: config.c 1.161 2008/02/17 13:39:00 kls Exp $
  */
 
 #include "config.h"
@@ -62,10 +62,10 @@
 {
   free(result);
   result = NULL;
-  char *cmdbuf = NULL;
+  cString cmdbuf;
   if (Parameters)
-     asprintf(&cmdbuf, "%s %s", command, Parameters);
-  const char *cmd = cmdbuf ? cmdbuf : command;
+     cmdbuf = cString::sprintf("%s %s", command, Parameters);
+  const char *cmd = *cmdbuf ? *cmdbuf : command;
   dsyslog("executing command '%s'", cmd);
   cPipe p;
   if (p.Open(cmd, "r")) {
@@ -82,11 +82,10 @@
      }
   else
      esyslog("ERROR: can't open pipe for command '%s'", cmd);
-  free(cmdbuf);
   return result;
 }
 
-// -- cSVDRPhost -------------------------------------------------------------
+// --- cSVDRPhost ------------------------------------------------------------
 
 cSVDRPhost::cSVDRPhost(void)
 {
@@ -122,12 +121,12 @@
   return (Address & mask) == (addr.s_addr & mask);
 }
 
-// -- cCommands --------------------------------------------------------------
+// --- cCommands -------------------------------------------------------------
 
 cCommands Commands;
 cCommands RecordingCommands;
 
-// -- cSVDRPhosts ------------------------------------------------------------
+// --- cSVDRPhosts -----------------------------------------------------------
 
 cSVDRPhosts SVDRPhosts;
 
@@ -142,7 +141,7 @@
   return false;
 }
 
-// -- cSetupLine -------------------------------------------------------------
+// --- cSetupLine ------------------------------------------------------------
 
 cSetupLine::cSetupLine(void)
 {
@@ -208,7 +207,7 @@
   return fprintf(f, "%s%s%s = %s\n", plugin ? plugin : "", plugin ? "." : "", name, value) > 0;
 }
 
-// -- cSetup -----------------------------------------------------------------
+// --- cSetup ----------------------------------------------------------------
 
 cSetup Setup;
 
@@ -322,10 +321,7 @@
 
 void cSetup::Store(const char *Name, int Value, const char *Plugin)
 {
-  char *buffer = NULL;
-  asprintf(&buffer, "%d", Value);
-  Store(Name, buffer, Plugin);
-  free(buffer);
+  Store(Name, cString::sprintf("%d", Value), Plugin);
 }
 
 bool cSetup::Load(const char *FileName)
diff -ruN vdr-1.5.14/config.h vdr-1.5.15/config.h
--- vdr-1.5.14/config.h	2008-01-19 13:08:29.000000000 +0100
+++ vdr-1.5.15/config.h	2008-02-05 16:35:11.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.h 1.304 2008/01/19 12:08:29 kls Exp $
+ * $Id: config.h 1.305 2008/02/05 15:35:11 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -22,13 +22,13 @@
 
 // VDR's own version number:
 
-#define VDRVERSION  "1.5.14"
-#define VDRVERSNUM   10514  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "1.5.15"
+#define VDRVERSNUM   10515  // Version * 10000 + Major * 100 + Minor
 
 // The plugin API's version number:
 
-#define APIVERSION  "1.5.14"
-#define APIVERSNUM   10514  // Version * 10000 + Major * 100 + Minor
+#define APIVERSION  "1.5.15"
+#define APIVERSNUM   10515  // Version * 10000 + Major * 100 + Minor
 
 // When loading plugins, VDR searches them by their APIVERSION, which
 // may be smaller than VDRVERSION in case there have been no changes to
diff -ruN vdr-1.5.14/device.c vdr-1.5.15/device.c
--- vdr-1.5.14/device.c	2008-01-27 11:40:46.000000000 +0100
+++ vdr-1.5.15/device.c	2008-02-16 14:52:11.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.c 1.149 2008/01/27 10:40:46 kls Exp $
+ * $Id: device.c 1.153 2008/02/16 13:52:11 kls Exp $
  */
 
 #include "device.h"
@@ -264,11 +264,6 @@
   DetachAllReceivers();
   delete liveSubtitle;
   delete dvbSubtitleConverter;
-  delete nitFilter;
-  delete sdtFilter;
-  delete patFilter;
-  delete eitFilter;
-  delete sectionHandler;
   delete pesAssembler;
 }
 
@@ -359,21 +354,6 @@
   return (0 <= Index && Index < numDevices) ? device[Index] : NULL;
 }
 
-static int GetClippedNumProvidedSystems(int AvailableBits, cDevice *Device)
-{
-  int MaxNumProvidedSystems = 1 << AvailableBits;
-  int NumProvidedSystems = Device->NumProvidedSystems();
-  if (NumProvidedSystems > MaxNumProvidedSystems) {
-     esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->CardIndex() + 1, NumProvidedSystems, MaxNumProvidedSystems);
-     NumProvidedSystems = MaxNumProvidedSystems;
-     }
-  else if (NumProvidedSystems <= 0) {
-     esyslog("ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->CardIndex() + 1, NumProvidedSystems);
-     NumProvidedSystems = 1;
-     }
-  return NumProvidedSystems;
-}
-
 cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView)
 {
   // Collect the current priorities of all CAM slots that can decrypt the channel:
@@ -423,7 +403,6 @@
              imp <<= 1; imp |= LiveView ? !device[i]->IsPrimaryDevice() || ndr : 0;                                  // prefer the primary device for live viewing if we don't need to detach existing receivers
              imp <<= 1; imp |= !device[i]->Receiving() && (device[i] != cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode
              imp <<= 1; imp |= device[i]->Receiving();                                                               // avoid devices that are receiving
-             imp <<= 2; imp |= GetClippedNumProvidedSystems(2, device[i]) - 1;                                       // avoid cards which support multiple delivery systems
              imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice();                                      // avoid the Transfer Mode receiver device
              imp <<= 8; imp |= min(max(device[i]->Priority() + MAXPRIORITY, 0), 0xFF);                               // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used)
              imp <<= 8; imp |= min(max((NumUsableSlots ? SlotPriority[j] : 0) + MAXPRIORITY, 0), 0xFF);              // use the CAM slot with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used)
@@ -666,6 +645,22 @@
      }
 }
 
+void cDevice::StopSectionHandler(void)
+{
+  if (sectionHandler) {
+     delete nitFilter;
+     delete sdtFilter;
+     delete patFilter;
+     delete eitFilter;
+     delete sectionHandler;
+     nitFilter = NULL;
+     sdtFilter = NULL;
+     patFilter = NULL;
+     eitFilter = NULL;
+     sectionHandler = NULL;
+     }
+}
+
 int cDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
 {
   return -1;
@@ -712,11 +707,6 @@
   return false;
 }
 
-int cDevice::NumProvidedSystems(void) const
-{
-  return 0;
-}
-
 bool cDevice::IsTunedToTransponder(const cChannel *Channel)
 {
   return false;
@@ -900,6 +890,10 @@
 {
 }
 
+void cDevice::SetSubtitleTrackDevice(eTrackType Type)
+{
+}
+
 bool cDevice::ToggleMute(void)
 {
   int OldVolume = volume;
@@ -1047,6 +1041,10 @@
         DELETENULL(dvbSubtitleConverter);
         }
      DELETENULL(liveSubtitle);
+     if (player)
+        player->SetSubtitleTrack(currentSubtitleTrack, GetTrack(currentSubtitleTrack));
+     else
+        SetSubtitleTrackDevice(currentSubtitleTrack);
      if (currentSubtitleTrack != ttNone && !Replaying() && !Transferring()) {
         const tTrackId *TrackId = GetTrack(currentSubtitleTrack);
         if (TrackId && TrackId->id) {
@@ -1252,7 +1250,7 @@
                break;
           case 0xC0 ... 0xDF: // audio
                SetAvailableTrack(ttAudio, c - 0xC0, c);
-               if (!VideoOnly && c == availableTracks[currentAudioTrack].id) {
+               if ((!VideoOnly || HasIBPTrickSpeed()) && c == availableTracks[currentAudioTrack].id) {
                   w = PlayAudio(Start, d, c);
                   if (FirstLoop)
                      Audios.PlayAudio(Data, Length, c);
@@ -1282,13 +1280,13 @@
                  case 0x20: // SPU
                  case 0x30: // SPU
                       SetAvailableTrack(ttSubtitle, SubStreamIndex, SubStreamId);
-                      if (!VideoOnly && currentSubtitleTrack != ttNone && SubStreamId == availableTracks[currentSubtitleTrack].id)
+                      if ((!VideoOnly || HasIBPTrickSpeed()) && currentSubtitleTrack != ttNone && SubStreamId == availableTracks[currentSubtitleTrack].id)
                          w = PlaySubtitle(Start, d);
                       break;
                  case 0x80: // AC3 & DTS
                       if (Setup.UseDolbyDigital) {
                          SetAvailableTrack(ttDolby, SubStreamIndex, SubStreamId);
-                         if (!VideoOnly && SubStreamId == availableTracks[currentAudioTrack].id) {
+                         if ((!VideoOnly || HasIBPTrickSpeed()) && SubStreamId == availableTracks[currentAudioTrack].id) {
                             w = PlayAudio(Start, d, SubStreamId);
                             if (FirstLoop)
                                Audios.PlayAudio(Data, Length, SubStreamId);
@@ -1297,7 +1295,7 @@
                       break;
                  case 0xA0: // LPCM
                       SetAvailableTrack(ttAudio, SubStreamIndex, SubStreamId);
-                      if (!VideoOnly && SubStreamId == availableTracks[currentAudioTrack].id) {
+                      if ((!VideoOnly || HasIBPTrickSpeed()) && SubStreamId == availableTracks[currentAudioTrack].id) {
                          w = PlayAudio(Start, d, SubStreamId);
                          if (FirstLoop)
                             Audios.PlayAudio(Data, Length, SubStreamId);
diff -ruN vdr-1.5.14/device.h vdr-1.5.15/device.h
--- vdr-1.5.14/device.h	2008-01-27 11:35:18.000000000 +0100
+++ vdr-1.5.15/device.h	2008-02-16 14:50:11.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.h 1.87 2008/01/27 10:35:18 kls Exp $
+ * $Id: device.h 1.90 2008/02/16 13:50:11 kls Exp $
  */
 
 #ifndef __DEVICE_H
@@ -224,12 +224,6 @@
          ///< function itself actually returns true.
          ///< The default implementation always returns false, so a derived cDevice
          ///< class that can provide channels must implement this function.
-  virtual int NumProvidedSystems(void) const;
-         ///< Returns the number of individual "delivery systems" this device provides.
-         ///< The default implementation returns 0, so any derived class that can
-         ///< actually provide channels must implement this function.
-         ///< The result of this function is used when selecting a device, in order
-         ///< to avoid devices that provide more than one system.
   virtual bool IsTunedToTransponder(const cChannel *Channel);
          ///< Returns true if this device is currently tuned to the given Channel's
          ///< transponder.
@@ -308,7 +302,12 @@
 protected:
   void StartSectionHandler(void);
        ///< A derived device that provides section data must call
-       ///< this function to actually set up the section handler.
+       ///< this function (typically in its constructor) to actually set
+       ///< up the section handler.
+  void StopSectionHandler(void);
+       ///< A device that has called StartSectionHandler() must call this
+       ///< function (typically in its destructor) to stop the section
+       ///< handler.
 public:
   virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
        ///< Opens a file handle for the given filter data.
@@ -387,6 +386,8 @@
 protected:
   virtual void SetAudioTrackDevice(eTrackType Type);
        ///< Sets the current audio track to the given value.
+  virtual void SetSubtitleTrackDevice(eTrackType Type);
+       ///< Sets the current subtitle track to the given value.
 public:
   void ClrAvailableTracks(bool DescriptionsOnly = false, bool IdsOnly = false);
        ///< Clears the list of currently availabe tracks. If DescriptionsOnly
diff -ruN vdr-1.5.14/diseqc.c vdr-1.5.15/diseqc.c
--- vdr-1.5.14/diseqc.c	2005-12-30 16:41:48.000000000 +0100
+++ vdr-1.5.15/diseqc.c	2008-02-10 15:09:27.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: diseqc.c 1.5 2005/12/30 15:41:48 kls Exp $
+ * $Id: diseqc.c 1.6 2008/02/10 14:09:27 kls Exp $
  */
 
 #include "diseqc.h"
@@ -12,7 +12,7 @@
 #include "sources.h"
 #include "thread.h"
 
-// -- cDiseqc ----------------------------------------------------------------
+// --- cDiseqc ---------------------------------------------------------------
 
 cDiseqc::cDiseqc(void)
 {
@@ -122,7 +122,7 @@
   return daNone;
 }
 
-// -- cDiseqcs ---------------------------------------------------------------
+// --- cDiseqcs --------------------------------------------------------------
 
 cDiseqcs Diseqcs;
 
diff -ruN vdr-1.5.14/dvbdevice.c vdr-1.5.15/dvbdevice.c
--- vdr-1.5.14/dvbdevice.c	2008-01-27 15:35:54.000000000 +0100
+++ vdr-1.5.15/dvbdevice.c	2008-02-09 17:11:44.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.c 1.168 2008/01/27 14:35:54 kls Exp $
+ * $Id: dvbdevice.c 1.170 2008/02/09 16:11:44 kls Exp $
  */
 
 #include "dvbdevice.h"
@@ -76,7 +76,7 @@
   int tuneTimeout;
   int lockTimeout;
   time_t lastTimeoutReport;
-  dvbfe_delsys frontendType;
+  fe_type_t frontendType;
   cChannel channel;
   const char *diseqcCommands;
   eTunerStatus tunerStatus;
@@ -87,14 +87,14 @@
   bool SetFrontend(void);
   virtual void Action(void);
 public:
-  cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType);
+  cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType);
   virtual ~cDvbTuner();
   bool IsTunedTo(const cChannel *Channel) const;
   void Set(const cChannel *Channel, bool Tune);
   bool Locked(int TimeoutMs = 0);
   };
 
-cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType)
+cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType)
 {
   fd_frontend = Fd_Frontend;
   cardIndex = CardIndex;
@@ -104,7 +104,7 @@
   lastTimeoutReport = 0;
   diseqcCommands = NULL;
   tunerStatus = tsIdle;
-  if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2))
+  if (frontendType == FE_QPSK)
      CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power
   SetDescription("tuner on device %d", cardIndex + 1);
   Start();
@@ -120,26 +120,7 @@
 
 bool cDvbTuner::IsTunedTo(const cChannel *Channel) const
 {
-  if (tunerStatus == tsIdle)
-     return false; // not tuned to
-  if (channel.Source() != Channel->Source() || channel.Transponder() != Channel->Transponder())
-     return false; // sufficient mismatch
-  char Type = **cSource::ToString(Channel->Source());
-#define ST(s, p) if (strchr(s, Type)) if (channel.p() != Channel->p()) return false;
-  // Polarization is already checked as part of the Transponder.
-  ST("  T", Alpha);
-  ST("  T", Bandwidth);
-  ST("CST", CoderateH);
-  ST("  T", CoderateL);
-  ST("  T", Guard);
-  ST("CST", Inversion);
-  ST("CST", Modulation);
-  ST(" S ", RollOff);
-  ST("  T", Priority);
-  ST(" S ", System);
-  ST("  T", Transmission);
-  ST("  T", Hierarchy);
-  return true;
+  return tunerStatus != tsIdle && channel.Source() == Channel->Source() && channel.Transponder() == Channel->Transponder();
 }
 
 void cDvbTuner::Set(const cChannel *Channel, bool Tune)
@@ -192,126 +173,114 @@
 
 bool cDvbTuner::SetFrontend(void)
 {
-  dvbfe_params Frontend;
+  dvb_frontend_parameters Frontend;
+
   memset(&Frontend, 0, sizeof(Frontend));
 
-  if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) {
-     unsigned int frequency = channel.Frequency();
-     if (Setup.DiSEqC) {
-        cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization());
-        if (diseqc) {
-           if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
-              cDiseqc::eDiseqcActions da;
-              for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
-                  switch (da) {
-                    case cDiseqc::daNone:      break;
-                    case cDiseqc::daToneOff:   CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
-                    case cDiseqc::daToneOn:    CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
-                    case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
-                    case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
-                    case cDiseqc::daMiniA:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
-                    case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
-                    case cDiseqc::daCodes: {
-                         int n = 0;
-                         uchar *codes = diseqc->Codes(n);
-                         if (codes) {
-                            struct dvb_diseqc_master_cmd cmd;
-                            memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
-                            cmd.msg_len = n;
-                            CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
-                            }
-                         }
-                         break;
-                    }
+  switch (frontendType) {
+    case FE_QPSK: { // DVB-S
+
+         unsigned int frequency = channel.Frequency();
+
+         if (Setup.DiSEqC) {
+            cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization());
+            if (diseqc) {
+               if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
+                  cDiseqc::eDiseqcActions da;
+                  for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
+                      switch (da) {
+                        case cDiseqc::daNone:      break;
+                        case cDiseqc::daToneOff:   CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
+                        case cDiseqc::daToneOn:    CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
+                        case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
+                        case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
+                        case cDiseqc::daMiniA:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
+                        case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+                        case cDiseqc::daCodes: {
+                             int n = 0;
+                             uchar *codes = diseqc->Codes(n);
+                             if (codes) {
+                                struct dvb_diseqc_master_cmd cmd;
+                                memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
+                                cmd.msg_len = n;
+                                CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
+                                }
+                             }
+                             break;
+                        }
+                      }
+                  diseqcCommands = diseqc->Commands();
                   }
-              diseqcCommands = diseqc->Commands();
-              }
-           frequency -= diseqc->Lof();
-           }
-        else {
-           esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
-           return false;
-           }
-        }
-     else {
-        int tone = SEC_TONE_OFF;
-        if (frequency < (unsigned int)Setup.LnbSLOF) {
-           frequency -= Setup.LnbFrequLo;
-           tone = SEC_TONE_OFF;
-           }
-        else {
-           frequency -= Setup.LnbFrequHi;
-           tone = SEC_TONE_ON;
-           }
-        int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
-        CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
-        CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
-        }
-     frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF
+               frequency -= diseqc->Lof();
+               }
+            else {
+               esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
+               return false;
+               }
+            }
+         else {
+            int tone = SEC_TONE_OFF;
 
-     Frontend.delivery = dvbfe_delsys(channel.System());
-     Frontend.frequency = frequency * 1000UL;
-     Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
-     if (Frontend.delivery == DVBFE_DELSYS_DVBS) {
-        Frontend.delsys.dvbs.modulation = dvbfe_modulation(channel.Modulation());
-        Frontend.delsys.dvbs.symbol_rate = channel.Srate() * 1000UL;
-        Frontend.delsys.dvbs.fec = dvbfe_fec(channel.CoderateH());
-        }
-     else {
-        Frontend.delsys.dvbs2.modulation = dvbfe_modulation(channel.Modulation());
-        Frontend.delsys.dvbs2.symbol_rate = channel.Srate() * 1000UL;
-        Frontend.delsys.dvbs2.fec = dvbfe_fec(channel.CoderateH());
-        Frontend.delsys.dvbs2.rolloff = dvbfe_rolloff(channel.RollOff());
-        }
+            if (frequency < (unsigned int)Setup.LnbSLOF) {
+               frequency -= Setup.LnbFrequLo;
+               tone = SEC_TONE_OFF;
+               }
+            else {
+               frequency -= Setup.LnbFrequHi;
+               tone = SEC_TONE_ON;
+               }
+            int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
+            CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
+            CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
+            }
 
-     tuneTimeout = DVBS_TUNE_TIMEOUT;
-     lockTimeout = DVBS_LOCK_TIMEOUT;
+         frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF
+         Frontend.frequency = frequency * 1000UL;
+         Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+         Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL;
+         Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH());
 
-     dvbfe_info feinfo;
-     feinfo.delivery = Frontend.delivery;
-     CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
-     }
-  else if (frontendType & DVBFE_DELSYS_DVBC) {
-     Frontend.delivery = DVBFE_DELSYS_DVBC;
-     Frontend.frequency = FrequencyToHz(channel.Frequency());
-     Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
-     Frontend.delsys.dvbc.symbol_rate = channel.Srate() * 1000UL;
-     Frontend.delsys.dvbc.fec = dvbfe_fec(channel.CoderateH());
-     Frontend.delsys.dvbc.modulation = dvbfe_modulation(channel.Modulation());
-
-     tuneTimeout = DVBC_TUNE_TIMEOUT;
-     lockTimeout = DVBC_LOCK_TIMEOUT;
-
-     dvbfe_info feinfo;
-     feinfo.delivery = Frontend.delivery;
-     CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
-     }
-  else if (frontendType & DVBFE_DELSYS_DVBT) {
-     Frontend.delivery = DVBFE_DELSYS_DVBT;
-     Frontend.frequency = FrequencyToHz(channel.Frequency());
-     Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
-     Frontend.delsys.dvbt.bandwidth = dvbfe_bandwidth(channel.Bandwidth());
-     Frontend.delsys.dvbt.code_rate_HP = dvbfe_fec(channel.CoderateH());
-     Frontend.delsys.dvbt.code_rate_LP = dvbfe_fec(channel.CoderateL());
-     Frontend.delsys.dvbt.constellation = dvbfe_modulation(channel.Modulation());
-     Frontend.delsys.dvbt.transmission_mode = dvbfe_transmission_mode(channel.Transmission());
-     Frontend.delsys.dvbt.guard_interval = dvbfe_guard_interval(channel.Guard());
-     Frontend.delsys.dvbt.hierarchy = dvbfe_hierarchy(channel.Hierarchy());
-     Frontend.delsys.dvbt.alpha = dvbfe_alpha(channel.Alpha());
-     Frontend.delsys.dvbt.priority = dvbfe_stream_priority(channel.Priority());
-
-     tuneTimeout = DVBT_TUNE_TIMEOUT;
-     lockTimeout = DVBT_LOCK_TIMEOUT;
-
-     dvbfe_info feinfo;
-     feinfo.delivery = Frontend.delivery;
-     CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
-     }
-  else {
-     esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
-     return false;
+         tuneTimeout = DVBS_TUNE_TIMEOUT;
+         lockTimeout = DVBS_LOCK_TIMEOUT;
+         }
+         break;
+    case FE_QAM: { // DVB-C
+
+         // Frequency and symbol rate:
+
+         Frontend.frequency = FrequencyToHz(channel.Frequency());
+         Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+         Frontend.u.qam.symbol_rate = channel.Srate() * 1000UL;
+         Frontend.u.qam.fec_inner = fe_code_rate_t(channel.CoderateH());
+         Frontend.u.qam.modulation = fe_modulation_t(channel.Modulation());
+
+         tuneTimeout = DVBC_TUNE_TIMEOUT;
+         lockTimeout = DVBC_LOCK_TIMEOUT;
+         }
+         break;
+    case FE_OFDM: { // DVB-T
+
+         // Frequency and OFDM paramaters:
+
+         Frontend.frequency = FrequencyToHz(channel.Frequency());
+         Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+         Frontend.u.ofdm.bandwidth = fe_bandwidth_t(channel.Bandwidth());
+         Frontend.u.ofdm.code_rate_HP = fe_code_rate_t(channel.CoderateH());
+         Frontend.u.ofdm.code_rate_LP = fe_code_rate_t(channel.CoderateL());
+         Frontend.u.ofdm.constellation = fe_modulation_t(channel.Modulation());
+         Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(channel.Transmission());
+         Frontend.u.ofdm.guard_interval = fe_guard_interval_t(channel.Guard());
+         Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(channel.Hierarchy());
+
+         tuneTimeout = DVBT_TUNE_TIMEOUT;
+         lockTimeout = DVBT_LOCK_TIMEOUT;
+         }
+         break;
+    default:
+         esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
+         return false;
     }
-  if (ioctl(fd_frontend, DVBFE_SET_PARAMS, &Frontend) < 0) {
+  if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) {
      esyslog("ERROR: frontend %d: %m", cardIndex);
      return false;
      }
@@ -382,23 +351,11 @@
 int cDvbDevice::devVideoOffset = -1;
 int cDvbDevice::setTransferModeForDolbyDigital = 1;
 
-const char *DeliverySystems[] = {
-  "DVBS",
-  "DSS",
-  "DVBS2",
-  "DVBC",
-  "DVBT",
-  "DVBH",
-  "ATSC",
-  NULL
-  };
-
 cDvbDevice::cDvbDevice(int n)
 {
   ciAdapter = NULL;
   dvbTuner = NULL;
-  frontendType = DVBFE_DELSYS_DUMMY;
-  numProvidedSystems = 0;
+  frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
   spuDecoder = NULL;
   digitalAudio = false;
   playMode = pmNone;
@@ -460,22 +417,9 @@
   // We only check the devices that must be present - the others will be checked before accessing them://XXX
 
   if (fd_frontend >= 0) {
-     if (ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0) {
-        const char **DeliverySystem = DeliverySystems;
-        cString ds;
-        for (int i = 0; i < 32; i++) {
-            if (frontendType & (1u << i)) {
-               numProvidedSystems++;
-               if (*DeliverySystem)
-                  ds = cString::sprintf("%s %s", *ds ? *ds : "", *DeliverySystem);
-               else
-                  esyslog("ERROR: unknown delivery system %d", i);
-               }
-            if (*DeliverySystem)
-               DeliverySystem++;
-            }
-        if (*ds)
-           isyslog("device %d provides:%s", CardIndex() + 1, *ds);
+     dvb_frontend_info feinfo;
+     if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
+        frontendType = feinfo.type;
         dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType);
         }
      else
@@ -489,6 +433,7 @@
 
 cDvbDevice::~cDvbDevice()
 {
+  StopSectionHandler();
   delete spuDecoder;
   delete dvbTuner;
   delete ciAdapter;
@@ -799,20 +744,14 @@
 {
   int type = Source & cSource::st_Mask;
   return type == cSource::stNone
-      || type == cSource::stCable && (frontendType & DVBFE_DELSYS_DVBC)
-      || type == cSource::stSat   && (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2))
-      || type == cSource::stTerr  && (frontendType & DVBFE_DELSYS_DVBT);
+      || type == cSource::stCable && frontendType == FE_QAM
+      || type == cSource::stSat   && frontendType == FE_QPSK
+      || type == cSource::stTerr  && frontendType == FE_OFDM;
 }
 
 bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const
 {
-  if (!ProvidesSource(Channel->Source()))
-     return false; // doesn't provide source
-  if (!cSource::IsSat(Channel->Source()))
-     return true; // source is sufficient for non sat
-  if (!(frontendType & Channel->System()))
-     return false; // requires modulation system which frontend doesn't provide
-  return !Setup.DiSEqC || Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization());
+  return ProvidesSource(Channel->Source()) && (!cSource::IsSat(Channel->Source()) || !Setup.DiSEqC || Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()));
 }
 
 bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const
@@ -821,7 +760,7 @@
   bool hasPriority = Priority < 0 || Priority > this->Priority();
   bool needsDetachReceivers = false;
 
-  if (ProvidesTransponder(Channel)) {
+  if (ProvidesSource(Channel->Source())) {
      result = hasPriority;
      if (Priority >= 0 && Receiving(true)) {
         if (dvbTuner->IsTunedTo(Channel)) {
@@ -853,11 +792,6 @@
   return result;
 }
 
-int cDvbDevice::NumProvidedSystems(void) const
-{
-  return numProvidedSystems;
-}
-
 bool cDvbDevice::IsTunedToTransponder(const cChannel *Channel)
 {
   return dvbTuner->IsTunedTo(Channel);
diff -ruN vdr-1.5.14/dvbdevice.h vdr-1.5.15/dvbdevice.h
--- vdr-1.5.14/dvbdevice.h	2008-01-27 11:21:02.000000000 +0100
+++ vdr-1.5.15/dvbdevice.h	2008-02-08 14:48:31.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.h 1.46 2008/01/27 10:21:02 kls Exp $
+ * $Id: dvbdevice.h 1.47 2008/02/08 13:48:31 kls Exp $
  */
 
 #ifndef __DVBDEVICE_H
@@ -15,8 +15,8 @@
 #include "device.h"
 #include "dvbspu.h"
 
-#if DVB_API_VERSION != 3 || DVB_API_VERSION_MINOR != 3
-#error VDR requires Linux DVB driver API version 3.3!
+#if DVB_API_VERSION != 3
+#error VDR requires Linux DVB driver API version 3!
 #endif
 
 #define MAXDVBDEVICES  8
@@ -35,8 +35,7 @@
          ///< Must be called before accessing any DVB functions.
          ///< \return True if any devices are available.
 private:
-  dvbfe_delsys frontendType;
-  int numProvidedSystems;
+  fe_type_t frontendType;
   int fd_osd, fd_audio, fd_video, fd_dvr, fd_stc, fd_ca;
 protected:
   virtual void MakePrimaryDevice(bool On);
@@ -67,7 +66,6 @@
   virtual bool ProvidesSource(int Source) const;
   virtual bool ProvidesTransponder(const cChannel *Channel) const;
   virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
-  virtual int NumProvidedSystems(void) const;
   virtual bool IsTunedToTransponder(const cChannel *Channel);
 protected:
   virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
diff -ruN vdr-1.5.14/dvbplayer.c vdr-1.5.15/dvbplayer.c
--- vdr-1.5.14/dvbplayer.c	2007-10-13 14:20:58.000000000 +0200
+++ vdr-1.5.15/dvbplayer.c	2008-02-09 16:10:54.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbplayer.c 1.47 2007/10/13 12:20:58 kls Exp $
+ * $Id: dvbplayer.c 1.48 2008/02/09 15:10:54 kls Exp $
  */
 
 #include "dvbplayer.h"
@@ -537,8 +537,10 @@
      Play();
   else {
      LOCK_THREAD;
-     if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward))
-        Empty();
+     if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
+        if (!(DeviceHasIBPTrickSpeed() && playDir == pdForward))
+           Empty();
+        }
      DeviceFreeze();
      playMode = pmPause;
      }
@@ -548,8 +550,10 @@
 {
   if (playMode != pmPlay) {
      LOCK_THREAD;
-     if (playMode == pmStill || playMode == pmFast || (playMode == pmSlow && playDir == pdBackward))
-        Empty();
+     if (playMode == pmStill || playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
+        if (!(DeviceHasIBPTrickSpeed() && playDir == pdForward))
+           Empty();
+        }
      DevicePlay();
      playMode = pmPlay;
      playDir = pdForward;
@@ -572,7 +576,8 @@
             // run into pmPlay
        case pmPlay: {
             LOCK_THREAD;
-            Empty();
+            if (!(DeviceHasIBPTrickSpeed() && playDir == pdForward))
+               Empty();
             DeviceMute();
             playMode = pmFast;
             playDir = pdForward;
diff -ruN vdr-1.5.14/epg.c vdr-1.5.15/epg.c
--- vdr-1.5.14/epg.c	2007-06-10 14:52:19.000000000 +0200
+++ vdr-1.5.15/epg.c	2008-02-16 17:09:12.000000000 +0100
@@ -7,11 +7,12 @@
  * Original version (as used in VDR before 1.3.0) written by
  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
  *
- * $Id: epg.c 1.82 2007/06/10 12:52:19 kls Exp $
+ * $Id: epg.c 1.83 2008/02/16 16:09:12 kls Exp $
  */
 
 #include "epg.h"
 #include <ctype.h>
+#include <limits.h>
 #include <time.h>
 #include "libsi/si.h"
 #include "timers.h"
diff -ruN vdr-1.5.14/font.c vdr-1.5.15/font.c
--- vdr-1.5.14/font.c	2007-11-04 12:08:12.000000000 +0100
+++ vdr-1.5.15/font.c	2008-02-09 12:52:25.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: font.c 1.22 2007/11/04 11:08:12 kls Exp $
+ * $Id: font.c 1.23 2008/02/09 11:52:25 kls Exp $
  */
 
 #include "font.h"
@@ -241,10 +241,16 @@
   return w;
 }
 
+#define MAX_BLEND_LEVELS 256
+
 void cFreetypeFont::DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
 {
   if (s && height) { // checking height to make sure we actually have a valid font
      bool AntiAliased = Setup.AntiAlias && Bitmap->Bpp() >= 8;
+     bool TransparentBackground = ColorBg == clrTransparent;
+     int16_t BlendLevelIndex[MAX_BLEND_LEVELS]; // tIndex is 8 bit unsigned, so a negative value can be used to mark unused entries
+     if (AntiAliased && !TransparentBackground)
+        memset(BlendLevelIndex, 0xFF, sizeof(BlendLevelIndex)); // initializes the array with negative values
      tIndex fg = Bitmap->Index(ColorFg);
      uint prevSym = 0;
      while (*s) {
@@ -266,12 +272,16 @@
                          if (bt > 0x00) {
                             int px = x + pitch + g->Left() + kerning;
                             int py = y + row + (height - Bottom() - g->Top());
+                            tColor bg;
                             if (bt == 0xFF)
-                               Bitmap->SetIndex(px, py, fg);
-                            else {
-                               tColor bg = (ColorBg != clrTransparent) ? ColorBg : Bitmap->GetColor(px, py);
-                               Bitmap->SetIndex(px, py, Bitmap->Index(Bitmap->Blend(ColorFg, bg, bt)));
-                               }
+                               bg = fg;
+                            else if (TransparentBackground)
+                               bg = Bitmap->Index(Bitmap->Blend(ColorFg, Bitmap->GetColor(px, py), bt));
+                            else if (BlendLevelIndex[bt] >= 0)
+                               bg = BlendLevelIndex[bt];
+                            else
+                               bg = BlendLevelIndex[bt] = Bitmap->Index(Bitmap->Blend(ColorFg, ColorBg, bt));
+                            Bitmap->SetIndex(px, py, bg);
                             }
                          }
                       else { //monochrome rendering
diff -ruN vdr-1.5.14/interface.c vdr-1.5.15/interface.c
--- vdr-1.5.14/interface.c	2007-08-04 16:39:25.000000000 +0200
+++ vdr-1.5.15/interface.c	2008-02-10 16:49:15.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: interface.c 1.76 2007/08/04 14:39:25 kls Exp $
+ * $Id: interface.c 1.77 2008/02/10 15:49:15 kls Exp $
  */
 
 #include "interface.h"
@@ -86,10 +86,7 @@
      DisplayMenu->SetItem(tr("Phase 2: Learning specific key codes"), 2, false, false);
      eKeys NewKey = kUp;
      while (NewKey != kNone) {
-           char *Prompt;
-           asprintf(&Prompt, tr("Press key for '%s'"), cKey::ToString(NewKey, true));
-           DisplayMenu->SetItem(Prompt, 4, false, false);
-           free(Prompt);
+           DisplayMenu->SetItem(cString::sprintf(tr("Press key for '%s'"), cKey::ToString(NewKey, true)), 4, false, false);
            cRemote::Clear();
            DisplayMenu->Flush();
            for (eKeys k = NewKey; k == NewKey; ) {
diff -ruN vdr-1.5.14/keys.c vdr-1.5.15/keys.c
--- vdr-1.5.14/keys.c	2007-08-26 14:35:21.000000000 +0200
+++ vdr-1.5.15/keys.c	2008-02-10 15:08:48.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: keys.c 1.16 2007/08/26 12:35:21 kls Exp $
+ * $Id: keys.c 1.17 2008/02/10 14:08:48 kls Exp $
  */
 
 #include "keys.h"
@@ -70,7 +70,7 @@
                     { kNone,                 NULL               },
                   };
 
-// -- cKey -------------------------------------------------------------------
+// --- cKey ------------------------------------------------------------------
 
 cKey::cKey(void)
 {
@@ -149,7 +149,7 @@
   return NULL;
 }
 
-// -- cKeys ------------------------------------------------------------------
+// --- cKeys -----------------------------------------------------------------
 
 cKeys Keys;
 
@@ -194,7 +194,7 @@
      esyslog("ERROR: called PutSetup() for %s, but setup has already been defined!", Remote);
 }
 
-// -- cKeyMacro --------------------------------------------------------------
+// --- cKeyMacro -------------------------------------------------------------
 
 cKeyMacro::cKeyMacro(void)
 {
@@ -260,7 +260,7 @@
   return true;
 }
 
-// -- cKeyMacros -------------------------------------------------------------
+// --- cKeyMacros ------------------------------------------------------------
 
 cKeyMacros KeyMacros;
 
diff -ruN vdr-1.5.14/menu.c vdr-1.5.15/menu.c
--- vdr-1.5.14/menu.c	2008-01-26 17:29:05.000000000 +0100
+++ vdr-1.5.15/menu.c	2008-02-16 14:53:26.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.c 1.470 2008/01/26 16:29:05 kls Exp $
+ * $Id: menu.c 1.477 2008/02/16 13:53:26 kls Exp $
  */
 
 #include "menu.h"
@@ -32,7 +32,7 @@
 
 #define MAXWAIT4EPGINFO   3 // seconds
 #define MODETIMEOUT       3 // seconds
-#define DISKSPACECHEK     5 // seconds between disk space checks in the main menu
+#define DISKSPACECHEK     5 // seconds between disk space checks
 #define NEWTIMERLIMIT   120 // seconds until the start time of a new timer created from the Schedule menu,
                             // within which it will go directly into the "Edit timer" menu to allow
                             // further parameter settings
@@ -47,6 +47,44 @@
 
 #define CHNUMWIDTH  (numdigits(Channels.MaxNumber()) + 1)
 
+// --- cFreeDiskSpace --------------------------------------------------------
+
+#define MB_PER_MINUTE 25.75 // this is just an estimate!
+
+class cFreeDiskSpace {
+private:
+  static time_t lastDiskSpaceCheck;
+  static int lastFreeMB;
+  static cString freeDiskSpaceString;
+public:
+  static bool HasChanged(bool ForceCheck = false);
+  static const char *FreeDiskSpaceString(void) { HasChanged(); return freeDiskSpaceString; }
+  };
+
+time_t cFreeDiskSpace::lastDiskSpaceCheck = 0;
+int cFreeDiskSpace::lastFreeMB = 0;
+cString cFreeDiskSpace::freeDiskSpaceString;
+
+cFreeDiskSpace FreeDiskSpace;
+
+bool cFreeDiskSpace::HasChanged(bool ForceCheck)
+{
+  if (ForceCheck || time(NULL) - lastDiskSpaceCheck > DISKSPACECHEK) {
+     int FreeMB;
+     int Percent = VideoDiskSpace(&FreeMB);
+     lastDiskSpaceCheck = time(NULL);
+     if (ForceCheck || FreeMB != lastFreeMB) {
+        int Minutes = int(double(FreeMB) / MB_PER_MINUTE);
+        int Hours = Minutes / 60;
+        Minutes %= 60;
+        freeDiskSpaceString = cString::sprintf("%s %d%%  -  %2d:%02d %s", tr("Disk"), Percent, Hours, Minutes, tr("free"));
+        lastFreeMB = FreeMB;
+        return true;
+        }
+     }
+  return false;
+}
+
 // --- cMenuEditCaItem -------------------------------------------------------
 
 class cMenuEditCaItem : public cMenuEditIntItem {
@@ -109,12 +147,8 @@
 
 void cMenuEditSrcItem::Set(void)
 {
-  if (source) {
-     char *buffer = NULL;
-     asprintf(&buffer, "%s - %s", *cSource::ToString(source->Code()), source->Description());
-     SetValue(buffer);
-     free(buffer);
-     }
+  if (source)
+     SetValue(cString::sprintf("%s - %s", *cSource::ToString(source->Code()), source->Description()));
   else
      cMenuEditIntItem::Set();
 }
@@ -148,6 +182,70 @@
   return state;
 }
 
+// --- cMenuEditMapItem ------------------------------------------------------
+
+class cMenuEditMapItem : public cMenuEditItem {
+protected:
+  int *value;
+  const tChannelParameterMap *map;
+  const char *zeroString;
+  virtual void Set(void);
+public:
+  cMenuEditMapItem(const char *Name, int *Value, const tChannelParameterMap *Map, const char *ZeroString = NULL);
+  virtual eOSState ProcessKey(eKeys Key);
+  };
+
+cMenuEditMapItem::cMenuEditMapItem(const char *Name, int *Value, const tChannelParameterMap *Map, const char *ZeroString)
+:cMenuEditItem(Name)
+{
+  value = Value;
+  map = Map;
+  zeroString = ZeroString;
+  Set();
+}
+
+void cMenuEditMapItem::Set(void)
+{
+  int n = MapToUser(*value, map);
+  if (n == 999)
+     SetValue(tr("auto"));
+  else if (n == 0 && zeroString)
+     SetValue(zeroString);
+  else if (n >= 0) {
+     char buf[16];
+     snprintf(buf, sizeof(buf), "%d", n);
+     SetValue(buf);
+     }
+  else
+     SetValue("???");
+}
+
+eOSState cMenuEditMapItem::ProcessKey(eKeys Key)
+{
+  eOSState state = cMenuEditItem::ProcessKey(Key);
+
+  if (state == osUnknown) {
+     int newValue = *value;
+     int n = DriverIndex(*value, map);
+     if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly?
+        if (n-- > 0)
+           newValue = map[n].driverValue;
+        }
+     else if (NORMALKEY(Key) == kRight) {
+        if (map[++n].userValue >= 0)
+           newValue = map[n].driverValue;
+        }
+     else
+        return state;
+     if (newValue != *value) {
+        *value = newValue;
+        Set();
+        }
+     state = osContinue;
+     }
+  return state;
+}
+
 // --- cMenuEditChannel ------------------------------------------------------
 
 class cMenuEditChannel : public cOsdMenu {
@@ -208,19 +306,15 @@
   XXX*/
   // Parameters for specific types of sources:
   ST(" S ")  Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hvlr"));
-  ST(" S ")  Add(new cMenuEditMapItem( tr("System"),       &data.system,       SystemValues));
   ST("CS ")  Add(new cMenuEditIntItem( tr("Srate"),        &data.srate));
-  ST("CST")  Add(new cMenuEditMapItem( tr("Inversion"),    &data.inversion,    InversionValues));
-  ST("CST")  Add(new cMenuEditMapItem( tr("CoderateH"),    &data.coderateH,    CoderateValues));
-  ST("  T")  Add(new cMenuEditMapItem( tr("CoderateL"),    &data.coderateL,    CoderateValues));
-  ST("CST")  Add(new cMenuEditMapItem( tr("Modulation"),   &data.modulation,   ModulationValues));
+  ST("CST")  Add(new cMenuEditMapItem( tr("Inversion"),    &data.inversion,    InversionValues, tr("off")));
+  ST("CST")  Add(new cMenuEditMapItem( tr("CoderateH"),    &data.coderateH,    CoderateValues, tr("none")));
+  ST("  T")  Add(new cMenuEditMapItem( tr("CoderateL"),    &data.coderateL,    CoderateValues, tr("none")));
+  ST("C T")  Add(new cMenuEditMapItem( tr("Modulation"),   &data.modulation,   ModulationValues, "QPSK"));
   ST("  T")  Add(new cMenuEditMapItem( tr("Bandwidth"),    &data.bandwidth,    BandwidthValues));
   ST("  T")  Add(new cMenuEditMapItem( tr("Transmission"), &data.transmission, TransmissionValues));
   ST("  T")  Add(new cMenuEditMapItem( tr("Guard"),        &data.guard,        GuardValues));
-  ST("  T")  Add(new cMenuEditMapItem( tr("Hierarchy"),    &data.hierarchy,    HierarchyValues));
-  ST("  T")  Add(new cMenuEditMapItem( tr("Alpha"),        &data.alpha,        AlphaValues));
-  ST("  T")  Add(new cMenuEditMapItem( tr("Priority"),     &data.priority,     PriorityValues));
-  ST(" S ")  Add(new cMenuEditMapItem( tr("Rolloff"),      &data.rollOff,      RollOffValues));
+  ST("  T")  Add(new cMenuEditMapItem( tr("Hierarchy"),    &data.hierarchy,    HierarchyValues, tr("none")));
 
   SetCurrent(Get(current));
   Display();
@@ -304,16 +398,16 @@
 
 void cMenuChannelItem::Set(void)
 {
-  char *buffer = NULL;
+  cString buffer;
   if (!channel->GroupSep()) {
      if (sortMode == csmProvider)
-        asprintf(&buffer, "%d\t%s - %s", channel->Number(), channel->Provider(), channel->Name());
+        buffer = cString::sprintf("%d\t%s - %s", channel->Number(), channel->Provider(), channel->Name());
      else
-        asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name());
+        buffer = cString::sprintf("%d\t%s", channel->Number(), channel->Name());
      }
   else
-     asprintf(&buffer, "---\t%s ----------------------------------------------------------------", channel->Name());
-  SetText(buffer, false);
+     buffer = cString::sprintf("---\t%s ----------------------------------------------------------------", channel->Name());
+  SetText(buffer);
 }
 
 // --- cMenuChannels ---------------------------------------------------------
@@ -718,8 +812,7 @@
      strftime(buffer, sizeof(buffer), "%Y%m%d", &tm_r);
      day = buffer;
      }
-  char *buffer = NULL;
-  asprintf(&buffer, "%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s",
+  SetText(cString::sprintf("%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s",
                     !(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>',
                     timer->Channel()->Number(),
                     *name,
@@ -729,8 +822,7 @@
                     timer->Start() % 100,
                     timer->Stop() / 100,
                     timer->Stop() % 100,
-                    timer->File());
-  SetText(buffer, false);
+                    timer->File()));
 }
 
 // --- cMenuTimers -----------------------------------------------------------
@@ -994,19 +1086,19 @@
   int OldTimerMatch = timerMatch;
   Timers.GetMatch(event, &timerMatch);
   if (Force || timerMatch != OldTimerMatch) {
-     char *buffer = NULL;
+     cString buffer;
      char t = TimerMatchChars[timerMatch];
      char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
      char r = event->SeenWithin(30) && event->IsRunning() ? '*' : ' ';
      const char *csn = channel ? channel->ShortName(true) : NULL;
      cString eds = event->GetDateString();
      if (channel && withDate)
-        asprintf(&buffer, "%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title());
+        buffer = cString::sprintf("%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title());
      else if (channel)
-        asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title());
+        buffer = cString::sprintf("%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title());
      else
-        asprintf(&buffer, "%.*s\t%s\t%c%c%c\t%s", Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title());
-     SetText(buffer, false);
+        buffer = cString::sprintf("%.*s\t%s\t%c%c%c\t%s", Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title());
+     SetText(buffer);
      result = true;
      }
   return result;
@@ -1227,10 +1319,7 @@
 {
   Clear();
   SetCols(7, 6, 4);
-  char *buffer = NULL;
-  asprintf(&buffer, tr("Schedule - %s"), Channel->Name());
-  SetTitle(buffer);
-  free(buffer);
+  SetTitle(cString::sprintf(tr("Schedule - %s"), Channel->Name()));
   if (schedules && Channel) {
      const cSchedule *Schedule = schedules->GetSchedule(Channel);
      if (Schedule) {
@@ -1248,10 +1337,7 @@
 {
   Clear();
   SetCols(7, 6, 4);
-  char *buffer = NULL;
-  asprintf(&buffer, tr("This event - %s"), Channel->Name());
-  SetTitle(buffer);
-  free(buffer);
+  SetTitle(cString::sprintf(tr("This event - %s"), Channel->Name()));
   if (schedules && Channel && Event) {
      const cSchedule *Schedule = schedules->GetSchedule(Channel);
      if (Schedule) {
@@ -1492,17 +1578,11 @@
 {
   cCommand *command = commands->Get(Current());
   if (command) {
-     char *buffer = NULL;
      bool confirmed = true;
-     if (command->Confirm()) {
-        asprintf(&buffer, "%s?", command->Title());
-        confirmed = Interface->Confirm(buffer);
-        free(buffer);
-        }
+     if (command->Confirm())
+        confirmed = Interface->Confirm(cString::sprintf("%s?", command->Title()));
      if (confirmed) {
-        asprintf(&buffer, "%s...", command->Title());
-        Skins.Message(mtStatus, buffer);
-        free(buffer);
+        Skins.Message(mtStatus, cString::sprintf("%s...", command->Title()));
         const char *Result = command->Execute(parameters);
         Skins.Message(mtStatus, NULL);
         if (Result)
@@ -1818,9 +1898,7 @@
   totalEntries++;
   if (New)
      newEntries++;
-  char *buffer = NULL;
-  asprintf(&buffer, "%d\t%d\t%s", totalEntries, newEntries, name);
-  SetText(buffer, false);
+  SetText(cString::sprintf("%d\t%d\t%s", totalEntries, newEntries, name));
 }
 
 // --- cMenuRecordings -------------------------------------------------------
@@ -1838,6 +1916,7 @@
      SetCurrent(First());
   else if (OpenSubMenus && cReplayControl::LastReplayed() && Open(true))
      return;
+  SetFreeDiskDisplay(true);
   Display();
   SetHelpKeys();
 }
@@ -1848,6 +1927,16 @@
   free(base);
 }
 
+bool cMenuRecordings::SetFreeDiskDisplay(bool Force)
+{
+  if (FreeDiskSpace.HasChanged(Force)) {
+     //XXX -> skin function!!!
+     SetTitle(cString::sprintf("%s  -  %s", base ? base : tr("Recordings"), FreeDiskSpace.FreeDiskSpaceString()));
+     return true;
+     }
+  return false;
+}
+
 void cMenuRecordings::SetHelpKeys(void)
 {
   cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
@@ -1909,6 +1998,7 @@
          }
       }
   free(LastItemText);
+  Refresh |= SetFreeDiskDisplay(Refresh);
   if (Refresh)
      Display();
 }
@@ -1926,13 +2016,12 @@
   cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
   if (ri && ri->IsDirectory()) {
      const char *t = ri->Name();
-     char *buffer = NULL;
+     cString buffer;
      if (base) {
-        asprintf(&buffer, "%s~%s", base, t);
+        buffer = cString::sprintf("%s~%s", base, t);
         t = buffer;
         }
      AddSubMenu(new cMenuRecordings(t, level + 1, OpenSubMenus));
-     free(buffer);
      return true;
      }
   return false;
@@ -1995,11 +2084,14 @@
            }
         cRecording *recording = GetRecording(ri);
         if (recording) {
+           if (cReplayControl::NowReplaying() && strcmp(cReplayControl::NowReplaying(), ri->FileName()) == 0)
+              cControl::Shutdown();
            if (recording->Delete()) {
               cReplayControl::ClearLastReplayed(ri->FileName());
               Recordings.DelByName(ri->FileName());
               cOsdMenu::Del(Current());
               SetHelpKeys();
+              SetFreeDiskDisplay(true);
               Display();
               if (!Count())
                  return osBack;
@@ -2033,11 +2125,8 @@
   if (ri && !ri->IsDirectory()) {
      cRecording *recording = GetRecording(ri);
      if (recording) {
-        char *parameter = NULL;
-        asprintf(&parameter, "\"%s\"", *strescape(recording->FileName(), "\"$"));
         cMenuCommands *menu;
-        eOSState state = AddSubMenu(menu = new cMenuCommands(tr("Recording commands"), &RecordingCommands, parameter));
-        free(parameter);
+        eOSState state = AddSubMenu(menu = new cMenuCommands(tr("Recording commands"), &RecordingCommands, cString::sprintf("\"%s\"", *strescape(recording->FileName(), "\"$"))));
         if (Key != kNone)
            state = menu->ProcessKey(Key);
         return state;
@@ -2074,8 +2163,12 @@
         return osBack;
      Display();
      }
-  if (!HasSubMenu() && Key != kNone)
-     SetHelpKeys();
+  if (!HasSubMenu()) {
+     if (HadSubMenu)
+        SetFreeDiskDisplay();
+     if (Key != kNone)
+        SetHelpKeys();
+     }
   return state;
 }
 
@@ -2740,12 +2833,8 @@
   SetHasHotkeys();
   for (int i = 0; ; i++) {
       cPlugin *p = cPluginManager::GetPlugin(i);
-      if (p) {
-         char *buffer = NULL;
-         asprintf(&buffer, "%s (%s) - %s", p->Name(), p->Version(), p->Description());
-         Add(new cMenuSetupPluginItem(hk(buffer), i));
-         free(buffer);
-         }
+      if (p)
+         Add(new cMenuSetupPluginItem(hk(cString::sprintf("%s (%s) - %s", p->Name(), p->Version(), p->Description())), i));
       else
          break;
       }
@@ -2874,8 +2963,6 @@
 cMenuMain::cMenuMain(eOSState State)
 :cOsdMenu("")
 {
-  lastDiskSpaceCheck = 0;
-  lastFreeMB = 0;
   replaying = false;
   stopReplayItem = NULL;
   cancelEditingItem = NULL;
@@ -2940,26 +3027,15 @@
   Display();
 }
 
-#define MB_PER_MINUTE 25.75 // this is just an estimate!
-
 bool cMenuMain::Update(bool Force)
 {
   bool result = false;
 
   // Title with disk usage:
-  if (Force || time(NULL) - lastDiskSpaceCheck > DISKSPACECHEK) {
-     int FreeMB;
-     int Percent = VideoDiskSpace(&FreeMB);
-     if (Force || FreeMB != lastFreeMB) {
-        int Minutes = int(double(FreeMB) / MB_PER_MINUTE);
-        int Hours = Minutes / 60;
-        Minutes %= 60;
-        //XXX -> skin function!!!
-        SetTitle(cString::sprintf("%s  -  %s %d%%  -  %2d:%02d %s", tr("VDR"), tr("Disk"), Percent, Hours, Minutes, tr("free")));
-        lastFreeMB = FreeMB;
-        result = true;
-        }
-     lastDiskSpaceCheck = time(NULL);
+  if (FreeDiskSpace.HasChanged(Force)) {
+     //XXX -> skin function!!!
+     SetTitle(cString::sprintf("%s  -  %s", tr("VDR"), FreeDiskSpace.FreeDiskSpaceString()));
+     result = true;
      }
 
   bool NewReplaying = cControl::Control() != NULL;
@@ -3000,10 +3076,8 @@
            }
      const char *s = NULL;
      while ((s = cRecordControls::GetInstantId(s)) != NULL) {
-           char *buffer = NULL;
-           asprintf(&buffer, "%s%s", tr(STOP_RECORDING), s);
            cOsdItem *item = new cOsdItem(osStopRecord);
-           item->SetText(buffer, false);
+           item->SetText(cString::sprintf("%s%s", tr(STOP_RECORDING), s));
            Add(item);
            if (!stopRecordingItem)
               stopRecordingItem = item;
@@ -3628,7 +3702,7 @@
 {
   displayTracks->SetTrack(track, descriptions);
   displayTracks->Flush();
-  //cStatus::MsgSetSubtitleTrack(track, descriptions); //TODO better make a more general cStatus::MsgSetTrack(tr("Subtitles"), track, descriptions)
+  cStatus::MsgSetSubtitleTrack(track, descriptions);
 }
 
 cDisplaySubtitleTracks *cDisplaySubtitleTracks::Create(void)
@@ -3694,7 +3768,6 @@
   cSchedules::Schedules(SchedulesLock);
 
   event = NULL;
-  instantId = NULL;
   fileName = NULL;
   recorder = NULL;
   device = Device;
@@ -3704,7 +3777,7 @@
      timer = new cTimer(true, Pause);
      Timers.Add(timer);
      Timers.SetModified();
-     asprintf(&instantId, cDevice::NumDevices() > 1 ? "%s - %d" : "%s", timer->Channel()->Name(), device->CardIndex() + 1);
+     instantId = cString::sprintf(cDevice::NumDevices() > 1 ? "%s - %d" : "%s", timer->Channel()->Name(), device->CardIndex() + 1);
      }
   timer->SetPending(true);
   timer->SetRecording(true);
@@ -3759,7 +3832,6 @@
 cRecordControl::~cRecordControl()
 {
   Stop();
-  free(instantId);
   free(fileName);
 }
 
@@ -4183,7 +4255,8 @@
          timeSearchActive = false;
          break;
     default:
-         timeSearchActive = false;
+         if (!(Key & k_Flags)) // ignore repeat/release keys
+            timeSearchActive = false;
          break;
     }
 
diff -ruN vdr-1.5.14/menu.h vdr-1.5.15/menu.h
--- vdr-1.5.14/menu.h	2007-08-26 16:35:57.000000000 +0200
+++ vdr-1.5.15/menu.h	2008-02-10 17:01:53.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.h 1.89 2007/08/26 14:35:57 kls Exp $
+ * $Id: menu.h 1.91 2008/02/10 16:01:53 kls Exp $
  */
 
 #ifndef __MENU_H
@@ -56,8 +56,6 @@
 
 class cMenuMain : public cOsdMenu {
 private:
-  time_t lastDiskSpaceCheck;
-  int lastFreeMB;
   bool replaying;
   cOsdItem *stopReplayItem;
   cOsdItem *cancelEditingItem;
@@ -156,6 +154,7 @@
   int level;
   int recordingsState;
   int helpKeys;
+  bool SetFreeDiskDisplay(bool Force = false);
   void SetHelpKeys(void);
   void Set(bool Refresh = false);
   bool Open(bool OpenSubMenus = false);
@@ -178,7 +177,7 @@
   cTimer *timer;
   cRecorder *recorder;
   const cEvent *event;
-  char *instantId;
+  cString instantId;
   char *fileName;
   bool GetEvent(void);
 public:
diff -ruN vdr-1.5.14/menuitems.c vdr-1.5.15/menuitems.c
--- vdr-1.5.14/menuitems.c	2008-01-26 17:07:07.000000000 +0100
+++ vdr-1.5.15/menuitems.c	2008-02-10 17:03:30.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menuitems.c 1.56 2008/01/26 16:07:07 kls Exp $
+ * $Id: menuitems.c 1.58 2008/02/10 16:03:30 kls Exp $
  */
 
 #include "menuitems.h"
@@ -34,9 +34,8 @@
 
 void cMenuEditItem::SetValue(const char *Value)
 {
-  char *buffer = NULL;
-  asprintf(&buffer, "%s:\t%s", name, Value);
-  SetText(buffer, false);
+  cString buffer = cString::sprintf("%s:\t%s", name, Value);
+  SetText(buffer);
   cStatus::MsgOsdCurrentItem(buffer);
 }
 
@@ -937,64 +936,6 @@
   return state;
 }
 
-// --- cMenuEditMapItem ------------------------------------------------------
-
-cMenuEditMapItem::cMenuEditMapItem(const char *Name, int *Value, const tChannelParameterMap *Map, const char *ZeroString)
-:cMenuEditItem(Name)
-{
-  value = Value;
-  map = Map;
-  zeroString = ZeroString;
-  Set();
-}
-
-void cMenuEditMapItem::Set(void)
-{
-  const char *s = NULL;
-  int n = MapToUser(*value, map, &s);
-  if (n == 999)
-     SetValue(tr("auto"));
-  else if (n == 0 && zeroString)
-     SetValue(zeroString);
-  else if (n >= 0) {
-     if (s)
-        SetValue(s);
-     else {
-        char buf[16];
-        snprintf(buf, sizeof(buf), "%d", n);
-        SetValue(buf);
-        }
-     }
-  else
-     SetValue("???");
-}
-
-eOSState cMenuEditMapItem::ProcessKey(eKeys Key)
-{
-  eOSState state = cMenuEditItem::ProcessKey(Key);
-
-  if (state == osUnknown) {
-     int newValue = *value;
-     int n = DriverIndex(*value, map);
-     if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly?
-        if (n-- > 0)
-           newValue = map[n].driverValue;
-        }
-     else if (NORMALKEY(Key) == kRight) {
-        if (map[++n].userValue >= 0)
-           newValue = map[n].driverValue;
-        }
-     else
-        return state;
-     if (newValue != *value) {
-        *value = newValue;
-        Set();
-        }
-     state = osContinue;
-     }
-  return state;
-}
-
 // --- cMenuSetupPage --------------------------------------------------------
 
 cMenuSetupPage::cMenuSetupPage(void)
diff -ruN vdr-1.5.14/menuitems.h vdr-1.5.15/menuitems.h
--- vdr-1.5.14/menuitems.h	2008-01-26 16:52:53.000000000 +0100
+++ vdr-1.5.15/menuitems.h	2008-02-16 17:09:58.000000000 +0100
@@ -4,12 +4,13 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menuitems.h 1.23 2008/01/26 15:52:53 kls Exp $
+ * $Id: menuitems.h 1.25 2008/02/16 16:09:58 kls Exp $
  */
 
 #ifndef __MENUITEMS_H
 #define __MENUITEMS_H
 
+#include <limits.h>
 #include "osdbase.h"
 
 extern const char *FileNameChars;
@@ -159,17 +160,6 @@
   virtual eOSState ProcessKey(eKeys Key);
   };
 
-class cMenuEditMapItem : public cMenuEditItem {
-protected:
-  int *value;
-  const tChannelParameterMap *map;
-  const char *zeroString;
-  virtual void Set(void);
-public:
-  cMenuEditMapItem(const char *Name, int *Value, const tChannelParameterMap *Map, const char *ZeroString = NULL);
-  virtual eOSState ProcessKey(eKeys Key);
-  };
-
 class cPlugin;
 
 class cMenuSetupPage : public cOsdMenu {
diff -ruN vdr-1.5.14/nit.c vdr-1.5.15/nit.c
--- vdr-1.5.14/nit.c	2008-01-26 16:08:01.000000000 +0100
+++ vdr-1.5.15/nit.c	2008-02-08 14:48:31.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: nit.c 1.17 2008/01/26 15:08:01 kls Exp $
+ * $Id: nit.c 1.18 2008/02/08 13:48:31 kls Exp $
  */
 
 #include "nit.h"
@@ -127,13 +127,8 @@
                  int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 100;
                  static char Polarizations[] = { 'h', 'v', 'l', 'r' };
                  char Polarization = Polarizations[sd->getPolarization()];
-                 static int CodeRates[] = { DVBFE_FEC_NONE, DVBFE_FEC_1_2, DVBFE_FEC_2_3, DVBFE_FEC_3_4, DVBFE_FEC_5_6, DVBFE_FEC_7_8, DVBFE_FEC_8_9, DVBFE_FEC_3_5, DVBFE_FEC_4_5, DVBFE_FEC_9_10, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_NONE };
+                 static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
                  int CodeRate = CodeRates[sd->getFecInner()];
-                 static int Modulations[] = { DVBFE_MOD_AUTO, DVBFE_MOD_QPSK, DVBFE_MOD_8PSK, DVBFE_MOD_QAM16 };
-                 int Modulation = Modulations[sd->getModulationType()];
-                 int System = sd->getModulationSystem() ? DVBFE_DELSYS_DVBS2 : DVBFE_DELSYS_DVBS;
-                 static int RollOffs[] = { DVBFE_ROLLOFF_35, DVBFE_ROLLOFF_25, DVBFE_ROLLOFF_20, DVBFE_ROLLOFF_UNKNOWN };
-                 int RollOff = sd->getModulationSystem() ? RollOffs[sd->getRollOff()] : DVBFE_ROLLOFF_UNKNOWN;
                  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
                  if (ThisNIT >= 0) {
                     for (int n = 0; n < NumFrequencies; n++) {
@@ -160,14 +155,14 @@
                                   }
                               }
                            if (ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Transponder())) // only modify channels if we're actually receiving this transponder
-                              Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate, Modulation, System, RollOff);
+                              Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate);
                            }
                         }
                     if (!found) {
                        for (int n = 0; n < NumFrequencies; n++) {
                            cChannel *Channel = new cChannel;
                            Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
-                           if (Channel->SetSatTransponderData(Source, Frequencies[n], Polarization, SymbolRate, CodeRate, Modulation, System, RollOff))
+                           if (Channel->SetSatTransponderData(Source, Frequencies[n], Polarization, SymbolRate, CodeRate))
                               EITScanner.AddTransponder(Channel);
                            else
                               delete Channel;
@@ -181,9 +176,9 @@
                  int Source = cSource::FromData(cSource::stCable);
                  int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 10;
                  //XXX FEC_outer???
-                 static int CodeRates[] = { DVBFE_FEC_NONE, DVBFE_FEC_1_2, DVBFE_FEC_2_3, DVBFE_FEC_3_4, DVBFE_FEC_5_6, DVBFE_FEC_7_8, DVBFE_FEC_8_9, DVBFE_FEC_3_5, DVBFE_FEC_4_5, DVBFE_FEC_9_10, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_NONE };
+                 static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
                  int CodeRate = CodeRates[sd->getFecInner()];
-                 static int Modulations[] = { DVBFE_MOD_NONE, DVBFE_MOD_QAM16, DVBFE_MOD_QAM32, DVBFE_MOD_QAM64, DVBFE_MOD_QAM128, DVBFE_MOD_QAM256, QAM_AUTO };
+                 static int Modulations[] = { QPSK, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO };
                  int Modulation = Modulations[min(sd->getModulation(), 6)];
                  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
                  if (ThisNIT >= 0) {
@@ -231,22 +226,19 @@
                  SI::TerrestrialDeliverySystemDescriptor *sd = (SI::TerrestrialDeliverySystemDescriptor *)d;
                  int Source = cSource::FromData(cSource::stTerr);
                  int Frequency = Frequencies[0] = sd->getFrequency() * 10;
-                 static int Bandwidths[] = { DVBFE_BANDWIDTH_8_MHZ, DVBFE_BANDWIDTH_7_MHZ, DVBFE_BANDWIDTH_6_MHZ, DVBFE_BANDWIDTH_5_MHZ, DVBFE_BANDWIDTH_AUTO, DVBFE_BANDWIDTH_AUTO, DVBFE_BANDWIDTH_AUTO, DVBFE_BANDWIDTH_AUTO };
+                 static int Bandwidths[] = { BANDWIDTH_8_MHZ, BANDWIDTH_7_MHZ, BANDWIDTH_6_MHZ, BANDWIDTH_AUTO, BANDWIDTH_AUTO, BANDWIDTH_AUTO, BANDWIDTH_AUTO, BANDWIDTH_AUTO };
                  int Bandwidth = Bandwidths[sd->getBandwidth()];
-                 static int Constellations[] = { DVBFE_MOD_QPSK, DVBFE_MOD_QAM16, DVBFE_MOD_QAM64, DVBFE_MOD_AUTO };
+                 static int Constellations[] = { QPSK, QAM_16, QAM_64, QAM_AUTO };
                  int Constellation = Constellations[sd->getConstellation()];
-                 static int CodeRates[] = { DVBFE_FEC_1_2, DVBFE_FEC_2_3, DVBFE_FEC_3_4, DVBFE_FEC_5_6, DVBFE_FEC_7_8, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO };
+                 static int Hierarchies[] = { HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, HIERARCHY_4, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO };
+                 int Hierarchy = Hierarchies[sd->getHierarchy()];
+                 static int CodeRates[] = { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO };
                  int CodeRateHP = CodeRates[sd->getCodeRateHP()];
                  int CodeRateLP = CodeRates[sd->getCodeRateLP()];
-                 static int GuardIntervals[] = { DVBFE_GUARD_INTERVAL_1_32, DVBFE_GUARD_INTERVAL_1_16, DVBFE_GUARD_INTERVAL_1_8, DVBFE_GUARD_INTERVAL_1_4 };
+                 static int GuardIntervals[] = { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4 };
                  int GuardInterval = GuardIntervals[sd->getGuardInterval()];
-                 static int TransmissionModes[] = { DVBFE_TRANSMISSION_MODE_2K, DVBFE_TRANSMISSION_MODE_8K, DVBFE_TRANSMISSION_MODE_4K, DVBFE_TRANSMISSION_MODE_AUTO };
+                 static int TransmissionModes[] = { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_AUTO, TRANSMISSION_MODE_AUTO };
                  int TransmissionMode = TransmissionModes[sd->getTransmissionMode()];
-                 static int Priorities[] = { DVBFE_STREAM_PRIORITY_LP, DVBFE_STREAM_PRIORITY_HP };
-                 int Priority = Priorities[sd->getPriority()];
-                 static int Alphas[] = { 0, DVBFE_ALPHA_1, DVBFE_ALPHA_2, DVBFE_ALPHA_4 };
-                 int Alpha = Alphas[sd->getHierarchy() & 3];
-                 int Hierarchy = Alpha ? DVBFE_HIERARCHY_ON : DVBFE_HIERARCHY_OFF;
                  if (ThisNIT >= 0) {
                     for (int n = 0; n < NumFrequencies; n++) {
                         if (ISTRANSPONDER(Frequencies[n] / 1000000, Transponder())) {
@@ -272,14 +264,14 @@
                                   }
                               }
                            if (ISTRANSPONDER(Frequency / 1000000, Transponder())) // only modify channels if we're actually receiving this transponder
-                              Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode, Alpha, Priority);
+                              Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode);
                            }
                         }
                     if (!found) {
                        for (int n = 0; n < NumFrequencies; n++) {
                            cChannel *Channel = new cChannel;
                            Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
-                           if (Channel->SetTerrTransponderData(Source, Frequencies[n], Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode, Alpha, Priority))
+                           if (Channel->SetTerrTransponderData(Source, Frequencies[n], Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode))
                               EITScanner.AddTransponder(Channel);
                            else
                               delete Channel;
diff -ruN vdr-1.5.14/osdbase.c vdr-1.5.15/osdbase.c
--- vdr-1.5.14/osdbase.c	2007-06-09 12:07:46.000000000 +0200
+++ vdr-1.5.15/osdbase.c	2008-02-17 12:33:04.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osdbase.c 1.31 2007/06/09 10:07:46 kls Exp $
+ * $Id: osdbase.c 1.32 2008/02/17 11:33:04 kls Exp $
  */
 
 #include "osdbase.h"
@@ -236,6 +236,7 @@
          i++;
          }
      }
+  displayMenu->SetScrollbar(count, first);
   if (!isempty(status))
      displayMenu->SetMessage(mtStatus, status);
 }
diff -ruN vdr-1.5.14/pat.c vdr-1.5.15/pat.c
--- vdr-1.5.14/pat.c	2008-01-27 14:53:43.000000000 +0100
+++ vdr-1.5.15/pat.c	2008-02-08 14:48:31.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: pat.c 1.19 2008/01/27 13:53:43 kls Exp $
+ * $Id: pat.c 1.20 2008/02/08 13:48:31 kls Exp $
  */
 
 #include "pat.h"
@@ -343,7 +343,6 @@
             switch (stream.getStreamType()) {
               case 1: // STREAMTYPE_11172_VIDEO
               case 2: // STREAMTYPE_13818_VIDEO
-//TODO        case 0x1B: // MPEG4
                       Vpid = stream.getPid();
                       break;
               case 3: // STREAMTYPE_11172_AUDIO
diff -ruN vdr-1.5.14/player.h vdr-1.5.15/player.h
--- vdr-1.5.14/player.h	2007-10-13 14:18:10.000000000 +0200
+++ vdr-1.5.15/player.h	2008-02-16 14:50:11.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: player.h 1.20 2007/10/13 12:18:10 kls Exp $
+ * $Id: player.h 1.21 2008/02/16 13:50:11 kls Exp $
  */
 
 #ifndef __PLAYER_H
@@ -22,6 +22,7 @@
   void DeviceClrAvailableTracks(bool DescriptionsOnly = false) { if (device) device->ClrAvailableTracks(DescriptionsOnly); }
   bool DeviceSetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, const char *Description = NULL) { return device ? device->SetAvailableTrack(Type, Index, Id, Language, Description) : false; }
   bool DeviceSetCurrentAudioTrack(eTrackType Type) { return device ? device->SetCurrentAudioTrack(Type) : false; }
+  bool DeviceSetCurrentSubtitleTrack(eTrackType Type) { return device ? device->SetCurrentSubtitleTrack(Type) : false; }
   bool DevicePoll(cPoller &Poller, int TimeoutMs = 0) { return device ? device->Poll(Poller, TimeoutMs) : false; }
   bool DeviceFlush(int TimeoutMs = 0) { return device ? device->Flush(TimeoutMs) : true; }
   bool DeviceHasIBPTrickSpeed(void) { return device ? device->HasIBPTrickSpeed() : false; }
@@ -58,6 +59,10 @@
        // Sets the current audio track to the given value.
        // This is just a virtual hook for players that need to do special things
        // in order to switch audio tracks.
+  virtual void SetSubtitleTrack(eTrackType Type, const tTrackId *TrackId) {}
+       // Sets the current subtitle track to the given value.
+       // This is just a virtual hook for players that need to do special things
+       // in order to switch subtitle tracks.
   };
 
 class cControl : public cOsdObject {
diff -ruN vdr-1.5.14/plugin.c vdr-1.5.15/plugin.c
--- vdr-1.5.14/plugin.c	2007-08-05 14:48:50.000000000 +0200
+++ vdr-1.5.15/plugin.c	2008-02-17 14:32:12.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: plugin.c 1.26 2007/08/05 12:48:50 kls Exp $
+ * $Id: plugin.c 1.28 2008/02/17 13:32:12 kls Exp $
  */
 
 #include "plugin.h"
@@ -142,12 +142,11 @@
 
 const char *cPlugin::ConfigDirectory(const char *PluginName)
 {
-  static char *buffer = NULL;
+  static cString buffer;
   if (!cThread::IsMainThread())
      esyslog("ERROR: plugin '%s' called cPlugin::ConfigDirectory(), which is not thread safe!", PluginName ? PluginName : "<no name given>");
-  free(buffer);
-  asprintf(&buffer, "%s/plugins%s%s", configDirectory, PluginName ? "/" : "", PluginName ? PluginName : "");
-  return MakeDirs(buffer, true) ? buffer : NULL;
+  buffer = cString::sprintf("%s/plugins%s%s", configDirectory, PluginName ? "/" : "", PluginName ? PluginName : "");
+  return MakeDirs(buffer, true) ? *buffer : NULL;
 }
 
 // --- cDll ------------------------------------------------------------------
@@ -317,10 +316,7 @@
   char *p = strchr(s, ' ');
   if (p)
      *p = 0;
-  char *buffer = NULL;
-  asprintf(&buffer, "%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, APIVERSION);
-  dlls.Add(new cDll(buffer, Args));
-  free(buffer);
+  dlls.Add(new cDll(cString::sprintf("%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, APIVERSION), Args));
   free(s);
 }
 
diff -ruN vdr-1.5.14/po/ca_ES.po vdr-1.5.15/po/ca_ES.po
--- vdr-1.5.14/po/ca_ES.po	2008-01-27 15:15:24.000000000 +0100
+++ vdr-1.5.15/po/ca_ES.po	2008-02-17 14:45:13.000000000 +0100
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Jordi Vilà <jvila@tinet.org>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -17,21 +17,6 @@
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "off"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "cap"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Canal incorrecte ***"
 
@@ -230,12 +215,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disc"
+
+msgid "free"
+msgstr "lliure"
+
 msgid "Free To Air"
 msgstr ""
 
 msgid "encrypted"
 msgstr ""
 
+msgid "auto"
+msgstr "auto"
+
 msgid "Edit channel"
 msgstr "Editar canal"
 
@@ -284,18 +278,21 @@
 msgid "Polarization"
 msgstr "Polarització"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversió"
 
+msgid "off"
+msgstr "off"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "cap"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -314,15 +311,6 @@
 msgid "Hierarchy"
 msgstr "Jerarquia"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioritat"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Propietats del canal duplicades!"
 
@@ -368,6 +356,9 @@
 msgid "VPS"
 msgstr ""
 
+msgid "Priority"
+msgstr "Prioritat"
+
 msgid "Lifetime"
 msgstr "Durada"
 
@@ -821,12 +812,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disc"
-
-msgid "free"
-msgstr "lliure"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Aturar la reproducció"
@@ -908,9 +893,6 @@
 msgid "Button$Insert"
 msgstr "Inserir"
 
-msgid "auto"
-msgstr "auto"
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -991,7 +973,7 @@
 msgid "Sunday"
 msgstr "Diumenge"
 
-msgid "Upcoming VPS recording!"
+msgid "Upcoming recording!"
 msgstr ""
 
 msgid "Recording started"
diff -ruN vdr-1.5.14/po/cs_CZ.po vdr-1.5.15/po/cs_CZ.po
--- vdr-1.5.14/po/cs_CZ.po	2008-01-27 15:15:42.000000000 +0100
+++ vdr-1.5.15/po/cs_CZ.po	2008-02-17 14:45:13.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Vladimír Bárta <vladimir.barta@k2atmitec.cz>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "vyp."
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "¾ádný"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Neplatný kanál ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "volno"
+
 msgid "Free To Air"
 msgstr "volný"
 
 msgid "encrypted"
 msgstr "kódovaný"
 
+msgid "auto"
+msgstr "auto"
+
 msgid "Edit channel"
 msgstr "Editace kanálu"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "Polarizace"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "vyp."
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "¾ádný"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "Hierarchy"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Priorita"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Nastavení kanálù nejsou unikátní!"
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Priorita"
+
 msgid "Lifetime"
 msgstr "®ivotnost"
 
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "volno"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Zastavit pøehrávání"
@@ -906,9 +891,6 @@
 msgid "Button$Insert"
 msgstr "Vlo¾it"
 
-msgid "auto"
-msgstr "auto"
-
 msgid "Plugin"
 msgstr "Modul"
 
@@ -989,8 +971,8 @@
 msgid "Sunday"
 msgstr "Nedìle"
 
-msgid "Upcoming VPS recording!"
-msgstr "Brzo zaène nahrávání VPS!"
+msgid "Upcoming recording!"
+msgstr "Brzo zaène nahrávání!"
 
 msgid "Recording started"
 msgstr "Zaèalo nahrávání"
diff -ruN vdr-1.5.14/po/da_DK.po vdr-1.5.15/po/da_DK.po
--- vdr-1.5.14/po/da_DK.po	2008-01-27 15:16:11.000000000 +0100
+++ vdr-1.5.15/po/da_DK.po	2008-02-17 14:45:14.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Mogens Elneff <mogens@elneff.dk>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "fra"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "ingen"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Ugyldig kanal! ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "fri"
+
 msgid "Free To Air"
 msgstr "Free To Air"
 
 msgid "encrypted"
 msgstr "kodet"
 
+msgid "auto"
+msgstr "automatisk"
+
 msgid "Edit channel"
 msgstr "Rediger kanal"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "Polarisation"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "fra"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "ingen"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "Hierarki"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioritet"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Kanalindstillinger er ikke entydige!"
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioritet"
+
 msgid "Lifetime"
 msgstr "Levetid"
 
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "fri"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Stop afspilning"
@@ -906,9 +891,6 @@
 msgid "Button$Insert"
 msgstr "Indsæt"
 
-msgid "auto"
-msgstr "automatisk"
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -989,8 +971,8 @@
 msgid "Sunday"
 msgstr "Søndag"
 
-msgid "Upcoming VPS recording!"
-msgstr "VPS optagelse starter snart!"
+msgid "Upcoming recording!"
+msgstr "Optagelse starter snart!"
 
 msgid "Recording started"
 msgstr "Optagelse startet"
diff -ruN vdr-1.5.14/po/de_DE.po vdr-1.5.15/po/de_DE.po
--- vdr-1.5.14/po/de_DE.po	2008-01-27 15:16:13.000000000 +0100
+++ vdr-1.5.15/po/de_DE.po	2008-02-17 14:45:14.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-11-25 15:19+0200\n"
 "Last-Translator: Klaus Schmidinger <kls@cadsoft.de>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "aus"
-
-msgid "on"
-msgstr "ein"
-
-msgid "none"
-msgstr "keine"
-
-msgid "high"
-msgstr "hoch"
-
-msgid "low"
-msgstr "niedrig"
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Ungültiger Kanal ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr "Benutzer9"
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "frei"
+
 msgid "Free To Air"
 msgstr "frei empfangbar"
 
 msgid "encrypted"
 msgstr "verschlüsselt"
 
+msgid "auto"
+msgstr "auto"
+
 msgid "Edit channel"
 msgstr "Kanal editieren"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "Polarisation"
 
-msgid "System"
-msgstr "System"
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "aus"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "keine"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "Hierarchie"
 
-msgid "Alpha"
-msgstr "Alpha"
-
-msgid "Priority"
-msgstr "Priorität"
-
-msgid "Rolloff"
-msgstr "Rolloff"
-
 msgid "Channel settings are not unique!"
 msgstr "Kanaleinstellungen sind nicht eindeutig!"
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Priorität"
+
 msgid "Lifetime"
 msgstr "Lebensdauer"
 
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "frei"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Wiedergabe beenden"
@@ -906,9 +891,6 @@
 msgid "Button$Insert"
 msgstr "Einfügen"
 
-msgid "auto"
-msgstr "auto"
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -989,8 +971,8 @@
 msgid "Sunday"
 msgstr "Sonntag"
 
-msgid "Upcoming VPS recording!"
-msgstr "VPS-Aufnahme beginnt in Kürze!"
+msgid "Upcoming recording!"
+msgstr "Aufnahme beginnt in Kürze!"
 
 msgid "Recording started"
 msgstr "Aufzeichnung gestartet"
diff -ruN vdr-1.5.14/po/el_GR.po vdr-1.5.15/po/el_GR.po
--- vdr-1.5.14/po/el_GR.po	2008-01-27 15:16:23.000000000 +0100
+++ vdr-1.5.15/po/el_GR.po	2008-02-17 14:45:14.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-7\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "êëåéóôü"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "êáíÝíá"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Áêõñï êáíÜëç ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Äßóêïò"
+
+msgid "free"
+msgstr "Åëåýèåñïò"
+
 msgid "Free To Air"
 msgstr ""
 
 msgid "encrypted"
 msgstr ""
 
+msgid "auto"
+msgstr "áõôüìáôï"
+
 msgid "Edit channel"
 msgstr "Ôñïðïðïßçóç Êáíáëéïý"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "Ðüëùóç"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "ÁíôéóôñïöÞ"
 
+msgid "off"
+msgstr "êëåéóôü"
+
 msgid "CoderateH"
 msgstr "Ñõèìüò Êþäéêá H"
 
+msgid "none"
+msgstr "êáíÝíá"
+
 msgid "CoderateL"
 msgstr "Ñõèìüò Êþäéêá L"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "Éåñáñ÷åßá"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Ðñïôåñáéüôçôá"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Ïé ñéèìýóåéò ôïí êáíáëéþí áëëõëïóõìðßðôïõí!"
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Ðñïôåñáéüôçôá"
+
 msgid "Lifetime"
 msgstr "ÄéÝñêåéá ÐáñáìïíÞò"
 
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Äßóêïò"
-
-msgid "free"
-msgstr "Åëåýèåñïò"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " ÔÝëïò áíáðáñáãùãÞò"
@@ -906,9 +891,6 @@
 msgid "Button$Insert"
 msgstr "ÅéóáãùãÞ"
 
-msgid "auto"
-msgstr "áõôüìáôï"
-
 msgid "Plugin"
 msgstr "ÅðÝêôáóç"
 
@@ -989,7 +971,7 @@
 msgid "Sunday"
 msgstr "ÊõñéáêÞ"
 
-msgid "Upcoming VPS recording!"
+msgid "Upcoming recording!"
 msgstr ""
 
 msgid "Recording started"
diff -ruN vdr-1.5.14/po/es_ES.po vdr-1.5.15/po/es_ES.po
--- vdr-1.5.14/po/es_ES.po	2008-01-27 15:16:34.000000000 +0100
+++ vdr-1.5.15/po/es_ES.po	2008-02-17 14:45:14.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Ruben Nunez Francisco <ruben.nunez@tang-it.com>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "off"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "ninguno"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Canal no válido ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disco"
+
+msgid "free"
+msgstr "libre"
+
 msgid "Free To Air"
 msgstr "en abierto"
 
 msgid "encrypted"
 msgstr "cifrado"
 
+msgid "auto"
+msgstr "auto"
+
 msgid "Edit channel"
 msgstr "Modificar canal"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "Polarización"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "T.símbolos"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "off"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "ninguno"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "Jerarquía"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioridad"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "!Propiedades de canal duplicadas!"
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioridad"
+
 msgid "Lifetime"
 msgstr "Duración"
 
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disco"
-
-msgid "free"
-msgstr "libre"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Parar reprodución"
@@ -906,9 +891,6 @@
 msgid "Button$Insert"
 msgstr "Insertar"
 
-msgid "auto"
-msgstr "auto"
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -989,7 +971,7 @@
 msgid "Sunday"
 msgstr "Domingo"
 
-msgid "Upcoming VPS recording!"
+msgid "Upcoming recording!"
 msgstr ""
 
 msgid "Recording started"
diff -ruN vdr-1.5.14/po/et_EE.po vdr-1.5.15/po/et_EE.po
--- vdr-1.5.14/po/et_EE.po	2008-01-27 15:16:43.000000000 +0100
+++ vdr-1.5.15/po/et_EE.po	2008-02-17 14:45:14.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Arthur Konovalov <kasjas@hot.ee>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-13\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "väljas"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "puudu"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Vigane kanal ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr "Lisaklahv9"
 
+msgid "Disk"
+msgstr "Ketas"
+
+msgid "free"
+msgstr "vaba"
+
 msgid "Free To Air"
 msgstr "FTA"
 
 msgid "encrypted"
 msgstr "krüptitud"
 
+msgid "auto"
+msgstr "automaatne"
+
 msgid "Edit channel"
 msgstr "Kanali muutmine"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "Polarisatsioon"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversioon"
 
+msgid "off"
+msgstr "väljas"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "puudu"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "Hierarhia"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioriteet"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Kanaliseaded ei ole unikaalsed!"
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioriteet"
+
 msgid "Lifetime"
 msgstr "Eluiga"
 
@@ -792,7 +783,7 @@
 msgstr "Helitugevus käivitamisel"
 
 msgid "Setup.Miscellaneous$Emergency exit"
-msgstr ""
+msgstr "Hädaväljumine"
 
 msgid "Plugins"
 msgstr "Laiendusmoodulid"
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Ketas"
-
-msgid "free"
-msgstr "vaba"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Lõpetada taasesitamine"
@@ -906,9 +891,6 @@
 msgid "Button$Insert"
 msgstr "Lisa (INS)"
 
-msgid "auto"
-msgstr "automaatne"
-
 msgid "Plugin"
 msgstr "Laiendusmoodul"
 
@@ -989,8 +971,8 @@
 msgid "Sunday"
 msgstr "Pühapäev"
 
-msgid "Upcoming VPS recording!"
-msgstr "VPS salvestamine tulekul!"
+msgid "Upcoming recording!"
+msgstr "Salvestamine tulekul!"
 
 msgid "Recording started"
 msgstr "Salvestamine algas"
diff -ruN vdr-1.5.14/po/fi_FI.po vdr-1.5.15/po/fi_FI.po
--- vdr-1.5.14/po/fi_FI.po	2008-01-27 15:16:56.000000000 +0100
+++ vdr-1.5.15/po/fi_FI.po	2008-02-17 14:45:14.000000000 +0100
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-15 15:52+0200\n"
 "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -18,21 +18,6 @@
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "pois"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "tyhjä"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Virheellinen kanavavalinta ***"
 
@@ -231,12 +216,21 @@
 msgid "Key$User9"
 msgstr "Lisänäppäin 9"
 
+msgid "Disk"
+msgstr "Levy"
+
+msgid "free"
+msgstr "vapaana"
+
 msgid "Free To Air"
 msgstr "vapaa"
 
 msgid "encrypted"
 msgstr "salattu"
 
+msgid "auto"
+msgstr "auto"
+
 msgid "Edit channel"
 msgstr "Muokkaa kanavaa"
 
@@ -285,18 +279,21 @@
 msgid "Polarization"
 msgstr "Polarisaatio"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Symbolinopeus"
 
 msgid "Inversion"
 msgstr "Inversio"
 
+msgid "off"
+msgstr "pois"
+
 msgid "CoderateH"
 msgstr "Suojaustaso (HP)"
 
+msgid "none"
+msgstr "tyhjä"
+
 msgid "CoderateL"
 msgstr "Suojaustaso (LP)"
 
@@ -315,15 +312,6 @@
 msgid "Hierarchy"
 msgstr "Hierarkia"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioriteetti"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Kanava-asetukset eivät ole yksilölliset!"
 
@@ -369,6 +357,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioriteetti"
+
 msgid "Lifetime"
 msgstr "Elinikä"
 
@@ -822,12 +813,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Levy"
-
-msgid "free"
-msgstr "vapaana"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Lopeta toisto"
@@ -909,9 +894,6 @@
 msgid "Button$Insert"
 msgstr "Lisää"
 
-msgid "auto"
-msgstr "auto"
-
 msgid "Plugin"
 msgstr "Laajennos"
 
@@ -992,8 +974,8 @@
 msgid "Sunday"
 msgstr "Sunnuntai"
 
-msgid "Upcoming VPS recording!"
-msgstr "VPS-tallennus on alkamassa!"
+msgid "Upcoming recording!"
+msgstr "Tallennus on alkamassa!"
 
 msgid "Recording started"
 msgstr "Tallennus aloitettu"
diff -ruN vdr-1.5.14/po/fr_FR.po vdr-1.5.15/po/fr_FR.po
--- vdr-1.5.14/po/fr_FR.po	2008-01-27 15:17:06.000000000 +0100
+++ vdr-1.5.15/po/fr_FR.po	2008-02-17 14:45:14.000000000 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-10-18 16:12+0100\n"
 "Last-Translator: Michael Nival <mnival@club-internet.fr>\n"
 "Language-Team:  <vdr@linuxtv.org>\n"
@@ -21,21 +21,6 @@
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "off"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "aucun"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Chaîne invalide ! ***"
 
@@ -234,12 +219,21 @@
 msgid "Key$User9"
 msgstr "Utilisateur9"
 
+msgid "Disk"
+msgstr "Disque"
+
+msgid "free"
+msgstr "restant"
+
 msgid "Free To Air"
 msgstr "Aucun cryptage"
 
 msgid "encrypted"
 msgstr "Crypté"
 
+msgid "auto"
+msgstr "auto"
+
 msgid "Edit channel"
 msgstr "Modifier une chaîne"
 
@@ -288,18 +282,21 @@
 msgid "Polarization"
 msgstr "Polarisation"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Fréq. Symbole"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "off"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "aucun"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -318,15 +315,6 @@
 msgid "Hierarchy"
 msgstr "Hiérarchie"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Priorité"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Caractéristiques des chaînes non uniques"
 
@@ -372,6 +360,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Priorité"
+
 msgid "Lifetime"
 msgstr "Durée de vie"
 
@@ -825,12 +816,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disque"
-
-msgid "free"
-msgstr "restant"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Arrêter la lecture"
@@ -912,9 +897,6 @@
 msgid "Button$Insert"
 msgstr "Insérer"
 
-msgid "auto"
-msgstr "auto"
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -995,8 +977,8 @@
 msgid "Sunday"
 msgstr "Dimanche"
 
-msgid "Upcoming VPS recording!"
-msgstr "Enregistrement VPS commence prochaînement"
+msgid "Upcoming recording!"
+msgstr "Enregistrement commence prochaînement"
 
 msgid "Recording started"
 msgstr "Enregistrement a commencé"
diff -ruN vdr-1.5.14/po/hr_HR.po vdr-1.5.15/po/hr_HR.po
--- vdr-1.5.14/po/hr_HR.po	2008-01-27 15:17:19.000000000 +0100
+++ vdr-1.5.15/po/hr_HR.po	2008-02-17 14:45:14.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Drazen Dupor <drazen.dupor@dupor.com>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -16,21 +16,6 @@
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "ugasi"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "nijedan"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Neispravan program ***"
 
@@ -229,12 +214,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "slobodno"
+
 msgid "Free To Air"
 msgstr ""
 
 msgid "encrypted"
 msgstr ""
 
+msgid "auto"
+msgstr "automatski"
+
 msgid "Edit channel"
 msgstr "Ureðivanje programa"
 
@@ -283,18 +277,21 @@
 msgid "Polarization"
 msgstr "Polarizacija"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inverzija"
 
+msgid "off"
+msgstr "ugasi"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "nijedan"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -313,15 +310,6 @@
 msgid "Hierarchy"
 msgstr "Hijerarhija"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioritet"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Parametri programa nisu jednoznaèni!"
 
@@ -367,6 +355,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioritet"
+
 msgid "Lifetime"
 msgstr "Trajanje"
 
@@ -820,12 +811,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "slobodno"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Prekini reprodukciju"
@@ -907,9 +892,6 @@
 msgid "Button$Insert"
 msgstr "Umetni"
 
-msgid "auto"
-msgstr "automatski"
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -990,7 +972,7 @@
 msgid "Sunday"
 msgstr "Nedjelja"
 
-msgid "Upcoming VPS recording!"
+msgid "Upcoming recording!"
 msgstr ""
 
 msgid "Recording started"
diff -ruN vdr-1.5.14/po/hu_HU.po vdr-1.5.15/po/hu_HU.po
--- vdr-1.5.14/po/hu_HU.po	2008-01-27 15:17:31.000000000 +0100
+++ vdr-1.5.15/po/hu_HU.po	2008-02-17 14:45:14.000000000 +0100
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-12-01 21:42+0200\n"
 "Last-Translator: István Füley <ifuley@tigercomp.ro>\n"
 "Language-Team:  <vdr@linuxtv.org>\n"
@@ -18,21 +18,6 @@
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "ki"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "semmi"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Érvénytelen csatorna ***"
 
@@ -231,12 +216,21 @@
 msgid "Key$User9"
 msgstr "Felhasználó9"
 
+msgid "Disk"
+msgstr "Lemez"
+
+msgid "free"
+msgstr "szabad"
+
 msgid "Free To Air"
 msgstr "Kódolatlan"
 
 msgid "encrypted"
 msgstr "Kódolt"
 
+msgid "auto"
+msgstr "auto"
+
 msgid "Edit channel"
 msgstr "Csatornák beállítása"
 
@@ -285,18 +279,21 @@
 msgid "Polarization"
 msgstr "Polarizáció"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "ki"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "semmi"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -315,15 +312,6 @@
 msgid "Hierarchy"
 msgstr "Hierarhia"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioritás"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Az adóbeállítások nem egyértelmûek"
 
@@ -369,6 +357,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioritás"
+
 msgid "Lifetime"
 msgstr "Élettartam"
 
@@ -823,12 +814,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Lemez"
-
-msgid "free"
-msgstr "szabad"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Lejátszást befejzni"
@@ -910,9 +895,6 @@
 msgid "Button$Insert"
 msgstr "Beilleszteni"
 
-msgid "auto"
-msgstr "auto"
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -993,8 +975,8 @@
 msgid "Sunday"
 msgstr "Vasárnap"
 
-msgid "Upcoming VPS recording!"
-msgstr "VPS-felvétel rögtön kezdõdik!"
+msgid "Upcoming recording!"
+msgstr "Felvétel rögtön kezdõdik!"
 
 msgid "Recording started"
 msgstr "A felvétel elindítva"
diff -ruN vdr-1.5.14/po/it_IT.po vdr-1.5.15/po/it_IT.po
--- vdr-1.5.14/po/it_IT.po	2008-01-27 15:17:40.000000000 +0100
+++ vdr-1.5.15/po/it_IT.po	2008-02-17 14:45:14.000000000 +0100
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-10-16 02:15+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
 "Language-Team:  <vdr@linuxtv.org>\n"
@@ -18,21 +18,6 @@
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "off"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "nessuno"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Canale NON valido ***"
 
@@ -231,12 +216,21 @@
 msgid "Key$User9"
 msgstr "Utente9"
 
+msgid "Disk"
+msgstr "Disco"
+
+msgid "free"
+msgstr "liberi"
+
 msgid "Free To Air"
 msgstr "in chiaro"
 
 msgid "encrypted"
 msgstr "criptato"
 
+msgid "auto"
+msgstr "automatico"
+
 msgid "Edit channel"
 msgstr "Modifica canale"
 
@@ -285,18 +279,21 @@
 msgid "Polarization"
 msgstr "Polarizzazione"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "SymbolRate"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "off"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "nessuno"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -315,15 +312,6 @@
 msgid "Hierarchy"
 msgstr "Hierarchy"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Priorità"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Parametri canale non univoci!"
 
@@ -369,6 +357,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Priorità"
+
 msgid "Lifetime"
 msgstr "Durata"
 
@@ -822,12 +813,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disco"
-
-msgid "free"
-msgstr "liberi"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Ferma riproduzione"
@@ -909,9 +894,6 @@
 msgid "Button$Insert"
 msgstr "Inserisci"
 
-msgid "auto"
-msgstr "automatico"
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -992,8 +974,8 @@
 msgid "Sunday"
 msgstr "Domenica"
 
-msgid "Upcoming VPS recording!"
-msgstr "Registrazione VPS imminente!"
+msgid "Upcoming recording!"
+msgstr "Registrazione imminente!"
 
 msgid "Recording started"
 msgstr "Registrazione avviata"
diff -ruN vdr-1.5.14/po/nl_NL.po vdr-1.5.15/po/nl_NL.po
--- vdr-1.5.14/po/nl_NL.po	2008-01-27 15:17:49.000000000 +0100
+++ vdr-1.5.15/po/nl_NL.po	2008-02-17 14:45:14.000000000 +0100
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Maarten Wisse <Maarten.Wisse@urz.uni-hd.de>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -17,21 +17,6 @@
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "uit"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "geen"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Ongeldig kanaal ***"
 
@@ -230,12 +215,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "vrij"
+
 msgid "Free To Air"
 msgstr ""
 
 msgid "encrypted"
 msgstr ""
 
+msgid "auto"
+msgstr "auto"
+
 msgid "Edit channel"
 msgstr "Kanaal aanpassen"
 
@@ -284,18 +278,21 @@
 msgid "Polarization"
 msgstr "Polarisatie"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "uit"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "geen"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -314,15 +311,6 @@
 msgid "Hierarchy"
 msgstr "Hierarchy"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioriteit"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Kanaalinstellingen zijn niet uniek!"
 
@@ -368,6 +356,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioriteit"
+
 msgid "Lifetime"
 msgstr "Bewaarduur"
 
@@ -821,12 +812,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "vrij"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Stop afspelen"
@@ -908,9 +893,6 @@
 msgid "Button$Insert"
 msgstr "Invoegen"
 
-msgid "auto"
-msgstr "auto"
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -991,7 +973,7 @@
 msgid "Sunday"
 msgstr "Zondag"
 
-msgid "Upcoming VPS recording!"
+msgid "Upcoming recording!"
 msgstr ""
 
 msgid "Recording started"
diff -ruN vdr-1.5.14/po/nn_NO.po vdr-1.5.15/po/nn_NO.po
--- vdr-1.5.14/po/nn_NO.po	2008-01-27 15:17:52.000000000 +0100
+++ vdr-1.5.15/po/nn_NO.po	2008-02-17 14:45:14.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Truls Slevigen <truls@slevigen.no>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -16,21 +16,6 @@
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr ""
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr ""
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Ugyldig Kanal! ***"
 
@@ -229,12 +214,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "ledig"
+
 msgid "Free To Air"
 msgstr ""
 
 msgid "encrypted"
 msgstr ""
 
+msgid "auto"
+msgstr ""
+
 msgid "Edit channel"
 msgstr "Editer kanal"
 
@@ -283,18 +277,21 @@
 msgid "Polarization"
 msgstr "Polarisasjon"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr ""
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr ""
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -313,15 +310,6 @@
 msgid "Hierarchy"
 msgstr "Hierarchy"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioritet"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr ""
 
@@ -367,6 +355,9 @@
 msgid "VPS"
 msgstr ""
 
+msgid "Priority"
+msgstr "Prioritet"
+
 msgid "Lifetime"
 msgstr "Levetid"
 
@@ -820,12 +811,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "ledig"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Stopp avspilling"
@@ -907,9 +892,6 @@
 msgid "Button$Insert"
 msgstr ""
 
-msgid "auto"
-msgstr ""
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -990,7 +972,7 @@
 msgid "Sunday"
 msgstr "Søndag"
 
-msgid "Upcoming VPS recording!"
+msgid "Upcoming recording!"
 msgstr ""
 
 msgid "Recording started"
diff -ruN vdr-1.5.14/po/pl_PL.po vdr-1.5.15/po/pl_PL.po
--- vdr-1.5.14/po/pl_PL.po	2008-01-27 15:18:01.000000000 +0100
+++ vdr-1.5.15/po/pl_PL.po	2008-02-17 14:45:14.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Michael Rakowski <mrak@gmx.de>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "wy³±cz"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "brak"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Niepoprawny kana³ ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Dysk"
+
+msgid "free"
+msgstr "wolnego"
+
 msgid "Free To Air"
 msgstr "nieszyfrowany"
 
 msgid "encrypted"
 msgstr "szyfrowany"
 
+msgid "auto"
+msgstr "auto"
+
 msgid "Edit channel"
 msgstr "Edycja kana³u"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "Polaryzacja"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inwersja"
 
+msgid "off"
+msgstr "wy³±cz"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "brak"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "Hierarchia"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Priorytet"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Ustawienia kana³u nie s± unikalne!"
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Priorytet"
+
 msgid "Lifetime"
 msgstr "Czas ¿ycia"
 
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Dysk"
-
-msgid "free"
-msgstr "wolnego"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Zatrzymaj odtwarzanie"
@@ -906,9 +891,6 @@
 msgid "Button$Insert"
 msgstr "Wstaw"
 
-msgid "auto"
-msgstr "auto"
-
 msgid "Plugin"
 msgstr "Wtyczka"
 
@@ -989,8 +971,8 @@
 msgid "Sunday"
 msgstr "Niedziela"
 
-msgid "Upcoming VPS recording!"
-msgstr "Wkrótce nagranie VPS!"
+msgid "Upcoming recording!"
+msgstr "Wkrótce nagranie!"
 
 msgid "Recording started"
 msgstr "Rozpoczêto nagrywanie"
diff -ruN vdr-1.5.14/po/pt_PT.po vdr-1.5.15/po/pt_PT.po
--- vdr-1.5.14/po/pt_PT.po	2008-01-27 15:18:19.000000000 +0100
+++ vdr-1.5.15/po/pt_PT.po	2008-02-17 14:45:14.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Paulo Lopes <pmml@netvita.pt>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "off"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr ""
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Canal Inválido! ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "livre"
+
 msgid "Free To Air"
 msgstr ""
 
 msgid "encrypted"
 msgstr ""
 
+msgid "auto"
+msgstr ""
+
 msgid "Edit channel"
 msgstr "Modificar canal"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "Polarização"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "off"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr ""
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "Hierarchy"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioridade"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr ""
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr ""
 
+msgid "Priority"
+msgstr "Prioridade"
+
 msgid "Lifetime"
 msgstr "Duração"
 
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "livre"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Parar reprodução"
@@ -906,9 +891,6 @@
 msgid "Button$Insert"
 msgstr ""
 
-msgid "auto"
-msgstr ""
-
 msgid "Plugin"
 msgstr "Plugin"
 
@@ -989,7 +971,7 @@
 msgid "Sunday"
 msgstr "Domingo"
 
-msgid "Upcoming VPS recording!"
+msgid "Upcoming recording!"
 msgstr ""
 
 msgid "Recording started"
diff -ruN vdr-1.5.14/po/ro_RO.po vdr-1.5.15/po/ro_RO.po
--- vdr-1.5.14/po/ro_RO.po	2008-01-27 15:18:31.000000000 +0100
+++ vdr-1.5.15/po/ro_RO.po	2008-02-17 14:45:14.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -16,21 +16,6 @@
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "inactiv"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "niciuna(ul)"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Canal invalid ***"
 
@@ -229,12 +214,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disc"
+
+msgid "free"
+msgstr "liber"
+
 msgid "Free To Air"
 msgstr "FTA (necriptat)"
 
 msgid "encrypted"
 msgstr "criptat"
 
+msgid "auto"
+msgstr "automat"
+
 msgid "Edit channel"
 msgstr "Modificare canal"
 
@@ -283,18 +277,21 @@
 msgid "Polarization"
 msgstr "Polarizare"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Ratã simboluri"
 
 msgid "Inversion"
 msgstr "Inversiune"
 
+msgid "off"
+msgstr "inactiv"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "niciuna(ul)"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -313,15 +310,6 @@
 msgid "Hierarchy"
 msgstr "Ierarhie"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioritate"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Parametrii canalului nu sunt univoci!"
 
@@ -367,6 +355,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioritate"
+
 msgid "Lifetime"
 msgstr "Timp de pãstrare"
 
@@ -820,12 +811,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disc"
-
-msgid "free"
-msgstr "liber"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Opreºte redarea"
@@ -907,9 +892,6 @@
 msgid "Button$Insert"
 msgstr "Insereazã"
 
-msgid "auto"
-msgstr "automat"
-
 msgid "Plugin"
 msgstr "Plugin (modul adiþional)"
 
@@ -990,8 +972,8 @@
 msgid "Sunday"
 msgstr "Duminicã"
 
-msgid "Upcoming VPS recording!"
-msgstr "Urmeazã o înregistrare VPS!"
+msgid "Upcoming recording!"
+msgstr "Urmeazã o înregistrare!"
 
 msgid "Recording started"
 msgstr "A început înregistrarea"
diff -ruN vdr-1.5.14/po/ru_RU.po vdr-1.5.15/po/ru_RU.po
--- vdr-1.5.14/po/ru_RU.po	2008-01-27 15:18:41.000000000 +0100
+++ vdr-1.5.15/po/ru_RU.po	2008-02-17 14:45:14.000000000 +0100
@@ -8,29 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
-"PO-Revision-Date: 2007-11-05 14:24+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
+"PO-Revision-Date: 2008-02-15 16:37+0100\n"
 "Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
 "Language-Team:  <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-5\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "ÒëÚÛ"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "ÝØçÕÓÞ"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** ½ÕßàÐÒØÛìÝëÙ ÚÐÝÐÛ ***"
 
@@ -229,12 +214,21 @@
 msgid "Key$User9"
 msgstr "¿ÞÛì×ÞÒÐâÕÛì9"
 
+msgid "Disk"
+msgstr "´ØáÚ"
+
+msgid "free"
+msgstr "áÒÞÑÞÔÝÞ"
+
 msgid "Free To Air"
 msgstr "FTA (ÝÕ×ÐÚÞÔØàÞÒÐÝÞ)"
 
 msgid "encrypted"
 msgstr "×ÐÚÞÔØàÞÒÐÝÞ"
 
+msgid "auto"
+msgstr "ÐÒâÞ"
+
 msgid "Edit channel"
 msgstr "ÀÕÔÐÚâØàÞÒÐÝØÕ ÚÐÝÐÛÐ"
 
@@ -283,18 +277,21 @@
 msgid "Polarization"
 msgstr "¿ÞÛïàØ×ÐæØï"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "ÁØÜÒ. áÚÞàÞáâì"
 
 msgid "Inversion"
 msgstr "¸ÝÒÕàáØï"
 
+msgid "off"
+msgstr "ÒëÚÛ"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "ÝØçÕÓÞ"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -313,15 +310,6 @@
 msgid "Hierarchy"
 msgstr "¸ÕàÐàåØï"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "¿àØÞàØâÕâ"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "½ÐáâàÞÙÚØ ÚÐÝÐÛÐ ÝÕ ãÝØÚÐÛìÝë!"
 
@@ -367,6 +355,9 @@
 msgid "VPS"
 msgstr "VPS ßÞßàÐÒÚÐ"
 
+msgid "Priority"
+msgstr "¿àØÞàØâÕâ"
+
 msgid "Lifetime"
 msgstr "ÁàÞÚ åàÐÝÕÝØï"
 
@@ -793,7 +784,7 @@
 msgstr "³àÞÜÚÞáâì ßàØ ÒÚÛîçÕÝØØ"
 
 msgid "Setup.Miscellaneous$Emergency exit"
-msgstr ""
+msgstr "°ÒÐàØÙÝëÙ ÒëåÞÔ"
 
 msgid "Plugins"
 msgstr "¼ÞÔãÛØ àÐáèØàÕÝØï"
@@ -820,12 +811,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "´ØáÚ"
-
-msgid "free"
-msgstr "áÒÞÑÞÔÝÞ"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " ¿àÕÚàÐâØâì ÒÞáßàÞØ×ÒÕÔÕÝØÕ"
@@ -907,9 +892,6 @@
 msgid "Button$Insert"
 msgstr "²áâÐÒÚÐ"
 
-msgid "auto"
-msgstr "ÐÒâÞ"
-
 msgid "Plugin"
 msgstr "¼ÞÔãÛì"
 
@@ -990,8 +972,8 @@
 msgid "Sunday"
 msgstr "²ÞáÚàÕáÕÝìÕ"
 
-msgid "Upcoming VPS recording!"
-msgstr "VPS-·ÐßØáì áÚÞàÞ ÝÐçÝÕâáï"
+msgid "Upcoming recording!"
+msgstr "·ÐßØáì áÚÞàÞ ÝÐçÝÕâáï"
 
 msgid "Recording started"
 msgstr "·ÐßØáì ÝÐçÐâÐ"
diff -ruN vdr-1.5.14/po/sl_SI.po vdr-1.5.15/po/sl_SI.po
--- vdr-1.5.14/po/sl_SI.po	2008-01-27 15:18:50.000000000 +0100
+++ vdr-1.5.15/po/sl_SI.po	2008-02-17 14:45:14.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -16,21 +16,6 @@
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "izklop"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "nobeden"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Neznan kanal ***"
 
@@ -229,12 +214,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "prosto"
+
 msgid "Free To Air"
 msgstr "nekodiran"
 
 msgid "encrypted"
 msgstr "kodiran"
 
+msgid "auto"
+msgstr "avtomatsko"
+
 msgid "Edit channel"
 msgstr "Uredi kanal"
 
@@ -283,18 +277,21 @@
 msgid "Polarization"
 msgstr "Polarizacija"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inverzija"
 
+msgid "off"
+msgstr "izklop"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "nobeden"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -313,15 +310,6 @@
 msgid "Hierarchy"
 msgstr "Hierarhija"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioriteta"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Nastavitve kanala niso edinstvene!"
 
@@ -367,6 +355,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioriteta"
+
 msgid "Lifetime"
 msgstr "Veljavnost"
 
@@ -820,12 +811,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "prosto"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Prekini predvajanje"
@@ -907,9 +892,6 @@
 msgid "Button$Insert"
 msgstr "Vstavi"
 
-msgid "auto"
-msgstr "avtomatsko"
-
 msgid "Plugin"
 msgstr "Vstavek"
 
@@ -990,8 +972,8 @@
 msgid "Sunday"
 msgstr "Nedelja"
 
-msgid "Upcoming VPS recording!"
-msgstr "Sledi VPS snemanje!"
+msgid "Upcoming recording!"
+msgstr "Sledi snemanje!"
 
 msgid "Recording started"
 msgstr "Snemanje se je prièelo"
diff -ruN vdr-1.5.14/po/sv_SE.po vdr-1.5.15/po/sv_SE.po
--- vdr-1.5.14/po/sv_SE.po	2008-01-27 15:19:01.000000000 +0100
+++ vdr-1.5.15/po/sv_SE.po	2008-02-17 14:45:14.000000000 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Tomas Prybil <tomas@prybil.se>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -16,21 +16,6 @@
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "av"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "ingen"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Felaktig kanal ***"
 
@@ -229,12 +214,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "ledigt"
+
 msgid "Free To Air"
 msgstr "Okodad"
 
 msgid "encrypted"
 msgstr "krypterad"
 
+msgid "auto"
+msgstr "automatisk"
+
 msgid "Edit channel"
 msgstr "Ändra kanal"
 
@@ -283,18 +277,21 @@
 msgid "Polarization"
 msgstr "Polarisation"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Inversion"
 
+msgid "off"
+msgstr "av"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "ingen"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -313,15 +310,6 @@
 msgid "Hierarchy"
 msgstr "Hierarchy"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Prioritet"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Kanalinställningarna är ej unika!"
 
@@ -367,6 +355,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Prioritet"
+
 msgid "Lifetime"
 msgstr "Livstid"
 
@@ -820,12 +811,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "ledigt"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Avsluta uppspelning"
@@ -907,9 +892,6 @@
 msgid "Button$Insert"
 msgstr "Infoga"
 
-msgid "auto"
-msgstr "automatisk"
-
 msgid "Plugin"
 msgstr "Modul"
 
@@ -990,8 +972,8 @@
 msgid "Sunday"
 msgstr "Söndag"
 
-msgid "Upcoming VPS recording!"
-msgstr "strax VPS inspelning..."
+msgid "Upcoming recording!"
+msgstr "strax inspelning..."
 
 msgid "Recording started"
 msgstr "Inspelningen har startat"
diff -ruN vdr-1.5.14/po/tr_TR.po vdr-1.5.15/po/tr_TR.po
--- vdr-1.5.14/po/tr_TR.po	2008-01-27 15:19:10.000000000 +0100
+++ vdr-1.5.15/po/tr_TR.po	2008-02-17 14:45:14.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-24 14:37+0200\n"
 "Last-Translator: Oktay Yolgeçen <oktay_73@yahoo.de>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-9\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "kapalý"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "hiç"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** Geçersiz kanal ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr "Kullanýcý9"
 
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "boþ"
+
 msgid "Free To Air"
 msgstr "Þifresiz"
 
 msgid "encrypted"
 msgstr "Þifreli"
 
+msgid "auto"
+msgstr "otomatik"
+
 msgid "Edit channel"
 msgstr "Kanal ayarlarýný deðiþtir"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "Kutuplaþma"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "Srate"
 
 msgid "Inversion"
 msgstr "Ýnversiyon"
 
+msgid "off"
+msgstr "kapalý"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "hiç"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "Hiyerarþi"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "Öncelik"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "Kanal ayarlarý belli deðýl!"
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr "VPS"
 
+msgid "Priority"
+msgstr "Öncelik"
+
 msgid "Lifetime"
 msgstr "Ömrü"
 
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "Disk"
-
-msgid "free"
-msgstr "boþ"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " Gösteriþi bitir"
@@ -906,9 +891,6 @@
 msgid "Button$Insert"
 msgstr "Ekle"
 
-msgid "auto"
-msgstr "otomatik"
-
 msgid "Plugin"
 msgstr "Eklenti"
 
@@ -989,8 +971,8 @@
 msgid "Sunday"
 msgstr "Pazar"
 
-msgid "Upcoming VPS recording!"
-msgstr "VPS çekim yakýnda baþlýyor!"
+msgid "Upcoming recording!"
+msgstr "Çekim yakýnda baþlýyor!"
 
 msgid "Recording started"
 msgstr "Kayýt baþlandý"
diff -ruN vdr-1.5.14/po/uk_UA.po vdr-1.5.15/po/uk_UA.po
--- vdr-1.5.14/po/uk_UA.po	2008-01-27 15:19:21.000000000 +0100
+++ vdr-1.5.15/po/uk_UA.po	2008-02-17 14:45:14.000000000 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: VDR 1.5.10\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
-"POT-Creation-Date: 2008-01-27 15:00+0100\n"
+"POT-Creation-Date: 2008-02-10 12:22+0100\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Yarema Aka Knedlyk <yupadmin@gmail.com>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
@@ -15,21 +15,6 @@
 "Content-Type: text/plain; charset=ISO-8859-5\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-msgid "off"
-msgstr "ÒØÚÛ"
-
-msgid "on"
-msgstr ""
-
-msgid "none"
-msgstr "ÝöçÞÓÞ"
-
-msgid "high"
-msgstr ""
-
-msgid "low"
-msgstr ""
-
 msgid "*** Invalid Channel ***"
 msgstr "*** ½ÕßàÐÒØÛìÝØÙ ÚÐÝÐÛ ***"
 
@@ -228,12 +213,21 @@
 msgid "Key$User9"
 msgstr ""
 
+msgid "Disk"
+msgstr "´ØáÚ"
+
+msgid "free"
+msgstr "ÒöÛìÝÞ"
+
 msgid "Free To Air"
 msgstr "FTA (ÝÕ×ÐÚÞÔÞÒÐÝÞ)"
 
 msgid "encrypted"
 msgstr "×ÐÚÞÔÞÒÐÝÞ"
 
+msgid "auto"
+msgstr "ÐÒâÞ"
+
 msgid "Edit channel"
 msgstr "ÀÕÔÐÚâãÒÐÝÝï ÚÐÝÐÛã"
 
@@ -282,18 +276,21 @@
 msgid "Polarization"
 msgstr "¿ÞÛïàØ×Ðæöï"
 
-msgid "System"
-msgstr ""
-
 msgid "Srate"
 msgstr "ÁØÜÒ. èÒØÔÚöáâì"
 
 msgid "Inversion"
 msgstr "¦ÝÒÕàáöï"
 
+msgid "off"
+msgstr "ÒØÚÛ"
+
 msgid "CoderateH"
 msgstr "CoderateH"
 
+msgid "none"
+msgstr "ÝöçÞÓÞ"
+
 msgid "CoderateL"
 msgstr "CoderateL"
 
@@ -312,15 +309,6 @@
 msgid "Hierarchy"
 msgstr "¦ôàÐàåöï"
 
-msgid "Alpha"
-msgstr ""
-
-msgid "Priority"
-msgstr "¿àöÞàØâÕâ"
-
-msgid "Rolloff"
-msgstr ""
-
 msgid "Channel settings are not unique!"
 msgstr "½ÐáâàÞÙÚØ ÚÐÝÐÛã ÝÕ ôÔØÝö!"
 
@@ -366,6 +354,9 @@
 msgid "VPS"
 msgstr "VPS ßÞßàÐÒÚÐ"
 
+msgid "Priority"
+msgstr "¿àöÞàØâÕâ"
+
 msgid "Lifetime"
 msgstr "ÁâàÞÚ ×ÑÕàöÓÐÝÝï"
 
@@ -819,12 +810,6 @@
 msgid "VDR"
 msgstr "VDR"
 
-msgid "Disk"
-msgstr "´ØáÚ"
-
-msgid "free"
-msgstr "ÒöÛìÝÞ"
-
 #. TRANSLATORS: note the leading blank!
 msgid " Stop replaying"
 msgstr " ·ãßØÝØâØ ßàÞÓàÐÒÐÝÝï"
@@ -908,9 +893,6 @@
 msgid "Button$Insert"
 msgstr "²áâÐÒÚÐ"
 
-msgid "auto"
-msgstr "ÐÒâÞ"
-
 msgid "Plugin"
 msgstr "¼ÞÔãÛì"
 
@@ -991,8 +973,8 @@
 msgid "Sunday"
 msgstr "½ÕÔöÛï"
 
-msgid "Upcoming VPS recording!"
-msgstr "VPS-·ÐßØá áÚÞàÞ ßÞçÝÕâìáï"
+msgid "Upcoming recording!"
+msgstr "·ÐßØá áÚÞàÞ ßÞçÝÕâìáï"
 
 msgid "Recording started"
 msgstr "·ÐßØá ßÞçÐÒáï"
diff -ruN vdr-1.5.14/recording.c vdr-1.5.15/recording.c
--- vdr-1.5.14/recording.c	2007-11-04 12:17:43.000000000 +0100
+++ vdr-1.5.15/recording.c	2008-02-16 14:31:39.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.c 1.157 2007/11/04 11:17:43 kls Exp $
+ * $Id: recording.c 1.161 2008/02/16 13:31:39 kls Exp $
  */
 
 #include "recording.h"
@@ -81,6 +81,7 @@
 
 void cRemoveDeletedRecordingsThread::Action(void)
 {
+  SetPriority(19);
   // Make sure only one instance of VDR does this:
   cLockFile LockFile(VideoDirectory);
   if (LockFile.Lock()) {
@@ -143,10 +144,12 @@
         cThreadLock DeletedRecordingsLock(&DeletedRecordings);
         if (DeletedRecordings.Count()) {
            cRecording *r = DeletedRecordings.First();
-           cRecording *r0 = r;
+           cRecording *r0 = NULL;
            while (r) {
-                 if (r->start < r0->start)
-                    r0 = r;
+                 if (IsOnVideoDirectoryFileSystem(r->FileName())) { // only remove recordings that will actually increase the free video disk space
+                    if (!r0 || r->start < r0->start)
+                       r0 = r;
+                    }
                  r = DeletedRecordings.Next(r);
                  }
            if (r0 && r0->Remove()) {
@@ -155,11 +158,13 @@
               return;
               }
            }
-        // DeletedRecordings was empty, so to be absolutely sure there are no
-        // deleted recordings we need to double check:
-        DeletedRecordings.Update(true);
-        if (DeletedRecordings.Count())
-           return; // the next call will actually remove it
+        else {
+           // DeletedRecordings was empty, so to be absolutely sure there are no
+           // deleted recordings we need to double check:
+           DeletedRecordings.Update(true);
+           if (DeletedRecordings.Count())
+              return; // the next call will actually remove it
+           }
         // No "deleted" files to remove, so let's see if we can delete a recording:
         isyslog("...no deleted recording found, trying to delete an old recording...");
         cThreadLock RecordingsLock(&Recordings);
@@ -167,15 +172,17 @@
            cRecording *r = Recordings.First();
            cRecording *r0 = NULL;
            while (r) {
-                 if (!r->IsEdited() && r->lifetime < MAXLIFETIME) { // edited recordings and recordings with MAXLIFETIME live forever
-                    if ((r->lifetime == 0 && Priority > r->priority) || // the recording has no guaranteed lifetime and the new recording has higher priority
-                        (r->lifetime > 0 && (time(NULL) - r->start) / SECSINDAY >= r->lifetime)) { // the recording's guaranteed lifetime has expired
-                       if (r0) {
-                          if (r->priority < r0->priority || (r->priority == r0->priority && r->start < r0->start))
-                             r0 = r; // in any case we delete the one with the lowest priority (or the older one in case of equal priorities)
+                 if (IsOnVideoDirectoryFileSystem(r->FileName())) { // only delete recordings that will actually increase the free video disk space
+                    if (!r->IsEdited() && r->lifetime < MAXLIFETIME) { // edited recordings and recordings with MAXLIFETIME live forever
+                       if ((r->lifetime == 0 && Priority > r->priority) || // the recording has no guaranteed lifetime and the new recording has higher priority
+                           (r->lifetime > 0 && (time(NULL) - r->start) / SECSINDAY >= r->lifetime)) { // the recording's guaranteed lifetime has expired
+                          if (r0) {
+                             if (r->priority < r0->priority || (r->priority == r0->priority && r->start < r0->start))
+                                r0 = r; // in any case we delete the one with the lowest priority (or the older one in case of equal priorities)
+                             }
+                          else
+                             r0 = r;
                           }
-                       else
-                          r0 = r;
                        }
                     }
                  r = Recordings.Next(r);
@@ -350,7 +357,7 @@
                          char *p = strchr(t, ' ');
                          if (p) {
                             free(channelName);
-                            asprintf(&channelName, "%s", compactspace(p));
+                            channelName = strdup(compactspace(p));
                             *p = 0; // strips optional channel name
                             }
                          if (*t)
@@ -524,7 +531,7 @@
   else if (Timer->IsSingleEvent() || !Setup.UseSubtitle)
      name = strdup(Timer->File());
   else
-     asprintf(&name, "%s~%s", Timer->File(), Subtitle);
+     name = strdup(cString::sprintf("%s~%s", Timer->File(), Subtitle));
   // substitute characters that would cause problems in file names:
   strreplace(name, '\n', ' ');
   start = Timer->StartTime();
@@ -565,22 +572,19 @@
         }
      GetResume();
      // read an optional info file:
-     char *InfoFileName = NULL;
-     asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX);
+     cString InfoFileName = cString::sprintf("%s%s", fileName, INFOFILESUFFIX);
      FILE *f = fopen(InfoFileName, "r");
      if (f) {
         if (!info->Read(f))
-           esyslog("ERROR: EPG data problem in file %s", InfoFileName);
+           esyslog("ERROR: EPG data problem in file %s", *InfoFileName);
         fclose(f);
         }
      else if (errno != ENOENT)
-        LOG_ERROR_STR(InfoFileName);
-     free(InfoFileName);
+        LOG_ERROR_STR(*InfoFileName);
 #ifdef SUMMARYFALLBACK
      // fall back to the old 'summary.vdr' if there was no 'info.vdr':
      if (isempty(info->Title())) {
-        char *SummaryFileName = NULL;
-        asprintf(&SummaryFileName, "%s%s", fileName, SUMMARYFILESUFFIX);
+        cString SummaryFileName = cString::sprintf("%s%s", fileName, SUMMARYFILESUFFIX);
         FILE *f = fopen(SummaryFileName, "r");
         if (f) {
            int line = 0;
@@ -626,8 +630,7 @@
                free(data[i]);
            }
         else if (errno != ENOENT)
-           LOG_ERROR_STR(SummaryFileName);
-        free(SummaryFileName);
+           LOG_ERROR_STR(*SummaryFileName);
         }
 #endif
      }
@@ -696,7 +699,7 @@
      struct tm tm_r;
      struct tm *t = localtime_r(&start, &tm_r);
      name = ExchangeChars(name, true);
-     asprintf(&fileName, NAMEFORMAT, VideoDirectory, name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, priority, lifetime);
+     fileName = strdup(cString::sprintf(NAMEFORMAT, VideoDirectory, name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, priority, lifetime));
      name = ExchangeChars(name, false);
      }
   return fileName;
@@ -715,7 +718,7 @@
         s++;
      else
         s = name;
-     asprintf(&titleBuffer, "%02d.%02d.%02d%c%02d:%02d%c%c%s",
+     titleBuffer = strdup(cString::sprintf("%02d.%02d.%02d%c%02d:%02d%c%c%s",
                             t->tm_mday,
                             t->tm_mon + 1,
                             t->tm_year % 100,
@@ -724,7 +727,7 @@
                             t->tm_min,
                             New,
                             Delimiter,
-                            s);
+                            s));
      // let's not display a trailing '~':
      if (!NewIndicator)
         stripspace(titleBuffer);
@@ -784,16 +787,14 @@
 
 bool cRecording::WriteInfo(void)
 {
-  char *InfoFileName = NULL;
-  asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX);
+  cString InfoFileName = cString::sprintf("%s%s", fileName, INFOFILESUFFIX);
   FILE *f = fopen(InfoFileName, "w");
   if (f) {
      info->Write(f);
      fclose(f);
      }
   else
-     LOG_ERROR_STR(InfoFileName);
-  free(InfoFileName);
+     LOG_ERROR_STR(*InfoFileName);
   return true;
 }
 
@@ -910,8 +911,7 @@
   struct dirent *e;
   while ((Foreground || Running()) && (e = d.Next()) != NULL) {
         if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
-           char *buffer;
-           asprintf(&buffer, "%s/%s", DirName, e->d_name);
+           char *buffer = strdup(AddDirectory(DirName, e->d_name));
            struct stat st;
            if (stat(buffer, &st) == 0) {
               int Link = 0;
@@ -993,10 +993,12 @@
 
 cRecording *cRecordings::GetByName(const char *FileName)
 {
-  for (cRecording *recording = First(); recording; recording = Next(recording)) {
-      if (strcmp(recording->FileName(), FileName) == 0)
-         return recording;
-      }
+  if (FileName) {
+     for (cRecording *recording = First(); recording; recording = Next(recording)) {
+         if (strcmp(recording->FileName(), FileName) == 0)
+            return recording;
+         }
+     }
   return NULL;
 }
 
@@ -1039,7 +1041,7 @@
   int size = 0;
   LOCK_THREAD;
   for (cRecording *recording = First(); recording; recording = Next(recording)) {
-      if (recording->fileSizeMB > 0)
+      if (recording->fileSizeMB > 0 && IsOnVideoDirectoryFileSystem(recording->FileName()))
          size += recording->fileSizeMB;
       }
   return size;
@@ -1070,9 +1072,7 @@
 
 cString cMark::ToText(void)
 {
-  char *buffer;
-  asprintf(&buffer, "%s%s%s\n", *IndexToHMSF(position, true), comment ? " " : "", comment ? comment : "");
-  return cString(buffer, true);
+  return cString::sprintf("%s%s%s\n", *IndexToHMSF(position, true), comment ? " " : "", comment ? comment : "");
 }
 
 bool cMark::Parse(const char *s)
@@ -1161,11 +1161,9 @@
 void cRecordingUserCommand::InvokeCommand(const char *State, const char *RecordingFileName)
 {
   if (command) {
-     char *cmd;
-     asprintf(&cmd, "%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\"$"));
-     isyslog("executing '%s'", cmd);
+     cString cmd = cString::sprintf("%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\"$"));
+     isyslog("executing '%s'", *cmd);
      SystemExec(cmd);
-     free(cmd);
      }
 }
 
@@ -1409,10 +1407,6 @@
 
 // --- cFileName -------------------------------------------------------------
 
-#include <errno.h>
-#include <unistd.h>
-#include "videodir.h"
-
 #define MAXFILESPERRECORDING 255
 #define RECORDFILESUFFIX    "/%03d.vdr"
 #define RECORDFILESUFFIXLEN 20 // some additional bytes for safety...
diff -ruN vdr-1.5.14/sdt.c vdr-1.5.15/sdt.c
--- vdr-1.5.14/sdt.c	2008-01-27 14:24:25.000000000 +0100
+++ vdr-1.5.15/sdt.c	2008-02-08 14:48:31.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sdt.c 1.18 2008/01/27 13:24:25 kls Exp $
+ * $Id: sdt.c 1.19 2008/02/08 13:48:31 kls Exp $
  */
 
 #include "sdt.h"
@@ -55,7 +55,6 @@
                    case 0x02: // digital radio sound service
                    case 0x04: // NVOD reference service
                    case 0x05: // NVOD time-shifted service
-                   case 0x19: // digital HD television service
                         {
                         char NameBuf[Utf8BufSize(1024)];
                         char ShortNameBuf[Utf8BufSize(1024)];
diff -ruN vdr-1.5.14/skinclassic.c vdr-1.5.15/skinclassic.c
--- vdr-1.5.14/skinclassic.c	2008-01-13 13:38:00.000000000 +0100
+++ vdr-1.5.15/skinclassic.c	2008-02-17 15:23:36.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinclassic.c 1.19 2008/01/13 12:38:00 kls Exp $
+ * $Id: skinclassic.c 1.25 2008/02/17 14:23:36 kls Exp $
  */
 
 #include "skinclassic.h"
@@ -77,6 +77,7 @@
   int lineHeight;
   int timeWidth;
   bool message;
+  cString lastDate;
 public:
   cSkinClassicDisplayChannel(bool WithInfo);
   virtual ~cSkinClassicDisplayChannel();
@@ -113,6 +114,7 @@
 {
   osd->DrawRectangle(0, 0, osd->Width() - 1, lineHeight - 1, Theme.Color(clrBackground));
   osd->DrawText(2, 0, ChannelString(Channel, Number), Theme.Color(clrChannelName), Theme.Color(clrBackground), cFont::GetFont(fontOsd));
+  lastDate = NULL;
 }
 
 void cSkinClassicDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
@@ -147,9 +149,12 @@
 {
   if (!message) {
      cString date = DayDateTime();
-     const cFont *font = cFont::GetFont(fontSml);
-     int w = font->Width(date);
-     osd->DrawText(osd->Width() - w - 2, 0, date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml), w);
+     if (!*lastDate || strcmp(date, lastDate)) {
+        const cFont *font = cFont::GetFont(fontSml);
+        int w = font->Width(date);
+        osd->DrawText(osd->Width() - w - 2, 0, date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml), w);
+        lastDate = date;
+        }
      }
   osd->Flush();
 }
@@ -159,12 +164,13 @@
 class cSkinClassicDisplayMenu : public cSkinDisplayMenu {
 private:
   cOsd *osd;
-  int x0, x1;
+  int x0, x1, x2, x3;
   int y0, y1, y2, y3, y4, y5;
   int lineHeight;
   int dateWidth;
   cString lastDate;
-  void SetScrollbar(void);
+  void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown);
+  void SetTextScrollbar(void);
 public:
   cSkinClassicDisplayMenu(void);
   virtual ~cSkinClassicDisplayMenu();
@@ -175,6 +181,7 @@
   virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
   virtual void SetMessage(eMessageType Type, const char *Text);
   virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable);
+  virtual void SetScrollbar(int Total, int Offset);
   virtual void SetEvent(const cEvent *Event);
   virtual void SetRecording(const cRecording *Recording);
   virtual void SetText(const char *Text, bool FixedFont);
@@ -189,7 +196,9 @@
   lineHeight = font->Height();
   dateWidth = 0;
   x0 = 0;
-  x1 = cOsd::OsdWidth();
+  x1 = x0 + 10;
+  x3 = cOsd::OsdWidth();
+  x2 = x3 - 2 * ScrollWidth;
   y0 = 0;
   y1 = lineHeight;
   y2 = y1 + lineHeight;
@@ -197,22 +206,22 @@
   y4 = y5 - lineHeight;
   y3 = y4 - lineHeight;
   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop());
-  tArea Areas[] = { { x0, y0, x1 - 1, y5 - 1, 8 } };
+  tArea Areas[] = { { x0, y0, x3 - 1, y5 - 1, 8 } };
   if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
   else {
-     tArea Areas[] = { { x0, y0, x1 - 1, y5 - 1, 4 } };
+     tArea Areas[] = { { x0, y0, x3 - 1, y5 - 1, 4 } };
      if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
      else {
-        tArea Areas[] = { { x0, y0, x1 - 1, y1 - 1, 2 },
-                          { x0, y1, x1 - 1, y3 - 1, 2 },
-                          { x0, y3, x1 - 1, y5 - 1, 4 }
+        tArea Areas[] = { { x0, y0, x3 - 1, y1 - 1, 2 },
+                          { x0, y1, x3 - 1, y3 - 1, 2 },
+                          { x0, y3, x3 - 1, y5 - 1, 4 }
                         };
         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
         }
      }
-  osd->DrawRectangle(x0, y0, x1 - 1, y5 - 1, Theme.Color(clrBackground));
+  osd->DrawRectangle(x0, y0, x3 - 1, y5 - 1, Theme.Color(clrBackground));
 }
 
 cSkinClassicDisplayMenu::~cSkinClassicDisplayMenu()
@@ -220,25 +229,31 @@
   delete osd;
 }
 
-void cSkinClassicDisplayMenu::SetScrollbar(void)
+void cSkinClassicDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown)
 {
-  if (textScroller.CanScroll()) {
-     int yt = textScroller.Top();
-     int yb = yt + textScroller.Height();
+  if (Total > 0 && Total > Shown) {
+     int yt = Top;
+     int yb = yt + Height - 1;
      int st = yt;
      int sb = yb;
-     int tt = st + (sb - st) * textScroller.Offset() / textScroller.Total();
-     int tb = tt + (sb - st) * textScroller.Shown() / textScroller.Total();
-     int xl = x1 - ScrollWidth;
-     osd->DrawRectangle(xl, st, x1 - 1, sb, Theme.Color(clrMenuScrollbarTotal));
-     osd->DrawRectangle(xl, tt, x1 - 1, tb, Theme.Color(clrMenuScrollbarShown));
+     int tt = st + (sb - st + 1) * Offset / Total;
+     int tb = tt + (sb - st + 1) * Shown / Total;
+     int xl = x3 - ScrollWidth;
+     osd->DrawRectangle(xl, st, x3 - 1, sb, Theme.Color(clrMenuScrollbarTotal));
+     osd->DrawRectangle(xl, tt, x3 - 1, tb, Theme.Color(clrMenuScrollbarShown));
      }
 }
 
+void cSkinClassicDisplayMenu::SetTextScrollbar(void)
+{
+  if (textScroller.CanScroll())
+     DrawScrollbar(textScroller.Total(), textScroller.Offset(), textScroller.Shown(), textScroller.Top(), textScroller.Height(), textScroller.CanScrollUp(), textScroller.CanScrollDown());
+}
+
 void cSkinClassicDisplayMenu::Scroll(bool Up, bool Page)
 {
   cSkinDisplayMenu::Scroll(Up, Page);
-  SetScrollbar();
+  SetTextScrollbar();
 }
 
 int cSkinClassicDisplayMenu::MaxItems(void)
@@ -249,24 +264,24 @@
 void cSkinClassicDisplayMenu::Clear(void)
 {
   textScroller.Reset();
-  osd->DrawRectangle(x0, y1, x1 - 1, y4 - 1, Theme.Color(clrBackground));
+  osd->DrawRectangle(x0, y1, x3 - 1, y4 - 1, Theme.Color(clrBackground));
 }
 
 void cSkinClassicDisplayMenu::SetTitle(const char *Title)
 {
   const cFont *font = cFont::GetFont(fontOsd);
-  osd->DrawText(x0, y0, Title, Theme.Color(clrMenuTitleFg), Theme.Color(clrMenuTitleBg), font, x1 - x0 - dateWidth);
+  osd->DrawText(x0, y0, Title, Theme.Color(clrMenuTitleFg), Theme.Color(clrMenuTitleBg), font, x3 - x0 - dateWidth);
 }
 
 void cSkinClassicDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
 {
   const cFont *font = cFont::GetFont(fontOsd);
-  int w = x1 - x0;
+  int w = x3 - x0;
   int t0 = x0;
   int t1 = x0 + w / 4;
   int t2 = x0 + w / 2;
-  int t3 = x1 - w / 4;
-  int t4 = x1;
+  int t3 = x3 - w / 4;
+  int t4 = x3;
   osd->DrawText(t0, y4, Red,    Theme.Color(clrButtonRedFg),    Red    ? Theme.Color(clrButtonRedBg)    : Theme.Color(clrBackground), font, t1 - t0, 0, taCenter);
   osd->DrawText(t1, y4, Green,  Theme.Color(clrButtonGreenFg),  Green  ? Theme.Color(clrButtonGreenBg)  : Theme.Color(clrBackground), font, t2 - t1, 0, taCenter);
   osd->DrawText(t2, y4, Yellow, Theme.Color(clrButtonYellowFg), Yellow ? Theme.Color(clrButtonYellowBg) : Theme.Color(clrBackground), font, t3 - t2, 0, taCenter);
@@ -277,9 +292,9 @@
 {
   const cFont *font = cFont::GetFont(fontOsd);
   if (Text)
-     osd->DrawText(x0, y3, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x1 - x0, 0, taCenter);
+     osd->DrawText(x0, y3, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x3 - x0, 0, taCenter);
   else
-     osd->DrawRectangle(x0, y3, x1 - 1, y4 - 1, Theme.Color(clrBackground));
+     osd->DrawRectangle(x0, y3, x3 - 1, y4 - 1, Theme.Color(clrBackground));
 }
 
 void cSkinClassicDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable)
@@ -299,12 +314,17 @@
       const char *s = GetTabbedText(Text, i);
       if (s) {
          int xt = x0 + Tab(i);
-         osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x1 - xt);
+         osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x2 - xt);
          }
       if (!Tab(i + 1))
          break;
       }
-  SetEditableWidth(x1 - x0 - Tab(1));
+  SetEditableWidth(x2 - x0 - Tab(1));
+}
+
+void cSkinClassicDisplayMenu::SetScrollbar(int Total, int Offset)
+{
+  DrawScrollbar(Total, Offset, MaxItems(), y2, MaxItems() * lineHeight, Offset > 0, Offset + MaxItems() < Total);
 }
 
 void cSkinClassicDisplayMenu::SetEvent(const cEvent *Event)
@@ -312,33 +332,30 @@
   if (!Event)
      return;
   const cFont *font = cFont::GetFont(fontOsd);
-  int xl = x0 + 10;
   int y = y2;
   cTextScroller ts;
   char t[32];
   snprintf(t, sizeof(t), "%s  %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
-  ts.Set(osd, xl, y, x1 - xl, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
+  ts.Set(osd, x1, y, x2 - x1, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
   if (Event->Vps() && Event->Vps() != Event->StartTime()) {
-     char *buffer;
-     asprintf(&buffer, " VPS: %s ", *Event->GetVpsString());
+     cString buffer = cString::sprintf(" VPS: %s ", *Event->GetVpsString());
      const cFont *font = cFont::GetFont(fontSml);
      int w = font->Width(buffer);
-     osd->DrawText(x1 - w, y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font, w);
-     free(buffer);
+     osd->DrawText(x3 - w, y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font, w);
      }
   y += ts.Height();
   y += font->Height();
-  ts.Set(osd, xl, y, x1 - xl, y3 - y, Event->Title(), font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
+  ts.Set(osd, x1, y, x2 - x1, y3 - y, Event->Title(), font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
   y += ts.Height();
   if (!isempty(Event->ShortText())) {
      const cFont *font = cFont::GetFont(fontSml);
-     ts.Set(osd, xl, y, x1 - xl, y3 - y, Event->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
+     ts.Set(osd, x1, y, x2 - x1, y3 - y, Event->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
      y += ts.Height();
      }
   y += font->Height();
   if (!isempty(Event->Description())) {
-     textScroller.Set(osd, xl, y, x1 - xl - 2 * ScrollWidth, y3 - y, Event->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
-     SetScrollbar();
+     textScroller.Set(osd, x1, y, x2 - x1, y3 - y, Event->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
+     SetTextScrollbar();
      }
 }
 
@@ -348,40 +365,39 @@
      return;
   const cRecordingInfo *Info = Recording->Info();
   const cFont *font = cFont::GetFont(fontOsd);
-  int xl = x0 + 10;
   int y = y2;
   cTextScroller ts;
   char t[32];
   snprintf(t, sizeof(t), "%s  %s", *DateString(Recording->start), *TimeString(Recording->start));
-  ts.Set(osd, xl, y, x1 - xl, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
+  ts.Set(osd, x1, y, x2 - x1, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
   y += ts.Height();
   y += font->Height();
   const char *Title = Info->Title();
   if (isempty(Title))
      Title = Recording->Name();
-  ts.Set(osd, xl, y, x1 - xl, y3 - y, Title, font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
+  ts.Set(osd, x1, y, x2 - x1, y3 - y, Title, font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
   y += ts.Height();
   if (!isempty(Info->ShortText())) {
      const cFont *font = cFont::GetFont(fontSml);
-     ts.Set(osd, xl, y, x1 - xl, y3 - y, Info->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
+     ts.Set(osd, x1, y, x2 - x1, y3 - y, Info->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
      y += ts.Height();
      }
   y += font->Height();
   if (!isempty(Info->Description())) {
-     textScroller.Set(osd, xl, y, x1 - xl - 2 * ScrollWidth, y3 - y, Info->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
-     SetScrollbar();
+     textScroller.Set(osd, x1, y, x2 - x1, y3 - y, Info->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
+     SetTextScrollbar();
      }
 }
 
 void cSkinClassicDisplayMenu::SetText(const char *Text, bool FixedFont)
 {
-  textScroller.Set(osd, x0, y2, GetTextAreaWidth(), y3 - y2, Text, GetTextAreaFont(FixedFont), Theme.Color(clrMenuText), Theme.Color(clrBackground));
-  SetScrollbar();
+  textScroller.Set(osd, x1, y2, GetTextAreaWidth(), y3 - y2, Text, GetTextAreaFont(FixedFont), Theme.Color(clrMenuText), Theme.Color(clrBackground));
+  SetTextScrollbar();
 }
 
 int cSkinClassicDisplayMenu::GetTextAreaWidth(void) const
 {
-  return x1 - x0 - 2 * ScrollWidth;
+return x2 - x1;
 }
 
 const cFont *cSkinClassicDisplayMenu::GetTextAreaFont(bool FixedFont) const
@@ -392,10 +408,10 @@
 void cSkinClassicDisplayMenu::Flush(void)
 {
   cString date = DayDateTime();
-  if (!lastDate || strcmp(date, lastDate)) {
+  if (!*lastDate || strcmp(date, lastDate)) {
      const cFont *font = cFont::GetFont(fontOsd);
      int w = font->Width(date);
-     osd->DrawText(x1 - w - 2, y0, date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font, w);
+     osd->DrawText(x3 - w - 2, y0, date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font, w);
      lastDate = date;
      dateWidth = max(w + 2, dateWidth);
      }
diff -ruN vdr-1.5.14/skins.c vdr-1.5.15/skins.c
--- vdr-1.5.14/skins.c	2007-01-04 14:08:55.000000000 +0100
+++ vdr-1.5.15/skins.c	2008-02-17 12:31:09.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skins.c 1.13 2007/01/04 13:08:55 kls Exp $
+ * $Id: skins.c 1.14 2008/02/17 11:31:09 kls Exp $
  */
 
 #include "skins.h"
@@ -108,6 +108,10 @@
   return buffer;
 }
 
+void cSkinDisplayMenu::SetScrollbar(int Total, int Offset)
+{
+}
+
 int cSkinDisplayMenu::GetTextAreaWidth(void) const
 {
   return 0;
diff -ruN vdr-1.5.14/skins.h vdr-1.5.15/skins.h
--- vdr-1.5.14/skins.h	2007-01-04 14:08:55.000000000 +0100
+++ vdr-1.5.15/skins.h	2008-02-17 12:30:56.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skins.h 1.15 2007/01/04 13:08:55 kls Exp $
+ * $Id: skins.h 1.16 2008/02/17 11:30:56 kls Exp $
  */
 
 #ifndef __SKINS_H
@@ -144,6 +144,11 @@
   virtual void SetItem(const cRecording *Recording, int Index, bool Current, bool Selectable);
   --> false: call SetItem(text)
   */
+  virtual void SetScrollbar(int Total, int Offset);
+       ///< Sets the Total number of items in the currently displayed list, and the
+       ///< Offset of the first item that is currently displayed (the skin knows how
+       ///< many items it can display at once, see MaxItems()). This can be used to
+       ///< display a scollbar.
   virtual void SetEvent(const cEvent *Event) = 0;
        ///< Sets the Event that shall be displayed, using the entire central area
        ///< of the menu. The Event's 'description' shall be displayed using a
diff -ruN vdr-1.5.14/skinsttng.c vdr-1.5.15/skinsttng.c
--- vdr-1.5.14/skinsttng.c	2007-06-17 15:51:56.000000000 +0200
+++ vdr-1.5.15/skinsttng.c	2008-02-17 15:23:45.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinsttng.c 1.21 2007/06/17 13:51:56 kls Exp $
+ * $Id: skinsttng.c 1.26 2008/02/17 14:23:45 kls Exp $
  */
 
 // Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
@@ -129,6 +129,7 @@
   tColor frameColor;
   bool message;
   const cEvent *present;
+  cString lastDate;
   int lastSeen;
   tTrackId lastTrackId;
   static cBitmap bmTeletext, bmRadio, bmAudio, bmDolbyDigital, bmEncrypted, bmRecording;
@@ -307,7 +308,10 @@
         const cFont *font = cFont::GetFont(fontSml);
         cString date = DayDateTime();
         int w = font->Width(date);
-        osd->DrawText(x4 - w - 2, y7 - font->Height(), date, Theme.Color(clrChannelDate), frameColor, font, w);
+        if (!*lastDate || strcmp(date, lastDate)) {
+           osd->DrawText(x4 - w - 2, y7 - font->Height(), date, Theme.Color(clrChannelDate), frameColor, font, w);
+           lastDate = date;
+           }
         cDevice *Device = cDevice::PrimaryDevice();
         const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack());
         if (!Track && *lastTrackId.description || Track && strcmp(lastTrackId.description, Track->description)) {
@@ -325,7 +329,7 @@
      if (seen != lastSeen) {
         osd->DrawRectangle(x1 + Gap, y3, x1 + Gap + ScrollWidth - 1, y4 - 1, Theme.Color(clrChannelTimebarRest));
         if (seen)
-        osd->DrawRectangle(x1 + Gap, y3, x1 + Gap + ScrollWidth - 1, y3 + seen, Theme.Color(clrChannelTimebarSeen));
+           osd->DrawRectangle(x1 + Gap, y3, x1 + Gap + ScrollWidth - 1, y3 + seen, Theme.Color(clrChannelTimebarSeen));
         lastSeen = seen;
         }
      }
@@ -344,7 +348,8 @@
   int currentIndex;
   bool message;
   cString lastDate;
-  void SetScrollbar(void);
+  void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown);
+  void SetTextScrollbar(void);
 public:
   cSkinSTTNGDisplayMenu(void);
   virtual ~cSkinSTTNGDisplayMenu();
@@ -355,6 +360,7 @@
   virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
   virtual void SetMessage(eMessageType Type, const char *Text);
   virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable);
+  virtual void SetScrollbar(int Total, int Offset);
   virtual void SetEvent(const cEvent *Event);
   virtual void SetRecording(const cRecording *Recording);
   virtual void SetText(const char *Text, bool FixedFont);
@@ -431,37 +437,43 @@
   delete osd;
 }
 
-void cSkinSTTNGDisplayMenu::SetScrollbar(void)
+void cSkinSTTNGDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown)
 {
-  if (textScroller.CanScroll()) {
+  if (Total > 0 && Total > Shown) {
      int h  = lineHeight;
-     int yt = textScroller.Top();
-     int yb = yt + textScroller.Height();
+     int yt = Top;
+     int yb = yt + Height - 1;
      int st = yt + h + Gap;
      int sb = yb - h - Gap;
-     int tt = st + (sb - st) * textScroller.Offset() / textScroller.Total();
-     int tb = tt + (sb - st) * textScroller.Shown() / textScroller.Total();
+     int tt = st + (sb - st + 1) * Offset / Total;
+     int tb = tt + (sb - st + 1) * Shown / Total;
      osd->DrawRectangle(x5, st, x5 + ScrollWidth - 1, sb, Theme.Color(clrMenuScrollbarTotal));
      osd->DrawRectangle(x5, tt, x5 + ScrollWidth - 1, tb, Theme.Color(clrMenuScrollbarShown));
      osd->DrawRectangle(x5, yt, x6 - 1, yt + h - 1, frameColor);
      osd->DrawEllipse  (x6, yt, x7 - 1, yt + h - 1, frameColor, 5);
      osd->DrawRectangle(x5, yb - h, x6 - 1, yb - 1, frameColor);
      osd->DrawEllipse  (x6, yb - h, x7 - 1, yb - 1, frameColor, 5);
-     if (textScroller.CanScrollUp()) {
+     if (CanScrollUp) {
         cBitmap bm(arrowup_xpm);
         osd->DrawBitmap(x5 + (x7 - x5 - bm.Width()) / 2 - 2, yt + (h - bm.Height()) / 2, bm, Theme.Color(clrMenuScrollbarArrow), frameColor);
         }
-     if (textScroller.CanScrollDown()) {
+     if (CanScrollDown) {
         cBitmap bm(arrowdown_xpm);
         osd->DrawBitmap(x5 + (x7 - x5 - bm.Width()) / 2 - 2, yb - h + (h - bm.Height()) / 2, bm, Theme.Color(clrMenuScrollbarArrow), frameColor);
         }
-     }
+   }
+}
+
+void cSkinSTTNGDisplayMenu::SetTextScrollbar(void)
+{
+  if (textScroller.CanScroll())
+     DrawScrollbar(textScroller.Total(), textScroller.Offset(), textScroller.Shown(), textScroller.Top(), textScroller.Height(), textScroller.CanScrollUp(), textScroller.CanScrollDown());
 }
 
 void cSkinSTTNGDisplayMenu::Scroll(bool Up, bool Page)
 {
   cSkinDisplayMenu::Scroll(Up, Page);
-  SetScrollbar();
+  SetTextScrollbar();
 }
 
 int cSkinSTTNGDisplayMenu::MaxItems(void)
@@ -554,6 +566,11 @@
   SetEditableWidth(x4 - x3 - 5 - Tab(1));
 }
 
+void cSkinSTTNGDisplayMenu::SetScrollbar(int Total, int Offset)
+{
+  DrawScrollbar(Total, Offset, MaxItems(), y3 + Roundness, MaxItems() * lineHeight, Offset > 0, Offset + MaxItems() < Total);
+}
+
 void cSkinSTTNGDisplayMenu::SetEvent(const cEvent *Event)
 {
   if (!Event)
@@ -566,15 +583,13 @@
   snprintf(t, sizeof(t), "%s  %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
   ts.Set(osd, xl, y, x4 - xl, y4 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
   if (Event->Vps() && Event->Vps() != Event->StartTime()) {
-     char *buffer;
-     asprintf(&buffer, " VPS: %s ", *Event->GetVpsString());
+     cString buffer = cString::sprintf(" VPS: %s ", *Event->GetVpsString());
      const cFont *font = cFont::GetFont(fontSml);
      int w = font->Width(buffer);
      osd->DrawText(x4 - w, y, buffer, Theme.Color(clrMenuEventVps), frameColor, font, w);
      int yb = y + font->Height();
      osd->DrawRectangle(x5, y, x6 - 1, yb - 1, frameColor);
      osd->DrawEllipse  (x6, y, x7 - 1, yb - 1, frameColor, 5);
-     free(buffer);
      }
   y += ts.Height();
   y += font->Height();
@@ -594,7 +609,7 @@
      osd->DrawEllipse  (x1, yt - Roundness, x2, yt,             frameColor, -3);
      osd->DrawRectangle(x1, yt,             x2, yb,             frameColor);
      osd->DrawEllipse  (x1, yb,             x2, yb + Roundness, frameColor, -2);
-     SetScrollbar();
+     SetTextScrollbar();
      }
 }
 
@@ -631,14 +646,14 @@
      osd->DrawEllipse  (x1, yt - Roundness, x2, yt,             frameColor, -3);
      osd->DrawRectangle(x1, yt,             x2, yb,             frameColor);
      osd->DrawEllipse  (x1, yb,             x2, yb + Roundness, frameColor, -2);
-     SetScrollbar();
+     SetTextScrollbar();
      }
 }
 
 void cSkinSTTNGDisplayMenu::SetText(const char *Text, bool FixedFont)
 {
   textScroller.Set(osd, x3, y3, GetTextAreaWidth(), y4 - y3, Text, GetTextAreaFont(FixedFont), Theme.Color(clrMenuText), Theme.Color(clrBackground));
-  SetScrollbar();
+  SetTextScrollbar();
 }
 
 int cSkinSTTNGDisplayMenu::GetTextAreaWidth(void) const
@@ -657,7 +672,7 @@
 {
   if (!message) {
      cString date = DayDateTime();
-     if (!lastDate || strcmp(date, lastDate)) {
+     if (!*lastDate || strcmp(date, lastDate)) {
         const cFont *font = cFont::GetFont(fontSml);
         int w = font->Width(date);
         osd->DrawText(x4 - w - 2, y7 - font->Height(), date, Theme.Color(clrMenuDate), frameColor, font, w);
diff -ruN vdr-1.5.14/sources.c vdr-1.5.15/sources.c
--- vdr-1.5.14/sources.c	2004-12-26 12:58:52.000000000 +0100
+++ vdr-1.5.15/sources.c	2008-02-10 15:07:26.000000000 +0100
@@ -4,13 +4,13 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sources.c 1.3 2004/12/26 11:58:52 kls Exp $
+ * $Id: sources.c 1.4 2008/02/10 14:07:26 kls Exp $
  */
 
 #include "sources.h"
 #include <ctype.h>
 
-// -- cSource ----------------------------------------------------------------
+// --- cSource ---------------------------------------------------------------
 
 cSource::cSource(void)
 {
@@ -101,7 +101,7 @@
   return code;
 }
 
-// -- cSources ---------------------------------------------------------------
+// --- cSources --------------------------------------------------------------
 
 cSources Sources;
 
diff -ruN vdr-1.5.14/spu.c vdr-1.5.15/spu.c
--- vdr-1.5.14/spu.c	2006-04-17 14:48:33.000000000 +0200
+++ vdr-1.5.15/spu.c	2008-02-10 15:06:48.000000000 +0100
@@ -6,13 +6,13 @@
  * This code is distributed under the terms and conditions of the
  * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
  *
- * $Id: spu.c 1.3 2006/04/17 12:48:33 kls Exp $
+ * $Id: spu.c 1.4 2008/02/10 14:06:48 kls Exp $
  */
 
 #include "spu.h"
 #include <inttypes.h>
 
-// -- cSpuDecoder ------------------------------------------------------------
+// --- cSpuDecoder -----------------------------------------------------------
 /*
 cSpuDecoder::cSpuDecoder()
 {};
diff -ruN vdr-1.5.14/status.c vdr-1.5.15/status.c
--- vdr-1.5.14/status.c	2005-12-31 16:10:10.000000000 +0100
+++ vdr-1.5.15/status.c	2008-02-16 15:46:31.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: status.c 1.8 2005/12/31 15:10:10 kls Exp $
+ * $Id: status.c 1.10 2008/02/16 14:46:31 kls Exp $
  */
 
 #include "status.h"
@@ -23,6 +23,12 @@
   statusMonitors.Del(this, false);
 }
 
+void cStatus::MsgTimerChange(const cTimer *Timer, eTimerChange Change)
+{
+  for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
+      sm->TimerChange(Timer, Change);
+}
+
 void cStatus::MsgChannelSwitch(const cDevice *Device, int ChannelNumber)
 {
   for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
@@ -59,6 +65,12 @@
       sm->SetAudioChannel(AudioChannel);
 }
 
+void cStatus::MsgSetSubtitleTrack(int Index, const char * const *Tracks)
+{
+  for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
+      sm->SetSubtitleTrack(Index, Tracks);
+}
+
 void cStatus::MsgOsdClear(void)
 {
   for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
diff -ruN vdr-1.5.14/status.h vdr-1.5.15/status.h
--- vdr-1.5.14/status.h	2007-08-12 12:34:40.000000000 +0200
+++ vdr-1.5.15/status.h	2008-02-16 16:00:33.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: status.h 1.10 2007/08/12 10:34:40 kls Exp $
+ * $Id: status.h 1.12 2008/02/16 15:00:33 kls Exp $
  */
 
 #ifndef __STATUS_H
@@ -15,11 +15,21 @@
 #include "player.h"
 #include "tools.h"
 
+enum eTimerChange { tcMod, tcAdd, tcDel };
+
+class cTimer;
+
 class cStatus : public cListObject {
 private:
   static cList<cStatus> statusMonitors;
 protected:
   // These functions can be implemented by derived classes to receive status information:
+  virtual void TimerChange(const cTimer *Timer, eTimerChange Change) {}
+               // Indicates a change in the timer settings.
+               // If Change is tcAdd or tcDel, Timer points to the timer that has
+               // been added or will be deleted, respectively. In case of tcMod,
+               // Timer is NULL; this indicates that some timer has been changed.
+               // Note that tcAdd and tcDel are always also followed by a tcMod.
   virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber) {}
                // Indicates a channel switch on the given DVB device.
                // If ChannelNumber is 0, this is before the channel is being switched,
@@ -44,6 +54,9 @@
   virtual void SetAudioChannel(int AudioChannel) {}
                // The audio channel has been set to the given value.
                // 0=stereo, 1=left, 2=right, -1=no information available.
+  virtual void SetSubtitleTrack(int Index, const char * const *Tracks) {}
+               // The subtitle track has been set to the one given by Index, which
+               // points into the Tracks array of strings. Tracks is NULL terminated.
   virtual void OsdClear(void) {}
                // The OSD has been cleared.
   virtual void OsdTitle(const char *Title) {}
@@ -71,12 +84,14 @@
   cStatus(void);
   virtual ~cStatus();
   // These functions are called whenever the related status information changes:
+  static void MsgTimerChange(const cTimer *Timer, eTimerChange Change);
   static void MsgChannelSwitch(const cDevice *Device, int ChannelNumber);
   static void MsgRecording(const cDevice *Device, const char *Name, const char *FileName, bool On);
   static void MsgReplaying(const cControl *Control, const char *Name, const char *FileName, bool On);
   static void MsgSetVolume(int Volume, bool Absolute);
   static void MsgSetAudioTrack(int Index, const char * const *Tracks);
   static void MsgSetAudioChannel(int AudioChannel);
+  static void MsgSetSubtitleTrack(int Index, const char * const *Tracks);
   static void MsgOsdClear(void);
   static void MsgOsdTitle(const char *Title);
   static void MsgOsdStatusMessage(const char *Message);
diff -ruN vdr-1.5.14/svdrp.c vdr-1.5.15/svdrp.c
--- vdr-1.5.14/svdrp.c	2008-01-13 16:06:25.000000000 +0100
+++ vdr-1.5.15/svdrp.c	2008-02-17 14:36:01.000000000 +0100
@@ -10,7 +10,7 @@
  * and interact with the Video Disk Recorder - or write a full featured
  * graphical interface that sits on top of an SVDRP connection.
  *
- * $Id: svdrp.c 1.105 2008/01/13 15:06:25 kls Exp $
+ * $Id: svdrp.c 1.109 2008/02/17 13:36:01 kls Exp $
  */
 
 #include "svdrp.h"
@@ -421,8 +421,8 @@
      if (Code != 0) {
         va_list ap;
         va_start(ap, fmt);
-        char *buffer;
-        vasprintf(&buffer, fmt, ap);
+        cString buffer = cString::sprintf(fmt, ap);
+        va_end(ap);
         const char *s = buffer;
         while (s && *s) {
               const char *n = strchr(s, '\n');
@@ -435,8 +435,6 @@
                  break;
               s = n ? n + 1 : NULL;
               }
-        free(buffer);
-        va_end(ap);
         }
      else {
         Reply(451, "Zero return code - looks like a programming error!");
@@ -728,7 +726,7 @@
 
 void cSVDRP::CmdGRAB(const char *Option)
 {
-  char *FileName = NULL;
+  const char *FileName = NULL;
   bool Jpeg = true;
   int Quality = -1, SizeX = -1, SizeY = -1;
   if (*Option) {
@@ -797,10 +795,10 @@
      char RealFileName[PATH_MAX];
      if (FileName) {
         if (grabImageDir) {
-           char *s = 0;
+           cString s;
            char *slash = strrchr(FileName, '/');
            if (!slash) {
-              asprintf(&s, "%s/%s", grabImageDir, FileName);
+              s = AddDirectory(grabImageDir, FileName);
               FileName = s;
               }
            slash = strrchr(FileName, '/'); // there definitely is one
@@ -810,12 +808,10 @@
            if (!r) {
               LOG_ERROR_STR(FileName);
               Reply(501, "Invalid file name \"%s\"", FileName);
-              free(s);
               return;
               }
            strcat(RealFileName, slash);
            FileName = RealFileName;
-           free(s);
            if (strncmp(FileName, grabImageDir, strlen(grabImageDir)) != 0) {
               Reply(501, "Invalid file name \"%s\"", FileName);
               return;
@@ -1424,7 +1420,7 @@
         else {
            int ReplyCode = 900;
            cString s = plugin->SVDRPCommand(cmd, option, ReplyCode);
-           if (s)
+           if (*s)
               Reply(abs(ReplyCode), "%s", *s);
            else
               Reply(500, "Command unrecognized: \"%s\"", cmd);
diff -ruN vdr-1.5.14/themes.c vdr-1.5.15/themes.c
--- vdr-1.5.14/themes.c	2007-08-05 16:11:35.000000000 +0200
+++ vdr-1.5.15/themes.c	2008-02-10 17:25:00.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: themes.c 1.7 2007/08/05 14:11:35 kls Exp $
+ * $Id: themes.c 1.8 2008/02/10 16:25:00 kls Exp $
  */
 
 #include "themes.h"
@@ -285,18 +285,14 @@
 
 void cThemes::Load(const char *SkinName, const char *ThemeName, cTheme *Theme)
 {
-  char *FileName = NULL;
-  asprintf(&FileName, "%s/%s-%s.theme", themesDirectory, SkinName, ThemeName);
+  cString FileName = cString::sprintf("%s/%s-%s.theme", themesDirectory, SkinName, ThemeName);
   if (access(FileName, F_OK) == 0) // the file exists
      Theme->Load(FileName);
-  free(FileName);
 }
 
 void cThemes::Save(const char *SkinName, cTheme *Theme)
 {
-  char *FileName = NULL;
-  asprintf(&FileName, "%s/%s-%s.theme", themesDirectory, SkinName, Theme->Name());
+  cString FileName = cString::sprintf("%s/%s-%s.theme", themesDirectory, SkinName, Theme->Name());
   if (access(FileName, F_OK) != 0) // the file does not exist
      Theme->Save(FileName);
-  free(FileName);
 }
diff -ruN vdr-1.5.14/thread.c vdr-1.5.15/thread.c
--- vdr-1.5.14/thread.c	2007-10-19 16:30:13.000000000 +0200
+++ vdr-1.5.15/thread.c	2008-02-15 15:17:42.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: thread.c 1.63 2007/10/19 14:30:13 kls Exp $
+ * $Id: thread.c 1.64 2008/02/15 14:17:42 kls Exp $
  */
 
 #include "thread.h"
@@ -231,7 +231,7 @@
   if (Description) {
      va_list ap;
      va_start(ap, Description);
-     vasprintf(&description, Description, ap);
+     description = strdup(cString::sprintf(Description, ap));
      va_end(ap);
      }
 }
diff -ruN vdr-1.5.14/timers.c vdr-1.5.15/timers.c
--- vdr-1.5.14/timers.c	2007-08-04 11:23:33.000000000 +0200
+++ vdr-1.5.15/timers.c	2008-02-16 15:47:40.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: timers.c 1.68 2007/08/04 09:23:33 kls Exp $
+ * $Id: timers.c 1.73 2008/02/16 14:47:40 kls Exp $
  */
 
 #include "timers.h"
@@ -13,13 +13,17 @@
 #include "device.h"
 #include "i18n.h"
 #include "libsi/si.h"
+#include "recording.h"
 #include "remote.h"
+#include "status.h"
+
+#define VFAT_MAX_FILENAME 40 // same as MAX_SUBTITLE_LENGTH in recording.c
 
 // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d'
 // format characters in order to allow any number of blanks after a numeric
 // value!
 
-// -- cTimer -----------------------------------------------------------------
+// --- cTimer ----------------------------------------------------------------
 
 cTimer::cTimer(bool Instant, bool Pause, cChannel *Channel)
 {
@@ -99,13 +103,14 @@
 cTimer& cTimer::operator= (const cTimer &Timer)
 {
   if (&Timer != this) {
+     uint OldFlags = flags & tfRecording;
      startTime    = Timer.startTime;
      stopTime     = Timer.stopTime;
      lastSetEvent = 0;
      recording    = Timer.recording;
      pending      = Timer.pending;
      inVpsMargin  = Timer.inVpsMargin;
-     flags        = Timer.flags;
+     flags        = Timer.flags | OldFlags;
      channel      = Timer.channel;
      day          = Timer.day;
      weekdays     = Timer.weekdays;
@@ -132,20 +137,17 @@
   return r;
 }
 
-cString cTimer::ToText(bool UseChannelID)
+cString cTimer::ToText(bool UseChannelID) const
 {
-  char *buffer;
   strreplace(file, ':', '|');
-  asprintf(&buffer, "%u:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? *Channel()->GetChannelID().ToString() : *itoa(Channel()->Number()), *PrintDay(day, weekdays, true), start, stop, priority, lifetime, file, aux ? aux : "");
+  cString buffer = cString::sprintf("%u:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? *Channel()->GetChannelID().ToString() : *itoa(Channel()->Number()), *PrintDay(day, weekdays, true), start, stop, priority, lifetime, file, aux ? aux : "");
   strreplace(file, '|', ':');
-  return cString(buffer, true);
+  return buffer;
 }
 
 cString cTimer::ToDescr(void) const
 {
-  char *buffer;
-  asprintf(&buffer, "%d (%d %04d-%04d %s'%s')", Index() + 1, Channel()->Number(), start, stop, HasFlags(tfVps) ? "VPS " : "", file);
-  return cString(buffer, true);
+  return cString::sprintf("%d (%d %04d-%04d %s'%s')", Index() + 1, Channel()->Number(), start, stop, HasFlags(tfVps) ? "VPS " : "", file);
 }
 
 int cTimer::TimeToInt(int t)
@@ -287,6 +289,18 @@
         }
      //TODO add more plausibility checks
      result = ParseDay(daybuffer, day, weekdays);
+     if (VfatFileSystem) {
+        char *p = strrchr(filebuffer, '~');
+        if (p)
+           p++;
+        else
+           p = filebuffer;
+        if (strlen(p) > VFAT_MAX_FILENAME) {
+           dsyslog("timer file name too long for VFAT file system: '%s'", p);
+           p[VFAT_MAX_FILENAME] = 0;
+           dsyslog("timer file name truncated to '%s'", p);
+           }
+        }
      Utf8Strn0Cpy(file, filebuffer, MaxFileName);
      strreplace(file, '|', ':');
      if (isnumber(channelbuffer))
@@ -607,7 +621,7 @@
   Matches(); // refresh start and end time
 }
 
-// -- cTimers ----------------------------------------------------------------
+// --- cTimers ---------------------------------------------------------------
 
 cTimers Timers;
 
@@ -683,9 +697,28 @@
 
 void cTimers::SetModified(void)
 {
+  cStatus::MsgTimerChange(NULL, tcMod);
   state++;
 }
 
+void cTimers::Add(cTimer *Timer, cTimer *After)
+{
+  cConfig<cTimer>::Add(Timer, After);
+  cStatus::MsgTimerChange(Timer, tcAdd);
+}
+
+void cTimers::Ins(cTimer *Timer, cTimer *Before)
+{
+  cConfig<cTimer>::Ins(Timer, Before);
+  cStatus::MsgTimerChange(Timer, tcAdd);
+}
+
+void cTimers::Del(cTimer *Timer, bool DeleteObject)
+{
+  cStatus::MsgTimerChange(Timer, tcDel);
+  cConfig<cTimer>::Del(Timer, DeleteObject);
+}
+
 bool cTimers::Modified(int &State)
 {
   bool Result = state != State;
diff -ruN vdr-1.5.14/timers.h vdr-1.5.15/timers.h
--- vdr-1.5.14/timers.h	2007-06-03 15:24:58.000000000 +0200
+++ vdr-1.5.15/timers.h	2008-02-16 15:33:23.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: timers.h 1.30 2007/06/03 13:24:58 kls Exp $
+ * $Id: timers.h 1.31 2008/02/16 14:33:23 kls Exp $
  */
 
 #ifndef __TIMERS_H
@@ -38,7 +38,7 @@
   int stop;
   int priority;
   int lifetime;
-  char file[MaxFileName];
+  mutable char file[MaxFileName];
   char *aux;
   const cEvent *event;
 public:
@@ -62,7 +62,7 @@
   const char *File(void) const { return file; }
   time_t FirstDay(void) const { return weekdays ? day : 0; }
   const char *Aux(void) const { return aux; }
-  cString ToText(bool UseChannelID = false);
+  cString ToText(bool UseChannelID = false) const;
   cString ToDescr(void) const;
   const cEvent *Event(void) const { return event; }
   bool Parse(const char *s);
@@ -119,6 +119,9 @@
       ///< Upon return the internal state will be stored in State.
   void SetEvents(void);
   void DeleteExpired(void);
+  void Add(cTimer *Timer, cTimer *After = NULL);
+  void Ins(cTimer *Timer, cTimer *Before = NULL);
+  void Del(cTimer *Timer, bool DeleteObject = true);
   };
 
 extern cTimers Timers;
diff -ruN vdr-1.5.14/tools.c vdr-1.5.15/tools.c
--- vdr-1.5.14/tools.c	2008-01-13 12:26:30.000000000 +0100
+++ vdr-1.5.15/tools.c	2008-02-16 14:38:22.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.c 1.140 2008/01/13 11:26:30 kls Exp $
+ * $Id: tools.c 1.143 2008/02/16 13:38:22 kls Exp $
  */
 
 #include "tools.h"
@@ -267,9 +267,7 @@
 
 cString AddDirectory(const char *DirName, const char *FileName)
 {
-  char *buf;
-  asprintf(&buf, "%s/%s", DirName && *DirName ? DirName : ".", FileName);
-  return cString(buf, true);
+  return cString::sprintf("%s/%s", DirName && *DirName ? DirName : ".", FileName);
 }
 
 cString itoa(int n)
@@ -279,6 +277,21 @@
   return buf;
 }
 
+bool EntriesOnSameFileSystem(const char *File1, const char *File2)
+{
+  struct statfs statFs;
+  if (statfs(File1, &statFs) == 0) {
+     fsid_t fsid1 = statFs.f_fsid;
+     if (statfs(File2, &statFs) == 0)
+        return memcmp(&statFs.f_fsid, &fsid1, sizeof(fsid1)) == 0;
+     else
+        LOG_ERROR_STR(File2);
+     }
+  else
+     LOG_ERROR_STR(File1);
+  return false;
+}
+
 int FreeDiskSpaceMB(const char *Directory, int *UsedMB)
 {
   if (UsedMB)
@@ -352,15 +365,14 @@
            struct dirent *e;
            while ((e = d.Next()) != NULL) {
                  if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
-                    char *buffer;
-                    asprintf(&buffer, "%s/%s", FileName, e->d_name);
+                    cString buffer = AddDirectory(FileName, e->d_name);
                     if (FollowSymlinks) {
                        int size = strlen(buffer) * 2; // should be large enough
                        char *l = MALLOC(char, size);
                        int n = readlink(buffer, l, size);
                        if (n < 0) {
                           if (errno != EINVAL)
-                             LOG_ERROR_STR(buffer);
+                             LOG_ERROR_STR(*buffer);
                           }
                        else if (n < size) {
                           l[n] = 0;
@@ -372,10 +384,9 @@
                           esyslog("ERROR: symlink name length (%d) exceeded anticipated buffer size (%d)", n, size);
                        free(l);
                        }
-                    dsyslog("removing %s", buffer);
+                    dsyslog("removing %s", *buffer);
                     if (remove(buffer) < 0)
-                       LOG_ERROR_STR(buffer);
-                    free(buffer);
+                       LOG_ERROR_STR(*buffer);
                     }
                  }
            }
@@ -405,8 +416,7 @@
      struct dirent *e;
      while ((e = d.Next()) != NULL) {
            if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) {
-              char *buffer;
-              asprintf(&buffer, "%s/%s", DirName, e->d_name);
+              cString buffer = AddDirectory(DirName, e->d_name);
               struct stat st;
               if (stat(buffer, &st) == 0) {
                  if (S_ISDIR(st.st_mode)) {
@@ -417,10 +427,9 @@
                     empty = false;
                  }
               else {
-                 LOG_ERROR_STR(buffer);
+                 LOG_ERROR_STR(*buffer);
                  empty = false;
                  }
-              free(buffer);
               }
            }
      if (RemoveThis && empty) {
@@ -445,8 +454,7 @@
      struct dirent *e;
      while (size >= 0 && (e = d.Next()) != NULL) {
            if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
-              char *buffer;
-              asprintf(&buffer, "%s/%s", DirName, e->d_name);
+              cString buffer = AddDirectory(DirName, e->d_name);
               struct stat st;
               if (stat(buffer, &st) == 0) {
                  if (S_ISDIR(st.st_mode)) {
@@ -460,10 +468,9 @@
                     size += st.st_size / MEGABYTE(1);
                  }
               else {
-                 LOG_ERROR_STR(buffer);
+                 LOG_ERROR_STR(*buffer);
                  size = -1;
                  }
-              free(buffer);
               }
            }
      return size;
@@ -489,13 +496,12 @@
 
 bool SpinUpDisk(const char *FileName)
 {
-  char *buf = NULL;
   for (int n = 0; n < 10; n++) {
-      free(buf);
+      cString buf;
       if (DirectoryOk(FileName))
-         asprintf(&buf, "%s/vdr-%06d", *FileName ? FileName : ".", n);
+         buf = cString::sprintf("%s/vdr-%06d", *FileName ? FileName : ".", n);
       else
-         asprintf(&buf, "%s.vdr-%06d", FileName, n);
+         buf = cString::sprintf("%s.vdr-%06d", FileName, n);
       if (access(buf, F_OK) != 0) { // the file does not exist
          timeval tp1, tp2;
          gettimeofday(&tp1, NULL);
@@ -503,21 +509,19 @@
          // O_SYNC doesn't work on all file systems
          if (f >= 0) {
             if (fdatasync(f) < 0)
-               LOG_ERROR_STR(buf);
+               LOG_ERROR_STR(*buf);
             close(f);
             remove(buf);
             gettimeofday(&tp2, NULL);
             double seconds = (((long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0;
             if (seconds > 0.5)
                dsyslog("SpinUpDisk took %.2f seconds", seconds);
-            free(buf);
             return true;
             }
          else
-            LOG_ERROR_STR(buf);
+            LOG_ERROR_STR(*buf);
          }
       }
-  free(buf);
   esyslog("ERROR: SpinUpDisk failed");
   return false;
 }
@@ -888,7 +892,21 @@
   va_list ap;
   va_start(ap, fmt);
   char *buffer;
-  vasprintf(&buffer, fmt, ap);
+  if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
+     esyslog("error in vasprintf('%s', ...)", fmt);
+     buffer = strdup("???");
+     }
+  va_end(ap);
+  return cString(buffer, true);
+}
+
+cString cString::sprintf(const char *fmt, va_list &ap)
+{
+  char *buffer;
+  if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
+     esyslog("error in vasprintf('%s', ...)", fmt);
+     buffer = strdup("???");
+     }
   return cString(buffer, true);
 }
 
@@ -1241,8 +1259,8 @@
               if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
                  if (DirsOnly) {
                     struct stat ds;
-                    if (stat(e->d_name, &ds) == 0) {
-                       if (S_ISDIR(ds.st_mode))
+                    if (stat(AddDirectory(Directory, e->d_name), &ds) == 0) {
+                       if (!S_ISDIR(ds.st_mode))
                           continue;
                        }
                     }
@@ -1622,7 +1640,7 @@
   fileName = NULL;
   f = -1;
   if (DirectoryOk(Directory))
-     asprintf(&fileName, "%s/%s", Directory, LOCKFILENAME);
+     fileName = strdup(AddDirectory(Directory, LOCKFILENAME));
 }
 
 cLockFile::~cLockFile()
diff -ruN vdr-1.5.14/tools.h vdr-1.5.15/tools.h
--- vdr-1.5.14/tools.h	2008-01-13 12:22:26.000000000 +0100
+++ vdr-1.5.15/tools.h	2008-02-17 14:41:27.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.h 1.110 2008/01/13 11:22:26 kls Exp $
+ * $Id: tools.h 1.113 2008/02/17 13:41:27 kls Exp $
  */
 
 #ifndef __TOOLS_H
@@ -156,11 +156,13 @@
   cString(const char *S = NULL, bool TakePointer = false);
   cString(const cString &String);
   virtual ~cString();
+  operator const void * () const { return s; } // to catch cases where operator*() should be used
   operator const char * () const { return s; } // for use in (const char *) context
   const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.)
   cString &operator=(const cString &String);
   cString &Truncate(int Index); ///< Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
   static cString sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+  static cString sprintf(const char *fmt, va_list &ap);
   };
 
 ssize_t safe_read(int filedes, void *buffer, size_t size);
@@ -192,6 +194,7 @@
 bool isnumber(const char *s);
 cString itoa(int n);
 cString AddDirectory(const char *DirName, const char *FileName);
+bool EntriesOnSameFileSystem(const char *File1, const char *File2);
 int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
 bool DirectoryOk(const char *DirName, bool LogErrors = false);
 bool MakeDirs(const char *FileName, bool IsDirectory = false);
diff -ruN vdr-1.5.14/vdr.1 vdr-1.5.15/vdr.1
--- vdr-1.5.14/vdr.1	2007-02-24 18:40:20.000000000 +0100
+++ vdr-1.5.15/vdr.1	2008-02-10 15:23:12.000000000 +0100
@@ -2,15 +2,15 @@
 .\" ** The above line should force tbl to be a preprocessor **
 .\" Man page for vdr
 .\"
-.\" Copyright (C) 2006 Klaus Schmidinger
+.\" Copyright (C) 2008 Klaus Schmidinger
 .\"
 .\" You may distribute under the terms of the GNU General Public
 .\" License as specified in the file COPYING that comes with the
 .\" vdr distribution.
 .\"
-.\" $Id: vdr.1 1.29 2007/02/24 17:40:20 kls Exp $
+.\" $Id: vdr.1 1.32 2008/02/10 14:23:12 kls Exp $
 .\"
-.TH vdr 1 "07 Jan 2007" "1.4.5" "Video Disk Recorder"
+.TH vdr 1 "10 Feb 2008" "1.6" "Video Disk Recorder"
 .SH NAME
 vdr - the Video Disk Recorder
 .SH SYNOPSIS
@@ -88,6 +88,9 @@
 Use a LIRC remote control device.
 If \fIpath\fR is omitted, vdr uses \fI/dev/lircd\fR.
 .TP
+.BI \-\-localedir= dir
+Search for locale files in \fIdir\fR (default is ./locale).
+.TP
 .B \-m, \-\-mute
 Mute audio of the primary DVB device at startup.
 .TP
@@ -139,6 +142,9 @@
 vdr can switch to a lesser privileged user id during normal
 operation.
 .TP
+.BI \-\-userdump
+allow coredumps if -u is given (only for debugging).
+.TP
 .BI \-\-vfat
 Encode special characters in recording names to avoid problems
 with VFAT file systems.
@@ -226,7 +232,7 @@
 .SH REPORTING BUGS
 Report bugs to <vdr\-bugs@cadsoft.de>.
 .SH COPYRIGHT
-Copyright \(co 2006 Klaus Schmidinger.
+Copyright \(co 2008 Klaus Schmidinger.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff -ruN vdr-1.5.14/vdr.5 vdr-1.5.15/vdr.5
--- vdr-1.5.14/vdr.5	2008-01-26 15:16:51.000000000 +0100
+++ vdr-1.5.15/vdr.5	2008-02-10 15:25:07.000000000 +0100
@@ -2,15 +2,15 @@
 .\" ** The above line should force tbl to be a preprocessor **
 .\" Man page for vdr file formats
 .\"
-.\" Copyright (C) 2006 Klaus Schmidinger
+.\" Copyright (C) 2008 Klaus Schmidinger
 .\"
 .\" You may distribute under the terms of the GNU General Public
 .\" License as specified in the file COPYING that comes with the
 .\" vdr distribution.
 .\"
-.\" $Id: vdr.5 1.65 2008/01/26 14:16:51 kls Exp $
+.\" $Id: vdr.5 1.67 2008/02/10 14:25:07 kls Exp $
 .\"
-.TH vdr 5 "07 Jan 2007" "1.4.5" "Video Disk Recorder Files"
+.TH vdr 5 "10 Feb 2008" "1.6" "Video Disk Recorder Files"
 .SH NAME
 vdr file formats - the Video Disk Recorder Files
 .SH DESCRIPTION
@@ -83,23 +83,19 @@
 .TS
 tab (@);
 l l.
-\fBA\fR@Alpha (0, 1, 2, 4)
-\fBB\fR@Bandwidth (5, 6, 7, 8)
-\fBC\fR@Code rate high priority (0, 12, 13, 14, 23, 25, 34, 35, 45, 56, 67, 78, 89, 910)
-\fBD\fR@coDe rate low priority (0, 12, 13, 14, 23, 25, 34, 35, 45, 56, 67, 78, 89, 910)
+\fBB\fR@Bandwidth (6, 7, 8)
+\fBC\fR@Code rate high priority (0, 12, 23, 34, 45, 56, 67, 78, 89)
+\fBD\fR@Code rate low priority (0, 12, 23, 34, 45, 56, 67, 78, 89)
 \fBG\fR@Guard interval (4, 8, 16, 32)
 \fBH\fR@Horizontal polarization
 \fBI\fR@Inversion (0, 1)
 \fBL\fR@Left circular polarization
-\fBM\fR@Modulation (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 32, 64, 128, 256, 512, 998, 1024)
-\fBO\fR@rollOff (0, 20, 25, 35)
-\fBP\fR@Priority (0, 1)
+\fBM\fR@Modulation (0, 16, 32, 64, 128, 256)
 \fBR\fR@Right circular polarization
-\fBT\fR@Transmission mode (2, 4, 8)
+\fBT\fR@Transmission mode (2, 8)
 \fBV\fR@Vertical polarization
-\fBY\fR@hierarchY (0, 1)
+\fBY\fR@Hierarchy (0, 1, 2, 4)
 .TE
-
 The polarization parameters have no integer numbers following them. This is for
 compatibility with files from older versions and also to keep the DVB-S entries
 as simple as possible.
@@ -673,7 +669,7 @@
 .SH REPORTING BUGS
 Report bugs to <vdr\-bugs@cadsoft.de>.
 .SH COPYRIGHT
-Copyright \(co 2006 Klaus Schmidinger.
+Copyright \(co 2008 Klaus Schmidinger.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff -ruN vdr-1.5.14/vdr.c vdr-1.5.15/vdr.c
--- vdr-1.5.14/vdr.c	2008-01-27 15:38:45.000000000 +0100
+++ vdr-1.5.15/vdr.c	2008-02-10 15:23:31.000000000 +0100
@@ -1,7 +1,7 @@
 /*
  * vdr.c: Video Disk Recorder main program
  *
- * Copyright (C) 2000, 2003, 2006 Klaus Schmidinger
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -22,7 +22,7 @@
  *
  * The project's page is at http://www.cadsoft.de/vdr
  *
- * $Id: vdr.c 1.307 2008/01/27 14:38:45 kls Exp $
+ * $Id: vdr.c 1.310 2008/02/10 14:23:31 kls Exp $
  */
 
 #include <getopt.h>
@@ -86,7 +86,7 @@
 
 static int LastSignal = 0;
 
-static bool SetUser(const char *UserName)
+static bool SetUser(const char *UserName, bool UserDump)//XXX name?
 {
   if (UserName) {
      struct passwd *user = getpwnam(UserName);
@@ -106,10 +106,8 @@
         fprintf(stderr, "vdr: cannot set user id %u: %s\n", (unsigned int)user->pw_uid, strerror(errno));
         return false;
         }
-     if (prctl(PR_SET_DUMPABLE, 2, 0, 0, 0) < 0) {
+     if (UserDump && prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0)
         fprintf(stderr, "vdr: warning - cannot set dumpable: %s\n", strerror(errno));
-        // always non-fatal, and will not work with kernel < 2.6.13
-        }
      }
   return true;
 }
@@ -187,6 +185,7 @@
 
   bool StartedAsRoot = false;
   const char *VdrUser = NULL;
+  bool UserDump = false;
   int SVDRPport = DEFAULTSVDRPPORT;
   const char *AudioCommand = NULL;
   const char *ConfigDirectory = NULL;
@@ -241,6 +240,7 @@
       { "shutdown", required_argument, NULL, 's' },
       { "terminal", required_argument, NULL, 't' },
       { "user",     required_argument, NULL, 'u' },
+      { "userdump", no_argument,       NULL, 'u' | 0x100 },
       { "version",  no_argument,       NULL, 'V' },
       { "vfat",     no_argument,       NULL, 'v' | 0x100 },
       { "video",    required_argument, NULL, 'v' },
@@ -346,6 +346,9 @@
           case 'u': if (*optarg)
                        VdrUser = optarg;
                     break;
+          case 'u' | 0x100:
+                    UserDump = true;
+                    break;
           case 'V': DisplayVersion = true;
                     break;
           case 'v' | 0x100:
@@ -376,7 +379,7 @@
      if (strcmp(VdrUser, "root")) {
         if (!SetKeepCaps(true))
            return 2;
-        if (!SetUser(VdrUser))
+        if (!SetUser(VdrUser, UserDump))
            return 2;
         if (!SetKeepCaps(false))
            return 2;
@@ -431,6 +434,7 @@
                "  -t TTY,   --terminal=TTY controlling tty\n"
                "  -u USER,  --user=USER    run as user USER; only applicable if started as\n"
                "                           root\n"
+               "            --userdump     allow coredumps if -u is given (debugging)\n"
                "  -v DIR,   --video=DIR    use DIR as video directory (default: %s)\n"
                "  -V,       --version      print version information and exit\n"
                "            --vfat         encode special characters in recording names to\n"
@@ -874,7 +878,7 @@
                         if (cDevice::PrimaryDevice()->HasDecoder() && !cDevice::PrimaryDevice()->HasProgramme()) {
                            // the previous SwitchChannel() has switched away the current live channel
                            Channels.SwitchTo(Timer->Channel()->Number()); // avoids toggling between old channel and black screen
-                           Skins.Message(mtInfo, tr("Upcoming VPS recording!"));
+                           Skins.Message(mtInfo, tr("Upcoming recording!"));
                            }
                         }
                      }
diff -ruN vdr-1.5.14/videodir.c vdr-1.5.15/videodir.c
--- vdr-1.5.14/videodir.c	2005-12-18 11:33:20.000000000 +0100
+++ vdr-1.5.15/videodir.c	2008-02-16 14:00:03.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: videodir.c 1.14 2005/12/18 10:33:20 kls Exp $
+ * $Id: videodir.c 1.15 2008/02/16 13:00:03 kls Exp $
  */
 
 #include "videodir.h"
@@ -232,3 +232,12 @@
      } while (Dir.Next());
 }
 
+bool IsOnVideoDirectoryFileSystem(const char *FileName)
+{
+  cVideoDirectory Dir;
+  do {
+     if (EntriesOnSameFileSystem(Dir.Name(), FileName))
+        return true;
+     } while (Dir.Next());
+  return false;
+}
diff -ruN vdr-1.5.14/videodir.h vdr-1.5.15/videodir.h
--- vdr-1.5.14/videodir.h	2005-10-31 12:50:23.000000000 +0100
+++ vdr-1.5.15/videodir.h	2008-02-16 13:53:11.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: videodir.h 1.6 2005/10/31 11:50:23 kls Exp $
+ * $Id: videodir.h 1.7 2008/02/16 12:53:11 kls Exp $
  */
 
 #ifndef __VIDEODIR_H
@@ -23,5 +23,6 @@
 int VideoDiskSpace(int *FreeMB = NULL, int *UsedMB = NULL); // returns the used disk space in percent
 cString PrefixVideoFileName(const char *FileName, char Prefix);
 void RemoveEmptyVideoDirectories(void);
+bool IsOnVideoDirectoryFileSystem(const char *FileName);
 
 #endif //__VIDEODIR_H
