diff -ruN vdr-1.3.46/CONTRIBUTORS vdr-1.3.47/CONTRIBUTORS
--- vdr-1.3.46/CONTRIBUTORS	2006-04-09 16:31:33.000000000 +0200
+++ vdr-1.3.47/CONTRIBUTORS	2006-04-17 14:18:50.000000000 +0200
@@ -1077,6 +1077,7 @@
  for speeding up cRemux::ScanVideoPacket()
  for implementing cDevice::ForceTransferMode()
  for changing the behaviour when hitting the end of a recording in fast forward mode
+ for suggesting to give the cRemote::CallPlugin() function a boolean return value
 
 Richard Robson <richard_robson@beeb.net>
  for reporting freezing replay if a timer starts while in Transfer Mode from the
@@ -1336,6 +1337,10 @@
  for improving OSD area handling in cDvbSpuDecoder
  for suggesting to log the description (if present) in case a thread is canceled
  for fixing handling DPID when deciding whether to switch to 'Transfer Mode'
+ for adding VBITeletextDescriptorTag, TeletextDescriptorTag, LocalTimeOffsetDescriptorTag
+ and PremiereContentTransmissionDescriptor to 'libsi'
+ for pointing out that plugins might be compiled with different DVB driver header
+ files than VDR itself
 
 J�rgen Schmitz <j.schmitz@web.de>
  for reporting a bug in displaying the current channel when switching via the SVDRP
@@ -1472,6 +1477,9 @@
  it won't follow symbolic links, and to canonicalize the file name
  for making all font and image data 'const'
  for fixing format string handling
+ for suggesting to add NULL checks to some strdup() calls in menuitems.c
+ for reporting a missing "Key$" in skincurses.c
+ for a patch that was used to implement kChanPrev
 
 Sean Carlos <seanc@libero.it>
  for translating OSD texts to the Italian language
@@ -1624,6 +1632,8 @@
  can use it
  for fixing converting arbitrarily formatted summary.vdr files
  for making the 'new' indicator in the Recordings menu kept up-to-date
+ for reporting a crash when setting the time transponder in the Setup menu
+ for reporting a bug in the initial setting of the time transponder setup parameter
 
 David Woodhouse <dwmw2@infradead.org>
  for his help in replacing the get/put_unaligned() macros from asm/unaligned.h with
@@ -1676,6 +1686,8 @@
  for suggesting that the cTimer constructor should take an optional cChannel
  for suggesting that any cReceivers still attached to a cDevice when that device
  switches to a different transponder shall be automatically detached
+ for reporting that characters 0x01 and 0x02 in recording names were a problem
+ with XML
 
 Ralf M�ller <ralf@bj-ig.de>
  for a patch that was used to implement cUnbufferedFile
@@ -1713,6 +1725,8 @@
 
 Christian Wieninger <cwieninger@gmx.de>
  for suggesting to add cMenuEditStrItem::InEditMode()
+ for his idea of going directly into the "Edit timer" menu for a timer created
+ from the "Schedule" menu in case it starts withing the next two minutes
 
 Thiemo Gehrke <tgehrke@reel-multimedia.com>
  for suggesting to add a setup option to turn off the automatic timeout of the
@@ -1772,7 +1786,7 @@
 
 Alexander Hans <cleditor@arcor.de>
  for reporting a crash when pressing '0' in the "Schedule" menu on a channel that
- doesn't have any EPG data 
+ doesn't have any EPG data
  for giving the DrawBitmap() function a new parameter 'Overlay' that allows a bitmap
  to be drawn with a transparent background
 
@@ -1785,6 +1799,8 @@
 
 Ronny Kornexl <ronny.kornexl@online.de>
  for reporting a problem with setting "No title" for broken event data
+ for suggesting to make the "Use small font" setup option *always* use the small
+ font if set to '3' - even if it would have been a fixed font
 
 B�rta Vladim�r <vladimir.barta@k2atmitec.cz>
  for translating OSD texts to the Czech language
@@ -1815,3 +1831,19 @@
 
 Jurij Retzlaff <jurij@topofweb.de>
  for fixing learning keys when VDR is already running
+
+Richard Lithvall <richard@lithvall.se>
+ for adding a tolerance for symbol rate values that are off by one
+
+Tobias Grimm <listaccount@e-tobi.net>
+ for suggesting to use geteuid() to check whether VDR is running as user 'root'
+
+Peter Dittmann <peter.dittmann@philips.com>
+ for a patch that was used as a base to implement cPlugin::Active()
+
+Helge Lenz <h.lenz@gmx.de>
+ for reporting a bug in setting the 'Delta' parameter when calling the shutdown
+ script with no active timer
+
+Peter Juszack <vdr@unterbrecher.de>
+ for a patch that was used as a base to implement kNext and kPrev
diff -ruN vdr-1.3.46/HISTORY vdr-1.3.47/HISTORY
--- vdr-1.3.46/HISTORY	2006-04-09 16:30:39.000000000 +0200
+++ vdr-1.3.47/HISTORY	2006-04-17 14:18:54.000000000 +0200
@@ -4499,3 +4499,123 @@
   --version option, to avoid error messages from plugins (reported by Udo Richter).
 - Now checking whether there is any text before calling cStatus::MsgOsdTextItem()
   (reported by Joachim Wilke).
+
+2006-04-17: Version 1.3.47
+
+- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
+- Fixed a crash when setting the time transponder in the Setup menu, caused by the
+  new 'noneString' in cMenuEditChanItem (reported by Thomas G�nther).
+- Added NULL checks to some strdup() calls in menuitems.c (suggested by Darren
+  Salt).
+- Removed the unnecessary 'value' member from cMenuEditItem.
+- Fixed the initial setting of the time transponder setup parameter (reported
+  by Thomas G�nther).
+- Fixed unnecessary Set() calls in cMenuEditIntItem::ProcessKey().
+- Allowing a tolerance for symbol rate values that are off by one (thanks to
+  Richard Lithvall).
+- Added VBITeletextDescriptorTag, TeletextDescriptorTag, LocalTimeOffsetDescriptorTag
+  and PremiereContentTransmissionDescriptor to 'libsi' (thanks to Marco Schl��ler).
+- Using geteuid() to check whether VDR is running as user 'root' (suggested by
+  Tobias Grimm).
+- Added a missing "Key$" in skincurses.c (reported by Darren Salt).
+- Reintroduced the log message "deleting plugin: ..." when shutting down VDR (upon
+  request by Ville Skytt�, as in the initial patch from Christoph Haubrich).
+- Fixed the vdr.1 man page (a single DVB card can record and do live tv).
+- The preferred audio language is now automatically selected when starting replay.
+- Updated the Danish OSD texts (thanks to Mogens Elneff).
+- The new function cPlugin::Active() can be used by a plugin to indicate that it
+  is still busy and the system should not shut down or restart (based on a patch
+  from Peter Dittmann). See PLUGINS.html for details.
+- Fixed setting the 'Delta' parameter when calling the shutdown script with
+  no active timer (reported by Helge Lenz).
+- In order to make sure that plugins are compiled with the same DVB driver header
+  files as VDR itself, the definition of DVBDIR has been removed from the VDR
+  Makefile. If you are using a driver version that has its header files at a location
+  other than /usr/include/linux/dvb, you can define DVBDIR in the Make.config
+  file (see also INSTALL). Any reference to DVBDIR should be removed from all
+  plugins' Makefiles, like this:
+
+  ------------------------------------------------------------
+  --- PLUGINS/src/hello/Makefile  2005/11/11 13:20:14     1.10
+  +++ PLUGINS/src/hello/Makefile  2006/04/15 11:58:46     1.11
+  @@ -20,7 +20,6 @@
+
+   ### The directory environment:
+
+  -DVBDIR = ../../../../DVB
+   VDRDIR = ../../..
+   LIBDIR = ../../lib
+   TMPDIR = /tmp
+  @@ -40,7 +39,7 @@
+
+   ### Includes and Defines (add further entries here):
+
+  -INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+  +INCLUDES += -I$(VDRDIR)/include
+
+   DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
+  ------------------------------------------------------------
+
+  Thanks to Marco Schl��ler for pointing out this problem.
+- Implemented kNext and kPrev keys (based on a patch from Peter Juszack).
+  See MANUAL for details.
+- Implemented kChanPrev (from a patch from Darren Salt).
+- The "Update channels" parameter in the "Setup/DVB" menu has been extended to
+  allow updating only the PIDs (see MANUAL for details). When updating to this
+  version of VDR, please verify that the setting is as you want it to be, because
+  the values have been shifted.
+- The new APIVERSION (see config.h) now allows existing compiled plugins to be
+  used with newer versions of VDR, as long as there have been no changes to the
+  VDR header files since the last APIVERSION. Existing plugins' Makefiles should
+  have all references to VDRVERSION changed to APIVERSION, like this:
+
+  ------------------------------------------------------------
+  --- PLUGINS/src/hello/Makefile  2006/04/15 11:58:46     1.11
+  +++ PLUGINS/src/hello/Makefile  2006/04/16 09:03:50     1.12
+  @@ -28,9 +28,9 @@
+
+   -include $(VDRDIR)/Make.config
+
+  -### The version number of VDR (taken from VDR's "config.h"):
+  +### The version number of VDR's plugin API (taken from VDR's "config.h"):
+
+  -VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+  +APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+
+   ### The name of the distribution archive:
+
+  @@ -67,7 +67,7 @@
+
+   libvdr-$(PLUGIN).so: $(OBJS)
+          $(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+  -       @cp $@ $(LIBDIR)/$@.$(VDRVERSION)
+  +       @cp $@ $(LIBDIR)/$@.$(APIVERSION)
+
+   dist: clean
+          @-rm -rf $(TMPDIR)/$(ARCHIVE)
+  ------------------------------------------------------------
+- If a timer is newly created from within the "Schedule" menu, and its event is
+  already running or has its start time within the next two minutes, it now goes
+  directly into the "Edit timer" menu in order to allow the user to make further
+  changes to timer parameters before the actual recording starts (inspired by
+  Christian Wieninger's "epgsearch" plugin).
+- Added format check to syslog_with_tid().
+- Updated the INSTALL file's section about non-VDR files in the video directory
+  (since version 1.3.38 disk access is done in a separate thread, so the watchdog
+  timer won't hit).
+- Changed the behaviour of the "Use small font" setup option to *always* use the small
+  font if set to '3' - even if it would have been a fixed font (suggested by Ronny
+  Kornexl).
+- No longer using characters 0x01 and 0x02 for mapping single quote and slash in
+  recording names (thanks to Patrick Fischer for reporting that this was a problem
+  with XML). The single quote is not mapped at all, and the slash is interchanged
+  with the tilde. Existing recordings will be handled like before, so there is
+  no need to actually rename them.
+- The cRemote::CallPlugin() function now has a boolean return value that tells
+  the caller whether initiating the plugin call was successful (suggested by
+  Reinhard Nissl). If it returns false, another plugin call is currently pending
+  and the caller should try again later. This also means that the SVDRP command
+  PLUG can now return an error code is the call fails.
+- The new function cPlugin::MainThreadHook() can be used by plugins to perform
+  actions in the context of the main program thread. Use this function with great
+  care and only of you absolutely have to! See also PLUGINS.html.
diff -ruN vdr-1.3.46/INSTALL vdr-1.3.47/INSTALL
--- vdr-1.3.46/INSTALL	2006-02-04 16:22:39.000000000 +0100
+++ vdr-1.3.47/INSTALL	2006-04-16 12:47:23.000000000 +0200
@@ -25,17 +25,12 @@
 
 VDR requires the Linux-DVB driver header files to compile.
 As of kernel 2.6 these are part of the official Linux kernel
-distribution, and VDR's Makefile will automatically locate
-them. If you are using kernel 2.4 or earlier, you should
-install the files from this package in a directory that is
-"parallel" to the DVB directory of the driver source (refer to
-http://linuxtv.org for more information about that driver).
-For example, if the DVB driver was extracted into the directory
-/home/kls/vdr/DVB, then this package should be extracted into
-/home/kls/vdr/VDR.
-If you have the DVB driver source in a different location
-you can rename the file Make.config.template to Make.config and
-adjust the definition of DVBDIR in that file.
+distribution, and so they should be automatically found in
+/usr/include/linux/dvb. If your DVB driver header files are
+in a different location, you can rename the file Make.config.template
+to Make.config and adjust the definition of DVBDIR in that file.
+
+Refer to http://linuxtv.org for more information about the Linux-DVB driver.
 
 VDR requires the Linux-DVB driver version dated 2003-08-23 or higher
 to work properly.
@@ -325,7 +320,7 @@
    vdr -v /video0
 
 Note that you should not copy any non-VDR files into the /videoX directories,
-since this might cause the watchdog timer to expire when VDR cleans up those
+since this might cause a lot of unnecessary disk access when VDR cleans up those
 directories and there is a large number of files and/or subdirectories in
 there.
 
diff -ruN vdr-1.3.46/MANUAL vdr-1.3.47/MANUAL
--- vdr-1.3.46/MANUAL	2006-04-09 15:22:49.000000000 +0200
+++ vdr-1.3.47/MANUAL	2006-04-16 12:15:20.000000000 +0200
@@ -45,8 +45,12 @@
   FastFwd     fast forward
   FastRew     fast rewind
 
+  Next        Next/previous channel group (in live tv mode)
+  Prev        or next/previous editing mark (in replay mode)
+
   Channel+    channel up
   Channel-    channel down
+  PrevChannel previous channel
 
   Power       shutdown
 
@@ -158,6 +162,10 @@
   default margin values will be sufficient, so in case this recording is
   really important you may want to add an extra margin ;-). VPS recordings
   will use the exact Start (or VPS) and Stop times as given in the event.
+  If a timer is newly created from within the "Schedule" menu, and its event is
+  already running or has its start time within the next two minutes, it goes
+  directly into the "Edit timer" menu in order to allow the user to make further
+  changes to timer parameters before the actual recording starts.
 
   The "Blue" button can be pressed to switch to the channel with the selected
   programme.
@@ -635,11 +643,11 @@
                          If turned off, Dolby Digital tracks also don't appear in the
                          "Audio" menu.
 
-  Update channels = 4    Controls the automatic channel update function. '0' means
+  Update channels = 5    Controls the automatic channel update function. '0' means
                          no update, '1' will only update channel names, '2' will
-                         update channel names and PIDs, '3' will perform all
-                         updates and also add newly found channels, and '4' will
-                         also add newly found transponders.
+                         only update PIDs, '3' will update channel names and PIDs,
+                         '4' will perform all updates and also add newly found channels,
+                         and '5' will also add newly found transponders.
 
   Audio languages = 0    Some tv stations broadcast various audio tracks in different
                          languages. This option allows you to define which language(s)
diff -ruN vdr-1.3.46/Make.config.template vdr-1.3.47/Make.config.template
--- vdr-1.3.46/Make.config.template	2006-01-13 17:06:11.000000000 +0100
+++ vdr-1.3.47/Make.config.template	2006-04-15 14:28:03.000000000 +0200
@@ -6,7 +6,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: Make.config.template 1.7 2006/01/13 16:06:11 kls Exp $
+# $Id: Make.config.template 1.8 2006/04/15 12:28:03 kls Exp $
 
 ### The C compiler and options:
 
@@ -18,7 +18,7 @@
 
 ### The directory environment:
 
-#DVBDIR   = ../DVB
+#DVBDIR   = /usr/src/v4l-dvb/linux
 MANDIR   = /usr/local/man
 BINDIR   = /usr/local/bin
 
@@ -33,3 +33,9 @@
 
 ## Define if you want vdr to not run as root
 #VDR_USER = vdr
+
+### You don't need to touch the following:
+
+ifdef DVBDIR
+INCLUDES += -I$(DVBDIR)/include
+endif
diff -ruN vdr-1.3.46/Makefile vdr-1.3.47/Makefile
--- vdr-1.3.46/Makefile	2006-02-05 14:37:11.000000000 +0100
+++ vdr-1.3.47/Makefile	2006-04-16 11:00:30.000000000 +0200
@@ -4,7 +4,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: Makefile 1.85 2006/02/05 13:37:11 kls Exp $
+# $Id: Makefile 1.87 2006/04/16 09:00:30 kls Exp $
 
 .DELETE_ON_ERROR:
 
@@ -14,16 +14,6 @@
 CXX      ?= g++
 CXXFLAGS ?= -fPIC -g -O2 -Wall -Woverloaded-virtual
 
-LINUX_VERSION := $(shell uname -r | cut -c-3)
-LINUX         := $(shell uname -r)
-DVBDIR        := /lib/modules/$(LINUX)/build
-ifeq ($(LINUX_VERSION), 2.4)
-   DVBDIR = ../DVB
-endif
-ifeq ($(LINUX_VERSION), 2.2)
-   DVBDIR = ../DVB
-endif
-
 LSIDIR   = ./libsi
 MANDIR   = /usr/local/man
 BINDIR   = /usr/local/bin
@@ -40,8 +30,6 @@
 
 -include Make.config
 
-INCLUDES += -I$(DVBDIR)/include
-
 SILIB    = $(LSIDIR)/libsi.a
 
 OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbosd.o\
@@ -91,9 +79,10 @@
 DEFINES += -DVIDEODIR=\"$(VIDEODIR)\"
 DEFINES += -DPLUGINDIR=\"$(PLUGINLIBDIR)\"
 
-# The version number of VDR (taken from VDR's "config.h"):
+# The version numbers of VDR and the plugin API (taken from VDR's "config.h"):
 
 VDRVERSION = $(shell grep 'define VDRVERSION ' config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+APIVERSION = $(shell grep 'define APIVERSION ' config.h | awk '{ print $$3 }' | sed -e 's/"//g')
 
 ifdef VFAT
 # for people who want their video directory on a VFAT partition
@@ -195,7 +184,7 @@
 
 clean-plugins:
 	@for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do $(MAKE) -C "$(PLUGINDIR)/src/$$i" clean; done
-	@-rm -f $(PLUGINDIR)/lib/libvdr-*.so.$(VDRVERSION)
+	@-rm -f $(PLUGINDIR)/lib/libvdr-*.so.$(APIVERSION)
 
 # Install the files:
 
@@ -227,7 +216,7 @@
 
 install-plugins: plugins
 	@mkdir -p $(PLUGINLIBDIR)
-	@cp $(PLUGINDIR)/lib/libvdr-*.so.$(VDRVERSION) $(PLUGINLIBDIR)
+	@cp $(PLUGINDIR)/lib/libvdr-*.so.$(APIVERSION) $(PLUGINLIBDIR)
 
 # Source documentation:
 
diff -ruN vdr-1.3.46/PLUGINS/src/hello/Makefile vdr-1.3.47/PLUGINS/src/hello/Makefile
--- vdr-1.3.46/PLUGINS/src/hello/Makefile	2005-11-11 14:20:14.000000000 +0100
+++ vdr-1.3.47/PLUGINS/src/hello/Makefile	2006-04-16 11:03:50.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.10 2005/11/11 13:20:14 kls Exp $
+# $Id: Makefile 1.12 2006/04/16 09:03:50 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -20,7 +20,6 @@
 
 ### The directory environment:
 
-DVBDIR = ../../../../DVB
 VDRDIR = ../../..
 LIBDIR = ../../lib
 TMPDIR = /tmp
@@ -29,9 +28,9 @@
 
 -include $(VDRDIR)/Make.config
 
-### The version number of VDR (taken from VDR's "config.h"):
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
 
-VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
 
 ### The name of the distribution archive:
 
@@ -40,7 +39,7 @@
 
 ### Includes and Defines (add further entries here):
 
-INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+INCLUDES += -I$(VDRDIR)/include
 
 DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
 
@@ -68,7 +67,7 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
-	@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
+	@cp $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.3.46/PLUGINS/src/osddemo/Makefile vdr-1.3.47/PLUGINS/src/osddemo/Makefile
--- vdr-1.3.46/PLUGINS/src/osddemo/Makefile	2005-11-11 14:20:14.000000000 +0100
+++ vdr-1.3.47/PLUGINS/src/osddemo/Makefile	2006-04-16 11:03:55.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.4 2005/11/11 13:20:14 kls Exp $
+# $Id: Makefile 1.6 2006/04/16 09:03:55 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -20,7 +20,6 @@
 
 ### The directory environment:
 
-DVBDIR = ../../../../DVB
 VDRDIR = ../../..
 LIBDIR = ../../lib
 TMPDIR = /tmp
@@ -29,9 +28,9 @@
 
 -include $(VDRDIR)/Make.config
 
-### The version number of VDR (taken from VDR's "config.h"):
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
 
-VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
 
 ### The name of the distribution archive:
 
@@ -40,7 +39,7 @@
 
 ### Includes and Defines (add further entries here):
 
-INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+INCLUDES += -I$(VDRDIR)/include
 
 DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
 
@@ -68,7 +67,7 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
-	@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
+	@cp $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.3.46/PLUGINS/src/servicedemo/Makefile vdr-1.3.47/PLUGINS/src/servicedemo/Makefile
--- vdr-1.3.46/PLUGINS/src/servicedemo/Makefile	2005-11-11 14:20:14.000000000 +0100
+++ vdr-1.3.47/PLUGINS/src/servicedemo/Makefile	2006-04-16 11:03:59.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.2 2005/11/11 13:20:14 kls Exp $
+# $Id: Makefile 1.4 2006/04/16 09:03:59 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -21,7 +21,6 @@
 
 ### The directory environment:
 
-DVBDIR = ../../../../DVB
 VDRDIR = ../../..
 LIBDIR = ../../lib
 TMPDIR = /tmp
@@ -30,9 +29,9 @@
 
 -include $(VDRDIR)/Make.config
 
-### The version number of VDR (taken from VDR's "config.h"):
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
 
-VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
 
 ### The name of the distribution archive:
 
@@ -41,7 +40,7 @@
 
 ### Includes and Defines (add further entries here):
 
-INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+INCLUDES += -I$(VDRDIR)/include
 
 DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
 
@@ -69,11 +68,11 @@
 
 libvdr-$(PLUGIN1).so: $(PLUGIN1).o
 	$(CXX) $(CXXFLAGS) -shared $(PLUGIN1).o -o $@
-	@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
+	@cp $@ $(LIBDIR)/$@.$(APIVERSION)
 
 libvdr-$(PLUGIN2).so: $(PLUGIN2).o
 	$(CXX) $(CXXFLAGS) -shared $(PLUGIN2).o -o $@
-	@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
+	@cp $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.3.46/PLUGINS/src/skincurses/HISTORY vdr-1.3.47/PLUGINS/src/skincurses/HISTORY
--- vdr-1.3.46/PLUGINS/src/skincurses/HISTORY	2005-11-26 14:53:31.000000000 +0100
+++ vdr-1.3.47/PLUGINS/src/skincurses/HISTORY	2006-04-14 13:36:41.000000000 +0200
@@ -25,3 +25,7 @@
 2005-11-26: Version 0.0.5
 
 - Fixed SetProgress() in case Total is 0.
+
+2006-04-14: Version 0.0.6
+
+- Added a missing "Key$" in skincurses.c.
diff -ruN vdr-1.3.46/PLUGINS/src/skincurses/Makefile vdr-1.3.47/PLUGINS/src/skincurses/Makefile
--- vdr-1.3.46/PLUGINS/src/skincurses/Makefile	2005-11-11 14:20:14.000000000 +0100
+++ vdr-1.3.47/PLUGINS/src/skincurses/Makefile	2006-04-16 11:04:04.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.2 2005/11/11 13:20:14 kls Exp $
+# $Id: Makefile 1.4 2006/04/16 09:04:04 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -20,7 +20,6 @@
 
 ### The directory environment:
 
-DVBDIR = ../../../../DVB
 VDRDIR = ../../..
 LIBDIR = ../../lib
 TMPDIR = /tmp
@@ -29,9 +28,9 @@
 
 -include $(VDRDIR)/Make.config
 
-### The version number of VDR (taken from VDR's "config.h"):
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
 
-VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
 
 ### The name of the distribution archive:
 
@@ -40,7 +39,7 @@
 
 ### Includes and Defines (add further entries here):
 
-INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+INCLUDES += -I$(VDRDIR)/include
 
 DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
 
@@ -68,7 +67,7 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -lncurses -o $@
-	@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
+	@cp $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.3.46/PLUGINS/src/skincurses/skincurses.c vdr-1.3.47/PLUGINS/src/skincurses/skincurses.c
--- vdr-1.3.46/PLUGINS/src/skincurses/skincurses.c	2005-11-26 14:52:39.000000000 +0100
+++ vdr-1.3.47/PLUGINS/src/skincurses/skincurses.c	2006-04-14 13:35:59.000000000 +0200
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: skincurses.c 1.7 2005/11/26 13:52:39 kls Exp $
+ * $Id: skincurses.c 1.8 2006/04/14 11:35:59 kls Exp $
  */
 
 #include <ncurses.h>
@@ -11,7 +11,7 @@
 #include <vdr/plugin.h>
 #include <vdr/skins.h>
 
-static const char *VERSION        = "0.0.5";
+static const char *VERSION        = "0.0.6";
 static const char *DESCRIPTION    = "A text only skin";
 static const char *MAINMENUENTRY  = NULL;
 
@@ -564,7 +564,7 @@
 {
   if (Mute) {
      osd->DrawRectangle(0, 0, OsdWidth - 1, 0, clrTransparent);
-     osd->DrawText(0, 0, tr("Mute"), clrGreen, clrBackground, &Font);
+     osd->DrawText(0, 0, tr("Key$Mute"), clrGreen, clrBackground, &Font);
      }
   else {
      const char *Prompt = tr("Volume ");
diff -ruN vdr-1.3.46/PLUGINS/src/sky/Makefile vdr-1.3.47/PLUGINS/src/sky/Makefile
--- vdr-1.3.46/PLUGINS/src/sky/Makefile	2005-11-11 14:20:14.000000000 +0100
+++ vdr-1.3.47/PLUGINS/src/sky/Makefile	2006-04-16 11:04:06.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.4 2005/11/11 13:20:14 kls Exp $
+# $Id: Makefile 1.6 2006/04/16 09:04:06 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -20,7 +20,6 @@
 
 ### The directory environment:
 
-DVBDIR = ../../../../DVB
 VDRDIR = ../../..
 LIBDIR = ../../lib
 TMPDIR = /tmp
@@ -29,9 +28,9 @@
 
 -include $(VDRDIR)/Make.config
 
-### The version number of VDR (taken from VDR's "config.h"):
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
 
-VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
 
 ### The name of the distribution archive:
 
@@ -40,7 +39,7 @@
 
 ### Includes and Defines (add further entries here):
 
-INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+INCLUDES += -I$(VDRDIR)/include
 
 DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
 
@@ -68,7 +67,7 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
-	@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
+	@cp $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.3.46/PLUGINS/src/status/Makefile vdr-1.3.47/PLUGINS/src/status/Makefile
--- vdr-1.3.46/PLUGINS/src/status/Makefile	2005-11-11 14:20:14.000000000 +0100
+++ vdr-1.3.47/PLUGINS/src/status/Makefile	2006-04-16 11:04:10.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.8 2005/11/11 13:20:14 kls Exp $
+# $Id: Makefile 1.10 2006/04/16 09:04:10 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -20,7 +20,6 @@
 
 ### The directory environment:
 
-DVBDIR = ../../../../DVB
 VDRDIR = ../../..
 LIBDIR = ../../lib
 TMPDIR = /tmp
@@ -29,9 +28,9 @@
 
 -include $(VDRDIR)/Make.config
 
-### The version number of VDR (taken from VDR's "config.h"):
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
 
-VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
 
 ### The name of the distribution archive:
 
@@ -40,7 +39,7 @@
 
 ### Includes and Defines (add further entries here):
 
-INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+INCLUDES += -I$(VDRDIR)/include
 
 DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
 
@@ -68,7 +67,7 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
-	@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
+	@cp $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.3.46/PLUGINS/src/svdrpdemo/Makefile vdr-1.3.47/PLUGINS/src/svdrpdemo/Makefile
--- vdr-1.3.46/PLUGINS/src/svdrpdemo/Makefile	2005-11-11 14:20:14.000000000 +0100
+++ vdr-1.3.47/PLUGINS/src/svdrpdemo/Makefile	2006-04-16 11:04:13.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.2 2005/11/11 13:20:14 kls Exp $
+# $Id: Makefile 1.4 2006/04/16 09:04:13 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
@@ -20,7 +20,6 @@
 
 ### The directory environment:
 
-DVBDIR = ../../../../DVB
 VDRDIR = ../../..
 LIBDIR = ../../lib
 TMPDIR = /tmp
@@ -29,9 +28,9 @@
 
 -include $(VDRDIR)/Make.config
 
-### The version number of VDR (taken from VDR's "config.h"):
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
 
-VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
 
 ### The name of the distribution archive:
 
@@ -40,7 +39,7 @@
 
 ### Includes and Defines (add further entries here):
 
-INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+INCLUDES += -I$(VDRDIR)/include
 
 DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
 
@@ -68,7 +67,7 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
-	@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
+	@cp $@ $(LIBDIR)/$@.$(APIVERSION)
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -ruN vdr-1.3.46/PLUGINS.html vdr-1.3.47/PLUGINS.html
--- vdr-1.3.46/PLUGINS.html	2006-02-05 14:38:17.000000000 +0100
+++ vdr-1.3.47/PLUGINS.html	2006-04-17 12:00:44.000000000 +0200
@@ -14,18 +14,18 @@
 <a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
 </center>
 <p>
-<!--X1.3.30--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
-Important modifications introduced in version 1.3.30 are marked like this.
-<!--X1.3.30--></td></tr></table>
-<!--X1.3.31--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
+<!--X1.3.31--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
 Important modifications introduced in version 1.3.31 are marked like this.
 <!--X1.3.31--></td></tr></table>
-<!--X1.3.37--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
+<!--X1.3.37--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
 Important modifications introduced in version 1.3.37 are marked like this.
 <!--X1.3.37--></td></tr></table>
-<!--X1.3.38--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<!--X1.3.38--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
 Important modifications introduced in version 1.3.38 are marked like this.
 <!--X1.3.38--></td></tr></table>
+<!--X1.3.47--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+Important modifications introduced in version 1.3.46 are marked like this.
+<!--X1.3.47--></td></tr></table>
 <p>
 VDR provides an easy to use plugin interface that allows additional functionality
 to be added to the program by implementing a dynamically loadable library file.
@@ -62,14 +62,16 @@
 <li><a href="#Main menu entry">Main menu entry</a>
 <li><a href="#User interaction">User interaction</a>
 <li><a href="#Housekeeping">Housekeeping</a>
+<!--X1.3.47--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<li><a href="#Main thread hook">Main thread hook</a>
+<li><a href="#Activity">Activity</a>
+<!--X1.3.47--></td></tr></table>
 <li><a href="#Setup parameters">Setup parameters</a>
 <li><a href="#The Setup menu">The Setup menu</a>
 <li><a href="#Configuration files">Configuration files</a>
 <li><a href="#Internationalization">Internationalization</a>
-<!--X1.3.30--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
 <li><a href="#Custom services">Custom services</a>
-<!--X1.3.30--></td></tr></table>
-<!--X1.3.31--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
+<!--X1.3.31--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
 <li><a href="#SVDRP commands">SVDRP commands</a>
 <!--X1.3.31--></td></tr></table>
 <li><a href="#Loading plugins into VDR">Loading plugins into VDR</a>
@@ -164,11 +166,20 @@
 The <tt>lib</tt> directory contains the dynamically loadable libraries of all
 available plugins. Note that the names of these files are created by concatenating
 <p>
+<!--X1.3.47--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
 <table border=2>
 <tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>hello</tt></b></td><td align=center><b><tt>.so.</tt></b></td><td align=center><b><tt>1.1.0</tt></b></td></tr>
-<tr><td align=center><font size=-1>VDR plugin<br>library prefix</font></td><td align=center><font size=-1>name of<br>the plugin</font></td><td align=center><font size=-1>shared object<br>indicator</font></td><td align=center><font size=-1>VDR version number<br>this plugin was<br>compiled for</font></td></tr>
+<tr><td align=center><font size=-1>VDR plugin<br>library prefix</font></td><td align=center><font size=-1>name of<br>the plugin</font></td><td align=center><font size=-1>shared object<br>indicator</font></td><td align=center><font size=-1>API version number<br>this plugin was<br>compiled for</font></td></tr>
 </table>
 <p>
+The <i>API version number</i> refers to the plugin API version number of the VDR
+version this plugin was compiled with. Compiled plugins can run with newer versions
+of VDR as long as their plugin API version number is still the same as that of
+the current VDR version. That way minor fixes to VDR, that don't require changes
+to the VDR header files, can be made without requiring all plugins to be
+recompiled.
+<!--X1.3.47--></td></tr></table>
+<p>
 The plugin library files can be stored in any directory. If the default organization
 is not used, the path to the plugin directory has be be given to VDR through the
 <b><tt>-L</tt></b> option.
@@ -609,6 +620,65 @@
 the plugin should launch a separate thread to do this.
 </b>
 
+<!--X1.3.47--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<a name="Main thread hook"><hr><h2>Main thread hook</h2>
+
+<center><i><b>Pushing in...</b></i></center><p>
+
+Normally a plugin only reacts on user input if directly called through its
+<a href="#Main menu entry">main menu entry</a>, or performs some background
+activity in a separate thread. However, sometimes a plugin may need to do
+something in the context of the main program thread, without being explicitly
+called up by the user. In such a case it can implement the function
+
+<p><table><tr><td bgcolor=#F0F0F0><pre>
+virtual void MainThreadHook(void);
+</pre></td></tr></table><p>
+
+in which it can do this. This function is called for every plugin once during
+every cycle of VDR's main program loop, which typically happens once every
+second.
+<b>Be very careful when using this function, and make sure you return from it
+as soon as possible! If you spend too much time in this function, the user
+interface performance will become sluggish!</b>
+
+<a name="Activity"><hr><h2>Activity</h2>
+
+<center><i><b>Now is not a good time!</b></i></center><p>
+
+If a plugin is running a background task that should be finished before shutting
+down the system, it can implement the function
+
+<p><table><tr><td bgcolor=#F0F0F0><pre>
+virtual cString Active(void);
+</pre></td></tr></table><p>
+
+which shall return an empty string if it is ok to shut down, and a proper message
+if not:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre>
+cString cDoSomethingPlugin::Active(void)
+{
+  if (busy)
+     return tr("Doing something");
+  return NULL;
+}
+</pre></td></tr></table><p>
+
+The message should be short and should indicate what is currently going on.
+It will be presented to the user as a confirmation message, followed by a
+hyphen and a "shut down anyway?" prompt, as in
+<p>
+<b>Doing something - shut down anyway?</b>
+<p>
+All plugins will be queried, and the first one that returns a non empty
+string will cause the confirmation message to be shown. If the user confirms
+the prompt by pressing the "Ok" button, the rest of the plugins will also
+be queried, and further prompts may show up. If all prompts have been confirmed,
+the shutdown will take place. As soon as one prompt is not confirmed, no
+further plugins will be queried and no shutdown will be done.
+<!--X1.3.47--></td></tr></table>
+
 <a name="Setup parameters"><hr><h2>Setup parameters</h2>
 
 <center><i><b>Remember me...</b></i></center><p>
@@ -864,7 +934,6 @@
 and then in the global VDR texts. So a plugin can make use of texts defined by the
 core VDR code.
 
-<!--X1.3.30--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
 <a name="Custom services"><hr><h2>Custom services</h2>
 
 <center><i><b>What can I do for you?</b></i></center><p>
@@ -933,9 +1002,7 @@
 <tt>cPluginManager::CallAllServices()</tt>. This function returns <tt>true</tt> if
 any plugin handled the request, or <tt>false</tt> if no plugin handled the request.
 
-<!--X1.3.30--></td></tr></table>
-
-<!--X1.3.31--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
+<!--X1.3.31--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
 <a name="SVDRP commands"><hr><h2>SVDRP commands</h2>
 
 <center><i><b>Infinite Diversity in Infinite Combinations</b></i></center><p>
@@ -1262,7 +1329,7 @@
   cMyControl(void);
   virtual ~cMyControl();
   virtual void Hide(void);
-<!--X1.3.38--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<!--X1.3.38--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
   virtual cOsdObject *GetInfo(void);
 <!--X1.3.38--></td></tr></table>
   virtual eOSState ProcessKey(eKeys Key);
@@ -1294,7 +1361,7 @@
 it has to hide itself from the OSD, in case it uses it. <tt>Hide()</tt> may be called at
 any time, and it may be called even if the <tt>cControl</tt> is not visible at the moment.
 <p>
-<!--X1.3.38--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<!--X1.3.38--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
 The <tt>GetInfo()</tt> function is called when the user presses the <tt>Info</tt> button,
 and shall return a pointer to a <tt>cOsdObject</tt> that contains information
 about the currently played programme. The caller takes ownership of the returned
@@ -1522,7 +1589,7 @@
 areas. Drawing areas are always rectangular and may not overlap (but do not need
 to be adjacent).
 
-<!--X1.3.37--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
+<!--X1.3.37--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
 <p>
 Directly accessing the OSD is only allowed from the foreground thread, which
 restricts this to a <tt>cOsdObject</tt> returned from the plugin's <tt>MainMenuAction()</tt>
diff -ruN vdr-1.3.46/UPDATE-1.4.0 vdr-1.3.47/UPDATE-1.4.0
--- vdr-1.3.46/UPDATE-1.4.0	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.3.47/UPDATE-1.4.0	2006-04-17 16:52:57.000000000 +0200
@@ -0,0 +1,334 @@
+This is a summary of the changes in VDR 1.4.0 since the last stable
+version 1.2.6. It only contains things that are of actual importance
+to the user and doesn't mention the many fixes and improvements that
+have been made "behind the scenes".
+
+See the file HISTORY for a detailed list of all changes.
+
+Plugins:
+
+- The new function cPlugin::Stop() shall be used to stop any background activities
+  of a plugin. Previously this was done in the plugin's desctructor, but it is
+  better to do this in a dedicated function that can be called early when shutting
+  down.
+- Added 'Service' functions to the plugin interface.
+  See PLUGINS.html, section "Custom services" for details.
+- Plugins can now implement their own SVDRP commands.
+  See PLUGINS.html, section "SVDRP commands" for details. The SVDRP commands
+  of a plugin are accessed through the new SVDRP command PLUG.
+- The main menu function of a plugin can now be activated through a key macro of
+  the form "@plugin" even if that plugin doesn't have a main menu entry.
+- The main menu function of a plugin can now be called programmatically through
+  the static function cRemote::CallPlugin().
+- The new function cPlugin::Active() can be used by a plugin to indicate that it
+  is still busy and the system should not shut down or restart.
+- The new APIVERSION (see config.h) now allows existing compiled plugins to be
+  used with newer versions of VDR, as long as there have been no changes to the
+  VDR header files since the last APIVERSION.
+- The new function cPlugin::MainThreadHook() can be used by plugins to perform
+  actions in the context of the main program thread.
+
+Skins:
+
+- The entire OSD display can now be implemented via "skins". See VDR/skins.[hc],
+  VDR/skinclassic.[hc], VDR/skinsttng.[hc] and PLUGINS.html for information on how
+  a plugin can implement its own skin. By default VDR comes with a "Classic" skin
+  that implements the OSD display known from previous versions, and the new skin
+  named "ST:TNG Panels", which is also the default skin now. The actual skin can
+  be selected through "Setup/OSD/Skin".
+- The colors used in a skin can now be configured using "themes". See PLUGINS.html
+  for information on how a skin can make use of themes, and man vdr(5) for the
+  structure of a theme file. The actual theme to use can be selected through
+  "Setup/OSD/Theme".
+
+Remote control:
+
+- Pressing the "Play" key in live viewing mode now resumes a previous replay
+  session (thanks to Mirko D�lle).
+- The new "Info" key brings up information on the currently viewed programme
+  or recording.
+- In string entry fields (like, e.g., the file name of a recording) the characters
+  can now be entered by pressing the numeric keys, the same way as on a
+  telephone keypad.
+- Key macros can now be defined for all non-modeless keys.
+- Switching channels with the Up/Down or Channel+/Channel- keys now works a lot
+  faster when the repeat function kicks in, by not actually switching the
+  channel every time, but rather only displaying the channel info and doing
+  the final switch when the key is released.
+- The "Back" key now restores the original string when pressed while editing a
+  string item.
+- The "Ok" key in the "Jump" mode of the replay progress display now confirms the
+  jump instead of closing the display.
+- Implemented kNext and kPrev keys.
+- Implemented kChanPrev.
+
+Devices:
+
+- Now waiting at startup until all DVB devices are ready. This includes having
+  all CAMs initialized and ready to decrypt, so that no more "channel not
+  available" happens if VDR is started with the current channel being an encrypted
+  one, or a timer on such a channel hits right after starting VDR.
+- The DVB devices now retune (and, if applicable, resend the DiSEqC data) if
+  the lock is lost.
+
+EPG:
+
+- Added support for selecting preferred EPG languages.
+- The "Red" button in the "Setup/EPG" menu can now be used to force an EPG
+  scan on a single DVB card system.
+- Implemented an "EPG linger time", which can be set to have older EPG information
+  still displayed in the "Schedule" menu.
+- The "Schedule" and "What's on now/next?" menus now have an additional column
+  which displays information on whether there is a timer defined for an event,
+  whether an event has a VPS time that's different than its start time, and
+  whether an event is currently running.
+- The format of the 'epg.data' files has been extended by the new tag 'X', which
+  contains the stream components of an event.
+- Modified the EPG scan so that it uses the primary device if it is
+  replaying and is the only device that provides the given transponder, and that
+  a forced EPG scan works even if EPG scan timeout is set to 0.
+- Removed EPG bugfix #0, because it removed actually important data.
+- No longer removing superfluous hyphens in EPG data - would become too
+  language dependent to handle all kinds of exceptions.
+- EPG events that are no longer in the currently broadcasted data stream are
+  now automatically deleted.
+- Schedules are now cleaned up once every hour (not only at 05:00).
+- The "Red" button in the "Schedule", "What's on now/next?" and "Event" menus
+  now immediately creates a timer for the selected event and marks it with 'T'.
+  If the event is already marked with 'T', the "Red" button opens the "Edit
+  timer" menu for that timer.
+- Pressing '0' in the "Schedule" menu now rotates through displaying "This event on
+  this channel", "This event on all channels" and "All events on all channels".
+  This can be used to find reruns of a given show, or the episodes of a series.
+  Note that if there are many channels in your channels.conf, displaying the
+  "All events on all channels" page may take a while.
+- The epg.data file is now written when VDR exits.
+- The 'event id' in EPG data has been extended to 32 bit, so that external tools
+  can generate ids that don't collide with those from the DVB data stream.
+- The status changes of EPG events are now logged for all channels that have timers.
+
+OSD:
+
+- Changed font handling to allow language specific character sets.
+- Adopted the small font character set from the "Elchi" patch
+- Increased the maximum number of possible OSD colors to 256.
+- Now using the 'running status' in the channel display, so that a programme
+  that has an end time that is before the current time, but is still running,
+  will still be shown in the display (provided the broadcasters handle the
+  'running status' flag correctly). This also applies to programmes that have
+  a start time that is in the future, but are already running.
+- The new setup option "OSD/Use small font" can be used to control the use of
+  the small font.
+- The new OSD setup parameters "Left" and "Top" can be used to define the top left
+  corner of the OSD.
+- The OSD size prameters are now in pixel (as opposed to formerly characters).
+  When reading a 'setup.conf' file from an older version of VDR, the OSDwidth
+  and OSDheight values will be converted to pixel automatically.
+- The OSD is now fully device independent. See the comments in VDR/osd.h and the
+  description in PLUGINS.html for information on how a plugin can implement an OSD
+  display on arbitrary hardware.
+- The OSD (actually its cBitmap class) can now handle XPM files. There are several
+  XPM files in the VDR/symbols directory which can be used by skins (some of these
+  have been taken from the "elchi" patch).
+- Due to the changes in the OSD handling the DEBUG_OSD option for a textual OSD
+  has been dropped. A textual OSD can now be displayed with the "skincurses"
+  plugin.
+- Single shot timers and events now show the day of week.
+- The new setup option "OSD/Channel info time" can be used to define the time after
+  which the channel display is removed if no key has been pressed.
+- The "Summary" button in the "Recordings" menu has been renamed to "Info", and
+  the page it brings up now shows the recording's information, much like the EPG
+  event page.
+- The new setup option "OSD/Scroll wraps" can be used to activate wrapping around
+  in menu lists.
+- The main menu now dynamically updates its contents in case an instant
+  recording or replay stops, etc.
+- The new option "Setup/OSD/Timeout requested channel info" can be used to turn
+  off the automatic timeout of the channel display in case it was invoked by
+  a press of the "Ok" key.
+
+Channels:
+
+- Channel data is now automatically derived from the DVB data stream
+- Channel names in 'channels.conf' can now have a short form, as provided
+  by some tv stations.
+- There can now be up to 32 audio and 16 Dolby PIDs.
+- The audio and Dolby PIDs in 'channels.conf' now can have an optional language
+  code.
+- Fixed transponder handling to make it work with satellites that provide two
+  transponders on the same frequency, with different polarization.
+- Now storing the name of the service provider (aka "bouquet") in the channel
+  name, separated by a semicolon.
+- The "Channels" menu can now be sorted "by number" (default), "by name" and
+  "by provider". While in the "Channels" menu, pressing the '0' key switches
+  through these modes.
+- Added support for circular polarization.
+- When reading the channels.conf file, duplicate channels (i.e. ones that have
+  the same channel ID) are now automatically deleted and only the first one is
+  actually stored.
+- In the "Channels" menu the numeric keys now position the cursor to the channel
+  with the given number.
+- The "Mark/Move" function in the "Channels" menu now also works in the non-numeric
+  sort modes.
+- The "Update channels" parameter in the "Setup/DVB" menu has been extended to
+  allow updating only the PIDs.
+
+Timers:
+
+- The '0' key now toggles the "Day" item in the "Timers" menu between "single
+  shot" and "repeating". The keys '1'...'7' can be used to toggle the individual
+  days ('1' is monday).
+- The day of a timer is now stored as a full date in ISO notation ("YYYY-MM-DD") in
+  'timers.conf' and for the result of the SVDRP command LSTT
+- The timer status now has a new bit that is set when that timer is currently
+  recording.
+- The 'summary' field of a timer definition has been renamed to 'aux', and is now
+  only used for external applications to store auxiliary information with a timer,
+  which has no meaning whatsoever to VDR itself.
+  The contents of the 'aux' field of a timer is copied into the recording's
+  'info.vdr' file, using the tag character '@'.
+- The description of a recording is now taken exclusively from its related EPG
+  data. If an application wants to use a different description it needs to set
+  it with SVDRP/PUTE and use table ID 0x00, so that it won't be overwritten (as
+  a side effect, however, this also disables VPS for such an event).
+- There is no more "Summary" menu when pressing "Ok" in the "Timers" menu.
+  The "Ok" key now always opens the "Edit timer" menu.
+- The upper 16 bit of a timer's "flags" are no longer treated specially when a timer
+  is modified in the "Edit timer" menu. If an external application needs to know if
+  a timer was modified, it has to keep a copy of the timer's data and compare that
+  to the actual data.
+- The option "Setup/OSD/Sort timers" has been removed. Timers are always sorted
+  by their start time and priority.
+- The "Blue" key in the "Timers" menu now displays the EPG info of the event the
+  selected timer will record (if available). The "On/Off" function has been shifted
+  to the "Red" button. Editing a timer is done by pressing "Ok".
+
+Recording:
+
+- Implemented handling the VPS timestamps (aka "Programme Identification Label")
+  for full VPS support for timers (provided the tv stations actually broadcast
+  this information). The VPS time is displayed in the event info page if it exists
+  and is different than the event's start time.
+- Timers can now be set to use the VPS information to control recording a programme.
+  The new setup options "Recording/Use VPS" and "Recording/VPS margin", as well as
+  the "VPS" option in the individual timers, can be used to control this feature
+- Now preferring budget cards when selecting a DVB device for recording.
+- The file 'summary.vdr' has been replaced with 'info.vdr' and now contains the
+  information about a recording, in the same format as the events are stored in
+  'epg.data'.
+- Recordings are now only started if there is at least 300MB free disk space.
+- No longer using characters 0x01 and 0x02 for mapping single quote and slash in
+  recording names.
+  The single quote is not mapped at all, and the slash is interchanged
+  with the tilde. Existing recordings will be handled like before, so there is
+  no need to actually rename them.
+
+SVDRP:
+
+- The new SVDRP command 'SCAN' can be used to force  an EPG scan on a single
+  DVB card system.
+- Extended the SVDRP command LSTE to allow limiting the listed data to a given
+  channel, the present or following events, or events at a given time.
+- The SVDRP command LSTR now lists the recording information in the same tagged
+  format as the LSTE command lists the EPG data.
+- The new SVDRP command PLAY can be used to start replaying a recording.
+- The new SVDRP command EDIT can be used to start the editing process of a recording.
+- The new SVDRP command PLUG can be used to call a plugin's main menu function.
+- Implemented the SVDRP command MOVC.
+- The SVDRP command GRAB now determines the image type (JPEG or PNM) from the
+  extension (".jpg", ".jpeg" or ".pnm") of the given file name. The explicit
+  'jpeg' or 'pnm' parameter is still accepted for backward compatibility, but
+  has no meaning any more.
+- The SVDRP command GRAB now writes the image data to the SVDRP connection
+  (encoded in base64) if the given file name consists of only the file
+  extension (".jpg", ".jpeg" or ".pnm"), or if only "-" is given as file
+  name.
+- The new command line option '-g' must be given if the SVDRP command GRAB
+  shall be allowed to write image files to disk. The parameter to this option
+  must be the full path name of an existing directory, without any "..", double
+  '/' or symlinks. By default, or if "-g- is given, grabbing to files is
+  not allowed any more because of potential security risks.
+- The SVDRP command LSTT now accepts the new option 'id' to have the channels
+  of the timers listed with their unique channel ids instead of their numbers.
+
+Audio:
+
+- AC3 audio can now be output directly over the full featured DVB cards.
+- The new remote control button "Audio" can be used to switch between different
+  audio tracks. The "Green" button in the "Main" menu has been changed from "Language"
+  to "Audio", since it now also controls switching between normal and Dolby Digital
+  audio tracks.
+- The description of the audio tracks is now taken from the "component descriptors"
+  that are broadcast in the EPG data. However (as no big surprise), not all channels
+  actually provide useful data here, so there are now some additional EPG bugfixes,
+  which can be activated by setting the "EPG bugfix level" to 3.
+- The new setup option "DVB/Audio languages" can be used to control which audio
+  language shall be selected in case a channel broadcasts in different languages.
+- The "Left" and "Right" keys in the "Audio" menu can be used to switch between
+  the left and right stereo channels in case there are different audio tracks
+  in these channels.
+- The setup option "Recording/Record Dobly Digital" has been renamed and moved to
+  "DVB/Use Dolby Digital". It now controls whether Dolby Digital is recorded and
+  whether an available DD audio track will appear in the "Audio" menu.
+- Recording and Transfer Mode now handle more than 2 audio PIDs.
+
+Conditional Access:
+
+- Improved CAM handling.
+- The file 'ca.conf' has been removed. VDR now automatically detects which
+  device contains a CAM that can decode a channel.
+- Removed the now obsolete CaCaps stuff. The Setup/CICAM menu now displays the
+  actual CAM type as reported by the CAM.
+- The Setup/CICAM menu now only contains the devices that actually have a CI and
+  dynamically detects the number of slots a CI provides.
+- The CAM menu now automatically updates itself in case of a progress display (as
+  used, for instance, when updating the firmware via satellite).
+- Improved the CAM enquiry menu.
+
+Internationalization:
+
+- Added Russian language texts.
+- Added Croatian language texts.
+- Added Estonian language texts.
+- Added Danish language texts.
+- Added Czech language texts.
+
+Misc:
+
+- Changed thread handling to make it work with NPTL ("Native Posix Thread Library").
+- The list of recordings is now kept statically in memory to avoid long delays
+  when opening the "Recordings" menu. As a side effect, external modifications to
+  the video directory are no longer immediately reflected in the "Recordings" menu.
+  If a plugin manipulates the video directory in any way, it can call the function
+  Recordings.TriggerUpdate() to trigger an update of the list of recordings.
+  If some external tool manipulates the video directory, it can touch the file
+  '.update' in the video directory to trigger an update of the list of recordings.
+- The new setup option "DVB/Video display format" can be used to define which display
+  format to use for playing wide screen video on a 4:3 tv set.
+- Added the command line options '--lirc', '--rcu' and '--no-kbd' to allow setting
+  the remote control at runtime.
+- Pressing Ok while entering a channel number now immediately switches to that
+  channel, without waiting for further input.
+- The new command line option '--vfat' can be used to make VDR encode special
+  characters in recording file names, even if it wasn't compiled with VFAT=1
+  The compile time option VFAT still exists and creates a VDR that always behaves
+  as if it were called with '--vfat'.
+- Replaced the ':' delimiter between hour and minute in recording file names with
+  a '.' under Linux, too. Existing recordings with ':' as delimiter will still work.
+- The list of recordings is now read in a separate thread, resulting in a faster
+  startup if there are a great many of recordings, or the disk(s) have to spin up.
+- When displaying the amount of free disk space, the space consumed by
+  recordings that have been "deleted" but not yet actually "removed" is now
+  taken into account.
+- Removing deleted recordings is now done in a separate thread.
+- When started as user 'root' VDR can now switch to a lesser privileged user id,
+  keeping the capability to set the system time. The 'runvdr' script has been
+  changed to use the new '-u' option.
+- The Makefile now reports a summary of failed plugins.
+- Removed the "buffer reserve" in Transfer Mode - it's no longer necessary with
+  recent driver/firmware versions.
+- The initial channel and volume can now be defined in the "Setup/Miscellaneous"
+  menu.
+- In order to make sure that plugins are compiled with the same DVB driver header
+  files as VDR itself, the definition of DVBDIR has been removed from the VDR
+  Makefile. It can now be defined, if necessary, in Make.config.
diff -ruN vdr-1.3.46/channels.c vdr-1.3.47/channels.c
--- vdr-1.3.46/channels.c	2006-02-28 14:54:34.000000000 +0100
+++ vdr-1.3.47/channels.c	2006-04-17 14:18:57.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: channels.c 1.49 2006/02/28 13:54:34 kls Exp $
+ * $Id: channels.c 1.51 2006/04/17 12:18:57 kls Exp $
  */
 
 #include "channels.h"
@@ -293,6 +293,9 @@
   // Sometimes the transponder frequency is set to 0, which is just wrong
   if (Frequency == 0)
      return false;
+  // Sometimes the symbol rate is off by one
+  if (abs(srate - Srate) <= 1)
+     Srate = srate;
 
   if (source != Source || frequency != Frequency || polarization != Polarization || srate != Srate || coderateH != CoderateH) {
      if (Number()) {
diff -ruN vdr-1.3.46/channels.conf vdr-1.3.47/channels.conf
--- vdr-1.3.46/channels.conf	2006-04-09 16:52:40.000000000 +0200
+++ vdr-1.3.47/channels.conf	2006-04-17 13:46:31.000000000 +0200
@@ -28,7 +28,7 @@
 HSE24,HSE24;BetaDigital:12480:vC34:S19.2E:27500:1279:1280=deu:37:0:40:133:33:0
 Bloomberg TV Germany;Bloomberg:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:1108:0
 EURONEWS;CSAT:11817:vC34:S19.2E:27500:163:92=fra,91=rus,93=eng,94=ita,95=esl,98=por,99=deu:0:0:8004:1:1070:0
-rbb Brandenburg;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28205:1:1073:0
+rbb Brandenburg;ARD:12109:hC34:S19.2E:27500:501:502=deu:504:0:28205:1:1073:0
 Sky News;BT:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0
 Veronica/JETIX;CANALDIGITAAL:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,100:5020:53:1109:0
 BVN;CANALDIGITAAL:12574:hC56:S19.2E:22000:515+8190:96=dut:36:0:5025:53:1109:0
@@ -47,9 +47,9 @@
 PREMIERE START,START;PREMIERE:11797:hC34:S19.2E:27500:255:256=deu:32:1722,1801,1702:8:133:2:0
 PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1:10:133:2:0
 PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1:11:133:2:0
-PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1:43:133:2:0
-PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu:32:1:9:133:2:0
-PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu:32:1:29:133:2:0
+PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu:32:1:43:133:2:0
+PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu,769=deu:32:1:9:133:2:0
+PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:32:1:29:133:2:0
 PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1:41:133:2:0
 PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1702,1801,1722:20:133:2:0
 DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:32:1:34:133:17:0
@@ -80,7 +80,7 @@
 ASTRA-Mosaic 4;SES ASTRA:12551:vC56:S19.2E:22000:185:170=fra:0:0:3985:1:1108:0
 ASTRA-Mosaic 5;SES ASTRA:12551:vC56:S19.2E:22000:163:164:0:0:3984:1:1108:0
 Chamber TV;Chambre des D�put�es:12551:vC56:S19.2E:22000:55:56=ltz:0:0:12180:1:1108:0
-RTL TELE Letzebuerg:12551:vC56:S19.2E:22000:168:144=eng,146=fra,151=ltz:74:0:3994:1:1108:0
+RTL TELE Letzebuerg:12551:vC56:S19.2E:22000:168:144=eng,146=fra,151=ltz:0:0:3994:1:1108:0
 Nick/Talpa;CANALDIGITAAL:12574:hC56:S19.2E:22000:512+8190:84=dut:33:622,100:5010:53:1109:0
 NICK;MTV Networks:12226:hC34:S19.2E:27500:513+8190:661=deu:577:0:28640:1:1091:0
 MTV Central;MTV Networks:11739:vC34:S19.2E:27500:3031:3032:3034:0:28653:1:1066:0
@@ -116,9 +116,9 @@
 Sky Movies 1;BSkyB:11836:hC23:S28.2E:27500:518+8190:646=eng,653=NAR;666=eng:582:960,961:4303:2:2007:0
 Sky Movies 2;BSkyB:11836:hC23:S28.2E:27500:519+8190:647=eng,655=NAR;667=eng:583:960,961:4302:2:2007:0
 Sky Movies 3;BSkyB:11836:hC23:S28.2E:27500:520+8190:648=eng,654=NAR;668=eng:584:960,961:4403:2:2007:0
-Sky Movies 4;BSkyB:11914:hC23:S28.2E:27500:512+8190:640=eng,655=NAR:576:960,961:4402:2:2011:0
-Sky Movies 5;BSkyB:11914:hC23:S28.2E:27500:515+8190:643=eng,656=NAR:579:960,961:4503:2:2011:0
-Sky Movies 6;BSkyB:11914:hC23:S28.2E:27500:513+8190:641=eng,657=NAR:577:960,961:4502:2:2011:0
+Sky Movies 4;BSkyB:11914:hC23:S28.2E:27500:512+8190:640=eng,655=NAR;660=eng:576:960,961:4402:2:2011:0
+Sky Movies 5;BSkyB:11914:hC23:S28.2E:27500:515+8190:643=eng,656=NAR;663=eng:579:960,961:4503:2:2011:0
+Sky Movies 6;BSkyB:11914:hC23:S28.2E:27500:513+8190:641=eng,657=NAR;661=eng:577:960,961:4502:2:2011:0
 Sky Movies 7;BSkyB:12285:vC23:S28.2E:27500:515+8190:643=eng,653=NAR;663=eng:579:960,961:4603:2:2030:0
 Sky Movies 8;BSkyB:11836:hC23:S28.2E:27500:515+8190:643=eng,656=NAR;663=eng:579:960,961:5502:2:2007:0
 Sky Movies 9;BSkyB:12285:vC23:S28.2E:27500:518+8190:646=eng,654=NAR;666=eng:2440:960,961:4602:2:2030:0
diff -ruN vdr-1.3.46/config.c vdr-1.3.47/config.c
--- vdr-1.3.46/config.c	2006-04-09 14:12:01.000000000 +0200
+++ vdr-1.3.47/config.c	2006-04-17 14:43:57.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.c 1.143 2006/04/09 12:12:01 kls Exp $
+ * $Id: config.c 1.145 2006/04/17 12:43:57 kls Exp $
  */
 
 #include "config.h"
@@ -20,7 +20,7 @@
 // format characters in order to allow any number of blanks after a numeric
 // value!
 
-// --- cCommand -------------------------------------------------------------
+// --- cCommand --------------------------------------------------------------
 
 char *cCommand::result = NULL;
 
@@ -251,7 +251,7 @@
   RecordingDirs = 1;
   VideoDisplayFormat = 1;
   VideoFormat = 0;
-  UpdateChannels = 4;
+  UpdateChannels = 5;
   UseDolbyDigital = 1;
   ChannelInfoPos = 0;
   ChannelInfoTime = 5;
diff -ruN vdr-1.3.46/config.h vdr-1.3.47/config.h
--- vdr-1.3.46/config.h	2006-04-09 14:09:05.000000000 +0200
+++ vdr-1.3.47/config.h	2006-04-16 11:36:10.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 1.249 2006/04/09 12:09:05 kls Exp $
+ * $Id: config.h 1.251 2006/04/16 09:36:10 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -19,8 +19,21 @@
 #include "i18n.h"
 #include "tools.h"
 
-#define VDRVERSION  "1.3.46"
-#define VDRVERSNUM   10346  // Version * 10000 + Major * 100 + Minor
+// VDR's own version number:
+
+#define VDRVERSION  "1.3.47"
+#define VDRVERSNUM   10347  // Version * 10000 + Major * 100 + Minor
+
+// The plugin API's version number:
+
+#define APIVERSION  "1.3.47"
+#define APIVERSNUM   10347  // 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
+// VDR header files since the last APIVERSION. This allows compiled
+// plugins to work with newer versions of the core VDR as long as no
+// VDR header files have changed.
 
 #define MAXPRIORITY 99
 #define MAXLIFETIME 99
diff -ruN vdr-1.3.46/device.c vdr-1.3.47/device.c
--- vdr-1.3.46/device.c	2006-04-09 12:46:36.000000000 +0200
+++ vdr-1.3.47/device.c	2006-04-14 16:34:43.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.c 1.127 2006/04/09 10:46:36 kls Exp $
+ * $Id: device.c 1.128 2006/04/14 14:34:43 kls Exp $
  */
 
 #include "device.h"
@@ -790,14 +790,19 @@
      }
 }
 
-void cDevice::ClrAvailableTracks(bool DescriptionsOnly)
+void cDevice::ClrAvailableTracks(bool DescriptionsOnly, bool IdsOnly)
 {
   if (DescriptionsOnly) {
      for (int i = ttNone; i < ttMaxTrackTypes; i++)
          *availableTracks[i].description = 0;
      }
   else {
-     memset(availableTracks, 0, sizeof(availableTracks));
+     if (IdsOnly) {
+        for (int i = ttNone; i < ttMaxTrackTypes; i++)
+            availableTracks[i].id = 0;
+        }
+     else
+        memset(availableTracks, 0, sizeof(availableTracks));
      pre_1_3_19_PrivateStream = false;
      SetAudioChannel(0); // fall back to stereo
      currentAudioTrackMissingCount = 0;
@@ -954,7 +959,7 @@
      pesAssembler->Reset();
      player = Player;
      if (!Transferring())
-        ClrAvailableTracks();
+        ClrAvailableTracks(false, true);
      SetPlayMode(player->playMode);
      player->device = this;
      player->Activate(true);
diff -ruN vdr-1.3.46/device.h vdr-1.3.47/device.h
--- vdr-1.3.46/device.h	2006-04-02 15:08:13.000000000 +0200
+++ vdr-1.3.47/device.h	2006-04-14 16:35:13.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 1.74 2006/04/02 13:08:13 kls Exp $
+ * $Id: device.h 1.75 2006/04/14 14:35:13 kls Exp $
  */
 
 #ifndef __DEVICE_H
@@ -356,7 +356,11 @@
   virtual void SetAudioTrackDevice(eTrackType Type);
        ///< Sets the current audio track to the given value.
 public:
-  void ClrAvailableTracks(bool DescriptionsOnly = false);
+  void ClrAvailableTracks(bool DescriptionsOnly = false, bool IdsOnly = false);
+       ///< Clears the list of currently availabe tracks. If DescriptionsOnly
+       ///< is true, only the track descriptions will be cleared. With IdsOnly
+       ///< set to true only the ids will be cleared. IdsOnly is only taken
+       ///< into account if DescriptionsOnly is false.
   bool SetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, const char *Description = NULL);
        ///< Sets the track of the given Type and Index to the given values.
        ///< Type must be one of the basic eTrackType values, like ttAudio or ttDolby.
diff -ruN vdr-1.3.46/dvbplayer.c vdr-1.3.47/dvbplayer.c
--- vdr-1.3.46/dvbplayer.c	2006-04-09 15:47:11.000000000 +0200
+++ vdr-1.3.47/dvbplayer.c	2006-04-17 14:45:48.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbplayer.c 1.44 2006/04/09 13:47:11 kls Exp $
+ * $Id: dvbplayer.c 1.45 2006/04/17 12:45:48 kls Exp $
  */
 
 #include "dvbplayer.h"
@@ -15,7 +15,7 @@
 #include "thread.h"
 #include "tools.h"
 
-// --- cBackTrace ----------------------------------------------------------
+// --- cBackTrace ------------------------------------------------------------
 
 #define AVG_FRAME_SIZE 15000         // an assumption about the average frame size
 #define DVB_BUF_SIZE   (256 * 1024)  // an assumption about the dvb firmware buffer size
diff -ruN vdr-1.3.46/dvbspu.c vdr-1.3.47/dvbspu.c
--- vdr-1.3.46/dvbspu.c	2006-02-12 12:50:20.000000000 +0100
+++ vdr-1.3.47/dvbspu.c	2006-04-17 14:45:05.000000000 +0200
@@ -8,7 +8,7 @@
  *
  * parts of this file are derived from the OMS program.
  *
- * $Id: dvbspu.c 1.20 2006/02/12 11:50:20 kls Exp $
+ * $Id: dvbspu.c 1.21 2006/04/17 12:45:05 kls Exp $
  */
 
 #include "dvbspu.h"
@@ -42,7 +42,7 @@
 #define DEBUG(format, args...)
 #endif
 
-// --- cDvbSpuPalette----------------------------------
+// --- cDvbSpuPalette---------------------------------------------------------
 
 void cDvbSpuPalette::setPalette(const uint32_t * pal)
 {
@@ -50,7 +50,7 @@
         palette[i] = yuv2rgb(pal[i]);
 }
 
-// --- cDvbSpuBitmap --------------------------------------------
+// --- cDvbSpuBitmap ---------------------------------------------------------
 
 #define setMin(a, b) if (a > b) a = b
 #define setMax(a, b) if (a < b) a = b
@@ -208,7 +208,7 @@
     }
 }
 
-// --- cDvbSpuDecoder-----------------------------
+// --- cDvbSpuDecoder---------------------------------------------------------
 
 #define CMD_SPU_MENU            0x00
 #define CMD_SPU_SHOW            0x01
diff -ruN vdr-1.3.46/dvbspu.h vdr-1.3.47/dvbspu.h
--- vdr-1.3.46/dvbspu.h	2006-01-05 11:18:31.000000000 +0100
+++ vdr-1.3.47/dvbspu.h	2006-04-17 14:47:29.000000000 +0200
@@ -8,7 +8,7 @@
  *
  * parts of this file are derived from the OMS program.
  *
- * $Id: dvbspu.h 1.11 2006/01/05 10:18:31 kls Exp $
+ * $Id: dvbspu.h 1.12 2006/04/17 12:47:29 kls Exp $
  */
 
 #ifndef __DVBSPU_H
@@ -46,7 +46,7 @@
 
 sDvbSpuRect;
 
-// --- cDvbSpuPalette----------------------------------
+// --- cDvbSpuPalette---------------------------------------------------------
 
 class cDvbSpuPalette {
   private:
@@ -60,7 +60,7 @@
     uint32_t getColor(uint8_t idx, uint8_t trans) const;
 };
 
-// --- cDvbSpuBitmap----------------------------------
+// --- cDvbSpuBitmap----------------------------------------------------------
 
 class cDvbSpuBitmap {
 
@@ -87,7 +87,7 @@
                        sDvbSpuRect & size) const;
 };
 
-// --- cDvbSpuDecoder------------------------------------
+// --- cDvbSpuDecoder---------------------------------------------------------
 
 class cDvbSpuDecoder:public cSpuDecoder {
   private:
@@ -151,7 +151,7 @@
     void processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow);
 };
 
-// --- cDvbSpuPalette -------------------------------------------
+// --- cDvbSpuPalette --------------------------------------------------------
 
 inline uint32_t cDvbSpuPalette::yuv2rgb(uint32_t yuv_color)
 {
diff -ruN vdr-1.3.46/eit.c vdr-1.3.47/eit.c
--- vdr-1.3.46/eit.c	2006-02-19 10:51:02.000000000 +0100
+++ vdr-1.3.47/eit.c	2006-04-15 16:11:52.000000000 +0200
@@ -8,7 +8,7 @@
  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
  * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
  *
- * $Id: eit.c 1.115 2006/02/19 09:51:02 kls Exp $
+ * $Id: eit.c 1.116 2006/04/15 14:11:52 kls Exp $
  */
 
 #include "eit.h"
@@ -180,10 +180,10 @@
                        if (link != channel) { // only link to other channels, not the same one
                           //fprintf(stderr, "Linkage %s %4d %4d %5d %5d %5d %5d  %02X  '%s'\n", hit ? "*" : "", channel->Number(), link ? link->Number() : -1, SiEitEvent.getEventId(), ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId(), ld->getLinkageType(), linkName);//XXX
                           if (link) {
-                             if (Setup.UpdateChannels >= 1)
+                             if (Setup.UpdateChannels == 1 || Setup.UpdateChannels >= 3)
                                 link->SetName(linkName, "", "");
                              }
-                          else if (Setup.UpdateChannels >= 3) {
+                          else if (Setup.UpdateChannels >= 4) {
                              link = Channels.NewChannel(channel, linkName, "", "", ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId());
                              //XXX patFilter->Trigger();
                              }
diff -ruN vdr-1.3.46/epg.c vdr-1.3.47/epg.c
--- vdr-1.3.46/epg.c	2006-03-26 16:06:11.000000000 +0200
+++ vdr-1.3.47/epg.c	2006-04-17 14:18:59.000000000 +0200
@@ -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 1.70 2006/03/26 14:06:11 kls Exp $
+ * $Id: epg.c 1.71 2006/04/17 12:18:59 kls Exp $
  */
 
 #include "epg.h"
@@ -698,7 +698,7 @@
   const cEvent *p = GetPresentEvent();
   if (p)
      p = events.Next(p);
-  else { 
+  else {
      time_t now = time(NULL);
      for (p = events.First(); p; p = events.Next(p)) {
          if (p->StartTime() >= now)
diff -ruN vdr-1.3.46/epg2html.pl vdr-1.3.47/epg2html.pl
--- vdr-1.3.46/epg2html.pl	2004-03-28 13:15:01.000000000 +0200
+++ vdr-1.3.47/epg2html.pl	2006-04-17 14:19:08.000000000 +0200
@@ -12,7 +12,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: epg2html.pl 1.6 2004/03/28 11:15:01 kls Exp $
+# $Id: epg2html.pl 1.7 2006/04/17 12:19:08 kls Exp $
 
 @Index = ();
 
@@ -95,4 +95,3 @@
 print INDEX sort { lc($a) cmp lc($b) } @Index;
 print INDEX "</body>\n</html>\n";
 close(INDEX);
-   
diff -ruN vdr-1.3.46/font.c vdr-1.3.47/font.c
--- vdr-1.3.46/font.c	2006-02-05 14:49:10.000000000 +0100
+++ vdr-1.3.47/font.c	2006-04-16 12:59:15.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: font.c 1.12 2006/02/05 13:49:10 kls Exp $
+ * $Id: font.c 1.13 2006/04/16 10:59:15 kls Exp $
  */
 
 #include "config.h"
@@ -123,7 +123,7 @@
 {
   if (Setup.UseSmallFont == 0 && Font == fontSml)
      Font = fontOsd;
-  else if (Setup.UseSmallFont == 2 && Font == fontOsd)
+  else if (Setup.UseSmallFont == 2)
      Font = fontSml;
   if (!fonts[Font])
      SetFont(Font);
diff -ruN vdr-1.3.46/i18n.c vdr-1.3.47/i18n.c
--- vdr-1.3.46/i18n.c	2006-04-09 15:04:50.000000000 +0200
+++ vdr-1.3.47/i18n.c	2006-04-15 16:13:45.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: i18n.c 1.255 2006/04/09 13:04:50 kls Exp $
+ * $Id: i18n.c 1.261 2006/04/15 14:13:45 kls Exp $
  *
  * Translations provided by:
  *
@@ -1275,6 +1275,28 @@
     "Vil du virkelig genstarte?",
     "Opravdu restartovat?",
   },
+  { "shut down anyway?",
+    "trotzdem ausschalten?",
+    "zares izklopi?",
+    "spengo comunque?",
+    "toch uitschakelen?",
+    "quer mesmo desligar?",
+    "confirmez l'arr�t",
+    "sl� av likevel?",
+    "sammutetaanko?",
+    "wy��czy� mimo to?",
+    "�apagar igualmente?",
+    "������ �� ����� �����������?",
+    "vill du �nd� avbryta?",
+    "�nchid, totu�i?",
+    "m�gis kikapcsolni?",
+    "Apagar de totes maneres?",
+    "������������� ���������?",
+    "svejedno isklju�iti?",
+    "l�litan v�lja?",
+    "sluk alligevel?",
+    "p�esto vypnout?",
+  },
   { "Recording - restart anyway?",
     "Aufnahme l�uft - trotzdem neu starten?",
     "Snemanje - zares ponoven zagon?",
@@ -2254,6 +2276,7 @@
     "",//TODO
     "",//TODO
     "",//TODO
+    "VPS-tallennus on alkamassa!",
     "",//TODO
     "",//TODO
     "",//TODO
@@ -2264,8 +2287,7 @@
     "",//TODO
     "",//TODO
     "",//TODO
-    "",//TODO
-    "",//TODO
+    "VPS optagelse starter snart!",
     "",//TODO
   },
   { "No free DVB device to record!",
@@ -3700,6 +3722,28 @@
     "kun navne",
     "jen n�zvy",
   },
+  { "PIDs only",
+    "nur PIDs",
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+  },
   { "names and PIDs",
     "Namen und PIDs",
     "imena in PIDe",
@@ -4412,6 +4456,7 @@
     "",// TODO
     "",// TODO
     "",// TODO
+    "Kanava k�ynnistett�ess�",
     "",// TODO
     "",// TODO
     "",// TODO
@@ -4422,8 +4467,7 @@
     "",// TODO
     "",// TODO
     "",// TODO
-    "",// TODO
-    "",// TODO
+    "Kanal ved opstart",
     "",// TODO
   },
   { "Setup.Miscellaneous$Initial volume",
@@ -4434,6 +4478,7 @@
     "",// TODO
     "",// TODO
     "",// TODO
+    "��nenvoimakkuus k�ynnistett�ess�",
     "",// TODO
     "",// TODO
     "",// TODO
@@ -4444,8 +4489,7 @@
     "",// TODO
     "",// TODO
     "",// TODO
-    "",// TODO
-    "",// TODO
+    "Lydstyrke ved opstart",
     "",// TODO
   },
   { "Setup.Miscellaneous$as before",
@@ -4456,6 +4500,7 @@
     "",// TODO
     "",// TODO
     "",// TODO
+    "edellinen",
     "",// TODO
     "",// TODO
     "",// TODO
@@ -4466,8 +4511,7 @@
     "",// TODO
     "",// TODO
     "",// TODO
-    "",// TODO
-    "",// TODO
+    "som før",
     "",// TODO
   },
   // The days of the week:
@@ -5267,6 +5311,50 @@
     "Spol tilbage",
     "Dozadu",
   },
+  { "Key$Next",
+    "Vorw�rts",
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+  },
+  { "Key$Prev",
+    "Zur�ck",
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+  },
   { "Key$Power",
     "Ausschalten",
     "Izklop",
@@ -5333,6 +5421,28 @@
     "Kanal-",
     "Kan�l-",
   },
+  { "Key$PrevChannel",
+    "Vorheriger Kanal",
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+    "",// TODO
+  },
   { "Key$Volume+",
     "Lautst�rke+",
     "Glasnost+",
diff -ruN vdr-1.3.46/keys.c vdr-1.3.47/keys.c
--- vdr-1.3.46/keys.c	2006-01-16 18:01:25.000000000 +0100
+++ vdr-1.3.47/keys.c	2006-04-15 15:50:43.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: keys.c 1.11 2006/01/16 17:01:25 kls Exp $
+ * $Id: keys.c 1.13 2006/04/15 13:50:43 kls Exp $
  */
 
 #include "keys.h"
@@ -39,9 +39,12 @@
                     { kRecord,        "Record"     },
                     { kFastFwd,       "FastFwd"    },
                     { kFastRew,       "FastRew"    },
+                    { kNext,          "Next"       },
+                    { kPrev,          "Prev"       },
                     { kPower,         "Power"      },
                     { kChanUp,        "Channel+"   },
                     { kChanDn,        "Channel-"   },
+                    { kChanPrev,      "PrevChannel"},
                     { kVolUp,         "Volume+"    },
                     { kVolDn,         "Volume-"    },
                     { kMute,          "Mute"       },
diff -ruN vdr-1.3.46/keys.h vdr-1.3.47/keys.h
--- vdr-1.3.46/keys.h	2006-01-05 16:39:06.000000000 +0100
+++ vdr-1.3.47/keys.h	2006-04-15 15:56:03.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: keys.h 1.7 2006/01/05 15:39:06 kls Exp $
+ * $Id: keys.h 1.9 2006/04/15 13:56:03 kls Exp $
  */
 
 #ifndef __KEYS_H
@@ -33,9 +33,12 @@
              kRecord,
              kFastFwd,
              kFastRew,
+             kNext,
+             kPrev,
              kPower,
              kChanUp,
              kChanDn,
+             kChanPrev,
              kVolUp,
              kVolDn,
              kMute,
diff -ruN vdr-1.3.46/libsi/descriptor.c vdr-1.3.47/libsi/descriptor.c
--- vdr-1.3.46/libsi/descriptor.c	2006-02-25 11:06:05.000000000 +0100
+++ vdr-1.3.47/libsi/descriptor.c	2006-04-17 14:19:15.000000000 +0200
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: descriptor.c 1.18 2006/02/25 10:06:05 kls Exp $
+ *   $Id: descriptor.c 1.20 2006/04/17 12:19:15 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -318,6 +318,31 @@
    languageCode[3]=0;
 }
 
+void TeletextDescriptor::Parse() {
+   //this descriptor is only a header and a loop
+   teletextLoop.setData(data+sizeof(descr_teletext), getLength()-sizeof(descr_teletext));
+}
+
+void TeletextDescriptor::Teletext::Parse() {
+   s=data.getData<const item_teletext>();
+   languageCode[0]=s->lang_code1;
+   languageCode[1]=s->lang_code2;
+   languageCode[2]=s->lang_code3;
+   languageCode[3]=0;
+}
+
+int TeletextDescriptor::Teletext::getTeletextType() const {
+   return s->type;
+}
+
+int TeletextDescriptor::Teletext::getTeletextMagazineNumber() const {
+   return s->magazine_number;
+}
+
+int TeletextDescriptor::Teletext::getTeletextPageNumber() const {
+   return s->page_number;
+}
+
 int CaDescriptor::getCaType() const {
    return HILO(s->CA_type);
 }
@@ -536,6 +561,14 @@
    description.setData(data+offset, getLength()-offset);
 }
 
+void PrivateDataSpecifierDescriptor::Parse() {
+   s=data.getData<const descr_private_data_specifier>();
+}
+
+int PrivateDataSpecifierDescriptor::getPrivateDataSpecifier() const {
+   return (HILO(s->private_data_specifier_hi) << 16) | HILO(s->private_data_specifier_lo);
+}
+
 void SubtitlingDescriptor::Parse() {
    subtitlingLoop.setData(data+sizeof(descr_subtitling), getLength()-sizeof(descr_subtitling));
 }
@@ -633,11 +666,47 @@
    name.setData(data+offset, mid->service_name_length);
 }
 
+void LocalTimeOffsetDescriptor::Parse() {
+   localTimeOffsetLoop.setData(data+sizeof(descr_local_time_offset), getLength()-sizeof(descr_local_time_offset));
+}
+
+int LocalTimeOffsetDescriptor::LocalTimeOffset::getCountryId() const {
+   return s->country_region_id;
+}
+
+int LocalTimeOffsetDescriptor::LocalTimeOffset::getLocalTimeOffsetPolarity() const {
+   return s->local_time_offset_polarity;
+}
+
+int LocalTimeOffsetDescriptor::LocalTimeOffset::getLocalTimeOffset() const {
+   return (s->local_time_offset_h << 8) | s->local_time_offset_m;
+}
+
+time_t LocalTimeOffsetDescriptor::LocalTimeOffset::getTimeOfChange() const {
+   return DVBTime::getTime(s->time_of_change_mjd_hi, s->time_of_change_mjd_lo, s->time_of_change_time_h, s->time_of_change_time_m, s->time_of_change_time_s);
+}
+
+int LocalTimeOffsetDescriptor::LocalTimeOffset::getNextTimeOffset() const {
+   return (s->next_time_offset_h << 8) | s->next_time_offset_m;
+}
+
+void LocalTimeOffsetDescriptor::LocalTimeOffset::Parse() {
+   s=data.getData<const local_time_offset_entry>();
+   countryCode[0]=s->country_code1;
+   countryCode[1]=s->country_code2;
+   countryCode[2]=s->country_code3;
+   countryCode[3]=0;
+}
+
 void LinkageDescriptor::Parse() {
    int offset=0;
+   s1 = NULL;
    data.setPointerAndOffset<const descr_linkage>(s, offset);
-   if (checkSize(getLength()-offset))
+   if (checkSize(getLength()-offset)) {
+      if (getLinkageType() == LinkageTypeMobileHandover)
+         data.setPointerAndOffset<const descr_linkage_8>(s1, offset);
       privateData.assign(data.getData(offset), getLength()-offset);
+      }
 }
 
 int LinkageDescriptor::getTransportStreamId() const {
@@ -656,9 +725,21 @@
    return (LinkageType)s->linkage_type;
 }
 
+int LinkageDescriptor::getHandOverType() const {
+   return s1 == NULL ? 0 : s1->hand_over_type;
+}
+
+int LinkageDescriptor::getOriginType() const {
+   return s1 == NULL ? 0 : s1->origin_type;
+}
+
+int LinkageDescriptor::getId() const {
+   return s1 == NULL ? 0 : HILO(s1->id);
+}
+
 void ISO639LanguageDescriptor::Parse() {
    languageLoop.setData(data+sizeof(descr_iso_639_language), getLength()-sizeof(descr_iso_639_language));
-   
+
    //all this is for backwards compatibility only
    Loop::Iterator it;
    Language first;
@@ -704,6 +785,44 @@
    return s->pil2 & 0x3F;
 }
 
+void AncillaryDataDescriptor::Parse() {
+   int offset=0;
+   data.setPointerAndOffset<const descr_ancillary_data>(s, offset);
+}
+
+int AncillaryDataDescriptor::getAncillaryDataIdentifier() const {
+   return s->ancillary_data_identifier;
+}
+
+int PremiereContentTransmissionDescriptor::getOriginalNetworkId() const {
+   return HILO(s->original_network_id);
+}
+
+int PremiereContentTransmissionDescriptor::getTransportStreamId() const {
+   return HILO(s->transport_stream_id);
+}
+
+int PremiereContentTransmissionDescriptor::getServiceId() const {
+   return HILO(s->service_id);
+}
+
+int PremiereContentTransmissionDescriptor::getMJD() const {
+   return HILO(s->mjd);
+}
+
+void PremiereContentTransmissionDescriptor::Parse() {
+   s=data.getData<const descr_premiere_content_transmission>();
+   startTimeLoop.setData(data+sizeof(descr_premiere_content_transmission), getLength()-sizeof(descr_premiere_content_transmission));
+}
+
+time_t PremiereContentTransmissionDescriptor::StartTimeEntry::getStartTime(int mjd) const {
+   return DVBTime::getTime(mjd >> 8, mjd & 0xff, s->start_time_h, s->start_time_m, s->start_time_s);
+}
+
+void PremiereContentTransmissionDescriptor::StartTimeEntry::Parse() {
+   s=data.getData<const item_premiere_content_transmission_reference>();
+}
+
 void ApplicationSignallingDescriptor::Parse() {
    entryLoop.setData(data+sizeof(descr_application_signalling), getLength()-sizeof(descr_application_signalling));
 }
diff -ruN vdr-1.3.46/libsi/descriptor.h vdr-1.3.47/libsi/descriptor.h
--- vdr-1.3.46/libsi/descriptor.h	2005-09-03 17:17:35.000000000 +0200
+++ vdr-1.3.47/libsi/descriptor.h	2006-04-14 12:53:44.000000000 +0200
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: descriptor.h 1.13 2005/09/03 15:17:35 kls Exp $
+ *   $Id: descriptor.h 1.14 2006/04/14 10:53:44 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -121,6 +121,25 @@
    virtual void Parse();
 };
 
+class TeletextDescriptor : public Descriptor {
+public:
+   class Teletext : public LoopElement {
+   public:
+      char languageCode[4];
+      int getTeletextType() const;
+      int getTeletextMagazineNumber() const;
+      int getTeletextPageNumber() const;
+      virtual int getLength() { return sizeof(item_teletext); }
+   protected:
+      virtual void Parse();
+   private:
+      const item_teletext *s;
+   };
+   StructureLoop<Teletext> teletextLoop;
+protected:
+   virtual void Parse();
+};
+
 class CaDescriptor : public Descriptor {
 public:
    int getCaType() const;
@@ -281,6 +300,15 @@
    const descr_component *s;
 };
 
+class PrivateDataSpecifierDescriptor : public Descriptor {
+public:
+   int getPrivateDataSpecifier() const;
+protected:
+   virtual void Parse();
+private:
+   const descr_private_data_specifier *s;
+};
+
 class SubtitlingDescriptor : public Descriptor {
 public:
    class Subtitling : public LoopElement {
@@ -377,17 +405,42 @@
    virtual void Parse();
 };
 
+class LocalTimeOffsetDescriptor : public Descriptor {
+public:
+   class LocalTimeOffset : public LoopElement {
+   public:
+      char countryCode[4];
+      virtual int getLength() { return sizeof(local_time_offset_entry); }
+      int getCountryId() const;
+      int getLocalTimeOffsetPolarity() const;
+      int getLocalTimeOffset() const;
+      time_t getTimeOfChange() const;
+      int getNextTimeOffset() const;
+   protected:
+      virtual void Parse();
+   private:
+      const local_time_offset_entry *s;
+   };
+   StructureLoop<LocalTimeOffset> localTimeOffsetLoop;
+protected:
+   virtual void Parse();
+};
+
 class LinkageDescriptor : public Descriptor {
 public:
    int getTransportStreamId() const;
    int getOriginalNetworkId() const;
    int getServiceId() const;
    LinkageType getLinkageType() const;
+   int getHandOverType() const;
+   int getOriginType() const;
+   int getId() const;
    CharArray privateData;
 protected:
    virtual void Parse();
 private:
    const descr_linkage *s;
+   const descr_linkage_8 *s1;
 };
 
 class ISO639LanguageDescriptor : public Descriptor {
@@ -422,6 +475,41 @@
    const descr_pdc *s;
 };
 
+class AncillaryDataDescriptor : public Descriptor {
+public:
+   int getAncillaryDataIdentifier() const;
+protected:
+   virtual void Parse();
+private:
+   const descr_ancillary_data *s;
+};
+
+// Private DVB Descriptor  Premiere.de
+// 0xF2  Content Transmission Descriptor
+// http://dvbsnoop.sourceforge.net/examples/example-private-section.html
+
+class PremiereContentTransmissionDescriptor : public Descriptor {
+public:
+   class StartTimeEntry : public LoopElement {
+   public:
+      virtual int getLength() { return sizeof(item_premiere_content_transmission_reference); }
+      time_t getStartTime(int mjd) const; //UTC
+   protected:
+      virtual void Parse();
+   private:
+      const item_premiere_content_transmission_reference *s;
+   };
+   StructureLoop<StartTimeEntry> startTimeLoop;
+   int getOriginalNetworkId() const;
+   int getTransportStreamId() const;
+   int getServiceId() const;
+   int getMJD() const;
+protected:
+   virtual void Parse();
+private:
+   const descr_premiere_content_transmission *s;
+};
+
 //a descriptor currently unimplemented in this library
 class UnimplementedDescriptor : public Descriptor {
 protected:
diff -ruN vdr-1.3.46/libsi/headers.h vdr-1.3.47/libsi/headers.h
--- vdr-1.3.46/libsi/headers.h	2005-09-03 17:18:16.000000000 +0200
+++ vdr-1.3.47/libsi/headers.h	2006-04-14 12:53:44.000000000 +0200
@@ -10,7 +10,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: headers.h 1.5 2005/09/03 15:18:16 kls Exp $
+ *   $Id: headers.h 1.6 2006/04/14 10:53:44 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -769,6 +769,57 @@
    /* descriptors  */
 };
 
+/* Premiere Content Information Table */
+
+#define PCIT_LEN 17
+
+struct pcit {
+   u_char table_id                               :8;
+#if BYTE_ORDER == BIG_ENDIAN
+   u_char section_syntax_indicator               :1;
+   u_char dummy                                  :1; // has to be 0
+   u_char                                        :2;
+   u_char section_length_hi                      :4;
+#else
+   u_char section_length_hi                      :4;
+   u_char                                        :2;
+   u_char dummy                                  :1; // has to be 0
+   u_char section_syntax_indicator               :1;
+#endif
+   u_char section_length_lo                      :8;
+   u_char                                        :8;
+   u_char                                        :8;
+#if BYTE_ORDER == BIG_ENDIAN
+   u_char                                        :2;
+   u_char version_number                         :5;
+   u_char current_next_indicator                 :1;
+#else
+   u_char current_next_indicator                 :1;
+   u_char version_number                         :5;
+   u_char                                        :2;
+#endif
+   u_char section_number                         :8;
+   u_char last_section_number                    :8;
+
+   u_char contentId_hi_hi                        :8;
+   u_char contentId_hi_lo                        :8;
+   u_char contentId_lo_hi                        :8;
+   u_char contentId_lo_lo                        :8;
+
+   u_char duration_h                             :8;
+   u_char duration_m                             :8;
+   u_char duration_s                             :8;
+
+#if BYTE_ORDER == BIG_ENDIAN
+   u_char                                        :4;
+   u_char descriptors_loop_length_hi             :4;
+#else
+   u_char descriptors_loop_length_hi             :4;
+   u_char                                        :4;
+#endif
+   u_char descriptors_loop_length_lo             :8;
+};
+
 /*
  *
  *    The following describes the different descriptors that can be used within
@@ -1010,6 +1061,21 @@
    u_char linkage_type                           :8;
 };
 
+#define DESCR_LINKAGE_8_LEN 3
+struct descr_linkage_8 {
+#if BYTE_ORDER == BIG_ENDIAN
+   u_char hand_over_type                         :4;
+   u_char reserved                               :3;
+   u_char origin_type                            :1;
+#else
+   u_char origin_type                            :1;
+   u_char reserved                               :3;
+   u_char hand_over_type                         :4;
+#endif
+   u_char id_hi                                  :8;
+   u_char id_lo                                  :8;
+};
+
 /* 0x4B nvod_reference_descriptor */
 
 #define DESCR_NVOD_REFERENCE_LEN 2
@@ -1364,7 +1430,10 @@
 struct descr_private_data_specifier {
    u_char descriptor_tag                         :8;
    u_char descriptor_length                      :8;
-   /* TBD */
+   u_char private_data_specifier_hi_hi           :8;
+   u_char private_data_specifier_hi_lo           :8;
+   u_char private_data_specifier_lo_hi           :8;
+   u_char private_data_specifier_lo_lo           :8;
 };
 
 /* 0x60 service_move_descriptor */
@@ -1717,6 +1786,34 @@
    u_char icon_flags_lo                          :8;
 };
 
+// Private DVB Descriptor  Premiere.de
+// 0xF2  Content Transmission Descriptor
+// http://dvbsnoop.sourceforge.net/examples/example-private-section.html
+
+#define DESCR_PREMIERE_CONTENT_TRANSMISSION_LEN 11
+
+struct descr_premiere_content_transmission {
+   u_char descriptor_tag                         :8;
+   u_char descriptor_length                      :8;
+   u_char transport_stream_id_hi                 :8;
+   u_char transport_stream_id_lo                 :8;
+   u_char original_network_id_hi                 :8;
+   u_char original_network_id_lo                 :8;
+   u_char service_id_hi                          :8;
+   u_char service_id_lo                          :8;
+   u_char mjd_hi                                 :8;
+   u_char mjd_lo                                 :8;
+   u_char start_time_loop                        :8;
+};
+
+#define ITEM_PREMIERE_CONTENT_TRANSMISSION_LEN 3
+
+struct item_premiere_content_transmission_reference {
+   u_char start_time_h                           :8;
+   u_char start_time_m                           :8;
+   u_char start_time_s                           :8;
+};
+
 } //end of namespace
 
 #endif //LIBSI_HEADERS_H
diff -ruN vdr-1.3.46/libsi/section.c vdr-1.3.47/libsi/section.c
--- vdr-1.3.46/libsi/section.c	2006-02-18 11:38:20.000000000 +0100
+++ vdr-1.3.47/libsi/section.c	2006-04-14 12:53:44.000000000 +0200
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: section.c 1.4 2006/02/18 10:38:20 kls Exp $
+ *   $Id: section.c 1.5 2006/04/14 10:53:44 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -341,4 +341,20 @@
    applicationDescriptors.setData(data+offset, HILO(s->application_descriptors_length));
 }
 
+/******************* PremiereCIT *******************/
+
+void PremiereCIT::Parse() {
+   int offset=0;
+   data.setPointerAndOffset<const pcit>(s, offset);
+   eventDescriptors.setData(data+offset, HILO(s->descriptors_loop_length));
+}
+
+int PremiereCIT::getContentId() const {
+   return (HILO(s->contentId_hi) << 16) | HILO(s->contentId_lo);
+}
+
+time_t PremiereCIT::getDuration() const {
+   return DVBTime::getDuration(s->duration_h, s->duration_m, s->duration_s);
+}
+
 } //end of namespace
diff -ruN vdr-1.3.46/libsi/section.h vdr-1.3.47/libsi/section.h
--- vdr-1.3.46/libsi/section.h	2004-02-20 14:45:45.000000000 +0100
+++ vdr-1.3.47/libsi/section.h	2006-04-14 12:53:44.000000000 +0200
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: section.h 1.3 2004/02/20 13:45:45 kls Exp $
+ *   $Id: section.h 1.4 2006/04/14 10:53:44 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -260,6 +260,21 @@
    virtual void Parse();
 };
 
+/* Premiere Content Information Table */
+
+class PremiereCIT : public NumberedSection {
+public:
+   PremiereCIT(const unsigned char *data, bool doCopy=true) : NumberedSection(data, doCopy) {}
+   PremiereCIT() {}
+   int getContentId() const;
+   time_t getDuration() const;
+   PCIT_DescriptorLoop eventDescriptors;
+protected:
+   virtual void Parse();
+private:
+   const pcit *s;
+};
+
 } //end of namespace
 
 #endif //LIBSI_TABLE_H
diff -ruN vdr-1.3.46/libsi/si.c vdr-1.3.47/libsi/si.c
--- vdr-1.3.46/libsi/si.c	2006-02-18 11:38:20.000000000 +0100
+++ vdr-1.3.47/libsi/si.c	2006-04-14 12:53:44.000000000 +0200
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: si.c 1.15 2006/02/18 10:38:20 kls Exp $
+ *   $Id: si.c 1.16 2006/04/14 10:53:44 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -373,6 +373,9 @@
          case MultilingualComponentDescriptorTag:
             d=new MultilingualComponentDescriptor();
             break;
+         case PrivateDataSpecifierDescriptorTag:
+            d=new PrivateDataSpecifierDescriptor();
+            break;
          case ServiceMoveDescriptorTag:
             d=new ServiceMoveDescriptor();
             break;
@@ -400,9 +403,16 @@
          case ParentalRatingDescriptorTag:
             d=new ParentalRatingDescriptor();
             break;
+         case TeletextDescriptorTag:
+         case VBITeletextDescriptorTag:
+            d=new TeletextDescriptor();
+            break;
          case ApplicationSignallingDescriptorTag:
             d=new ApplicationSignallingDescriptor();
             break;
+         case LocalTimeOffsetDescriptorTag:
+            d=new LocalTimeOffsetDescriptor();
+            break;
          case LinkageDescriptorTag:
             d=new LinkageDescriptor();
             break;
@@ -412,6 +422,9 @@
          case PDCDescriptorTag:
             d=new PDCDescriptor();
             break;
+         case AncillaryDataDescriptorTag:
+            d=new AncillaryDataDescriptor();
+            break;
 
          //note that it is no problem to implement one
          //of the unimplemented descriptors.
@@ -436,13 +449,9 @@
          //defined in ETSI EN 300 468
          case StuffingDescriptorTag:
          case VBIDataDescriptorTag:
-         case VBITeletextDescriptorTag:
          case CountryAvailabilityDescriptorTag:
          case MocaicDescriptorTag:
-         case TeletextDescriptorTag:
          case TelephoneDescriptorTag:
-         case LocalTimeOffsetDescriptorTag:
-         case PrivateDataSpecifierDescriptorTag:
          case CellListDescriptorTag:
          case CellFrequencyLinkDescriptorTag:
          case ServiceAvailabilityDescriptorTag:
@@ -453,7 +462,6 @@
          case CaSystemDescriptorTag:
          case AC3DescriptorTag:
          case DSNGDescriptorTag:
-         case AncillaryDataDescriptorTag:
          case AnnouncementSupportDescriptorTag:
          case AdaptationFieldDataDescriptorTag:
          case TransportStreamDescriptorTag:
@@ -500,6 +508,27 @@
             break;
       }
       break;
+   case PCIT:
+      switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) {
+         case ContentDescriptorTag:
+            d=new ContentDescriptor();
+            break;
+         case ShortEventDescriptorTag:
+            d=new ShortEventDescriptor();
+            break;
+         case ExtendedEventDescriptorTag:
+            d=new ExtendedEventDescriptor();
+            break;
+         case PremiereContentTransmissionDescriptorTag:
+            d=new PremiereContentTransmissionDescriptor();
+            break;
+         default:
+            if (!returnUnimplemetedDescriptor)
+               return 0;
+            d=new UnimplementedDescriptor();
+            break;
+      }
+      break;
    }
    d->setData(da);
    return d;
diff -ruN vdr-1.3.46/libsi/si.h vdr-1.3.47/libsi/si.h
--- vdr-1.3.46/libsi/si.h	2006-02-18 11:38:20.000000000 +0100
+++ vdr-1.3.47/libsi/si.h	2006-04-14 12:53:44.000000000 +0200
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: si.h 1.13 2006/02/18 10:38:20 kls Exp $
+ *   $Id: si.h 1.14 2006/04/14 10:53:44 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
@@ -43,7 +43,8 @@
                TableIdTOT = 0x73, //time offset section
                TableIdDIT = 0x7E, //discontinuity information section
                TableIdSIT = 0x7F, //service information section
-               TableIdAIT = 0x74  //application information section
+               TableIdAIT = 0x74, //application information section
+               TableIdPremiereCIT = 0xA0 //premiere content information section
              };
 
 
@@ -139,13 +140,15 @@
                MHP_PrefetchDescriptorTag = 0x0C,
                MHP_DelegatedApplicationDescriptorTag = 0x0E,
                MHP_ApplicationStorageDescriptorTag = 0x10,
+  // Premiere private Descriptor Tags
+               PremiereContentTransmissionDescriptorTag = 0xF2,
 
                //a descriptor currently unimplemented in this library
                //the actual value 0xFF is "forbidden" according to the spec.
                UnimplementedDescriptorTag = 0xFF
 };
 
-enum DescriptorTagDomain { SI, MHP };
+enum DescriptorTagDomain { SI, MHP, PCIT };
 
 enum RunningStatus { RunningStatusUndefined = 0,
                      RunningStatusNotRunning = 1,
@@ -411,6 +414,12 @@
    MHP_DescriptorLoop() { domain=MHP; }
 };
 
+//Premiere Content Information Table
+class PCIT_DescriptorLoop : public DescriptorLoop {
+public:
+   PCIT_DescriptorLoop() { domain=PCIT; }
+};
+
 //The content of the ExtendedEventDescriptor may be split over several
 //descriptors if the text is longer than 256 bytes.
 //The following classes provide base functionality to handle this case.
diff -ruN vdr-1.3.46/menu.c vdr-1.3.47/menu.c
--- vdr-1.3.46/menu.c	2006-04-09 16:29:24.000000000 +0200
+++ vdr-1.3.47/menu.c	2006-04-16 14:20:46.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.c 1.428 2006/04/09 14:29:24 kls Exp $
+ * $Id: menu.c 1.434 2006/04/16 12:20:46 kls Exp $
  */
 
 #include "menu.h"
@@ -32,6 +32,9 @@
 #define MAXWAIT4EPGINFO   3 // seconds
 #define MODETIMEOUT       3 // seconds
 #define DISKSPACECHEK     5 // seconds between disk space checks in the main menu
+#define NEWTIMERLIMIT   120 // seconds until the start time of a new timer created from the Schedule menu,
+                            // within which it will go directly into the "Edit timer" menu to allow
+                            // further parameter settings
 
 #define MAXRECORDCONTROLS (MAXDEVICES * MAXRECEIVERS)
 #define MAXINSTANTRECTIME (24 * 60 - 1) // 23:59 hours
@@ -1152,9 +1155,10 @@
         }
      else {
         Timers.Add(timer);
-        timer->Matches();
         Timers.SetModified();
         isyslog("timer %s added (active)", *timer->ToDescr());
+        if (timer->Matches(0, false, NEWTIMERLIMIT))
+           return AddSubMenu(new cMenuEditTimer(timer));
         if (HasSubMenu())
            CloseSubMenu();
         if (Update())
@@ -1400,9 +1404,10 @@
         }
      else {
         Timers.Add(timer);
-        timer->Matches();
         Timers.SetModified();
         isyslog("timer %s added (active)", *timer->ToDescr());
+        if (timer->Matches(0, false, NEWTIMERLIMIT))
+           return AddSubMenu(new cMenuEditTimer(timer));
         if (HasSubMenu())
            CloseSubMenu();
         if (Update())
@@ -2031,7 +2036,7 @@
      cRecording *recording = GetRecording(ri);
      if (recording) {
         char *parameter = NULL;
-        asprintf(&parameter, "'%s'", recording->FileName());
+        asprintf(&parameter, "\"%s\"", *strescape(recording->FileName(), "\"$"));
         cMenuCommands *menu;
         eOSState state = AddSubMenu(menu = new cMenuCommands(tr("Recording commands"), &RecordingCommands, parameter));
         free(parameter);
@@ -2299,7 +2304,7 @@
   int numAudioLanguages;
   void Setup(void);
   const char *videoDisplayFormatTexts[3];
-  const char *updateChannelsTexts[5];
+  const char *updateChannelsTexts[6];
 public:
   cMenuSetupDVB(void);
   virtual eOSState ProcessKey(eKeys Key);
@@ -2315,9 +2320,10 @@
   videoDisplayFormatTexts[2] = tr("center cut out");
   updateChannelsTexts[0] = tr("no");
   updateChannelsTexts[1] = tr("names only");
-  updateChannelsTexts[2] = tr("names and PIDs");
-  updateChannelsTexts[3] = tr("add new channels");
-  updateChannelsTexts[4] = tr("add new transponders");
+  updateChannelsTexts[2] = tr("PIDs only");
+  updateChannelsTexts[3] = tr("names and PIDs");
+  updateChannelsTexts[4] = tr("add new channels");
+  updateChannelsTexts[5] = tr("add new transponders");
 
   SetSection(tr("DVB"));
   Setup();
@@ -2334,7 +2340,7 @@
   if (data.VideoFormat == 0)
      Add(new cMenuEditStraItem(tr("Setup.DVB$Video display format"), &data.VideoDisplayFormat, 3, videoDisplayFormatTexts));
   Add(new cMenuEditBoolItem(tr("Setup.DVB$Use Dolby Digital"),     &data.UseDolbyDigital));
-  Add(new cMenuEditStraItem(tr("Setup.DVB$Update channels"),       &data.UpdateChannels, 5, updateChannelsTexts));
+  Add(new cMenuEditStraItem(tr("Setup.DVB$Update channels"),       &data.UpdateChannels, 6, updateChannelsTexts));
   Add(new cMenuEditIntItem( tr("Setup.DVB$Audio languages"),       &numAudioLanguages, 0, I18nNumLanguages));
   for (int i = 0; i < numAudioLanguages; i++)
       Add(new cMenuEditStraItem(tr("Setup.DVB$Audio language"),    &data.AudioLanguages[i], I18nNumLanguages, I18nLanguages()));
@@ -2696,7 +2702,9 @@
 
 eOSState cMenuSetup::Restart(void)
 {
-  if (Interface->Confirm(cRecordControls::Active() ? tr("Recording - restart anyway?") : tr("Really restart?"))) {
+  if (Interface->Confirm(tr("Really restart?"))
+     && (!cRecordControls::Active() || Interface->Confirm(tr("Recording - restart anyway?")))
+     && !cPluginManager::Active(tr("Really restart?"))) {
      cThread::EmergencyExit(true);
      return osEnd;
      }
@@ -3156,6 +3164,10 @@
     case kLeft:
     case kRight|k_Repeat:
     case kRight:
+    case kNext|k_Repeat:
+    case kNext:
+    case kPrev|k_Repeat:
+    case kPrev:
          withInfo = false;
          number = 0;
          if (group < 0) {
@@ -3165,7 +3177,7 @@
             }
          if (group >= 0) {
             int SaveGroup = group;
-            if (NORMALKEY(Key) == kRight)
+            if (NORMALKEY(Key) == kRight || NORMALKEY(Key) == kNext)
                group = Channels.GetNextGroup(group) ;
             else
                group = Channels.GetPrevGroup(group < 1 ? 1 : group);
@@ -3199,6 +3211,8 @@
     case kDown|k_Release:
     case kChanUp|k_Release:
     case kChanDn|k_Release:
+    case kNext|k_Release:
+    case kPrev|k_Release:
          if (!(Key & k_Repeat) && channel && channel->Number() != cDevice::CurrentChannel())
             NewChannel = channel;
          withInfo = true;
@@ -3788,6 +3802,7 @@
   marks.Load(fileName);
   cRecording Recording(fileName);
   cStatus::MsgReplaying(this, Recording.Name(), Recording.FileName(), true);
+  SetTrackDescriptions(false);
 }
 
 cReplayControl::~cReplayControl()
@@ -4143,8 +4158,12 @@
       switch (Key) {
         // Editing:
         case kMarkToggle:      MarkToggle(); break;
+        case kPrev|k_Repeat:
+        case kPrev:
         case kMarkJumpBack|k_Repeat:
         case kMarkJumpBack:    MarkJump(false); break;
+        case kNext|k_Repeat:
+        case kNext:
         case kMarkJumpForward|k_Repeat:
         case kMarkJumpForward: MarkJump(true); break;
         case kMarkMoveBack|k_Repeat:
diff -ruN vdr-1.3.46/menuitems.c vdr-1.3.47/menuitems.c
--- vdr-1.3.46/menuitems.c	2006-04-09 15:10:02.000000000 +0200
+++ vdr-1.3.47/menuitems.c	2006-04-14 12:41:28.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menuitems.c 1.36 2006/04/09 13:10:02 kls Exp $
+ * $Id: menuitems.c 1.42 2006/04/14 10:41:28 kls Exp $
  */
 
 #include "menuitems.h"
@@ -23,22 +23,18 @@
 
 cMenuEditItem::cMenuEditItem(const char *Name)
 {
-  name = strdup(Name);
-  value = NULL;
+  name = strdup(Name ? Name : "???");
 }
 
 cMenuEditItem::~cMenuEditItem()
 {
   free(name);
-  free(value);
 }
 
 void cMenuEditItem::SetValue(const char *Value)
 {
-  free(value);
-  value = strdup(Value);
   char *buffer = NULL;
-  asprintf(&buffer, "%s:\t%s", name, value);
+  asprintf(&buffer, "%s:\t%s", name, Value);
   SetText(buffer, false);
   cStatus::MsgOsdCurrentItem(buffer);
 }
@@ -102,7 +98,7 @@
             if (*value > max) { *value = max; Set(); }
             return state;
        }
-     if ((!fresh || min <= newValue) && newValue <= max) {
+     if (newValue != *value && (!fresh || min <= newValue) && newValue <= max) {
         *value = newValue;
         Set();
         }
@@ -205,7 +201,7 @@
 :cMenuEditItem(Name)
 {
   value = Value;
-  allowed = strdup(Allowed);
+  allowed = strdup(Allowed ? Allowed : "");
   current = strchr(allowed, *Value);
   if (!current)
      current = allowed;
@@ -254,7 +250,7 @@
   orgValue = NULL;
   value = Value;
   length = Length;
-  allowed = strdup(Allowed);
+  allowed = strdup(Allowed ? Allowed : "");
   pos = -1;
   insert = uppercase = false;
   newchar = true;
@@ -572,7 +568,7 @@
      snprintf(buf, sizeof(buf), "%d %s", *value, channel ? channel->Name() : "");
      SetValue(buf);
      }
-  else
+  else if (noneString)
      SetValue(noneString);
 }
 
@@ -602,7 +598,7 @@
 // --- cMenuEditTranItem -----------------------------------------------------
 
 cMenuEditTranItem::cMenuEditTranItem(const char *Name, int *Value, int *Source)
-:cMenuEditChanItem(Name, &number)
+:cMenuEditChanItem(Name, &number, "-")
 {
   number = 0;
   source = Source;
@@ -626,6 +622,10 @@
      *source = channel->Source();
      *transponder = channel->Transponder();
      }
+  else {
+     *source = 0;
+     *transponder = 0;
+     }
   return state;
 }
 
diff -ruN vdr-1.3.46/menuitems.h vdr-1.3.47/menuitems.h
--- vdr-1.3.46/menuitems.h	2006-04-09 14:56:48.000000000 +0200
+++ vdr-1.3.47/menuitems.h	2006-04-14 12:01:47.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menuitems.h 1.19 2006/04/09 12:56:48 kls Exp $
+ * $Id: menuitems.h 1.20 2006/04/14 10:01:47 kls Exp $
  */
 
 #ifndef __MENUITEMS_H
@@ -17,7 +17,6 @@
 class cMenuEditItem : public cOsdItem {
 private:
   char *name;
-  char *value;
 public:
   cMenuEditItem(const char *Name);
   ~cMenuEditItem();
diff -ruN vdr-1.3.46/newplugin vdr-1.3.47/newplugin
--- vdr-1.3.46/newplugin	2005-11-11 14:20:14.000000000 +0100
+++ vdr-1.3.47/newplugin	2006-04-17 11:49:13.000000000 +0200
@@ -12,7 +12,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: newplugin 1.22 2005/11/11 13:20:14 kls Exp $
+# $Id: newplugin 1.26 2006/04/17 09:49:13 kls Exp $
 
 $PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin <name>\n";
 
@@ -75,7 +75,6 @@
 
 ### The directory environment:
 
-DVBDIR = ../../../../DVB
 VDRDIR = ../../..
 LIBDIR = ../../lib
 TMPDIR = /tmp
@@ -84,9 +83,9 @@
 
 -include \$(VDRDIR)/Make.config
 
-### The version number of VDR (taken from VDR's "config.h"):
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
 
-VDRVERSION = \$(shell grep 'define VDRVERSION ' \$(VDRDIR)/config.h | awk '{ print \$\$3 }' | sed -e 's/"//g')
+APIVERSION = \$(shell grep 'define APIVERSION ' \$(VDRDIR)/config.h | awk '{ print \$\$3 }' | sed -e 's/"//g')
 
 ### The name of the distribution archive:
 
@@ -95,7 +94,7 @@
 
 ### Includes and Defines (add further entries here):
 
-INCLUDES += -I\$(VDRDIR)/include -I\$(DVBDIR)/include
+INCLUDES += -I\$(VDRDIR)/include
 
 DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"\$(PLUGIN)"'
 
@@ -123,7 +122,7 @@
 
 libvdr-\$(PLUGIN).so: \$(OBJS)
 	\$(CXX) \$(CXXFLAGS) -shared \$(OBJS) -o \$\@
-	\@cp \$\@ \$(LIBDIR)/\$\@.\$(VDRVERSION)
+	\@cp \$\@ \$(LIBDIR)/\$\@.\$(APIVERSION)
 
 dist: clean
 	\@-rm -rf \$(TMPDIR)/\$(ARCHIVE)
@@ -166,6 +165,8 @@
   virtual bool Start(void);
   virtual void Stop(void);
   virtual void Housekeeping(void);
+  virtual void MainThreadHook(void);
+  virtual cString Active(void);
   virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; }
   virtual cOsdObject *MainMenuAction(void);
   virtual cMenuSetupPage *SetupMenu(void);
@@ -221,6 +222,18 @@
   // Perform any cleanup or other regular tasks.
 }
 
+void cPlugin${PLUGIN_CLASS}::MainThreadHook(void)
+{
+  // Perform actions in the context of the main program thread.
+  // WARNING: Use with great care - see PLUGINS.html!
+}
+
+cString cPlugin${PLUGIN_CLASS}::Active(void)
+{
+  // Return a message string if shutdown should be postponed
+  return NULL;
+}
+
 cOsdObject *cPlugin${PLUGIN_CLASS}::MainMenuAction(void)
 {
   // Perform the action when selected from the main VDR menu.
diff -ruN vdr-1.3.46/nit.c vdr-1.3.47/nit.c
--- vdr-1.3.46/nit.c	2004-10-17 14:00:54.000000000 +0200
+++ vdr-1.3.47/nit.c	2006-04-15 16:10:42.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: nit.c 1.10 2004/10/17 12:00:54 kls Exp $
+ * $Id: nit.c 1.11 2006/04/15 14:10:42 kls Exp $
  */
 
 #include "nit.h"
@@ -116,12 +116,12 @@
                  bool found = false;
                  for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
                      if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
-                        if (Setup.UpdateChannels >= 4)
+                        if (Setup.UpdateChannels >= 5)
                            Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate);
                         found = true;
                         }
                      }
-                 if (!found && Setup.UpdateChannels >= 4) {
+                 if (!found && Setup.UpdateChannels >= 5) {
                     cChannel *Channel = new cChannel;
                     Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
                     if (Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate))
@@ -151,12 +151,12 @@
                  bool found = false;
                  for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
                      if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
-                        if (Setup.UpdateChannels >= 4)
+                        if (Setup.UpdateChannels >= 5)
                            Channel->SetCableTransponderData(Source, Frequency, Modulation, SymbolRate, CodeRate);
                         found = true;
                         }
                      }
-                 if (!found && Setup.UpdateChannels >= 4) {
+                 if (!found && Setup.UpdateChannels >= 5) {
                     cChannel *Channel = new cChannel;
                     Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
                     if (Channel->SetCableTransponderData(Source, Frequency, Modulation, SymbolRate, CodeRate))
@@ -193,12 +193,12 @@
                  bool found = false;
                  for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
                      if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
-                        if (Setup.UpdateChannels >= 4)
+                        if (Setup.UpdateChannels >= 5)
                            Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode);
                         found = true;
                         }
                      }
-                 if (!found && Setup.UpdateChannels >= 4) {
+                 if (!found && Setup.UpdateChannels >= 5) {
                     cChannel *Channel = new cChannel;
                     Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
                     if (Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode))
diff -ruN vdr-1.3.46/plugin.c vdr-1.3.47/plugin.c
--- vdr-1.3.46/plugin.c	2006-04-09 16:16:17.000000000 +0200
+++ vdr-1.3.47/plugin.c	2006-04-17 11:20:05.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: plugin.c 1.18 2006/04/09 14:16:17 kls Exp $
+ * $Id: plugin.c 1.22 2006/04/17 09:20:05 kls Exp $
  */
 
 #include "plugin.h"
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <time.h>
 #include "config.h"
+#include "interface.h"
 
 #define LIBVDR_PREFIX  "libvdr-"
 #define SO_INDICATOR   ".so."
@@ -69,6 +70,15 @@
 {
 }
 
+void cPlugin::MainThreadHook(void)
+{
+}
+
+cString cPlugin::Active(void)
+{
+  return NULL;
+}
+
 const char *cPlugin::MainMenuEntry(void)
 {
   return NULL;
@@ -284,7 +294,7 @@
               if (p) {
                  *p = 0;
                  p += strlen(SO_INDICATOR);
-                 if (strcmp(p, VDRVERSION) == 0) {
+                 if (strcmp(p, APIVERSION) == 0) {
                     char *name = e->d_name + strlen(LIBVDR_PREFIX);
                     if (strcmp(name, "*") != 0) { // let's not get into a loop!
                        AddPlugin(e->d_name + strlen(LIBVDR_PREFIX));
@@ -300,7 +310,7 @@
   if (p)
      *p = 0;
   char *buffer = NULL;
-  asprintf(&buffer, "%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, VDRVERSION);
+  asprintf(&buffer, "%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, APIVERSION);
   dlls.Add(new cDll(buffer, Args));
   free(buffer);
   free(s);
@@ -364,6 +374,32 @@
      }
 }
 
+void cPluginManager::MainThreadHook(void)
+{
+  for (cDll *dll = pluginManager->dlls.First(); dll; dll = pluginManager->dlls.Next(dll)) {
+      cPlugin *p = dll->Plugin();
+      if (p)
+         p->MainThreadHook();
+      }
+}
+
+bool cPluginManager::Active(const char *Prompt)
+{
+  if (pluginManager) {
+     for (cDll *dll = pluginManager->dlls.First(); dll; dll = pluginManager->dlls.Next(dll)) {
+         cPlugin *p = dll->Plugin();
+         if (p) {
+            cString s = p->Active();
+            if (!isempty(*s)) {
+               if (!Prompt || !Interface->Confirm(cString::sprintf("%s - %s", *s, Prompt)))
+                  return true;
+               }
+            }
+         }
+     }
+  return false;
+}
+
 bool cPluginManager::HasPlugins(void)
 {
   return pluginManager && pluginManager->dlls.Count();
@@ -424,9 +460,13 @@
       }
 }
 
-void cPluginManager::Shutdown(void)
+void cPluginManager::Shutdown(bool Log)
 {
   cDll *dll;
-  while ((dll = dlls.Last()) != NULL)
+  while ((dll = dlls.Last()) != NULL) {
+        cPlugin *p = dll->Plugin();
+        if (p && Log)
+           isyslog("deleting plugin: %s", p->Name());
         dlls.Del(dll);
+        }
 }
diff -ruN vdr-1.3.46/plugin.h vdr-1.3.47/plugin.h
--- vdr-1.3.46/plugin.h	2005-08-27 18:13:17.000000000 +0200
+++ vdr-1.3.47/plugin.h	2006-04-17 11:18:16.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: plugin.h 1.10 2005/08/27 16:13:17 kls Exp $
+ * $Id: plugin.h 1.13 2006/04/17 09:18:16 kls Exp $
  */
 
 #ifndef __PLUGIN_H
@@ -39,6 +39,8 @@
   virtual bool Start(void);
   virtual void Stop(void);
   virtual void Housekeeping(void);
+  virtual void MainThreadHook(void);
+  virtual cString Active(void);
 
   virtual const char *MainMenuEntry(void);
   virtual cOsdObject *MainMenuAction(void);
@@ -89,13 +91,15 @@
   bool InitializePlugins(void);
   bool StartPlugins(void);
   void Housekeeping(void);
+  void MainThreadHook(void);
+  static bool Active(const char *Prompt = NULL);
   static bool HasPlugins(void);
   static cPlugin *GetPlugin(int Index);
   static cPlugin *GetPlugin(const char *Name);
   static cPlugin *CallFirstService(const char *Id, void *Data = NULL);
   static bool CallAllServices(const char *Id, void *Data = NULL);
   void StopPlugins(void);
-  void Shutdown(void);
+  void Shutdown(bool Log = false);
   };
 
 #endif //__PLUGIN_H
diff -ruN vdr-1.3.46/recording.c vdr-1.3.47/recording.c
--- vdr-1.3.46/recording.c	2006-04-09 15:49:51.000000000 +0200
+++ vdr-1.3.47/recording.c	2006-04-17 14:47:59.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.c 1.144 2006/04/09 13:49:51 kls Exp $
+ * $Id: recording.c 1.146 2006/04/17 12:47:59 kls Exp $
  */
 
 #include "recording.h"
@@ -192,7 +192,7 @@
      }
 }
 
-// --- cResumeFile ------------------------------------------------------------
+// --- cResumeFile -----------------------------------------------------------
 
 cResumeFile::cResumeFile(const char *FileName)
 {
@@ -389,7 +389,10 @@
 struct tCharExchange { char a; char b; };
 tCharExchange CharExchange[] = {
   { '~',  '/'    },
+  { '/',  '~'    },
   { ' ',  '_'    },
+  // backwards compatibility:
+  { '\'', '\''   },
   { '\'', '\x01' },
   { '/',  '\x02' },
   { 0, 0 }
diff -ruN vdr-1.3.46/remote.c vdr-1.3.47/remote.c
--- vdr-1.3.46/remote.c	2006-01-29 15:43:07.000000000 +0100
+++ vdr-1.3.47/remote.c	2006-04-17 10:58:28.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remote.c 1.49 2006/01/29 14:43:07 kls Exp $
+ * $Id: remote.c 1.50 2006/04/17 08:58:28 kls Exp $
  */
 
 #include "remote.h"
@@ -145,10 +145,23 @@
   return false;
 }
 
-void cRemote::CallPlugin(const char *Plugin)
+bool cRemote::CallPlugin(const char *Plugin)
 {
-  plugin = Plugin;
-  Put(k_Plugin);
+  cMutexLock MutexLock(&mutex);
+  if (!plugin) {
+     plugin = Plugin;
+     Put(k_Plugin);
+     return true;
+     }
+  return false;
+}
+
+const char *cRemote::GetPlugin(void)
+{
+  cMutexLock MutexLock(&mutex);
+  const char *p = plugin;
+  plugin = NULL;
+  return p;
 }
 
 bool cRemote::HasKeys(void)
diff -ruN vdr-1.3.46/remote.h vdr-1.3.47/remote.h
--- vdr-1.3.46/remote.h	2006-03-31 16:18:44.000000000 +0200
+++ vdr-1.3.47/remote.h	2006-04-17 10:59:48.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remote.h 1.34 2006/03/31 14:18:44 kls Exp $
+ * $Id: remote.h 1.35 2006/04/17 08:59:48 kls Exp $
  */
 
 #ifndef __REMOTE_H
@@ -46,11 +46,18 @@
   static void Clear(void);
   static bool Put(eKeys Key, bool AtFront = false);
   static bool PutMacro(eKeys Key);
-  static void CallPlugin(const char *Plugin);
+  static bool CallPlugin(const char *Plugin);
       ///< Initiates calling the given plugin's main menu function.
       ///< The Plugin parameter is the name of the plugin, and must be
-      ///< a static string.
-  static const char *GetPlugin(void) { return plugin; }
+      ///< a static string. Returns true if the plugin call was successfully
+      ///< initiated (the actual call to the plugin's main menu function
+      ///< will take place some time later, during the next execution
+      ///< of VDR's main loop). If there is already a plugin call pending
+      ///< false will be returned and the caller should try again later.
+  static const char *GetPlugin(void);
+      ///< Returns the name of the plugin that was set with a previous
+      ///< call to CallPlugin(). The internally stored pointer to the
+      ///< plugin name will be reset to NULL by this call.
   static bool HasKeys(void);
   static eKeys Get(int WaitMs = 1000, char **UnknownCode = NULL);
   };
diff -ruN vdr-1.3.46/remux.c vdr-1.3.47/remux.c
--- vdr-1.3.46/remux.c	2006-03-25 13:27:30.000000000 +0100
+++ vdr-1.3.47/remux.c	2006-04-17 14:48:12.000000000 +0200
@@ -11,7 +11,7 @@
  * The cRepacker family's code was originally written by Reinhard Nissl <rnissl@gmx.de>,
  * and adapted to the VDR coding style by Klaus.Schmidinger@cadsoft.de.
  *
- * $Id: remux.c 1.55 2006/03/25 12:27:30 kls Exp $
+ * $Id: remux.c 1.56 2006/04/17 12:48:12 kls Exp $
  */
 
 #include "remux.h"
@@ -148,7 +148,7 @@
   return n;
 }
 
-// --- cCommonRepacker --------------------------------------------------------
+// --- cCommonRepacker -------------------------------------------------------
 
 class cCommonRepacker : public cRepacker {
 protected:
diff -ruN vdr-1.3.46/sdt.c vdr-1.3.47/sdt.c
--- vdr-1.3.46/sdt.c	2005-08-27 11:27:47.000000000 +0200
+++ vdr-1.3.47/sdt.c	2006-04-15 16:12:21.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sdt.c 1.15 2005/08/27 09:27:47 kls Exp $
+ * $Id: sdt.c 1.16 2006/04/15 14:12:21 kls Exp $
  */
 
 #include "sdt.h"
@@ -78,7 +78,7 @@
                         char *pp = compactspace(ProviderNameBuf);
                         if (channel) {
                            channel->SetId(sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
-                           if (Setup.UpdateChannels >= 1)
+                           if (Setup.UpdateChannels == 1 || Setup.UpdateChannels >= 3)
                               channel->SetName(pn, ps, pp);
                            // Using SiSdtService.getFreeCaMode() is no good, because some
                            // tv stations set this flag even for non-encrypted channels :-(
@@ -86,7 +86,7 @@
                            // and would have been overwritten with real CA values later:
                            // channel->SetCa(SiSdtService.getFreeCaMode() ? 0xFFFF : 0);
                            }
-                        else if (*pn && Setup.UpdateChannels >= 3) {
+                        else if (*pn && Setup.UpdateChannels >= 4) {
                            channel = Channels.NewChannel(Channel(), pn, ps, pp, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
                            patFilter->Trigger();
                            }
@@ -111,7 +111,7 @@
                  SI::NVODReferenceDescriptor::Service Service;
                  for (SI::Loop::Iterator it; nrd->serviceLoop.getNext(Service, it); ) {
                      cChannel *link = Channels.GetByChannelID(tChannelID(Source(), Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId()));
-                     if (!link && Setup.UpdateChannels >= 3) {
+                     if (!link && Setup.UpdateChannels >= 4) {
                         link = Channels.NewChannel(Channel(), "NVOD", "", "", Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId());
                         patFilter->Trigger();
                         }
diff -ruN vdr-1.3.46/sources.conf vdr-1.3.47/sources.conf
--- vdr-1.3.46/sources.conf	2006-03-31 16:03:59.000000000 +0200
+++ vdr-1.3.47/sources.conf	2006-04-17 14:19:21.000000000 +0200
@@ -29,7 +29,7 @@
 S21.6E  Eutelsat W6
 S23.5E  Astra 1D 3A
 S26E    Arabsat 2D/2C/3A
-S28.2E  Astra 2D/A/B 
+S28.2E  Astra 2D/A/B
 S28.5E  Eurobird 1 & Astra 2A/B/D
 S30.5E  Arabsat 2B
 S33E    Eurobird 3 & Intelsat 802
@@ -46,11 +46,11 @@
 S57E    NSS 703
 S60E    Intelsat 904
 S62E    Intelsat 902
-S64E    Intelsat 906 
+S64E    Intelsat 906
 S66E    Intelsat 704
 S68.5E  PAS 7/10
 S70.5E  Eutelsat W5
-S72E    PAS 4 
+S72E    PAS 4
 
 # Asia
 
@@ -67,7 +67,7 @@
 S91.5E  Measat 1
 S93.5E  Insat 3A
 S95E    NSS 6
-S96.5E  Express AM 11  
+S96.5E  Express AM 11
 S100.5E Asiasat 2
 S103E   Express A2
 S105.5E Asiasat 3S
diff -ruN vdr-1.3.46/spu.c vdr-1.3.47/spu.c
--- vdr-1.3.46/spu.c	2006-03-26 16:07:59.000000000 +0200
+++ vdr-1.3.47/spu.c	2006-04-17 14:48:33.000000000 +0200
@@ -6,13 +6,13 @@
  * This code is distributed under the terms and conditions of the
  * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
  *
- * $Id: spu.c 1.2 2006/03/26 14:07:59 kls Exp $
+ * $Id: spu.c 1.3 2006/04/17 12:48:33 kls Exp $
  */
 
 #include "spu.h"
 #include <inttypes.h>
 
-// -- cSpuDecoder ----------------
+// -- cSpuDecoder ------------------------------------------------------------
 /*
 cSpuDecoder::cSpuDecoder()
 {};
diff -ruN vdr-1.3.46/spu.h vdr-1.3.47/spu.h
--- vdr-1.3.46/spu.h	2005-02-20 12:21:31.000000000 +0100
+++ vdr-1.3.47/spu.h	2006-04-17 14:48:55.000000000 +0200
@@ -6,7 +6,7 @@
  * This code is distributed under the terms and conditions of the
  * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
  *
- * $Id: spu.h 1.4 2005/02/20 11:21:31 kls Exp $
+ * $Id: spu.h 1.5 2006/04/17 12:48:55 kls Exp $
  */
 
 #ifndef __SPU_VDR_H
@@ -14,7 +14,7 @@
 
 #include <inttypes.h>
 
-// --- cSpuDecoder -------------------------------------------
+// --- cSpuDecoder -----------------------------------------------------------
 
 class cSpuDecoder {
   public:
diff -ruN vdr-1.3.46/summary2info.pl vdr-1.3.47/summary2info.pl
--- vdr-1.3.46/summary2info.pl	2005-09-17 11:20:31.000000000 +0200
+++ vdr-1.3.47/summary2info.pl	2006-04-17 14:19:24.000000000 +0200
@@ -10,7 +10,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: summary2info.pl 1.5 2005/09/17 09:20:31 kls Exp $
+# $Id: summary2info.pl 1.6 2006/04/17 12:19:24 kls Exp $
 
 $VideoDir = $ARGV[0] || die "please provide the name of the video directory\n";
 
@@ -41,7 +41,7 @@
        # if line 1 is too long, it can't be the short text,
        # so assume the short text is missing and concatenate
        # line 1 and line 2 to be the long text:
-       if (length($data[1]) > 80) { 
+       if (length($data[1]) > 80) {
           $data[2] = $data[1] . "|" . $data[2];
           $data[1] = "";
           }
diff -ruN vdr-1.3.46/svdrp.c vdr-1.3.47/svdrp.c
--- vdr-1.3.46/svdrp.c	2006-03-26 11:14:13.000000000 +0200
+++ vdr-1.3.47/svdrp.c	2006-04-17 11:02:23.000000000 +0200
@@ -10,7 +10,7 @@
  * and interact with the Video Disk Recorder - or write a full featured
  * graphical interface that sits on top of an SVDRP connection.
  *
- * $Id: svdrp.c 1.94 2006/03/26 09:14:13 kls Exp $
+ * $Id: svdrp.c 1.95 2006/04/17 09:02:23 kls Exp $
  */
 
 #include "svdrp.h"
@@ -1351,8 +1351,10 @@
               }
            }
         else if (strcasecmp(cmd, "MAIN") == 0) {
-           cRemote::CallPlugin(plugin->Name());
-           Reply(250, "Initiated call to main menu function of plugin \"%s\"", plugin->Name());
+           if (cRemote::CallPlugin(plugin->Name()))
+              Reply(250, "Initiated call to main menu function of plugin \"%s\"", plugin->Name());
+           else
+              Reply(550, "A plugin call is already pending - please try again later");
            }
         else {
            int ReplyCode = 900;
diff -ruN vdr-1.3.46/svdrphosts.conf vdr-1.3.47/svdrphosts.conf
--- vdr-1.3.46/svdrphosts.conf	2002-02-02 18:15:54.000000000 +0100
+++ vdr-1.3.47/svdrphosts.conf	2006-04-17 14:19:27.000000000 +0200
@@ -3,7 +3,7 @@
 #               are allowed to connect to the SVDRP port of the Video
 #               Disk Recorder (VDR) running on this system.
 # Syntax:
-#    
+#
 # IP-Address[/Netmask]
 #
 
diff -ruN vdr-1.3.46/tools.c vdr-1.3.47/tools.c
--- vdr-1.3.46/tools.c	2006-03-19 13:28:16.000000000 +0100
+++ vdr-1.3.47/tools.c	2006-04-17 14:19:31.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.c 1.115 2006/03/19 12:28:16 kls Exp $
+ * $Id: tools.c 1.116 2006/04/17 12:19:31 kls Exp $
  */
 
 #include "tools.h"
@@ -39,7 +39,7 @@
   snprintf(fmt, sizeof(fmt), "[%d] %s", cThread::ThreadId(), format);
   va_start(ap, format);
   vsyslog(priority, fmt, ap);
-  va_end(ap); 
+  va_end(ap);
 }
 
 int BCD2INT(int x)
diff -ruN vdr-1.3.46/tools.h vdr-1.3.47/tools.h
--- vdr-1.3.46/tools.h	2006-02-04 15:27:05.000000000 +0100
+++ vdr-1.3.47/tools.h	2006-04-16 12:40:45.000000000 +0200
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.h 1.92 2006/02/04 14:27:05 kls Exp $
+ * $Id: tools.h 1.93 2006/04/16 10:40:45 kls Exp $
  */
 
 #ifndef __TOOLS_H
@@ -52,7 +52,7 @@
 template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
 #endif
 
-void syslog_with_tid(int priority, const char *format, ...);
+void syslog_with_tid(int priority, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
 
 #define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF))
 int BCD2INT(int x);
diff -ruN vdr-1.3.46/vdr.1 vdr-1.3.47/vdr.1
--- vdr-1.3.46/vdr.1	2006-01-14 12:09:08.000000000 +0100
+++ vdr-1.3.47/vdr.1	2006-04-14 15:03:18.000000000 +0200
@@ -8,9 +8,9 @@
 .\" License as specified in the file COPYING that comes with the
 .\" vdr distribution.
 .\"
-.\" $Id: vdr.1 1.22 2006/01/14 11:09:08 kls Exp $
+.\" $Id: vdr.1 1.23 2006/04/14 13:03:18 kls Exp $
 .\"
-.TH vdr 1 "08 Jan 2006" "1.3.38" "Video Disk Recorder"
+.TH vdr 1 "14 Apr 2006" "1.3.47" "Video Disk Recorder"
 .SH NAME
 vdr - the Video Disk Recorder
 .SH SYNOPSIS
@@ -22,10 +22,12 @@
 It can work with signals received from satellites (DVB-S) as
 well as cable (DVB-C) and terrestrial (DVB-T) signals.
 
-At least one DVB card is required to run \fBvdr\fR, but in order
-to watch one broadcast while recording another, or to start watching
-a recorded programme before the live broadcast has ended (\fBtime shifting\fR),
-two DVB cards are necessary. By default \fBvdr\fR can support up to four
+At least one DVB card is required to run \fBvdr\fR. With it you can watch
+live tv while recording one or more other broadcasts from the same transponder.
+It is also possible to start watching a recorded programme before the live
+broadcast has ended (\fBtime shifting\fR). In order to record from different
+transponders simultaneously two or more DVB cards are necessary.
+By default \fBvdr\fR can support up to four
 DVB cards. The primary DVB card (the one your tv set is connected to) has
 to be a "full featured" card, which means it must contain an MPEG decoder
 and provide audio and video signal outputs.
diff -ruN vdr-1.3.46/vdr.c vdr-1.3.47/vdr.c
--- vdr-1.3.46/vdr.c	2006-04-09 14:22:46.000000000 +0200
+++ vdr-1.3.47/vdr.c	2006-04-17 16:43:46.000000000 +0200
@@ -22,7 +22,7 @@
  *
  * The project's page is at http://www.cadsoft.de/vdr
  *
- * $Id: vdr.c 1.254 2006/04/09 12:22:46 kls Exp $
+ * $Id: vdr.c 1.262 2006/04/17 14:43:46 kls Exp $
  */
 
 #include <getopt.h>
@@ -346,7 +346,7 @@
 
   // Set user id in case we were started as root:
 
-  if (VdrUser && getuid() == 0) {
+  if (VdrUser && geteuid() == 0) {
      StartedAsRoot = true;
      if (strcmp(VdrUser, "root")) {
         if (!SetKeepCaps(true))
@@ -980,6 +980,8 @@
                           if (Interface->Confirm(tr("Recording - shut down anyway?")))
                              ForceShutdown = true;
                           }
+                       if (cPluginManager::Active(tr("shut down anyway?")))
+                          ForceShutdown = true;
                        LastActivity = 1; // not 0, see below!
                        UserShutdown = true;
                        break;
@@ -1051,6 +1053,7 @@
               }
            switch (key) {
              // Toggle channels:
+             case kChanPrev:
              case k0: {
                   if (PreviousChannel[PreviousChannelIndex ^ 1] == LastChannel || LastChannel != PreviousChannel[0] && LastChannel != PreviousChannel[1])
                      PreviousChannelIndex ^= 1;
@@ -1059,11 +1062,16 @@
                   }
              // Direct Channel Select:
              case k1 ... k9:
-             // Left/Right rotates trough channel groups:
+             // Left/Right rotates through channel groups:
              case kLeft|k_Repeat:
              case kLeft:
              case kRight|k_Repeat:
              case kRight:
+             // Previous/Next rotates through channel groups:
+             case kPrev|k_Repeat:
+             case kPrev:
+             case kNext|k_Repeat:
+             case kNext:
              // Up/Down Channel Select:
              case kUp|k_Repeat:
              case kUp:
@@ -1093,7 +1101,7 @@
                  Skins.Message(mtInfo, tr("Editing process finished"));
               }
            }
-        if (!Interact && ((!cRecordControls::Active() && !cCutter::Active() && (!Interface->HasSVDRPConnection() || UserShutdown)) || ForceShutdown)) {
+        if (!Interact && ((!cRecordControls::Active() && !cCutter::Active() && !cPluginManager::Active() && (!Interface->HasSVDRPConnection() || UserShutdown)) || ForceShutdown)) {
            time_t Now = time(NULL);
            if (Now - LastActivity > ACTIVITYTIMEOUT) {
               // Shutdown:
@@ -1130,7 +1138,8 @@
                        cControl::Shutdown();
                        int Channel = timer ? timer->Channel()->Number() : 0;
                        const char *File = timer ? timer->File() : "";
-                       Delta = Next - time(NULL); // compensates for Confirm() timeout
+                       if (timer)
+                          Delta = Next - time(NULL); // compensates for Confirm() timeout
                        char *cmd;
                        asprintf(&cmd, "%s %ld %ld %d \"%s\" %d", Shutdown, Next, Delta, Channel, *strescape(File, "\"$"), UserShutdown);
                        isyslog("executing '%s'", cmd);
@@ -1157,6 +1166,8 @@
               PluginManager.Housekeeping();
               }
            }
+        // Main thread hooks of plugins:
+        PluginManager.MainThreadHook();
         }
   if (Interrupted)
      isyslog("caught signal %d", Interrupted);
@@ -1179,7 +1190,7 @@
      Setup.Save();
      }
   cDevice::Shutdown();
-  PluginManager.Shutdown();
+  PluginManager.Shutdown(true);
   cSchedules::Cleanup(true);
   ReportEpgBugFixStats();
   if (WatchdogTimeout > 0)
