diff -ruN vdr-1.7.16/CONTRIBUTORS vdr-1.7.17/CONTRIBUTORS
--- vdr-1.7.16/CONTRIBUTORS	2010-09-19 14:35:33.000000000 +0200
+++ vdr-1.7.17/CONTRIBUTORS	2011-03-12 14:09:30.000000000 +0100
@@ -673,10 +673,11 @@
  for adding missing AUDIO_PAUSE/AUDIO_CONTINUE calls to cDvbDevice
  for reporting that the video type is unnecessarily written into channels.conf if
  VPID is 0
- for reporting chirping sound disturbences at editing points in TS recordings
+ for reporting chirping sound disturbances at editing points in TS recordings
  for reporting broken index generation in TS recordings after a buffer overflow
  for fixing the way the OSD size is determined on full featured DVB cards
  for his input on calculating the Aspect factor in GetOsdSize()
+ for suggesting a better way of handling calls to realloc()
 
 Reinhard Walter Buchner <rw.buchner@freenet.de>
  for adding some satellites to 'sources.conf'
@@ -740,6 +741,7 @@
  or Makefile.config as defaults
  for helping to debug a crash when using the --terminal option without having access
  to the given terminal
+ for fixing following symbolic links in RemoveFileOrDir()
 
 Peter Seyringer <e9425234@student.tuwien.ac.at>
  for reporting a bug in saving the polarization parameter of channels that have a
@@ -1021,7 +1023,7 @@
  for reporting a problem with starting the editing process if no marks have been set
 
 Marc Rovira Vall <tm05462@salleURL.edu>, Ramon Roca <ramon.roca@xcombo.com> and Jordi Vilà <jvila@tinet.org>
- for translating OSD texts to the Catalanian language
+ for translating OSD texts to the Catalan language
 
 Lars Bläser <LBlaeser@hofheim.de>
  for reporting a bug in EPG bugfix statistics which made log entries for undefined
@@ -1099,6 +1101,8 @@
  for implementing handling of HD resolution subtitles according to v1.3.1 of
  ETSI EN 300 743, chapter 7.2.1
  for fixing the array size of Atypes in cPatFilter::Process()
+ for adding support for "registration descriptor" to 'libsi' and using it in pat.c
+ for adding an include of VDR's 'Make.global' to libsi's Makefile
 
 Ralf Klueber <ralf.klueber@vodafone.com>
  for reporting a bug in cutting a recording if there is only a single editing mark
@@ -1247,7 +1251,7 @@
  to 'double'
  for suggesting to use different names for the Aspect parameter in GetVideoSize()
  and GetOsdSize()
- for reporting a problem with calculating menu colum widths in case the font has a
+ for reporting a problem with calculating menu column widths in case the font has a
  size other than the default size
  for reporting a bug in storing the current OSD size in case the
  device has changed it in its setup menu
@@ -1257,6 +1261,9 @@
  for implementing cDeviceHook
  for implementing cDevice::GetCurrentlyTunedTransponder()
  for fixing DDS detection for HD resolution subtitles
+ for some valuable input during development of the TrueColor OSD, help with
+ debugging, and an implementation of the AlphaBlend() function.
+ for storing the original display size when handling DVB subtitles
 
 Richard Robson <richard_robson@beeb.net>
  for reporting freezing replay if a timer starts while in Transfer Mode from the
@@ -1831,7 +1838,7 @@
  for suggesting to implement a timeout for remote controls that don't deliver
  "repeat" keypresses very fast
  for reporting a broken entry 'A111.1W' in sources.conf
- for translating OSD texts to the Spanish and Catalanian language
+ for translating OSD texts to the Spanish and Catalan language
 
 Mikko Salo <mikko.salo@ppe.inet.fi>
  for suggesting to make the setup option "DVB/Video display format" available only
@@ -1876,6 +1883,9 @@
  for adding missing #include <limits.h> to epg.c and menuitems.h
  for fixing various spelling errors and improving PLUGINS.html
  for adding some missing 'const' keywords to avoid compilation errors with gcc 4.4
+ for adding passing package name and version to xgettext
+ for making 'dist' target dependent on up to date *.po
+ for adding Language and fixing Language-Team header of *.po
 
 Steffen Beyer <cpunk@reactor.de>
  for fixing setting the colored button help after deleting a recording in case the next
@@ -1966,9 +1976,11 @@
  for his help in replacing the get/put_unaligned() macros from asm/unaligned.h with
  own inline functions to avoid problems on platforms that don't provide these
 
-Marcus Hilbrich <s4440288@mail.inf.tu-dresden.de>
+Marcus Hilbrich <hilbrich@gmx.de>
  for a bug report that lead to fixing the EPG scan, so that it doesn't use the
  primary device if that is currently in Transfer-Mode from itself
+ for a bug report that led to fixing setting up the 'Recordings' menu in case there
+ are several recordings with exactly the same name
 
 Hardy Flor <HFlor@web.de>
  for a patch that was used as a base to implement SVDRP commands for plugins
@@ -2230,8 +2242,9 @@
  for making the non-breaking space symbol be rendered as a blank
  for fixing a signed character used as index in cBase64Encoder::NextLine()
  for fixing formatting the name section in the VDR man pages
- for reporting unneeded include files <linux/dvb/dmx.h> und <time.h> in remux.h
+ for reporting unneeded include files <linux/dvb/dmx.h> and <time.h> in remux.h
  for a patch that added a workaround for the broken linux-dvb driver header files
+ for reporting a faulty "frame duration" instead of "frame rate" in vdr.5
 
 Helge Lenz <h.lenz@gmx.de>
  for reporting a bug in setting the 'Delta' parameter when calling the shutdown
@@ -2286,6 +2299,7 @@
  from within its source directory
  for fixing stopping subtitle display when switching the primary device
  for fixing plugin arguments corruption with glibc 2.11 on x86_64
+ for setting the audio type of language descriptors to 0x00 in the PAT/PMT generator
 
 Antti Hartikainen <ami+vdr@ah.fi>
  for updating 'S13E' in 'sources.conf'
@@ -2538,6 +2552,7 @@
  for updating sources.conf
  for reporting a problem where the frame rate was not detected correctly
  for testing the implementation of FE_CAN_TURBO_FEC
+ for reporting unjustified log entries about changed channel pids
 
 Marcel Unbehaun <frostworks@gmx.de>
  for adding cRecordingInfo::GetEvent()
@@ -2563,6 +2578,8 @@
  for fixing saving terminal settings when running in background
  for making the SVDRP port open only for the local host if svdrphosts.conf
  contains only the address of the local host
+ for a patch that was used as a base for making editing marks be updated every 10
+ seconds during replay
 
 Rene van den Braken <rene@vandenbraken.name>
  for reporting a bug in writing the PCR pid into the PMT in
@@ -2602,7 +2619,9 @@
  for adding handling of EnhancedAC3DescriptorTag
 
 Paul Menzel <paulepanter@users.sourceforge.net>
- for making include paths be added instead of overwriting INCLUDES in the Makefile
+ for making include paths not be overwritten in the Makefile
+ for adding LDFLAGS to the linker calls in the Makefiles
+ for reporting a possible memory leak in the "pictures" plugin
 
 Radek Stastny <dedkus@gmail.com>
  for translating OSD texts to the Czech language
@@ -2625,3 +2644,29 @@
 Osama Alrawab <alrawab@hotmail.com>
  for adding support for languages that are written right-to-left
  for translating OSD texts to the Arabian language
+
+Antti Seppälä <a.seppala@gmail.com>
+ for suggesting to add cString::operator=(const char *String)
+
+Henning Heinold <heinold@inf.fu-berlin.de>
+ for fixing inclusion of <stdarg.h>
+
+Dominik Strasser <dominik@die-strassers.de>
+ for making a cRemote be removed from the Remotes list in case its initialization failed
+
+Joerg Bornkessel <hd_brummy@gentoo.org>
+ for adding LDFLAGS to the linker calls in the Makefiles
+
+Andreas Oberritter <obi@opendreambox.org>
+ for suggesting to retrieve the include path to the freetype2 header files
+ via a call to 'pkg-config --cflags freetype2'
+
+Milan Cvijanovic <elcom_cvijo@hotmail.com>
+ for translating OSD texts to the Serbian language
+
+Frank Neumann <frank.neumann@hp.com>
+ for suggesting to reduce the thread and I/O priority cCuttingThread::Action()
+
+Gerald Dachs <vdr@dachsweb.de>
+ for reporting a problem with checking for minimum line length of 21 characters in
+ the LIRC receiver code
diff -ruN vdr-1.7.16/HISTORY vdr-1.7.17/HISTORY
--- vdr-1.7.16/HISTORY	2010-09-19 14:36:07.000000000 +0200
+++ vdr-1.7.17/HISTORY	2011-03-12 17:08:08.000000000 +0100
@@ -2154,7 +2154,7 @@
   called before trying to learn the keys (problem reported by Oliver Endriss).
 - No longer starting the editing process if no marks have been set (thanks to
   Matthias Raus for reporting this one).
-- Added Catalanian language texts (thanks to Marc Rovira Vall and Ramon Roca).
+- Added Catalan language texts (thanks to Marc Rovira Vall and Ramon Roca).
   Plugin authors may want to add the new entries to their I18N texts and contact
   the translators to have their texts translated. Note that there are now 16
   different OSD languages, so please make sure you have 16 versions for each of
@@ -2219,7 +2219,7 @@
 - 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 this one).
-- Some corrections to the Catalanian OSD texts (thanks to Jordi Vilà).
+- Some corrections to the Catalan OSD texts (thanks to Jordi Vilà).
 - Single event timers are now deleted if the recording they are doing is
   deleted before the timer ends.
 - Fixed an uninitialized variable in cDisplayChannel (thanks to Stefan Huelswitt).
@@ -5706,7 +5706,7 @@
   ISO-8859-9.
 - Fixed a signed character used as index in cBase64Encoder::NextLine() (thanks
   to Tobias Grimm).
-- Updated the Spanish and Catalanian OSD texts (thanks to Luca Olivetti).
+- Updated the Spanish and Catalan OSD texts (thanks to Luca Olivetti).
 - Fixed automatically selecting the preferred subtitle language (based on a patch
   from Rolf Ahrenberg).
 - Updated the Ukrainian OSD texts (thanks to Yarema Aka Knedlyk).
@@ -5811,7 +5811,7 @@
 - Replaced the Finnish language code "smi" with "suo" (thanks to Rolf Ahrenberg).
 - Fixed wrong value for TableIdBAT in libsi/si.h (thanks to Winfried Köhler).
 - Errors in config files no longer keep VDR from starting.
-- Removed unneeded include files <linux/dvb/dmx.h> und <time.h> from remux.h
+- Removed unneeded include files <linux/dvb/dmx.h> and <time.h> from remux.h
   (reported by Tobias Grimm).
 
 2008-09-06: Version 1.6.0-2
@@ -5829,7 +5829,7 @@
   to Udo Richter).
 - Replaced the Finnish language code "smi" with "suo" (thanks to Rolf Ahrenberg).
 - Fixed wrong value for TableIdBAT in libsi/si.h (thanks to Winfried Köhler).
-- Removed unneeded include files <linux/dvb/dmx.h> und <time.h> from remux.h
+- Removed unneeded include files <linux/dvb/dmx.h> and <time.h> from remux.h
   (reported by Tobias Grimm).
 
 2008-12-14: Version 1.7.2
@@ -6052,7 +6052,7 @@
 - Any TS packets in the first "frame" after a cut in an edited recording that don't
   belong to a payload unit that started in that frame now get their TEI flag set,
   so that a decoder will ignore them together with any PES data collected for that
-  PID so far (thanks to Oliver Endriss for reporting chirping sound disturbences at
+  PID so far (thanks to Oliver Endriss for reporting chirping sound disturbances at
   editing points in TS recordings).
 - cDvbPlayer::Empty() subtracts 1 from readIndex, because Action() will first
   increment it.
@@ -6426,7 +6426,7 @@
   there is less than MIN_TS_PACKETS_FOR_FRAME_DETECTOR left (reported by Derek Kelly).
 - Added a note about not deleting cDeviceHook objects to device.h.
 - Added user defined key kUser0 (suggested by Ulf Kiener).
-- Include paths are now added instead of overwriting INCLUDES in the Makefile (thanks
+- Include paths are no longer overwritten in the Makefile (thanks
   to Paul Menzel).
 - The various modulation types are now taken into account when selecting a device for
   a recording or live viewing, so that devices that provide more capabilities are
@@ -6480,3 +6480,79 @@
 - Added support for languages that are written right-to-left (based on a patch
   from Osama Alrawab). See INSTALL for information on how to turn this on.
 - Added Arabian language texts (thanks to Osama Alrawab).
+
+2011-03-12: Version 1.7.17
+
+- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
+- Fixed following symbolic links in RemoveFileOrDir() (cont'd) (thanks to
+  Steffen Barszus).
+- Changed the description of cDevice::GetSTC() to make it mandatory for devices
+  that can replay.
+- Removed the check for positive STC values from cDvbSubtitleConverter::Action().
+- Added cString::operator=(const char *String) (suggested by Antti Seppälä).
+- Some spelling fixes (thanks to Ville Skyttä).
+- Passing package name and version to xgettext (thanks to Ville Skyttä).
+- Made 'dist' target dependent on up to date *.po (thanks to Ville Skyttä).
+- Added Language and fixed Language-Team header of *.po (thanks to Ville Skyttä).
+- Updated the Lithuanian OSD texts (thanks to Valdemaras Pipiras).
+- Fixed detecting frames on channels that broadcast with 50 or 60 fps.
+  This avoids artifacts during fast forward/rewind when replaying recordings from such
+  channels. To fix the index of existing recordings from such channels, just delete the
+  'index' file of the recording and VDR will generate a new one the next time you play it.
+  You should also change the line "F 25" to "F 50" in the 'info' file of that recording.
+- Added support for "registration descriptor" to 'libsi' and using it in pat.c (thanks
+  to Rolf Ahrenberg).
+- Fixed unjustified log entries about changed channel pids (reported by Derek Kelly).
+- Added an include of VDR's 'Make.global' to libsi's Makefile (thanks to Rolf
+  Ahrenberg).
+- Removed displaying the "contents" information from the "Classic VDR" and
+  "ST:TNG Panels" skins, because it is often wrong and nothing but irritating.
+- Added typecasts to avoid gcc 4.5 warnings in switch statements on eKeys
+  variables where additional 'k_...' flags are used.
+- Fixed inclusion of <stdarg.h> (thanks to Henning Heinold).
+- Changed "frame duration" to "frame rate" in vdr.5 (reported by Tobias Grimm).
+- Removing a cRemote from the Remotes list in case its initialization failed (thanks
+  to Dominik Strasser).
+- Added LDFLAGS to the linker calls in the Makefiles (thanks to Joerg Bornkessel and
+  Paul Menzel).
+- Now updating the 'frames per second' data in the list of recordings when a new
+  recording is started that has a frame rate other than the default.
+- The include path to the freetype2 header files is now retrieved via a call to
+  'pkg-config --cflags freetype2' (suggested by Andreas Oberritter).
+- The OSD now has full TrueColor support. There can be several "pixmaps" that can
+  be overlayed with alpha blending. All existing skins should work out of the box
+  with the TrueColor OSD - the only exception being cOsd::GetBitmap(). Since the
+  TrueColor OSD doesn't use bitmaps, this function will return a dummy bitmap, which
+  may not be what the plugin expects. As long as this bitmap is only used for setting
+  the palette, there is no problem. However, any other operations on this bitmap will
+  have no effect. See the description of the cPixmap functions in osd.h for details
+  about the new functionalities.
+  The "ST:TNG Panels" skin has been enhanced to automatically use the TrueColor OSD
+  if available.
+  The "osddemo" plugin has been extended to show some of the possibilities of the
+  TrueColor OSD if it is run on a system that actually provides TrueColor support.
+  Thanks to Reinhard Nissl for some valuable input, help with debugging, and an
+  implementation of the AlphaBlend() function.
+- Updated the Slovakian language texts (thanks to Milan Hrala).
+- Added Serbian language texts (thanks to Milan Cvijanovic).
+- Fixed reallocating memory in the "pictures" plugin (reported by Paul Menzel, with
+  input from Oliver Endriss).
+- Fixed reallocating memory in cTsToPes::PutTs() (suggested by Oliver Endriss).
+- Now checking the result of all realloc() calls.
+- Fixed setting up the 'Recordings' menu in case there are several recordings
+  with exactly the same name (reported by Marcus Hilbrich).
+- Setting the audio type of language descriptors to 0x00 in the PAT/PMT generator
+  (thanks to Anssi Hannula).
+- Changed the compiler optimization flag to -O3, which gives quite a performance
+  boost in the AlphaBlend() function.
+- While replaying, the editing marks are now updated every 10 seconds (based on a
+  patch from Manuel Reimer).
+- Now reducing the thread and I/O priority cCuttingThread::Action() to make the
+  foreground process more responsive (suggested by Frank Neumann).
+- Removed checking for minimum line length of 21 characters in the LIRC receiver code
+  (reported by Gerald Dachs).
+- Updated the Romanian OSD texts (thanks to Lucian Muresan).
+- Now storing the original display size when handling DVB subtitles (thanks to
+  Reinhard Nissl).
+- The original display size of subtitles is now used to scale them properly when
+  displaying them on an HD OSD.
diff -ruN vdr-1.7.16/Makefile vdr-1.7.17/Makefile
--- vdr-1.7.16/Makefile	2010-09-17 15:28:50.000000000 +0200
+++ vdr-1.7.17/Makefile	2011-02-27 10:59:11.000000000 +0100
@@ -4,15 +4,15 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: Makefile 2.10 2010/09/17 13:28:50 kls Exp $
+# $Id: Makefile 2.14 2011/02/27 09:59:11 kls Exp $
 
 .DELETE_ON_ERROR:
 
 CC       ?= gcc
-CFLAGS   ?= -g -O2 -Wall
+CFLAGS   ?= -g -O3 -Wall
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 LSIDIR   = ./libsi
 DESTDIR ?=
@@ -21,7 +21,7 @@
 BINDIR   = $(PREFIX)/bin
 LOCDIR   = ./locale
 LIBS     = -ljpeg -lpthread -ldl -lcap -lrt -lfreetype -lfontconfig
-INCLUDES ?= -I/usr/include/freetype2
+INCLUDES ?= $(shell pkg-config --cflags freetype2)
 
 PLUGINDIR= ./PLUGINS
 PLUGINLIBDIR= $(PLUGINDIR)/lib
@@ -95,7 +95,7 @@
 # The main program:
 
 vdr: $(OBJS) $(SILIB)
-	$(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(LIBS) $(LIBDIRS) $(SILIB) -o vdr
+	$(CXX) $(CXXFLAGS) -rdynamic $(LDFLAGS) $(OBJS) $(LIBS) $(LIBDIRS) $(SILIB) -o vdr
 
 # The libsi library:
 
@@ -114,7 +114,7 @@
 	msgfmt -c -o $@ $<
 
 $(I18Npot): $(wildcard *.c)
-	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ $^
+	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=VDR --package-version=$(VDRVERSION) --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ $^
 
 %.po: $(I18Npot)
 	msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
diff -ruN vdr-1.7.16/PLUGINS/src/dvbsddevice/Makefile vdr-1.7.17/PLUGINS/src/dvbsddevice/Makefile
--- vdr-1.7.16/PLUGINS/src/dvbsddevice/Makefile	2010-02-06 15:50:03.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/dvbsddevice/Makefile	2011-02-27 11:04:54.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.2 2010/02/06 14:50:03 kls Exp $
+# $Id: Makefile 1.6 2011/02/27 10:04:54 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -18,7 +18,7 @@
 ### The C++ compiler and options:
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 ### The directory environment:
 
@@ -83,7 +83,7 @@
 	msgfmt -c -o $@ $<
 
 $(I18Npot): $(wildcard *.c)
-	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<see README>' -o $@ $^
+	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=VDR --package-version=$(VDRVERSION) --msgid-bugs-address='<see README>' -o $@ $^
 
 %.po: $(I18Npot)
 	msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
@@ -99,10 +99,10 @@
 ### Targets:
 
 libvdr-$(PLUGIN).so: $(OBJS)
-	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 
-dist: clean
+dist: $(I18Npo) clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
 	@mkdir $(TMPDIR)/$(ARCHIVE)
 	@cp -a * $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.7.16/PLUGINS/src/hello/Makefile vdr-1.7.17/PLUGINS/src/hello/Makefile
--- vdr-1.7.16/PLUGINS/src/hello/Makefile	2010-02-06 15:50:03.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/hello/Makefile	2011-02-27 11:04:58.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.2 2010/02/06 14:50:03 kls Exp $
+# $Id: Makefile 2.6 2011/02/27 10:04:58 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -18,7 +18,7 @@
 ### The C++ compiler and options:
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 ### The directory environment:
 
@@ -83,7 +83,7 @@
 	msgfmt -c -o $@ $<
 
 $(I18Npot): $(wildcard *.c)
-	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ $^
+	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=VDR --package-version=$(VDRVERSION) --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ $^
 
 %.po: $(I18Npot)
 	msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
@@ -99,10 +99,10 @@
 ### Targets:
 
 libvdr-$(PLUGIN).so: $(OBJS)
-	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 
-dist: clean
+dist: $(I18Npo) clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
 	@mkdir $(TMPDIR)/$(ARCHIVE)
 	@cp -a * $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/ca_ES.po vdr-1.7.17/PLUGINS/src/hello/po/ca_ES.po
--- vdr-1.7.16/PLUGINS/src/hello/po/ca_ES.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/ca_ES.po	2010-10-24 16:43:03.000000000 +0200
@@ -9,13 +9,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Jordi Vilà <jvila@tinet.org>\n"
-"Language-Team: Catalanian\n"
+"Language-Team: Catalan <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: ca\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/cs_CZ.po vdr-1.7.17/PLUGINS/src/hello/po/cs_CZ.po
--- vdr-1.7.16/PLUGINS/src/hello/po/cs_CZ.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/cs_CZ.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Vladimír Bárta <vladimir.barta@k2atmitec.cz>\n"
-"Language-Team: Czech\n"
+"Language-Team: Czech <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: cs\n"
 
 msgid "A friendly greeting"
 msgstr "Pøátelský pozdrav"
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/da_DK.po vdr-1.7.17/PLUGINS/src/hello/po/da_DK.po
--- vdr-1.7.16/PLUGINS/src/hello/po/da_DK.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/da_DK.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Mogens Elneff <mogens@elneff.dk>\n"
-"Language-Team: Danish\n"
+"Language-Team: Danish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/de_DE.po vdr-1.7.17/PLUGINS/src/hello/po/de_DE.po
--- vdr-1.7.16/PLUGINS/src/hello/po/de_DE.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/de_DE.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n"
-"Language-Team: German\n"
+"Language-Team: German <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
 
 msgid "A friendly greeting"
 msgstr "Ein freundlicher Gruß"
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/el_GR.po vdr-1.7.17/PLUGINS/src/hello/po/el_GR.po
--- vdr-1.7.16/PLUGINS/src/hello/po/el_GR.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/el_GR.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n"
-"Language-Team: Greek\n"
+"Language-Team: Greek <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-7\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: el\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/es_ES.po vdr-1.7.17/PLUGINS/src/hello/po/es_ES.po
--- vdr-1.7.16/PLUGINS/src/hello/po/es_ES.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/es_ES.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Ruben Nunez Francisco <ruben.nunez@tang-it.com>\n"
-"Language-Team: Spanish\n"
+"Language-Team: Spanish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: es\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/et_EE.po vdr-1.7.17/PLUGINS/src/hello/po/et_EE.po
--- vdr-1.7.16/PLUGINS/src/hello/po/et_EE.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/et_EE.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Arthur Konovalov <kasjas@hot.ee>\n"
-"Language-Team: Estonian\n"
+"Language-Team: Estonian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-13\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: et\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/fi_FI.po vdr-1.7.17/PLUGINS/src/hello/po/fi_FI.po
--- vdr-1.7.16/PLUGINS/src/hello/po/fi_FI.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/fi_FI.po	2010-10-24 16:43:03.000000000 +0200
@@ -10,13 +10,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
-"Language-Team: Finnish\n"
+"Language-Team: Finnish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fi\n"
 
 msgid "A friendly greeting"
 msgstr "YstÃ¤vÃ¤llisin terveisin"
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/fr_FR.po vdr-1.7.17/PLUGINS/src/hello/po/fr_FR.po
--- vdr-1.7.16/PLUGINS/src/hello/po/fr_FR.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/fr_FR.po	2010-10-24 16:43:03.000000000 +0200
@@ -10,13 +10,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Nicolas Huillard <nhuillard@e-dition.fr>\n"
-"Language-Team: French\n"
+"Language-Team: French <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fr\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/hr_HR.po vdr-1.7.17/PLUGINS/src/hello/po/hr_HR.po
--- vdr-1.7.16/PLUGINS/src/hello/po/hr_HR.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/hr_HR.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-03-17 19:52+0100\n"
 "Last-Translator: Adrian Caval <anrxc@sysphere.org>\n"
-"Language-Team: Croatian\n"
+"Language-Team: Croatian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: hr\n"
 
 msgid "A friendly greeting"
 msgstr "Prijateljska dobrodo¹lica"
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/hu_HU.po vdr-1.7.17/PLUGINS/src/hello/po/hu_HU.po
--- vdr-1.7.16/PLUGINS/src/hello/po/hu_HU.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/hu_HU.po	2010-10-24 16:43:03.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Istvan Koenigsberger <istvnko@hotmail.com>, Guido Josten <guido.josten@t-online.de>\n"
-"Language-Team: Hungarian\n"
+"Language-Team: Hungarian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: hu\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/it_IT.po vdr-1.7.17/PLUGINS/src/hello/po/it_IT.po
--- vdr-1.7.16/PLUGINS/src/hello/po/it_IT.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/it_IT.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-01-27 20:11+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
-"Language-Team: Italian\n"
+"Language-Team: Italian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: it\n"
 
 msgid "A friendly greeting"
 msgstr "Un saluto cordiale"
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/lt_LT.po vdr-1.7.17/PLUGINS/src/hello/po/lt_LT.po
--- vdr-1.7.16/PLUGINS/src/hello/po/lt_LT.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/lt_LT.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.10\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2009-12-08 12:18+0200\n"
 "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
-"Language-Team: Lietuviai\n"
+"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: lt\n"
 
 msgid "A friendly greeting"
 msgstr "DraugiÅ¡kas labas"
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/nl_NL.po vdr-1.7.17/PLUGINS/src/hello/po/nl_NL.po
--- vdr-1.7.16/PLUGINS/src/hello/po/nl_NL.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/nl_NL.po	2010-10-24 16:43:03.000000000 +0200
@@ -9,13 +9,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Maarten Wisse <Maarten.Wisse@urz.uni-hd.de>\n"
-"Language-Team: Dutch\n"
+"Language-Team: Dutch <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: nl\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/nn_NO.po vdr-1.7.17/PLUGINS/src/hello/po/nn_NO.po
--- vdr-1.7.16/PLUGINS/src/hello/po/nn_NO.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/nn_NO.po	2010-10-24 16:43:03.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Truls Slevigen <truls@slevigen.no>\n"
-"Language-Team: Norwegian\n"
+"Language-Team: Norwegian Nynorsk <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: nn\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/pl_PL.po vdr-1.7.17/PLUGINS/src/hello/po/pl_PL.po
--- vdr-1.7.16/PLUGINS/src/hello/po/pl_PL.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/pl_PL.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Michael Rakowski <mrak@gmx.de>\n"
-"Language-Team: Polish\n"
+"Language-Team: Polish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: pl\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/pt_PT.po vdr-1.7.17/PLUGINS/src/hello/po/pt_PT.po
--- vdr-1.7.16/PLUGINS/src/hello/po/pt_PT.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/pt_PT.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Paulo Lopes <pmml@netvita.pt>\n"
-"Language-Team: Portuguese\n"
+"Language-Team: Portuguese <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: pt\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/ro_RO.po vdr-1.7.17/PLUGINS/src/hello/po/ro_RO.po
--- vdr-1.7.16/PLUGINS/src/hello/po/ro_RO.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/ro_RO.po	2010-10-24 16:43:03.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n"
-"Language-Team: Romanian\n"
+"Language-Team: Romanian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: ro\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/ru_RU.po vdr-1.7.17/PLUGINS/src/hello/po/ru_RU.po
--- vdr-1.7.16/PLUGINS/src/hello/po/ru_RU.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/ru_RU.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Vyacheslav Dikonov <sdiconov@mail.ru>\n"
-"Language-Team: Russian\n"
+"Language-Team: Russian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-5\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: ru\n"
 
 msgid "A friendly greeting"
 msgstr "´àãÖÕáÚÞÕ ßàØÒÕâáâÒØÕ"
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/sk_SK.po vdr-1.7.17/PLUGINS/src/hello/po/sk_SK.po
--- vdr-1.7.16/PLUGINS/src/hello/po/sk_SK.po	2010-09-19 14:45:55.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/sk_SK.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2009-09-30 09:48+0100\n"
 "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
-"Language-Team: Slovak\n"
+"Language-Team: Slovak <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: sk\n"
 
 msgid "A friendly greeting"
 msgstr "Priateµský pozdrav"
@@ -32,4 +33,3 @@
 
 msgid "Hello world!"
 msgstr "Ahoj svet!"
-
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/sl_SI.po vdr-1.7.17/PLUGINS/src/hello/po/sl_SI.po
--- vdr-1.7.16/PLUGINS/src/hello/po/sl_SI.po	2010-09-19 14:45:56.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/sl_SI.po	2010-10-24 16:43:03.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n"
-"Language-Team: Slovenian\n"
+"Language-Team: Slovenian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: sl\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/sv_SE.po vdr-1.7.17/PLUGINS/src/hello/po/sv_SE.po
--- vdr-1.7.16/PLUGINS/src/hello/po/sv_SE.po	2010-09-19 14:45:56.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/sv_SE.po	2010-10-24 16:43:03.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-11 12:34+0200\n"
 "Last-Translator: Tomas Prybil <tomas@prybil.se>\n"
-"Language-Team: Swedish\n"
+"Language-Team: Swedish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: sv\n"
 
 msgid "A friendly greeting"
 msgstr ""
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/tr_TR.po vdr-1.7.17/PLUGINS/src/hello/po/tr_TR.po
--- vdr-1.7.16/PLUGINS/src/hello/po/tr_TR.po	2010-09-19 14:45:56.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/tr_TR.po	2010-10-24 16:43:03.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-05-12 22:34:4800\n"
 "Last-Translator: Oktay Yolgeçen <oktay_73@yahoo.de>\n"
-"Language-Team: Turkish\n"
+"Language-Team: Turkish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-9\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: tr\n"
 
 msgid "A friendly greeting"
 msgstr "Dostça selam"
diff -ruN vdr-1.7.16/PLUGINS/src/hello/po/zh_CN.po vdr-1.7.17/PLUGINS/src/hello/po/zh_CN.po
--- vdr-1.7.16/PLUGINS/src/hello/po/zh_CN.po	2010-09-19 14:45:56.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/hello/po/zh_CN.po	2010-10-24 16:43:03.000000000 +0200
@@ -10,13 +10,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2009-01-23 09:48+0800\n"
 "Last-Translator: senin\n"
-"Language-Team: Catalanian\n"
+"Language-Team: Chinese (simplified) <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
 
 msgid "A friendly greeting"
 msgstr "å�‹å¥½çš„é—®å€™"
@@ -35,4 +36,3 @@
 
 msgid "Hello world!"
 msgstr "ä¸–ç•Œæ‚¨å¥½ï¼�"
-
diff -ruN vdr-1.7.16/PLUGINS/src/osddemo/HISTORY vdr-1.7.17/PLUGINS/src/osddemo/HISTORY
--- vdr-1.7.16/PLUGINS/src/osddemo/HISTORY	2008-04-13 15:02:53.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/osddemo/HISTORY	2011-02-20 16:06:52.000000000 +0100
@@ -21,3 +21,7 @@
 2008-04-13: Version 0.1.3
 
 - Fixed setting the OSD level (thanks to Wolfgang Rohdewald).
+
+2011-02-20: Version 0.2.0
+
+- Added support for TrueColor OSD.
diff -ruN vdr-1.7.16/PLUGINS/src/osddemo/Makefile vdr-1.7.17/PLUGINS/src/osddemo/Makefile
--- vdr-1.7.16/PLUGINS/src/osddemo/Makefile	2010-02-06 15:50:03.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/osddemo/Makefile	2011-02-27 11:05:01.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.1 2010/02/06 14:50:03 kls Exp $
+# $Id: Makefile 2.3 2011/02/27 10:05:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -16,7 +16,7 @@
 ### The C++ compiler and options:
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 ### The directory environment:
 
@@ -72,7 +72,7 @@
 ### Targets:
 
 libvdr-$(PLUGIN).so: $(OBJS)
-	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
diff -ruN vdr-1.7.16/PLUGINS/src/osddemo/README vdr-1.7.17/PLUGINS/src/osddemo/README
--- vdr-1.7.16/PLUGINS/src/osddemo/README	2009-10-18 16:02:34.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/osddemo/README	2011-02-20 16:10:34.000000000 +0100
@@ -19,4 +19,11 @@
 It's a very primitive game that opens a small window in which the
 user can draw lines with the Up, Down, Left and Right buttons.
 The color buttons are used to switch color.
+
+On a VDR system with TrueColor support it displays some of the
+possibilities available with the TrueColor OSD. Once the "Animation"
+pixmap is displayed, it can be moved around with the Up, Down, Left
+and Right buttons. The Red button turns off the "Tiled Pixmaps"
+display, and the Green button toggles the color display.
+
 Press Ok to close the window.
diff -ruN vdr-1.7.16/PLUGINS/src/osddemo/osddemo.c vdr-1.7.17/PLUGINS/src/osddemo/osddemo.c
--- vdr-1.7.16/PLUGINS/src/osddemo/osddemo.c	2008-04-13 14:59:57.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/osddemo/osddemo.c	2011-02-26 13:08:13.000000000 +0100
@@ -3,12 +3,13 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: osddemo.c 2.1 2008/04/13 12:59:57 kls Exp $
+ * $Id: osddemo.c 2.3 2011/02/26 12:08:13 kls Exp $
  */
 
+#include <vdr/osd.h>
 #include <vdr/plugin.h>
 
-static const char *VERSION        = "0.1.3";
+static const char *VERSION        = "0.2.0";
 static const char *DESCRIPTION    = "Demo of arbitrary OSD setup";
 static const char *MAINMENUENTRY  = "Osd Demo";
 
@@ -22,7 +23,7 @@
   tColor color;
 public:
   cLineGame(void);
-  ~cLineGame();
+  virtual ~cLineGame();
   virtual void Show(void);
   virtual eOSState ProcessKey(eKeys Key);
   };
@@ -73,6 +74,366 @@
   return state;
 }
 
+// --- cTrueColorDemo --------------------------------------------------------
+
+class cTrueColorDemo : public cOsdObject, public cThread {
+private:
+  cOsd *osd;
+  cPoint cursor;
+  cRect cursorLimits;
+  bool clockwise;
+  cPixmap *destroyablePixmap;
+  cPixmap *toggleablePixmap;
+  virtual void Action(void);
+  cPixmap *CreateTextPixmap(const char *s, int Line, int Layer, tColor ColorFg, tColor ColorBg, const cFont *Font = NULL);
+public:
+  cTrueColorDemo(void);
+  virtual ~cTrueColorDemo();
+  virtual void Show(void);
+  virtual eOSState ProcessKey(eKeys Key);
+  };
+
+cTrueColorDemo::cTrueColorDemo(void)
+{
+  osd = NULL;
+  clockwise = true;
+  destroyablePixmap = NULL;
+  toggleablePixmap = NULL;
+}
+
+cTrueColorDemo::~cTrueColorDemo()
+{
+  delete osd;
+}
+
+cPixmap *cTrueColorDemo::CreateTextPixmap(const char *s, int Line, int Layer, tColor ColorFg, tColor ColorBg, const cFont *Font)
+{
+  if (!Font)
+     Font = cFont::GetFont(fontOsd);
+  const int h = Font->Height(s);
+  int w = Font->Width(s);
+  cPixmap *Pixmap = osd->CreatePixmap(Layer, cRect((osd->Width() - w) / 2, Line, w, h));
+  if (Pixmap) {
+     Pixmap->Clear();
+     Pixmap->SetAlpha(0);
+     Pixmap->DrawText(cPoint(0, 0), s, ColorFg, ColorBg, Font);
+     }
+  return Pixmap;
+}
+
+void cTrueColorDemo::Action(void)
+{
+  cPixmap *FadeInPixmap = NULL;
+  cPixmap *FadeOutPixmap = NULL;
+  cPixmap *MovePixmap = NULL;
+  cPixmap *NextPixmap = NULL;
+  cPixmap *TilePixmap = NULL;
+  cPixmap *ScrollPixmap = NULL;
+  cPixmap *AnimPixmap = NULL;
+  int FrameTime = 40; // ms
+  int FadeTime = 1000; // ms
+  int MoveTime = 4000; // ms
+  int TileTime = 6000; // ms
+  int ScrollWaitTime = 1000; // ms
+  int ScrollLineTime = 200; // ms
+  int ScrollTotalTime = 8000; // ms
+  uint64_t Start = 0;
+  uint64_t ScrollStartTime = 0;
+  int ScrollLineNumber = 0;
+  cPoint MoveStart, MoveEnd;
+  cPoint TileStart, TileEnd;
+  cPoint ScrollStart, ScrollEnd;
+  int Line = osd->Height() / 20;
+  int StartLine = Line;
+  cPoint OldCursor;
+  int State = 0;
+  while (Running()) {
+        cPixmap::Lock();
+        bool Animated = false;
+        uint64_t Now = cTimeMs::Now();
+        if (FadeInPixmap) {
+           double t = min(double(Now - Start) / FadeTime, 1.0);
+           int Alpha = t * ALPHA_OPAQUE;
+           FadeInPixmap->SetAlpha(Alpha);
+           if (t >= 1)
+              FadeInPixmap = NULL;
+           Animated = true;
+           }
+        if (FadeOutPixmap) {
+           double t = min(double(Now - Start) / FadeTime, 1.0);
+           int Alpha = ALPHA_OPAQUE - t * ALPHA_OPAQUE;
+           FadeOutPixmap->SetAlpha(Alpha);
+           if (t >= 1)
+              FadeOutPixmap = NULL;
+           Animated = true;
+           }
+        if (MovePixmap) {
+           double t = min(double(Now - Start) / MoveTime, 1.0);
+           int x = MoveStart.X() + t * (MoveEnd.X() - MoveStart.X());
+           int y = MoveStart.Y() + t * (MoveEnd.Y() - MoveStart.Y());
+           cRect r = MovePixmap->ViewPort();
+           r.SetPoint(x, y);
+           MovePixmap->SetViewPort(r);
+           if (t >= 1)
+              MovePixmap = NULL;
+           Animated = true;
+           }
+        if (TilePixmap) {
+           double t = min(double(Now - Start) / TileTime, 1.0);
+           int x = TileStart.X() + t * (TileEnd.X() - TileStart.X());
+           int y = TileStart.Y() + t * (TileEnd.Y() - TileStart.Y());
+           TilePixmap->SetDrawPortPoint(cPoint(x, y));
+           if (t >= 1) {
+              destroyablePixmap = TilePixmap;
+              TilePixmap = NULL;
+              }
+           Animated = true;
+           }
+        if (ScrollPixmap) {
+           if (int(Now - Start) > ScrollWaitTime) {
+              if (ScrollStartTime) {
+                 double t = min(double(Now - ScrollStartTime) / ScrollLineTime, 1.0);
+                 int x = ScrollStart.X() + t * (ScrollEnd.X() - ScrollStart.X());
+                 int y = ScrollStart.Y() + t * (ScrollEnd.Y() - ScrollStart.Y());
+                 ScrollPixmap->SetDrawPortPoint(cPoint(x, y));
+                 if (t >= 1) {
+                    if (int(Now - Start) < ScrollTotalTime) {
+                       cRect r = ScrollPixmap->DrawPort();
+                       r.SetPoint(-r.X(), -r.Y());
+                       ScrollPixmap->Pan(cPoint(0, 0), r);
+                       const cFont *Font = cFont::GetFont(fontOsd);
+                       cString s = cString::sprintf("Line %d", ++ScrollLineNumber);
+                       ScrollPixmap->DrawRectangle(cRect(0, ScrollPixmap->ViewPort().Height(), ScrollPixmap->DrawPort().Width(), ScrollPixmap->DrawPort().Height()), clrTransparent);
+                       ScrollPixmap->DrawText(cPoint(0, ScrollPixmap->ViewPort().Height()), s, clrYellow, clrTransparent, Font);
+                       ScrollStartTime = Now;
+                       }
+                    else {
+                       FadeOutPixmap = ScrollPixmap;
+                       ScrollPixmap = NULL;
+                       Start = cTimeMs::Now();
+                       }
+                    }
+                 }
+              else
+                 ScrollStartTime = Now;
+              }
+           Animated = true;
+           }
+        if (AnimPixmap) {
+           int d = AnimPixmap->ViewPort().Height();
+           if (clockwise)
+              d = -d;
+           cPoint p = AnimPixmap->DrawPort().Point().Shifted(0, d);
+           if (clockwise && p.Y() <= -AnimPixmap->DrawPort().Height())
+              p.SetY(0);
+           else if (!clockwise && p.Y() > 0)
+              p.SetY(-(AnimPixmap->DrawPort().Height() - AnimPixmap->ViewPort().Height()));
+           AnimPixmap->SetDrawPortPoint(p);
+           }
+        if (!Animated) {
+           switch (State) {
+             case 0: {
+                       if (cFont *Font = cFont::CreateFont(DefaultFontOsd, osd->Height() / 10)) {
+                          FadeInPixmap = CreateTextPixmap("VDR", Line, 1, clrYellow, clrTransparent, Font);
+                          if (FadeInPixmap)
+                             Line += FadeInPixmap->DrawPort().Height();
+                          delete Font;
+                          Start = cTimeMs::Now();
+                          }
+                       State++;
+                     }
+                     break;
+             case 1: { 
+                       FadeInPixmap = CreateTextPixmap("Video Disk Recorder", Line, 3, clrYellow, clrTransparent);
+                       if (FadeInPixmap)
+                          Line += FadeInPixmap->DrawPort().Height();
+                       Start = cTimeMs::Now();
+                       State++;
+                     }
+                     break;
+             case 2: {
+                       FadeInPixmap = CreateTextPixmap("True Color OSD Demo", Line, 1, clrYellow, clrTransparent);
+                       if (FadeInPixmap)
+                          Line += FadeInPixmap->DrawPort().Height();
+                       Start = cTimeMs::Now();
+                       State++;
+                     }
+                     break;
+             case 3: {
+                       if (cFont *Font = cFont::CreateFont(DefaultFontOsd, osd->Height() / 10)) {
+                          NextPixmap = CreateTextPixmap("Millions of colors", Line, 1, clrYellow, clrTransparent, Font);
+                          if (NextPixmap) {
+                             FadeInPixmap = NextPixmap;
+                             }
+                          Start = cTimeMs::Now();
+                          StartLine = Line;
+                          Line += NextPixmap->DrawPort().Height();
+                          }
+                       State++;
+                     }
+                     break;
+             case 4: {
+                       Line += osd->Height() / 10;
+                       int w = osd->Width() / 2;
+                       int h = osd->Height() - Line - osd->Height() / 10;
+                       cImage Image(cSize(w, h));
+                       for (int y = 0; y < h; y++) {
+                           for (int x = 0; x < w; x++)
+                               Image.SetPixel(cPoint(x, y), HsvToColor(360 * double(x) / w, 1 - double(y) / h, 1) | 0xDF000000);
+                           }
+                       if (cPixmap *Pixmap = osd->CreatePixmap(2, cRect((osd->Width() - w) / 2, Line, w, h))) {
+                          Pixmap->DrawImage(cPoint(0, 0), Image);
+                          toggleablePixmap = Pixmap;
+                          }
+                       State++;
+                     }
+                     break;
+             case 5: {
+                       if (NextPixmap) {
+                          MovePixmap = NextPixmap;
+                          MoveStart = MovePixmap->ViewPort().Point();
+                          MoveEnd.Set(osd->Width() - MovePixmap->ViewPort().Width(), osd->Height() - MovePixmap->ViewPort().Height());
+                          Start = cTimeMs::Now();
+                          }
+                       State++;
+                     }
+                     break;
+             case 6: {
+                       TilePixmap = CreateTextPixmap("Tiled Pixmaps", StartLine, 1, clrRed, clrWhite);
+                       if (TilePixmap) {
+                          TilePixmap->SetViewPort(TilePixmap->ViewPort().Grown(TilePixmap->DrawPort().Width(), TilePixmap->DrawPort().Height()));
+                          TilePixmap->SetAlpha(200);
+                          TilePixmap->SetTile(true);
+                          TileStart = TilePixmap->DrawPort().Point();
+                          TileEnd = TileStart.Shifted(TilePixmap->ViewPort().Width(), TilePixmap->ViewPort().Height());
+                          MovePixmap = TilePixmap;
+                          MoveStart = MovePixmap->ViewPort().Point();
+                          MoveEnd.Set(10, osd->Height() - MovePixmap->ViewPort().Height() - 10);
+                          Start = cTimeMs::Now();
+                          }
+                       State++;
+                     }
+                     break;
+             case 7: {
+                       const cFont *Font = cFont::GetFont(fontOsd);
+                       const char *Text = "Scrolling Pixmaps";
+                       int w = Font->Width(Text);
+                       int h = Font->Height();
+                       if (cPixmap *Pixmap = osd->CreatePixmap(2, cRect((osd->Width() - w) / 2, StartLine, w, 2 * h), cRect(0, 0, w, 3 * h))) {
+                          Pixmap->Clear();
+                          Pixmap->DrawText(cPoint(0, 0), Text, clrYellow, clrTransparent, Font);
+                          cString s = cString::sprintf("Line %d", ++ScrollLineNumber);
+                          Pixmap->DrawText(cPoint(0, Pixmap->ViewPort().Height()), s, clrYellow, clrTransparent, Font);
+                          ScrollPixmap = Pixmap;
+                          ScrollStart.Set(0, 0);
+                          ScrollEnd.Set(0, -h);
+                          Start = cTimeMs::Now();
+                          }
+                       State++;
+                     }
+                     break;
+             case 8: {
+                       const cFont *Font = cFont::GetFont(fontSml);
+                       const char *Text = "Animation";
+                       const int Size = Font->Width(Text) + 10;
+                       const int NumDots = 12;
+                       const int AnimFrames = NumDots;
+                       // Temporarily using pixmap layer 0 to have the text alpha blended:
+                       AnimPixmap = osd->CreatePixmap(0, cRect((osd->Width() - Size) / 2, StartLine, Size, Size), cRect(0, 0, Size, Size * AnimFrames));
+                       if (AnimPixmap) {
+                          AnimPixmap->SetAlpha(0);
+                          AnimPixmap->Clear();
+                          const int Diameter = Size / 5;
+                          int xc = Size / 2 - Diameter / 2;
+                          for (int Frame = 0; Frame < AnimFrames; Frame++) {
+                              AnimPixmap->DrawEllipse(cRect(0, Frame * Size, Size, Size), 0xDDFFFFFF);
+                              int yc = Frame * Size + Size / 2 - Diameter / 2;
+                              int Color = 0xFF;
+                              int Delta = Color / NumDots / 3;
+                              for (int a = 0; a < NumDots; a++) {
+                                  double t = 2 * M_PI * (Frame + a) / NumDots;
+                                  int x = xc + ((Size - Diameter) / 2 - 5) * cos(t);
+                                  int y = yc + ((Size - Diameter) / 2 - 5) * sin(t);
+                                  AnimPixmap->DrawEllipse(cRect(x, y, Diameter, Diameter), ArgbToColor(0xFF, Color, Color, Color));
+                                  Color -= Delta;
+                                  }
+                              AnimPixmap->DrawText(cPoint(0, Frame * Size), Text, clrBlack, clrTransparent, cFont::GetFont(fontSml), Size, Size, taCenter);
+                              }
+                          AnimPixmap->SetLayer(3); // now setting the actual pixmap layer
+                          FadeInPixmap = AnimPixmap;
+                          LOCK_THREAD;
+                          OldCursor = cursor = AnimPixmap->ViewPort().Point();
+                          cursorLimits.Set(0, 0, osd->Width(), osd->Height());
+                          cursorLimits.SetRight(cursorLimits.Right() - Size);
+                          cursorLimits.SetBottom(cursorLimits.Bottom() - Size);
+                          cursorLimits.Grow(-10, -10);
+                          Start = cTimeMs::Now();
+                          }
+                       State++;
+                     }
+                     break;
+             case 9: {
+                       LOCK_THREAD;
+                       if (cursor != OldCursor) {
+                          MovePixmap = AnimPixmap;
+                          MoveStart = MovePixmap->ViewPort().Point();
+                          MoveEnd = OldCursor = cursor;
+                          MoveTime = 500;
+                          Start = cTimeMs::Now();
+                          }
+                     }
+                     break;
+             }
+           }
+        osd->Flush();
+        cPixmap::Unlock();
+        int Delta = cTimeMs::Now() - Now;
+        if (Delta < FrameTime)
+           cCondWait::SleepMs(FrameTime - Delta);
+        }
+}
+
+void cTrueColorDemo::Show(void)
+{
+  osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop(), 50);
+  if (osd) {
+     tArea Area = { 0, 0, cOsd::OsdWidth() - 1, cOsd::OsdHeight() - 1,  32 };
+     if (osd->SetAreas(&Area, 1) == oeOk) {
+        osd->DrawRectangle(0, 0, osd->Width() -1 , osd->Height() - 1, clrGray50);
+        osd->Flush();
+        Start();
+        }
+     }
+}
+
+eOSState cTrueColorDemo::ProcessKey(eKeys Key)
+{
+  eOSState state = cOsdObject::ProcessKey(Key);
+  if (state == osUnknown) {
+     LOCK_PIXMAPS;
+     LOCK_THREAD;
+     const int d = 80;
+     switch (Key & ~k_Repeat) {
+       case kUp:     cursor.SetY(max(cursorLimits.Top(),    cursor.Y() - d)); clockwise = false; break;
+       case kDown:   cursor.SetY(min(cursorLimits.Bottom(), cursor.Y() + d)); clockwise = true; break;
+       case kLeft:   cursor.SetX(max(cursorLimits.Left(),   cursor.X() - d)); clockwise = false; break;
+       case kRight:  cursor.SetX(min(cursorLimits.Right(),  cursor.X() + d)); clockwise = true; break;
+       case kRed:    if (destroyablePixmap) {
+                        osd->DestroyPixmap(destroyablePixmap);
+                        destroyablePixmap = NULL;
+                        }
+                     break;
+       case kGreen:  if (toggleablePixmap)
+                        toggleablePixmap->SetLayer(-toggleablePixmap->Layer());
+                     break;
+       case kOk:     return osEnd;
+       default: return state;
+       }
+     state = osContinue;
+     }
+  return state;
+}
+
 // --- cPluginOsddemo --------------------------------------------------------
 
 class cPluginOsddemo : public cPlugin {
@@ -131,6 +492,8 @@
 cOsdObject *cPluginOsddemo::MainMenuAction(void)
 {
   // Perform the action when selected from the main VDR menu.
+  if (cOsdProvider::SupportsTrueColor())
+     return new cTrueColorDemo;
   return new cLineGame;
 }
 
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/HISTORY vdr-1.7.17/PLUGINS/src/pictures/HISTORY
--- vdr-1.7.16/PLUGINS/src/pictures/HISTORY	2010-02-28 13:49:50.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/pictures/HISTORY	2011-02-20 17:50:57.000000000 +0100
@@ -41,3 +41,7 @@
 2010-02-28: Version 0.0.9
 
 - Added Lithuanian language translations (thanks to Valdemaras Pipiras).
+
+2011-02-20: Version 0.1.0
+
+- Fixed reallocating memory (reported by Paul Menzel).
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/Makefile vdr-1.7.17/PLUGINS/src/pictures/Makefile
--- vdr-1.7.16/PLUGINS/src/pictures/Makefile	2010-02-06 15:50:03.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/pictures/Makefile	2011-02-27 11:05:02.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.2 2010/02/06 14:50:03 kls Exp $
+# $Id: Makefile 2.6 2011/02/27 10:05:02 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -18,7 +18,7 @@
 ### The C++ compiler and options:
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 ### The directory environment:
 
@@ -83,7 +83,7 @@
 	msgfmt -c -o $@ $<
 
 $(I18Npot): $(wildcard *.c)
-	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ $^
+	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=VDR --package-version=$(VDRVERSION) --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ $^
 
 %.po: $(I18Npot)
 	msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
@@ -99,10 +99,10 @@
 ### Targets:
 
 libvdr-$(PLUGIN).so: $(OBJS)
-	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 
-dist: clean
+dist: $(I18Npo) clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
 	@mkdir $(TMPDIR)/$(ARCHIVE)
 	@cp -a * $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/pictures.c vdr-1.7.17/PLUGINS/src/pictures/pictures.c
--- vdr-1.7.16/PLUGINS/src/pictures/pictures.c	2010-02-28 13:49:55.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/pictures/pictures.c	2011-02-20 17:50:01.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: pictures.c 2.2 2010/02/28 12:49:55 kls Exp $
+ * $Id: pictures.c 2.3 2011/02/20 16:50:01 kls Exp $
  */
 
 #include <getopt.h>
@@ -11,7 +11,7 @@
 #include "menu.h"
 #include "player.h"
 
-static const char *VERSION       = "0.0.9";
+static const char *VERSION       = "0.1.0";
 static const char *DESCRIPTION   = trNOOP("A simple picture viewer");
 static const char *MAINMENUENTRY = trNOOP("Pictures");
 
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/player.c vdr-1.7.17/PLUGINS/src/pictures/player.c
--- vdr-1.7.16/PLUGINS/src/pictures/player.c	2008-02-09 13:13:10.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/pictures/player.c	2011-02-20 18:15:25.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: player.c 2.0 2008/02/09 12:13:10 kls Exp $
+ * $Id: player.c 2.1 2011/02/20 17:15:25 kls Exp $
  */
 
 #include "player.h"
@@ -66,8 +66,15 @@
          length = read(f, buffer, size);
          if (length > 0) {
             if (length >= size) {
-               size = size * 3 / 2;
-               buffer = (uchar *)realloc(buffer, size);
+               int NewSize = size * 3 / 2;
+               if (uchar *NewBuffer = (uchar *)realloc(buffer, NewSize)) {
+                  buffer = NewBuffer;
+                  size = NewSize;
+                  }
+               else {
+                  LOG_ERROR_STR("out of memory");
+                  break;
+                  }
                lseek(f, 0, SEEK_SET);
                continue;
                }
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/po/de_DE.po vdr-1.7.17/PLUGINS/src/pictures/po/de_DE.po
--- vdr-1.7.16/PLUGINS/src/pictures/po/de_DE.po	2010-09-19 14:46:03.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/pictures/po/de_DE.po	2010-10-24 16:43:10.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2008-01-12 17:38+0100\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-01-12 17:41+0100\n"
 "Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n"
-"Language-Team: German\n"
+"Language-Team: German <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 msgid "Pictures"
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/po/fi_FI.po vdr-1.7.17/PLUGINS/src/pictures/po/fi_FI.po
--- vdr-1.7.16/PLUGINS/src/pictures/po/fi_FI.po	2010-09-19 14:46:03.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/pictures/po/fi_FI.po	2010-10-24 16:43:10.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2008-01-12 17:38+0100\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-01-12 17:41+0100\n"
 "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
-"Language-Team: Finnish\n"
+"Language-Team: Finnish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fi\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 msgid "Pictures"
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/po/fr_FR.po vdr-1.7.17/PLUGINS/src/pictures/po/fr_FR.po
--- vdr-1.7.16/PLUGINS/src/pictures/po/fr_FR.po	2010-09-19 14:46:03.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/pictures/po/fr_FR.po	2010-10-24 16:43:10.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2008-01-12 17:38+0100\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-01-12 17:41+0100\n"
 "Last-Translator: Patrice Staudt <ipatrice.staudt@laposte.net>\n"
-"Language-Team: French\n"
+"Language-Team: French <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fr\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 msgid "Pictures"
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/po/it_IT.po vdr-1.7.17/PLUGINS/src/pictures/po/it_IT.po
--- vdr-1.7.16/PLUGINS/src/pictures/po/it_IT.po	2010-09-19 14:46:03.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/pictures/po/it_IT.po	2010-10-24 16:43:10.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2008-01-12 17:38+0100\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-01-27 20:22+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
-"Language-Team: Italian\n"
+"Language-Team: Italian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: it\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 msgid "Pictures"
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/po/lt_LT.po vdr-1.7.17/PLUGINS/src/pictures/po/lt_LT.po
--- vdr-1.7.16/PLUGINS/src/pictures/po/lt_LT.po	2010-09-19 14:46:03.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/pictures/po/lt_LT.po	2010-10-24 16:43:10.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.10\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2008-01-12 17:38+0100\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2009-12-08 12:41+0100\n"
 "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>, 2009\n"
-"Language-Team: Lietuviai\n"
+"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: lt\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 msgid "Pictures"
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/po/ru_RU.po vdr-1.7.17/PLUGINS/src/pictures/po/ru_RU.po
--- vdr-1.7.16/PLUGINS/src/pictures/po/ru_RU.po	2010-09-19 14:46:03.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/pictures/po/ru_RU.po	2010-10-24 16:43:10.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2008-01-12 17:38+0100\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-03-14 00:45+0100\n"
 "Last-Translator: Alexander Gross <Bikalexander@gmail.com>\n"
-"Language-Team: Russian\n"
+"Language-Team: Russian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-5\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: ru\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Generator: KBabel 1.11.4\n"
 
diff -ruN vdr-1.7.16/PLUGINS/src/pictures/po/sk_SK.po vdr-1.7.17/PLUGINS/src/pictures/po/sk_SK.po
--- vdr-1.7.16/PLUGINS/src/pictures/po/sk_SK.po	2010-09-19 14:46:03.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/pictures/po/sk_SK.po	2010-10-24 16:43:10.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2008-01-12 17:38+0100\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2009-09-30 12:54+0100\n"
 "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
-"Language-Team: Slovak\n"
+"Language-Team: Slovak <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: sk\n"
 
 msgid "Pictures"
 msgstr "Obrázky"
@@ -29,4 +30,3 @@
 
 msgid "No picture directory has been defined!"
 msgstr "Neboli preukázané ¾iadne fotky v adresári!"
-
diff -ruN vdr-1.7.16/PLUGINS/src/servicedemo/Makefile vdr-1.7.17/PLUGINS/src/servicedemo/Makefile
--- vdr-1.7.16/PLUGINS/src/servicedemo/Makefile	2010-02-06 15:50:03.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/servicedemo/Makefile	2011-02-27 11:05:04.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.1 2010/02/06 14:50:03 kls Exp $
+# $Id: Makefile 2.3 2011/02/27 10:05:04 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -18,7 +18,7 @@
 ### The C++ compiler and options:
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 ### The directory environment:
 
@@ -74,11 +74,11 @@
 ### Targets:
 
 libvdr-$(PLUGIN1).so: $(PLUGIN1).o
-	$(CXX) $(CXXFLAGS) -shared $(PLUGIN1).o -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN1).o -o $@
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 
 libvdr-$(PLUGIN2).so: $(PLUGIN2).o
-	$(CXX) $(CXXFLAGS) -shared $(PLUGIN2).o -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN2).o -o $@
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
diff -ruN vdr-1.7.16/PLUGINS/src/skincurses/Makefile vdr-1.7.17/PLUGINS/src/skincurses/Makefile
--- vdr-1.7.16/PLUGINS/src/skincurses/Makefile	2010-02-06 15:50:03.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/skincurses/Makefile	2011-02-27 11:05:05.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.2 2010/02/06 14:50:03 kls Exp $
+# $Id: Makefile 2.6 2011/02/27 10:05:05 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -18,7 +18,7 @@
 ### The C++ compiler and options:
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 ### The directory environment:
 
@@ -83,7 +83,7 @@
 	msgfmt -c -o $@ $<
 
 $(I18Npot): $(wildcard *.c)
-	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ $^
+	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=VDR --package-version=$(VDRVERSION) --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ $^
 
 %.po: $(I18Npot)
 	msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
@@ -99,10 +99,10 @@
 ### Targets:
 
 libvdr-$(PLUGIN).so: $(OBJS)
-	$(CXX) $(CXXFLAGS) -shared $(OBJS) -lncursesw -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -lncursesw -o $@
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 
-dist: clean
+dist: $(I18Npo) clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
 	@mkdir $(TMPDIR)/$(ARCHIVE)
 	@cp -a * $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.7.16/PLUGINS/src/skincurses/po/de_DE.po vdr-1.7.17/PLUGINS/src/skincurses/po/de_DE.po
--- vdr-1.7.16/PLUGINS/src/skincurses/po/de_DE.po	2010-09-19 14:46:05.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/skincurses/po/de_DE.po	2010-10-24 16:43:12.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-08-15 16:04+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-15 16:07+0200\n"
 "Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n"
-"Language-Team: German\n"
+"Language-Team: German <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
 
 msgid "A text only skin"
 msgstr "Eine reine Text-Oberfläche"
diff -ruN vdr-1.7.16/PLUGINS/src/skincurses/po/fi_FI.po vdr-1.7.17/PLUGINS/src/skincurses/po/fi_FI.po
--- vdr-1.7.16/PLUGINS/src/skincurses/po/fi_FI.po	2010-09-19 14:46:05.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/skincurses/po/fi_FI.po	2010-10-24 16:43:13.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-08-14 20:54+0300\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2007-08-14 20:48+0300\n"
 "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
-"Language-Team: Finnish\n"
+"Language-Team: Finnish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fi\n"
 
 msgid "A text only skin"
 msgstr "Tekstipohjainen ulkoasu"
diff -ruN vdr-1.7.16/PLUGINS/src/skincurses/po/it_IT.po vdr-1.7.17/PLUGINS/src/skincurses/po/it_IT.po
--- vdr-1.7.16/PLUGINS/src/skincurses/po/it_IT.po	2010-09-19 14:46:05.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/skincurses/po/it_IT.po	2010-10-24 16:43:13.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-08-15 16:04+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-01-27 20:35+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
-"Language-Team: Italian\n"
+"Language-Team: Italian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: it\n"
 
 msgid "A text only skin"
 msgstr "Una interfaccia solo testo"
diff -ruN vdr-1.7.16/PLUGINS/src/skincurses/po/lt_LT.po vdr-1.7.17/PLUGINS/src/skincurses/po/lt_LT.po
--- vdr-1.7.16/PLUGINS/src/skincurses/po/lt_LT.po	2010-09-19 14:46:05.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/skincurses/po/lt_LT.po	2010-10-24 16:43:13.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.12\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2009-10-13 11:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2010-02-22 18:18+0200\n"
 "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
-"Language-Team: Lietuviai\n"
+"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: lt\n"
 
 msgid "A text only skin"
 msgstr "Tekstinis apvalkalas"
diff -ruN vdr-1.7.16/PLUGINS/src/skincurses/po/ru_RU.po vdr-1.7.17/PLUGINS/src/skincurses/po/ru_RU.po
--- vdr-1.7.16/PLUGINS/src/skincurses/po/ru_RU.po	2010-09-19 14:46:05.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/skincurses/po/ru_RU.po	2010-10-24 16:43:13.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-08-15 16:04+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2008-03-14 00:21+0100\n"
 "Last-Translator: Alexander Gross <Bikalexander@gmail.com>\n"
-"Language-Team: Russian\n"
+"Language-Team: Russian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-5\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: ru\n"
 "X-Generator: KBabel 1.11.4\n"
 
 msgid "A text only skin"
diff -ruN vdr-1.7.16/PLUGINS/src/skincurses/po/sk_SK.po vdr-1.7.17/PLUGINS/src/skincurses/po/sk_SK.po
--- vdr-1.7.16/PLUGINS/src/skincurses/po/sk_SK.po	2010-09-19 14:46:05.000000000 +0200
+++ vdr-1.7.17/PLUGINS/src/skincurses/po/sk_SK.po	2010-10-24 16:43:13.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2007-08-15 16:04+0200\n"
+"POT-Creation-Date: 2010-10-24 16:43+0200\n"
 "PO-Revision-Date: 2009-09-30 12:52+0100\n"
 "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
-"Language-Team: Slovak\n"
+"Language-Team: Slovak <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: sk\n"
 
 msgid "A text only skin"
 msgstr "Iba text vzhµadu"
@@ -26,4 +27,3 @@
 
 msgid "Text mode"
 msgstr "Textový re¾im"
-
diff -ruN vdr-1.7.16/PLUGINS/src/skincurses/skincurses.c vdr-1.7.17/PLUGINS/src/skincurses/skincurses.c
--- vdr-1.7.16/PLUGINS/src/skincurses/skincurses.c	2010-02-28 13:50:13.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/skincurses/skincurses.c	2011-01-04 09:52:03.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: skincurses.c 2.4 2010/02/28 12:50:13 kls Exp $
+ * $Id: skincurses.c 2.5 2011/01/04 08:52:03 kls Exp $
  */
 
 #include <ncurses.h>
@@ -23,6 +23,7 @@
   virtual int Width(const char *s) const { return s ? Utf8StrLen(s) : 0; }
   virtual int Height(void) const { return 1; }
   virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}
+  virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}
   };
 
 static const cCursesFont Font;
diff -ruN vdr-1.7.16/PLUGINS/src/status/Makefile vdr-1.7.17/PLUGINS/src/status/Makefile
--- vdr-1.7.16/PLUGINS/src/status/Makefile	2010-02-06 15:50:03.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/status/Makefile	2011-02-27 11:05:08.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.1 2010/02/06 14:50:03 kls Exp $
+# $Id: Makefile 2.3 2011/02/27 10:05:08 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -16,7 +16,7 @@
 ### The C++ compiler and options:
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 ### The directory environment:
 
@@ -72,7 +72,7 @@
 ### Targets:
 
 libvdr-$(PLUGIN).so: $(OBJS)
-	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
diff -ruN vdr-1.7.16/PLUGINS/src/svdrpdemo/Makefile vdr-1.7.17/PLUGINS/src/svdrpdemo/Makefile
--- vdr-1.7.16/PLUGINS/src/svdrpdemo/Makefile	2010-02-06 15:50:03.000000000 +0100
+++ vdr-1.7.17/PLUGINS/src/svdrpdemo/Makefile	2011-02-27 11:05:10.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.1 2010/02/06 14:50:03 kls Exp $
+# $Id: Makefile 2.3 2011/02/27 10:05:10 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -16,7 +16,7 @@
 ### The C++ compiler and options:
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 ### The directory environment:
 
@@ -72,7 +72,7 @@
 ### Targets:
 
 libvdr-$(PLUGIN).so: $(OBJS)
-	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
diff -ruN vdr-1.7.16/channels.c vdr-1.7.17/channels.c
--- vdr-1.7.16/channels.c	2010-06-05 15:33:57.000000000 +0200
+++ vdr-1.7.17/channels.c	2010-11-07 13:24:59.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: channels.c 2.16 2010/06/05 13:33:57 kls Exp $
+ * $Id: channels.c 2.17 2010/11/07 12:24:59 kls Exp $
  */
 
 #include "channels.h"
@@ -262,12 +262,14 @@
 {
   int result = 0;
   for (int i = 0; a[i] || b[i]; i++) {
-      if (a[i] && na && nb && strcmp(na[i], nb[i]) != 0)
+      if (!a[i] || !b[i]) {
+         result |= VALDIFF;
+         break;
+         }
+      if (na && nb && strcmp(na[i], nb[i]) != 0)
          result |= STRDIFF;
       if (a[i] != b[i])
          result |= VALDIFF;
-      if (!a[i] || !b[i])
-         break;
       }
   return result;
 }
diff -ruN vdr-1.7.16/config.h vdr-1.7.17/config.h
--- vdr-1.7.16/config.h	2010-09-12 13:31:21.000000000 +0200
+++ vdr-1.7.17/config.h	2010-10-24 13:22:35.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.h 2.28 2010/09/12 11:31:21 kls Exp $
+ * $Id: config.h 2.29 2010/10/24 11:22:35 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -22,13 +22,13 @@
 
 // VDR's own version number:
 
-#define VDRVERSION  "1.7.16"
-#define VDRVERSNUM   10716  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "1.7.17"
+#define VDRVERSNUM   10717  // Version * 10000 + Major * 100 + Minor
 
 // The plugin API's version number:
 
-#define APIVERSION  "1.7.16"
-#define APIVERSNUM   10716  // Version * 10000 + Major * 100 + Minor
+#define APIVERSION  "1.7.17"
+#define APIVERSNUM   10717  // Version * 10000 + Major * 100 + Minor
 
 // When loading plugins, VDR searches them by their APIVERSION, which
 // may be smaller than VDRVERSION in case there have been no changes to
diff -ruN vdr-1.7.16/cutter.c vdr-1.7.17/cutter.c
--- vdr-1.7.16/cutter.c	2010-08-29 15:35:18.000000000 +0200
+++ vdr-1.7.17/cutter.c	2011-03-06 15:54:33.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: cutter.c 2.5 2010/08/29 13:35:18 kls Exp $
+ * $Id: cutter.c 2.6 2011/03/06 14:54:33 kls Exp $
  */
 
 #include "cutter.h"
@@ -68,6 +68,8 @@
 {
   cMark *Mark = fromMarks.First();
   if (Mark) {
+     SetPriority(19);
+     SetIOPriority(7);
      fromFile = fromFileName->Open();
      toFile = toFileName->Open();
      if (!fromFile || !toFile)
diff -ruN vdr-1.7.16/device.c vdr-1.7.17/device.c
--- vdr-1.7.16/device.c	2010-06-03 15:35:02.000000000 +0200
+++ vdr-1.7.17/device.c	2011-02-25 16:12:03.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 2.37 2010/06/03 13:35:02 kls Exp $
+ * $Id: device.c 2.38 2011/02/25 15:12:03 kls Exp $
  */
 
 #include "device.h"
@@ -1087,11 +1087,17 @@
                  int l;
                  while (const uchar *p = TsToPes.GetPes(l)) {
                        int Offset = Size;
-                       Size += l;
-                       buf = (uchar *)realloc(buf, Size);
-                       if (!buf)
+                       int NewSize = Size + l;
+                       if (uchar *NewBuffer = (uchar *)realloc(buf, NewSize)) {
+                          Size = NewSize;
+                          buf = NewBuffer;
+                          memcpy(buf + Offset, p, l);
+                          }
+                       else {
+                          LOG_ERROR_STR("out of memory");
+                          free(buf);
                           return;
-                       memcpy(buf + Offset, p, l);
+                          }
                        }
                  TsToPes.Reset();
                  }
@@ -1103,11 +1109,17 @@
      int l;
      while (const uchar *p = TsToPes.GetPes(l)) {
            int Offset = Size;
-           Size += l;
-           buf = (uchar *)realloc(buf, Size);
-           if (!buf)
+           int NewSize = Size + l;
+           if (uchar *NewBuffer = (uchar *)realloc(buf, NewSize)) {
+              Size = NewSize;
+              buf = NewBuffer;
+              memcpy(buf + Offset, p, l);
+              }
+           else {
+              esyslog("ERROR: out of memory");
+              free(buf);
               return;
-           memcpy(buf + Offset, p, l);
+              }
            }
      StillPicture(buf, Size);
      free(buf);
diff -ruN vdr-1.7.16/device.h vdr-1.7.17/device.h
--- vdr-1.7.16/device.h	2010-04-05 11:51:29.000000000 +0200
+++ vdr-1.7.17/device.h	2010-10-24 14:11:16.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.h 2.22 2010/04/05 09:51:29 kls Exp $
+ * $Id: device.h 2.23 2010/10/24 12:11:16 kls Exp $
  */
 
 #ifndef __DEVICE_H
@@ -586,8 +586,8 @@
 public:
   virtual int64_t GetSTC(void);
        ///< Gets the current System Time Counter, which can be used to
-       ///< synchronize audio and video. If this device is unable to
-       ///< provide the STC, -1 will be returned.
+       ///< synchronize audio, video and subtitles. If this device is able to
+       ///< replay, it must provide an STC.
        ///< The value returned doesn't need to be an actual "clock" value,
        ///< it is sufficient if it holds the PTS (Presentation Time Stamp) of
        ///< the most recently presented frame. A proper value must be returned
diff -ruN vdr-1.7.16/dvbsubtitle.c vdr-1.7.17/dvbsubtitle.c
--- vdr-1.7.16/dvbsubtitle.c	2010-08-29 16:08:23.000000000 +0200
+++ vdr-1.7.17/dvbsubtitle.c	2011-03-12 16:13:03.000000000 +0100
@@ -7,7 +7,7 @@
  * Original author: Marco Schlüßler <marco@lordzodiac.de>
  * With some input from the "subtitle plugin" by Pekka Virtanen <pekka.virtanen@sci.fi>
  *
- * $Id: dvbsubtitle.c 2.7 2010/08/29 14:08:23 kls Exp $
+ * $Id: dvbsubtitle.c 2.11 2011/03/12 15:13:03 kls Exp $
  */
 
 #include "dvbsubtitle.h"
@@ -420,7 +420,7 @@
   int PageId(void) { return pageId; }
   int Version(void) { return version; }
   int State(void) { return state; }
-  tArea *GetAreas(void);
+  tArea *GetAreas(double Factor);
   cSubtitleClut *GetClutById(int ClutId, bool New = false);
   cSubtitleObject *GetObjectById(int ObjectId);
   cSubtitleRegion *GetRegionById(int RegionId, bool New = false);
@@ -446,16 +446,16 @@
 {
 }
 
-tArea *cDvbSubtitlePage::GetAreas(void)
+tArea *cDvbSubtitlePage::GetAreas(double Factor)
 {
   if (regions.Count() > 0) {
      tArea *Areas = new tArea[regions.Count()];
      tArea *a = Areas;
      for (cSubtitleRegion *sr = regions.First(); sr; sr = regions.Next(sr)) {
-         a->x1 = sr->HorizontalAddress();
-         a->y1 = sr->VerticalAddress();
-         a->x2 = sr->HorizontalAddress() + sr->Width() - 1;
-         a->y2 = sr->VerticalAddress() + sr->Height() - 1;
+         a->x1 = int(round(Factor * sr->HorizontalAddress()));
+         a->y1 = int(round(Factor * sr->VerticalAddress()));
+         a->x2 = int(round(Factor * (sr->HorizontalAddress() + sr->Width() - 1)));
+         a->y2 = int(round(Factor * (sr->VerticalAddress() + sr->Height() - 1)));
          a->bpp = sr->Bpp();
          while ((a->Width() & 3) != 0)
                a->x2++; // aligns width to a multiple of 4, so 2, 4 and 8 bpp will work
@@ -570,12 +570,17 @@
 bool cDvbSubtitleAssembler::Realloc(int Size)
 {
   if (Size > size) {
-     size = max(Size, 2048);
-     data = (uchar *)realloc(data, size);
-     if (!data) {
+     Size = max(Size, 2048);
+     if (uchar *NewBuffer = (uchar *)realloc(data, Size)) {
+        size = Size;
+        data = NewBuffer;
+        }
+     else {
         esyslog("ERROR: can't allocate memory for subtitle assembler");
         length = 0;
         size = 0;
+        free(data);
+        data = NULL;
         return false;
         }
      }
@@ -611,9 +616,10 @@
   int timeout;
   tArea *areas;
   int numAreas;
+  double osdFactor;
   cVector<cBitmap *> bitmaps;
 public:
-  cDvbSubtitleBitmaps(int64_t Pts, int Timeout, tArea *Areas, int NumAreas);
+  cDvbSubtitleBitmaps(int64_t Pts, int Timeout, tArea *Areas, int NumAreas, double OsdFactor);
   ~cDvbSubtitleBitmaps();
   int64_t Pts(void) { return pts; }
   int Timeout(void) { return timeout; }
@@ -621,12 +627,13 @@
   void Draw(cOsd *Osd);
   };
 
-cDvbSubtitleBitmaps::cDvbSubtitleBitmaps(int64_t Pts, int Timeout, tArea *Areas, int NumAreas)
+cDvbSubtitleBitmaps::cDvbSubtitleBitmaps(int64_t Pts, int Timeout, tArea *Areas, int NumAreas, double OsdFactor)
 {
   pts = Pts;
   timeout = Timeout;
   areas = Areas;
   numAreas = NumAreas;
+  osdFactor = OsdFactor;
 }
 
 cDvbSubtitleBitmaps::~cDvbSubtitleBitmaps()
@@ -644,8 +651,14 @@
 void cDvbSubtitleBitmaps::Draw(cOsd *Osd)
 {
   if (Osd->SetAreas(areas, numAreas) == oeOk) {
-     for (int i = 0; i < bitmaps.Size(); i++)
-         Osd->DrawBitmap(bitmaps[i]->X0(), bitmaps[i]->Y0(), *bitmaps[i]);
+     for (int i = 0; i < bitmaps.Size(); i++) {
+         cBitmap *b = bitmaps[i];
+         if (osdFactor != 1.0)
+            b = b->Scale(osdFactor, osdFactor);
+         Osd->DrawBitmap(int(round(b->X0() * osdFactor)), int(round(b->Y0() * osdFactor)), *b);
+         if (b != bitmaps[i])
+            delete b;
+         }
      Osd->Flush();
      }
 }
@@ -661,10 +674,11 @@
   osd = NULL;
   frozen = false;
   ddsVersionNumber = -1;
-  displayWidth = 720;
-  displayHeight = 576;
-  displayHorizontalOffset = 0;
-  displayVerticalOffset = 0;
+  displayWidth = windowWidth = 720;
+  displayHeight = windowHeight = 576;
+  windowHorizontalOffset = 0;
+  windowVerticalOffset = 0;
+  SetOsdData();
   pages = new cList<cDvbSubtitlePage>;
   bitmaps = new cList<cDvbSubtitleBitmaps>;
   Start();
@@ -694,10 +708,11 @@
   DELETENULL(osd);
   frozen = false;
   ddsVersionNumber = -1;
-  displayWidth = 720;
-  displayHeight = 576;
-  displayHorizontalOffset = 0;
-  displayVerticalOffset = 0;
+  displayWidth = windowWidth = 720;
+  displayHeight = windowHeight = 576;
+  windowHorizontalOffset = 0;
+  windowVerticalOffset = 0;
+  SetOsdData();
   Unlock();
 }
 
@@ -781,7 +796,7 @@
   return 0;
 }
 
-#define LimitTo32Bit(n) (n & 0x00000000FFFFFFFFL)
+#define LimitTo32Bit(n) ((n) & 0x00000000FFFFFFFFL)
 #define MAXDELTA 40000 // max. reasonable PTS/STC delta in ms
 
 void cDvbSubtitleConverter::Action(void)
@@ -801,17 +816,11 @@
            Lock();
            if (cDvbSubtitleBitmaps *sb = bitmaps->First()) {
               int64_t STC = cDevice::PrimaryDevice()->GetSTC();
-              int64_t Delta = 0;
-              if (STC >= 0) {
-                 Delta = LimitTo32Bit(sb->Pts()) - LimitTo32Bit(STC); // some devices only deliver 32 bits
-                 if (Delta > (int64_t(1) << 31))
-                    Delta -= (int64_t(1) << 32);
-                 else if (Delta < -((int64_t(1) << 31) - 1))
-                    Delta += (int64_t(1) << 32);
-                 }
-              else {
-                 //TODO sync on PTS? are there actually devices that don't deliver an STC?
-                 }
+              int64_t Delta = LimitTo32Bit(sb->Pts()) - LimitTo32Bit(STC); // some devices only deliver 32 bits
+              if (Delta > (int64_t(1) << 31))
+                 Delta -= (int64_t(1) << 32);
+              else if (Delta < -((int64_t(1) << 31) - 1))
+                 Delta += (int64_t(1) << 32);
               Delta /= 90; // STC and PTS are in 1/90000s
               if (Delta <= MAXDELTA) {
                  if (Delta <= 0) {
@@ -851,9 +860,29 @@
   return (Er << 16) | (Eg << 8) | Eb;
 }
 
+void cDvbSubtitleConverter::SetOsdData(void)
+{
+  int OsdWidth;
+  int OsdHeight;
+  double OsdAspect;
+  cDevice::PrimaryDevice()->GetOsdSize(OsdWidth, OsdHeight, OsdAspect);
+  osdDeltaX = osdDeltaY = 0;
+  osdFactor = 1.0;
+  double fw = double(OsdWidth) / displayWidth;
+  double fh = double(OsdHeight) / displayHeight;
+  if (fw >= fh) {
+     osdFactor = fh;
+     osdDeltaX = (OsdWidth - displayWidth * osdFactor) / 2;
+     }
+  else {
+     osdFactor = fw;
+     osdDeltaY = (OsdHeight - displayHeight * osdFactor) / 2;
+     }
+}
+
 bool cDvbSubtitleConverter::AssertOsd(void)
 {
-  return osd || (osd = cOsdProvider::NewOsd(displayHorizontalOffset, displayVerticalOffset + Setup.SubtitleOffset, OSD_LEVEL_SUBTITLES));
+  return osd || (osd = cOsdProvider::NewOsd(int(round(osdFactor * windowHorizontalOffset + osdDeltaX)), int(round(osdFactor * windowVerticalOffset + osdDeltaY)) + Setup.SubtitleOffset, OSD_LEVEL_SUBTITLES));
 }
 
 int cDvbSubtitleConverter::ExtractSegment(const uchar *Data, int Length, int64_t Pts)
@@ -1017,16 +1046,17 @@
             int version = (Data[6] & 0xF0) >> 4;
             if (version != ddsVersionNumber) {
                int displayWindowFlag   = (Data[6] & 0x08) >> 3;
-               displayHorizontalOffset = 0;
-               displayVerticalOffset   = 0;
-               displayWidth            = ((Data[7] << 8) | Data[8]) + 1;
-               displayHeight           = ((Data[9] << 8) | Data[10]) + 1;
+               windowHorizontalOffset = 0;
+               windowVerticalOffset   = 0;
+               displayWidth = windowWidth   = ((Data[7] << 8) | Data[8]) + 1;
+               displayHeight = windowHeight = ((Data[9] << 8) | Data[10]) + 1;
                if (displayWindowFlag) { 
-                  displayHorizontalOffset = (Data[11] << 8) | Data[12];                                 // displayWindowHorizontalPositionMinimum
-                  displayWidth            = ((Data[13] << 8) | Data[14]) - displayHorizontalOffset + 1; // displayWindowHorizontalPositionMaximum
-                  displayVerticalOffset   = (Data[15] << 8) | Data[16];                                 // displayWindowVerticalPositionMinimum
-                  displayHeight           = ((Data[17] << 8) | Data[18]) - displayVerticalOffset + 1;   // displayWindowVerticalPositionMaximum
+                  windowHorizontalOffset = (Data[11] << 8) | Data[12];                                // displayWindowHorizontalPositionMinimum
+                  windowWidth            = ((Data[13] << 8) | Data[14]) - windowHorizontalOffset + 1; // displayWindowHorizontalPositionMaximum
+                  windowVerticalOffset   = (Data[15] << 8) | Data[16];                                // displayWindowVerticalPositionMinimum
+                  windowHeight           = ((Data[17] << 8) | Data[18]) - windowVerticalOffset + 1;   // displayWindowVerticalPositionMaximum
                   }
+               SetOsdData();
                SetupChanged();
                ddsVersionNumber = version;
                }
@@ -1049,7 +1079,7 @@
 {
   if (!AssertOsd())
      return;
-  tArea *Areas = Page->GetAreas();
+  tArea *Areas = Page->GetAreas(osdFactor);
   int NumAreas = Page->regions.Count();
   int Bpp = 8;
   bool Reduced = false;
@@ -1086,7 +1116,7 @@
             }
          }
      }
-  cDvbSubtitleBitmaps *Bitmaps = new cDvbSubtitleBitmaps(Page->Pts(), Page->Timeout(), Areas, NumAreas);
+  cDvbSubtitleBitmaps *Bitmaps = new cDvbSubtitleBitmaps(Page->Pts(), Page->Timeout(), Areas, NumAreas, osdFactor);
   bitmaps->Add(Bitmaps);
   for (cSubtitleRegion *sr = Page->regions.First(); sr; sr = Page->regions.Next(sr)) {
       int posX = sr->HorizontalAddress();
diff -ruN vdr-1.7.16/dvbsubtitle.h vdr-1.7.17/dvbsubtitle.h
--- vdr-1.7.16/dvbsubtitle.h	2010-05-13 16:43:44.000000000 +0200
+++ vdr-1.7.17/dvbsubtitle.h	2011-03-12 15:03:42.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * Original author: Marco Schlüßler <marco@lordzodiac.de>
  *
- * $Id: dvbsubtitle.h 2.3 2010/05/13 14:43:44 kls Exp $
+ * $Id: dvbsubtitle.h 2.5 2011/03/12 14:03:42 kls Exp $
  */
 
 #ifndef __DVBSUBTITLE_H
@@ -29,11 +29,17 @@
   int ddsVersionNumber;
   int displayWidth;
   int displayHeight;
-  int displayHorizontalOffset;
-  int displayVerticalOffset;
+  int windowHorizontalOffset;
+  int windowVerticalOffset;
+  int windowWidth;
+  int windowHeight;
+  int osdDeltaX;
+  int osdDeltaY;
+  double osdFactor;
   cList<cDvbSubtitlePage> *pages;
   cList<cDvbSubtitleBitmaps> *bitmaps;
   tColor yuv2rgb(int Y, int Cb, int Cr);
+  void SetOsdData(void);
   bool AssertOsd(void);
   int ExtractSegment(const uchar *Data, int Length, int64_t Pts);
   void FinishPage(cDvbSubtitlePage *Page);
diff -ruN vdr-1.7.16/epg.c vdr-1.7.17/epg.c
--- vdr-1.7.16/epg.c	2010-02-28 15:24:55.000000000 +0100
+++ vdr-1.7.17/epg.c	2011-02-25 16:16:05.000000000 +0100
@@ -7,7 +7,7 @@
  * Original version (as used in VDR before 1.3.0) written by
  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
  *
- * $Id: epg.c 2.6 2010/02/28 14:24:55 kls Exp $
+ * $Id: epg.c 2.7 2011/02/25 15:16:05 kls Exp $
  */
 
 #include "epg.h"
@@ -56,25 +56,34 @@
   free(components);
 }
 
-void cComponents::Realloc(int Index)
+bool cComponents::Realloc(int Index)
 {
   if (Index >= numComponents) {
-     int n = numComponents;
-     numComponents = Index + 1;
-     components = (tComponent *)realloc(components, numComponents * sizeof(tComponent));
-     memset(&components[n], 0, sizeof(tComponent) * (numComponents - n));
+     Index++;
+     if (tComponent *NewBuffer = (tComponent *)realloc(components, Index * sizeof(tComponent))) {
+        int n = numComponents;
+        numComponents = Index;
+        components = NewBuffer;
+        memset(&components[n], 0, sizeof(tComponent) * (numComponents - n));
+        }
+     else {
+        esyslog("ERROR: out of memory");
+        return false;
+        }
      }
+  return true;
 }
 
 void cComponents::SetComponent(int Index, const char *s)
 {
-  Realloc(Index);
-  components[Index].FromString(s);
+  if (Realloc(Index))
+     components[Index].FromString(s);
 }
 
 void cComponents::SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description)
 {
-  Realloc(Index);
+  if (!Realloc(Index))
+     return;
   tComponent *p = &components[Index];
   p->stream = Stream;
   p->type = Type;
diff -ruN vdr-1.7.16/epg.h vdr-1.7.17/epg.h
--- vdr-1.7.16/epg.h	2010-01-08 16:20:34.000000000 +0100
+++ vdr-1.7.17/epg.h	2011-02-25 15:14:38.000000000 +0100
@@ -7,7 +7,7 @@
  * Original version (as used in VDR before 1.3.0) written by
  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
  *
- * $Id: epg.h 2.4 2010/01/08 15:20:34 kls Exp $
+ * $Id: epg.h 2.5 2011/02/25 14:14:38 kls Exp $
  */
 
 #ifndef __EPG_H
@@ -51,7 +51,7 @@
 private:
   int numComponents;
   tComponent *components;
-  void Realloc(int Index);
+  bool Realloc(int Index);
 public:
   cComponents(void);
   ~cComponents(void);
diff -ruN vdr-1.7.16/font.c vdr-1.7.17/font.c
--- vdr-1.7.16/font.c	2010-09-19 13:49:19.000000000 +0200
+++ vdr-1.7.17/font.c	2011-02-26 13:09:18.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * BiDi support by Osama Alrawab <alrawab@hotmail.com> @2008 Tripoli-Libya.
  *
- * $Id: font.c 2.5 2010/09/19 11:49:19 kls Exp $
+ * $Id: font.c 2.7 2011/02/26 12:09:18 kls Exp $
  */
 
 #include "font.h"
@@ -118,6 +118,7 @@
   virtual int Width(const char *s) const;
   virtual int Height(void) const { return height; }
   virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const;
+  virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const;
   };
 
 cFreetypeFont::cFreetypeFont(const char *Name, int CharHeight, int CharWidth)
@@ -329,6 +330,53 @@
      }
 }
 
+void cFreetypeFont::DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
+{
+  if (s && height) { // checking height to make sure we actually have a valid font
+#ifdef BIDI
+     cString bs = Bidi(s);
+     s = bs;
+#endif
+     bool AntiAliased = Setup.AntiAlias;
+     uint prevSym = 0;
+     while (*s) {
+           int sl = Utf8CharLen(s);
+           uint sym = Utf8CharGet(s, sl);
+           s += sl;
+           cGlyph *g = Glyph(sym, AntiAliased);
+           if (!g)
+              continue;
+           int kerning = Kerning(g, prevSym);
+           prevSym = sym;
+           uchar *buffer = g->Bitmap();
+           int symWidth = g->Width();
+           if (Width && x + symWidth + g->Left() + kerning - 1 > Width)
+              break; // we don't draw partial characters
+           if (x + symWidth + g->Left() + kerning > 0) {
+              for (int row = 0; row < g->Rows(); row++) {
+                  for (int pitch = 0; pitch < g->Pitch(); pitch++) {
+                      uchar bt = *(buffer + (row * g->Pitch() + pitch));
+                      if (AntiAliased) {
+                         if (bt > 0x00)
+                            Pixmap->DrawPixel(cPoint(x + pitch + g->Left() + kerning, y + row + (height - Bottom() - g->Top())), AlphaBlend(ColorFg, ColorBg, bt));
+                         }
+                      else { //monochrome rendering
+                         for (int col = 0; col < 8 && col + pitch * 8 <= symWidth; col++) {
+                             if (bt & 0x80)
+                                Pixmap->DrawPixel(cPoint(x + col + pitch * 8 + g->Left() + kerning, y + row + (height - Bottom() - g->Top())), ColorFg);
+                             bt <<= 1;
+                             }
+                         }
+                      }
+                  }
+              }
+           x += g->AdvanceX() + kerning;
+           if (x > Pixmap->DrawPort().Width() - 1)
+              break;
+           }
+     }
+}
+
 // --- cDummyFont ------------------------------------------------------------
 
 // A dummy font, in case there are no fonts installed:
@@ -339,6 +387,7 @@
   virtual int Width(const char *s) const { return 50; }
   virtual int Height(void) const { return 20; }
   virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}
+  virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {};
   };
 
 // --- cFont -----------------------------------------------------------------
diff -ruN vdr-1.7.16/font.h vdr-1.7.17/font.h
--- vdr-1.7.16/font.h	2010-09-19 13:48:37.000000000 +0200
+++ vdr-1.7.17/font.h	2011-01-14 17:22:03.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: font.h 2.4 2010/09/19 11:48:37 kls Exp $
+ * $Id: font.h 2.5 2011/01/14 16:22:03 kls Exp $
  */
 
 #ifndef __FONT_H
@@ -26,6 +26,7 @@
   };
 
 class cBitmap;
+class cPixmap;
 typedef uint32_t tColor; // see also osd.h
 typedef uint8_t tIndex;
 
@@ -54,6 +55,9 @@
   virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const = 0;
           ///< Draws the given text into the Bitmap at position (x, y) with the given colors.
           ///< The text will not exceed the given Width (if > 0), and will end with a complete character.
+  virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}; // not "pure", so that existing implementations still compile
+          ///< Draws the given text into the Pixmap at position (x, y) with the given colors.
+          ///< The text will not exceed the given Width (if > 0), and will end with a complete character.
   static void SetFont(eDvbFont Font, const char *Name, int CharHeight);
           ///< Sets the given Font to use the font data according to Name (see CreateFont())
           ///< and make its characters CharHeight pixels high.
@@ -81,7 +85,7 @@
           ///< of the actual font file.
           ///< Returns true if any font names were found.
   static cString GetFontFileName(const char *FontName);
-          ///< Retruns the actual font file name for the given FontName.
+          ///< Returns the actual font file name for the given FontName.
 #ifdef BIDI
   static cString Bidi(const char *Ltr);
           ///< Converts any "right-to-left" parts in the "left-to-right" string Ltr
diff -ruN vdr-1.7.16/i18n.c vdr-1.7.17/i18n.c
--- vdr-1.7.16/i18n.c	2010-09-19 13:22:39.000000000 +0200
+++ vdr-1.7.17/i18n.c	2011-02-20 16:56:20.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: i18n.c 2.2 2010/09/19 11:22:39 kls Exp $
+ * $Id: i18n.c 2.3 2011/02/20 15:56:20 kls Exp $
  */
 
 /*
@@ -52,6 +52,7 @@
   "hun",
   "cat,cln",
   "rus",
+  "srb,srp,scr,scc",
   "hrv",
   "est",
   "dan",
diff -ruN vdr-1.7.16/libsi/Makefile vdr-1.7.17/libsi/Makefile
--- vdr-1.7.16/libsi/Makefile	2006-05-26 12:40:19.000000000 +0200
+++ vdr-1.7.17/libsi/Makefile	2010-11-07 14:31:05.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Makefile for a libsi
 #
-# $Id: Makefile 2.0 2006/05/26 10:40:19 kls Exp $
+# $Id: Makefile 2.1 2010/11/07 13:31:05 kls Exp $
 
 ### The C++ compiler and options:
 
@@ -11,6 +11,7 @@
 ARFLAGS = ru
 RANLIB = ranlib
 
+include ../Make.global
 -include ../Make.config
 
 ### The directory environment:
diff -ruN vdr-1.7.16/libsi/descriptor.c vdr-1.7.17/libsi/descriptor.c
--- vdr-1.7.16/libsi/descriptor.c	2007-02-03 12:45:58.000000000 +0100
+++ vdr-1.7.17/libsi/descriptor.c	2010-11-01 16:24:31.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: descriptor.c 2.0 2007/02/03 11:45:58 kls Exp $
+ *   $Id: descriptor.c 2.1 2010/11/01 15:24:31 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -1032,4 +1032,15 @@
    data.setPointerAndOffset<const descr_application_icons_descriptor_end>(s, offset);
 }
 
+int RegistrationDescriptor::getFormatIdentifier() const {
+   return HILOHILO(s->format_identifier);
+}
+
+void RegistrationDescriptor::Parse() {
+   int offset=0;
+   data.setPointerAndOffset<const descr_registration>(s, offset);
+   if (checkSize(getLength()-offset))
+      privateData.assign(data.getData(offset), getLength()-offset);
+}
+
 } //end of namespace
diff -ruN vdr-1.7.16/libsi/descriptor.h vdr-1.7.17/libsi/descriptor.h
--- vdr-1.7.16/libsi/descriptor.h	2007-02-03 12:45:58.000000000 +0100
+++ vdr-1.7.17/libsi/descriptor.h	2010-11-01 16:24:32.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: descriptor.h 2.0 2007/02/03 11:45:58 kls Exp $
+ *   $Id: descriptor.h 2.1 2010/11/01 15:24:32 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -660,6 +660,16 @@
    const descr_application_icons_descriptor_end *s;
 };
 
+class RegistrationDescriptor : public Descriptor {
+public:
+   int getFormatIdentifier() const;
+   CharArray privateData;
+protected:
+   virtual void Parse();
+private:
+   const descr_registration *s;
+};
+
 } //end of namespace
 
 #endif //LIBSI_TABLE_H
diff -ruN vdr-1.7.16/libsi/headers.h vdr-1.7.17/libsi/headers.h
--- vdr-1.7.16/libsi/headers.h	2007-02-03 12:45:58.000000000 +0100
+++ vdr-1.7.17/libsi/headers.h	2010-11-01 16:24:32.000000000 +0100
@@ -10,7 +10,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: headers.h 2.0 2007/02/03 11:45:58 kls Exp $
+ *   $Id: headers.h 2.1 2010/11/01 15:24:32 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -2006,6 +2006,18 @@
    u_char start_time_s                           :8;
 };
 
+/* 0x05 registration_descriptor */
+
+#define DESCR_REGISTRATION_LEN 6
+struct descr_registration {
+   u_char descriptor_tag                         :8;
+   u_char descriptor_length                      :8;
+   u_char format_identifier_hi_hi                :8;
+   u_char format_identifier_hi_lo                :8;
+   u_char format_identifier_lo_hi                :8;
+   u_char format_identifier_lo_lo                :8;
+};
+
 } //end of namespace
 
 #endif //LIBSI_HEADERS_H
diff -ruN vdr-1.7.16/libsi/si.c vdr-1.7.17/libsi/si.c
--- vdr-1.7.16/libsi/si.c	2010-02-13 11:31:52.000000000 +0100
+++ vdr-1.7.17/libsi/si.c	2010-11-01 16:24:32.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: si.c 2.2 2010/02/13 10:31:52 kls Exp $
+ *   $Id: si.c 2.3 2010/11/01 15:24:32 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -606,6 +606,9 @@
          case ExtensionDescriptorTag:
             d=new ExtensionDescriptor();
             break;
+         case RegistrationDescriptorTag:
+            d=new RegistrationDescriptor();
+            break;
 
          //note that it is no problem to implement one
          //of the unimplemented descriptors.
@@ -614,7 +617,6 @@
          case VideoStreamDescriptorTag:
          case AudioStreamDescriptorTag:
          case HierarchyDescriptorTag:
-         case RegistrationDescriptorTag:
          case DataStreamAlignmentDescriptorTag:
          case TargetBackgroundGridDescriptorTag:
          case VideoWindowDescriptorTag:
diff -ruN vdr-1.7.16/libsi/util.h vdr-1.7.17/libsi/util.h
--- vdr-1.7.16/libsi/util.h	2008-05-22 12:49:08.000000000 +0200
+++ vdr-1.7.17/libsi/util.h	2010-11-01 16:24:32.000000000 +0100
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: util.h 2.1 2008/05/22 10:49:08 kls Exp $
+ *   $Id: util.h 2.2 2010/11/01 15:24:32 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -19,6 +19,7 @@
 #include <time.h>
 
 #define HILO(x) (x##_hi << 8 | x##_lo)
+#define HILOHILO(x) (x##_hi_hi << 24 | x##_hi_lo << 16 | x##_lo_hi << 8 | x##_lo_lo)
 #define BCD_TIME_TO_SECONDS(x) ((3600 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \
                              (60 * ((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))) + \
                              ((10*((x##_s & 0xF0)>>4)) + (x##_s & 0xF)))
diff -ruN vdr-1.7.16/lirc.c vdr-1.7.17/lirc.c
--- vdr-1.7.16/lirc.c	2006-05-28 10:48:13.000000000 +0200
+++ vdr-1.7.17/lirc.c	2011-03-08 16:35:13.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * LIRC support added by Carsten Koch <Carsten.Koch@icem.de>  2000-06-16.
  *
- * $Id: lirc.c 2.0 2006/05/28 08:48:13 kls Exp $
+ * $Id: lirc.c 2.1 2011/03/08 15:35:13 kls Exp $
  */
 
 #include "lirc.h"
@@ -86,7 +86,8 @@
                  }
            }
 
-        if (ready && ret > 21) {
+        if (ready && ret > 0) {
+           buf[ret - 1] = 0;
            int count;
            char KeyName[LIRC_KEY_BUF];
            if (sscanf(buf, "%*x %x %29s", &count, KeyName) != 2) { // '29' in '%29s' is LIRC_KEY_BUF-1!
diff -ruN vdr-1.7.16/menu.c vdr-1.7.17/menu.c
--- vdr-1.7.16/menu.c	2010-06-06 11:56:16.000000000 +0200
+++ vdr-1.7.17/menu.c	2011-02-27 13:37:48.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 2.24 2010/06/06 09:56:16 kls Exp $
+ * $Id: menu.c 2.28 2011/02/27 12:37:48 kls Exp $
  */
 
 #include "menu.h"
@@ -606,7 +606,7 @@
 
 eOSState cMenuText::ProcessKey(eKeys Key)
 {
-  switch (Key) {
+  switch (int(Key)) {
     case kUp|k_Repeat:
     case kUp:
     case kDown|k_Repeat:
@@ -1253,7 +1253,7 @@
 
 eOSState cMenuEvent::ProcessKey(eKeys Key)
 {
-  switch (Key) {
+  switch (int(Key)) {
     case kUp|k_Repeat:
     case kUp:
     case kDown|k_Repeat:
@@ -1860,8 +1860,14 @@
               int l = 0;
               int c;
               while ((c = fgetc(p)) != EOF) {
-                    if (l % 20 == 0)
-                       result = (char *)realloc(result, l + 21);
+                    if (l % 20 == 0) {
+                       if (char *NewBuffer = (char *)realloc(result, l + 21))
+                          result = NewBuffer;
+                       else {
+                          esyslog("ERROR: out of memory");
+                          break;
+                          }
+                       }
                     result[l++] = char(c);
                     }
               if (result)
@@ -2116,7 +2122,7 @@
 
 eOSState cMenuRecording::ProcessKey(eKeys Key)
 {
-  switch (Key) {
+  switch (int(Key)) {
     case kUp|k_Repeat:
     case kUp:
     case kDown|k_Repeat:
@@ -2270,7 +2276,7 @@
   for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
       if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == FOLDERDELIMCHAR)) {
          cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level);
-         if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) {
+         if (*Item->Text() && (!Item->IsDirectory() || (!LastItem || !LastItem->IsDirectory() || strcmp(Item->Text(), LastItemText) != 0))) {
             Add(Item);
             LastItem = Item;
             free(LastItemText);
@@ -3614,7 +3620,7 @@
   cChannel *NewChannel = NULL;
   if (Key != kNone)
      lastTime.Set();
-  switch (Key) {
+  switch (int(Key)) {
     case k0:
          if (number == 0) {
             // keep the "Toggle channels" function working
@@ -3818,7 +3824,7 @@
 
 eOSState cDisplayVolume::ProcessKey(eKeys Key)
 {
-  switch (Key) {
+  switch (int(Key)) {
     case kVolUp|k_Repeat:
     case kVolUp:
     case kVolDn|k_Repeat:
@@ -3914,7 +3920,7 @@
 {
   int oldTrack = track;
   int oldAudioChannel = audioChannel;
-  switch (Key) {
+  switch (int(Key)) {
     case kUp|k_Repeat:
     case kUp:
     case kDown|k_Repeat:
@@ -4031,7 +4037,7 @@
 eOSState cDisplaySubtitleTracks::ProcessKey(eKeys Key)
 {
   int oldTrack = track;
-  switch (Key) {
+  switch (int(Key)) {
     case kUp|k_Repeat:
     case kUp:
     case kDown|k_Repeat:
@@ -4736,6 +4742,8 @@
 {
   if (!Active())
      return osEnd;
+  if (Key == kNone)
+     marks.Update();
   if (visible) {
      if (timeoutShow && time(NULL) > timeoutShow) {
         Hide();
@@ -4754,7 +4762,7 @@
      return osContinue;
      }
   bool DoShowMode = true;
-  switch (Key) {
+  switch (int(Key)) {
     // Positioning:
     case kPlay:
     case kUp:      Play(); break;
@@ -4781,7 +4789,7 @@
                    return osEnd;
     default: {
       DoShowMode = false;
-      switch (Key) {
+      switch (int(Key)) {
         // Editing:
         case kMarkToggle:      MarkToggle(); break;
         case kPrev|k_Repeat:
diff -ruN vdr-1.7.16/menuitems.c vdr-1.7.17/menuitems.c
--- vdr-1.7.16/menuitems.c	2010-06-06 12:37:08.000000000 +0200
+++ vdr-1.7.17/menuitems.c	2010-12-12 14:41:09.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menuitems.c 2.7 2010/06/06 10:37:08 kls Exp $
+ * $Id: menuitems.c 2.8 2010/12/12 13:41:09 kls Exp $
  */
 
 #include "menuitems.h"
@@ -527,7 +527,7 @@
      Set();
      return osContinue;
      }
-  switch (Key) {
+  switch (int(Key)) {
     case kRed:   // Switch between upper- and lowercase characters
                  if (InEditMode()) {
                     if (!insert || !newchar) {
@@ -733,7 +733,7 @@
 {
   int delta = 1;
 
-  switch (Key) {
+  switch (int(Key)) {
     case kLeft|k_Repeat:
     case kLeft:  delta = -1;
     case kRight|k_Repeat:
diff -ruN vdr-1.7.16/newplugin vdr-1.7.17/newplugin
--- vdr-1.7.16/newplugin	2010-02-06 15:50:03.000000000 +0100
+++ vdr-1.7.17/newplugin	2011-02-27 11:06:06.000000000 +0100
@@ -12,7 +12,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: newplugin 2.2 2010/02/06 14:50:03 kls Exp $
+# $Id: newplugin 2.6 2011/02/27 10:06:06 kls Exp $
 
 $PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin <name>\n";
 
@@ -77,7 +77,7 @@
 ### The C++ compiler and options:
 
 CXX      ?= g++
-CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
 
 ### The directory environment:
 
@@ -142,7 +142,7 @@
 	msgfmt -c -o \$\@ \$<
 
 \$(I18Npot): \$(wildcard *.c)
-	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<see README>' -o \$\@ \$^
+	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-\$(PLUGIN) --package-version=\$(VERSION) --msgid-bugs-address='<see README>' -o \$\@ \$^
 
 %.po: \$(I18Npot)
 	msgmerge -U --no-wrap --no-location --backup=none -q \$\@ \$<
@@ -158,10 +158,10 @@
 ### Targets:
 
 libvdr-\$(PLUGIN).so: \$(OBJS)
-	\$(CXX) \$(CXXFLAGS) -shared \$(OBJS) -o \$\@
+	\$(CXX) \$(CXXFLAGS) \$(LDFLAGS) -shared \$(OBJS) -o \$\@
 	\@cp --remove-destination \$\@ \$(LIBDIR)/\$\@.\$(APIVERSION)
 
-dist: clean
+dist: \$(I18Npo) clean
 	\@-rm -rf \$(TMPDIR)/\$(ARCHIVE)
 	\@mkdir \$(TMPDIR)/\$(ARCHIVE)
 	\@cp -a * \$(TMPDIR)/\$(ARCHIVE)
diff -ruN vdr-1.7.16/osd.c vdr-1.7.17/osd.c
--- vdr-1.7.16/osd.c	2010-05-02 15:56:53.000000000 +0200
+++ vdr-1.7.17/osd.c	2011-03-12 16:32:33.000000000 +0100
@@ -4,12 +4,11 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osd.c 2.10 2010/05/02 13:56:53 kls Exp $
+ * $Id: osd.c 2.17 2011/03/12 15:32:33 kls Exp $
  */
 
 #include "osd.h"
 #include <math.h>
-#include <stdarg.h>
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
@@ -17,6 +16,92 @@
 #include "device.h"
 #include "tools.h"
 
+tColor HsvToColor(double H, double S, double V)
+{
+  if (S > 0) {
+     H /= 60;
+     int i = floor(H);
+     double f = H - i;
+     double p = V * (1 - S);
+     double q = V * (1 - S * f);
+     double t = V * (1 - S * (1 - f));
+     switch (i) {
+       case 0:  return RgbToColor(V, t, p);
+       case 1:  return RgbToColor(q, V, p);
+       case 2:  return RgbToColor(p, V, t);
+       case 3:  return RgbToColor(p, q, V);
+       case 4:  return RgbToColor(t, p, V);
+       default: return RgbToColor(V, p, q);
+       }
+     }
+  else { // greyscale
+     uint8_t n = V * 0xFF;
+     return RgbToColor(n, n, n);
+     }
+}
+
+#define USE_ALPHA_LUT
+#ifdef USE_ALPHA_LUT
+// Alpha blending with lookup table (by Reinhard Nissl <rnissl@gmx.de>)
+// A little slower (138 %) on fast machines than the implementation below and faster
+// on slow machines (79 %), but requires some 318KB of RAM for the lookup table.
+static uint16_t AlphaLutFactors[255][256][2];
+static uint8_t AlphaLutAlpha[255][256];
+
+class cInitAlphaLut {
+public:
+  cInitAlphaLut(void)
+  {
+    for (int alphaA = 0; alphaA < 255; alphaA++) {
+        int range = (alphaA == 255 ? 255 : 254);
+        for (int alphaB = 0; alphaB < 256; alphaB++) {
+            int alphaO_x_range = 255 * alphaA + alphaB * (range - alphaA);
+            if (!alphaO_x_range)
+               alphaO_x_range++;
+            int factorA = (256 * 255 * alphaA + alphaO_x_range / 2) / alphaO_x_range;
+            int factorB = (256 * alphaB * (range - alphaA) + alphaO_x_range / 2) / alphaO_x_range;
+            AlphaLutFactors[alphaA][alphaB][0] = factorA;
+            AlphaLutFactors[alphaA][alphaB][1] = factorB;
+            AlphaLutAlpha[alphaA][alphaB] = alphaO_x_range / range;
+            }
+        }
+  }
+  } InitAlphaLut;
+
+tColor AlphaBlend(tColor ColorFg, tColor ColorBg, uint8_t AlphaLayer)
+{
+  tColor Alpha = (ColorFg & 0xFF000000) >> 24;
+  Alpha *= AlphaLayer;
+  Alpha >>= 8;
+  uint16_t *lut = &AlphaLutFactors[Alpha][(ColorBg & 0xFF000000) >> 24][0];
+  return (tColor)((AlphaLutAlpha[Alpha][(ColorBg & 0xFF000000) >> 24] << 24)
+    | (((((ColorFg & 0x00FF00FF) * lut[0] + (ColorBg & 0x00FF00FF) * lut[1])) & 0xFF00FF00)
+    |  ((((ColorFg & 0x0000FF00) * lut[0] + (ColorBg & 0x0000FF00) * lut[1])) & 0x00FF0000)) >> 8);
+}
+#else
+// Alpha blending without lookup table.
+// Also works fast, but doesn't return the theoretically correct result.
+// It's "good enough", though.
+static tColor Multiply(tColor Color, uint8_t Alpha)
+{
+  tColor RB = (Color & 0x00FF00FF) * Alpha;
+  RB = ((RB + ((RB >> 8) & 0x00FF00FF) + 0x00800080) >> 8) & 0x00FF00FF;
+  tColor AG = ((Color >> 8) & 0x00FF00FF) * Alpha;
+  AG = ((AG + ((AG >> 8) & 0x00FF00FF) + 0x00800080)) & 0xFF00FF00;
+  return AG | RB;
+}
+
+tColor AlphaBlend(tColor ColorFg, tColor ColorBg, uint8_t AlphaLayer)
+{
+  tColor Alpha = (ColorFg & 0xFF000000) >> 24;
+  if (AlphaLayer < ALPHA_OPAQUE) {
+     Alpha *= AlphaLayer;
+     Alpha = ((Alpha + ((Alpha >> 8) & 0x000000FF) + 0x00000080) >> 8) & 0x000000FF;
+     }
+  return Multiply(ColorFg, Alpha) + Multiply(ColorBg, 255 - Alpha);
+}
+#endif
+
 // --- cPalette --------------------------------------------------------------
 
 cPalette::cPalette(int Bpp)
@@ -613,8 +698,6 @@
 
 void cBitmap::DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type)
 {
-  // TODO This is just a quick and dirty implementation of a slope drawing
-  // machanism. If somebody can come up with a better solution, let's have it!
   if (!Intersects(x1, y1, x2, y2))
      return;
   bool upper    = Type & 0x01;
@@ -724,6 +807,756 @@
      }
 }
 
+cBitmap *cBitmap::Scale(double FactorX, double FactorY)
+{
+  // Fixed point scaling code based on www.inversereality.org/files/bitmapscaling.pdf
+  // by deltener@mindtremors.com
+  cBitmap *b = new cBitmap(int(round(Width() * FactorX)), int(round(Height() * FactorY)), Bpp(), X0(), Y0());
+  b->Replace(*this); // copy palette
+  int RatioX = (Width() << 16) / b->Width();
+  int RatioY = (Height() << 16) / b->Height();
+  tIndex *DestRow = b->bitmap;
+  int SourceY = 0;
+  for (int y = 0; y < b->Height(); y++) {
+      int SourceX = 0;
+      tIndex *SourceRow = bitmap + (SourceY >> 16) * Width();
+      tIndex *Dest = DestRow;
+      for (int x = 0; x < b->Width(); x++) {
+          *Dest++ = SourceRow[SourceX >> 16];
+          SourceX += RatioX;
+          }
+      SourceY += RatioY;
+      DestRow += b->Width();
+      }
+  return b;
+}
+
+// --- cRect -----------------------------------------------------------------
+
+const cRect cRect::Null;
+
+void cRect::Grow(int Dx, int Dy)
+{
+  point.Shift(-Dx, -Dy);
+  size.Grow(Dx, Dy);
+}
+
+bool cRect::Contains(const cPoint &Point) const
+{
+  return Left() <= Point.X() &&
+         Top() <= Point.Y() &&
+         Right() >= Point.X() &&
+         Bottom() >= Point.Y();
+}
+
+bool cRect::Contains(const cRect &Rect) const
+{
+  return Left() <= Rect.Left() &&
+         Top() <= Rect.Top() &&
+         Right() >= Rect.Right() &&
+         Bottom() >= Rect.Bottom();
+}
+
+bool cRect::Intersects(const cRect &Rect) const
+{
+  return !(Left() > Rect.Right() ||
+           Top() > Rect.Bottom() ||
+           Right() < Rect.Left() ||
+           Bottom() < Rect.Top());
+}
+
+cRect cRect::Intersected(const cRect &Rect) const
+{
+  cRect r;
+  if (!IsEmpty() && !Rect.IsEmpty()) {
+     r.SetLeft(max(Left(), Rect.Left()));
+     r.SetTop(max(Top(), Rect.Top()));
+     r.SetRight(min(Right(), Rect.Right()));
+     r.SetBottom(min(Bottom(), Rect.Bottom()));
+     }
+  return r;
+}
+
+void cRect::Combine(const cRect &Rect)
+{
+  if (IsEmpty())
+     *this = Rect;
+  if (Rect.IsEmpty())
+     return;
+  // must set right/bottom *before* top/left!
+  SetRight(max(Right(), Rect.Right()));
+  SetBottom(max(Bottom(), Rect.Bottom()));
+  SetLeft(min(Left(), Rect.Left()));
+  SetTop(min(Top(), Rect.Top()));
+}
+
+void cRect::Combine(const cPoint &Point)
+{
+  if (IsEmpty())
+     Set(Point.X(), Point.Y(), 1, 1);
+  // must set right/bottom *before* top/left!
+  SetRight(max(Right(), Point.X()));
+  SetBottom(max(Bottom(), Point.Y()));
+  SetLeft(min(Left(), Point.X()));
+  SetTop(min(Top(), Point.Y()));
+}
+
+// --- cPixmap ---------------------------------------------------------------
+
+cMutex cPixmap::mutex;
+
+cPixmap::cPixmap(void)
+{
+  layer = -1;
+  alpha = ALPHA_OPAQUE;
+  tile = false;
+}
+
+cPixmap::cPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort)
+{
+  layer = Layer;
+  if (layer >= MAXPIXMAPLAYERS) {
+     layer = MAXPIXMAPLAYERS - 1;
+     esyslog("ERROR: pixmap layer %d limited to %d", Layer, layer);
+     }
+  viewPort = ViewPort;
+  if (!DrawPort.IsEmpty())
+     drawPort = DrawPort;
+  else {
+     drawPort = viewPort;
+     drawPort.SetPoint(0, 0);
+     }
+  alpha = ALPHA_OPAQUE;
+  tile = false;
+}
+
+void cPixmap::MarkViewPortDirty(const cRect &Rect)
+{
+  dirtyViewPort.Combine(Rect.Intersected(viewPort));
+}
+
+void cPixmap::MarkViewPortDirty(const cPoint &Point)
+{
+  if (viewPort.Contains(Point))
+     dirtyViewPort.Combine(Point);
+}
+
+void cPixmap::MarkDrawPortDirty(const cRect &Rect)
+{
+  dirtyDrawPort.Combine(Rect.Intersected(drawPort));
+  if (tile)
+     MarkViewPortDirty(viewPort);
+  else
+     MarkViewPortDirty(Rect.Shifted(viewPort.Point()));
+}
+
+void cPixmap::MarkDrawPortDirty(const cPoint &Point)
+{
+  if (drawPort.Contains(Point)) {
+     dirtyDrawPort.Combine(Point);
+     if (tile)
+        MarkViewPortDirty(viewPort);
+     else
+        MarkViewPortDirty(Point.Shifted(viewPort.Point()));
+     }
+}
+
+void cPixmap::SetClean(void)
+{
+  dirtyViewPort = dirtyDrawPort = cRect();
+}
+
+void cPixmap::SetLayer(int Layer)
+{
+  Lock();
+  if (Layer >= MAXPIXMAPLAYERS) {
+     esyslog("ERROR: pixmap layer %d limited to %d", Layer, MAXPIXMAPLAYERS - 1);
+     Layer = MAXPIXMAPLAYERS - 1;
+     }
+  if (Layer != layer) {
+     if (Layer > 0 || layer > 0)
+        MarkViewPortDirty(viewPort);
+     layer = Layer;
+     }
+  Unlock();
+}
+
+void cPixmap::SetAlpha(int Alpha)
+{
+  Lock();
+  Alpha = min(max(Alpha, ALPHA_TRANSPARENT), ALPHA_OPAQUE);
+  if (Alpha != alpha) {
+     MarkViewPortDirty(viewPort);
+     alpha = Alpha;
+     }
+  Unlock();
+}
+
+void cPixmap::SetTile(bool Tile)
+{
+  Lock();
+  if (Tile != tile) {
+     if (drawPort.Point() != cPoint(0, 0) || drawPort.Width() < viewPort.Width() || drawPort.Height() < viewPort.Height())
+        MarkViewPortDirty(viewPort);
+     tile = Tile;
+     }
+  Unlock();
+}
+
+void cPixmap::SetViewPort(const cRect &Rect)
+{
+  Lock();
+  if (Rect != viewPort) {
+     if (tile)
+        MarkViewPortDirty(viewPort);
+     else
+        MarkViewPortDirty(drawPort.Shifted(viewPort.Point()));
+     viewPort = Rect;
+     if (tile)
+        MarkViewPortDirty(viewPort);
+     else
+        MarkViewPortDirty(drawPort.Shifted(viewPort.Point()));
+     }
+  Unlock();
+}
+
+void cPixmap::SetDrawPortPoint(const cPoint &Point, bool Dirty)
+{
+  Lock();
+  if (Point != drawPort.Point()) {
+     if (Dirty) {
+        if (tile)
+           MarkViewPortDirty(viewPort);
+        else
+           MarkViewPortDirty(drawPort.Shifted(viewPort.Point()));
+        }
+     drawPort.SetPoint(Point);
+     if (Dirty && !tile)
+        MarkViewPortDirty(drawPort.Shifted(viewPort.Point()));
+     }
+  Unlock();
+}
+
+// --- cImage ----------------------------------------------------------------
+
+cImage::cImage(void)
+{
+  data = NULL;
+}
+
+cImage::cImage(const cImage &Image)
+{
+  size = Image.Size();
+  int l = size.Width() * size.Height() * sizeof(tColor);
+  data = MALLOC(tColor, l);
+  memcpy(data, Image.Data(), l);
+}
+
+cImage::cImage(const cSize &Size, const tColor *Data)
+{
+  size = Size;
+  int l = size.Width() * size.Height() * sizeof(tColor);
+  data = MALLOC(tColor, l);
+  if (Data)
+     memcpy(data, Data, l);
+}
+
+cImage::~cImage()
+{
+  free(data);
+}
+
+void cImage::Clear(void)
+{
+  memset(data, 0x00, Width() * Height() * sizeof(tColor));
+}
+
+void cImage::Fill(tColor Color)
+{
+  for (int i = Width() * Height() - 1; i >= 0; i--)
+      data[i] = Color;
+}
+
+// --- cPixmapMemory ---------------------------------------------------------
+
+cPixmapMemory::cPixmapMemory(void)
+{
+  data = NULL;
+  panning = false;
+}
+
+cPixmapMemory::cPixmapMemory(int Layer, const cRect &ViewPort, const cRect &DrawPort)
+:cPixmap(Layer, ViewPort, DrawPort)
+{
+  data = MALLOC(tColor, this->DrawPort().Width() * this->DrawPort().Height());
+}
+
+cPixmapMemory::~cPixmapMemory()
+{
+  free(data);
+}
+
+void cPixmapMemory::Clear(void)
+{
+  Lock();
+  memset(data, 0x00, DrawPort().Width() * DrawPort().Height() * sizeof(tColor));
+  MarkDrawPortDirty(DrawPort());
+  Unlock();
+}
+
+void cPixmapMemory::Fill(tColor Color)
+{
+  Lock();
+  for (int i = DrawPort().Width() * DrawPort().Height() - 1; i >= 0; i--)
+      data[i] = Color;
+  MarkDrawPortDirty(DrawPort());
+  Unlock();
+}
+
+void cPixmap::DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty)
+{
+  if (Pixmap->Tile() && (Pixmap->DrawPort().Point() != cPoint(0, 0) || Pixmap->DrawPort().Size() < Pixmap->ViewPort().Size())) {
+     cPoint t0 = Pixmap->DrawPort().Point().Shifted(Pixmap->ViewPort().Point()); // the origin of the draw port in absolute OSD coordinates
+     // Find the top/leftmost location where the draw port touches the view port:
+     while (t0.X() > Pixmap->ViewPort().Left())
+           t0.Shift(-Pixmap->DrawPort().Width(), 0);
+     while (t0.Y() > Pixmap->ViewPort().Top())
+           t0.Shift(0, -Pixmap->DrawPort().Height());
+     cPoint t = t0;;
+     while (t.Y() <= Pixmap->ViewPort().Bottom()) {
+           while (t.X() <= Pixmap->ViewPort().Right()) {
+                 cRect Source = Pixmap->DrawPort(); // assume the entire pixmap needs to be rendered
+                 Source.Shift(Pixmap->ViewPort().Point()); // Source is now in absolute OSD coordinates
+                 cPoint Delta = Source.Point() - t;
+                 Source.SetPoint(t); // Source is now where the pixmap's data shall be drawn
+                 Source = Source.Intersected(Pixmap->ViewPort()); // Source is now limited to the pixmap's view port
+                 Source = Source.Intersected(Dirty); // Source is now limited to the actual dirty rectangle
+                 if (!Source.IsEmpty()) {
+                    cPoint Dest = Source.Point().Shifted(-ViewPort().Point()); // remember the destination point
+                    Source.Shift(Delta); // Source is now back at the pixmap's draw port location, still in absolute OSD coordinates
+                    Source.Shift(-Pixmap->ViewPort().Point()); // Source is now relative to the pixmap's view port again
+                    Source.Shift(-Pixmap->DrawPort().Point()); // Source is now relative to the pixmap's data
+                    if (Pixmap->Layer() == 0)
+                       Copy(Pixmap, Source, Dest); // this is the "background" pixmap
+                    else
+                       Render(Pixmap, Source, Dest); // all others are alpha blended over the background
+                    }
+                 t.Shift(Pixmap->DrawPort().Width(), 0); // increase one draw port width to the right
+                 }
+           t.SetX(t0.X()); // go back to the leftmost position
+           t.Shift(0, Pixmap->DrawPort().Height()); // increase one draw port height down
+           }
+     }
+  else {
+     cRect Source = Pixmap->DrawPort(); // assume the entire pixmap needs to be rendered
+     Source.Shift(Pixmap->ViewPort().Point()); // Source is now in absolute OSD coordinates
+     Source = Source.Intersected(Pixmap->ViewPort()); // Source is now limited to the pixmap's view port
+     Source = Source.Intersected(Dirty); // Source is now limited to the actual dirty rectangle
+     if (!Source.IsEmpty()) {
+        cPoint Dest = Source.Point().Shifted(-ViewPort().Point()); // remember the destination point
+        Source.Shift(-Pixmap->ViewPort().Point()); // Source is now relative to the pixmap's draw port again
+        Source.Shift(-Pixmap->DrawPort().Point()); // Source is now relative to the pixmap's data
+        if (Pixmap->Layer() == 0)
+           Copy(Pixmap, Source, Dest); // this is the "background" pixmap
+        else
+           Render(Pixmap, Source, Dest); // all others are alpha blended over the background
+        }
+     }
+}
+
+void cPixmapMemory::DrawImage(const cPoint &Point, const cImage &Image)
+{
+  Lock();
+  cRect r = cRect(Point, Image.Size()).Intersected(DrawPort().Size());
+  if (!r.IsEmpty()) {
+     int ws = Image.Size().Width();
+     int wd = DrawPort().Width();
+     int w = r.Width() * sizeof(tColor);
+     const tColor *ps = Image.Data();
+     if (Point.Y() < 0)
+        ps -= Point.Y() * ws;
+     if (Point.X() < 0)
+        ps -= Point.X();
+     tColor *pd = data + wd * r.Top() + r.Left();
+     for (int y = r.Height(); y-- > 0; ) {
+         memcpy(pd, ps, w);
+         ps += ws;
+         pd += wd;
+         }
+     MarkDrawPortDirty(r);
+     }
+  Unlock();
+}
+
+void cPixmapMemory::DrawImage(const cPoint &Point, int ImageHandle)
+{
+  Lock();
+  if (const cImage *Image = cOsdProvider::GetImageData(ImageHandle))
+     DrawImage(Point, *Image);
+  Unlock();
+}
+
+void cPixmapMemory::DrawPixel(const cPoint &Point, tColor Color)
+{
+  Lock();
+  if (DrawPort().Size().Contains(Point)) {
+     int p = Point.Y() * DrawPort().Width() + Point.X();
+     if (Layer() == 0 && !IS_OPAQUE(Color))
+        data[p] = AlphaBlend(Color, data[p]);
+     else
+        data[p] = Color;
+     MarkDrawPortDirty(Point);
+     }
+  Unlock();
+}
+
+void cPixmapMemory::DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool Overlay)
+{
+  Lock();
+  cRect r = cRect(Point, cSize(Bitmap.Width(), Bitmap.Height())).Intersected(DrawPort().Size());
+  if (!r.IsEmpty()) {
+     bool UseColors = ColorFg || ColorBg;
+     int wd = DrawPort().Width();
+     tColor *pd = data + wd * r.Top() + r.Left();
+     for (int y = r.Top(); y <= r.Bottom(); y++) {
+         tColor *cd = pd;
+         for (int x = r.Left(); x <= r.Right(); x++) {
+             tIndex Index = *Bitmap.Data(x - Point.X(), y - Point.Y());
+             if (Index || !Overlay) {
+                if (UseColors)
+                   *cd = Index ? ColorFg : ColorBg;
+                else
+                   *cd = Bitmap.Color(Index);
+                }
+             cd++;
+             }
+         pd += wd;
+         }
+     MarkDrawPortDirty(r);
+     }
+  Unlock();
+}
+
+void cPixmapMemory::DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment)
+{
+  Lock();
+  int x = Point.X();
+  int y = Point.Y();
+  int w = Font->Width(s);
+  int h = Font->Height();
+  int limit = 0;
+  int cw = Width ? Width : w;
+  int ch = Height ? Height : h;
+  cRect r(x, y, cw, ch);
+  if (ColorBg != clrTransparent)
+     DrawRectangle(r, ColorBg);
+  if (Width || Height) {
+     limit = x + cw;
+     if (Width) {
+        if ((Alignment & taLeft) != 0)
+           ;
+        else if ((Alignment & taRight) != 0) {
+           if (w < Width)
+              x += Width - w;
+           }
+        else { // taCentered
+           if (w < Width)
+              x += (Width - w) / 2;
+           }
+        }
+     if (Height) {
+        if ((Alignment & taTop) != 0)
+           ;
+        else if ((Alignment & taBottom) != 0) {
+           if (h < Height)
+              y += Height - h;
+           }
+        else { // taCentered
+           if (h < Height)
+              y += (Height - h) / 2;
+           }
+        }
+     }
+  Font->DrawText(this, x, y, s, ColorFg, ColorBg, limit);
+  MarkDrawPortDirty(r);
+  Unlock();
+}
+
+void cPixmapMemory::DrawRectangle(const cRect &Rect, tColor Color)
+{
+  Lock();
+  cRect r = Rect.Intersected(DrawPort().Size());
+  if (!r.IsEmpty()) {
+     int wd = DrawPort().Width();
+     int w = r.Width() * sizeof(tColor);
+     tColor *ps = NULL;
+     tColor *pd = data + wd * r.Top() + r.Left();
+     for (int y = r.Height(); y-- > 0; ) {
+         if (ps)
+            memcpy(pd, ps, w); // all other lines are copied fast from the first one
+         else {
+            // explicitly fill the first line:
+            tColor *cd = ps = pd;
+            for (int x = r.Width(); x-- > 0; ) {
+                *cd = Color;
+                cd++;
+                }
+            }
+         pd += wd;
+         }
+     MarkDrawPortDirty(r);
+     }
+  Unlock();
+}
+
+void cPixmapMemory::DrawEllipse(const cRect &Rect, tColor Color, int Quadrants)
+{
+//TODO use anti-aliasing?
+//TODO fix alignment
+  Lock();
+  // Algorithm based on http://homepage.smc.edu/kennedy_john/BELIPSE.PDF
+  int x1 = Rect.Left();
+  int y1 = Rect.Top();
+  int x2 = Rect.Right();
+  int y2 = Rect.Bottom();
+  int rx = x2 - x1;
+  int ry = y2 - y1;
+  int cx = (x1 + x2) / 2;
+  int cy = (y1 + y2) / 2;
+  switch (abs(Quadrants)) {
+    case 0: rx /= 2; ry /= 2; break;
+    case 1: cx = x1; cy = y2; break;
+    case 2: cx = x2; cy = y2; break;
+    case 3: cx = x2; cy = y1; break;
+    case 4: cx = x1; cy = y1; break;
+    case 5: cx = x1;          ry /= 2; break;
+    case 6:          cy = y2; rx /= 2; break;
+    case 7: cx = x2;          ry /= 2; break;
+    case 8:          cy = y1; rx /= 2; break;
+    default: ;
+    }
+  int TwoASquare = 2 * rx * rx;
+  int TwoBSquare = 2 * ry * ry;
+  int x = rx;
+  int y = 0;
+  int XChange = ry * ry * (1 - 2 * rx);
+  int YChange = rx * rx;
+  int EllipseError = 0;
+  int StoppingX = TwoBSquare * rx;
+  int StoppingY = 0;
+  while (StoppingX >= StoppingY) {
+        switch (Quadrants) {
+          case  5: DrawRectangle(cRect(cx,     cy + y, x + 1, 1), Color); // no break
+          case  1: DrawRectangle(cRect(cx,     cy - y, x + 1, 1), Color); break;
+          case  7: DrawRectangle(cRect(cx - x, cy + y, x + 1, 1), Color); // no break
+          case  2: DrawRectangle(cRect(cx - x, cy - y, x + 1, 1), Color); break;
+          case  3: DrawRectangle(cRect(cx - x, cy + y, x + 1, 1), Color); break;
+          case  4: DrawRectangle(cRect(cx,     cy + y, x + 1, 1), Color); break;
+          case  0:
+          case  6: DrawRectangle(cRect(cx - x, cy - y, 2 * x + 1,       1), Color); if (Quadrants == 6) break;
+          case  8: DrawRectangle(cRect(cx - x, cy + y, 2 * x + 1,       1), Color); break;
+          case -1: DrawRectangle(cRect(cx + x, cy - y, x2 - x + 1,      1), Color); break;
+          case -2: DrawRectangle(cRect(x1,     cy - y, cx - x - x1 + 1, 1), Color); break;
+          case -3: DrawRectangle(cRect(x1,     cy + y, cx - x - x1 + 1, 1), Color); break;
+          case -4: DrawRectangle(cRect(cx + x, cy + y, x2 - x + 1,      1), Color); break;
+          default: ;
+          }
+        y++;
+        StoppingY += TwoASquare;
+        EllipseError += YChange;
+        YChange += TwoASquare;
+        if (2 * EllipseError + XChange > 0) {
+           x--;
+           StoppingX -= TwoBSquare;
+           EllipseError += XChange;
+           XChange += TwoBSquare;
+           }
+        }
+  x = 0;
+  y = ry;
+  XChange = ry * ry;
+  YChange = rx * rx * (1 - 2 * ry);
+  EllipseError = 0;
+  StoppingX = 0;
+  StoppingY = TwoASquare * ry;
+  while (StoppingX <= StoppingY) {
+        switch (Quadrants) {
+          case  5: DrawRectangle(cRect(cx,     cy + y, x + 1, 1), Color); // no break
+          case  1: DrawRectangle(cRect(cx,     cy - y, x + 1, 1), Color); break;
+          case  7: DrawRectangle(cRect(cx - x, cy + y, x + 1, 1), Color); // no break
+          case  2: DrawRectangle(cRect(cx - x, cy - y, x + 1, 1), Color); break;
+          case  3: DrawRectangle(cRect(cx - x, cy + y, x + 1, 1), Color); break;
+          case  4: DrawRectangle(cRect(cx,     cy + y, x + 1, 1), Color); break;
+          case  0:
+          case  6: DrawRectangle(cRect(cx - x, cy - y, 2 * x + 1,       1), Color); if (Quadrants == 6) break;
+          case  8: DrawRectangle(cRect(cx - x, cy + y, 2 * x + 1,       1), Color); break;
+          case -1: DrawRectangle(cRect(cx + x, cy - y, x2 - x + 1,      1), Color); break;
+          case -2: DrawRectangle(cRect(x1,     cy - y, cx - x - x1 + 1, 1), Color); break;
+          case -3: DrawRectangle(cRect(x1,     cy + y, cx - x - x1 + 1, 1), Color); break;
+          case -4: DrawRectangle(cRect(cx + x, cy + y, x2 - x + 1,      1), Color); break;
+          }
+        x++;
+        StoppingX += TwoBSquare;
+        EllipseError += XChange;
+        XChange += TwoBSquare;
+        if (2 * EllipseError + YChange > 0) {
+           y--;
+           StoppingY -= TwoASquare;
+           EllipseError += YChange;
+           YChange += TwoASquare;
+           }
+        }
+  MarkDrawPortDirty(Rect);
+  Unlock();
+}
+
+void cPixmapMemory::DrawSlope(const cRect &Rect, tColor Color, int Type)
+{
+  //TODO anti-aliasing?
+  //TODO also simplify cBitmap::DrawSlope()
+  Lock();
+  bool upper    = Type & 0x01;
+  bool falling  = Type & 0x02;
+  bool vertical = Type & 0x04;
+  int x1 = Rect.Left();
+  int y1 = Rect.Top();
+  int x2 = Rect.Right();
+  int y2 = Rect.Bottom();
+  int w  = Rect.Width();
+  int h  = Rect.Height();
+  if (vertical) {
+     for (int y = y1; y <= y2; y++) {
+         double c = cos((y - y1) * M_PI / h);
+         if (falling)
+            c = -c;
+         int x = (x1 + x2) / 2 + int(w * c / 2);
+         if (upper && !falling || !upper && falling)
+            DrawRectangle(cRect(x1, y, x - x1 + 1, 1), Color);
+         else
+            DrawRectangle(cRect(x, y, x2 - x + 1, 1), Color);
+         }
+     }
+  else {
+     for (int x = x1; x <= x2; x++) {
+         double c = cos((x - x1) * M_PI / w);
+         if (falling)
+            c = -c;
+         int y = (y1 + y2) / 2 + int(h * c / 2);
+         if (upper)
+            DrawRectangle(cRect(x, y1, 1, y - y1 + 1), Color);
+         else
+            DrawRectangle(cRect(x, y, 1, y2 - y + 1), Color);
+         }
+     }
+  MarkDrawPortDirty(Rect);
+  Unlock();
+}
+
+void cPixmapMemory::Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest)
+{
+  Lock();
+  if (Pixmap->Alpha() != ALPHA_TRANSPARENT) {
+     if (const cPixmapMemory *pm = dynamic_cast<const cPixmapMemory *>(Pixmap)) {
+        cRect s = Source.Intersected(Pixmap->DrawPort().Size());
+        if (!s.IsEmpty()) {
+           cPoint v = Dest - Source.Point();
+           cRect d = s.Shifted(v).Intersected(DrawPort().Size());
+           if (!d.IsEmpty()) {
+              s = d.Shifted(-v);
+              int a = pm->Alpha();
+              int ws = pm->DrawPort().Width();
+              int wd = DrawPort().Width();
+              const tColor *ps = pm->data + ws * s.Top() + s.Left();
+              tColor *pd = data + wd * d.Top() + d.Left();
+              for (int y = d.Height(); y-- > 0; ) {
+                  const tColor *cs = ps;
+                  tColor *cd = pd;
+                  for (int x = d.Width(); x-- > 0; ) {
+                      *cd = AlphaBlend(*cs, *cd, a);
+                      cs++;
+                      cd++;
+                      }
+                  ps += ws;
+                  pd += wd;
+                  }
+              MarkDrawPortDirty(d);
+              }
+           }
+        }
+     }
+  Unlock();
+}
+
+void cPixmapMemory::Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest)
+{
+  Lock();
+  if (const cPixmapMemory *pm = dynamic_cast<const cPixmapMemory *>(Pixmap)) {
+     cRect s = Source.Intersected(pm->DrawPort().Size());
+     if (!s.IsEmpty()) {
+        cPoint v = Dest - Source.Point();
+        cRect d = s.Shifted(v).Intersected(DrawPort().Size());
+        if (!d.IsEmpty()) {
+           s = d.Shifted(-v);
+           int ws = pm->DrawPort().Width();
+           int wd = DrawPort().Width();
+           int w = d.Width() * sizeof(tColor);
+           const tColor *ps = pm->data + ws * s.Top() + s.Left();
+           tColor *pd = data + wd * d.Top() + d.Left();
+           for (int y = d.Height(); y-- > 0; ) {
+               memcpy(pd, ps, w);
+               ps += ws;
+               pd += wd;
+               }
+           MarkDrawPortDirty(d);
+           }
+        }
+     }
+  Unlock();
+}
+
+void cPixmapMemory::Scroll(const cPoint &Dest, const cRect &Source)
+{
+  Lock();
+  cRect s;
+  if (&Source == &cRect::Null)
+     s = DrawPort().Shifted(-DrawPort().Point());
+  else
+     s = Source.Intersected(DrawPort().Size());
+  if (!s.IsEmpty()) {
+     cPoint v = Dest - Source.Point();
+     cRect d = s.Shifted(v).Intersected(DrawPort().Size());
+     if (!d.IsEmpty()) {
+        s = d.Shifted(-v);
+        if (d.Point() != s.Point()) {
+           int ws = DrawPort().Width();
+           int wd = ws;
+           int w = d.Width() * sizeof(tColor);
+           const tColor *ps = data + ws * s.Top() + s.Left();
+           tColor *pd = data + wd * d.Top() + d.Left();
+           for (int y = d.Height(); y-- > 0; ) {
+               memmove(pd, ps, w); // source and destination might overlap!
+               ps += ws;
+               pd += wd;
+               }
+           if (panning)
+              SetDrawPortPoint(DrawPort().Point().Shifted(s.Point() - d.Point()), false);
+           else
+              MarkDrawPortDirty(d);
+           }
+        }
+     }
+  Unlock();
+}
+
+void cPixmapMemory::Pan(const cPoint &Dest, const cRect &Source)
+{
+  Lock();
+  panning = true;
+  Scroll(Dest, Source);
+  panning = false;
+  Unlock();
+}
+
 // --- cOsd ------------------------------------------------------------------
 
 static const char *OsdErrorTexts[] = {
@@ -746,8 +1579,11 @@
 
 cOsd::cOsd(int Left, int Top, uint Level)
 {
-  savedRegion = NULL;
+  isTrueColor = false;
+  savedBitmap = NULL;
   numBitmaps = 0;
+  savedPixmap = NULL;
+  numPixmaps = 0;
   left = Left;
   top = Top;
   width = height = 0;
@@ -766,7 +1602,10 @@
 {
   for (int i = 0; i < numBitmaps; i++)
       delete bitmaps[i];
-  delete savedRegion;
+  delete savedBitmap;
+  delete savedPixmap;
+  for (int i = 0; i < numPixmaps; i++)
+      delete pixmaps[i];
   for (int i = 0; i < Osds.Size(); i++) {
       if (Osds[i] == this) {
          Osds.Remove(i);
@@ -787,15 +1626,108 @@
 
 void cOsd::SetAntiAliasGranularity(uint FixedColors, uint BlendColors)
 {
+  if (isTrueColor)
+     return;
   for (int i = 0; i < numBitmaps; i++)
       bitmaps[i]->SetAntiAliasGranularity(FixedColors, BlendColors);
 }
 
 cBitmap *cOsd::GetBitmap(int Area)
 {
+  if (isTrueColor)
+     Area = 0; // returns the dummy bitmap
   return Area < numBitmaps ? bitmaps[Area] : NULL;
 }
 
+cPixmap *cOsd::CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort)
+{
+  if (isTrueColor) {
+     LOCK_PIXMAPS;
+     cPixmap *Pixmap = new cPixmapMemory(Layer, ViewPort, DrawPort);
+     if (AddPixmap(Pixmap))
+        return Pixmap;
+     delete Pixmap;
+     }
+  return NULL;
+}
+
+void cOsd::DestroyPixmap(cPixmap *Pixmap)
+{
+  if (isTrueColor) {
+     LOCK_PIXMAPS;
+     for (int i = 1; i < numPixmaps; i++) { // begin at 1 - don't let the background pixmap be destroyed!
+         if (pixmaps[i] == Pixmap) {
+            pixmaps[0]->MarkViewPortDirty(Pixmap->ViewPort());
+            delete Pixmap;
+            while (i < numPixmaps - 1) {
+                  pixmaps[i] = pixmaps[i + 1];
+                  i++;
+                  }
+            numPixmaps--;
+            return;
+            }
+         }
+     esyslog("ERROR: attempt to destroy an unregistered pixmap");
+     }
+}
+
+cPixmap *cOsd::AddPixmap(cPixmap *Pixmap)
+{
+  LOCK_PIXMAPS;
+  if (numPixmaps < MAXOSDPIXMAPS)
+     return pixmaps[numPixmaps++] = Pixmap;
+  else
+     esyslog("ERROR: too many OSD pixmaps requested (maximum is %d)", MAXOSDPIXMAPS);
+  return NULL;
+}
+
+cPixmapMemory *cOsd::RenderPixmaps(void)
+{
+  cPixmapMemory *Pixmap = NULL;
+  if (isTrueColor) {
+     LOCK_PIXMAPS;
+     // Collect overlapping dirty rectangles:
+     cRect d;
+     for (int i = 0; i < numPixmaps; i++) {
+         cPixmap *pm = pixmaps[i];
+         if (!pm->DirtyViewPort().IsEmpty()) {
+            if (d.IsEmpty() || d.Intersects(pm->DirtyViewPort())) {
+               d.Combine(pm->DirtyViewPort());
+               pm->SetClean();
+               }
+            }
+         }
+     if (!d.IsEmpty()) {
+//#define DebugDirty
+#ifdef DebugDirty
+        static cRect OldDirty;
+        cRect NewDirty = d;
+        d.Combine(OldDirty);
+        OldDirty = NewDirty;
+#endif
+        Pixmap = new cPixmapMemory(0, d);
+        Pixmap->Clear();
+        // Render the individual pixmaps into the resulting pixmap:
+        for (int Layer = 0; Layer < MAXPIXMAPLAYERS; Layer++) {
+            for (int i = 0; i < numPixmaps; i++) {
+                cPixmap *pm = pixmaps[i];
+                if (pm->Layer() == Layer)
+                   Pixmap->DrawPixmap(pm, d);
+                }
+            }
+#ifdef DebugDirty
+        cPixmapMemory DirtyIndicator(7, NewDirty);
+        static tColor DirtyIndicatorColors[] = { 0x7FFFFF00, 0x7F00FFFF };
+        static int DirtyIndicatorIndex = 0;
+        DirtyIndicator.Fill(DirtyIndicatorColors[DirtyIndicatorIndex]);
+        DirtyIndicatorIndex = 1 - DirtyIndicatorIndex;
+        Pixmap->Render(&DirtyIndicator, DirtyIndicator.DrawPort(), DirtyIndicator.ViewPort().Point().Shifted(-Pixmap->ViewPort().Point()));
+#endif
+        }
+     }
+  return Pixmap;
+}
+
 eOsdError cOsd::CanHandleAreas(const tArea *Areas, int NumAreas)
 {
   if (NumAreas > MAXOSDAREAS)
@@ -810,6 +1742,10 @@
              break;
              }
           }
+      if (Areas[i].bpp == 32) {
+         if (NumAreas > 1)
+            return oeTooManyAreas;
+         }
       }
   return Result;
 }
@@ -821,11 +1757,21 @@
      while (numBitmaps)
            delete bitmaps[--numBitmaps];
      width = height = 0;
-     for (int i = 0; i < NumAreas; i++) {
-         bitmaps[numBitmaps++] = new cBitmap(Areas[i].Width(), Areas[i].Height(), Areas[i].bpp, Areas[i].x1, Areas[i].y1);
-         width = max(width, Areas[i].x2 + 1);
-         height = max(height, Areas[i].y2 + 1);
-         }
+     isTrueColor = NumAreas == 1 && Areas[0].bpp == 32;
+     if (isTrueColor) {
+        width = Areas[0].x2 - Areas[0].x1 + 1;
+        height = Areas[0].y2 - Areas[0].y1 + 1;
+        cPixmap *Pixmap = CreatePixmap(0, cRect(Areas[0].x1, Areas[0].y1, width, height));
+        Pixmap->Clear();
+        bitmaps[numBitmaps++] = new cBitmap(10, 10, 8); // dummy bitmap for GetBitmap()
+        }
+     else {
+        for (int i = 0; i < NumAreas; i++) {
+            bitmaps[numBitmaps++] = new cBitmap(Areas[i].Width(), Areas[i].Height(), Areas[i].bpp, Areas[i].x1, Areas[i].y1);
+            width = max(width, Areas[i].x2 + 1);
+            height = max(height, Areas[i].y2 + 1);
+            }
+        }
      }
   else
      esyslog("ERROR: cOsd::SetAreas returned %d (%s)", Result, Result < oeUnknown ? OsdErrorTexts[Result] : OsdErrorTexts[oeUnknown]);
@@ -834,62 +1780,119 @@
 
 void cOsd::SaveRegion(int x1, int y1, int x2, int y2)
 {
-  delete savedRegion;
-  savedRegion = new cBitmap(x2 - x1 + 1, y2 - y1 + 1, 8, x1, y1);
-  for (int i = 0; i < numBitmaps; i++)
-      savedRegion->DrawBitmap(bitmaps[i]->X0(), bitmaps[i]->Y0(), *bitmaps[i]);
+  if (isTrueColor) {
+     delete savedPixmap;
+     cRect r(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+     savedPixmap = new cPixmapMemory(0, r);
+     savedPixmap->Copy(pixmaps[0], r, cPoint(0, 0));
+     }
+  else {
+     delete savedBitmap;
+     savedBitmap = new cBitmap(x2 - x1 + 1, y2 - y1 + 1, 8, x1, y1);
+     for (int i = 0; i < numBitmaps; i++)
+         savedBitmap->DrawBitmap(bitmaps[i]->X0(), bitmaps[i]->Y0(), *bitmaps[i]);
+     }
 }
 
 void cOsd::RestoreRegion(void)
 {
-  if (savedRegion) {
-     DrawBitmap(savedRegion->X0(), savedRegion->Y0(), *savedRegion);
-     delete savedRegion;
-     savedRegion = NULL;
+  if (isTrueColor) {
+     if (savedPixmap) {
+        pixmaps[0]->Copy(savedPixmap, savedPixmap->DrawPort(), savedPixmap->ViewPort().Point());
+        delete savedPixmap;
+        savedPixmap = NULL;
+        }
+     }
+  else {
+     if (savedBitmap) {
+        DrawBitmap(savedBitmap->X0(), savedBitmap->Y0(), *savedBitmap);
+        delete savedBitmap;
+        savedBitmap = NULL;
+        }
      }
 }
 
 eOsdError cOsd::SetPalette(const cPalette &Palette, int Area)
 {
-  if (Area < numBitmaps)
+  if (isTrueColor)
+     return oeOk;
+  if (Area < numBitmaps) {
      bitmaps[Area]->Take(Palette);
+     return oeOk;
+     }
   return oeUnknown;
 }
 
+void cOsd::DrawImage(const cPoint &Point, const cImage &Image)
+{
+  if (isTrueColor)
+     pixmaps[0]->DrawImage(Point, Image);
+}
+
+void cOsd::DrawImage(const cPoint &Point, int ImageHandle)
+{
+  if (isTrueColor)
+     pixmaps[0]->DrawImage(Point, ImageHandle);
+}
+
 void cOsd::DrawPixel(int x, int y, tColor Color)
 {
-  for (int i = 0; i < numBitmaps; i++)
-      bitmaps[i]->DrawPixel(x, y, Color);
+  if (isTrueColor)
+     pixmaps[0]->DrawPixel(cPoint(x, y), Color);
+  else {
+     for (int i = 0; i < numBitmaps; i++)
+         bitmaps[i]->DrawPixel(x, y, Color);
+     }
 }
 
 void cOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool ReplacePalette, bool Overlay)
 {
-  for (int i = 0; i < numBitmaps; i++)
-      bitmaps[i]->DrawBitmap(x, y, Bitmap, ColorFg, ColorBg, ReplacePalette, Overlay);
+  if (isTrueColor)
+     pixmaps[0]->DrawBitmap(cPoint(x, y), Bitmap, ColorFg, ColorBg, Overlay);
+  else {
+     for (int i = 0; i < numBitmaps; i++)
+         bitmaps[i]->DrawBitmap(x, y, Bitmap, ColorFg, ColorBg, ReplacePalette, Overlay);
+     }
 }
 
 void cOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment)
 {
-  for (int i = 0; i < numBitmaps; i++)
-      bitmaps[i]->DrawText(x, y, s, ColorFg, ColorBg, Font, Width, Height, Alignment);
+  if (isTrueColor)
+     pixmaps[0]->DrawText(cPoint(x, y), s, ColorFg, ColorBg, Font, Width, Height, Alignment);
+  else {
+     for (int i = 0; i < numBitmaps; i++)
+         bitmaps[i]->DrawText(x, y, s, ColorFg, ColorBg, Font, Width, Height, Alignment);
+     }
 }
 
 void cOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
 {
-  for (int i = 0; i < numBitmaps; i++)
-      bitmaps[i]->DrawRectangle(x1, y1, x2, y2, Color);
+  if (isTrueColor)
+     pixmaps[0]->DrawRectangle(cRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1), Color);
+  else {
+     for (int i = 0; i < numBitmaps; i++)
+         bitmaps[i]->DrawRectangle(x1, y1, x2, y2, Color);
+     }
 }
 
 void cOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants)
 {
-  for (int i = 0; i < numBitmaps; i++)
-      bitmaps[i]->DrawEllipse(x1, y1, x2, y2, Color, Quadrants);
+  if (isTrueColor)
+     pixmaps[0]->DrawEllipse(cRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1), Color, Quadrants);
+  else {
+     for (int i = 0; i < numBitmaps; i++)
+         bitmaps[i]->DrawEllipse(x1, y1, x2, y2, Color, Quadrants);
+     }
 }
 
 void cOsd::DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type)
 {
-  for (int i = 0; i < numBitmaps; i++)
-      bitmaps[i]->DrawSlope(x1, y1, x2, y2, Color, Type);
+  if (isTrueColor)
+     pixmaps[0]->DrawSlope(cRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1), Color, Type);
+  else {
+     for (int i = 0; i < numBitmaps; i++)
+         bitmaps[i]->DrawSlope(x1, y1, x2, y2, Color, Type);
+     }
 }
 
 void cOsd::Flush(void)
@@ -902,6 +1905,7 @@
 int cOsdProvider::oldWidth = 0;
 int cOsdProvider::oldHeight = 0;
 double cOsdProvider::oldAspect = 1.0;
+cImage *cOsdProvider::images[MAXOSDIMAGES] = { NULL };
 
 cOsdProvider::cOsdProvider(void)
 {
@@ -958,6 +1962,58 @@
      }
 }
 
+bool cOsdProvider::SupportsTrueColor(void)
+{
+  if (osdProvider) {
+     return osdProvider->ProvidesTrueColor();
+     }
+  else
+     esyslog("ERROR: no OSD provider available in call to SupportsTrueColor()");
+  return false;
+}
+
+int cOsdProvider::StoreImageData(const cImage &Image)
+{
+  LOCK_PIXMAPS;
+  for (int i = 1; i < MAXOSDIMAGES; i++) {
+      if (!images[i]) {
+         images[i] = new cImage(Image);
+         return i;
+         }
+      }
+  return 0;
+}
+
+void cOsdProvider::DropImageData(int ImageHandle)
+{
+  LOCK_PIXMAPS;
+  if (0 < ImageHandle && ImageHandle < MAXOSDIMAGES) {
+     delete images[ImageHandle];
+     images[ImageHandle] = NULL;
+     }
+}
+
+const cImage *cOsdProvider::GetImageData(int ImageHandle)
+{
+  LOCK_PIXMAPS;
+  if (0 < ImageHandle && ImageHandle < MAXOSDIMAGES)
+     return images[ImageHandle];
+  return NULL;
+}
+
+int cOsdProvider::StoreImage(const cImage &Image)
+{
+  if (osdProvider)
+     return osdProvider->StoreImageData(Image);
+  return -1;
+}
+
+void cOsdProvider::DropImage(int ImageHandle)
+{
+  if (osdProvider)
+     osdProvider->DropImageData(ImageHandle);
+}
+
 void cOsdProvider::Shutdown(void)
 {
   delete osdProvider;
diff -ruN vdr-1.7.16/osd.h vdr-1.7.17/osd.h
--- vdr-1.7.16/osd.h	2010-01-17 14:23:50.000000000 +0100
+++ vdr-1.7.17/osd.h	2011-03-12 17:06:48.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osd.h 2.5 2010/01/17 13:23:50 kls Exp $
+ * $Id: osd.h 2.11 2011/03/12 16:06:48 kls Exp $
  */
 
 #ifndef __OSD_H
@@ -15,12 +15,16 @@
 #include <stdint.h>
 #include "config.h"
 #include "font.h"
+#include "thread.h"
 #include "tools.h"
 
 #define OSD_LEVEL_DEFAULT     0
 #define OSD_LEVEL_SUBTITLES  10
 
 #define MAXNUMCOLORS 256
+#define ALPHA_TRANSPARENT  0x00
+#define ALPHA_OPAQUE       0xFF
+#define IS_OPAQUE(c)       ((c >> 24) == ALPHA_OPAQUE)
 
 enum {
                    //AARRGGBB
@@ -50,6 +54,28 @@
 typedef uint32_t tColor; // see also font.h
 typedef uint8_t tIndex;
 
+inline tColor ArgbToColor(uint8_t A, uint8_t R, uint8_t G, uint8_t B)
+{
+  return (tColor(A) << 24) | (tColor(R) << 16) | (tColor(G) << 8) | B;
+}
+
+inline tColor RgbToColor(uint8_t R, uint8_t G, uint8_t B)
+{
+  return (tColor(R) << 16) | (tColor(G) << 8) | B;
+}
+
+inline tColor RgbToColor(double R, double G, double B)
+{
+  return RgbToColor(uint8_t(0xFF * R), uint8_t(0xFF * G), uint8_t(0xFF * B));
+}
+
+tColor HsvToColor(double H, double S, double V);
+   ///< Converts the given Hue (0..360), Saturation (0..1) and Value (0..1)
+   ///< to an RGB tColor value. The alpha value of the result is 0x00, so
+   ///< the caller may need to set it accordingly.
+
+tColor AlphaBlend(tColor ColorFg, tColor ColorBg, uint8_t AlphaLayer = ALPHA_OPAQUE);
+
 class cPalette {
 private:
   tColor color[MAXNUMCOLORS];
@@ -247,6 +273,9 @@
        ///< the 2^NewBpp most frequently used colors as defined in the current palette.
        ///< If NewBpp is not smaller than the bitmap's current color depth,
        ///< or if it is not one of 4bpp or 2bpp, nothing happens.
+  cBitmap *Scale(double FactorX, double FactorY);
+       ///< Creates a copy of this bitmap, scaled by the given factors.
+       ///< The caller must delete the returned bitmap once it is no longer used.
   };
 
 struct tArea {
@@ -257,16 +286,433 @@
   bool Intersects(const tArea &Area) const { return !(x2 < Area.x1 || x1 > Area.x2 || y2 < Area.y1 || y1 > Area.y2); }
   };
 
+class cPoint {
+private:
+  int x;
+  int y;
+public:
+  cPoint(void) { x = y = 0; }
+  cPoint(int X, int Y) { x = X; y = Y; }
+  cPoint(const cPoint &Point) { x = Point.X(); y = Point.Y(); }
+  bool operator==(const cPoint &Point) const { return x == Point.X() && y == Point.Y(); }
+  bool operator!=(const cPoint &Point) const { return !(*this == Point); }
+  cPoint operator-(void) const { return cPoint(-x, -y); }
+  cPoint operator-(const cPoint &Point) const { return cPoint(x - Point.X(), y - Point.Y()); }
+  int X(void) const { return x; }
+  int Y(void) const { return y; }
+  void SetX(int X) { x = X; }
+  void SetY(int Y) { y = Y; }
+  void Set(int X, int Y) { x = X; y = Y; }
+  void Set(const cPoint &Point) { x = Point.X(); y = Point.Y(); }
+  void Shift(int Dx, int Dy) { x += Dx; y += Dy; }
+  void Shift(const cPoint &Dp) { x += Dp.X(); y += Dp.Y(); }
+  cPoint Shifted(int Dx, int Dy) const { cPoint p(*this); p.Shift(Dx, Dy); return p; }
+  cPoint Shifted(const cPoint &Dp) const { cPoint p(*this); p.Shift(Dp); return p; }
+  };
+
+class cSize {
+private:
+  int width;
+  int height;
+public:
+  cSize(void) { width = height = 0; }
+  cSize(int Width, int Height) { width = Width; height = Height; }
+  cSize(const cSize &Size) { width = Size.Width(); height = Size.Height(); }
+  bool operator==(const cSize &Size) const { return width == Size.Width() && height == Size.Height(); }
+  bool operator!=(const cSize &Size) const { return !(*this == Size); }
+  bool operator<(const cSize &Size) const { return width < Size.Width() && height < Size.Height(); }
+  int Width(void) const { return width; }
+  int Height(void) const { return height; }
+  void SetWidth(int Width) { width = Width; }
+  void SetHeight(int Height) { height = Height; }
+  void Set(int Width, int Height) { width = Width; height = Height; }
+  void Set(const cSize &Size) { width = Size.Width(); height = Size.Height(); }
+  bool Contains(const cPoint &Point) const { return 0 <= Point.X() && 0 <= Point.Y() && Point.X() < width && Point.Y() < height; }
+  void Grow(int Dw, int Dh) { width += 2 * Dw; height += 2 * Dh; }
+  cSize Grown(int Dw, int Dh) const { cSize s(*this); s.Grow(Dw, Dh); return s; }
+  };
+
+class cRect {
+private:
+  cPoint point;
+  cSize size;
+public:
+  static const cRect Null;
+  cRect(void): point(0, 0), size(0, 0) {}
+  cRect(int X, int Y, int Width, int Height): point(X, Y), size(Width, Height) {}
+  cRect(const cPoint &Point, const cSize &Size): point(Point), size(Size) {}
+  cRect(const cSize &Size): point(0, 0), size(Size) {}
+  cRect(const cRect &Rect): point(Rect.Point()), size(Rect.Size()) {}
+  bool operator==(const cRect &Rect) const { return point == Rect.Point() && size == Rect.Size(); }
+  bool operator!=(const cRect &Rect) const { return !(*this == Rect); }
+  int X(void) const { return point.X(); }
+  int Y(void) const { return point.Y(); }
+  int Width(void) const { return size.Width(); }
+  int Height(void) const { return size.Height(); }
+  int Left(void) const { return X(); }
+  int Top(void) const { return Y(); }
+  int Right(void) const { return X() + Width() - 1; }
+  int Bottom(void) const { return Y() + Height() - 1; }
+  const cPoint &Point(void) const { return point; }
+  const cSize &Size(void) const { return size; }
+  void Set(int X, int Y, int Width, int Height) { point.Set(X, Y); size.Set(Width, Height); }
+  void Set(cPoint Point, cSize Size) { point.Set(Point); size.Set(Size); }
+  void SetPoint(int X, int Y) { point.Set(X, Y); }
+  void SetPoint(const cPoint &Point) { point.Set(Point); }
+  void SetSize(int Width, int Height) { size.Set(Width, Height); }
+  void SetSize(const cSize &Size) { size.Set(Size); }
+  void SetX(int X) { point.SetX(X); }
+  void SetY(int Y) { point.SetY(Y); }
+  void SetWidth(int Width) { size.SetWidth(Width); }
+  void SetHeight(int Height) { size.SetHeight(Height); }
+  void SetLeft(int Left) { SetWidth(Width() + X() - Left); SetX(Left); }
+  void SetTop(int Top) { SetHeight(Height() + Y() - Top); SetY(Top); }
+  void SetRight(int Right) { SetWidth(Right - X() + 1); }
+  void SetBottom(int Bottom) { SetHeight(Bottom - Y() + 1); }
+  void Shift(int Dx, int Dy) { point.Shift(Dx, Dy); }
+  void Shift(const cPoint &Dp) { point.Shift(Dp); }
+  cRect Shifted(int Dx, int Dy) const { cRect r(*this); r.Shift(Dx, Dy); return r; }
+  cRect Shifted(const cPoint &Dp) const { cRect r(*this); r.Shift(Dp); return r; }
+  void Grow(int Dx, int Dy);
+       ///< Grows the rectangle by the given number of pixels in either direction.
+       ///< A negative value will shrink the rectangle.
+  cRect Grown(int Dw, int Dh) const { cRect r(*this); r.Grow(Dw, Dh); return r; }
+  bool Contains(const cPoint &Point) const;
+       ///< Returns true if this rectangle contains Point.
+  bool Contains(const cRect &Rect) const;
+       ///< Returns true if this rectangle completely contains Rect.
+  bool Intersects(const cRect &Rect) const;
+       ///< Returns true if this rectangle intersects with Rect.
+  cRect Intersected(const cRect &Rect) const;
+       ///< Returns the intersection of this rectangle and the given Rect.
+  void Combine(const cRect &Rect);
+       ///< Combines this rectangle with the given Rect.
+  cRect Combined(const cRect &Rect) const { cRect r(*this); r.Combine(Rect); return r; }
+       ///< Returns the surrounding rectangle that contains this rectangle and the
+       ///< given Rect.
+  void Combine(const cPoint &Point);
+       ///< Combines this rectangle with the given Point.
+  cRect Combined(const cPoint &Point) const { cRect r(*this); r.Combine(Point); return r; }
+       ///< Returns the surrounding rectangle that contains this rectangle and the
+       ///< given Point.
+  bool IsEmpty(void) const { return Width() <= 0 || Height() <= 0; }
+       ///< Returns true if this rectangle is empty.
+  };
+
+class cImage {
+private:
+  cSize size;
+  tColor *data;
+public:
+  cImage(void);
+  cImage(const cImage &Image);
+  cImage(const cSize &Size, const tColor *Data = NULL);
+       ///< Creates an image with the given Size and allocates the necessary memory
+       ///< to copy the pixels pointed to by Data, which is a sequence of
+       ///< (Size.Width() * Size.Height()) tColor values.
+       ///< If Data is NULL, the allocated memory is not initialized.
+       ///< The alpha value of the Image's pixels is taken into account, so it has to be
+       ///< greater than 0 for the image to be visible.
+  virtual ~cImage();
+  const cSize &Size(void) const { return size; }
+  int Width(void) const { return size.Width(); }
+  int Height(void) const { return size.Height(); }
+  const tColor *Data(void) const { return data; }
+  tColor GetPixel(const cPoint &Point) const { return data[size.Width() * Point.Y() + Point.X()]; }
+       ///< Returns the pixel value at the given Point.
+       ///< For performance reasons there is no range check here, so the caller
+       ///< must make sure that the Point is within the images size.
+  void SetPixel(const cPoint &Point, tColor Color) { data[size.Width() * Point.Y() + Point.X()] = Color; }
+       ///< Sets the pixel at the given Point to Color.
+       ///< For performance reasons there is no range check here, so the caller
+       ///< must make sure that the Point is within the images size.
+  void Clear(void);
+       ///< Clears the image data by setting all pixels to be fully transparent.
+  void Fill(tColor Color);
+       ///< Fills the image data with the given Color.
+  };
+
+#define MAXPIXMAPLAYERS    8
+
+class cPixmap {
+  friend class cOsd;
+  friend class cPixmapMutexLock;
+private:
+  static cMutex mutex;
+  int layer;
+  int alpha;
+  bool tile;
+  cRect viewPort;
+  cRect drawPort;
+  cRect dirtyViewPort;
+  cRect dirtyDrawPort;
+protected:
+  virtual ~cPixmap() {}
+  void MarkViewPortDirty(const cRect &Rect);
+       ///< Marks the given rectangle of the view port of this pixmap as dirty.
+       ///< Rect is combined with the existing dirtyViewPort rectangle.
+       ///< The coordinates of Rect are given in absolute OSD values.
+  void MarkViewPortDirty(const cPoint &Point);
+       ///< Marks the given point of the view port of this pixmap as dirty.
+       ///< Point is combined with the existing dirtyViewPort rectangle.
+       ///< The coordinates of Point are given in absolute OSD values.
+  void MarkDrawPortDirty(const cRect &Rect);
+       ///< Marks the given rectangle of the draw port of this pixmap as dirty.
+       ///< Rect is combined with the existing dirtyDrawPort rectangle.
+       ///< The coordinates of Rect are relative to the pixmap's draw port.
+       ///< If Rect extends into the currently visible view port of this pixmap,
+       ///< MarkViewPortDirty() is called with the appropriate value.
+  void MarkDrawPortDirty(const cPoint &Point);
+       ///< Marks the given point of the draw port of this pixmap as dirty.
+       ///< Point is combined with the existing dirtyDrawPort rectangle.
+       ///< The coordinates of Point are relative to the pixmap's draw port.
+       ///< If Point is within the currently visible view port of this pixmap,
+       ///< MarkViewPortDirty() is called with the appropriate value.
+  void SetClean(void);
+       ///< Resets the "dirty" rectangles of this pixmap.
+  virtual void DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty);
+       ///< Draws the Dirty part of the given Pixmap into this pixmap. If the
+       ///< Pixmap's layer is 0, it is copied, otherwise it is rendered into this
+       ///< pixmap. This function is used only to implement the tile handling
+       ///< in the final rendering to the OSD.
+public:
+  cPixmap(void);
+  cPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null);
+       ///< Creates a pixmap in the given Layer. When rendering the final OSD, pixmaps
+       ///< are handled in ascending order of their individual layer. This is
+       ///< important if pixmaps overlap each other. The one with the highest layer is
+       ///< rendered last. The actual value of Layer doesn't matter, it is only used
+       ///< for defining the rendering sequence. If Layer is less than zero, this
+       ///< pixmap will not be rendered into the final OSD (it can be activated by a
+       ///< later call to SetLayer()). The value 0 is reserved for the background
+       ///< pixmap and shall not be used otherwise (with the sole exception of
+       ///< temporarily using layer 0 to have a text with transparent background
+       ///< rendered with alpha blending into that pixmap; see also DrawPixel()).
+       ///< If there are several pixmaps with the same value of Layer, their rendering
+       ///< sequence within that layer is undefined.
+       ///< In order to allow devices that can handle only a limited number of layers,
+       ///< the Layer parameter must be less than 8 (MAXPIXMAPLAYERS).
+       ///< ViewPort defines the rectangle in which this pixmap will be rendered on
+       ///< the OSD. If no DrawPort ist given, it defaults to the same size as the
+       ///< ViewPort, with its upper left corner set to (0, 0).
+       ///< All drawing operations will be executed relative to the origin of the
+       ///< DrawPort rectangle, and will be clipped to the size of this rectangle.
+       ///< The DrawPort may have a different size than the ViewPort. If it is smaller
+       ///< than the ViewPort, the rest of the ViewPort is treated as fully transparent
+       ///< (unless this is a tiled pixmap, in which case the DrawPort is repeated
+       ///< horizontally and vertically to fill the entire ViewPort). If the DrawPort
+       ///< is larger than the ViewPort, only that portion of the DrawPort that
+       ///< intersects with the ViewPort will be visible on the OSD.
+       ///< The drawing area of a newly created cPixmap is not initialized and may
+       ///< contain random data.
+  static void Lock(void) { mutex.Lock(); }
+       ///< All public member functions of cPixmap set locks as necessary to make sure
+       ///< they are thread-safe (unless noted otherwise). If several cPixmap member
+       ///< functions need to be called in a row, the caller must surround these calls
+       ///< with proper Lock()/Unlock() calls. See the LOCK_PIXMAPS macro for a
+       ///< convenient way of doing this.
+  static void Unlock(void) { mutex.Unlock(); }
+  int Layer(void) const { return layer; }
+  int Alpha(void) const { return alpha; }
+  bool Tile(void) const { return tile; }
+  const cRect &ViewPort(void) const { return viewPort; }
+       ///< Returns the pixmap's view port, which is relative to the OSD's origin.
+       ///< Since this function returns a reference to a data member, the caller must
+       ///< use Lock()/Unlock() to make sure the data doesn't change while it is used.
+  const cRect &DrawPort(void) const { return drawPort; }
+       ///< Returns the pixmap's draw port, which is relative to the view port.
+       ///< Since this function returns a reference to a data member, the caller must
+       ///< use Lock()/Unlock() to make sure the data doesn't change while it is used.
+  const cRect &DirtyViewPort(void) const { return dirtyViewPort; }
+       ///< Returns the "dirty" rectangle this pixmap causes on the OSD. This is the
+       ///< surrounding rectangle around all pixels that have been modified since the
+       ///< last time this pixmap has been rendered to the OSD. The rectangle is
+       ///< relative to the OSD's origin.
+       ///< Since this function returns a reference to a data member, the caller must
+       ///< use Lock()/Unlock() to make sure the data doesn't change while it is used.
+  const cRect &DirtyDrawPort(void) const { return dirtyDrawPort; }
+       ///< Returns the "dirty" rectangle in the draw port of this this pixmap. This is
+       ///< the surrounding rectangle around all pixels that have been modified since the
+       ///< last time this pixmap has been rendered to the OSD. The rectangle is
+       ///< relative to the draw port's origin.
+       ///< Since this function returns a reference to a data member, the caller must
+       ///< use Lock()/Unlock() to make sure the data doesn't change while it is used.
+  virtual void SetLayer(int Layer);
+       ///< Sets the layer of this pixmap to the given value.
+       ///< If the new layer is greater than zero, the pixmap will be visible.
+       ///< If it is less than zero, it will be invisible.
+       ///< A value of 0 will be silently ignored.
+       ///< If a derived class reimplements this function, it needs to call the base
+       ///< class function.
+  virtual void SetAlpha(int Alpha);
+       ///< Sets the alpha value of this pixmap to the given value.
+       ///< Alpha is limited to the range 0 (fully transparent) to 255 (fully opaque).
+       ///< If a derived class reimplements this function, it needs to call the base
+       ///< class function.
+  virtual void SetTile(bool Tile);
+       ///< Sets the tile property of this pixmap to the given value. If Tile is true,
+       ///< the pixmaps data will be repeated horizontally and vertically if necessary
+       ///< to fill the entire view port.
+       ///< If a derived class reimplements this function, it needs to call the base
+       ///< class function.
+  virtual void SetViewPort(const cRect &Rect);
+       ///< Sets the pixmap's view port to the given Rect.
+       ///< If a derived class reimplements this function, it needs to call the base
+       ///< class function.
+  virtual void SetDrawPortPoint(const cPoint &Point, bool Dirty = true);
+       ///< Sets the pixmap's draw port to the given Point.
+       ///< Only the origin point of the draw port can be modified, its size is fixed.
+       ///< By default, setting a new draw port point results in marking the relevant
+       ///< part of the view port as "drity". If Dirty is set to false, the view port
+       ///< will not be marked as dirty. This is mainly used to implement the Pan()
+       ///< function.
+       ///< If a derived class reimplements this function, it needs to call the base
+       ///< class function.
+  virtual void Clear(void) = 0;
+       ///< Clears the pixmap's draw port by setting all pixels to be fully transparent.
+       ///< A derived class must call Lock()/Unlock().
+  virtual void Fill(tColor Color) = 0;
+       ///< Fills the pixmap's draw port with the given Color.
+       ///< A derived class must call Lock()/Unlock().
+  virtual void DrawImage(const cPoint &Point, const cImage &Image) = 0;
+       ///< Draws the given Image into this pixmap at the given Point.
+  virtual void DrawImage(const cPoint &Point, int ImageHandle) = 0;
+       ///< Draws the image referenced by the given ImageHandle into this pixmap at
+       ///< the given Point. ImageHandle must be a value that has previously been
+       ///< returned by a call to cOsdProvider::StoreImage(). If ImageHandle
+       ///< has an invalid value, nothing happens.
+  virtual void DrawPixel(const cPoint &Point, tColor Color) = 0;
+       ///< Sets the pixel at the given Point to the given Color, which is
+       ///< a full 32 bit ARGB value. If the alpha value of Color is not 0xFF
+       ///< (fully opaque), and this is the background pixmap (layer 0), the pixel is
+       ///< alpha blended with the existing color at the given position in this pixmap.
+  virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false) = 0;
+       ///< Sets the pixels in the OSD with the data from the given
+       ///< Bitmap, putting the upper left corner of the Bitmap at Point.
+       ///< If ColorFg or ColorBg is given, the first palette entry of the Bitmap
+       ///< will be mapped to ColorBg and the second palette entry will be mapped to
+       ///< ColorFg (palette indexes are defined so that 0 is the background and
+       ///< 1 is the foreground color).
+       ///< If Overlay is true, any pixel in Bitmap that has color index 0 will
+       ///< not overwrite the corresponding pixel in the target area.
+       ///< This function is mainly for compatibility with skins or plugins that
+       ///< draw bitmaps onto the OSD.
+  virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault) = 0;
+       ///< Draws the given string at Point with the given foreground
+       ///< and background color and font. If Width and Height are given, the text
+       ///< will be drawn into a rectangle with the given size and the given
+       ///< Alignment (default is top-left). If ColorBg is clrTransparent, no
+       ///< background pixels will be drawn, which allows drawing "transparent" text.
+  virtual void DrawRectangle(const cRect &Rect, tColor Color) = 0;
+       ///< Draws a filled rectangle with the given Color.
+  virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants = 0) = 0;
+       ///< Draws a filled ellipse with the given Color that fits into the given
+       ///< rectangle. Quadrants controls which parts of the ellipse are actually drawn:
+       ///< 0       draws the entire ellipse
+       ///< 1..4    draws only the first, second, third or fourth quadrant, respectively
+       ///< 5..8    draws the right, top, left or bottom half, respectively
+       ///< -1..-8  draws the inverted part of the given quadrant(s)
+       ///< If Quadrants is not 0, the coordinates are those of the actual area, not
+       ///< the full circle!
+  virtual void DrawSlope(const cRect &Rect, tColor Color, int Type) = 0;
+       ///< Draws a "slope" with the given Color into the given rectangle.
+       ///< Type controls the direction of the slope and which side of it will be drawn:
+       ///< 0: horizontal, rising,  lower
+       ///< 1: horizontal, rising,  upper
+       ///< 2: horizontal, falling, lower
+       ///< 3: horizontal, falling, upper
+       ///< 4: vertical,   rising,  lower
+       ///< 5: vertical,   rising,  upper
+       ///< 6: vertical,   falling, lower
+       ///< 7: vertical,   falling, upper
+  virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) = 0;
+       ///< Renders the part of the given Pixmap covered by Source into this pixmap at
+       ///< location Dest. The Source rectangle is relative to the given Pixmap's draw port.
+       ///< The Pixmap's alpha value is to be used when rendering.
+  virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) = 0;
+       ///< Copies the part of the given Pixmap covered by Source into this pixmap at
+       ///< location Dest. The Source rectangle is relative to the given Pixmap's draw port.
+       ///< The data from Pixmap is copied as is, no alpha handling of any kind takes
+       ///< place.
+  virtual void Scroll(const cPoint &Dest, const cRect &Source = cRect::Null) = 0;
+       ///< Scrolls the data in the pixmap's draw port to the given Dest point.
+       ///< If Source is given, only the data within that rectangle is scrolled.
+       ///< Source and Dest are relative to this pixmap's draw port.
+  virtual void Pan(const cPoint &Dest, const cRect &Source = cRect::Null) = 0;
+       ///< Does the same as Scroll(), but also shifts the draw port accordingly,
+       ///< so that the view port doesn't get dirty if the scrolled rectangle
+       ///< covers the entire view port. This may be of advantage if, e.g.,
+       ///< there is a draw port that holds, say, 11 lines of text, while the
+       ///< view port displays only 10 lines. By Pan()'ing the draw port up one
+       ///< line, an new bottom line can be written into the draw port (without
+       ///< being seen through the view port), and later the draw port can be
+       ///< shifted smoothly, resulting in a smooth scrolling.
+       ///< It is the caller's responsibility to make sure that Source and Dest
+       ///< are given in such a way that the view port will not get dirty. No
+       ///< check is done whether this condition actually holds true.
+  };
+
+class cPixmapMutexLock : public cMutexLock {
+public:
+  cPixmapMutexLock(void): cMutexLock(&cPixmap::mutex) {}
+  };
+
+#define LOCK_PIXMAPS cPixmapMutexLock PixmapMutexLock
+
+// cPixmapMemory is an implementation of cPixmap that uses an array of tColor
+// values to store the pixmap.
+
+class cPixmapMemory : public cPixmap {
+private:
+  tColor *data;
+  bool panning;
+public:
+  cPixmapMemory(void);
+  cPixmapMemory(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null);
+  virtual ~cPixmapMemory();
+  const uint8_t *Data(void) { return (uint8_t *)data; }
+  virtual void Clear(void);
+  virtual void Fill(tColor Color);
+  virtual void DrawImage(const cPoint &Point, const cImage &Image);
+  virtual void DrawImage(const cPoint &Point, int ImageHandle);
+  virtual void DrawPixel(const cPoint &Point, tColor Color);
+  virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false);
+  virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
+  virtual void DrawRectangle(const cRect &Rect, tColor Color);
+  virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants = 0);
+  virtual void DrawSlope(const cRect &Rect, tColor Color, int Type);
+  virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest);
+  virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest);
+  virtual void Scroll(const cPoint &Dest, const cRect &Source = cRect::Null);
+  virtual void Pan(const cPoint &Dest, const cRect &Source = cRect::Null);
+  };
+
 #define MAXOSDAREAS 16
+#define MAXOSDPIXMAPS 64
+
+/// The cOsd class is the interface to the "On Screen Display".
+/// An actual output device needs to derive from this class and implement
+/// the functionality necessary to display the OSD on the TV screen.
+/// If the actual OSD supports "True Color", it can either let VDR do
+/// all the rendering by calling RenderPixmaps() ("raw mode"), or it can
+/// reimplement all necessary cPixmap functions and do the rendering
+/// itself ("high level mode").
+/// If an OSD provides a "high level mode", it shall also provide a "raw mode"
+/// in order to verify proper operation. The plugin that impements the OSD
+/// shall offer a configuration switch in its setup.
 
 class cOsd {
   friend class cOsdProvider;
 private:
   static int osdLeft, osdTop, osdWidth, osdHeight;
   static cVector<cOsd *> Osds;
-  cBitmap *savedRegion;
+  bool isTrueColor;
+  cBitmap *savedBitmap;
   cBitmap *bitmaps[MAXOSDAREAS];
   int numBitmaps;
+  cPixmapMemory *savedPixmap;
+  cPixmap *pixmaps[MAXOSDPIXMAPS];
+  int numPixmaps;
   int left, top, width, height;
   uint level;
   bool active;
@@ -295,6 +741,32 @@
   virtual void SetActive(bool On) { active = On; }
        ///< Sets this OSD to be the active one.
        ///< A derived class must call cOsd::SetActive(On).
+  const cPixmap * const *Pixmaps(void) { return pixmaps; }
+       ///< Returns the list of currently active pixmaps in this OSD.
+  int NumPixmaps(void) { return numPixmaps; }
+       ///< Returns the number of currently active pixmaps in this OSD.
+  cPixmap *AddPixmap(cPixmap *Pixmap);
+       ///< Adds the given Pixmap to the list of currently active pixmaps in this OSD.
+       ///< Returns Pixmap if the operation was successful, or NULL if the maximum
+       ///< number of pixmaps has been exceeded.
+       ///< A derived class that implements its own cPixmap class must call AddPixmap()
+       ///< in order to add a newly created pixmap to the OSD's list of pixmaps.
+  cPixmapMemory *RenderPixmaps(void);
+       ///< Renders the dirty part of all pixmaps into a resulting pixmap that
+       ///< shall be displayed on the OSD. The returned pixmap's view port is
+       ///< set to the location of the rectangle on the OSD that needs to be
+       ///< refreshed; its draw port's origin is at (0, 0), and it has the same
+       ///< size as the view port.
+       ///< If there are several non-overlapping dirty rectangles from different pixmaps,
+       ///< they are returned separately in order to avoid re-rendering large parts
+       ///< of the OSD that haven't changed at all. The caller must therefore call
+       ///< RenderPixmaps() repeatedly until it returns NULL, and display the returned
+       ///< parts of the OSD at their appropriate locations. During this entire
+       ///< operation the caller must hold a lock on the cPixmap mutex (for instance
+       ///< by putting a LOCK_PIXMAPS into the scope of the operation).
+       ///< If there are no dirty pixmaps, or if this is not a true color OSD,
+       ///< this function returns NULL.
+       ///< The caller must delete the returned pixmap after use.
 public:
   virtual ~cOsd();
        ///< Shuts down the OSD.
@@ -309,6 +781,9 @@
        ///< screen.
   static int IsOpen(void) { return Osds.Size() && Osds[0]->level == OSD_LEVEL_DEFAULT; }
        ///< Returns true if there is currently a level 0 OSD open.
+  bool IsTrueColor(void) const { return isTrueColor; }
+       ///< Returns 'true' if this is a true color OSD (providing full 32 bit color
+       ///< depth).
   int Left(void) { return left; }
   int Top(void) { return top; }
   int Width(void) { return width; }
@@ -323,9 +798,33 @@
        ///< a single color combination, and may not be able to serve all
        ///< requested colors. By default the palette assumes there will be
        ///< 10 fixed colors and 10 color combinations.
+       ///< If this is a true color OSD, this function does nothing.
   cBitmap *GetBitmap(int Area);
        ///< Returns a pointer to the bitmap for the given Area, or NULL if no
        ///< such bitmap exists.
+       ///< If this is a true color OSD, a pointer to a dummy bitmap with 8bpp
+       ///< is returned. This is done so that skins that call this function
+       ///< in order to preset the bitmap's palette won't crash.
+  virtual cPixmap *CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null);
+       ///< Creates a new true color pixmap on this OSD (see cPixmap for details).
+       ///< The caller must not delete the returned object, it will be deleted when
+       ///< the OSD is deleted. DestroyPixmap() can be called if a pixmap shall be
+       ///< destroyed before the OSD is deleted.
+       ///< If this is not a true color OSD, this function returns NULL.
+  virtual void DestroyPixmap(cPixmap *Pixmap);
+       ///< Destroys the given Pixmap, which has previously been created by a call to
+       ///< CreatePixmap(). When the OSD is deleted, all pixmaps are destroyed
+       ///< automatically. So this function only needs to be used if a pixmap shall
+       ///< be destroyed while the OSD is still being used.
+  virtual void DrawImage(const cPoint &Point, const cImage &Image);
+       ///< Draws the given Image on this OSD at the given Point.
+       ///< If this is not a true color OSD, this function does nothing.
+  virtual void DrawImage(const cPoint &Point, int ImageHandle);
+       ///< Draws the image referenced by the given ImageHandle on this OSD at
+       ///< the given Point. ImageHandle must be a value that has previously been
+       ///< returned by a call to cOsdProvider::StoreImage(). If ImageHandle
+       ///< has an invalid value, nothing happens.
+       ///< If this is not a true color OSD, this function does nothing.
   virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
        ///< Checks whether the OSD can display the given set of sub-areas.
        ///< The return value indicates whether a call to SetAreas() with this
@@ -343,6 +842,9 @@
        ///< are part of the rectangle that surrounds a given drawing operation
        ///< will be drawn into, with the proper offsets.
        ///< A new call overwrites any previous settings
+       ///< To set up a true color OSD, exactly one area must be requested, with
+       ///< its coordinates set to the full area the OSD shall cover, and the
+       ///< bpp value set to 32.
   virtual void SaveRegion(int x1, int y1, int x2, int y2);
        ///< Saves the region defined by the given coordinates for later restoration
        ///< through RestoreRegion(). Only one saved region can be active at any
@@ -352,6 +854,7 @@
        ///< If SaveRegion() has not been called before, nothing will happen.
   virtual eOsdError SetPalette(const cPalette &Palette, int Area);
        ///< Sets the Palette for the given Area (the first area is numbered 0).
+       ///< If this is a true color OSD, nothing happens and oeOk is returned.
   virtual void DrawPixel(int x, int y, tColor Color);
        ///< Sets the pixel at the given coordinates to the given Color, which is
        ///< a full 32 bit ARGB value.
@@ -368,6 +871,7 @@
        ///< area shall have its palette replaced with the one from Bitmap.
        ///< If Overlay is true, any pixel in Bitmap that has color index 0 will
        ///< not overwrite the corresponding pixel in the target area.
+       ///< If this is a true color OSD, ReplacePalette has no meaning.
   virtual void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
        ///< Draws the given string at coordinates (x, y) with the given foreground
        ///< and background color and font. If Width and Height are given, the text
@@ -401,18 +905,51 @@
        ///< 7: vertical,   falling, upper
   virtual void Flush(void);
        ///< Actually commits all data to the OSD hardware.
+       ///< Flush() should return as soon as possible.
+       ///< For a true color OSD using the default implementation with in memory
+       ///< pixmaps, the Flush() function should basically do something like this:
+       ///<
+       ///<  LOCK_PIXMAPS;
+       ///<  while (cPixmapMemory *pm = RenderPixmaps()) {
+       ///<        int w = pm->ViewPort().Width();
+       ///<        int h = pm->ViewPort().Height();
+       ///<        int d = w * sizeof(tColor);
+       ///<        MyOsdDrawPixmap(Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y(), pm->Data(), w, h, h * d);
+       ///<        delete pm;
+       ///<        }
   };
 
+#define MAXOSDIMAGES 64
+
 class cOsdProvider {
+  friend class cPixmapMemory;
 private:
   static cOsdProvider *osdProvider;
   static int oldWidth;
   static int oldHeight;
   static double oldAspect;
+  static cImage *images[MAXOSDIMAGES];
 protected:
   virtual cOsd *CreateOsd(int Left, int Top, uint Level) = 0;
       ///< Returns a pointer to a newly created cOsd object, which will be located
       ///< at the given coordinates.
+  virtual bool ProvidesTrueColor(void) { return false; }
+      ///< Returns true if this OSD provider is able to handle a true color OSD.
+  virtual int StoreImageData(const cImage &Image);
+      ///< Copies the given Image and returns a handle for later reference.
+      ///< A derived class can implement its own image storing mechanism by
+      ///< reimplementing this function as well as DropImageData().
+      ///< The base class implementation simply copies the image data to allow
+      ///< plugins to always use this interface, no matter if the actual device
+      ///< provides support for storing image data or not. The handles returned
+      ///< by the default implementation are positive integers. A derived class
+      ///< might want to use negative integers as handles, so that it can fall
+      ///< back to using the base class image storing mechanism if, e.g.,  it runs
+      ///< out of memory.
+  virtual void DropImageData(int ImageHandle);
+      ///< Drops the image data referenced by ImageHandle.
+  static const cImage *GetImageData(int ImageHandle);
+      ///< Gets the image data referenced by ImageHandle.
 public:
   cOsdProvider(void);
       //XXX maybe parameter to make this one "sticky"??? (frame-buffer etc.)
@@ -427,7 +964,22 @@
       ///< Inquires the actual size of the video display and adjusts the OSD and
       ///< font sizes accordingly. If Force is true, all settings are recalculated,
       ///< even if the video resolution hasn't changed since the last call to
-      ///< this funtion.
+      ///< this function.
+  static bool SupportsTrueColor(void);
+      ///< Returns true if the current OSD provider is able to handle a true color OSD.
+  static int StoreImage(const cImage &Image);
+      ///< Stores the given Image for later use with DrawImage() on an OSD or
+      ///< pixmap. The returned number is a handle that must be used when
+      ///< referencing this image in a call to DrawImage() or DropImage().
+      ///< The image data is copied, so any later changes to Image will have
+      ///< no effect on the stored image.
+      ///< A derived class may be able to copy frequently used images to some
+      ///< space where they can be retrieved faster than using a cImage in each call.
+      ///< If this is not a true color OSD, or if the image data can't be stored for
+      ///< any reason, this function returns 0 and nothing is stored.
+  static void DropImage(int ImageHandle);
+      ///< Drops the image referenced by the given ImageHandle. If ImageHandle
+      ///< has an invalid value, nothing happens.
   static void Shutdown(void);
       ///< Shuts down the OSD provider facility by deleting the current OSD provider.
   };
diff -ruN vdr-1.7.16/osdbase.c vdr-1.7.17/osdbase.c
--- vdr-1.7.16/osdbase.c	2010-01-17 12:36:12.000000000 +0100
+++ vdr-1.7.17/osdbase.c	2010-12-12 14:41:28.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osdbase.c 2.2 2010/01/17 11:36:12 kls Exp $
+ * $Id: osdbase.c 2.3 2010/12/12 13:41:28 kls Exp $
  */
 
 #include "osdbase.h"
@@ -500,7 +500,7 @@
         return state;
         }
      }
-  switch (Key) {
+  switch (int(Key)) {
     case k0:      return osUnknown;
     case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown;
     case kUp|k_Repeat:
diff -ruN vdr-1.7.16/pat.c vdr-1.7.17/pat.c
--- vdr-1.7.16/pat.c	2010-06-13 13:12:12.000000000 +0200
+++ vdr-1.7.17/pat.c	2010-11-07 14:47:16.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: pat.c 2.13 2010/06/13 11:12:12 kls Exp $
+ * $Id: pat.c 2.15 2010/11/07 13:47:16 kls Exp $
  */
 
 #include "pat.h"
@@ -456,29 +456,51 @@
                          }
                       }
                       break;
-              case 0x81: // STREAMTYPE_USER_PRIVATE
-                      if (Channel->IsAtsc()) { // ATSC AC-3
-                         char lang[MAXLANGCODE1] = { 0 };
-                         SI::Descriptor *d;
-                         for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
-                             switch (d->getDescriptorTag()) {
-                               case SI::ISO639LanguageDescriptorTag: {
-                                    SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
-                                    strn0cpy(lang, I18nNormalizeLanguageCode(ld->languageCode), MAXLANGCODE1);
-                                    }
-                                    break;
-                               default: ;
-                               }
-                             delete d;
-                             }
-                         if (NumDpids < MAXDPIDS) {
-                            Dpids[NumDpids] = esPid;
-                            Dtypes[NumDpids] = SI::AC3DescriptorTag;
-                            strn0cpy(DLangs[NumDpids], lang, MAXLANGCODE1);
-                            NumDpids++;
+              case 0x80 ... 0xFF: // STREAMTYPE_USER_PRIVATE
+                      {
+                      char lang[MAXLANGCODE1] = { 0 };
+                      bool IsAc3 = false;
+                      SI::Descriptor *d;
+                      for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
+                          switch (d->getDescriptorTag()) {
+                            case SI::RegistrationDescriptorTag: {
+                                 SI::RegistrationDescriptor *rd = (SI::RegistrationDescriptor *)d;
+                                 // http://www.smpte-ra.org/mpegreg/mpegreg.html
+                                 switch (rd->getFormatIdentifier()) {
+                                   case 0x44434949: // 'DCII' aka. DigiCipher II
+                                        Vpid = esPid;
+                                        Ppid = pmt.getPCRPid();
+                                        Vtype = 0x02; // DCII compression is based upon MPEG-2
+                                        ProcessCaDescriptors = true;
+                                        break;
+                                   case 0x41432D33: // 'AC-3'
+                                        IsAc3 = true;
+                                        break;
+                                   default:
+                                        //printf("Format identifier: 0x08X\n", rd->getFormatIdentifier());
+                                        break;
+                                   }
+                                 }
+                                 break;
+                            case SI::ISO639LanguageDescriptorTag: {
+                                 SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
+                                 strn0cpy(lang, I18nNormalizeLanguageCode(ld->languageCode), MAXLANGCODE1);
+                                 }
+                                 break;
+                            default: ;
                             }
+                         delete d;
+                         }
+                      if (IsAc3) {
+                         if (NumDpids < MAXDPIDS) {
+                           Dpids[NumDpids] = esPid;
+                           Dtypes[NumDpids] = SI::AC3DescriptorTag;
+                           strn0cpy(DLangs[NumDpids], lang, MAXLANGCODE1);
+                           NumDpids++;
+                           }
                          ProcessCaDescriptors = true;
                          }
+                      }
                       break;
               default: ;//printf("PID: %5d %5d %2d %3d %3d\n", pmt.getServiceId(), stream.getPid(), stream.getStreamType(), pmt.getVersionNumber(), Channel->Number());
               }
diff -ruN vdr-1.7.16/po/ar.po vdr-1.7.17/po/ar.po
--- vdr-1.7.16/po/ar.po	2010-09-19 14:44:29.000000000 +0200
+++ vdr-1.7.17/po/ar.po	2010-12-24 12:36:42.000000000 +0100
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-09-12 13:37+0200\n"
+"POT-Creation-Date: 2010-12-24 12:35+0100\n"
 "PO-Revision-Date: 2008-10-16 11:16-0400\n"
 "Last-Translator: Osama Alrawab <alrawab@hotmail.com>\n"
 "Language-Team: Arabic <ar@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: ar\n"
 "X-Poedit-Bookmarks: -1,-1,-1,-1,-1,-1,-1,-1,1249,-1\n"
 "X-Poedit-Language: Arabic\n"
 "X-Poedit-Country: LIBYA\n"
diff -ruN vdr-1.7.16/po/ca_ES.po vdr-1.7.17/po/ca_ES.po
--- vdr-1.7.16/po/ca_ES.po	2010-09-19 14:44:29.000000000 +0200
+++ vdr-1.7.17/po/ca_ES.po	2010-10-24 16:40:27.000000000 +0200
@@ -10,13 +10,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-03-02 19:02+0100\n"
 "Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
-"Language-Team: Catalanian\n"
+"Language-Team: Catalan <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: ca\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Canal incorrecte ***"
diff -ruN vdr-1.7.16/po/cs_CZ.po vdr-1.7.17/po/cs_CZ.po
--- vdr-1.7.16/po/cs_CZ.po	2010-09-19 14:44:29.000000000 +0200
+++ vdr-1.7.17/po/cs_CZ.po	2010-10-24 16:40:27.000000000 +0200
@@ -9,13 +9,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.14\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2010-05-06 11:00+0200\n"
 "Last-Translator: Radek Å Å¥astnÃ½ <dedkus@gmail.com>\n"
-"Language-Team: Czech\n"
+"Language-Team: Czech <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: cs\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** NeplatnÃ½ kanÃ¡l ***"
diff -ruN vdr-1.7.16/po/da_DK.po vdr-1.7.17/po/da_DK.po
--- vdr-1.7.16/po/da_DK.po	2010-09-19 14:44:29.000000000 +0200
+++ vdr-1.7.17/po/da_DK.po	2010-10-24 16:40:27.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Mogens Elneff <mogens@elneff.dk>\n"
-"Language-Team: Danish\n"
+"Language-Team: Danish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Ugyldig kanal! ***"
diff -ruN vdr-1.7.16/po/de_DE.po vdr-1.7.17/po/de_DE.po
--- vdr-1.7.16/po/de_DE.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/de_DE.po	2010-10-24 16:40:27.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2010-01-16 16:46+0100\n"
 "Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n"
-"Language-Team: German\n"
+"Language-Team: German <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Ungültiger Kanal ***"
diff -ruN vdr-1.7.16/po/el_GR.po vdr-1.7.17/po/el_GR.po
--- vdr-1.7.16/po/el_GR.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/el_GR.po	2010-10-24 16:40:27.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n"
-"Language-Team: Greek\n"
+"Language-Team: Greek <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-7\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: el\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Áêõñï êáíÜëç ***"
diff -ruN vdr-1.7.16/po/es_ES.po vdr-1.7.17/po/es_ES.po
--- vdr-1.7.16/po/es_ES.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/es_ES.po	2010-10-24 16:40:28.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-03-02 19:02+0100\n"
 "Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
-"Language-Team: Spanish\n"
+"Language-Team: Spanish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: es\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Canal no válido ***"
diff -ruN vdr-1.7.16/po/et_EE.po vdr-1.7.17/po/et_EE.po
--- vdr-1.7.16/po/et_EE.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/et_EE.po	2010-10-24 16:40:28.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
-"Language-Team: Estonian\n"
+"Language-Team: Estonian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-13\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: et\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Vigane kanal ***"
@@ -840,7 +841,7 @@
 msgstr "Kaustad taimeri menüüs"
 
 msgid "Setup.OSD$Number keys for characters"
-msgstr ""
+msgstr "Teksti sisestamine numbriklahvidega"
 
 msgid "EPG"
 msgstr "EPG"
diff -ruN vdr-1.7.16/po/fi_FI.po vdr-1.7.17/po/fi_FI.po
--- vdr-1.7.16/po/fi_FI.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/fi_FI.po	2010-10-24 16:40:28.000000000 +0200
@@ -10,13 +10,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2007-08-15 15:52+0200\n"
 "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
-"Language-Team: Finnish\n"
+"Language-Team: Finnish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fi\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Virheellinen kanavavalinta ***"
diff -ruN vdr-1.7.16/po/fr_FR.po vdr-1.7.17/po/fr_FR.po
--- vdr-1.7.16/po/fr_FR.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/fr_FR.po	2010-10-24 16:40:28.000000000 +0200
@@ -13,13 +13,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-02-27 18:14+0100\n"
 "Last-Translator: Jean-Claude Repetto <jc@repetto.org>\n"
-"Language-Team: French\n"
+"Language-Team: French <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fr\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Chaîne invalide ! ***"
diff -ruN vdr-1.7.16/po/hr_HR.po vdr-1.7.17/po/hr_HR.po
--- vdr-1.7.16/po/hr_HR.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/hr_HR.po	2010-10-24 16:40:28.000000000 +0200
@@ -9,13 +9,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-03-17 19:00+0100\n"
 "Last-Translator: Adrian Caval <anrxc@sysphere.org>\n"
-"Language-Team: Croatian\n"
+"Language-Team: Croatian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: hr\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Neispravan Program ***"
diff -ruN vdr-1.7.16/po/hu_HU.po vdr-1.7.17/po/hu_HU.po
--- vdr-1.7.16/po/hu_HU.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/hu_HU.po	2010-10-24 16:40:28.000000000 +0200
@@ -10,13 +10,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2007-12-01 21:42+0200\n"
 "Last-Translator: István Füley <ifuley@tigercomp.ro>\n"
-"Language-Team: Hungarian\n"
+"Language-Team: Hungarian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: hu\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Érvénytelen csatorna ***"
diff -ruN vdr-1.7.16/po/it_IT.po vdr-1.7.17/po/it_IT.po
--- vdr-1.7.16/po/it_IT.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/it_IT.po	2010-10-24 16:40:28.000000000 +0200
@@ -11,13 +11,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2010-06-13 00:30+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
-"Language-Team: Italian\n"
+"Language-Team: Italian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: it\n"
 "X-Poedit-Language: Italian\n"
 "X-Poedit-Country: ITALY\n"
 "X-Poedit-SourceCharset: utf-8\n"
diff -ruN vdr-1.7.16/po/lt_LT.po vdr-1.7.17/po/lt_LT.po
--- vdr-1.7.16/po/lt_LT.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/lt_LT.po	2010-10-30 11:55:40.000000000 +0200
@@ -5,18 +5,19 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: VDR 1.7.12\n"
+"Project-Id-Version: VDR 1.7.16\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
 "POT-Creation-Date: 2010-06-06 12:52+0200\n"
-"PO-Revision-Date: 2010-02-22 18:05+0200\n"
+"PO-Revision-Date: 2010-10-30 11:55+0200\n"
 "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
-"Language-Team: Lithuanian\n"
+"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: lt\n"
 
 msgid "*** Invalid Channel ***"
-msgstr "*** Klaidingas kanalas ***"
+msgstr "*** Blogi kanalo nustatymai ***"
 
 msgid "Channel not available!"
 msgstr "Kanalas neegzistuoja!"
@@ -837,10 +838,10 @@
 msgstr "Ä®raÅ¡Å³ katalogai"
 
 msgid "Setup.OSD$Folders in timer menu"
-msgstr ""
+msgstr "Katalogai esantys laikmaÄ�iÅ³ meniu"
 
 msgid "Setup.OSD$Number keys for characters"
-msgstr ""
+msgstr "SkaiÄ�iÅ³ mygtukai simboliams"
 
 msgid "EPG"
 msgstr "Elektroninis programÅ³ gidas (EPG)"
@@ -893,10 +894,10 @@
 msgstr "pavadinimai ir PID'ai"
 
 msgid "add new channels"
-msgstr "pridÄ—ti naujÅ³ kanalÅ³"
+msgstr "pridÄ—ti naujus kanalus"
 
 msgid "add new transponders"
-msgstr "pridÄ—ti naujÅ³ siÅ³stuvÅ³"
+msgstr "pridÄ—ti naujus siÅ³stuvus"
 
 msgid "DVB"
 msgstr "DVB"
@@ -935,7 +936,7 @@
 msgstr "SubtitrÅ³ pozicionavimo nuokrypis"
 
 msgid "Setup.DVB$Subtitle foreground transparency"
-msgstr "SubtitrÅ³ priekinio vaizdo permatomumas"
+msgstr "SubtitrÅ³ fonto permatomumas"
 
 msgid "Setup.DVB$Subtitle background transparency"
 msgstr "SubtitrÅ³ fono permatomumas"
@@ -995,7 +996,7 @@
 msgstr "pristabdyti 'gyvÄ…' video srautÄ…"
 
 msgid "confirm"
-msgstr ""
+msgstr "patvirtinti"
 
 msgid "yes"
 msgstr "taip"
@@ -1052,16 +1053,16 @@
 msgstr "Suskaidyti koreguotus failus"
 
 msgid "Setup.Recording$Delete timeshift recording"
-msgstr ""
+msgstr "Trinti atidÄ—to grojimo Ä¯raÅ¡Ä…"
 
 msgid "Replay"
-msgstr "Pakartoti"
+msgstr "Pakartojimai"
 
 msgid "Setup.Replay$Multi speed mode"
-msgstr "Daugiagreitis rÄ™Å¾imas"
+msgstr "Prasukimo rÄ™Å¾imas"
 
 msgid "Setup.Replay$Show replay mode"
-msgstr "Rodyti atvaizdavimo rÄ™Å¾imÄ…"
+msgstr "Rodyti pakartojimo rÄ™Å¾imÄ…"
 
 msgid "Setup.Replay$Resume ID"
 msgstr "KÅ«rinio ID"
@@ -1172,7 +1173,7 @@
 msgstr "Sustabdomas 'gyvo' video grojimas..."
 
 msgid "Delete timeshift recording?"
-msgstr ""
+msgstr "Trinti atidÄ—to grojimo Ä¯raÅ¡Ä…?"
 
 #. TRANSLATORS: note the trailing blank!
 msgid "Jump: "
diff -ruN vdr-1.7.16/po/mk_MK.po vdr-1.7.17/po/mk_MK.po
--- vdr-1.7.16/po/mk_MK.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/mk_MK.po	2010-10-24 16:40:28.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR-1.7.14\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2010-03-11 00:54+0100\n"
 "Last-Translator: Dimitar Petrovski <dimeptr@gmail.com>\n"
 "Language-Team: Macedonian <en@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: mk\n"
 "X-Generator: KBabel 1.11.4\n"
 
 msgid "*** Invalid Channel ***"
diff -ruN vdr-1.7.16/po/nl_NL.po vdr-1.7.17/po/nl_NL.po
--- vdr-1.7.16/po/nl_NL.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/nl_NL.po	2010-10-24 16:40:28.000000000 +0200
@@ -11,13 +11,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-02-26 17:20+0100\n"
 "Last-Translator: Johan Schuring <johan.schuring@vetteblei.nl>\n"
-"Language-Team: Dutch\n"
+"Language-Team: Dutch <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: nl\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Ongeldig kanaal ***"
diff -ruN vdr-1.7.16/po/nn_NO.po vdr-1.7.17/po/nn_NO.po
--- vdr-1.7.16/po/nn_NO.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/nn_NO.po	2010-10-24 16:40:28.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Truls Slevigen <truls@slevigen.no>\n"
-"Language-Team: Norwegian\n"
+"Language-Team: Norwegian Nynorsk <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: nn\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Ugyldig Kanal! ***"
diff -ruN vdr-1.7.16/po/pl_PL.po vdr-1.7.17/po/pl_PL.po
--- vdr-1.7.16/po/pl_PL.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/pl_PL.po	2010-10-24 16:40:28.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-03-09 12:59+0100\n"
 "Last-Translator: Michael Rakowski <mrak@gmx.de>\n"
-"Language-Team:  Polish\n"
+"Language-Team: Polish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: pl\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Niepoprawny kana³ ***"
diff -ruN vdr-1.7.16/po/pt_PT.po vdr-1.7.17/po/pt_PT.po
--- vdr-1.7.16/po/pt_PT.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/pt_PT.po	2010-10-24 16:40:28.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.15\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2010-03-28 22:49+0100\n"
 "Last-Translator: Cris Silva <hudokkow@gmail.com>\n"
-"Language-Team: Portuguese\n"
+"Language-Team: Portuguese <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: pt\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Canal inválido ***"
diff -ruN vdr-1.7.16/po/ro_RO.po vdr-1.7.17/po/ro_RO.po
--- vdr-1.7.16/po/ro_RO.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/ro_RO.po	2011-03-12 11:30:13.000000000 +0100
@@ -2,19 +2,20 @@
 # Copyright (C) 2008 Klaus Schmidinger <kls@tvdr.de>
 # This file is distributed under the same license as the VDR package.
 # Paul Lacatus <paul@campina.iiruc.ro>, 2002
-# Lucian Muresan <lucianm@users.sourceforge.net>, 2004, 2005, 2006, 2008, 2010
+# Lucian Muresan <lucianm@users.sourceforge.net>, 2004, 2005, 2006, 2008, 2010, 2011
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: VDR 1.7.12\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
-"PO-Revision-Date: 2010-02-11 13:38+0100\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
+"PO-Revision-Date: 2011-03-10 23:52+0100\n"
 "Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n"
-"Language-Team: Romanian\n"
+"Language-Team: Romanian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: ro\n"
 "X-Poedit-Language: Romanian\n"
 "X-Poedit-Country: ROMANIA\n"
 
@@ -840,10 +841,10 @@
 msgstr "Directoare înregistrãri"
 
 msgid "Setup.OSD$Folders in timer menu"
-msgstr ""
+msgstr "Directoare în meniul de timer-e"
 
 msgid "Setup.OSD$Number keys for characters"
-msgstr ""
+msgstr "Caractere pe tastele numerice"
 
 msgid "EPG"
 msgstr "EPG"
@@ -998,7 +999,7 @@
 msgstr "înregistreazã emisiunea"
 
 msgid "confirm"
-msgstr ""
+msgstr "confirmare"
 
 msgid "yes"
 msgstr "da"
@@ -1055,7 +1056,7 @@
 msgstr "Separare fiºiere montate"
 
 msgid "Setup.Recording$Delete timeshift recording"
-msgstr ""
+msgstr "ªterge înregistrarea pentru vizionare decalatã"
 
 msgid "Replay"
 msgstr "Redare"
@@ -1175,7 +1176,7 @@
 msgstr "Trec în pauzã emisiunea transmisã..."
 
 msgid "Delete timeshift recording?"
-msgstr ""
+msgstr "ªterg înregistrarea pentru vizionare decalatã?"
 
 #. TRANSLATORS: note the trailing blank!
 msgid "Jump: "
diff -ruN vdr-1.7.16/po/ru_RU.po vdr-1.7.17/po/ru_RU.po
--- vdr-1.7.16/po/ru_RU.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/ru_RU.po	2010-10-24 16:40:28.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-12-15 14:37+0100\n"
 "Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
-"Language-Team: Russian\n"
+"Language-Team: Russian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-5\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: ru\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** ½ÕßàÐÒØÛìÝëÙ ÚÐÝÐÛ ***"
diff -ruN vdr-1.7.16/po/sk_SK.po vdr-1.7.17/po/sk_SK.po
--- vdr-1.7.16/po/sk_SK.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/sk_SK.po	2011-02-20 16:43:24.000000000 +0100
@@ -1,20 +1,20 @@
 # VDR language source file.
 # Copyright (C) 2008 Klaus Schmidinger <kls@tvdr.de>
 # This file is distributed under the same license as the VDR package.
-# Vladimír Bárta <vladimir.barta@k2atmitec.cz>, 2006, 2008
-# Jiøí Dobrý <jdobry@centrum.cz>, 2008
+# Milan Hrala <hrala.milan@gmail.com>, 2011
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: VDR 1.6.0\n"
+"Project-Id-Version: VDR 1.7.16\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
 "POT-Creation-Date: 2010-06-06 12:52+0200\n"
-"PO-Revision-Date: 2009-09-30 12:50+0100\n"
+"PO-Revision-Date: 2011-02-15 16:29+0100\n"
 "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
-"Language-Team: Slovak\n"
+"Language-Team: Slovak <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: sk\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Neplatný kanál ***"
@@ -71,251 +71,251 @@
 msgstr "Hierarchia"
 
 msgid "Rolloff"
-msgstr ""
+msgstr "Rolloff"
 
 msgid "Starting EPG scan"
 msgstr "Zaèína prehµadáva» EPG"
 
 msgid "Content$Movie/Drama"
-msgstr ""
+msgstr "Film/Dráma"
 
 msgid "Content$Detective/Thriller"
-msgstr ""
+msgstr "Detektívka/Triler"
 
 msgid "Content$Adventure/Western/War"
-msgstr ""
+msgstr "Dobrodru¾ný/Western/Vojnový"
 
 msgid "Content$Science Fiction/Fantasy/Horror"
-msgstr ""
+msgstr "Vedecko fantastický/Fantastický/Horor"
 
 msgid "Content$Comedy"
-msgstr ""
+msgstr "Komédia"
 
 msgid "Content$Soap/Melodrama/Folkloric"
-msgstr ""
+msgstr "Soap epera/Melodráma/Folklór"
 
 msgid "Content$Romance"
-msgstr ""
+msgstr "Romantický"
 
 msgid "Content$Serious/Classical/Religious/Historical Movie/Drama"
-msgstr ""
+msgstr "Skutoèný/Klasický/Nábo¾ensky/Historický film/Dráma"
 
 msgid "Content$Adult Movie/Drama"
-msgstr ""
+msgstr "Film pre dospelých/Dráma"
 
 msgid "Content$News/Current Affairs"
-msgstr ""
+msgstr "Správy/Aktuálne udalosti"
 
 msgid "Content$News/Weather Report"
-msgstr ""
+msgstr "Správy/Predpoveï poèasia"
 
 msgid "Content$News Magazine"
-msgstr ""
+msgstr "Spravodajský magazín"
 
 msgid "Content$Documentary"
-msgstr ""
+msgstr "Dokumentárny"
 
 msgid "Content$Discussion/Inverview/Debate"
-msgstr ""
+msgstr "Diskusia/Rozhovor/debata"
 
 msgid "Content$Show/Game Show"
-msgstr ""
+msgstr "©ou/Zábavné hry"
 
 msgid "Content$Game Show/Quiz/Contest"
-msgstr ""
+msgstr "Zábavná hra/vedemostná/sú»a¾ná"
 
 msgid "Content$Variety Show"
-msgstr ""
+msgstr "varieté"
 
 msgid "Content$Talk Show"
-msgstr ""
+msgstr "Televízna relácia"
 
 msgid "Content$Sports"
-msgstr ""
+msgstr "©port"
 
 msgid "Content$Special Event"
-msgstr ""
+msgstr "Zvlá¹tne udalosti"
 
 msgid "Content$Sport Magazine"
-msgstr ""
+msgstr "©portový magazín"
 
 msgid "Content$Football/Soccer"
-msgstr ""
+msgstr "Fudbal"
 
 msgid "Content$Tennis/Squash"
-msgstr ""
+msgstr "Tenis/Squash"
 
 msgid "Content$Team Sports"
-msgstr ""
+msgstr "Týmové ¹porty"
 
 msgid "Content$Athletics"
-msgstr ""
+msgstr "Atletika"
 
 msgid "Content$Motor Sport"
-msgstr ""
+msgstr "Motorizmus"
 
 msgid "Content$Water Sport"
-msgstr ""
+msgstr "Vodné ¹porty"
 
 msgid "Content$Winter Sports"
-msgstr ""
+msgstr "Zimné ¹porty"
 
 msgid "Content$Equestrian"
-msgstr ""
+msgstr "Jazdecké ¹porty"
 
 msgid "Content$Martial Sports"
-msgstr ""
+msgstr "Bojvé ¹porty"
 
 msgid "Content$Children's/Youth Programme"
-msgstr ""
+msgstr "Pre deti/program pre mláde¾"
 
 msgid "Content$Pre-school Children's Programme"
-msgstr ""
+msgstr "Program pre pred¹kolské deti"
 
 msgid "Content$Entertainment Programme for 6 to 14"
-msgstr ""
+msgstr "Zábavný program od 6 do 14 rokov"
 
 msgid "Content$Entertainment Programme for 10 to 16"
-msgstr ""
+msgstr "Zábavný program od 10 do 16 rokov"
 
 msgid "Content$Informational/Educational/School Programme"
-msgstr ""
+msgstr "Informaèný/Výchovný/©kolský program"
 
 msgid "Content$Cartoons/Puppets"
-msgstr ""
+msgstr "Kreslený/Bábkový"
 
 msgid "Content$Music/Ballet/Dance"
-msgstr ""
+msgstr "Hudba/Balet/Tanec"
 
 msgid "Content$Rock/Pop"
-msgstr ""
+msgstr "Rock/Pop"
 
 msgid "Content$Serious/Classical Music"
-msgstr ""
+msgstr "Vá¾na/Klasická hudba"
 
 msgid "Content$Folk/Tradional Music"
-msgstr ""
+msgstr "¥udová/Tradièná Hudba"
 
 msgid "Content$Jazz"
-msgstr ""
+msgstr "Jazz"
 
 msgid "Content$Musical/Opera"
-msgstr ""
+msgstr "Muzikál/Opera"
 
 msgid "Content$Ballet"
-msgstr ""
+msgstr "Balet"
 
 msgid "Content$Arts/Culture"
-msgstr ""
+msgstr "Umenie/Kultúra"
 
 msgid "Content$Performing Arts"
-msgstr ""
+msgstr "Herecké umenie"
 
 msgid "Content$Fine Arts"
-msgstr ""
+msgstr "Výtvarné umenie"
 
 msgid "Content$Religion"
-msgstr ""
+msgstr "Nábo¾enstvo"
 
 msgid "Content$Popular Culture/Traditional Arts"
-msgstr ""
+msgstr "Populárna kultúra/Tradièné umenie"
 
 msgid "Content$Literature"
-msgstr ""
+msgstr "Literatúra"
 
 msgid "Content$Film/Cinema"
-msgstr ""
+msgstr "Film/Kino"
 
 msgid "Content$Experimental Film/Video"
-msgstr ""
+msgstr "Experimentálny film/Video"
 
 msgid "Content$Broadcasting/Press"
-msgstr ""
+msgstr "Rozhlas/Tlaè"
 
 msgid "Content$New Media"
-msgstr ""
+msgstr "Nové média"
 
 msgid "Content$Arts/Culture Magazine"
-msgstr ""
+msgstr "Umenie/Kultúrny magazín"
 
 msgid "Content$Fashion"
-msgstr ""
+msgstr "Móda"
 
 msgid "Content$Social/Political/Economics"
-msgstr ""
+msgstr "Sociálny/Politický/Ekonomický"
 
 msgid "Content$Magazine/Report/Documentary"
-msgstr ""
+msgstr "Magazín/Reportá¾e/"
 
 msgid "Content$Economics/Social Advisory"
-msgstr ""
+msgstr "Ekonomika/Sociálne poradenstvo"
 
 msgid "Content$Remarkable People"
-msgstr ""
+msgstr "Významné osobnosti"
 
 msgid "Content$Education/Science/Factual"
-msgstr ""
+msgstr "Vzdelávanie/Veda/Fakta"
 
 msgid "Content$Nature/Animals/Environment"
-msgstr ""
+msgstr "Príroda/Zvieratá/®ivotné prostredie"
 
 msgid "Content$Technology/Natural Sciences"
-msgstr ""
+msgstr "Technológia/Prírodné vedy"
 
 msgid "Content$Medicine/Physiology/Psychology"
-msgstr ""
+msgstr "Medicína/Filozofia/Psychológia"
 
 msgid "Content$Foreign Countries/Expeditions"
-msgstr ""
+msgstr "Zahranièné krajiny/Expediícia"
 
 msgid "Content$Social/Spiritual Sciences"
-msgstr ""
+msgstr "sociálne/duchovné vedy"
 
 msgid "Content$Further Education"
-msgstr ""
+msgstr "ïal¹ie vzdelávanie"
 
 msgid "Content$Languages"
-msgstr ""
+msgstr "Jazyky"
 
 msgid "Content$Leisure/Hobbies"
-msgstr ""
+msgstr "vólny èas"
 
 msgid "Content$Tourism/Travel"
-msgstr ""
+msgstr "Turistika/Cestovanie"
 
 msgid "Content$Handicraft"
-msgstr ""
+msgstr "Remeslá"
 
 msgid "Content$Motoring"
-msgstr ""
+msgstr "Motorizmus"
 
 msgid "Content$Fitness & Health"
-msgstr ""
+msgstr "Fitness a zdravie"
 
 msgid "Content$Cooking"
-msgstr ""
+msgstr "Varenie"
 
 msgid "Content$Advertisement/Shopping"
-msgstr ""
+msgstr "Reklama/Predaj"
 
 msgid "Content$Gardening"
-msgstr ""
+msgstr "Záhradkárstvo"
 
 msgid "Content$Original Language"
-msgstr ""
+msgstr "Pôvodný jazyk"
 
 msgid "Content$Black & White"
-msgstr ""
+msgstr "Èiernobiely"
 
 msgid "Content$Unpublished"
-msgstr ""
+msgstr "Nepublikované"
 
 msgid "Content$Live Broadcast"
-msgstr ""
+msgstr "®ivé vysielanie"
 
 #, c-format
 msgid "ParentalRating$from %d"
-msgstr ""
+msgstr "od %d"
 
 msgid "No title"
 msgstr "Bez názvu"
@@ -326,7 +326,7 @@
 
 #. TRANSLATORS: The 3-letter code of the language
 msgid "LanguageCode$eng"
-msgstr "sk"
+msgstr "slv"
 
 msgid "Phase 1: Detecting RC code type"
 msgstr "Fáza 1: Detekcia typu kódu"
@@ -348,19 +348,19 @@
 msgstr "Stlaète klávesu pre '%s'"
 
 msgid "Press 'Up' to confirm"
-msgstr "Stlaète 'Hore' pre potvrdenie"
+msgstr "Pre potvrdenie stlaète klávesu 'Hore'"
 
 msgid "Press 'Down' to continue"
-msgstr "Stlaète 'Dole' pre pokraèovanie"
+msgstr "Pokraèujete stlaèením klávesy 'Dole' "
 
 msgid "(press 'Up' to go back)"
-msgstr "(stlaète 'hore' pre návrat)"
+msgstr "(Vrátite sa stlaèením klávesy 'hore')"
 
 msgid "(press 'Down' to end key definition)"
-msgstr "(stlaète 'dole' pre skonèenie)"
+msgstr "(Definovanie tlaèítok ukonèíte stlaèením klávesy 'dole')"
 
 msgid "(press 'Menu' to skip this key)"
-msgstr "(stlaète 'Menu' pre preskoèenie definície klávesy)"
+msgstr "(stlaèením 'Menu' preskoèíte definíciu klávesy)"
 
 msgid "Learning Remote Control Keys"
 msgstr "Urèenie kódu diaµkového ovládania"
@@ -369,7 +369,7 @@
 msgstr "Fáza 3: Ulo¾enie kódu"
 
 msgid "Press 'Up' to save, 'Down' to cancel"
-msgstr "Stlaète 'hore' pre ulo¾enie, 'Dole' pre zru¹enie"
+msgstr "Stlaèením 'hore' ulo¾íte, 'Dole' zru¹íte"
 
 msgid "Key$Up"
 msgstr "Hore"
@@ -468,7 +468,7 @@
 msgstr "Plány nahrávania"
 
 msgid "Key$Recordings"
-msgstr "Záznamy"
+msgstr "Nahrávky"
 
 msgid "Key$Setup"
 msgstr "Nastavenie"
@@ -588,29 +588,29 @@
 msgstr "Odstráni» kanál?"
 
 msgid "Edit folder"
-msgstr ""
+msgstr "Upravi» zlo¾ku"
 
 msgid "New folder"
-msgstr ""
+msgstr "Nový zlo¾ka"
 
 msgid "Sub folder"
-msgstr ""
+msgstr "Pod zlo¾ka"
 
 msgid "Folder name already exists!"
-msgstr ""
+msgstr "Názov zlo¾ky u¾ existuje!"
 
 #, c-format
 msgid "Folder name must not contain '%c'!"
-msgstr ""
+msgstr "Názov zlo¾ky nesmie obsahova» '%c'!"
 
 msgid "Button$Select"
-msgstr ""
+msgstr "Vybra»"
 
 msgid "Delete folder and all sub folders?"
-msgstr ""
+msgstr "Vymaza» zlo¾ku a v¹etky pod zlo¾ky?"
 
 msgid "Delete folder?"
-msgstr ""
+msgstr "Vymaza» zlo¾ku?"
 
 msgid "Edit timer"
 msgstr "Úprava plánu nahrávania"
@@ -643,13 +643,13 @@
 msgstr "Súbor"
 
 msgid "Button$Folder"
-msgstr ""
+msgstr "Zlo¾ka"
 
 msgid "First day"
 msgstr "Prvý deò"
 
 msgid "Select folder"
-msgstr ""
+msgstr "Vybra» zlo¾ku"
 
 msgid "Timers"
 msgstr "Plány nahrávania"
@@ -679,10 +679,10 @@
 msgstr "Prepnú»"
 
 msgid "What's on now?"
-msgstr "Aktuálny program"
+msgstr "Èo ide?"
 
 msgid "What's on next?"
-msgstr "Následujúci program"
+msgstr "Èo nasleduje?"
 
 msgid "Button$Next"
 msgstr "Ïalej"
@@ -718,7 +718,7 @@
 msgstr "CAM neodpovedá!"
 
 msgid "Recording info"
-msgstr "Podrobnosti záznamu"
+msgstr "Podrobnosti nahrávky"
 
 msgid "Button$Play"
 msgstr "Prehra»"
@@ -727,7 +727,7 @@
 msgstr "Na zaèiatok"
 
 msgid "Recordings"
-msgstr "Záznamy"
+msgstr "Nahrávky"
 
 msgid "Button$Open"
 msgstr "Otvori»"
@@ -736,13 +736,13 @@
 msgstr "Príkazy"
 
 msgid "Error while accessing recording!"
-msgstr "Chyba pri prístupe k záznamom!"
+msgstr "Chyba pri prístupe k nahrávkam!"
 
 msgid "Delete recording?"
-msgstr "Zmaza» záznam?"
+msgstr "Zmaza» nahrávku?"
 
 msgid "Error while deleting recording!"
-msgstr "Pri vymazávaní záznamu pri¹lo k chybe!"
+msgstr "Pri vymazávaní nahrávky pri¹lo k chybe!"
 
 msgid "Recording commands"
 msgstr "Príkazy nahrávania"
@@ -796,7 +796,7 @@
 msgstr "Malé písmo"
 
 msgid "Setup.OSD$Fixed font"
-msgstr "Urèené písmo"
+msgstr "Fixné písmo"
 
 msgid "Setup.OSD$Default font size (%)"
 msgstr "Veµkos» predvoleného písma (%)"
@@ -805,7 +805,7 @@
 msgstr "Veµkos» malého písma (%)"
 
 msgid "Setup.OSD$Fixed font size (%)"
-msgstr "Veµkos» urèeného písma (%)"
+msgstr "Veµkos» fixného písma (%)"
 
 msgid "Setup.OSD$Channel info position"
 msgstr "Pozícia informácií o kanále"
@@ -835,13 +835,13 @@
 msgstr "Klávesa Menu zaviera"
 
 msgid "Setup.OSD$Recording directories"
-msgstr "Zoznam záznamov"
+msgstr "Zoznam nahrávok"
 
 msgid "Setup.OSD$Folders in timer menu"
-msgstr ""
+msgstr "Zlo¾ky v menu plánovaèa"
 
 msgid "Setup.OSD$Number keys for characters"
-msgstr ""
+msgstr "Èíselné tlaèidlá pre znaky"
 
 msgid "EPG"
 msgstr "EPG"
@@ -957,7 +957,7 @@
 msgstr "Horná frekvencia LNB (MHz)"
 
 msgid "CAM reset"
-msgstr "Reset CAMu"
+msgstr "Resetnutie CAMu"
 
 msgid "CAM present"
 msgstr "CAM prítomný"
@@ -972,7 +972,7 @@
 msgstr "Menu"
 
 msgid "Button$Reset"
-msgstr "Reset"
+msgstr "Resetnú»"
 
 msgid "Opening CAM menu..."
 msgstr "Otvára sa menu CAM..."
@@ -990,13 +990,13 @@
 msgstr "nepreru¹ova» ¾ivé vysielanie"
 
 msgid "confirm pause live video"
-msgstr "Potrdi» preru¹enie ¾ivého vysielania"
+msgstr "potvrdi» preru¹enie ¾ivého vysielania"
 
 msgid "pause live video"
-msgstr "Preru¹i» ¾ivé vysielanie"
+msgstr "preru¹i» ¾ivé vysielanie"
 
 msgid "confirm"
-msgstr ""
+msgstr "overi»"
 
 msgid "yes"
 msgstr "áno"
@@ -1020,7 +1020,7 @@
 msgstr "Predvolená ¾ivotnos»"
 
 msgid "Setup.Recording$Pause key handling"
-msgstr ""
+msgstr "Chovanie klávesy pozastavenia"
 
 msgid "Setup.Recording$Pause priority"
 msgstr "Priorita preru¹enia"
@@ -1053,7 +1053,7 @@
 msgstr "Deli» upravované súbory"
 
 msgid "Setup.Recording$Delete timeshift recording"
-msgstr ""
+msgstr "Vymaza» timeshift záznamy"
 
 msgid "Replay"
 msgstr "Prehrávanie"
@@ -1095,7 +1095,7 @@
 msgstr "Hlasitos» po spustení"
 
 msgid "Setup.Miscellaneous$Channels wrap"
-msgstr ""
+msgstr "Prepína» z prvého na posledný a opaène"
 
 msgid "Setup.Miscellaneous$Emergency exit"
 msgstr "Núdzové ukonèenie"
@@ -1113,7 +1113,7 @@
 msgstr "Re¹tart"
 
 msgid "Really restart?"
-msgstr "Opravdu re¹tartova»?"
+msgstr "Naozaj re¹tartova»?"
 
 #. TRANSLATORS: note the leading and trailing blanks!
 msgid " Stop recording "
@@ -1173,14 +1173,14 @@
 msgstr "Preru¹uje sa be¾iaci program ..."
 
 msgid "Delete timeshift recording?"
-msgstr ""
+msgstr "Vymaza» timeshift záznamy?"
 
 #. TRANSLATORS: note the trailing blank!
 msgid "Jump: "
 msgstr "Skok: "
 
 msgid "No editing marks defined!"
-msgstr "Nie sú urèené upravované znaèky!"
+msgstr "Nie sú urèené znaèky úprav!"
 
 msgid "Can't start editing process!"
 msgstr "Nemô¾e zaèa» spracovanie úprav!"
@@ -1219,10 +1219,10 @@
 msgstr "Za chvíµku bude plný disk!"
 
 msgid "Regenerating index file"
-msgstr ""
+msgstr "Regeneraèný indexový súbor"
 
 msgid "Index file regeneration complete"
-msgstr ""
+msgstr "Regenerácia indexového súboru hotová"
 
 msgid "Can't shutdown - option '-s' not given!"
 msgstr "Vypnutie nie je mo¾né - chýba voµba '-s'!"
@@ -1261,11 +1261,11 @@
 msgstr "Klasické VDR"
 
 msgid "ST:TNG Panels"
-msgstr "ST:TNG konzola"
+msgstr "ST:TNG panely"
 
 #. TRANSLATORS: the first character of each weekday, beginning with monday
 msgid "MTWTFSS"
-msgstr "PÚSÈPSN"
+msgstr "PUS©PSN"
 
 #. TRANSLATORS: abbreviated weekdays, beginning with monday (must all be 3 letters!)
 msgid "MonTueWedThuFriSatSun"
@@ -1302,7 +1302,7 @@
 msgstr "Zaèalo nahrávanie"
 
 msgid "VDR will shut down later - press Power to force"
-msgstr "Vypnutie VDR bude odlo¾ené - vypnete klávesou Power"
+msgstr "Vypnutie VDR bude odlo¾ené - platnos» potvrdte klávesou Power"
 
 msgid "Press any key to cancel shutdown"
 msgstr "Ktorákoµvek klávesa zru¹í vypnutie"
diff -ruN vdr-1.7.16/po/sl_SI.po vdr-1.7.17/po/sl_SI.po
--- vdr-1.7.16/po/sl_SI.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/sl_SI.po	2010-10-24 16:40:28.000000000 +0200
@@ -8,13 +8,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-02-28 19:44+0100\n"
 "Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n"
-"Language-Team: Slovenian\n"
+"Language-Team: Slovenian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-2\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: sl\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Neznan kanal ***"
diff -ruN vdr-1.7.16/po/sr_SR.po vdr-1.7.17/po/sr_SR.po
--- vdr-1.7.16/po/sr_SR.po	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.7.17/po/sr_SR.po	2011-02-20 19:03:05.000000000 +0100
@@ -0,0 +1,1351 @@
+# VDR language source file.
+# Copyright (C) 2008 Klaus Schmidinger <kls@tvdr.de>
+# This file is distributed under the same license as the VDR package.
+# Milan Cvijanoviæ <elcom_cvijo@hotmail.com>, 2010
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: VDR 1.7.1\n"
+"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+"POT-Creation-Date: 2011-02-20 19:02+0100\n"
+"PO-Revision-Date: 2011-01-09 15:57+0100\n"
+"Last-Translator: Milan Cvijanoviæ <elcom_cvijo@hotmail.com>\n"
+"Language-Team: Serbian <vdr@linuxtv.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: Serbian-latin\n"
+
+msgid "*** Invalid Channel ***"
+msgstr "*** Neispravan Kanal ***"
+
+msgid "Channel not available!"
+msgstr "Kanal nije dostupan!"
+
+msgid "Can't start Transfer Mode!"
+msgstr "Nemoguæe zapoèeti Prenos!!"
+
+msgid "off"
+msgstr "iskljuèi"
+
+#, fuzzy
+msgid "on"
+msgstr "na"
+
+msgid "auto"
+msgstr "automatski"
+
+msgid "none"
+msgstr "ni¹ta"
+
+msgid "Polarization"
+msgstr "Polarizacija"
+
+msgid "System"
+msgstr "Sistem"
+
+msgid "Srate"
+msgstr "Srate"
+
+msgid "Inversion"
+msgstr "Inverzija"
+
+msgid "CoderateH"
+msgstr "CoderateH"
+
+msgid "CoderateL"
+msgstr "CoderateL"
+
+msgid "Modulation"
+msgstr "Modulacija"
+
+msgid "Bandwidth"
+msgstr "Propusnost"
+
+msgid "Transmission"
+msgstr "Prenos"
+
+msgid "Guard"
+msgstr "Za¹tita"
+
+msgid "Hierarchy"
+msgstr "Hijerarhija"
+
+msgid "Rolloff"
+msgstr ""
+
+msgid "Starting EPG scan"
+msgstr "Poèinjem EPG pretragu"
+
+msgid "Content$Movie/Drama"
+msgstr "Film/Drama"
+
+msgid "Content$Detective/Thriller"
+msgstr "Detektivski/Triler"
+
+msgid "Content$Adventure/Western/War"
+msgstr "Avantura/Vestern/Ratni"
+
+msgid "Content$Science Fiction/Fantasy/Horror"
+msgstr "Nauèno Fantastièni/Fantazija/Horor"
+
+msgid "Content$Comedy"
+msgstr "Komedija"
+
+msgid "Content$Soap/Melodrama/Folkloric"
+msgstr "Sapunica/Melodrama/Folklor"
+
+msgid "Content$Romance"
+msgstr "Romansa"
+
+msgid "Content$Serious/Classical/Religious/Historical Movie/Drama"
+msgstr "Ozbiljan/Klasièni/Religiozan/Istorijski Film/Drama"
+
+msgid "Content$Adult Movie/Drama"
+msgstr "Za odrasle Film/Drama"
+
+msgid "Content$News/Current Affairs"
+msgstr "Vesti/Trenutni poslovi"
+
+msgid "Content$News/Weather Report"
+msgstr "Vesti/Vremenski izvje¹taj"
+
+msgid "Content$News Magazine"
+msgstr "Magazin Vesti"
+
+msgid "Content$Documentary"
+msgstr "Dokumentarni"
+
+msgid "Content$Discussion/Inverview/Debate"
+msgstr "Diskusije/Intervjui/Debate"
+
+msgid "Content$Show/Game Show"
+msgstr "Zabavni/Igre Zabavne"
+
+msgid "Content$Game Show/Quiz/Contest"
+msgstr "Igre Zabavne/Kviz/Takmièenja"
+
+msgid "Content$Variety Show"
+msgstr "Cirkus"
+
+msgid "Content$Talk Show"
+msgstr "Talk ¹ou"
+
+msgid "Content$Sports"
+msgstr "Sport"
+
+msgid "Content$Special Event"
+msgstr "Specijalne emisije"
+
+msgid "Content$Sport Magazine"
+msgstr "Sportski Magazin"
+
+msgid "Content$Football/Soccer"
+msgstr "Futball/Igraè"
+
+msgid "Content$Tennis/Squash"
+msgstr "Tenis/Skvo¹"
+
+msgid "Content$Team Sports"
+msgstr "Timski Sport"
+
+msgid "Content$Athletics"
+msgstr "Atletika"
+
+msgid "Content$Motor Sport"
+msgstr "Moto Sport"
+
+msgid "Content$Water Sport"
+msgstr "Sportovi na vodi"
+
+msgid "Content$Winter Sports"
+msgstr "Zimski Sportovi"
+
+msgid "Content$Equestrian"
+msgstr "Jahaèki"
+
+msgid "Content$Martial Sports"
+msgstr "Vojni Sportovi"
+
+msgid "Content$Children's/Youth Programme"
+msgstr "Deèiji/Program za Mlade"
+
+msgid "Content$Pre-school Children's Programme"
+msgstr "Pred¹kolski deèiji program"
+
+msgid "Content$Entertainment Programme for 6 to 14"
+msgstr "Zabavni program za uzrast od 6 do 14"
+
+msgid "Content$Entertainment Programme for 10 to 16"
+msgstr "Zabavni program za uzrast od 10 do 16"
+
+msgid "Content$Informational/Educational/School Programme"
+msgstr "Informativni/Edukacioni/©kolski Program"
+
+msgid "Content$Cartoons/Puppets"
+msgstr "Crtiæi/Lutkarski"
+
+msgid "Content$Music/Ballet/Dance"
+msgstr "Muzièki/Balet/Ples"
+
+msgid "Content$Rock/Pop"
+msgstr "Rok/Pop"
+
+msgid "Content$Serious/Classical Music"
+msgstr "Ozbiljna/Klasièna Muzika"
+
+msgid "Content$Folk/Tradional Music"
+msgstr "Narodna/Izvorna Muzika"
+
+msgid "Content$Jazz"
+msgstr "D¾ez"
+
+msgid "Content$Musical/Opera"
+msgstr "Mjuzikli/Opera"
+
+msgid "Content$Ballet"
+msgstr "Balet"
+
+msgid "Content$Arts/Culture"
+msgstr "Umetnost/Kultura"
+
+msgid "Content$Performing Arts"
+msgstr ""
+
+msgid "Content$Fine Arts"
+msgstr ""
+
+msgid "Content$Religion"
+msgstr "Religija"
+
+msgid "Content$Popular Culture/Traditional Arts"
+msgstr "Moderna umetnost/Tradicionalna umetnost"
+
+msgid "Content$Literature"
+msgstr "Literarni"
+
+msgid "Content$Film/Cinema"
+msgstr "Film/Kino"
+
+msgid "Content$Experimental Film/Video"
+msgstr ""
+
+msgid "Content$Broadcasting/Press"
+msgstr ""
+
+msgid "Content$New Media"
+msgstr ""
+
+msgid "Content$Arts/Culture Magazine"
+msgstr ""
+
+msgid "Content$Fashion"
+msgstr "Sadr¾aj$Moda"
+
+msgid "Content$Social/Political/Economics"
+msgstr "Sadr¾aj$Socijalni/Politièki/Ekonomski"
+
+msgid "Content$Magazine/Report/Documentary"
+msgstr "Sadr¾aj$Magazin/Reporta¾a/Dokumentarni"
+
+msgid "Content$Economics/Social Advisory"
+msgstr ""
+
+msgid "Content$Remarkable People"
+msgstr "Neverovatni Ljudi"
+
+msgid "Content$Education/Science/Factual"
+msgstr ""
+
+msgid "Content$Nature/Animals/Environment"
+msgstr ""
+
+msgid "Content$Technology/Natural Sciences"
+msgstr ""
+
+msgid "Content$Medicine/Physiology/Psychology"
+msgstr ""
+
+msgid "Content$Foreign Countries/Expeditions"
+msgstr ""
+
+msgid "Content$Social/Spiritual Sciences"
+msgstr ""
+
+msgid "Content$Further Education"
+msgstr ""
+
+#, fuzzy
+msgid "Content$Languages"
+msgstr "Jezik"
+
+msgid "Content$Leisure/Hobbies"
+msgstr ""
+
+msgid "Content$Tourism/Travel"
+msgstr ""
+
+msgid "Content$Handicraft"
+msgstr ""
+
+msgid "Content$Motoring"
+msgstr ""
+
+msgid "Content$Fitness & Health"
+msgstr ""
+
+msgid "Content$Cooking"
+msgstr ""
+
+msgid "Content$Advertisement/Shopping"
+msgstr ""
+
+msgid "Content$Gardening"
+msgstr ""
+
+msgid "Content$Original Language"
+msgstr ""
+
+msgid "Content$Black & White"
+msgstr "Crno i Belo"
+
+msgid "Content$Unpublished"
+msgstr "Neobjavljeno"
+
+msgid "Content$Live Broadcast"
+msgstr "Prenos U¾ivo"
+
+#, c-format
+msgid "ParentalRating$from %d"
+msgstr "Roditeljska ocena$od %d"
+
+msgid "No title"
+msgstr "Nema naslova"
+
+#. TRANSLATORS: The name of the language, as written natively
+msgid "LanguageName$English"
+msgstr "Srpski"
+
+#. TRANSLATORS: The 3-letter code of the language
+msgid "LanguageCode$eng"
+msgstr "scc"
+
+msgid "Phase 1: Detecting RC code type"
+msgstr "Faza 1: detekcija koda daljinskog upravljaèa"
+
+msgid "Press any key on the RC unit"
+msgstr "Pritisnite jedan taster na daljinskom upravljaèu"
+
+msgid "RC code detected!"
+msgstr "Kod daljinskog upravljaèa je prepoznat!"
+
+msgid "Do not press any key..."
+msgstr "Ne pritiskaj nijedan taster..."
+
+msgid "Phase 2: Learning specific key codes"
+msgstr "Faza 2: Uèenje posebnih kodova"
+
+#, c-format
+msgid "Press key for '%s'"
+msgstr "Pritisnite taster za '%s'"
+
+msgid "Press 'Up' to confirm"
+msgstr "Pritisni 'Gore' za prihvatanje"
+
+msgid "Press 'Down' to continue"
+msgstr "Pritisni 'Dole' za nastavak"
+
+msgid "(press 'Up' to go back)"
+msgstr "(pritisni 'Gore' za nazad)"
+
+msgid "(press 'Down' to end key definition)"
+msgstr "(pritisni 'Dole' za kraj)"
+
+msgid "(press 'Menu' to skip this key)"
+msgstr "pritisni 'Meni' da preskoèite ovu tipku"
+
+msgid "Learning Remote Control Keys"
+msgstr "Uèenje rasporeda tastera daljinskog upravljaèa"
+
+msgid "Phase 3: Saving key codes"
+msgstr "Faza 3: Snimanje kodova tastera"
+
+msgid "Press 'Up' to save, 'Down' to cancel"
+msgstr "'Gore' za snimi, 'Dole' za prekid"
+
+msgid "Key$Up"
+msgstr "Gore"
+
+msgid "Key$Down"
+msgstr "Dole"
+
+msgid "Key$Menu"
+msgstr "Meni"
+
+msgid "Key$Ok"
+msgstr "Ok"
+
+msgid "Key$Back"
+msgstr "Nazad"
+
+msgid "Key$Left"
+msgstr "Levo"
+
+msgid "Key$Right"
+msgstr "Desno"
+
+msgid "Key$Red"
+msgstr "Crveno"
+
+msgid "Key$Green"
+msgstr "Zeleno"
+
+msgid "Key$Yellow"
+msgstr "®uto"
+
+msgid "Key$Blue"
+msgstr "Plavo"
+
+msgid "Key$Info"
+msgstr "Info"
+
+msgid "Key$Play"
+msgstr "Start"
+
+msgid "Key$Pause"
+msgstr "Pauza"
+
+msgid "Key$Stop"
+msgstr "Stop"
+
+msgid "Key$Record"
+msgstr "Snimaj"
+
+msgid "Key$FastFwd"
+msgstr "Napred"
+
+msgid "Key$FastRew"
+msgstr "Nazad"
+
+msgid "Key$Next"
+msgstr "Sledeæe"
+
+msgid "Key$Prev"
+msgstr "Prethodno"
+
+msgid "Key$Power"
+msgstr "Power"
+
+msgid "Key$Channel+"
+msgstr "Kanal+"
+
+msgid "Key$Channel-"
+msgstr "Kanal-"
+
+msgid "Key$PrevChannel"
+msgstr "PrethodniKanal"
+
+msgid "Key$Volume+"
+msgstr "Glasnije"
+
+msgid "Key$Volume-"
+msgstr "Ti¹e"
+
+msgid "Key$Mute"
+msgstr "Bez tona"
+
+msgid "Key$Audio"
+msgstr "Audio"
+
+msgid "Key$Subtitles"
+msgstr "Titlovi"
+
+msgid "Key$Schedule"
+msgstr "Raspored"
+
+msgid "Key$Channels"
+msgstr "Kanali"
+
+msgid "Key$Timers"
+msgstr "Tajmeri"
+
+msgid "Key$Recordings"
+msgstr "Snimke"
+
+msgid "Key$Setup"
+msgstr "Pode¹avanje"
+
+msgid "Key$Commands"
+msgstr "Naredbe"
+
+msgid "Key$User0"
+msgstr "Korisnik0"
+
+msgid "Key$User1"
+msgstr "Korisnik1"
+
+msgid "Key$User2"
+msgstr "Korisnik2"
+
+msgid "Key$User3"
+msgstr "Korisnik3"
+
+msgid "Key$User4"
+msgstr "Korisnik4"
+
+msgid "Key$User5"
+msgstr "Korisnik5"
+
+msgid "Key$User6"
+msgstr "Korisnik6"
+
+msgid "Key$User7"
+msgstr "Korisnik7"
+
+msgid "Key$User8"
+msgstr "Korisnik8"
+
+msgid "Key$User9"
+msgstr "Korisnik9"
+
+msgid "Disk"
+msgstr "Disk"
+
+msgid "free"
+msgstr "slobodno"
+
+msgid "Free To Air"
+msgstr "Slobodno"
+
+msgid "encrypted"
+msgstr "kriptirano"
+
+msgid "Edit channel"
+msgstr "Ispravke kanala"
+
+msgid "Name"
+msgstr "Naziv"
+
+msgid "Source"
+msgstr "Izvor"
+
+msgid "Frequency"
+msgstr "Frekvencija"
+
+msgid "Vpid"
+msgstr "Vpid"
+
+msgid "Ppid"
+msgstr "Ppid"
+
+msgid "Apid1"
+msgstr "Apid1"
+
+msgid "Apid2"
+msgstr "Apid2"
+
+msgid "Dpid1"
+msgstr "Dpid1"
+
+msgid "Dpid2"
+msgstr "Dpid2"
+
+msgid "Spid1"
+msgstr "Spid1"
+
+msgid "Spid2"
+msgstr "Spid2"
+
+msgid "Tpid"
+msgstr "Tpid"
+
+msgid "CA"
+msgstr "Kodiranje (CA)"
+
+msgid "Sid"
+msgstr "Sid"
+
+msgid "Channel settings are not unique!"
+msgstr "Postavke programa nisu jedinstvene!"
+
+msgid "Channels"
+msgstr "Kanali"
+
+msgid "Button$Edit"
+msgstr "Promeni"
+
+msgid "Button$New"
+msgstr "Novi"
+
+msgid "Button$Delete"
+msgstr "Obri¹i"
+
+msgid "Button$Mark"
+msgstr "Oznaèi"
+
+msgid "Channel is being used by a timer!"
+msgstr "Kanal je trenutno zauzet tajmerom!"
+
+msgid "Delete channel?"
+msgstr "Obrisati kanal?"
+
+#, fuzzy
+msgid "Edit folder"
+msgstr "Ureðivanje tajmera"
+
+msgid "New folder"
+msgstr "Novi direktorij"
+
+msgid "Sub folder"
+msgstr "Pod Direktorij"
+
+msgid "Folder name already exists!"
+msgstr "Ime direktorija veæ postoji"
+
+#, c-format
+msgid "Folder name must not contain '%c'!"
+msgstr "Naziv direktorija ne smije sadr¾avati '%c'! "
+
+#, fuzzy
+msgid "Button$Select"
+msgstr "Zabilje¾i"
+
+msgid "Delete folder and all sub folders?"
+msgstr "Obri¹i direktorij i sve poddirektorije"
+
+#, fuzzy
+msgid "Delete folder?"
+msgstr "Obri¹i direktorij?"
+
+msgid "Edit timer"
+msgstr "Ureðivanje tajmera"
+
+msgid "Active"
+msgstr "Aktivan"
+
+msgid "Channel"
+msgstr "Kanal"
+
+msgid "Day"
+msgstr "Dan"
+
+msgid "Start"
+msgstr "Poèetak"
+
+msgid "Stop"
+msgstr "Kraj"
+
+msgid "VPS"
+msgstr "VPS"
+
+msgid "Priority"
+msgstr "Prioritet"
+
+msgid "Lifetime"
+msgstr "Trajanje"
+
+msgid "File"
+msgstr "Datoteka"
+
+#, fuzzy
+msgid "Button$Folder"
+msgstr "Taster$Direktorij"
+
+msgid "First day"
+msgstr "Prvi dan"
+
+msgid "Select folder"
+msgstr "Odaberi direktorij"
+
+msgid "Timers"
+msgstr "Tajmeri"
+
+msgid "Button$On/Off"
+msgstr "Taster$ukljuèi/iskljuèi"
+
+msgid "Button$Info"
+msgstr "Taster$Info"
+
+msgid "Delete timer?"
+msgstr "Obri¹i tajmer?"
+
+msgid "Timer still recording - really delete?"
+msgstr "Tajmer jo¹ snima - zaista obri¹i?"
+
+msgid "Event"
+msgstr "Emisija"
+
+msgid "Button$Timer"
+msgstr "Tajmer"
+
+msgid "Button$Record"
+msgstr "Snimi"
+
+msgid "Button$Switch"
+msgstr "Prebaci"
+
+msgid "What's on now?"
+msgstr "Trenutno na programu ?"
+
+msgid "What's on next?"
+msgstr "©ta je sledeæe?"
+
+msgid "Button$Next"
+msgstr "Sledi"
+
+msgid "Button$Now"
+msgstr "Trenutno"
+
+msgid "Button$Schedule"
+msgstr "TV Raspored"
+
+msgid "Can't switch channel!"
+msgstr "Nemoguæe promeniti kanal!"
+
+#, c-format
+msgid "Schedule - %s"
+msgstr "TV Raspored - %s"
+
+#, c-format
+msgid "This event - %s"
+msgstr "Ovaj dogaðaj - %s"
+
+msgid "This event - all channels"
+msgstr "Ovaj dogaðaj - svi kanali"
+
+msgid "All events - all channels"
+msgstr "Svi dogaðaji - svi kanali"
+
+#, c-format
+msgid "Please enter %d digits!"
+msgstr "Molim unesi %d brojeve!"
+
+msgid "CAM not responding!"
+msgstr "CAM ne reaguje!"
+
+msgid "Recording info"
+msgstr "Detalji snimanja"
+
+msgid "Button$Play"
+msgstr "Start"
+
+msgid "Button$Rewind"
+msgstr "Poèetak"
+
+#, fuzzy
+msgid "Recordings"
+msgstr "Snimanje"
+
+#, fuzzy
+msgid "Button$Open"
+msgstr "Meni"
+
+#, fuzzy
+msgid "Commands"
+msgstr "Naredbe"
+
+msgid "Error while accessing recording!"
+msgstr "Gre¹ka prilikom pristupa snimanju!"
+
+msgid "Delete recording?"
+msgstr "Obri¹i snimku?"
+
+msgid "Error while deleting recording!"
+msgstr "Gre¹ka prilikom brisanja snimke!"
+
+msgid "Recording commands"
+msgstr "Naredbe snimanja"
+
+msgid "never"
+msgstr "Nikada"
+
+msgid "skin dependent"
+msgstr "Zavisi od skin-a"
+
+msgid "always"
+msgstr "uvek"
+
+msgid "OSD"
+msgstr "OSD"
+
+msgid "Setup.OSD$Language"
+msgstr "Jezik"
+
+msgid "Setup.OSD$Skin"
+msgstr "Izgled"
+
+msgid "Setup.OSD$Theme"
+msgstr "Tema"
+
+#, fuzzy
+msgid "Setup.OSD$Left (%)"
+msgstr "Levo(%)"
+
+#, fuzzy
+msgid "Setup.OSD$Top (%)"
+msgstr "Gore(%)"
+
+#, fuzzy
+msgid "Setup.OSD$Width (%)"
+msgstr "©irina (%)"
+
+#, fuzzy
+msgid "Setup.OSD$Height (%)"
+msgstr "Visina (%)"
+
+msgid "Setup.OSD$Message time (s)"
+msgstr "Du¾ina prikaza poruka (s)"
+
+msgid "Setup.OSD$Use small font"
+msgstr "Koristi mala slova"
+
+msgid "Setup.OSD$Anti-alias"
+msgstr "Anti-alias"
+
+msgid "Setup.OSD$Default font"
+msgstr "Zadani font"
+
+msgid "Setup.OSD$Small font"
+msgstr "Mali font"
+
+msgid "Setup.OSD$Fixed font"
+msgstr "Nepromenjiv font"
+
+#, fuzzy
+msgid "Setup.OSD$Default font size (%)"
+msgstr "Velièina zadanog fonta (piksel)"
+
+#, fuzzy
+msgid "Setup.OSD$Small font size (%)"
+msgstr "Velièina malog fonta (piksel)"
+
+#, fuzzy
+msgid "Setup.OSD$Fixed font size (%)"
+msgstr "Velièina nepromenjivog fonta (piksel)"
+
+msgid "Setup.OSD$Channel info position"
+msgstr "Pozicija informacija o programu"
+
+msgid "bottom"
+msgstr "dno"
+
+msgid "top"
+msgstr "vrh"
+
+msgid "Setup.OSD$Channel info time (s)"
+msgstr "Vreme prikaza informacije o kanalu (s)"
+
+msgid "Setup.OSD$Info on channel switch"
+msgstr "Informacije kod promene kanala"
+
+msgid "Setup.OSD$Timeout requested channel info"
+msgstr "Du¾ina prikaza informacije o kanalu"
+
+msgid "Setup.OSD$Scroll pages"
+msgstr "Listaj po stranicama"
+
+msgid "Setup.OSD$Scroll wraps"
+msgstr "Skoèi s kraja na poèetak"
+
+msgid "Setup.OSD$Menu key closes"
+msgstr "Taster Meni zatvara"
+
+msgid "Setup.OSD$Recording directories"
+msgstr "Direktorij za snimke"
+
+#, fuzzy
+msgid "Setup.OSD$Folders in timer menu"
+msgstr "Direktoriji u tajmer meni-ju "
+
+#, fuzzy
+msgid "Setup.OSD$Number keys for characters"
+msgstr "Number keys for characters"
+
+msgid "EPG"
+msgstr "EPG (TV Raspored¨)"
+
+msgid "Button$Scan"
+msgstr "Pretra¾i"
+
+msgid "Setup.EPG$EPG scan timeout (h)"
+msgstr "Vreme do EPG pregleda (h)"
+
+msgid "Setup.EPG$EPG bugfix level"
+msgstr "Nivo ispravaka EPG gre¹aka"
+
+msgid "Setup.EPG$EPG linger time (min)"
+msgstr "Vreme EPG zadr¾avanja (min)"
+
+msgid "Setup.EPG$Set system time"
+msgstr "Podesi sistemsko vreme"
+
+msgid "Setup.EPG$Use time from transponder"
+msgstr "Koristi vreme sa transpondera"
+
+#. TRANSLATORS: note the plural!
+msgid "Setup.EPG$Preferred languages"
+msgstr "Odaberi jezike"
+
+#. TRANSLATORS: note the singular!
+msgid "Setup.EPG$Preferred language"
+msgstr "Odaberi jezik"
+
+msgid "pan&scan"
+msgstr "pro¹iri i ispitaj"
+
+msgid "letterbox"
+msgstr "pravougaonik"
+
+msgid "center cut out"
+msgstr "izre¾i sredinu"
+
+#, fuzzy
+msgid "no"
+msgstr "ni¹ta"
+
+msgid "names only"
+msgstr "samo imena"
+
+msgid "PIDs only"
+msgstr "Samo PID-ovi"
+
+msgid "names and PIDs"
+msgstr "imena i (PIDs)"
+
+msgid "add new channels"
+msgstr "dodaj nove kanale"
+
+msgid "add new transponders"
+msgstr "dodaj nove transpondere"
+
+msgid "DVB"
+msgstr "DVB"
+
+msgid "Setup.DVB$Primary DVB interface"
+msgstr "Primarni DVB ureðaj"
+
+msgid "Setup.DVB$Video format"
+msgstr "Video format"
+
+msgid "Setup.DVB$Video display format"
+msgstr "Format video prikaza"
+
+msgid "Setup.DVB$Use Dolby Digital"
+msgstr "Koristi Dolby Digital"
+
+msgid "Setup.DVB$Update channels"
+msgstr "A¾uriranje kanala"
+
+msgid "Setup.DVB$Audio languages"
+msgstr "Audio jezici"
+
+msgid "Setup.DVB$Audio language"
+msgstr "Audio jezik"
+
+msgid "Setup.DVB$Display subtitles"
+msgstr "Poka¾i titlove"
+
+msgid "Setup.DVB$Subtitle languages"
+msgstr "Jezici titla"
+
+msgid "Setup.DVB$Subtitle language"
+msgstr "Jezik titla"
+
+msgid "Setup.DVB$Subtitle offset"
+msgstr "Pomak titla"
+
+msgid "Setup.DVB$Subtitle foreground transparency"
+msgstr "Providnost titla"
+
+msgid "Setup.DVB$Subtitle background transparency"
+msgstr "Providnost pozadine titla"
+
+msgid "LNB"
+msgstr "LNB"
+
+msgid "Setup.LNB$Use DiSEqC"
+msgstr "Koristi DiSEqC"
+
+msgid "Setup.LNB$SLOF (MHz)"
+msgstr "SLOF (MHz)"
+
+msgid "Setup.LNB$Low LNB frequency (MHz)"
+msgstr "Donja LNB frekv. (MHz)"
+
+msgid "Setup.LNB$High LNB frequency (MHz)"
+msgstr "Gornja LNB frekv. (MHz)"
+
+msgid "CAM reset"
+msgstr "Ponovno pokreni CAM"
+
+msgid "CAM present"
+msgstr "CAM prisutan"
+
+msgid "CAM ready"
+msgstr "CAM spreman"
+
+msgid "CAM"
+msgstr "CAM"
+
+msgid "Button$Menu"
+msgstr "Meni"
+
+msgid "Button$Reset"
+msgstr "Ponovno pokreni"
+
+msgid "Opening CAM menu..."
+msgstr "Otvaram CAM meni..."
+
+msgid "Can't open CAM menu!"
+msgstr "Otvaranje CAM menija neuspe¹no!"
+
+msgid "CAM is in use - really reset?"
+msgstr "CAM u upotrebi - ponovno pokrenuti?"
+
+msgid "Can't reset CAM!"
+msgstr "Ponovno pokretanje CAM-a neuspe¹no!"
+
+#, fuzzy
+msgid "do not pause live video"
+msgstr "Ne zaustavljaj izravan prenos"
+
+#, fuzzy
+msgid "confirm pause live video"
+msgstr "Potvrdi zaustavljanje izravnog prenosa..."
+
+#, fuzzy
+msgid "pause live video"
+msgstr "Zaustavljanje izravnog prenosa..."
+
+msgid "confirm"
+msgstr "potvrdi"
+
+msgid "yes"
+msgstr ""
+
+msgid "Recording"
+msgstr "Snimanje"
+
+msgid "Setup.Recording$Margin at start (min)"
+msgstr "Rezerva na poèetku snimanja (min)"
+
+msgid "Setup.Recording$Margin at stop (min)"
+msgstr "Rezerva na kraju (min)"
+
+msgid "Setup.Recording$Primary limit"
+msgstr "Standardno ogranièenje"
+
+msgid "Setup.Recording$Default priority"
+msgstr "Zadani prioritet"
+
+msgid "Setup.Recording$Default lifetime (d)"
+msgstr "Zadano trajanje (d)"
+
+#, fuzzy
+msgid "Setup.Recording$Pause key handling"
+msgstr "Trajanje pauze (d)"
+
+msgid "Setup.Recording$Pause priority"
+msgstr "Prioritet pauze"
+
+msgid "Setup.Recording$Pause lifetime (d)"
+msgstr "Trajanje pauze (d)"
+
+msgid "Setup.Recording$Use episode name"
+msgstr "Koristi naziv epizode"
+
+msgid "Setup.Recording$Use VPS"
+msgstr "Koristi VPS"
+
+msgid "Setup.Recording$VPS margin (s)"
+msgstr "Vremenska rezerva kod VPS (s)"
+
+msgid "Setup.Recording$Mark instant recording"
+msgstr "Oznaèi trenutno snimanje"
+
+msgid "Setup.Recording$Name instant recording"
+msgstr "Imenuj trenutno snimanje"
+
+msgid "Setup.Recording$Instant rec. time (min)"
+msgstr "Trajanje trenutnog snimanja (min)"
+
+msgid "Setup.Recording$Max. video file size (MB)"
+msgstr "Maks. velièina datoteke (MB)"
+
+msgid "Setup.Recording$Split edited files"
+msgstr "Podeli ureðene datoteke"
+
+msgid "Setup.Recording$Delete timeshift recording"
+msgstr "Bri¹i vremenski pomak snimke"
+
+msgid "Replay"
+msgstr "Reprodukcija"
+
+msgid "Setup.Replay$Multi speed mode"
+msgstr "Vi¹estruke brzine reprodukcije"
+
+msgid "Setup.Replay$Show replay mode"
+msgstr "Prika¾i re¾im reprodukcije"
+
+msgid "Setup.Replay$Resume ID"
+msgstr "ID nastavka"
+
+msgid "Miscellaneous"
+msgstr "Razno"
+
+msgid "Setup.Miscellaneous$Min. event timeout (min)"
+msgstr "Min. vreme pauze (min)"
+
+msgid "Setup.Miscellaneous$Min. user inactivity (min)"
+msgstr "Min. vreme neaktivnosti (min)"
+
+msgid "Setup.Miscellaneous$SVDRP timeout (s)"
+msgstr "SVDRP vreme (s)"
+
+msgid "Setup.Miscellaneous$Zap timeout (s)"
+msgstr "Zap istièe (s)"
+
+msgid "Setup.Miscellaneous$Channel entry timeout (ms)"
+msgstr "Upis kanala istièe (ms)"
+
+msgid "Setup.Miscellaneous$Initial channel"
+msgstr "Poèetni kanal"
+
+msgid "Setup.Miscellaneous$as before"
+msgstr "kao prethodno"
+
+msgid "Setup.Miscellaneous$Initial volume"
+msgstr "Poèetna jaèina tona"
+
+#, fuzzy
+msgid "Setup.Miscellaneous$Channels wrap"
+msgstr "Kanal spakovan"
+
+msgid "Setup.Miscellaneous$Emergency exit"
+msgstr "Izlaz u sluèaju nu¾de"
+
+msgid "Plugins"
+msgstr "Dodaci"
+
+msgid "This plugin has no setup parameters!"
+msgstr "Ovaj dodatak nema parametara!"
+
+msgid "Setup"
+msgstr "Podesi"
+
+msgid "Restart"
+msgstr "Restart sistema"
+
+msgid "Really restart?"
+msgstr "Ponovo pokretanje ???"
+
+#. TRANSLATORS: note the leading and trailing blanks!
+msgid " Stop recording "
+msgstr " Zaustavi snimanje "
+
+msgid "Schedule"
+msgstr "Raspored Programa"
+
+msgid "VDR"
+msgstr "VDR"
+
+#. TRANSLATORS: note the leading blank!
+msgid " Stop replaying"
+msgstr " Zaustavi reprodukciju"
+
+msgid "Button$Audio"
+msgstr "Audio"
+
+msgid "Button$Pause"
+msgstr "Pauza"
+
+msgid "Button$Stop"
+msgstr "Stop"
+
+msgid "Button$Resume"
+msgstr "Nastavi"
+
+#. TRANSLATORS: note the leading blank!
+msgid " Cancel editing"
+msgstr "Zaustavi ispravke"
+
+msgid "Stop recording?"
+msgstr "Zaustavi snimanje?"
+
+msgid "Cancel editing?"
+msgstr "Otka¾i ispravke?"
+
+msgid "No audio available!"
+msgstr "Ton nedostupan"
+
+msgid "No subtitles"
+msgstr "Bez titlova"
+
+msgid "Button$Subtitles"
+msgstr "Titlovi"
+
+msgid "No subtitles available!"
+msgstr "Titlovi nisu dostupni!"
+
+msgid "Not enough disk space to start recording!"
+msgstr "Nedovoljno prostora na disku za snimanje!"
+
+#, fuzzy
+msgid "No free DVB device to record!"
+msgstr "Nema slobodnog DVB ureðaja za snimanje!"
+
+msgid "Pausing live video..."
+msgstr "Zaustavljanje izravnog prenosa..."
+
+#, fuzzy
+msgid "Delete timeshift recording?"
+msgstr "Obrisati snimku vremenskog pomaka?"
+
+#. TRANSLATORS: note the trailing blank!
+msgid "Jump: "
+msgstr "Skoèi: "
+
+msgid "No editing marks defined!"
+msgstr "Nijedna taèka rezanja nije odreðena!"
+
+msgid "Can't start editing process!"
+msgstr "Ne mogu zapoèeti ureðivanje!"
+
+msgid "Editing process started"
+msgstr "Ureðivanje zapoèelo"
+
+msgid "Editing process already active!"
+msgstr "Ureðivanje je veæ u toku!!"
+
+msgid "FileNameChars$ abcdefghijklmnopqrstuvwxyz0123456789-.,#~\\^$[]|()*+?{}/:%@&"
+msgstr "abcÄ‡dÄ‘efghijklmnopqrstuvwxyzÅ¾Å¸0123456789-.,#~\\^$[]|()*+?{}/:%@&"
+
+msgid "CharMap$ 0\t-.,1#~\\^$[]|()*+?{}/:%@&\tabc2\tdef3\tghi4\tjkl5\tmno6\tpqrs7\ttuv8\twxyz9"
+msgstr "0\t-.,1#~\\^$[]|()*+?{}/:%@&\tabc2\tdef3\tghi4\tjkl5\tmno6\tpqrs7\ttuv8\twxyz9"
+
+msgid "Button$ABC/abc"
+msgstr "ABC/abc"
+
+msgid "Button$Overwrite"
+msgstr "Prepi¹i"
+
+msgid "Button$Insert"
+msgstr "Ubaci"
+
+msgid "Plugin"
+msgstr "Dodatak"
+
+msgid "Up/Dn for new location - OK to move"
+msgstr "Gore/Dole na novu poziciju - OK za prihvati"
+
+msgid "Channel locked (recording)!"
+msgstr "Kanal zakljuèan (snimanje)!"
+
+msgid "Low disk space!"
+msgstr "Malo prostora na disku!"
+
+msgid "Regenerating index file"
+msgstr "Obnavljanje index datoteke"
+
+msgid "Index file regeneration complete"
+msgstr "Obnavljanje index datoteke zavr¹eno"
+
+msgid "Can't shutdown - option '-s' not given!"
+msgstr "Ga¹enje nemoguæe - nedostaje opcija '-s'!"
+
+msgid "Editing - shut down anyway?"
+msgstr "Ispravke u toku - u svakom sluèaju iskljuèi ?"
+
+msgid "Recording - shut down anyway?"
+msgstr "Snimanje u toku - u svakom sluèaju iskljuèi ?"
+
+#, c-format
+msgid "Recording in %ld minutes, shut down anyway?"
+msgstr "Snimanje za %ld minuta - u svakom sluèaju iskljuèi?"
+
+msgid "shut down anyway?"
+msgstr "u svakom sluèaju iskljuèi?"
+
+#, c-format
+msgid "Plugin %s wakes up in %ld min, continue?"
+msgstr "Dodatak %s budi se u %ld min, nastavi?"
+
+msgid "Editing - restart anyway?"
+msgstr "Ureðivanje u toku - ponovno pokreni!!!?"
+
+msgid "Recording - restart anyway?"
+msgstr "Snimanje je u toku - ponovno pokreni!!!?"
+
+msgid "restart anyway?"
+msgstr "ponovo pokreni?"
+
+#. TRANSLATORS: note the trailing blank!
+msgid "Volume "
+msgstr "Jaèina "
+
+msgid "Classic VDR"
+msgstr "Klasièni VDR"
+
+msgid "ST:TNG Panels"
+msgstr "ST:TNG Panele"
+
+#. TRANSLATORS: the first character of each weekday, beginning with monday
+msgid "MTWTFSS"
+msgstr "PUSÈPSN"
+
+#. TRANSLATORS: abbreviated weekdays, beginning with monday (must all be 3 letters!)
+msgid "MonTueWedThuFriSatSun"
+msgstr "PonUtoSreÈetPetSubNed"
+
+msgid "Monday"
+msgstr "Ponedeljak"
+
+msgid "Tuesday"
+msgstr "Utorak"
+
+msgid "Wednesday"
+msgstr "Sreda"
+
+msgid "Thursday"
+msgstr "Èetvrtak"
+
+msgid "Friday"
+msgstr "Petak"
+
+msgid "Saturday"
+msgstr "Subota"
+
+msgid "Sunday"
+msgstr "Nedelja"
+
+msgid "Upcoming recording!"
+msgstr "Predstojeæe snimanje!"
+
+#, fuzzy
+msgid "Pause live video?"
+msgstr "Zaustavljam izravni prenos..."
+
+msgid "Recording started"
+msgstr "Snimanje zapoèelo"
+
+msgid "VDR will shut down later - press Power to force"
+msgstr "VDR æe se iskljuèiti kasnije - pritisni Power-taster za prisilno iskljuèenje"
+
+msgid "Press any key to cancel shutdown"
+msgstr "Pritisni taster za prekid iskljuèenja"
+
+msgid "Switching primary DVB..."
+msgstr "Prebacivanje primarnog DVB ureðaja..."
+
+msgid "Editing process failed!"
+msgstr "Ureðivanje neusp¹jeno!"
+
+msgid "Editing process finished"
+msgstr "Ureðivanje zavr¹eno"
+
+msgid "Press any key to cancel restart"
+msgstr "Pritisni jedan taster za poni¹tenje restart-a"
+
+#, c-format
+msgid "VDR will shut down in %s minutes"
+msgstr "VDR se iskljuèuje za %s minuta"
diff -ruN vdr-1.7.16/po/sv_SE.po vdr-1.7.17/po/sv_SE.po
--- vdr-1.7.16/po/sv_SE.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/sv_SE.po	2010-10-24 16:40:28.000000000 +0200
@@ -10,13 +10,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-03-12 18:25+0100\n"
 "Last-Translator: Magnus Andersson <svankan@bahnhof.se>\n"
-"Language-Team: Swedish\n"
+"Language-Team: Swedish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: sv\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Felaktig kanal ***"
diff -ruN vdr-1.7.16/po/tr_TR.po vdr-1.7.17/po/tr_TR.po
--- vdr-1.7.16/po/tr_TR.po	2010-09-19 14:44:30.000000000 +0200
+++ vdr-1.7.17/po/tr_TR.po	2010-10-24 16:40:29.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2008-02-28 00:33+0100\n"
 "Last-Translator: Oktay Yolgeçen <oktay_73@yahoo.de>\n"
-"Language-Team: Turkish\n"
+"Language-Team: Turkish <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-9\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: tr\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Geçersiz kanal ***"
diff -ruN vdr-1.7.16/po/uk_UA.po vdr-1.7.17/po/uk_UA.po
--- vdr-1.7.16/po/uk_UA.po	2010-09-19 14:44:31.000000000 +0200
+++ vdr-1.7.17/po/uk_UA.po	2010-10-24 16:40:29.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.7.7\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2010-04-25 16:35+0200\n"
 "Last-Translator: Yarema aka Knedlyk <yupadmin@gmail.com>\n"
-"Language-Team: Ukrainian\n"
+"Language-Team: Ukrainian <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: uk\n"
 
 msgid "*** Invalid Channel ***"
 msgstr "*** Ð�ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¸Ð¹ ÐºÐ°Ð½Ð°Ð» ***"
diff -ruN vdr-1.7.16/po/zh_CN.po vdr-1.7.17/po/zh_CN.po
--- vdr-1.7.16/po/zh_CN.po	2010-09-19 14:44:31.000000000 +0200
+++ vdr-1.7.17/po/zh_CN.po	2010-10-24 16:40:29.000000000 +0200
@@ -7,13 +7,14 @@
 msgstr ""
 "Project-Id-Version: VDR 1.6.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
-"POT-Creation-Date: 2010-06-06 12:52+0200\n"
+"POT-Creation-Date: 2010-10-24 16:26+0200\n"
 "PO-Revision-Date: 2009-09-23 23:50+0800\n"
 "Last-Translator: Nan Feng <nfgx@21cn.com>\n"
-"Language-Team: Chinese\n"
+"Language-Team: Chinese (simplified) <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
 "X-Poedit-Language: Chinese\n"
 "X-Poedit-Country: CHINA\n"
 "X-Poedit-SourceCharset: utf-8\n"
diff -ruN vdr-1.7.16/receiver.c vdr-1.7.17/receiver.c
--- vdr-1.7.16/receiver.c	2010-02-28 15:25:32.000000000 +0100
+++ vdr-1.7.17/receiver.c	2010-12-13 00:16:25.000000000 +0100
@@ -4,11 +4,10 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: receiver.c 2.3 2010/02/28 14:25:32 kls Exp $
+ * $Id: receiver.c 2.4 2010/12/12 23:16:25 kls Exp $
  */
 
 #include "receiver.h"
-#include <stdarg.h>
 #include <stdio.h>
 #include "tools.h"
 
diff -ruN vdr-1.7.16/recorder.c vdr-1.7.17/recorder.c
--- vdr-1.7.16/recorder.c	2010-01-29 17:37:22.000000000 +0100
+++ vdr-1.7.17/recorder.c	2010-12-27 12:35:46.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recorder.c 2.8 2010/01/29 16:37:22 kls Exp $
+ * $Id: recorder.c 2.9 2010/12/27 11:35:46 kls Exp $
  */
 
 #include "recorder.h"
@@ -24,8 +24,9 @@
 cRecorder::cRecorder(const char *FileName, const cChannel *Channel, int Priority)
 :cReceiver(Channel, Priority)
 ,cThread("recording")
-,recordingInfo(FileName)
 {
+  recordingName = strdup(FileName);
+
   // Make sure the disk is up and running:
 
   SpinUpDisk(FileName);
@@ -69,6 +70,7 @@
   delete fileName;
   delete frameDetector;
   delete ringBuffer;
+  free(recordingName);
 }
 
 bool cRecorder::RunningLowOnDiskSpace(void)
@@ -127,10 +129,12 @@
                  break;
               if (frameDetector->Synced()) {
                  if (!InfoWritten) {
-                    if (recordingInfo.Read()) {
-                       if (frameDetector->FramesPerSecond() > 0 && !DoubleEqual(recordingInfo.FramesPerSecond(), frameDetector->FramesPerSecond())) {
-                          recordingInfo.SetFramesPerSecond(frameDetector->FramesPerSecond());
-                          recordingInfo.Write();
+                    cRecordingInfo RecordingInfo(recordingName);
+                    if (RecordingInfo.Read()) {
+                       if (frameDetector->FramesPerSecond() > 0 && !DoubleEqual(RecordingInfo.FramesPerSecond(), frameDetector->FramesPerSecond())) {
+                          RecordingInfo.SetFramesPerSecond(frameDetector->FramesPerSecond());
+                          RecordingInfo.Write();
+                          Recordings.UpdateByName(recordingName);
                           }
                        }
                     InfoWritten = true;
diff -ruN vdr-1.7.16/recorder.h vdr-1.7.17/recorder.h
--- vdr-1.7.16/recorder.h	2010-01-29 17:32:32.000000000 +0100
+++ vdr-1.7.17/recorder.h	2010-12-27 12:17:04.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recorder.h 2.2 2010/01/29 16:32:32 kls Exp $
+ * $Id: recorder.h 2.3 2010/12/27 11:17:04 kls Exp $
  */
 
 #ifndef __RECORDER_H
@@ -24,7 +24,7 @@
   cFileName *fileName;
   cIndexFile *index;
   cUnbufferedFile *recordFile;
-  cRecordingInfo recordingInfo;
+  char *recordingName;
   off_t fileSize;
   time_t lastDiskSpaceCheck;
   bool RunningLowOnDiskSpace(void);
diff -ruN vdr-1.7.16/recording.c vdr-1.7.17/recording.c
--- vdr-1.7.16/recording.c	2010-03-07 15:06:04.000000000 +0100
+++ vdr-1.7.17/recording.c	2011-02-27 14:35:20.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 2.23 2010/03/07 14:06:04 kls Exp $
+ * $Id: recording.c 2.26 2011/02/27 13:35:20 kls Exp $
  */
 
 #include "recording.h"
@@ -57,6 +57,7 @@
 #define DELETEDLIFETIME   300 // seconds after which a deleted recording will be actually removed
 #define DISKCHECKDELTA    100 // seconds between checks for free disk space
 #define REMOVELATENCY      10 // seconds to wait until next check after removing a file
+#define MARKSUPDATEDELTA   10 // seconds between checks for updating editing marks
 
 #define MAX_SUBTITLE_LENGTH  40
 
@@ -548,13 +549,17 @@
                      default:
                        if (strchr(InvalidChars, *p) || *p == '.' && (!*(p + 1) || *(p + 1) == FOLDERDELIMCHAR)) { // Windows can't handle '.' at the end of file/directory names
                           int l = p - s;
-                          s = (char *)realloc(s, strlen(s) + 10);
-                          p = s + l;
-                          char buf[4];
-                          sprintf(buf, "#%02X", (unsigned char)*p);
-                          memmove(p + 2, p, strlen(p) + 1);
-                          strncpy(p, buf, 3);
-                          p += 2;
+                          if (char *NewBuffer = (char *)realloc(s, strlen(s) + 10)) {
+                             s = NewBuffer;
+                             p = s + l;
+                             char buf[4];
+                             sprintf(buf, "#%02X", (unsigned char)*p);
+                             memmove(p + 2, p, strlen(p) + 1);
+                             strncpy(p, buf, 3);
+                             p += 2;
+                             }
+                          else
+                             esyslog("ERROR: out of memory");
                           }
                      }
               }
@@ -678,7 +683,7 @@
   const char *p = strrchr(FileName, '/');
 
   name = NULL;
-  info = new cRecordingInfo;
+  info = new cRecordingInfo(fileName);
   if (p) {
      time_t now = time(NULL);
      struct tm tm_r;
@@ -729,9 +734,13 @@
                     if (data[line]) {
                        int len = strlen(s);
                        len += strlen(data[line]) + 1;
-                       data[line] = (char *)realloc(data[line], len + 1);
-                       strcat(data[line], "\n");
-                       strcat(data[line], s);
+                       if (char *NewBuffer = (char *)realloc(data[line], len + 1)) {
+                          data[line] = NewBuffer;
+                          strcat(data[line], "\n");
+                          strcat(data[line], s);
+                          }
+                       else
+                          esyslog("ERROR: out of memory");
                        }
                     else
                        data[line] = strdup(s);
@@ -750,12 +759,16 @@
               // line 1 and line 2 to be the long text:
               int len = strlen(data[1]);
               if (len > 80) {
-                 data[1] = (char *)realloc(data[1], len + 1 + strlen(data[2]) + 1);
-                 strcat(data[1], "\n");
-                 strcat(data[1], data[2]);
-                 free(data[2]);
-                 data[2] = data[1];
-                 data[1] = NULL;
+                 if (char *NewBuffer = (char *)realloc(data[1], len + 1 + strlen(data[2]) + 1)) {
+                    data[1] = NewBuffer;
+                    strcat(data[1], "\n");
+                    strcat(data[1], data[2]);
+                    free(data[2]);
+                    data[2] = data[1];
+                    data[1] = NULL;
+                    }
+                 else
+                    esyslog("ERROR: out of memory");
                  }
               }
            info->SetData(data[0], data[1], data[2]);
@@ -921,6 +934,14 @@
   return *s == '%';
 }
 
+void cRecording::ReadInfo(void)
+{
+  info->Read();
+  priority = info->priority;
+  lifetime = info->lifetime;
+  framesPerSecond = info->framesPerSecond;
+}
+
 bool cRecording::WriteInfo(void)
 {
   cString InfoFileName = cString::sprintf("%s%s", fileName, isPesRecording ? INFOFILESUFFIX ".vdr" : INFOFILESUFFIX);
@@ -1172,6 +1193,14 @@
      }
 }
 
+void cRecordings::UpdateByName(const char *FileName)
+{
+  LOCK_THREAD;
+  cRecording *recording = GetByName(FileName);
+  if (recording)
+     recording->ReadInfo();
+}
+
 int cRecordings::TotalFileSizeMB(void)
 {
   int size = 0;
@@ -1239,12 +1268,28 @@
 
 bool cMarks::Load(const char *RecordingFileName, double FramesPerSecond, bool IsPesRecording)
 {
-  cMutexLock MutexLock(&MutexMarkFramesPerSecond);
+  fileName = AddDirectory(RecordingFileName, IsPesRecording ? MARKSFILESUFFIX ".vdr" : MARKSFILESUFFIX);
   framesPerSecond = FramesPerSecond;
-  MarkFramesPerSecond = framesPerSecond;
-  if (cConfig<cMark>::Load(AddDirectory(RecordingFileName, IsPesRecording ? MARKSFILESUFFIX ".vdr" : MARKSFILESUFFIX))) {
-     Sort();
-     return true;
+  lastUpdate = 0;
+  lastFileTime = -1; // the first call to Load() must take place!
+  return Update();
+}
+
+bool cMarks::Update(void)
+{
+  time_t t = time(NULL);
+  if (t - lastUpdate > MARKSUPDATEDELTA) {
+     lastUpdate = t;
+     t = LastModifiedTime(fileName);
+     if (t > lastFileTime) {
+        lastFileTime = t;
+        cMutexLock MutexLock(&MutexMarkFramesPerSecond);
+        MarkFramesPerSecond = framesPerSecond;
+        if (cConfig<cMark>::Load(fileName)) {
+           Sort();
+           return true;
+           }
+        }
      }
   return false;
 }
@@ -1604,13 +1649,15 @@
                }
             int newLast = int(buf.st_size / sizeof(tIndexTs) - 1);
             if (newLast > last) {
-               if (size <= newLast) {
-                  size *= 2;
-                  if (size <= newLast)
-                     size = newLast + 1;
+               int NewSize = size;
+               if (NewSize <= newLast) {
+                  NewSize *= 2;
+                  if (NewSize <= newLast)
+                     NewSize = newLast + 1;
                   }
-               index = (tIndexTs *)realloc(index, size * sizeof(tIndexTs));
-               if (index) {
+               if (tIndexTs *NewBuffer = (tIndexTs *)realloc(index, NewSize * sizeof(tIndexTs))) {
+                  size = NewSize;
+                  index = NewBuffer;
                   int offset = (last + 1) * sizeof(tIndexTs);
                   int delta = (newLast - last) * sizeof(tIndexTs);
                   if (lseek(f, offset, SEEK_SET) == offset) {
@@ -1629,8 +1676,10 @@
                   else
                      LOG_ERROR_STR(fileName);
                   }
-               else
+               else {
                   esyslog("ERROR: can't realloc() index");
+                  break;
+                  }
                }
             }
          else
diff -ruN vdr-1.7.16/recording.h vdr-1.7.17/recording.h
--- vdr-1.7.16/recording.h	2010-03-07 15:06:15.000000000 +0100
+++ vdr-1.7.17/recording.h	2011-02-27 13:48:21.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.h 2.14 2010/03/07 14:06:15 kls Exp $
+ * $Id: recording.h 2.16 2011/02/27 12:48:21 kls Exp $
  */
 
 #ifndef __RECORDING_H
@@ -117,6 +117,7 @@
   bool IsNew(void) const { return GetResume() <= 0; }
   bool IsEdited(void) const;
   bool IsPesRecording(void) const { return isPesRecording; }
+  void ReadInfo(void);
   bool WriteInfo(void);
   bool Delete(void);
        // Changes the file name so that it will no longer be visible in the "Recordings" menu
@@ -165,6 +166,7 @@
   cRecording *GetByName(const char *FileName);
   void AddByName(const char *FileName, bool TriggerUpdate = true);
   void DelByName(const char *FileName);
+  void UpdateByName(const char *FileName);
   int TotalFileSizeMB(void); ///< Only for deleted recordings!
   };
 
@@ -188,9 +190,13 @@
 
 class cMarks : public cConfig<cMark> {
 private:
+  cString fileName;
   double framesPerSecond;
+  time_t lastUpdate;
+  time_t lastFileTime;
 public:
   bool Load(const char *RecordingFileName, double FramesPerSecond = DEFAULTFRAMESPERSECOND, bool IsPesRecording = false);
+  bool Update(void);
   void Sort(void);
   cMark *Add(int Position);
   cMark *Get(int Position);
diff -ruN vdr-1.7.16/remote.c vdr-1.7.17/remote.c
--- vdr-1.7.16/remote.c	2009-12-06 13:08:03.000000000 +0100
+++ vdr-1.7.17/remote.c	2010-12-24 16:26:05.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 2.1 2009/12/06 12:08:03 kls Exp $
+ * $Id: remote.c 2.2 2010/12/24 15:26:05 kls Exp $
  */
 
 #include "remote.h"
@@ -42,6 +42,7 @@
 
 cRemote::~cRemote()
 {
+  Remotes.Del(this, false);
   free(name);
 }
 
diff -ruN vdr-1.7.16/remux.c vdr-1.7.17/remux.c
--- vdr-1.7.16/remux.c	2010-06-05 15:32:15.000000000 +0200
+++ vdr-1.7.17/remux.c	2011-02-26 16:51:04.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remux.c 2.47 2010/06/05 13:32:15 kls Exp $
+ * $Id: remux.c 2.51 2011/02/26 15:51:04 kls Exp $
  */
 
 #include "remux.h"
@@ -225,7 +225,7 @@
       Target[i++] = *Language++;
       Target[i++] = *Language++;
       Target[i++] = *Language++;
-      Target[i++] = 0x01;     // audio type
+      Target[i++] = 0x00;     // audio type
       Target[Length] += 0x04; // length
       if (*Language == '+')
          Language++;
@@ -666,9 +666,13 @@
      return; // skip everything before the first payload start
   Length = TsGetPayload(&Data);
   if (length + Length > size) {
-     size = max(KILOBYTE(2), length + Length);
-     data = (uchar *)realloc(data, size);
-     if (!data) {
+     int NewSize = max(KILOBYTE(2), length + Length);
+     if (uchar *NewData = (uchar *)realloc(data, NewSize)) {
+        data = NewData;
+        size = NewSize;
+        }
+     else {
+        esyslog("ERROR: out of memory");
         Reset();
         return;
         }
@@ -780,9 +784,8 @@
   newFrame = independentFrame = false;
   numPtsValues = 0;
   numIFrames = 0;
-  frameDuration = 0;
+  framesPerSecond = 0;
   framesInPayloadUnit = framesPerPayloadUnit = 0;
-  payloadUnitOfFrame = 0;
   scanning = false;
   scanner = EMPTY_SCANNER;
 }
@@ -804,7 +807,6 @@
 void cFrameDetector::Reset(void)
 {
   newFrame = independentFrame = false;
-  payloadUnitOfFrame = 0;
   scanning = false;
   scanner = EMPTY_SCANNER;
 }
@@ -831,8 +833,8 @@
                     return Processed;
                  if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE)
                     return Processed; // need more data, in case the frame type is not stored in the first TS packet
-                 if (!frameDuration) {
-                    // frame duration unknown, so collect a sequence of PTS values:
+                 if (!framesPerSecond) {
+                    // frame rate unknown, so collect a sequence of PTS values:
                     if (numPtsValues < MaxPtsValues && numIFrames < 2) { // collect a sequence containing at least two I-frames
                        const uchar *Pes = Data + TsPayloadOffset(Data);
                        if (PesHasPts(Pes)) {
@@ -857,28 +859,22 @@
                        uint32_t Delta = ptsValues[0];
                        // determine frame info:
                        if (isVideo) {
-                          if (Delta % 3600 == 0)
-                             frameDuration = 3600; // PAL, 25 fps, exact timing
-                          else if (abs(Delta % 3600) == 3599 || abs(Delta % 3600) == 1)
-                             frameDuration = 3600; // PAL, 25 fps, timing with jitter
+                          if (abs(Delta - 3600) <= 1)
+                             framesPerSecond = 25.0;
                           else if (Delta % 3003 == 0)
-                             frameDuration = 3003; // NTSC, 29.97 fps
-                          else if (abs(Delta - 1800) <= 1) {
-                             frameDuration = 3600; // PAL, 25 fps
-                             framesPerPayloadUnit = -2;
-                             }
-                          else if (Delta == 1501) {
-                             frameDuration = 3003; // NTSC, 29.97 fps
-                             framesPerPayloadUnit = -2;
-                             }
+                             framesPerSecond = 30.0 / 1.001;
+                          else if (abs(Delta - 1800) <= 1)
+                             framesPerSecond = 50.0;
+                          else if (Delta == 1501)
+                             framesPerSecond = 60.0 / 1.001;
                           else {
-                             frameDuration = 3600; // unknown, assuming 25 fps
-                             dsyslog("unknown frame duration (%d), assuming 25 fps", Delta);
+                             framesPerSecond = 25.0;
+                             dsyslog("unknown frame delta (%d), assuming 25 fps", Delta);
                              }
                           }
                        else // audio
-                          frameDuration = Delta; // PTS of audio frames is always increasing
-                       dbgframes("\nframe duration = %d  FPS = %5.2f  FPPU = %d\n", frameDuration, 90000.0 / frameDuration, framesPerPayloadUnit);
+                          framesPerSecond = 90000.0 / Delta; // PTS of audio frames is always increasing
+                       dbgframes("\nDelta = %d  FPS = %5.2f  FPPU = %d\n", Delta, framesPerSecond, framesPerPayloadUnit);
                        }
                     }
                  scanner = EMPTY_SCANNER;
@@ -927,13 +923,6 @@
                                newFrame = true;
                                independentFrame = Data[i + 1] == 0x10;
                                if (synced) {
-                                  if (framesPerPayloadUnit < 0) {
-                                     payloadUnitOfFrame = (payloadUnitOfFrame + 1) % -framesPerPayloadUnit;
-                                     if (payloadUnitOfFrame != 0 && independentFrame)
-                                        payloadUnitOfFrame = 0;
-                                     if (payloadUnitOfFrame)
-                                        newFrame = false;
-                                     }
                                   if (framesPerPayloadUnit <= 1)
                                      scanning = false;
                                   }
@@ -964,7 +953,7 @@
                                 pid = 0; // let's just ignore any further data
                        }
                      }
-                 if (!synced && frameDuration && independentFrame) {
+                 if (!synced && framesPerSecond && independentFrame) {
                     synced = true;
                     dbgframes("*");
                     Reset();
diff -ruN vdr-1.7.16/remux.h vdr-1.7.17/remux.h
--- vdr-1.7.16/remux.h	2010-06-05 15:27:55.000000000 +0200
+++ vdr-1.7.17/remux.h	2010-11-01 12:24:20.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remux.h 2.26 2010/06/05 13:27:55 kls Exp $
+ * $Id: remux.h 2.27 2010/11/01 11:24:20 kls Exp $
  */
 
 #ifndef __REMUX_H
@@ -347,12 +347,10 @@
   int numPtsValues;
   int numIFrames;
   bool isVideo;
-  int frameDuration;
+  double framesPerSecond;
   int framesInPayloadUnit;
   int framesPerPayloadUnit; // Some broadcasters send one frame per payload unit (== 1),
-                            // some put an entire GOP into one payload unit (> 1), and
-                            // some spread a single frame over several payload units (< 0).
-  int payloadUnitOfFrame;
+                            // while others put an entire GOP into one payload unit (> 1).
   bool scanning;
   uint32_t scanner;
 public:
@@ -380,7 +378,7 @@
       ///< Returns true if a new frame was detected and this is an independent frame
       ///< (i.e. one that can be displayed by itself, without using data from any
       ///< other frames).
-  double FramesPerSecond(void) { return frameDuration ? 90000.0 / frameDuration : 0; }
+  double FramesPerSecond(void) { return framesPerSecond; }
       ///< Returns the number of frames per second, or 0 if this information is not
       ///< available.
   };
diff -ruN vdr-1.7.16/skinclassic.c vdr-1.7.17/skinclassic.c
--- vdr-1.7.16/skinclassic.c	2010-02-13 14:44:48.000000000 +0100
+++ vdr-1.7.17/skinclassic.c	2010-11-07 16:10:23.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 2.4 2010/02/13 13:44:48 kls Exp $
+ * $Id: skinclassic.c 2.5 2010/11/07 15:10:23 kls Exp $
  */
 
 #include "skinclassic.h"
@@ -361,14 +361,6 @@
      ts.Set(osd, x1, y, x2 - x1, y3 - y, Event->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
      y += ts.Height();
      }
-  for (int i = 0; Event->Contents(i); i++) {
-      const char *s = Event->ContentToString(Event->Contents(i));
-      if (!isempty(s)) {
-         const cFont *font = cFont::GetFont(fontSml);
-         ts.Set(osd, x1, y, x2 - x1, y3 - y, s, font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
-         y += ts.Height();
-         }
-      }
   y += font->Height();
   if (!isempty(Event->Description())) {
      textScroller.Set(osd, x1, y, x2 - x1, y3 - y, Event->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
@@ -405,14 +397,6 @@
      ts.Set(osd, x1, y, x2 - x1, y3 - y, Info->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
      y += ts.Height();
      }
-  for (int i = 0; Info->GetEvent()->Contents(i); i++) {
-      const char *s = Info->GetEvent()->ContentToString(Info->GetEvent()->Contents(i));
-      if (!isempty(s)) {
-         const cFont *font = cFont::GetFont(fontSml);
-         ts.Set(osd, x1, y, x2 - x1, y3 - y, s, font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
-         y += ts.Height();
-         }
-      }
   y += font->Height();
   if (!isempty(Info->Description())) {
      textScroller.Set(osd, x1, y, x2 - x1, y3 - y, Info->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
diff -ruN vdr-1.7.16/skinsttng.c vdr-1.7.17/skinsttng.c
--- vdr-1.7.16/skinsttng.c	2010-02-13 14:30:59.000000000 +0100
+++ vdr-1.7.17/skinsttng.c	2011-02-20 14:02:49.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 2.5 2010/02/13 13:30:59 kls Exp $
+ * $Id: skinsttng.c 2.7 2011/02/20 13:02:49 kls Exp $
  */
 
 // Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
@@ -182,12 +182,17 @@
      int yt = (y0 + y1) / 2;
      int yb = (y6 + y7) / 2;
      osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - y7));
-     tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } };
-     if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+     tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 32 } }; // TrueColor
+     if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
      else {
-        tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } };
-        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } }; // 256 colors
+        if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+           osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        else {
+           tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } }; // 16 colors
+           osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+           }
         }
      osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
      osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
@@ -220,12 +225,17 @@
      y0 = 0;
      y1 = lineHeight;
      osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - y1));
-     tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } };
-     if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+     tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 32 } }; // TrueColor
+     if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
      else {
-        tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } };
-        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } }; // 256 colors
+        if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+           osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        else {
+           tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } }; // 16 colors
+           osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+           }
         }
      osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
      osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
@@ -397,21 +407,26 @@
   int yt = (y0 + y1) / 2;
   int yb = (y6 + y7) / 2;
   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop());
-  tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } };
-  if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+  tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 32 } }; // TrueColor
+  if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
   else {
-     tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } };
-     if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+     tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } }; // 256 colors
+     if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
      else {
-        tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 },
-                          { x0, y3, x3 - 1, y4 - 1, 1 },
-                          { x3, y3, x4 - 1, y4 - 1, 2 },
-                          { x4, y3, x7 - 1, y4 - 1, 2 },
-                          { x0, y4, x7 - 1, y7 - 1, 4 }
-                        };
-        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } }; // 16 colors
+        if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+           osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        else {
+           tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 }, // 2..16 colors
+                             { x0, y3, x3 - 1, y4 - 1, 1 },
+                             { x3, y3, x4 - 1, y4 - 1, 2 },
+                             { x4, y3, x7 - 1, y4 - 1, 2 },
+                             { x0, y4, x7 - 1, y7 - 1, 4 }
+                           };
+           osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+           }
         }
      }
   osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
@@ -612,14 +627,6 @@
      ts.Set(osd, xl, y, x4 - xl, y4 - y, Event->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
      y += ts.Height();
      }
-  for (int i = 0; Event->Contents(i); i++) {
-      const char *s = Event->ContentToString(Event->Contents(i));
-      if (!isempty(s)) {
-         const cFont *font = cFont::GetFont(fontSml);
-         ts.Set(osd, xl, y, x4 - xl, y4 - y, s, font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
-         y += ts.Height();
-         }
-      }
   y += font->Height();
   if (!isempty(Event->Description())) {
      int yt = y;
@@ -666,14 +673,6 @@
      ts.Set(osd, xl, y, x4 - xl, y4 - y, Info->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
      y += ts.Height();
      }
-  for (int i = 0; Info->GetEvent()->Contents(i); i++) {
-      const char *s = Info->GetEvent()->ContentToString(Info->GetEvent()->Contents(i));
-      if (!isempty(s)) {
-         const cFont *font = cFont::GetFont(fontSml);
-         ts.Set(osd, xl, y, x4 - xl, y4 - y, s, font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
-         y += ts.Height();
-         }
-      }
   y += font->Height();
   if (!isempty(Info->Description())) {
      int yt = y;
@@ -770,12 +769,17 @@
   int yt = (y0 + y1) / 2;
   int yb = (y6 + y7) / 2;
   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y7);
-  tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } };
-  if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+  tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 32 } }; // TrueColor
+  if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
   else {
-     tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } };
-     osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+     tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } }; // 256 colors
+     if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+     else {
+        tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } }; // 16 colors
+        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        }
      }
   osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, ModeOnly ? clrTransparent : Theme.Color(clrBackground));
   if (!ModeOnly) {
@@ -904,12 +908,17 @@
   y0 = 0;
   y1 = lineHeight;
   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1);
-  tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } };
-  if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+  tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 32 } }; // TrueColor
+  if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
   else {
-     tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } };
-     osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+     tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } }; // 256 colors
+     if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+     else {
+        tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } }; // 16 colors
+        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        }
      }
   osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
   osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
@@ -1019,21 +1028,26 @@
   int yt = (y0 + y1) / 2;
   int yb = (y6 + y7) / 2;
   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y7);
-  tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } };
-  if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+  tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 32 } }; // TrueColor
+  if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
   else {
-     tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } };
-     if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+     tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } }; // 256 colors
+     if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
      else {
-        tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 },
-                          { x0, y3, x3 - 1, y4 - 1, 1 },
-                          { x3, y3, x4 - 1, y4 - 1, 2 },
-                          { x4, y3, x7 - 1, y4 - 1, 2 },
-                          { x0, y4, x7 - 1, y7 - 1, 4 }
-                        };
-        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } }; // 16 colors
+        if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+           osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        else {
+           tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 }, // 2..16 colors
+                             { x0, y3, x3 - 1, y4 - 1, 1 },
+                             { x3, y3, x4 - 1, y4 - 1, 2 },
+                             { x4, y3, x7 - 1, y4 - 1, 2 },
+                             { x0, y4, x7 - 1, y7 - 1, 4 }
+                           };
+           osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+           }
         }
      }
   osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
@@ -1147,12 +1161,17 @@
   y0 = 0;
   y1 = lineHeight;
   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1);
-  tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } };
-  if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+  tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 32 } }; // TrueColor
+  if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
   else {
-     tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 2 } };
-     osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+     tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } }; // 256 colors
+     if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
+        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+     else {
+        tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 2 } }; // 4 colors
+        osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
+        }
      }
   osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
   osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
diff -ruN vdr-1.7.16/svdrp.c vdr-1.7.17/svdrp.c
--- vdr-1.7.16/svdrp.c	2010-01-17 13:23:31.000000000 +0100
+++ vdr-1.7.17/svdrp.c	2011-02-25 15:38:45.000000000 +0100
@@ -10,7 +10,7 @@
  * and interact with the Video Disk Recorder - or write a full featured
  * graphical interface that sits on top of an SVDRP connection.
  *
- * $Id: svdrp.c 2.8 2010/01/17 12:23:31 kls Exp $
+ * $Id: svdrp.c 2.9 2011/02/25 14:38:45 kls Exp $
  */
 
 #include "svdrp.h"
@@ -1664,8 +1664,16 @@
                  }
               else {
                  if (numChars >= length - 1) {
-                    length += BUFSIZ;
-                    cmdLine = (char *)realloc(cmdLine, length);
+                    int NewLength = length + BUFSIZ;
+                    if (char *NewBuffer = (char *)realloc(cmdLine, NewLength)) {
+                       length = NewLength;
+                       cmdLine = NewBuffer;
+                       }
+                    else {
+                       esyslog("ERROR: out of memory");
+                       Close();
+                       break;
+                       }
                     }
                  cmdLine[numChars++] = c;
                  cmdLine[numChars] = 0;
diff -ruN vdr-1.7.16/themes.c vdr-1.7.17/themes.c
--- vdr-1.7.16/themes.c	2008-02-10 17:25:00.000000000 +0100
+++ vdr-1.7.17/themes.c	2011-02-25 15:45:18.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: themes.c 2.0 2008/02/10 16:25:00 kls Exp $
+ * $Id: themes.c 2.1 2011/02/25 14:45:18 kls Exp $
  */
 
 #include "themes.h"
@@ -248,12 +248,30 @@
                  cString FileName = AddDirectory(themesDirectory, e->d_name);
                  cTheme Theme;
                  if (Theme.Load(*FileName, true)) {
-                    names = (char **)realloc(names, (numThemes + 1) * sizeof(char *));
-                    names[numThemes] = strdup(Theme.Name());
-                    fileNames = (char **)realloc(fileNames, (numThemes + 1) * sizeof(char *));
-                    fileNames[numThemes] = strdup(*FileName);
-                    descriptions = (char **)realloc(descriptions, (numThemes + 1) * sizeof(char *));
-                    descriptions[numThemes] = strdup(Theme.Description());
+                    if (char **NewBuffer = (char **)realloc(names, (numThemes + 1) * sizeof(char *))) {
+                       names = NewBuffer;
+                       names[numThemes] = strdup(Theme.Name());
+                       }
+                    else {
+                       esyslog("ERROR: out of memory");
+                       break;
+                       }
+                    if (char **NewBuffer = (char **)realloc(fileNames, (numThemes + 1) * sizeof(char *))) {
+                       fileNames = NewBuffer;
+                       fileNames[numThemes] = strdup(*FileName);
+                       }
+                    else {
+                       esyslog("ERROR: out of memory");
+                       break;
+                       }
+                    if (char **NewBuffer = (char **)realloc(descriptions, (numThemes + 1) * sizeof(char *))) {
+                       descriptions = NewBuffer;
+                       descriptions[numThemes] = strdup(Theme.Description());
+                       }
+                    else {
+                       esyslog("ERROR: out of memory");
+                       break;
+                       }
                     numThemes++;
                     }
                  }
diff -ruN vdr-1.7.16/tools.c vdr-1.7.17/tools.c
--- vdr-1.7.16/tools.c	2010-08-29 17:03:08.000000000 +0200
+++ vdr-1.7.17/tools.c	2011-02-25 15:58:31.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.c 2.8 2010/08/29 15:03:08 kls Exp $
+ * $Id: tools.c 2.12 2011/02/25 14:58:31 kls Exp $
  */
 
 #include "tools.h"
@@ -18,7 +18,6 @@
 #include <jpeglib.h>
 #undef boolean
 }
-#include <stdarg.h>
 #include <stdlib.h>
 #include <sys/time.h>
 #include <sys/vfs.h>
@@ -157,8 +156,14 @@
      int l  = strlen(s);
      int l1 = strlen(s1);
      int l2 = strlen(s2);
-     if (l2 > l1)
-        s = (char *)realloc(s, l + l2 - l1 + 1);
+     if (l2 > l1) {
+        if (char *NewBuffer = (char *)realloc(s, l + l2 - l1 + 1))
+           s = NewBuffer;
+        else {
+           esyslog("ERROR: out of memory");
+           return s;
+           }
+        }
      char *sof = s + of;
      if (l2 != l1)
         memmove(sof + l2, sof + l1, l - of - l1 + 1);
@@ -368,7 +373,7 @@
                     cString buffer = AddDirectory(FileName, e->d_name);
                     if (FollowSymlinks) {
                        struct stat st2;
-                       if (stat(buffer, &st2) == 0) {
+                       if (lstat(buffer, &st2) == 0) {
                           if (S_ISLNK(st2.st_mode)) {
                              int size = st2.st_size + 1;
                              char *l = MALLOC(char, size);
@@ -377,14 +382,12 @@
                                 if (errno != EINVAL)
                                    LOG_ERROR_STR(*buffer);
                                 }
-                             else if (n < size) {
+                             else {
                                 l[n] = 0;
                                 dsyslog("removing %s", l);
                                 if (remove(l) < 0)
                                    LOG_ERROR_STR(l);
                                 }
-                             else
-                                esyslog("ERROR: symlink name length (%d) exceeded anticipated buffer size (%d)", n, size);
                              free(l);
                              }
                           }
@@ -822,8 +825,15 @@
      size_t FromLength = strlen(From);
      char *ToPtr = To;
      if (!ToPtr) {
-        length = max(length, FromLength * 2); // some reserve to avoid later reallocations
-        result = (char *)realloc(result, length);
+        int NewLength = max(length, FromLength * 2); // some reserve to avoid later reallocations
+        if (char *NewBuffer = (char *)realloc(result, NewLength)) {
+           length = NewLength;
+           result = NewBuffer;
+           }
+        else {
+           esyslog("ERROR: out of memory");
+           return From;
+           }
         ToPtr = result;
         ToLength = length;
         }
@@ -839,8 +849,15 @@
                  // The result buffer is too small, so increase it:
                  size_t d = ToPtr - result;
                  size_t r = length / 2;
-                 length += r;
-                 Converted = result = (char *)realloc(result, length);
+                 int NewLength = length + r;
+                 if (char *NewBuffer = (char *)realloc(result, NewLength)) {
+                    length = NewLength;
+                    Converted = result = NewBuffer;
+                    }
+                 else {
+                    esyslog("ERROR: out of memory");
+                    return From;
+                    }
                  ToLength += r;
                  ToPtr = result + d;
                  }
@@ -887,6 +904,13 @@
   return *this;
 }
 
+cString &cString::operator=(const char *String)
+{
+  free(s);
+  s = String ? strdup(String) : NULL;
+  return *this;
+}
+
 cString &cString::Truncate(int Index)
 {
   int l = strlen(s);
@@ -1025,15 +1049,22 @@
   tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
   if (jcd) {
      int Used = jcd->size;
-     jcd->size += JPEGCOMPRESSMEM;
-     jcd->mem = (uchar *)realloc(jcd->mem, jcd->size);
+     int NewSize = jcd->size + JPEGCOMPRESSMEM;
+     if (uchar *NewBuffer = (uchar *)realloc(jcd->mem, NewSize)) {
+        jcd->size = NewSize;
+        jcd->mem = NewBuffer;
+        }
+     else {
+        esyslog("ERROR: out of memory");
+        return false;
+        }
      if (jcd->mem) {
         cinfo->dest->next_output_byte = jcd->mem + Used;
         cinfo->dest->free_in_buffer = jcd->size - Used;
-        return TRUE;
+        return true;
         }
      }
-  return FALSE;
+  return false;
 }
 
 static void JpegCompressTermDestination(j_compress_ptr cinfo)
@@ -1042,8 +1073,12 @@
   if (jcd) {
      int Used = cinfo->dest->next_output_byte - jcd->mem;
      if (Used < jcd->size) {
-        jcd->size = Used;
-        jcd->mem = (uchar *)realloc(jcd->mem, jcd->size);
+        if (uchar *NewBuffer = (uchar *)realloc(jcd->mem, Used)) {
+           jcd->size = Used;
+           jcd->mem = NewBuffer;
+           }
+        else
+           esyslog("ERROR: out of memory");
         }
      }
 }
diff -ruN vdr-1.7.16/tools.h vdr-1.7.17/tools.h
--- vdr-1.7.16/tools.h	2009-12-23 16:14:39.000000000 +0100
+++ vdr-1.7.17/tools.h	2011-02-25 16:05:58.000000000 +0100
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.h 2.4 2009/12/23 15:14:39 kls Exp $
+ * $Id: tools.h 2.7 2011/02/25 15:05:58 kls Exp $
  */
 
 #ifndef __TOOLS_H
@@ -17,6 +17,7 @@
 #include <iconv.h>
 #include <math.h>
 #include <poll.h>
+#include <stdarg.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -171,6 +172,7 @@
   operator const char * () const { return s; } // for use in (const char *) context
   const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.)
   cString &operator=(const cString &String);
+  cString &operator=(const char *String);
   cString &Truncate(int Index); ///< Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
   static cString sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
   static cString sprintf(const char *fmt, va_list &ap);
@@ -432,6 +434,10 @@
   {
     if (++Index > allocated) {
        data = (T *)realloc(data, Index * sizeof(T));
+       if (!data) {
+          esyslog("ERROR: out of memory - abort!");
+          abort();
+          }
        for (int i = allocated; i < Index; i++)
            data[i] = T(0);
        allocated = Index;
diff -ruN vdr-1.7.16/vdr.5 vdr-1.7.17/vdr.5
--- vdr-1.7.16/vdr.5	2010-05-16 14:15:48.000000000 +0200
+++ vdr-1.7.17/vdr.5	2010-12-24 16:19:21.000000000 +0100
@@ -8,7 +8,7 @@
 .\" License as specified in the file COPYING that comes with the
 .\" vdr distribution.
 .\"
-.\" $Id: vdr.5 2.19 2010/05/16 12:15:48 kls Exp $
+.\" $Id: vdr.5 2.21 2010/12/24 15:19:21 kls Exp $
 .\"
 .TH vdr 5 "10 Feb 2008" "1.6" "Video Disk Recorder Files"
 .SH NAME
@@ -114,7 +114,7 @@
 
 \fBGuard interval:\fR The guard interval value (DVB-T only): 4 = 1/4, 8 = 1/8, 16 = 1/16, 32 = 1/32.
 
-\fBInversion:\fR Specifes whether the DVB frontend needs spectral inversion (DVB-T and DVB-C only). This is frontend specific, if in doubt, omit.
+\fBInversion:\fR Specifies whether the DVB frontend needs spectral inversion (DVB-T and DVB-C only). This is frontend specific, if in doubt, omit.
 
 \fBModulation:\fR Specifies the modulation/constellation of the channel as follows:
 .TS
@@ -721,7 +721,7 @@
 .TS
 tab (|);
 l l.
-\fBF\fR|<frame duration>
+\fBF\fR|<frame rate>
 \fBL\fR|<lifetime>
 \fBP\fR|<priority>
 \fB@\fR|<auxiliary data>
diff -ruN vdr-1.7.16/vdr.c vdr-1.7.17/vdr.c
--- vdr-1.7.16/vdr.c	2010-04-05 12:06:16.000000000 +0200
+++ vdr-1.7.17/vdr.c	2010-12-12 14:42:00.000000000 +0100
@@ -22,7 +22,7 @@
  *
  * The project's page is at http://www.tvdr.de
  *
- * $Id: vdr.c 2.19 2010/04/05 10:06:16 kls Exp $
+ * $Id: vdr.c 2.20 2010/12/12 13:42:00 kls Exp $
  */
 
 #include <getopt.h>
@@ -937,7 +937,7 @@
            ShutdownHandler.SetUserInactiveTimeout();
            }
         // Keys that must work independent of any interactive mode:
-        switch (key) {
+        switch (int(key)) {
           // Menu control:
           case kMenu: {
                key = kNone; // nobody else needs to see this key
@@ -1185,7 +1185,7 @@
               cRemote::PutMacro(key);
               key = kNone;
               }
-           switch (key) {
+           switch (int(key)) {
              // Toggle channels:
              case kChanPrev:
              case k0: {
