diff -ruN vdr-1.5.15/CONTRIBUTORS vdr-1.5.16/CONTRIBUTORS
--- vdr-1.5.15/CONTRIBUTORS	2008-02-16 17:12:21.000000000 +0100
+++ vdr-1.5.16/CONTRIBUTORS	2008-02-24 11:30:49.000000000 +0100
@@ -122,7 +122,7 @@
  for pointing out a possible hangup when reading a broken epg.data file
 
 Paulo Lopes <pmml@netvita.pt>
- for translating OSD texts to the Portugese language
+ for translating OSD texts to the Portuguese language
 
 Markus Lang <pretender@gaze.de> and Ulrich Röder <dynamite@efr-net.de>
  for making DiSEqC support configurable
@@ -186,7 +186,7 @@
  for reporting a bug in handling of Ca parameters with values <= MAXDEVICES, which
  don't indicate an actual encrypted channel
  for implementing setting the "broken link" flag for GOPs at the beginning of a new
- video sequence, which avoids artefacts when cutting
+ video sequence, which avoids artifacts when cutting
  for suggesting to add VDRVERSNUM to config.h
  for fixing a memory leak in cNonBlockingFileReader
  for fixing an uninitialized variable in cDisplayChannel
@@ -899,6 +899,7 @@
  for pointing out that the canonical spelling of codesets is with '-'
  for a hint on using _nl_msg_cat_cntr
  for adding some missing 'const' keywords
+ for pointing out that "%016llX" should be used instead of "%016LX"
 
 Thomas Koch <tom@harhar.net>
  for his support in keeping the Premiere World channels up to date in 'channels.conf'
@@ -1043,6 +1044,7 @@
  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
+ for increasing the valid range of the "Subtitle offset" setup option to -100...100
 
 Ralf Klueber <ralf.klueber@vodafone.com>
  for reporting a bug in cutting a recording if there is only a single editing mark
@@ -1060,6 +1062,8 @@
  for adding more error messages and line numbers when reading EPG data and info.vdr
  for fixing handling "more than 3 byte" key sequences in cKbdRemote::ReadKeySequence()
  for suggesting to ignore lines tagged with '#' in the 'info.vdr' file of a recording
+ for reporting a problem with the backslash ('\') in parameters when executing
+ external commands
 
 Alexander Damhuis <ad@phonedation.de>
  for reporting problems when deleting a timer that is currently recording
@@ -1082,7 +1086,7 @@
  for reporting a crash when canceling a newly created timer
  for making 'diseqc.conf' a required file only if Setup.DiSEqC is activated
  for making VDR use the default configuration directory as defined in the CONFDIR
- varable in the Makefile
+ variable in the Makefile
 
 Michael Walle <michael.walle@web.de>
  for reporting a bug in channel switching after Left/Right has been pressed
@@ -1163,6 +1167,8 @@
  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
+ for pointing out that cDevice::Transferring() doesn't return the right value in the
+ early stage of channel switching
 
 Richard Robson <richard_robson@beeb.net>
  for reporting freezing replay if a timer starts while in Transfer Mode from the
@@ -1350,7 +1356,7 @@
  for reporting a spelling error in 'canceling'
  for adding some 'mkdir -p' to the Makefile's 'install' target
  for reporting some missing braces in remux.c
- for suggesting to modifiy the Makefile to copy and clean up additional libraries
+ for suggesting to modify the Makefile to copy and clean up additional libraries
  a plugin might provide
 
 Marco Schlüßler <marco@lordzodiac.de>
@@ -1449,7 +1455,7 @@
  for fixing selecting the audio track when pressing Ok in the Audio menu
  for implementing handling DVB subtitles
  for fixing the description of DeviceSetAvailableTrack() and cReceiver(), and adding
- an example ~cMyReceiver() in PLUGINS.html (thanks to Marco Schlüßler).
+ an example ~cMyReceiver() in PLUGINS.html
  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,
@@ -1750,6 +1756,7 @@
  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
+ for fixing various spelling errors and improving PLUGINS.html
 
 Steffen Beyer <cpunk@reactor.de>
  for fixing setting the colored button help after deleting a recording in case the next
@@ -1884,7 +1891,7 @@
 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
  for making VDR use use daemon() instead of fork() to run in daemon mode
  for fixing a possible endless loop in a menu with no selectable items if
- Setup.MenuScrollWrap is true (thanks to Enrico Scholz)
+ Setup.MenuScrollWrap is true
 
 Nicolas Huillard <nhuillard@e-dition.fr>
  for translating OSD texts to the French language
@@ -2132,7 +2139,7 @@
 Anssi Hannula <anssi.hannula@gmail.com>
  for a patch that was used to implement processing the "frequency list descriptor"
  for suggesting that cDevice::GetDevice() should prefer any device that's already
- receiving and doesn't require detatching receivers
+ receiving and doesn't require detaching receivers
  for improving handling Transfer Mode devices when selecting a device to receive
  for fixing handling frequencies in NitFilter::Process()
  for making non-primary devices in Transfer mode be also used for recording
@@ -2202,11 +2209,12 @@
  for reporting that cPlugin::Active() was called too often
 
 Peter Pinnau <vdr@unterbrecher.de>
- for reporting that 'uint32_t' requires uncluding stdint.h in font.h on some systems
+ for reporting that 'uint32_t' requires including stdint.h in font.h on some systems
 
 Petri Helin <phelin@googlemail.com>
  for suggesting to avoid budget DVB cards with Common Interface when tuning to an
  FTA channel
+ for reporting a bug in setting the current subtitle track in Transfer-Mode
 
 Oktay Yolgeçen <oktay_73@yahoo.de>
  for translating OSD texts to the Turkish language
@@ -2299,3 +2307,6 @@
 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
+
+Carel Willemse <ca_willemse@planet.nl>
+ for translating OSD texts to the Dutch language
diff -ruN vdr-1.5.15/HISTORY vdr-1.5.16/HISTORY
--- vdr-1.5.15/HISTORY	2008-02-17 15:29:24.000000000 +0100
+++ vdr-1.5.16/HISTORY	2008-02-24 11:29:50.000000000 +0100
@@ -247,10 +247,10 @@
 2000-11-01: Version 0.67
 
 - The EIT information is now gathered in a separate thread.
-- The sytem time can now be synchronized to the time broadcast in the DVB data
+- The system time can now be synchronized to the time broadcast in the DVB data
   stream. This can be enabled in the "Setup" menu by setting "SetSystemTime" to
   1.  Note that this works only if VDR is running under a user ID that has
-  permisson to set the system time.
+  permission to set the system time.
 - The new item "Schedule" in the "Main" menu opens VDR's EPG (thanks to Robert
   Schneider). See the MANUAL file for a detailed description.
 - The new setup parameters MarginStart and MarginStop define how long (in
@@ -640,7 +640,7 @@
 - The new command line option '-E' can be used to define where the EPG data
   shall be written to. This is especially useful if VDR runs in a system
   that turns off the video disk when it is not used, and therefore needs
-  to write the EPG file to a ramdisk (or turn off writing it alltogether).
+  to write the EPG file to a ramdisk (or turn off writing it altogether).
   See 'vdr --help' for details.
 - Making sure the disk is up and running before starting recording (this
   is important for systems that turn off the video disk when it is not used).
@@ -776,7 +776,7 @@
   set to INVERSION_AUTO, which should work with all channels on Astra).
 - Removing unnecessary double quotes from EPG Subtitle in EPGBugfixLevel >=1.
 - EPG info is now updated if the contents changes but the ID remains the same.
-- Fixed handling SVDRP commands whith more than one blank between the command
+- Fixed handling SVDRP commands with more than one blank between the command
   word and the options.
 - The current volume setting is now saved to setup.conf and restored at the
   next program start.
@@ -907,7 +907,7 @@
   in the call to the shutdown command (option '-s') and the recording command
   (option '-r').
 - Improved error handling in the editing process; the resulting file will be
-  deleted if an error occured.
+  deleted if an error occurred.
 - A message is now prompted at the end of the editing process, indicating
   whether the process succeeded or failed.
 - Fixed setting the LastActivity timestamp after a shutdown prompt (thanks to
@@ -1058,7 +1058,7 @@
 - Changed the meaning of the 'Ca' parameter in 'channels.conf'. Each channel can
   now define which decryption method it needs in order to be accessed. The new
   configuration file 'ca.conf' contains the defined values, and the default
-  'channels.conf' has been modifed to contain the new values for 'Premiere World'
+  'channels.conf' has been modified to contain the new values for 'Premiere World'
   and 'ORF'. If you use the default 'channels.conf' and have the conditional
   access hardware to receive encrypted channels, please make sure you copy the
   file 'ca.conf' into your /video directory (or wherever your configuration files
@@ -1369,7 +1369,7 @@
   cPlayer and cControl have been given the functions GetIndex() and GetReplayMode() to
   allow access to the player's status.
 - Added cOsd::OpenRaw() to create a raw OSD (needed for displaying SPUs).
-- Changed the symantics of the Name parameter in cStatus::Recording() and
+- Changed the semantics of the Name parameter in cStatus::Recording() and
   cStatus::Replaying(). It is no longer the full directory name of the recording,
   but rather just the basic name. This has been changed to allow players that can't
   provide a name to simply use a string that describes the player type (like, e.g.,
@@ -1661,7 +1661,7 @@
 - Implemented new keys to directly access the VDR main menu functions "Schedule",
   "Channels", "Timers", "Recordings", "Setup" and "Commands". If your remote
   control provides keys you want to assign these functions to, you can delete
-  your 'remote.cof' file and restart VDR to  go through the key learning procedure
+  your 'remote.conf' file and restart VDR to  go through the key learning procedure
   again in order to assign these new keys. See MANUAL for more information.
 - The new configuration file 'keymacros.conf' can be used to assign macros to
   the color buttons in normal viewing mode, as well as to up to 9 user defined
@@ -1905,7 +1905,7 @@
 - Fixed handling channels in the "Channels" menu in case there are ':@nnn' group
   separators without names (thanks to Guy Roussin for reporting this one).
 - The SVDRP command CHAN now also accepts channel IDs.
-- Increased the timeout until an index file is considerd no longer to be written
+- Increased the timeout until an index file is considered no longer to be written
   (sometimes in time shift with heavy system load the index file was closed too
   early by the replay thread).
 - Implemented "Link Layer" based CAM support, which hopefully will solve the
@@ -2006,7 +2006,7 @@
 - Added some missing cAudio handling calls (thanks to Werner Fink).
 - Replaced the 'for' loops in StripAudioPackets() with memset() calls (thanks to
   Werner Fink).
-- Further increased the timeout until an index file is considerd no longer to be
+- Further increased the timeout until an index file is considered no longer to be
   written.
 - Fixed a crash in case the index file can't be accessed any more during replay
   (thanks to Stefan Huelswitt for reporting this one).
@@ -2068,7 +2068,7 @@
 - Fixed deleting the last recording in the "Recordings" menu, which started pausing
   live video (thanks to Christoph Friederich for reporting this one).
 - Now setting the "broken link" flag for GOPs at the beginning of a new video
-  sequence, which avoids artefacts when cutting (thanks to Stefan Huelswitt).
+  sequence, which avoids artifacts when cutting (thanks to Stefan Huelswitt).
 - Removed the Mute() call from cDvbDevice::StillPicture() (suggested by Andreas
   Schultz).
 - Updated 'channels.conf.terr' for Berlin (thanks to Andreas Brachold).
@@ -2136,7 +2136,7 @@
 - Updated 'channels.conf.terr' for Berlin (thanks to Juri Haberland).
 - Avoiding short display of the "Main" menu when pressing the "Recordings" button
   or the "Back" button during replay.
-- Further increased the timeout until an index file is considerd no longer to be
+- Further increased the timeout until an index file is considered no longer to be
   written.
 - Implemented separate PausePriority and PauseLifetime parameters for the recordings
   created when pausing live video (suggested by Alfred Zastrow).
@@ -2168,7 +2168,7 @@
 - Updated 'channels.conf.cable' (thanks to Stefan Hußfeldt).
 - Fixed reading 'epg.data' for channels with non-zero RID (thanks to Oliver
   Endriss for reporting this one).
-- Fixed EPG bugfix statistics to avoid log entires for undefined channels (thanks
+- Fixed EPG bugfix statistics to avoid log entries for undefined channels (thanks
   to Lars Bläser for reporting this one).
 - No longer waiting inside cIndexFile::CatchUp() to avoid shortly blocking replay
   at the end of a recording.
@@ -2218,7 +2218,7 @@
   Ahrenberg).
 - Completed the Italian OSD texts (thanks to Antonio Ospite).
 - Fixed breaking off replay in case the user hits "Play" or "Pause" too soon after
-  going into "Pause live video" mode (thanks to Karim Afifi for reporting ths one).
+  going into "Pause live video" mode (thanks to Karim Afifi for reporting this one).
 - Some corrections to the Catalanian OSD texts (thanks to Jordi Vilà).
 - Single event timers are now deleted if the recording they are doing is
   deleted before the timer ends.
@@ -2247,7 +2247,7 @@
   Josten).
 - Fixed device handling in the CICAM menu in case a VDR instance was started
   with a specific device using the -D option (thanks to Gerald Raaf for reporting
-  ths one).
+  this one).
 - Initializing the current channel to '1' to avoid a crash in creating a new
   timer in case there is no device in the system that can actually receive any
   channel (thanks to Malcolm Caldwell for reporting this one).
@@ -2448,7 +2448,7 @@
 2003-10-26: Version 1.2.6pre4
 
 - Fixed handling CAM menus in case the CAM connection fails while the menu
-  is being presented (thanks to Thomas v. Keller for reportign this one).
+  is being presented (thanks to Thomas v. Keller for reporting this one).
 - Added missing 'const' to some cChannel member functions (thanks to Torsten
   Herz).
 
@@ -2668,7 +2668,7 @@
   recording exceeds 10 (suggested by Gregoire Favre). Since the UPT error doesn't
   happen on my system, this has not been explicitly tested.
   The "preliminary fix" for the UPT error in VDR/dvbdevice.c has been disabled
-  by default, since it makes channel switching unpleasently slow. If you want
+  by default, since it makes channel switching unpleasantly slow. If you want
   to have that workaround back, you can uncomment the line
   //#define WAIT_FOR_LOCK_AFTER_TUNING 1
   in VDR/dvbdevice.c.
@@ -2815,7 +2815,7 @@
 - Added a hint to PLUGINS.html about how to name a plugin that implements a skin.
 - Completed the Finnish OSD texts (thanks to Rolf Ahrenberg).
 - Single shot timers and events now show the day of week (adopted with some changes
-  from the "elchi" patch, orginally introduced by Oskar Signell). Plugins that use
+  from the "elchi" patch, originally introduced by Oskar Signell). Plugins that use
   cEvent::GetDateString() should note that this function now returns a longer
   string, including the day of week. The new function const char *WeekDayName(time_t t)
   can be called with a time_t value to get the day of week for that time.
@@ -3267,7 +3267,7 @@
 - Skins need to implement the new cSkinDisplayTrack class to display the audio
   track menu.
 - The ST:TNG skin now displays the current audio track description (if any) at the
-  botton left side.
+  bottom left side.
 - The new setup option "DVB/Audio languages" can be used to control which audio
   language shall be selected in case a channel broadcasts in different languages
   (see MANUAL for details).
@@ -3959,7 +3959,7 @@
   (thanks to Holger Brunn).
 - The new function Skins.QueueMessage() can be called from a background thread
   to queue a message for display. See VDR/skins.h for details.
-- The SVDRP command MESG uses the new message queueing facility, so MESG
+- The SVDRP command MESG uses the new message queuing facility, so MESG
   commands may now be executed at any time, and the message will be displayed
   (no more "pending message").
 
@@ -4483,7 +4483,7 @@
 - Fixed a typo in skins.h (thanks to Alexander Rieger).
 - cSkins::QueueMessage() called from a background thread with an empty message
   now clears all messages that have been previously queued by that thread and have
-  not yet beed displayed (thanks to Alexander Rieger).
+  not yet been displayed (thanks to Alexander Rieger).
 - Fixed handling the color button texts when switching from the 'Schedule' menu of
   a channel without EPG info to the 'What's on now' menu (reported by Rolf
   Ahrenberg).
@@ -4736,7 +4736,7 @@
 - Fixed handling VPS timers in case the EPG event hasn't been 'seen' in a while.
 - Fixed calculating the cache size in cUnbufferedFile::Read() (thanks to Artur Skawina).
 - Removed -fPIC from VDR's and libsi's Makefile (suggested by Prakash Punnoor).
-- Modifed the device selection to better handle timer conflicts (reported by
+- Modified the device selection to better handle timer conflicts (reported by
   Christian Wieninger).
 - Avoiding a compiler warning in libsi's TypeLoop::operator[].
 - Now processing the "frequency list descriptor" (based on a patch from Anssi Hannula).
@@ -4827,7 +4827,7 @@
 - Fixed handling client side termination of SVDRP connections (thanks to Frank
   Schmirler).
 - cDevice::GetDevice() now prefers any device that's already receiving and doesn't
-  require detatching receivers (suggested by Anssi Hannula).
+  require detaching receivers (suggested by Anssi Hannula).
 - Fixed handling numeric keys in the channel display after switching channel groups
   (thanks to Andreas Regel).
 - Menu items derived from cMenuEditIntItem now loop though their values if they
@@ -4893,7 +4893,7 @@
 
 - Revoked the change to cDevice::GetDevice() that was introduced in version 1.4.1-2,
   which made it prefer any device that's already receiving and doesn't require
-  detatching receivers. This change has caused some unwanted behavior, so further
+  detaching receivers. This change has caused some unwanted behavior, so further
   testing is necessary.
 
 2006-09-03: Version 1.4.2-1
@@ -5041,7 +5041,7 @@
   decrypting the current channel again.
 - The Setup/CAM menu now dynamically refreshes its items and displays whether
   a CAM is present or ready. The 'Reset' function no longer leaves the menu.
-- The CAM menu will now be openend when pressing the Ok key on a slot entry.
+- The CAM menu will now be opened when pressing the Ok key on a slot entry.
 - The CAM menu now stays within the current menu context and doesn't close and
   reopen the menu every time an option is selected.
 - When an encrypted channel is switched to for the first time, VDR now checks
@@ -5400,7 +5400,7 @@
   texts they want to reuse from VDR's core translations (suggested by Matthias
   Becker).
 - VDR now uses the default configuration directory as defined in the CONFDIR
-  varable in the Makefile (thanks to Thomas Schmidt).
+  variable in the Makefile (thanks to Thomas Schmidt).
 - The SVDRP command LSTC can now list the channels with group separators if the
   option ':groups' is given (thanks to Andreas Mair).
 - Added a missing error report to cCuttingThread::Action() (thanks to Udo
@@ -5479,7 +5479,7 @@
   i18n: $(I18Npot) $(I18Nmo)
   (based on a suggestion by Torsten Kunkel).
 - Removed a duplicate ',' from the ca_ES.po file (thanks to Thomas Günther).
-- Added the 'ß' character to the "allowed charcaters" in the de_DE.po file
+- Added the 'ß' character to the "allowed characters" in the de_DE.po file
   (suggested by Thomas Günther).
 - Made the default copy ctor of cRecording private (thanks to Markus Hahn).
   Same for the assign operator.
@@ -5550,7 +5550,7 @@
 - Added a missing setting of lastFreeMB in cMenuMain::Update() (reported by
   Andreas Brugger).
 - Added '-Wno-parentheses' to the compiler options in order to avoid silly compiler
-  warnings for expessions like 'a || b && c', where GCC 4.3 wants to force the
+  warnings for expressions like 'a || b && c', where GCC 4.3 wants to force the
   programmer to write 'a || (b && c)', while everybody knows that '&&' links
   stronger than '||' (reported by Tobias Grimm).
 - Updated the Hungarian language texts (thanks to István Füley).
@@ -5572,7 +5572,7 @@
 - The new option --localedir can be used to set the locale directory at runtime
   (based on a patch from Stefan Huelswitt).
 - Fixed finding new transponders (thanks to Winfried Köhler).
-- Implemented handling of DVB-S2 (thanks to Marco Schlüßler and Reinhald Nissl
+- Implemented handling of DVB-S2 (thanks to Marco Schlüßler and Reinhard Nissl
   for a patch that was used to implement this). VDR now requires the "multiproto"
   DVB driver, e.g. from http://jusst.de/hg/multiproto.
 - Removed switching to the next higher or lower channel if the current channel
@@ -5643,3 +5643,30 @@
 - Introduced 'operator const void * ()' in cString to catch cases where operator*()
   should be used.
 - Fixed calculating the scrollbar sizes in the skins.
+
+2008-02-24: Version 1.5.16
+
+- Fixed setting the current subtitle track in Transfer-Mode (reported by Petri Helin,
+  thanks to Reinhard Nissl for pointing out that cDevice::Transferring() doesn't
+  return the right value in the early stage of channel switching).
+- Updated the Danish OSD texts (thanks to Mogens Elneff).
+- Updated the Dutch OSD texts (thanks to Carel Willemse).
+- Fixed various spelling errors and improved PLUGINS.html (thanks to Ville Skyttä).
+- Updated the Italian OSD texts (thanks to Diego Pierotto).
+- Fixed the format in cRemote::Put() to use "%016llX" instead of "%016LX" (thanks
+  to Ludwig Nussel for pointing this out).
+- Revised the fix of calculating the scrollbar height in the skins. The scrollbar
+  handle now always has a height that is at least the width of the scrollbar.
+- When switching the device that's used for live viewing away from the current
+  transponder in favor of an upcoming recording, an attempt is now made to stay
+  on the current channel by possibly going into 'Transfer Mode'.
+- The CAM menu now stays open as long as it is automatically updated, even without
+  pressing a remote control key. This is important when updating the CAM firmware
+  from the transponder.
+- No longer trying to switch to an available channel if the primary device has
+  no valid programme and a menu is open (avoids interference with the CAM in
+  case a CAM menu is open).
+- Increased the valid range of the "Subtitle offset" setup option to -100...100
+  (thanks to Rolf Ahrenberg).
+- Added the backslash ('\') to the list of characters that need to be escaped
+  when executing external commands (thanks to Peter Bieringer for reporting this one).
diff -ruN vdr-1.5.15/MANUAL vdr-1.5.16/MANUAL
--- vdr-1.5.15/MANUAL	2008-02-10 15:23:48.000000000 +0100
+++ vdr-1.5.16/MANUAL	2008-02-24 11:09:17.000000000 +0100
@@ -691,8 +691,8 @@
                          individual preferred languages.
 
   Subtitle offset = 0    Allows you to shift the location of the subtitles in the
-                         vertical direction. The valid range is -50...50. This option
-                         is only avialable if "Display subtitles" is set to 'yes'.
+                         vertical direction. The valid range is -100...100. This option
+                         is only available if "Display subtitles" is set to 'yes'.
 
   Subtitle foreground transparency = 0
   Subtitle background transparency = 0
diff -ruN vdr-1.5.15/PLUGINS/src/skincurses/HISTORY vdr-1.5.16/PLUGINS/src/skincurses/HISTORY
--- vdr-1.5.15/PLUGINS/src/skincurses/HISTORY	2008-02-17 15:28:26.000000000 +0100
+++ vdr-1.5.16/PLUGINS/src/skincurses/HISTORY	2008-02-23 11:50:28.000000000 +0100
@@ -70,3 +70,8 @@
 
 - Using cString::sprintf() instead of asprintf().
 - Implemented cSkinCursesDisplayMenu::SetScrollbar().
+
+2008-02-23: Version 0.1.6
+
+- Revised the fix of calculating the scrollbar height in the skins. The scrollbar
+  handle now always has a height that is at least the width of the scrollbar.
diff -ruN vdr-1.5.15/PLUGINS/src/skincurses/skincurses.c vdr-1.5.16/PLUGINS/src/skincurses/skincurses.c
--- vdr-1.5.15/PLUGINS/src/skincurses/skincurses.c	2008-02-17 15:28:19.000000000 +0100
+++ vdr-1.5.16/PLUGINS/src/skincurses/skincurses.c	2008-02-23 11:38:04.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: skincurses.c 1.20 2008/02/17 14:28:19 kls Exp $
+ * $Id: skincurses.c 1.22 2008/02/23 10:38:04 kls Exp $
  */
 
 #include <ncurses.h>
@@ -11,7 +11,7 @@
 #include <vdr/plugin.h>
 #include <vdr/skins.h>
 
-static const char *VERSION        = "0.1.5";
+static const char *VERSION        = "0.1.6";
 static const char *DESCRIPTION    = trNOOP("A text only skin");
 static const char *MAINMENUENTRY  = NULL;
 
@@ -296,14 +296,15 @@
 {
   if (Total > 0 && Total > Shown) {
      int yt = Top;
-     int yb = yt + Height - 1;
+     int yb = yt + Height;
      int st = yt;
      int sb = yb;
-     int tt = st + (sb - st + 1) * Offset / Total;
-     int tb = tt + (sb - st + 1) * Shown / Total;
+     int th = max(int((sb - st) * double(Shown) / Total + 0.5), 1);
+     int tt = min(int(st + (sb - st) * double(Offset) / Total + 0.5), sb - th);
+     int tb = min(tt + th, sb);
      int xl = ScOsdWidth - 1;
-     osd->DrawRectangle(xl, st, xl, sb, clrWhite);
-     osd->DrawRectangle(xl, tt, xl, tb, clrCyan);
+     osd->DrawRectangle(xl, st, xl, sb - 1, clrWhite);
+     osd->DrawRectangle(xl, tt, xl, tb - 1, clrCyan);
      }
 }
 
diff -ruN vdr-1.5.15/PLUGINS.html vdr-1.5.16/PLUGINS.html
--- vdr-1.5.15/PLUGINS.html	2008-02-10 15:22:21.000000000 +0100
+++ vdr-1.5.16/PLUGINS.html	2008-02-18 21:40:08.000000000 +0100
@@ -1,18 +1,36 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
 <html>
 <head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <title>The VDR Plugin System</title>
+<style type="text/css">
+html, body {
+    background-color: white;
+}
+.blurb {
+    font-style: italic;
+    font-weight: bold;
+    text-align: center;
+}
+.center {
+    text-align: center;
+}
+.code {
+    background-color: #f0f0f0;
+}
+</style>
 </head>
-<body bgcolor="white">
+<body>
 
-<center><h1>The VDR Plugin System</h1></center>
+<div class="center">
+<h1>The VDR Plugin System</h1>
 
-<center><b>Version 1.6</b></center>
+<b>Version 1.6</b>
 <p>
-<center>
 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>
+</div>
 <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.
@@ -78,11 +96,11 @@
 </ul>
 </ul>
 
-<a name="Part I - The External Interface"><hr><center><h1>Part I - The External Interface</h1></center>
+<hr><h1 class="center"><a name="Part I - The External Interface">Part I - The External Interface</a></h1>
 
-<a name="Quick start"><hr><h2>Quick start</h2>
+<hr><h2><a name="Quick start">Quick start</a></h2>
 
-<center><i><b>Can't wait, can't wait!</b></i></center><p>
+<div class="blurb">Can't wait, can't wait!</div><p>
 
 Actually you should read this entire document before starting to work with VDR plugins,
 but you probably want to see something happening right away <tt>;-)</tt>
@@ -102,9 +120,9 @@
 If you enjoyed this brief glimpse into VDR plugin handling, read through the rest of
 this document and eventually write your own VDR plugin.
 
-<a name="The name of the plugin"><hr><h2>The name of the plugin</h2>
+<hr><h2><a name="The name of the plugin">The name of the plugin</a></h2>
 
-<center><i><b>Give me some I.D.!</b></i></center><p>
+<div class="blurb">Give me some I.D.!</div><p>
 
 One of the first things to consider when writing a VDR plugin is giving the thing
 a proper name. This name will be used in the VDR command line in order to load
@@ -119,22 +137,22 @@
 <p>
 A plugin can access its name through the (non virtual) member function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 const char *Name(void);
 </pre></td></tr></table><p>
 
 The actual name is derived from the plugin's library file name, as defined in the
 next chapter.
 
-<a name="The plugin directory structure"><hr><h2>The plugin directory structure</h2>
+<hr><h2><a name="The plugin directory structure">The plugin directory structure</a></h2>
 
-<center><i><b>Where is everybody?</b></i></center><p>
+<div class="blurb">Where is everybody?</div><p>
 
 By default plugins are located in a directory named <tt>PLUGINS</tt> below the
 VDR source directory. Inside this directory the following subdirectory structure
 is used:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 VDR/PLUGINS/src
 VDR/PLUGINS/src/hello
 VDR/PLUGINS/lib
@@ -154,7 +172,7 @@
 <p>
 <table border=2>
 <tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>hello</tt></b></td><td align=center><b><tt>.so.</tt></b></td><td align=center><b><tt>1.1.0</tt></b></td></tr>
-<tr><td align=center><font size=-1>VDR plugin<br>library prefix</font></td><td align=center><font size=-1>name of<br>the plugin</font></td><td align=center><font size=-1>shared object<br>indicator</font></td><td align=center><font size=-1>API version number<br>this plugin was<br>compiled for</font></td></tr>
+<tr><td align=center><small>VDR plugin<br>library prefix</small></td><td align=center><small>name of<br>the plugin</small></td><td align=center><small>shared object<br>indicator</small></td><td align=center><small>API version number<br>this plugin was<br>compiled for</small></td></tr>
 </table>
 <p>
 The <i>API version number</i> refers to the plugin API version number of the VDR
@@ -186,7 +204,7 @@
 you need to unpack such an archive into the <tt>VDR/PLUGINS/src</tt> directory and
 create a symbolic link with the basic plugin name, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 ln -s hello-0.0.1 hello
 </pre></td></tr></table><p>
 
@@ -206,9 +224,9 @@
 <tt>libhello-bar.so.0.0.1</tt>
 <p>
 
-<a name="Initializing a new plugin directory"><hr><h2>Initializing a new plugin directory</h2>
+<hr><h2><a name="Initializing a new plugin directory">Initializing a new plugin directory</a></h2>
 
-<center><i><b>A room with a view</b></i></center><p>
+<div class="blurb">A room with a view</div><p>
 
 Call the Perl script <tt>newplugin</tt> from the VDR source directory to create
 a new plugin directory with a <tt>Makefile</tt> and a main source file implementing
@@ -225,9 +243,9 @@
 Add further files and maybe subdirectories to your plugin source directory as
 necessary. Don't forget to adapt the <tt>Makefile</tt> appropriately.
 
-<a name="The actual implementation"><hr><h2>The actual implementation</h2>
+<hr><h2><a name="The actual implementation">The actual implementation</a></h2>
 
-<center><i><b>Use the source, Luke!</b></i></center><p>
+<div class="blurb">Use the source, Luke!</div><p>
 
 A newly initialized plugin doesn't really do very much yet.
 If you <a href="#Loading plugins into VDR">load it into VDR</a> you will find a new
@@ -250,7 +268,7 @@
 <p>
 At the end of the plugin's source file you will find a line that looks like this:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 VDRPLUGINCREATOR(cPluginHello);
 </pre></td></tr></table><p>
 
@@ -263,7 +281,7 @@
 Header files usually contain preprocessor statements that prevent the same
 file (or rather its contents, to be precise) from being included more than once, like
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #ifndef __I18N_H
 #define __I18N_H
 
@@ -292,13 +310,13 @@
 <tt>i18n.h</tt> it uses the macro <tt>_I18N__H</tt> (one underline at the beginning
 and two replacing the dot).
 
-<a name="Construction and Destruction"><hr><h2>Construction and Destruction</h2>
+<hr><h2><a name="Construction and Destruction">Construction and Destruction</a></h2>
 
-<center><i><b>What goes up, must come down...</b></i></center><p>
+<div class="blurb">What goes up, must come down...</div><p>
 
 The constructor and destructor of a plugin are defined as
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 cPlugin(void);
 virtual ~cPlugin();
 </pre></td></tr></table><p>
@@ -321,15 +339,15 @@
 Of course, if your plugin doesn't define any member variables that need to be
 initialized (and deleted), you don't need to implement either of these functions.
 
-<a name="Version number"><hr><h2>Version number</h2>
+<hr><h2><a name="Version number">Version number</a></h2>
 
-<center><i><b>Which incarnation is this?</b></i></center><p>
+<div class="blurb">Which incarnation is this?</div><p>
 
 Every plugin must have a version number of its own, which does not necessarily
 have to be in any way related to the VDR version number.
 VDR requests a plugin's version number through a call to the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual const char *Version(void) = 0;
 </pre></td></tr></table><p>
 
@@ -340,7 +358,7 @@
 be as long as really necessary, and shall not contain the plugin's name itself.
 Here's an example:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 static const char *VERSION = "0.0.1";
 
 const char *cPluginHello::Version(void)
@@ -354,6 +372,7 @@
 <pre>
 static const char *VERSION = ...
 </pre>
+<p>
 just like shown in the above example. This is a convention that allows the <tt>Makefile</tt>
 to extract the version number when generating the file name for the distribution archive.
 <p>
@@ -366,19 +385,19 @@
 a version number are not limited to single digits, so a version number of <tt>1.2.15</tt>
 would be acceptable.
 
-<a name="Description"><hr><h2>Description</h2>
+<hr><h2><a name="Description">Description</a></h2>
 
-<center><i><b>What is it that you do?</b></i></center><p>
+<div class="blurb">What is it that you do?</div><p>
 
 In order to tell the user what exactly a plugin does, it must implement the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual const char *Description(void) = 0;
 </pre></td></tr></table><p>
 
 which returns a short, one line description of the plugin's purpose:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 static const char *DESCRIPTION = "A friendly greeting";
 
 virtual const char *Description(void)
@@ -390,15 +409,15 @@
 Note the <tt>tr()</tt> around the <tt>DESCRIPTION</tt>, which allows the description
 to be <a href="#Internationalization">internationalized</a>.
 
-<a name="Command line arguments"><hr><h2>Command line arguments</h2>
+<hr><h2><a name="Command line arguments">Command line arguments</a></h2>
 
-<center><i><b>Taking orders</b></i></center><p>
+<div class="blurb">Taking orders</div><p>
 
 A VDR plugin can have command line arguments just like any normal program.
 If a plugin wants to react on command line arguments, it needs to implement
 the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual bool ProcessArgs(int argc, char *argv[]);
 </pre></td></tr></table><p>
 
@@ -415,7 +434,7 @@
 will survive the entire lifetime of the plugin, so it is safe to store pointers to
 these values inside the plugin. Here's an example:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 bool cPluginHello::ProcessArgs(int argc, char *argv[])
 {
   // Implement command line argument processing here if applicable.
@@ -444,13 +463,13 @@
 <i>false</i> from a call to its <tt>ProcessArgs()</tt> function will cause VDR
 to exit.
 
-<a name="Command line help"><hr><h2>Command line help</h2>
+<hr><h2><a name="Command line help">Command line help</a></h2>
 
-<center><i><b>Tell me about it...</b></i></center><p>
+<div class="blurb">Tell me about it...</div><p>
 
 If a plugin accepts command line options, it should implement the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual const char *CommandLineHelp(void);
 </pre></td></tr></table><p>
 
@@ -458,7 +477,7 @@
 The returned string should contain the command line help for this plugin, formatted
 in the same way as done by VDR itself:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 const char *cPluginHello::CommandLineHelp(void)
 {
   // Return a string that describes all known command line options.
@@ -473,15 +492,15 @@
 Note that all lines should be terminated with a newline character, and should
 be shorter than 80 characters.
 
-<a name="Getting started"><hr><h2>Getting started</h2>
+<hr><h2><a name="Getting started">Getting started</a></h2>
 
-<center><i><b>Let's get ready to rumble!</b></i></center><p>
+<div class="blurb">Let's get ready to rumble!</div><p>
 
 If a plugin implements a function that runs in the background (presumably in a
 thread of its own), or wants to make use of <a href="#Internationalization">internationalization</a>,
 it needs to implement one of the functions
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual bool Initialize(void);
 virtual bool Start(void);
 </pre></td></tr></table><p>
@@ -511,13 +530,13 @@
 If the plugin doesn't implement any background functionality or internationalized
 texts, it doesn't need to implement either of these functions.
 
-<a name="Shutting down"><hr><h2>Shutting down</h2>
+<hr><h2><a name="Shutting down">Shutting down</a></h2>
 
-<center><i><b>Stop it, right there!</b></i></center><p>
+<div class="blurb">Stop it, right there!</div><p>
 
 If a plugin performs any background tasks, it shall implement the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual void Stop(void);
 </pre></td></tr></table><p>
 
@@ -528,8 +547,9 @@
 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.
 
-<a name="Logging"><hr><h2>Logging</h2>
+<hr><h2><a name="Logging">Logging</a></h2>
 
+<p>
 If the plugin should print log messages, you can use <tt>dsyslog()</tt>, <tt>isyslog()</tt> or <tt>esyslog()</tt>.<br>
 <ul>
 <li><tt>dsyslog()</tt> prints the log message only if the log level of vdr is set to 3.
@@ -539,21 +559,21 @@
 The output of this log is the syslog of the system vdr is running on.
 The logmessage can be formatted like <tt>printf()</tt>, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 esyslog("pluginname: error #%d has occurred", ErrorNumber);
 </pre></td></tr></table><p>
 
 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.
+automatically be added, so make sure your log messages are obvious enough.
 
-<a name="Main menu entry"><hr><h2>Main menu entry</h2>
+<hr><h2><a name="Main menu entry">Main menu entry</a></h2>
 
-<center><i><b>Today's special is...</b></i></center><p>
+<div class="blurb">Today's special is...</div><p>
 
 If the plugin implements a feature that the user shall be able to access
 from VDR's main menu, it needs to implement the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual const char *MainMenuEntry(void);
 </pre></td></tr></table><p>
 
@@ -561,7 +581,7 @@
 this plugin will not have an item in the main menu. Here's an example of a
 plugin that will have a main menu item:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 static const char *MAINMENUENTRY = "Hello";
 
 const char *cPluginHello::MainMenuEntry(void)
@@ -574,13 +594,13 @@
 after the <i>Recordings</i> item, in the same sequence as they were given
 in the call to VDR.
 
-<a name="User interaction"><hr><h2>User interaction</h2>
+<hr><h2><a name="User interaction">User interaction</a></h2>
 
-<center><i><b>It's showtime!</b></i></center><p>
+<div class="blurb">It's showtime!</div><p>
 
 If the user selects the main menu entry of a plugin, VDR calls the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual cOsdObject *MainMenuAction(void);
 </pre></td></tr></table><p>
 
@@ -607,14 +627,14 @@
 the plugin should launch a separate thread to do this.
 </b>
 
-<a name="Housekeeping"><hr><h2>Housekeeping</h2>
+<hr><h2><a name="Housekeeping">Housekeeping</a></h2>
 
-<center><i><b>Chores, chores...</b></i></center><p>
+<div class="blurb">Chores, chores...</div><p>
 
 From time to time a plugin may want to do some regular tasks, like cleaning
 up some files or other things. In order to do this it can implement the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual void Housekeeping(void);
 </pre></td></tr></table><p>
 
@@ -632,9 +652,9 @@
 the plugin should launch a separate thread to do this.
 </b>
 
-<a name="Main thread hook"><hr><h2>Main thread hook</h2>
+<hr><h2><a name="Main thread hook">Main thread hook</a></h2>
 
-<center><i><b>Pushing in...</b></i></center><p>
+<div class="blurb">Pushing in...</div><p>
 
 Normally a plugin only reacts on user input if directly called through its
 <a href="#Main menu entry">main menu entry</a>, or performs some background
@@ -642,7 +662,7 @@
 something in the context of the main program thread, without being explicitly
 called up by the user. In such a case it can implement the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual void MainThreadHook(void);
 </pre></td></tr></table><p>
 
@@ -653,21 +673,21 @@
 as soon as possible! If you spend too much time in this function, the user
 interface performance will become sluggish!</b>
 
-<a name="Activity"><hr><h2>Activity</h2>
+<hr><h2><a name="Activity">Activity</a></h2>
 
-<center><i><b>Now is not a good time!</b></i></center><p>
+<div class="blurb">Now is not a good time!</div><p>
 
 If a plugin is running a background task that should be finished before shutting
 down the system, it can implement the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual cString Active(void);
 </pre></td></tr></table><p>
 
 which shall return an empty string if it is ok to shut down, and a proper message
 if not:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 cString cDoSomethingPlugin::Active(void)
 {
   if (busy)
@@ -689,15 +709,15 @@
 the shutdown will take place. As soon as one prompt is not confirmed, no
 further plugins will be queried and no shutdown will be done.
 
-<a name="Wakeup"><hr><h2>Wakeup</h2>
+<hr><h2><a name="Wakeup">Wakeup</a></h2>
 
-<center><i><b>Wake me up before you go-go</b></i></center><p>
+<div class="blurb">Wake me up before you go-go</div><p>
 
 If a plugin wants to schedule activity for a later time, or wants to perform
 periodic activity at a certain time at night, and if VDR shall wake up from
 shutdown at that time, the plugin can implement the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual time_t WakeupTime(void);
 </pre></td></tr></table><p>
 
@@ -706,7 +726,7 @@
 timer time, whichever comes first, to the shutdown script. The following sample
 will wake up VDR every night at 1:00:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 time_t MyPlugin::WakeupTime(void)
 {
   time_t Now = time(NULL);
@@ -722,14 +742,14 @@
 again instantly. If <tt>WakeupTime()</tt> returns a time that is not in
 the future, the time will be ignored.
 
-<a name="Setup parameters"><hr><h2>Setup parameters</h2>
+<hr><h2><a name="Setup parameters">Setup parameters</a></h2>
 
-<center><i><b>Remember me...</b></i></center><p>
+<div class="blurb">Remember me...</div><p>
 
 If a plugin requires its own setup parameters, it needs to implement the following
 functions to handle these parameters:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual cMenuSetupPage *SetupMenu(void);
 virtual bool SetupParse(const char *Name, const char *Value);
 </pre></td></tr></table><p>
@@ -744,7 +764,7 @@
 the log file (and program execution will continue).
 A possible implementation of <tt>SetupParse()</tt> could look like this:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 bool cPluginHello::SetupParse(const char *Name, const char *Value)
 {
   // Parse your own setup parameters and store their values.
@@ -770,7 +790,7 @@
 <p>
 To store its values in the global setup, a plugin has to call the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 void SetupStore(const char *Name, <i>type</i> Value);
 </pre></td></tr></table><p>
 
@@ -795,15 +815,15 @@
 <tt>SetupStore()</tt> and <tt>SetupParse()</tt> without presenting these
 parameters to the user.
 
-<a name="The Setup menu"><hr><h2>The Setup menu</h2>
+<hr><h2><a name="The Setup menu">The Setup menu</a></h2>
 
-<center><i><b>Have it your way!</b></i></center><p>
+<div class="blurb">Have it your way!</div><p>
 
 To implement a <i>Setup</i> menu, a plugin needs to derive a class from
 <tt>cMenuSetupPage</tt> and implement its constructor and the pure virtual
 <tt>Store()</tt> member function:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 int GreetingTime = 3;
 int UseAlternateGreeting = false;
 
@@ -853,9 +873,9 @@
 your setup parameters and use that one to copy all parameters with one single statement
 (like VDR does with its cSetup class).
 
-<a name="Configuration files"><hr><h2>Configuration files</h2>
+<hr><h2><a name="Configuration files">Configuration files</a></h2>
 
-<center><i><b>I want my own stuff!</b></i></center><p>
+<div class="blurb">I want my own stuff!</div><p>
 
 There may be situations where a plugin requires configuration files of its own, maybe
 for data that can't be stored in the simple <a href="#Setup parameters">setup parameters</a>
@@ -864,7 +884,7 @@
 sees fit, it might be a good idea to put them in a common place, preferably
 where other configuration data already exists. VDR provides the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 const char *ConfigDirectory(const char *PluginName = NULL);
 </pre></td></tr></table><p>
 
@@ -887,7 +907,7 @@
 the <tt>ConfigDirectory()</tt> function can be given an additional string that will
 be appended to the returned directory name, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 const char *MyConfigDir = ConfigDirectory(Name());
 </pre></td></tr></table><p>
 
@@ -904,19 +924,19 @@
 class. This allows it to be called even from outside any member function of the derived
 plugin class, by writing
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 const char *MyConfigDir = cPlugin::ConfigDirectory();
 </pre></td></tr></table><p>
 
-<a name="Internationalization"><hr><h2>Internationalization</h2>
+<hr><h2><a name="Internationalization">Internationalization</a></h2>
 
-<center><i><b>Welcome to Babylon!</b></i></center><p>
+<div class="blurb">Welcome to Babylon!</div><p>
 
 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
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 const char *s = tr("Hello world!");
 </pre></td></tr></table><p>
 
@@ -931,7 +951,7 @@
 differently, using the trNOOP() macro. The actual translation is then done
 when such a text is used, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 const char *Texts = {
   trNOOP("First text"),
   trNOOP("Second text"),
@@ -954,9 +974,9 @@
 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.
 
-<a name="Custom services"><hr><h2>Custom services</h2>
+<hr><h2><a name="Custom services">Custom services</a></h2>
 
-<center><i><b>What can I do for you?</b></i></center><p>
+<div class="blurb">What can I do for you?</div><p>
 
 In some situations, two plugins may want to communicate directly, talking about things
 that VDR doesn't handle itself. For example, a plugin may want to use features
@@ -964,7 +984,7 @@
 things it does. To receive requests or messages, a plugin can implement the
 following function:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual bool Service(const char *Id, void *Data = NULL);
 </pre></td></tr></table><p>
 
@@ -981,7 +1001,7 @@
 may be called, for example whether the service may be called from every thread, or
 just from the main thread. A possible implementation could look like this:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 struct Hello_SetGreetingTime_v1_0 {
   int NewGreetingTime;
   };
@@ -1004,7 +1024,7 @@
 To send messages to, or request services from a specific plugin, one plugin can directly
 call another plugin's service function:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 Hello_SetGreetingTime_v1_0 hellodata;
 hellodata.NewGreetingTime = 3;
 cPlugin *Plugin = cPluginManager::GetPlugin("hello");
@@ -1022,21 +1042,21 @@
 <tt>cPluginManager::CallAllServices()</tt>. This function returns <tt>true</tt> if
 any plugin handled the request, or <tt>false</tt> if no plugin handled the request.
 
-<a name="SVDRP commands"><hr><h2>SVDRP commands</h2>
+<hr><h2><a name="SVDRP commands">SVDRP commands</a></h2>
 
-<center><i><b>Infinite Diversity in Infinite Combinations</b></i></center><p>
+<div class="blurb">Infinite Diversity in Infinite Combinations</div><p>
 
 A plugin can implement its own SVDRP commands through the two functions
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual const char **SVDRPHelpPages(void);
-virtual cString SVDRPCommand(const char *Cmd, const char *Option, int &ReplyCode);
+virtual cString SVDRPCommand(const char *Cmd, const char *Option, int &amp;ReplyCode);
 </pre></td></tr></table><p>
 
 The <tt>SVDRPHelpPages()</tt> function must return a pointer to a list of help
 strings for all of the plugin's SVDRP commands, like this
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 const char **cPluginSvdrpdemo::SVDRPHelpPages(void)
 {
   static const char *HelpPages[] = {
@@ -1067,8 +1087,8 @@
 Here's an example of such a function, which implements the commands advertised in
 the above help texts:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
-cString cPluginSvdrpdemo::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
+<p><table><tr><td class="code"><pre>
+cString cPluginSvdrpdemo::SVDRPCommand(const char *Command, const char *Option, int &amp;ReplyCode)
 {
   if (strcasecmp(Command, "DATE") == 0) {
      // we use the default reply code here
@@ -1113,26 +1133,26 @@
 when presenting them to the caller, and the continuation character ('<tt>-</tt>')
 will be set for all but the last one.
 
-<a name="Loading plugins into VDR"><hr><h2>Loading plugins into VDR</h2>
+<hr><h2><a name="Loading plugins into VDR">Loading plugins into VDR</a></h2>
 
-<center><i><b>Saddling up!</b></i></center><p>
+<div class="blurb">Saddling up!</div><p>
 
 Plugins are loaded into VDR using the command line option <b><tt>-P</tt></b>, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 vdr -Phello
 </pre></td></tr></table><p>
 
 If the plugin accepts command line options, they are given as part of the argument
 to the <b><tt>-P</tt></b> option, which then has to be enclosed in quotes:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 vdr -P"hello -a abc -b"
 </pre></td></tr></table><p>
 
 Any number of plugins can be loaded this way, each with its own <b><tt>-P</tt></b> option:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 vdr -P"hello -a abc -b" -Pdvd -Pmp3
 </pre></td></tr></table><p>
 
@@ -1140,7 +1160,7 @@
 cannot be found at their default location) you need to tell VDR the location of
 the plugins through the <b><tt>-L</tt></b> option:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 vdr -L/usr/lib/vdr -Phello
 </pre></td></tr></table><p>
 
@@ -1153,9 +1173,9 @@
 <a href="#The plugin directory structure">naming convention</a>,
 and display their help and/or version information in addition to its own output.
 
-<a name="Building the distribution package"><hr><h2>Building the distribution package</h2>
+<hr><h2><a name="Building the distribution package">Building the distribution package</a></h2>
 
-<center><i><b>Let's get this show on the road!</b></i></center><p>
+<div class="blurb">Let's get this show on the road!</div><p>
 
 If you want to make your plugin available to other VDR users, you'll need to
 make a package that can be easily distributed.
@@ -1165,30 +1185,30 @@
 <p>
 Simply change into your source directory and execute <tt>make dist</tt>:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 cd VDR/PLUGINS/src/hello
 make dist
 </pre></td></tr></table><p>
 
 After this you should find a file named like
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 vdr-hello-0.0.1.tgz
 </pre></td></tr></table><p>
 
 in your source directory, where <tt>hello</tt> will be replaced with your actual
 plugin's name, and <tt>0.0.1</tt> will be your plugin's current version number.
 
-<a name="Part II - The Internal Interface"><hr><center><h1>Part II - The Internal Interface</h1></center>
+<hr><h1 class="center"><a name="Part II - The Internal Interface">Part II - The Internal Interface</a></h1>
 
-<a name="Status monitor"><hr><h2>Status monitor</h2>
+<hr><h2><a name="Status monitor">Status monitor</a></h2>
 
-<center><i><b>A piece of the action</b></i></center><p>
+<div class="blurb">A piece of the action</div><p>
 
 If a plugin wants to get informed on various events in VDR, it can derive a class from
 <tt>cStatus</tt>, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/status.h&gt;
 
 class cMyStatusMonitor : public cStatus {
@@ -1208,7 +1228,7 @@
 An object of this class will be informed whenever the channel is switched on one of
 the DVB devices. It could be used in a plugin like this:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/plugin.h&gt;
 
 class cPluginStatus : public cPlugin {
@@ -1254,14 +1274,14 @@
 member functions are available in <tt>cStatus</tt>. You only need to implement
 the functions you actually want to use.
 
-<a name="Players"><hr><h2>Players</h2>
+<hr><h2><a name="Players">Players</a></h2>
 
-<center><i><b>Play it again, Sam!</b></i></center><p>
+<div class="blurb">Play it again, Sam!</div><p>
 
 Implementing a player is a two step process.
 First you need the actual player class, which is derived from the abstract <tt>cPlayer</tt>:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/player.h&gt;
 
 class cMyPlayer : public cPlayer {
@@ -1277,7 +1297,7 @@
 thread which, e.g.,  reads data from a file, you can additionally derive your class from
 <tt>cThread</tt> and implement the necessary functionality:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/player.h&gt;
 
 class cMyPlayer : public cPlayer, cThread {
@@ -1295,7 +1315,7 @@
 <p>
 To play the actual data, the player needs to call its member function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 int PlayPes(const uchar *Data, int Length, bool VideoOnly);
 </pre></td></tr></table><p>
 
@@ -1308,7 +1328,7 @@
 DVB device doesn't run out of data.
 To avoid busy loops the player should call its member function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 bool DevicePoll(cPoller &amp;Poller, int TimeoutMs = 0);
 </pre></td></tr></table><p>
 
@@ -1320,14 +1340,14 @@
 requirements in order to set a given track, it can implement the
 following function to allow the device to set a specific track:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId)
 </pre></td></tr></table><p>
 
 A player that has special requirements about audio tracks should announce its
 available audio tracks by calling
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 bool DeviceSetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, const char *Description = NULL)
 </pre></td></tr></table><p>
 
@@ -1336,7 +1356,7 @@
 The second part needed here is a control object that receives user input from the main
 program loop and reacts on this by telling the player what to do:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/player.h&gt;
 
 class cMyControl : public cControl {
@@ -1355,7 +1375,7 @@
 hand over a pointer to it to the <tt>cControl</tt> base class, so that it
 can be later attached to the primary DVB device:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 cMyControl::cMyControl(void)
 :cControl(player = new cMyPlayer)
 {
@@ -1386,7 +1406,7 @@
 infrastructure like displaying a list of playable stuff etc) simply has to call the
 static function <tt>cControl::Launch()</tt> with the player control object, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 cControl::Launch(new cMyControl);
 </pre></td></tr></table><p>
 
@@ -1397,7 +1417,7 @@
 <p>
 The <tt>cPlayer</tt> class has a member function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 void DeviceStillPicture(const uchar *Data, int Length);
 </pre></td></tr></table><p>
 
@@ -1435,14 +1455,14 @@
 that they already know. If you absolutely want to do things differently, just go
 ahead - it's your show...
 
-<a name="Receivers"><hr><h2>Receivers</h2>
+<hr><h2><a name="Receivers">Receivers</a></h2>
 
-<center><i><b>Tapping into the stream...</b></i></center><p>
+<div class="blurb">Tapping into the stream...</div><p>
 
 In order to receive any kind of data from a <tt>cDevice</tt>, a plugin must set up an
 object derived from the <tt>cReceiver</tt> class:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/receiver.h&gt;
 
 class cMyReceiver : public cReceiver, cThread {
@@ -1486,7 +1506,7 @@
 Once a <tt>cReceiver</tt> has been created, it needs to be <i>attached</i> to
 a <tt>cDevice</tt>:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 cMyReceiver *Receiver = new cMyReceiver(123);
 
 cDevice::ActualDevice()-&gt;AttachReceiver(Receiver);
@@ -1500,15 +1520,15 @@
 If the <tt>cReceiver</tt> isn't needed any more, it may simply be <i>deleted</i>
 and will automatically detach itself from the <tt>cDevice</tt>.
 
-<a name="Filters"><hr><h2>Filters</h2>
+<hr><h2><a name="Filters">Filters</a></h2>
 
-<center><i><b>A Fistful of Data</b></i></center><p>
+<div class="blurb">A Fistful of Data</div><p>
 
 If you want to receive section data you have to implement a derived <tt>cFilter</tt>
 class which at least implements the <tt>Process()</tt> function and a constructor
 that sets the (initial) filter parameters:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/filter.h&gt;
 
 class cMyFilter : public cFilter {
@@ -1533,7 +1553,7 @@
 An instance of such a filter needs to be attached to the device from
 which it shall receive data, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 cMyFilter *Filter = new cMyFilter();
 
 cDevice::ActualDevice()-&gt;AttachFilter(Filter);
@@ -1544,14 +1564,14 @@
 <p>
 See VDR/eit.c or VDR/pat.c to learn how to process filter data.
 
-<a name="The On Screen Display"><hr><h2>The On Screen Display</h2>
+<hr><h2><a name="The On Screen Display">The On Screen Display</a></h2>
 
-<center><i><b>Window to the world</b></i></center><p>
+<div class="blurb">Window to the world</div><p>
 
 If a plugin needs to have total control over the OSD, it can call the
 static function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/osd.h&gt;
 
 cOsd *MyOsd = cOsdProvider::NewOsd(x, y);
@@ -1561,7 +1581,7 @@
 of the OSD area on the screen. Such an OSD doesn't display anything
 yet, so you need to at least call the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 tArea Area = { 0, 0, 100, 100, 4 };
 MyOsd-&gt;SetAreas(&amp;Area, 1);
 </pre></td></tr></table><p>
@@ -1580,7 +1600,7 @@
 all over the OSD area, a plugin can divide the total drawing area into several
 sub-areas with different color depths and separate color palettes, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 tArea Area = { 0, 0, 99, 99, 4 };
 if (osd-&gt;CanHandleAreas(Area, 1) == oeOk)
    osd-&gt;SetAreas(&amp;Area, 1);
@@ -1615,7 +1635,7 @@
 combination (and thus be unable to draw any other colors at all), it may be
 useful to call
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 osd-&gt;SetAntiAliasGranularity();
 </pre></td></tr></table><p>
 
@@ -1629,15 +1649,15 @@
 If a plugin runs a separate thread and wants to issue a message directly from
 within that tread, it can call
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds = 0, int Timeout = 0);
 </pre></td></tr></table><p>
 
 to queue that message for display. See <tt>VDR/skins.h</tt> for details.
 
-<a name="Skins"><hr><h2>Skins</h2>
+<hr><h2><a name="Skins">Skins</a></h2>
 
-<center><i><b>The emperor's new clothes</b></i></center><p>
+<div class="blurb">The emperor's new clothes</div><p>
 
 The way VDR displays its menus to the user is implemented through <i>skins</i>.
 A particular skin provides several functions that return objects to be used
@@ -1652,7 +1672,7 @@
 The first step in implementing a new skin is to derive a class from <tt>cSkin</tt>
 that provides the handling objects necessary to do the actual work:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include "skins.h"
 
 class cMySkin : public cSkin {
@@ -1676,7 +1696,7 @@
 To add your new skin to the list of skins available to the user in Setup/OSD/Skin,
 all you need to do is create a new object of your skin class, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 new cMySkin;
 </pre></td></tr></table><p>
 
@@ -1686,15 +1706,15 @@
 In order to be able to easily identify plugins that implement a skin it is recommended
 that the name of such a plugin should be
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 skinxyz
 </pre></td></tr></table><p>
 
 where <tt>xyz</tt> is the actual name of the skin.
 
-<a name="Themes"><hr><h2>Themes</h2>
+<hr><h2><a name="Themes">Themes</a></h2>
 
-<center><i><b>Eye of the beholder...</b></i></center><p>
+<div class="blurb">Eye of the beholder...</div><p>
 
 A <i>theme</i> is a collection of colors that can be used by a <a href="#Skins">skin</a>.
 Since every skin most likely has its own idea about what parts of it can be
@@ -1705,13 +1725,13 @@
 <p>
 In order to make a skin "themeable" is shall create an object of type cTheme, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 static cTheme Theme;
 </pre></td></tr></table><p>
 
 The next step is to define the colors that shall be provided by this theme, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 THEME_CLR(Theme, clrTitle,        0xFFBC8024);
 THEME_CLR(Theme, clrButtonRedFg,  clrWhite);
 THEME_CLR(Theme, clrButtonRedBg,  clrRed);
@@ -1732,7 +1752,7 @@
 In the actual drawing code of a skin, the color names defined with the <tt>THEME_CLR()</tt>
 macros can be used to fetch the actual color values from the theme, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 osd-&gt;DrawText(x, y, s, Theme.Color(clrButtonRedFg), Theme.Color(clrButtonRedBg), font);
 </pre></td></tr></table><p>
 
@@ -1740,9 +1760,9 @@
 <tt>THEME_CLR()</tt> line, but may be overwritten through user supplied theme
 files (see <tt>man vdr(5)</tt> for information about the format of a theme file).
 
-<a name="Devices"><hr><h2>Devices</h2>
+<hr><h2><a name="Devices">Devices</a></h2>
 
-<center><i><b>Expanding the possibilities</b></i></center><p>
+<div class="blurb">Expanding the possibilities</div><p>
 
 By default VDR is based on using DVB PCI cards that are supported by the
 LinuxDVB driver. However, a plugin can implement additional devices that
@@ -1756,7 +1776,7 @@
 <p>
 To implement an additional device, a plugin must derive a class from <tt>cDevice</tt>:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/device.h&gt;
 
 class cMyDevice : public cDevice {
@@ -1775,7 +1795,7 @@
 If the new device can receive, it most likely needs to provide a way of
 selecting which channel it shall tune to:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 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;
@@ -1791,7 +1811,7 @@
 If the device can provide more than a single audio track, it can implement the
 following function to make them available:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual void SetAudioTrackDevice(eTrackType Type);
 virtual int GetAudioChannelDevice(void);
 virtual void SetAudioChannelDevice(int AudioChannel);
@@ -1802,7 +1822,7 @@
 <p>
 A device that can be used for recording must implement the functions
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
 virtual bool OpenDvr(void);
 virtual void CloseDvr(void);
@@ -1819,7 +1839,7 @@
 <p>
 The functions to implement replaying capabilities are
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual bool HasDecoder(void) const;
 virtual bool CanReplay(void) const;
 virtual bool SetPlayMode(ePlayMode PlayMode);
@@ -1838,7 +1858,7 @@
 In addition, the following functions may be implemented to provide further
 functionality:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
 virtual void SetVideoFormat(bool VideoFormat16_9);
 virtual void SetVolumeDevice(int Volume);
@@ -1850,7 +1870,7 @@
 If your device provides section filtering capabilities it can implement
 the functions
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
 virtual void CloseFilter(int Handle);
 </pre></td></tr></table><p>
@@ -1861,7 +1881,7 @@
 In order to actually start section handling, the
 device also needs to call the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 StartSectionHandler();
 </pre></td></tr></table><p>
 
@@ -1879,7 +1899,7 @@
 function is called, returns an object derived from <tt>cOsd</tt>, which can be used to
 access the device's OSD:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 class cMyOsdProvider : public cOsdProvider {
 public:
   cMyOsdProvider(void);
@@ -1890,7 +1910,7 @@
 In its <tt>MakePrimaryDevice()</tt> function the device shall create an object
 of this class, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 void cMyDevice::MakePrimaryDevice(bool On)
 {
   new cMyOsdProvider;
@@ -1927,9 +1947,9 @@
 important that the devices are created on the heap, using the <tt>new</tt>
 operator!
 
-<a name="Audio"><hr><h2>Audio</h2>
+<hr><h2><a name="Audio">Audio</a></h2>
 
-<center><i><b>"The stereo effect may only be experienced if stereo equipment is used!"</b></i></center><p>
+<div class="blurb">"The stereo effect may only be experienced if stereo equipment is used!"</div><p>
 
 There are many different ways to replay additional audio tracks, like Dolby Digital.
 So VDR offers a plugin interface that allows for the implementation of any kind of
@@ -1938,7 +1958,7 @@
 To implement a new audio output facility, simply derive a class from <tt>cAudio</tt>,
 as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/audio.h&gt;
 #include &lt;vdr/thread.h&gt;
 
@@ -1970,9 +1990,9 @@
 The <tt>Mute()</tt> and <tt>Clear()</tt> functions will be called whenever the audio shall
 be muted, or any buffered data shall be cleared, respectively.
 
-<a name="Remote Control"><hr><h2>Remote Control</h2>
+<hr><h2><a name="Remote Control">Remote Control</a></h2>
 
-<center><i><b>The joy of zapping!</b></i></center><p>
+<div class="blurb">The joy of zapping!</div><p>
 
 There are several ways to control the operation of VDR. The builtin methods
 are using the PC keyboard, a homebuilt RCU unit or the LIRC interface.
@@ -1982,7 +2002,7 @@
 The simplest method for a plugin to issue commands to VDR is to call the
 static function <tt>cRemote::Put(eKeys Key)</tt>, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 cRemote::Put(kUp);
 </pre></td></tr></table><p>
 
@@ -1994,7 +2014,7 @@
 be supported by the actual remote control in use, you may want to derive your
 own remote control class from <tt>cRemote</tt>, as in
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 #include &lt;vdr/remote.h&gt;
 #include &lt;vdr/thread.h&gt;
 
@@ -2019,7 +2039,7 @@
 <p>
 The constructor of your remote control class should look like this
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 cMyRemote::cMyRemote(const char *Name)
 :cRemote(Name)
 {
@@ -2039,7 +2059,7 @@
 If your remote control for some reason can't work (maybe because it was unable to
 open some file handle it requires) it can implement the virtual function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual bool Ready(void);
 </pre></td></tr></table><p>
 
@@ -2060,7 +2080,7 @@
 readily available next time VDR starts (without having to go through the initialization
 procedure again) it can use the <tt>cRemote</tt> member functions
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 void PutSetup(const char *Setup);
 const char *GetSetup(void);
 </pre></td></tr></table><p>
@@ -2074,7 +2094,7 @@
 expressed as a character string. So whatever data your remote control provides
 needs to be given to the base class by calling
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 Put(const char *Code, bool Repeat = false, bool Release = false);
 </pre></td></tr></table><p>
 
@@ -2085,15 +2105,15 @@
 value, there is another <tt>Put()</tt> function available for your convenience,
 which takes a 64 bit unsigned integer value instead of a character string:
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 Put(uint64 Code, bool Repeat = false, bool Release = false);
 </pre></td></tr></table><p>
 
 The other parameters have the same meaning as in the first version of this function.
 
-<a name="Conditional Access"><hr><h2>Conditional Access</h2>
+<hr><h2><a name="Conditional Access">Conditional Access</a></h2>
 
-<center><i><b>Members only!</b></i></center><p>
+<div class="blurb">Members only!</div><p>
 
 Pay TV providers usually encrypt their broadcasts, so that only viewers who
 have the proper smart card can watch them. Such a smart card needs to be inserted
@@ -2120,7 +2140,7 @@
 for example). The decision whether the adapter can actually be assigned to different
 devices is made in the function
 
-<p><table><tr><td bgcolor=#F0F0F0><pre>
+<p><table><tr><td class="code"><pre>
 virtual bool Assign(cDevice *Device, bool Query = false);
 </pre></td></tr></table><p>
 
diff -ruN vdr-1.5.15/config.h vdr-1.5.16/config.h
--- vdr-1.5.15/config.h	2008-02-05 16:35:11.000000000 +0100
+++ vdr-1.5.16/config.h	2008-02-17 17:04:52.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.305 2008/02/05 15:35:11 kls Exp $
+ * $Id: config.h 1.306 2008/02/17 16:04:52 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -22,8 +22,8 @@
 
 // VDR's own version number:
 
-#define VDRVERSION  "1.5.15"
-#define VDRVERSNUM   10515  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "1.5.16"
+#define VDRVERSNUM   10516  // Version * 10000 + Major * 100 + Minor
 
 // The plugin API's version number:
 
diff -ruN vdr-1.5.15/device.c vdr-1.5.16/device.c
--- vdr-1.5.15/device.c	2008-02-16 14:52:11.000000000 +0100
+++ vdr-1.5.16/device.c	2008-02-23 14:09:01.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.153 2008/02/16 13:52:11 kls Exp $
+ * $Id: device.c 1.155 2008/02/23 13:09:01 kls Exp $
  */
 
 #include "device.h"
@@ -218,6 +218,7 @@
 int cDevice::currentChannel = 1;
 cDevice *cDevice::device[MAXDEVICES] = { NULL };
 cDevice *cDevice::primaryDevice = NULL;
+cDevice *cDevice::avoidDevice = NULL;
 
 cDevice::cDevice(void)
 {
@@ -356,6 +357,8 @@
 
 cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView)
 {
+  cDevice *AvoidDevice = avoidDevice;
+  avoidDevice = NULL;
   // Collect the current priorities of all CAM slots that can decrypt the channel:
   int NumCamSlots = CamSlots.Count();
   int SlotPriority[NumCamSlots];
@@ -385,6 +388,8 @@
       if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY)
          continue; // there is no CAM available in this slot
       for (int i = 0; i < numDevices; i++) {
+          if (device[i] == AvoidDevice)
+             continue; // this device shall be temporarily avoided
           if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->CardIndex() + 1)
              continue; // a specific card was requested, but not this one
           if (NumUsableSlots && !CamSlots.Get(j)->Assign(device[i], true))
@@ -1159,7 +1164,7 @@
 
 bool cDevice::Transferring(void) const
 {
-  return dynamic_cast<cTransfer *>(player) != NULL;
+  return ActualDevice() != PrimaryDevice();
 }
 
 bool cDevice::AttachPlayer(cPlayer *Player)
diff -ruN vdr-1.5.15/device.h vdr-1.5.16/device.h
--- vdr-1.5.15/device.h	2008-02-16 14:50:11.000000000 +0100
+++ vdr-1.5.16/device.h	2008-02-23 14:13:04.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.90 2008/02/16 13:50:11 kls Exp $
+ * $Id: device.h 1.91 2008/02/23 13:13:04 kls Exp $
  */
 
 #ifndef __DEVICE_H
@@ -101,6 +101,7 @@
   static int useDevice;
   static cDevice *device[MAXDEVICES];
   static cDevice *primaryDevice;
+  static cDevice *avoidDevice;
 public:
   static int NumDevices(void) { return numDevices; }
          ///< Returns the total number of devices.
@@ -145,6 +146,9 @@
          ///< this device/CAM combination will be skipped in the next call to
          ///< GetDevice().
          ///< See also ProvidesChannel().
+  static void SetAvoidDevice(cDevice *Device) { avoidDevice = Device; }
+         ///< Sets the given Device to be temporarily avoided in the next call to
+         ///< GetDevice(const cChannel, int, bool).
   static void Shutdown(void);
          ///< Closes down all devices.
          ///< Must be called at the end of the program.
diff -ruN vdr-1.5.15/menu.c vdr-1.5.16/menu.c
--- vdr-1.5.15/menu.c	2008-02-16 14:53:26.000000000 +0100
+++ vdr-1.5.16/menu.c	2008-02-24 11:28:46.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.477 2008/02/16 13:53:26 kls Exp $
+ * $Id: menu.c 1.480 2008/02/24 10:28:46 kls Exp $
  */
 
 #include "menu.h"
@@ -1697,6 +1697,7 @@
         AddMultiLineItem(ciMenu->BottomText());
         dsyslog("CAM %d: '%s'", camSlot->SlotNumber(), ciMenu->BottomText());
         }
+     cRemote::TriggerLastActivity();
      }
   else if (ciEnquiry) {
      Clear();
@@ -2126,7 +2127,7 @@
      cRecording *recording = GetRecording(ri);
      if (recording) {
         cMenuCommands *menu;
-        eOSState state = AddSubMenu(menu = new cMenuCommands(tr("Recording commands"), &RecordingCommands, cString::sprintf("\"%s\"", *strescape(recording->FileName(), "\"$"))));
+        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;
@@ -2497,7 +2498,7 @@
      Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle languages"),    &numSubtitleLanguages, 0, I18nLanguages()->Size()));
      for (int i = 0; i < numSubtitleLanguages; i++)
          Add(new cMenuEditStraItem(tr("Setup.DVB$Subtitle language"), &data.SubtitleLanguages[i], I18nLanguages()->Size(), &I18nLanguages()->At(0)));
-     Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle offset"),                  &data.SubtitleOffset,       -50, 50));
+     Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle offset"),                  &data.SubtitleOffset,      -100, 100));
      Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9));
      Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10));
      }
diff -ruN vdr-1.5.15/po/da_DK.po vdr-1.5.16/po/da_DK.po
--- vdr-1.5.15/po/da_DK.po	2008-02-17 14:45:14.000000000 +0100
+++ vdr-1.5.16/po/da_DK.po	2008-02-24 11:18:14.000000000 +0100
@@ -166,7 +166,7 @@
 msgstr "Audio"
 
 msgid "Key$Subtitles"
-msgstr ""
+msgstr "Undertekster"
 
 msgid "Key$Schedule"
 msgstr "Programoversigt"
@@ -187,31 +187,31 @@
 msgstr "Kommandoer"
 
 msgid "Key$User1"
-msgstr ""
+msgstr "Bruger1"
 
 msgid "Key$User2"
-msgstr ""
+msgstr "Bruger2"
 
 msgid "Key$User3"
-msgstr ""
+msgstr "Bruger3"
 
 msgid "Key$User4"
-msgstr ""
+msgstr "Bruger4"
 
 msgid "Key$User5"
-msgstr ""
+msgstr "Bruger5"
 
 msgid "Key$User6"
-msgstr ""
+msgstr "Bruger6"
 
 msgid "Key$User7"
-msgstr ""
+msgstr "Bruger7"
 
 msgid "Key$User8"
-msgstr ""
+msgstr "Bruger8"
 
 msgid "Key$User9"
-msgstr ""
+msgstr "Bruger9"
 
 msgid "Disk"
 msgstr "Disk"
@@ -259,10 +259,10 @@
 msgstr "Dpid2"
 
 msgid "Spid1"
-msgstr ""
+msgstr "Spid1"
 
 msgid "Spid2"
-msgstr ""
+msgstr "Spid2"
 
 msgid "Tpid"
 msgstr "Tpid"
@@ -430,7 +430,7 @@
 msgstr "Indtast venligst %d cifre!"
 
 msgid "CAM not responding!"
-msgstr ""
+msgstr "CAM svarer ikke!"
 
 msgid "Recording info"
 msgstr "Optagelses info"
@@ -502,25 +502,25 @@
 msgstr "Anvend lille skrift"
 
 msgid "Setup.OSD$Anti-alias"
-msgstr ""
+msgstr "Anti-alias"
 
 msgid "Setup.OSD$Default font"
-msgstr ""
+msgstr "Standard skrift"
 
 msgid "Setup.OSD$Small font"
-msgstr ""
+msgstr "Lille skrift"
 
 msgid "Setup.OSD$Fixed font"
-msgstr ""
+msgstr "Fast skrift"
 
 msgid "Setup.OSD$Default font size (pixel)"
-msgstr ""
+msgstr "Standard skrift størrelse (pixel)"
 
 msgid "Setup.OSD$Small font size (pixel)"
-msgstr ""
+msgstr "Lille skrift størrelse (pixel)"
 
 msgid "Setup.OSD$Fixed font size (pixel)"
-msgstr ""
+msgstr "Fast skrift størrelse (pixel)"
 
 msgid "Setup.OSD$Channel info position"
 msgstr "Placering af kanalinfo"
@@ -633,22 +633,22 @@
 msgstr "Audio sprog"
 
 msgid "Setup.DVB$Display subtitles"
-msgstr ""
+msgstr "Vis undertekster"
 
 msgid "Setup.DVB$Subtitle languages"
-msgstr ""
+msgstr "Undertekst sprog (ant.)"
 
 msgid "Setup.DVB$Subtitle language"
-msgstr ""
+msgstr "Undertekst sprog"
 
 msgid "Setup.DVB$Subtitle offset"
-msgstr ""
+msgstr "Undertekst offset"
 
 msgid "Setup.DVB$Subtitle foreground transparency"
-msgstr ""
+msgstr "Undertekst forgrundsgennemsigtighed"
 
 msgid "Setup.DVB$Subtitle background transparency"
-msgstr ""
+msgstr "Undertekst baggrundsgennemsigtighed"
 
 msgid "LNB"
 msgstr "LNB"
@@ -666,13 +666,13 @@
 msgstr "Øvre LNB frekvens (MHz)"
 
 msgid "CAM reset"
-msgstr ""
+msgstr "CAM nulstil"
 
 msgid "CAM present"
-msgstr ""
+msgstr "CAM til stede"
 
 msgid "CAM ready"
-msgstr ""
+msgstr "CAM klar"
 
 msgid "CAM"
 msgstr "CAM"
@@ -681,7 +681,7 @@
 msgstr "Menu"
 
 msgid "Button$Reset"
-msgstr "Nulstille"
+msgstr "Nulstil"
 
 msgid "Opening CAM menu..."
 msgstr "Åbner CAM menu..."
@@ -690,7 +690,7 @@
 msgstr "Kan ikke åbne CAM menuen!"
 
 msgid "CAM is in use - really reset?"
-msgstr ""
+msgstr "CAM er i brug - virkelig nulstille?"
 
 msgid "Can't reset CAM!"
 msgstr "Kan ikke nulstille CAM!"
@@ -771,7 +771,7 @@
 msgstr "Zap timeout (s)"
 
 msgid "Setup.Miscellaneous$Channel entry timeout (ms)"
-msgstr ""
+msgstr "Kanal adgang timeout (ms)"
 
 msgid "Setup.Miscellaneous$Initial channel"
 msgstr "Kanal ved opstart"
@@ -783,7 +783,7 @@
 msgstr "Lydstyrke ved opstart"
 
 msgid "Setup.Miscellaneous$Emergency exit"
-msgstr ""
+msgstr "Nødudgang"
 
 msgid "Plugins"
 msgstr "Plugins"
@@ -840,13 +840,13 @@
 msgstr "Ingen lyd tilgængelig!"
 
 msgid "No subtitles"
-msgstr ""
+msgstr "Ingen undertekster"
 
 msgid "Button$Subtitles"
-msgstr ""
+msgstr "Undertekster"
 
 msgid "No subtitles available!"
-msgstr ""
+msgstr "Ingen undertekster tilgængelig!"
 
 msgid "Not enough disk space to start recording!"
 msgstr "For lidt harddisk plads til optagelse!"
@@ -907,7 +907,7 @@
 msgstr "Kan ikke slukke - parameter '-s' ikke angivet!"
 
 msgid "Editing - shut down anyway?"
-msgstr ""
+msgstr "Redigering igang - sluk alligevel?"
 
 msgid "Recording - shut down anyway?"
 msgstr "Optagelse igang - sluk alligevel?"
@@ -921,10 +921,10 @@
 
 #, c-format
 msgid "Plugin %s wakes up in %ld min, continue?"
-msgstr ""
+msgstr "Plugin %s vågner om %ld min, fortsæt?"
 
 msgid "Editing - restart anyway?"
-msgstr ""
+msgstr "Redigering igang - genstart alligevel?"
 
 msgid "Recording - restart anyway?"
 msgstr "Optagelse igang - genstart alligevel?"
@@ -978,7 +978,7 @@
 msgstr "Optagelse startet"
 
 msgid "VDR will shut down later - press Power to force"
-msgstr ""
+msgstr "VDR slukker senere - tryk Sluk for at tvinge"
 
 msgid "Press any key to cancel shutdown"
 msgstr "Tryk vilkårlig tast for at annullere sluk"
@@ -993,8 +993,8 @@
 msgstr "Redigeringsproces afsluttet"
 
 msgid "Press any key to cancel restart"
-msgstr ""
+msgstr "Tryk vilkårlig knap for at annullere genstart"
 
 #, c-format
 msgid "VDR will shut down in %s minutes"
-msgstr ""
+msgstr "VDR slukker om %s minutter"
diff -ruN vdr-1.5.15/po/it_IT.po vdr-1.5.16/po/it_IT.po
--- vdr-1.5.15/po/it_IT.po	2008-02-17 14:45:14.000000000 +0100
+++ vdr-1.5.16/po/it_IT.po	2008-02-24 11:18:14.000000000 +0100
@@ -11,7 +11,7 @@
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n"
 "POT-Creation-Date: 2008-02-10 12:22+0100\n"
-"PO-Revision-Date: 2007-10-16 02:15+0100\n"
+"PO-Revision-Date: 2008-02-21 20:29+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
 "Language-Team:  <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
@@ -25,7 +25,7 @@
 msgstr "Canale non disponibile!"
 
 msgid "Can't start Transfer Mode!"
-msgstr "Impossibile iniziare la modalità di trasferimento!"
+msgstr "Impossibile avviare la modalità di trasferimento!"
 
 msgid "Starting EPG scan"
 msgstr "Inizio scansione EPG"
@@ -42,7 +42,7 @@
 msgstr "ita"
 
 msgid "Phase 1: Detecting RC code type"
-msgstr "Fase 1: tipo ricevitore RC"
+msgstr "Fase 1: Rilevamento tipo codice RC"
 
 msgid "Press any key on the RC unit"
 msgstr "Premi un tasto dell'unità RC"
@@ -54,7 +54,7 @@
 msgstr "Non premere alcun tasto..."
 
 msgid "Phase 2: Learning specific key codes"
-msgstr "Fase 2: Codici specifici dei tasti"
+msgstr "Fase 2: Apprendimento codici specifici dei tasti"
 
 #, c-format
 msgid "Press key for '%s'"
@@ -82,7 +82,7 @@
 msgstr "Fase 3: Salvataggio codici tasti"
 
 msgid "Press 'Up' to save, 'Down' to cancel"
-msgstr "'Premi 'Su' per salvare, 'Giù' per annullare"
+msgstr "Premi 'Su' per salvare, 'Giù' per annullare"
 
 msgid "Key$Up"
 msgstr "Su"
@@ -169,7 +169,7 @@
 msgstr "Audio"
 
 msgid "Key$Subtitles"
-msgstr "Key$Sottotitoli"
+msgstr "Sottotitoli"
 
 msgid "Key$Schedule"
 msgstr "Programmi"
@@ -226,7 +226,7 @@
 msgstr "in chiaro"
 
 msgid "encrypted"
-msgstr "criptato"
+msgstr "codificato"
 
 msgid "auto"
 msgstr "automatico"
@@ -283,7 +283,7 @@
 msgstr "SymbolRate"
 
 msgid "Inversion"
-msgstr "Inversion"
+msgstr "Inversione"
 
 msgid "off"
 msgstr "off"
@@ -298,19 +298,19 @@
 msgstr "CoderateL"
 
 msgid "Modulation"
-msgstr "Modulation"
+msgstr "Modulazione"
 
 msgid "Bandwidth"
 msgstr "Banda passante"
 
 msgid "Transmission"
-msgstr "Transmission"
+msgstr "Trasmissione"
 
 msgid "Guard"
 msgstr "Guard"
 
 msgid "Hierarchy"
-msgstr "Hierarchy"
+msgstr "Gerarchia"
 
 msgid "Channel settings are not unique!"
 msgstr "Parametri canale non univoci!"
@@ -325,16 +325,16 @@
 msgstr "Nuovo"
 
 msgid "Button$Delete"
-msgstr "Cancella"
+msgstr "Elimina"
 
 msgid "Button$Mark"
-msgstr "Marca"
+msgstr "Segna"
 
 msgid "Channel is being used by a timer!"
 msgstr "Canale occupato da un timer!"
 
 msgid "Delete channel?"
-msgstr "Cancellare il canale?"
+msgstr "Eliminare il canale?"
 
 msgid "Edit timer"
 msgstr "Modifica timer"
@@ -373,16 +373,16 @@
 msgstr "Timer"
 
 msgid "Button$On/Off"
-msgstr "On/Off"
+msgstr "Attivo/Disattivo"
 
 msgid "Button$Info"
 msgstr "Informazioni"
 
 msgid "Delete timer?"
-msgstr "Cancellare il timer?"
+msgstr "Eliminare il timer?"
 
 msgid "Timer still recording - really delete?"
-msgstr "Timer in registrazione - cancellare?"
+msgstr "Timer in registrazione - eliminare?"
 
 msgid "Event"
 msgstr "Eventi"
@@ -457,10 +457,10 @@
 msgstr "Errore nell'accedere alla registrazione!"
 
 msgid "Delete recording?"
-msgstr "Cancellare la registrazione?"
+msgstr "Eliminare la registrazione?"
 
 msgid "Error while deleting recording!"
-msgstr "Errore nel cancellare la registrazione!"
+msgstr "Errore eliminazione della registrazione!"
 
 msgid "Recording commands"
 msgstr "Comandi di registrazione"
@@ -469,7 +469,7 @@
 msgstr "mai"
 
 msgid "skin dependent"
-msgstr "in base allo stile"
+msgstr "in base allo stile interfaccia"
 
 msgid "always"
 msgstr "sempre"
@@ -502,7 +502,7 @@
 msgstr "Tempo del messaggio (s)"
 
 msgid "Setup.OSD$Use small font"
-msgstr "Utilizzare caratteri piccoli"
+msgstr "Utilizza caratteri piccoli"
 
 msgid "Setup.OSD$Anti-alias"
 msgstr "Anti-alias"
@@ -541,7 +541,7 @@
 msgstr "Mostra informazioni al cambio canale"
 
 msgid "Setup.OSD$Timeout requested channel info"
-msgstr "Scadenza informazioni canale richieste"
+msgstr "Scadenza richieste informazioni canale"
 
 msgid "Setup.OSD$Scroll pages"
 msgstr "Scorri per pagine"
@@ -550,7 +550,7 @@
 msgstr "Scorri riavvolgendo"
 
 msgid "Setup.OSD$Menu key closes"
-msgstr "Utilizza il pulsante Menu per chiudere"
+msgstr "Utilizza il tasto Menu per chiudere"
 
 msgid "Setup.OSD$Recording directories"
 msgstr "Directory di registrazione"
@@ -562,13 +562,13 @@
 msgstr "Scansione"
 
 msgid "Setup.EPG$EPG scan timeout (h)"
-msgstr "Timeout scansione aggiorn. EPG (ore)"
+msgstr "Scadenza scansione aggiorn. EPG (ore)"
 
 msgid "Setup.EPG$EPG bugfix level"
 msgstr "Livello correzione EPG"
 
 msgid "Setup.EPG$EPG linger time (min)"
-msgstr "Visualizzazione dati vecchi (min)"
+msgstr "Visualizzazione vecchi dati EPG (min)"
 
 msgid "Setup.EPG$Set system time"
 msgstr "Imposta orario automatico"
@@ -636,22 +636,22 @@
 msgstr "Lingua per l'audio"
 
 msgid "Setup.DVB$Display subtitles"
-msgstr "Setup.DVB$Mostra sottotitoli"
+msgstr "Mostra sottotitoli"
 
 msgid "Setup.DVB$Subtitle languages"
-msgstr "Setup.DVB$Lingue sottotitoli"
+msgstr "Lingue sottotitoli"
 
 msgid "Setup.DVB$Subtitle language"
-msgstr "Setup.DVB$Lingua sottotitoli"
+msgstr "Lingua sottotitoli"
 
 msgid "Setup.DVB$Subtitle offset"
-msgstr "Setup.DVB$Posizione sottotitolo"
+msgstr "Posizione sottotitoli"
 
 msgid "Setup.DVB$Subtitle foreground transparency"
-msgstr "Setup.DVB$Trasparenza primo piano sottotitoli"
+msgstr "Trasparenza primo piano sottotitoli"
 
 msgid "Setup.DVB$Subtitle background transparency"
-msgstr "Setup.DVB$Trasparenza sfondo sottotitoli"
+msgstr "Trasparenza sfondo sottotitoli"
 
 msgid "LNB"
 msgstr "LNB"
@@ -729,10 +729,10 @@
 msgstr "Utilizza VPS"
 
 msgid "Setup.Recording$VPS margin (s)"
-msgstr "Margine VPS"
+msgstr "Margine VPS (s)"
 
 msgid "Setup.Recording$Mark instant recording"
-msgstr "Marca registrazione immediata"
+msgstr "Segna registrazione immediata"
 
 msgid "Setup.Recording$Name instant recording"
 msgstr "Nome registrazione immediata"
@@ -756,7 +756,7 @@
 msgstr "Mostra modalità riproduzione"
 
 msgid "Setup.Replay$Resume ID"
-msgstr "ID di rispristino"
+msgstr "ID di ripristino"
 
 msgid "Miscellaneous"
 msgstr "Generici"
@@ -786,7 +786,7 @@
 msgstr "Volume iniziale"
 
 msgid "Setup.Miscellaneous$Emergency exit"
-msgstr ""
+msgstr "Uscita d'emergenza"
 
 msgid "Plugins"
 msgstr "Plugins"
@@ -846,7 +846,7 @@
 msgstr "Nessun sottotitolo"
 
 msgid "Button$Subtitles"
-msgstr "Button$Sottotitoli"
+msgstr "Sottotitoli"
 
 msgid "No subtitles available!"
 msgstr "Nessun sottotitolo disponibile!"
@@ -868,10 +868,10 @@
 msgstr "Nessun marcatore di modifica definito!"
 
 msgid "Can't start editing process!"
-msgstr "Impossibile iniziare il processo di modifica!"
+msgstr "Impossibile avviare il processo di modifica!"
 
 msgid "Editing process started"
-msgstr "Processo di modifica iniziato"
+msgstr "Processo di modifica avviato"
 
 msgid "Editing process already active!"
 msgstr "Processo di modifica già attivo!"
diff -ruN vdr-1.5.15/po/nl_NL.po vdr-1.5.16/po/nl_NL.po
--- vdr-1.5.15/po/nl_NL.po	2008-02-17 14:45:14.000000000 +0100
+++ vdr-1.5.16/po/nl_NL.po	2008-02-24 11:18:14.000000000 +0100
@@ -4,14 +4,15 @@
 # Arnold Niessen <niessen@iae.nl> <arnold.niessen@philips.com>, 2001
 # Hans Dingemans <hans.dingemans@tacticalops.nl>, 2003
 # Maarten Wisse <Maarten.Wisse@urz.uni-hd.de>, 2005
+# Carel Willemse <ca_willemse@planet.nl>, 2008
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\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"
+"PO-Revision-Date: 2008-02-18 17:50+0200\n"
+"Last-Translator: Carel Willemse <ca_willemse@planet.nl>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
@@ -138,10 +139,10 @@
 msgstr "Terugspoelen"
 
 msgid "Key$Next"
-msgstr ""
+msgstr "Volgende"
 
 msgid "Key$Prev"
-msgstr ""
+msgstr "Vorige"
 
 msgid "Key$Power"
 msgstr "Uitschakelen"
@@ -153,7 +154,7 @@
 msgstr "Kanaal-"
 
 msgid "Key$PrevChannel"
-msgstr ""
+msgstr "VorigKanaal"
 
 msgid "Key$Volume+"
 msgstr "Volume+"
@@ -168,10 +169,10 @@
 msgstr "Audio"
 
 msgid "Key$Subtitles"
-msgstr ""
+msgstr "Ondertiteling"
 
 msgid "Key$Schedule"
-msgstr "Gids"
+msgstr "ProgrammaGids"
 
 msgid "Key$Channels"
 msgstr "Kanalen"
@@ -189,43 +190,43 @@
 msgstr "Commando's"
 
 msgid "Key$User1"
-msgstr ""
+msgstr "Gebruiker1"
 
 msgid "Key$User2"
-msgstr ""
+msgstr "Gebruiker2"
 
 msgid "Key$User3"
-msgstr ""
+msgstr "Gebruiker3"
 
 msgid "Key$User4"
-msgstr ""
+msgstr "Gebruiker4"
 
 msgid "Key$User5"
-msgstr ""
+msgstr "Gebruiker5"
 
 msgid "Key$User6"
-msgstr ""
+msgstr "Gebruiker6"
 
 msgid "Key$User7"
-msgstr ""
+msgstr "Gebruiker7"
 
 msgid "Key$User8"
-msgstr ""
+msgstr "Gebruiker8"
 
 msgid "Key$User9"
-msgstr ""
+msgstr "Gebruiker9"
 
 msgid "Disk"
-msgstr "Disk"
+msgstr "Schijf"
 
 msgid "free"
 msgstr "vrij"
 
 msgid "Free To Air"
-msgstr ""
+msgstr "Vrij te ontvangen"
 
 msgid "encrypted"
-msgstr ""
+msgstr "gecodeerd"
 
 msgid "auto"
 msgstr "auto"
@@ -261,10 +262,10 @@
 msgstr "Dpid2"
 
 msgid "Spid1"
-msgstr ""
+msgstr "Spid1"
 
 msgid "Spid2"
-msgstr ""
+msgstr "Spid2"
 
 msgid "Tpid"
 msgstr "Tpid"
@@ -297,19 +298,19 @@
 msgstr "CoderateL"
 
 msgid "Modulation"
-msgstr "Modulation"
+msgstr "Modulatie"
 
 msgid "Bandwidth"
-msgstr "Bandwidth"
+msgstr "Bandbreedte"
 
 msgid "Transmission"
-msgstr "Transmission"
+msgstr "Transmissie"
 
 msgid "Guard"
 msgstr "Guard"
 
 msgid "Hierarchy"
-msgstr "Hierarchy"
+msgstr "Hierarchie"
 
 msgid "Channel settings are not unique!"
 msgstr "Kanaalinstellingen zijn niet uniek!"
@@ -363,7 +364,7 @@
 msgstr "Bewaarduur"
 
 msgid "File"
-msgstr "Filenaam"
+msgstr "Bestandnaam"
 
 msgid "First day"
 msgstr "Eerste dag"
@@ -387,7 +388,7 @@
 msgstr "Uitzending"
 
 msgid "Button$Timer"
-msgstr ""
+msgstr "Timer"
 
 msgid "Button$Record"
 msgstr "Opnemen"
@@ -408,7 +409,7 @@
 msgstr "Nu"
 
 msgid "Button$Schedule"
-msgstr "Programma"
+msgstr "Programmagids"
 
 msgid "Can't switch channel!"
 msgstr "Kan geen kanaal wisselen!"
@@ -419,20 +420,20 @@
 
 #, c-format
 msgid "This event - %s"
-msgstr ""
+msgstr "Deze uitzending - %s"
 
 msgid "This event - all channels"
-msgstr ""
+msgstr "Deze uitzending - alle kanalen"
 
 msgid "All events - all channels"
-msgstr ""
+msgstr "Alle uitzendingen - alle kanalen"
 
 #, c-format
 msgid "Please enter %d digits!"
 msgstr "Vul %d cijfers in!"
 
 msgid "CAM not responding!"
-msgstr ""
+msgstr "CAM reageert niet!"
 
 msgid "Recording info"
 msgstr "Opname info"
@@ -504,25 +505,25 @@
 msgstr "Klein lettertype gebruiken"
 
 msgid "Setup.OSD$Anti-alias"
-msgstr ""
+msgstr "Anti-alias"
 
 msgid "Setup.OSD$Default font"
-msgstr ""
+msgstr "Standaard lettertype"
 
 msgid "Setup.OSD$Small font"
-msgstr ""
+msgstr "Kleine lettertype"
 
 msgid "Setup.OSD$Fixed font"
-msgstr ""
+msgstr "Letter met vaste breedte"
 
 msgid "Setup.OSD$Default font size (pixel)"
-msgstr ""
+msgstr "Afmetingen standaard lettertype (pixel)"
 
 msgid "Setup.OSD$Small font size (pixel)"
-msgstr ""
+msgstr "Afmetingen klein lettertype (pixel)"
 
 msgid "Setup.OSD$Fixed font size (pixel)"
-msgstr ""
+msgstr "Afmetingen lettertype met vaste breedte (pixel)"
 
 msgid "Setup.OSD$Channel info position"
 msgstr "Kanaal info positie"
@@ -540,7 +541,7 @@
 msgstr "Kanaal info tonen"
 
 msgid "Setup.OSD$Timeout requested channel info"
-msgstr ""
+msgstr "Tijdsduur opgevraagde kanaalinfo."
 
 msgid "Setup.OSD$Scroll pages"
 msgstr "Scrollen per pagina"
@@ -549,10 +550,10 @@
 msgstr "Rondom scrollen"
 
 msgid "Setup.OSD$Menu key closes"
-msgstr ""
+msgstr "Menu toets sluit ook af"
 
 msgid "Setup.OSD$Recording directories"
-msgstr "Opname directories"
+msgstr "Opname mappen"
 
 msgid "EPG"
 msgstr "EPG"
@@ -599,7 +600,7 @@
 msgstr "alleen namen"
 
 msgid "PIDs only"
-msgstr ""
+msgstr "alleen PIDs"
 
 msgid "names and PIDs"
 msgstr "namen en PIDs"
@@ -635,22 +636,22 @@
 msgstr "Audio taal"
 
 msgid "Setup.DVB$Display subtitles"
-msgstr ""
+msgstr "Toon ondertiteling"
 
 msgid "Setup.DVB$Subtitle languages"
-msgstr ""
+msgstr "Talen ondertiteling"
 
 msgid "Setup.DVB$Subtitle language"
-msgstr ""
+msgstr "Taal ondertiteling"
 
 msgid "Setup.DVB$Subtitle offset"
-msgstr ""
+msgstr "Positie ondertiteling"
 
 msgid "Setup.DVB$Subtitle foreground transparency"
-msgstr ""
+msgstr "Transparantie voorgrond ondertiteling"
 
 msgid "Setup.DVB$Subtitle background transparency"
-msgstr ""
+msgstr "Transparantie achtergrond ondertiteling"
 
 msgid "LNB"
 msgstr "LNB"
@@ -668,13 +669,13 @@
 msgstr "Hoogste LNB frequentie (MHz)"
 
 msgid "CAM reset"
-msgstr ""
+msgstr "CAM herstarten"
 
 msgid "CAM present"
-msgstr ""
+msgstr "CAM aanwezig"
 
 msgid "CAM ready"
-msgstr ""
+msgstr "CAM gereed"
 
 msgid "CAM"
 msgstr "CAM"
@@ -692,7 +693,7 @@
 msgstr "Kan CAM-menu niet openen!"
 
 msgid "CAM is in use - really reset?"
-msgstr ""
+msgstr "CAM wordt gebruikt - werkelijk herstarten?"
 
 msgid "Can't reset CAM!"
 msgstr "Kan CAM niet herstarten!"
@@ -773,19 +774,19 @@
 msgstr "Zap timeout (s)"
 
 msgid "Setup.Miscellaneous$Channel entry timeout (ms)"
-msgstr ""
+msgstr "Tijdsduur kanaalinvoer (ms)"
 
 msgid "Setup.Miscellaneous$Initial channel"
-msgstr ""
+msgstr "Opstartkanaal"
 
 msgid "Setup.Miscellaneous$as before"
-msgstr ""
+msgstr "zoals eerder"
 
 msgid "Setup.Miscellaneous$Initial volume"
-msgstr ""
+msgstr "Opstartvolume"
 
 msgid "Setup.Miscellaneous$Emergency exit"
-msgstr ""
+msgstr "Nooduitgang"
 
 msgid "Plugins"
 msgstr "Plugins"
@@ -807,7 +808,7 @@
 msgstr " Stop opnemen "
 
 msgid "Schedule"
-msgstr "Gids"
+msgstr "Programmagids"
 
 msgid "VDR"
 msgstr "VDR"
@@ -826,7 +827,7 @@
 msgstr "Eindigen"
 
 msgid "Button$Resume"
-msgstr "Verder"
+msgstr "Hervat"
 
 #. TRANSLATORS: note the leading blank!
 msgid " Cancel editing"
@@ -842,16 +843,16 @@
 msgstr "Geen audio beschikbaar!"
 
 msgid "No subtitles"
-msgstr ""
+msgstr "Geen ondertiteling"
 
 msgid "Button$Subtitles"
-msgstr ""
+msgstr "Ondertiteling"
 
 msgid "No subtitles available!"
-msgstr ""
+msgstr "Geen ondertiteling beschikbaar"
 
 msgid "Not enough disk space to start recording!"
-msgstr ""
+msgstr "Onvoldoende hardeschijfruimte voor deze opname!"
 
 msgid "No free DVB device to record!"
 msgstr "Geen vrije DVB kaart om op te nemen!"
@@ -903,13 +904,13 @@
 msgstr "Kanaal geblokkeerd (neemt op)!"
 
 msgid "Low disk space!"
-msgstr "Disk bijna vol!"
+msgstr "Hardeschijf bijna vol!"
 
 msgid "Can't shutdown - option '-s' not given!"
 msgstr "Shutdown onmogelijk - Optie '-s' ontbreekt!"
 
 msgid "Editing - shut down anyway?"
-msgstr ""
+msgstr "Bewerken aktief - toch uitschakelen?"
 
 msgid "Recording - shut down anyway?"
 msgstr "Opname loopt - toch uitschakelen?"
@@ -923,10 +924,10 @@
 
 #, c-format
 msgid "Plugin %s wakes up in %ld min, continue?"
-msgstr ""
+msgstr "Plugin %s wordt binnen %ld min. aktief, doorgaan?"
 
 msgid "Editing - restart anyway?"
-msgstr ""
+msgstr "Bewerken aktief - toch herstarten?"
 
 msgid "Recording - restart anyway?"
 msgstr "Opname loopt - toch opnieuw starten?"
@@ -953,13 +954,13 @@
 msgstr "MaaDinWoeDonVryZatZon"
 
 msgid "Monday"
-msgstr "maandag"
+msgstr "Maandag"
 
 msgid "Tuesday"
 msgstr "Dinsdag"
 
 msgid "Wednesday"
-msgstr "woensdag"
+msgstr "Woensdag"
 
 msgid "Thursday"
 msgstr "Donderdag"
@@ -974,13 +975,13 @@
 msgstr "Zondag"
 
 msgid "Upcoming recording!"
-msgstr ""
+msgstr "Opname start binnenkort!"
 
 msgid "Recording started"
-msgstr ""
+msgstr "Opname is gestart!"
 
 msgid "VDR will shut down later - press Power to force"
-msgstr ""
+msgstr "VDR zal later uitschakelen - Druk 'Power' om te forceren"
 
 msgid "Press any key to cancel shutdown"
 msgstr "Druk een toets om shutdown af te breken"
@@ -995,8 +996,8 @@
 msgstr "Bewerken is klaar"
 
 msgid "Press any key to cancel restart"
-msgstr ""
+msgstr "Druk een willekeurige toets om herstarten af te breken"
 
 #, c-format
 msgid "VDR will shut down in %s minutes"
-msgstr ""
+msgstr "VDR zal na %s minuten uitschakelen"
diff -ruN vdr-1.5.15/recording.c vdr-1.5.16/recording.c
--- vdr-1.5.15/recording.c	2008-02-16 14:31:39.000000000 +0100
+++ vdr-1.5.16/recording.c	2008-02-24 11:28:53.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.161 2008/02/16 13:31:39 kls Exp $
+ * $Id: recording.c 1.162 2008/02/24 10:28:53 kls Exp $
  */
 
 #include "recording.h"
@@ -1161,7 +1161,7 @@
 void cRecordingUserCommand::InvokeCommand(const char *State, const char *RecordingFileName)
 {
   if (command) {
-     cString cmd = cString::sprintf("%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\"$"));
+     cString cmd = cString::sprintf("%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$"));
      isyslog("executing '%s'", *cmd);
      SystemExec(cmd);
      }
diff -ruN vdr-1.5.15/remote.c vdr-1.5.16/remote.c
--- vdr-1.5.15/remote.c	2007-04-30 14:27:56.000000000 +0200
+++ vdr-1.5.16/remote.c	2008-02-23 15:14:46.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remote.c 1.57 2007/04/30 12:27:56 kls Exp $
+ * $Id: remote.c 1.59 2008/02/23 14:14:46 kls Exp $
  */
 
 #include "remote.h"
@@ -121,7 +121,7 @@
 bool cRemote::Put(uint64_t Code, bool Repeat, bool Release)
 {
   char buffer[32];
-  snprintf(buffer, sizeof(buffer), "%016LX", Code);
+  snprintf(buffer, sizeof(buffer), "%016llX", Code);
   return Put(buffer, Repeat, Release);
 }
 
@@ -185,7 +185,7 @@
             out = 0;
          if ((k & k_Repeat) != 0)
             repeatTimeout.Set(REPEATTIMEOUT);
-         lastActivity = time(NULL);
+         TriggerLastActivity();
          return enabled ? k : kNone;
          }
       else if (!WaitMs || !keyPressed.TimedWait(mutex, WaitMs) && repeatTimeout.TimedOut())
@@ -198,6 +198,11 @@
       }
 }
 
+void cRemote::TriggerLastActivity(void)
+{
+  lastActivity = time(NULL);
+}
+
 // --- cRemotes --------------------------------------------------------------
 
 cRemotes Remotes;
diff -ruN vdr-1.5.15/remote.h vdr-1.5.16/remote.h
--- vdr-1.5.15/remote.h	2007-04-30 14:37:37.000000000 +0200
+++ vdr-1.5.16/remote.h	2008-02-23 15:38:47.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remote.h 1.40 2007/04/30 12:37:37 kls Exp $
+ * $Id: remote.h 1.41 2008/02/23 14:38:47 kls Exp $
  */
 
 #ifndef __REMOTE_H
@@ -67,6 +67,9 @@
   static eKeys Get(int WaitMs = 1000, char **UnknownCode = NULL);
   static time_t LastActivity(void) { return lastActivity; }
       ///< Absolute time when last key was delivered by Get().
+  static void TriggerLastActivity(void);
+      ///< Simulates user activity, for instance to keep the current menu open
+      ///< even if no remote control key has been pressed.
   };
 
 class cRemotes : public cList<cRemote> {};
diff -ruN vdr-1.5.15/shutdown.c vdr-1.5.16/shutdown.c
--- vdr-1.5.15/shutdown.c	2008-01-13 15:27:29.000000000 +0100
+++ vdr-1.5.16/shutdown.c	2008-02-24 11:29:00.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * Original version written by Udo Richter <udo_richter@gmx.de>.
  *
- * $Id: shutdown.c 1.4 2008/01/13 14:27:29 kls Exp $
+ * $Id: shutdown.c 1.5 2008/02/24 10:29:00 kls Exp $
  */
 
 #include "shutdown.h"
@@ -130,7 +130,7 @@
 void cShutdownHandler::CallShutdownCommand(time_t WakeupTime, int Channel, const char *File, bool UserShutdown)
 {
   time_t Delta = WakeupTime ? WakeupTime - time(NULL) : 0;
-  cString cmd = cString::sprintf("%s %ld %ld %d \"%s\" %d", shutdownCommand, WakeupTime, Delta, Channel, *strescape(File, "\"$"), UserShutdown);
+  cString cmd = cString::sprintf("%s %ld %ld %d \"%s\" %d", shutdownCommand, WakeupTime, Delta, Channel, *strescape(File, "\\\"$"), UserShutdown);
   isyslog("executing '%s'", *cmd);
   int Status = SystemExec(cmd, true);
   if (!WIFEXITED(Status) || WEXITSTATUS(Status))
diff -ruN vdr-1.5.15/skinclassic.c vdr-1.5.16/skinclassic.c
--- vdr-1.5.15/skinclassic.c	2008-02-17 15:23:36.000000000 +0100
+++ vdr-1.5.16/skinclassic.c	2008-02-23 11:31:58.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.25 2008/02/17 14:23:36 kls Exp $
+ * $Id: skinclassic.c 1.27 2008/02/23 10:31:58 kls Exp $
  */
 
 #include "skinclassic.h"
@@ -233,14 +233,15 @@
 {
   if (Total > 0 && Total > Shown) {
      int yt = Top;
-     int yb = yt + Height - 1;
+     int yb = yt + Height;
      int st = yt;
      int sb = yb;
-     int tt = st + (sb - st + 1) * Offset / Total;
-     int tb = tt + (sb - st + 1) * Shown / Total;
+     int th = max(int((sb - st) * double(Shown) / Total + 0.5), ScrollWidth);
+     int tt = min(int(st + (sb - st) * double(Offset) / Total + 0.5), sb - th);
+     int tb = min(tt + th, sb);
      int xl = x3 - ScrollWidth;
-     osd->DrawRectangle(xl, st, x3 - 1, sb, Theme.Color(clrMenuScrollbarTotal));
-     osd->DrawRectangle(xl, tt, x3 - 1, tb, Theme.Color(clrMenuScrollbarShown));
+     osd->DrawRectangle(xl, st, x3 - 1, sb - 1, Theme.Color(clrMenuScrollbarTotal));
+     osd->DrawRectangle(xl, tt, x3 - 1, tb - 1, Theme.Color(clrMenuScrollbarShown));
      }
 }
 
diff -ruN vdr-1.5.15/skinsttng.c vdr-1.5.16/skinsttng.c
--- vdr-1.5.15/skinsttng.c	2008-02-17 15:23:45.000000000 +0100
+++ vdr-1.5.16/skinsttng.c	2008-02-23 11:23:44.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.26 2008/02/17 14:23:45 kls Exp $
+ * $Id: skinsttng.c 1.28 2008/02/23 10:23:44 kls Exp $
  */
 
 // Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
@@ -442,13 +442,14 @@
   if (Total > 0 && Total > Shown) {
      int h  = lineHeight;
      int yt = Top;
-     int yb = yt + Height - 1;
+     int yb = yt + Height;
      int st = yt + h + Gap;
      int sb = yb - h - Gap;
-     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));
+     int th = max(int((sb - st) * double(Shown) / Total + 0.5), ScrollWidth);
+     int tt = min(int(st + (sb - st) * double(Offset) / Total + 0.5), sb - th);
+     int tb = min(tt + th, sb);
+     osd->DrawRectangle(x5, st, x5 + ScrollWidth - 1, sb - 1, Theme.Color(clrMenuScrollbarTotal));
+     osd->DrawRectangle(x5, tt, x5 + ScrollWidth - 1, tb - 1, 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);
diff -ruN vdr-1.5.15/vdr.c vdr-1.5.16/vdr.c
--- vdr-1.5.15/vdr.c	2008-02-10 15:23:31.000000000 +0100
+++ vdr-1.5.16/vdr.c	2008-02-23 16:36:01.000000000 +0100
@@ -22,7 +22,7 @@
  *
  * The project's page is at http://www.cadsoft.de/vdr
  *
- * $Id: vdr.c 1.310 2008/02/10 14:23:31 kls Exp $
+ * $Id: vdr.c 1.312 2008/02/23 15:36:01 kls Exp $
  */
 
 #include <getopt.h>
@@ -730,7 +730,7 @@
         // Make sure we have a visible programme in case device usage has changed:
         if (!EITScanner.Active() && cDevice::PrimaryDevice()->HasDecoder() && !cDevice::PrimaryDevice()->HasProgramme()) {
            static time_t lastTime = 0;
-           if (Now - lastTime > MINCHANNELWAIT) {
+           if (!Menu && Now - lastTime > MINCHANNELWAIT) { // !Menu to avoid interfering with the CAM if a CAM menu is open
               cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel());
               if (Channel && (Channel->Vpid() || Channel->Apid(0))) {
                  if (!Channels.SwitchTo(cDevice::CurrentChannel()) // try to switch to the original channel...
@@ -877,7 +877,9 @@
                            }
                         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
+                           cDevice::SetAvoidDevice(Device);
+                           if (!Channels.SwitchTo(cDevice::CurrentChannel())) // try to switch to the original channel on a different device...
+                              Channels.SwitchTo(Timer->Channel()->Number()); // ...or avoid toggling between old channel and black screen
                            Skins.Message(mtInfo, tr("Upcoming recording!"));
                            }
                         }
