[vdr] 01/01: Version 2.1.1 VDR developer version 2.1.1 is now available at

Tobias Grimm tiber-guest at moszumanska.debian.org
Sun Aug 30 16:18:06 UTC 2015


This is an automated email from the git hooks/post-receive script.

tiber-guest pushed a commit to annotated tag vdr-2.1.1
in repository vdr.

commit 5076cfb2ed0888dd16baeed1cbaa15cfbcd483c7
Author: Klaus Schmidinger <Klaus (dot) Schmidinger (at) tvdr (dot) de>
Date:   Sun Aug 25 12:35:00 2013 +0200

    Version 2.1.1
    VDR developer version 2.1.1 is now available at
    
           ftp://ftp.tvdr.de/vdr/Developer/vdr-2.1.1.tar.bz2
    
    A 'diff' against the previous version is available at
    
           ftp://ftp.tvdr.de/vdr/Developer/vdr-2.0.0-2.1.1.diff
    
    MD5 checksums:
    
    b17f9838bb8ddee9620f838fea7a171d  vdr-2.1.1.tar.bz2
    8b8ca593885c380cd370e6d19a5b16a1  vdr-2.0.0-2.1.1.diff
    
    WARNING:
    ========
    
    This is a *developer* version. Even though *I* use it in my productive
    environment, I strongly recommend that you only use it under controlled
    conditions and for testing and debugging.
    
    The main focus of this version is on adding basic support for positioners
    to control steerable satellite dishes. Manually controlling the dish position
    and storing individual positions will follow later.
    
    The fixes contained in this version will be released in a stable version 2.0.3
    later, if there are no problems.
    
    From the HISTORY file:
    - Fixed initializing cDevice::keepTracks.
    - Fixed an endless loop in cTextWrapper::Set() in case the given Width is smaller than
      one character (reported by Stefan Braun).
    - Removed all "modified since version 1.6" markers from PLUGINS.html.
    - Added definitions for older DVB API versions, back until 5.0 (based on a patch from
      Udo Richter).
    - Changed cThread::SetIOPriority() from "best effort class" to "idle class" in order to
      improve overall performance when an editing process is running (thanks to Jochen
      Dolze).
    - Fixed handling '/' and '~' in recording file names in case DirectoryEncoding is
      used (thanks to Lars Hanisch).
    - Changed the sign of the satellite position value in cSource to reflect the standard
      of western values being negative. The new member function cSource::Position() can be
      used to retrieve the orbital position of a satellite.
    - Fixed multiple occurrences of the same directory in the recordings list in case there
      are directories that only differ in non-alphanumeric characters (was broken by
      "Fixed selecting the last replayed recording in the Recordings menu in case there
      are folders and plain recordings with names that differ only in non-alphanumeric
      characters" in version 1.7.36).
    - Fixed displaying the frame number when setting an editing mark (thanks to Thomas
      Günther).
    - Fixed no longer generating any editing marks if the edited recording results in just
      one single sequence (reported by Halim Sahin).
    - Fixed an error message when parsing SCR values in diseqc.conf.
    - Fixed an unexpected RCS version tag in the newplugin script.
    - Fixed an endless loop in the DrawEllipse() functions for very small ellipses (reported
      by Stefan Braun).
    - Fixed a crash in the LCARS skin's main menu in case there is no current channel
      (reported by Dominique Dumont).
    - Added basic support for positioners to control steerable satellite dishes (based on
      a patch from Seppo Ingalsuo and Ales Jurik).
      + Supports GotoN (aka "DiSEqC 1.2") and GotoX (aka "USALS").
      + The new DiSEqC command code 'P' can be used to instruct a positioner to move the
        dish to the required satellite position. When a 'P' code is processed, further
        execution of the remaining DiSEqC sequence (if any) is postponed until the positioner
        has reached the new satellite position.
      + The new special source value of "S360E" can be used in diseqc.conf to indicate that
        an entry using a positioner can move the dish to any requested position within its
        range. Think of it as "full circle".
      + The devices a particular cDiseqc or cScr applies to are now stored directly in each
        cDiseqc or cScr, respectively.
      + A plugin can implement a custom positioner control (see PLUGINS.html, section "Positioners").
      + The new function cSkinDisplayChannel::SetPositioner() can be implemented by skins to
        show the user a progress display when the dish is being moved. The default implementation
        calls SetMessage() with a string indicating the new position the dish is being moved to.
        The LCARS skin shows a progress bar indicating the movement of the dish.
      + The new parameters "Site latitude", "Site longitude", "Positioner speed", and
        "Positioner swing" in the "Setup/LNB" menu can be used to configure the necessary
        values for a steerable dish.
      + The cDvbTuner now has a new status tsPositioning, in which it waits until a steerable
        dish has reached its target position. Parsing SI data is paused until the target
        position has been reached.
    - The LCARS skin now shows the source value of the current channel in its channel display.
    - Fixed asserting free disk space in the cutter.
    - No longer trying to delete old recordings in AssertFreeDiskSpace() if the given
      Priority is less than 1.
    - Fixed handling LIRC events in case repeated events are lost.
    - Fixed a possible crash when shutting down VDR while subtitles are being displayed
      (reported by Ville Skyttä).
    - cDevice::IsPrimaryDevice() now also checks whether the primary device actually has
      a decoder and returns false otherwise. This should improve device allocation on
      systems that are only used as a receiver and don't actually display anything.
    - Increased the value of MAXRETRIES to 20 to reduce the probability of disturbances
      in transfer mode.
    - All bonded devices (except for the master) now turn off their LNB power completely
      to avoid problems when receiving vertically polarized transponders (suggested by
      Manfred Völkel and Oliver Endriss).
    - Reverted the change from version 1.5.7 that made all logging go to LOG_ERR (thanks
      to Christopher Reimer).
    - Added Begin/EndSegmentTransfer() to the EPG handler interface (thanks to Jörg Wendel).
    - The code for distributing recordings over several video directories is now
      deprecated and disabled by default.
      You can re-enable this feature by removing the comment sign ('//') from the beginning
      of the line
      //#define DEPRECATED_DISTRIBUTED_VIDEODIR // Code enclosed with this macro is ...
      in the file videodir.c. Note, though, that this can only be a temporary workaround.
      This feature will be completely removed in one of the next developer versions.
      Distributing the video directory over several disks was a useful feature in times
      when disks were still relatively small, but it also caused serious problems in case
      one of the disks failed. Nowadays hard disks come in sizes measured in terabytes,
      and tools like "mhddfs" can be used to combine several disks to form one large volume.
      A recommended method for a relatively safe disk setup in a VDR system is to use two
      1TB (or larger) disks and use them as a RAID-1 (mirrored). That way, if one disk
      fails, you can replace it without data loss.
---
 CONTRIBUTORS                            |  19 ++-
 Doxyfile.filter                         |   2 +-
 HISTORY                                 |  93 ++++++++++++++-
 INSTALL                                 |  35 +-----
 MANUAL                                  |  22 ++++
 Make.config.template                    |   2 +-
 Make.global                             |   2 +-
 Makefile                                |   4 +-
 PLUGINS.html                            | 104 +++++++++--------
 PLUGINS/src/dvbhddevice/HISTORY         |   5 +
 PLUGINS/src/dvbhddevice/dvbhddevice.c   |   2 +-
 PLUGINS/src/dvbhddevice/menu.c          |   7 +-
 PLUGINS/src/dvbhddevice/po/de_DE.po     |   5 +-
 PLUGINS/src/dvbhddevice/po/fi_FI.po     |   5 +-
 PLUGINS/src/dvbhddevice/po/it_IT.po     |   5 +-
 PLUGINS/src/dvbsddevice/HISTORY         |   5 +
 PLUGINS/src/dvbsddevice/Makefile        |   2 +-
 PLUGINS/src/dvbsddevice/dvbsddevice.c   |   6 +-
 PLUGINS/src/dvbsddevice/dvbsdffdevice.c |   2 +-
 PLUGINS/src/dvbsddevice/dvbsdffdevice.h |   2 +-
 PLUGINS/src/dvbsddevice/dvbsdffosd.c    |   2 +-
 PLUGINS/src/dvbsddevice/dvbsdffosd.h    |   2 +-
 PLUGINS/src/epgtableid0/Makefile        |   2 +-
 PLUGINS/src/epgtableid0/epgtableid0.c   |   2 +-
 PLUGINS/src/hello/Makefile              |   2 +-
 PLUGINS/src/hello/hello.c               |   2 +-
 PLUGINS/src/osddemo/Makefile            |   2 +-
 PLUGINS/src/osddemo/osddemo.c           |   2 +-
 PLUGINS/src/pictures/HISTORY            |   4 +
 PLUGINS/src/pictures/Makefile           |   2 +-
 PLUGINS/src/pictures/entry.c            |   2 +-
 PLUGINS/src/pictures/entry.h            |   2 +-
 PLUGINS/src/pictures/menu.c             |   2 +-
 PLUGINS/src/pictures/menu.h             |   2 +-
 PLUGINS/src/pictures/pic2mpg            |  10 +-
 PLUGINS/src/pictures/pictures.c         |   2 +-
 PLUGINS/src/pictures/player.c           |   2 +-
 PLUGINS/src/pictures/player.h           |   2 +-
 PLUGINS/src/rcu/Makefile                |   2 +-
 PLUGINS/src/rcu/rcu.c                   |   2 +-
 PLUGINS/src/servicedemo/Makefile        |   2 +-
 PLUGINS/src/servicedemo/svccli.c        |   2 +-
 PLUGINS/src/servicedemo/svcsvr.c        |   2 +-
 PLUGINS/src/skincurses/Makefile         |   2 +-
 PLUGINS/src/skincurses/skincurses.c     |   2 +-
 PLUGINS/src/status/Makefile             |   2 +-
 PLUGINS/src/status/status.c             |   2 +-
 PLUGINS/src/svdrpdemo/Makefile          |   2 +-
 PLUGINS/src/svdrpdemo/svdrpdemo.c       |   2 +-
 audio.c                                 |   2 +-
 audio.h                                 |   2 +-
 channels.c                              |   2 +-
 channels.h                              |   2 +-
 ci.c                                    |   2 +-
 ci.h                                    |   2 +-
 config.c                                |  20 +++-
 config.h                                |  16 ++-
 cutter.c                                |   6 +-
 cutter.h                                |   2 +-
 device.c                                |  10 +-
 device.h                                |  10 +-
 diseqc.c                                | 200 +++++++++++++++++++++++++++-----
 diseqc.conf                             |  14 ++-
 diseqc.h                                |  43 ++++++-
 dvbci.c                                 |   2 +-
 dvbci.h                                 |   2 +-
 dvbdevice.c                             | 101 +++++++++++++---
 dvbdevice.h                             |   3 +-
 dvbplayer.c                             |   2 +-
 dvbplayer.h                             |   2 +-
 dvbspu.c                                |   2 +-
 dvbspu.h                                |   2 +-
 dvbsubtitle.c                           |   2 +-
 dvbsubtitle.h                           |   2 +-
 eit.c                                   |   4 +-
 eit.h                                   |   2 +-
 eitscan.c                               |   2 +-
 eitscan.h                               |   2 +-
 epg.c                                   |  18 ++-
 epg.h                                   |  10 +-
 epg2html                                |   2 +-
 filter.c                                |   2 +-
 filter.h                                |   2 +-
 font.c                                  |   2 +-
 font.h                                  |   2 +-
 i18n.c                                  |   2 +-
 i18n.h                                  |   2 +-
 interface.c                             |   2 +-
 interface.h                             |   2 +-
 keys.c                                  |   2 +-
 keys.h                                  |   2 +-
 libsi/Makefile                          |   2 +-
 libsi/descriptor.c                      |   2 +-
 libsi/descriptor.h                      |   2 +-
 libsi/gendescr                          |   2 +-
 libsi/headers.h                         |   2 +-
 libsi/section.c                         |   2 +-
 libsi/section.h                         |   2 +-
 libsi/si.c                              |   2 +-
 libsi/si.h                              |   2 +-
 libsi/util.c                            |   2 +-
 libsi/util.h                            |   2 +-
 lirc.c                                  |   3 +-
 lirc.h                                  |   2 +-
 menu.c                                  |  30 ++++-
 menu.h                                  |   3 +-
 menuitems.c                             |  52 ++++++++-
 menuitems.h                             |  15 ++-
 newplugin                               |   2 +-
 nit.c                                   |   2 +-
 nit.h                                   |   2 +-
 osd.c                                   |   2 +-
 osd.h                                   |   2 +-
 osdbase.c                               |   4 +-
 osdbase.h                               |   2 +-
 pat.c                                   |   2 +-
 pat.h                                   |   2 +-
 player.c                                |   2 +-
 player.h                                |   2 +-
 plugin.c                                |   2 +-
 plugin.h                                |   2 +-
 po/ar.po                                |  33 +++++-
 po/ca_ES.po                             |  33 +++++-
 po/cs_CZ.po                             |  33 +++++-
 po/da_DK.po                             |  33 +++++-
 po/de_DE.po                             |  33 +++++-
 po/el_GR.po                             |  33 +++++-
 po/es_ES.po                             |  33 +++++-
 po/et_EE.po                             |  33 +++++-
 po/fi_FI.po                             |  33 +++++-
 po/fr_FR.po                             |  33 +++++-
 po/hr_HR.po                             |  33 +++++-
 po/hu_HU.po                             |  33 +++++-
 po/it_IT.po                             |  33 +++++-
 po/lt_LT.po                             |  33 +++++-
 po/mk_MK.po                             |  33 +++++-
 po/nl_NL.po                             |  33 +++++-
 po/nn_NO.po                             |  33 +++++-
 po/pl_PL.po                             |  33 +++++-
 po/pt_PT.po                             |  33 +++++-
 po/ro_RO.po                             |  33 +++++-
 po/ru_RU.po                             |  33 +++++-
 po/sk_SK.po                             |  33 +++++-
 po/sl_SI.po                             |  33 +++++-
 po/sr_RS.po                             |  33 +++++-
 po/sv_SE.po                             |  33 +++++-
 po/tr_TR.po                             |  33 +++++-
 po/uk_UA.po                             |  33 +++++-
 po/zh_CN.po                             |  33 +++++-
 positioner.c                            | 140 ++++++++++++++++++++++
 positioner.h                            | 171 +++++++++++++++++++++++++++
 receiver.c                              |   2 +-
 receiver.h                              |   2 +-
 recorder.c                              |   2 +-
 recorder.h                              |   2 +-
 recording.c                             |  48 ++++----
 recording.h                             |   2 +-
 remote.c                                |   2 +-
 remote.h                                |   2 +-
 remux.c                                 |   2 +-
 remux.h                                 |   2 +-
 ringbuffer.c                            |   2 +-
 ringbuffer.h                            |   2 +-
 runvdr.template                         |   2 +-
 sdt.c                                   |   2 +-
 sdt.h                                   |   2 +-
 sections.c                              |   2 +-
 sections.h                              |   2 +-
 shutdown.c                              |   2 +-
 shutdown.h                              |   2 +-
 skinclassic.c                           |   2 +-
 skinclassic.h                           |   2 +-
 skinlcars.c                             |  71 +++++++++++-
 skinlcars.h                             |   2 +-
 skins.c                                 |  18 ++-
 skins.h                                 |  17 ++-
 skinsttng.c                             |   2 +-
 skinsttng.h                             |   2 +-
 sourceparams.c                          |   2 +-
 sourceparams.h                          |   2 +-
 sources.c                               |  34 ++++--
 sources.conf                            |   2 +
 sources.h                               |  17 ++-
 spu.c                                   |   2 +-
 spu.h                                   |   2 +-
 status.c                                |   2 +-
 status.h                                |   2 +-
 summary2info                            |   2 +-
 svdrp.c                                 |   2 +-
 svdrp.h                                 |   2 +-
 themes.c                                |   2 +-
 themes.h                                |   2 +-
 thread.c                                |   2 +-
 thread.h                                |   3 +-
 timers.c                                |   2 +-
 timers.h                                |   2 +-
 tools.c                                 |   6 +-
 tools.h                                 |  14 ++-
 transfer.c                              |   4 +-
 transfer.h                              |   2 +-
 vdr.1                                   |   2 +-
 vdr.5                                   |   3 +-
 vdr.c                                   |   8 +-
 videodir.c                              |  42 ++++++-
 videodir.h                              |   2 +-
 205 files changed, 2277 insertions(+), 390 deletions(-)

diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 7203001..f162806 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -537,7 +537,7 @@ Andreas B
 Onno Kreuzinger <ok at solutas.net>
  for reporting leftover references to the file FORMATS in MANUAL and svdrp.c
 
-Rudi Hofer (Rudi.Hofer at gmx.de)
+Rudi Hofer <Rudi.Hofer at gmx.de>
  for his help in keeping 'channels.conf' up to date
  for reporting a problem with overlapping tab positions in skins when using wide fonts
 
@@ -700,6 +700,8 @@ Oliver Endriss <o.endriss at gmx.de>
  for helping to debug a problem with reduced number of retries in Transfer Mode on
  SD-FF cards
  for reporting a problem with resuming replay of PES recordings
+ for suggesting to make all bonded devices (except for the master) turn off their LNB
+ power completely to avoid problems when receiving vertically polarized transponders
 
 Reinhard Walter Buchner <rw.buchner at freenet.de>
  for adding some satellites to 'sources.conf'
@@ -1790,6 +1792,7 @@ Udo Richter <udo_richter at gmx.de>
  for requesting to keep using relative paths when building plugins locally
  for fixing a problem with detecting user inactivity in case the system time is
  changed after VDR has been started
+ for a patch that was used to add definitions for older DVB API versions, back until 5.0
 
 Sven Kreiensen <svenk at kammer.uni-hannover.de>
  for his help in keeping 'channels.conf.terr' up to date
@@ -2017,6 +2020,8 @@ Ville Skytt
  be escaped
  for changing the template for PLGCFG to $(CONFDIR)/plugins.mk
  for updating the help and man page entry about the location of the epg.data file
+ for reporting a possible crash when shutting down VDR while subtitles are being
+ displayed
 
 Steffen Beyer <cpunk at reactor.de>
  for fixing setting the colored button help after deleting a recording in case the next
@@ -2545,6 +2550,7 @@ J
  for reporting that cPlugin::Active() was called too often
  for adding HandledExternally() to the EPG handler interface
  for adding IsUpdate() to the EPG handler interface
+ for adding Begin/EndSegmentTransfer() to the EPG handler interface
 
 Peter Pinnau <vdr at unterbrecher.de>
  for reporting that 'uint32_t' requires including stdint.h in font.h on some systems
@@ -2695,6 +2701,7 @@ Ales Jurik <ajurik at quick.cz>
  for reporting broken SI data on Czech/Slovak channels after changing the default
  character set to ISO-8859-9
  for adding MPEG 1 handling to remux.c
+ for a patch that was used as a base for implementing support for positioners
 
 Magnus Andersson <svankan at bahnhof.se>
  for translating OSD texts to the Swedish language
@@ -2752,7 +2759,7 @@ Johann Friedrichs <johann.friedrichs at web.de>
 Timo Helkio <timolavi at mbnet.fi>
  for reporting a hangup when replaying a TS recording with subtitles activated
 
-Derek Kelly (user.vdr at gmail.com)
+Derek Kelly <user.vdr at gmail.com>
  for fixing handling the 'new' indicator in the recordings menu for TS recordings
  for reporting a problem with HD NTSC broadcasts that split frames over several payload
  units
@@ -2876,6 +2883,7 @@ Christopher Reimer <reimer.christopher at freenet.de>
  for making plugin Makefiles use DESTDIR and the 'install' program
  for suggesting to make sure that plugins include the VDR header files from the actual
  VDR source directory when doing "make plugins"
+ for reverting the change from version 1.5.7 that made all logging go to LOG_ERR
 
 Stefan Huskamp <coca_cola1 at gmx.de>
  for suggesting to make entering characters via the number keys
@@ -3154,3 +3162,10 @@ Jochen Dolze <vdr at dolze.de>
 
 Dominique Dumont <domi.dumont at free.fr>
  for reporting a crash in the LCARS skin's main menu in case there is no current channel
+
+Seppo Ingalsuo <seppo.ingalsuo at iki.fi>
+ for a patch that was used as a base for implementing support for positioners
+
+Manfred V�lkel <mvoelkel at digitaldevices.de>
+ for suggesting to make all bonded devices (except for the master) turn off their LNB
+ power completely to avoid problems when receiving vertically polarized transponders
diff --git a/Doxyfile.filter b/Doxyfile.filter
index 7fde955..59ba783 100755
--- a/Doxyfile.filter
+++ b/Doxyfile.filter
@@ -9,7 +9,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: Doxyfile.filter 2.1 2013/02/17 10:54:05 kls Exp $
+# $Id: Doxyfile.filter 3.0 2013/02/17 10:54:05 kls Exp $
 
 $TAG = "///<";
 
diff --git a/HISTORY b/HISTORY
index b6877ff..4794470 100644
--- a/HISTORY
+++ b/HISTORY
@@ -7144,7 +7144,7 @@ Video Disk Recorder Revision History
   Christian Richter).
 - Added DeleteEvent() to the EPG handler interface, so that an EPG handler can trigger
   deleting of an event (thanks to Christian Kaiser).
-- Speeded up opening menus on systems with many (several thousands) of recordings, by
+- Speeded up opening menus on systems with many (several thousands of) recordings, by
   caching the information whether a recording is stored on the video directory file
   system within the cRecording data (based on a patch from Torsten Lang).
 
@@ -7782,7 +7782,7 @@ Video Disk Recorder Revision History
 - Bumped all version numbers to 2.0.0.
 - Official release.
 
-2013-04-13: Version 2.0.1
+2013-04-11: Version 2.0.1
 
 - Fixed initializing cDevice::keepTracks.
 - Fixed an endless loop in cTextWrapper::Set() in case the given Width is smaller than
@@ -7805,10 +7805,97 @@ Video Disk Recorder Revision History
 - Fixed displaying the frame number when setting an editing mark (thanks to Thomas
   G�nther).
 - Fixed no longer generating any editing marks if the edited recording results in just
-  one single sequence.
+  one single sequence (reported by Halim Sahin).
 - Fixed an error message when parsing SCR values in diseqc.conf.
 - Fixed an unexpected RCS version tag in the newplugin script.
 - Fixed an endless loop in the DrawEllipse() functions for very small ellipses (reported
   by Stefan Braun).
 - Fixed a crash in the LCARS skin's main menu in case there is no current channel
   (reported by Dominique Dumont).
+
+2013-08-25: Version 2.1.1
+
+- Fixed initializing cDevice::keepTracks.
+- Fixed an endless loop in cTextWrapper::Set() in case the given Width is smaller than
+  one character (reported by Stefan Braun).
+- Removed all "modified since version 1.6" markers from PLUGINS.html.
+- Added definitions for older DVB API versions, back until 5.0 (based on a patch from
+  Udo Richter).
+- Changed cThread::SetIOPriority() from "best effort class" to "idle class" in order to
+  improve overall performance when an editing process is running (thanks to Jochen
+  Dolze).
+- Fixed handling '/' and '~' in recording file names in case DirectoryEncoding is
+  used (thanks to Lars Hanisch).
+- Changed the sign of the satellite position value in cSource to reflect the standard
+  of western values being negative. The new member function cSource::Position() can be
+  used to retrieve the orbital position of a satellite.
+- Fixed multiple occurrences of the same directory in the recordings list in case there
+  are directories that only differ in non-alphanumeric characters (was broken by
+  "Fixed selecting the last replayed recording in the Recordings menu in case there
+  are folders and plain recordings with names that differ only in non-alphanumeric
+  characters" in version 1.7.36).
+- Fixed displaying the frame number when setting an editing mark (thanks to Thomas
+  G�nther).
+- Fixed no longer generating any editing marks if the edited recording results in just
+  one single sequence (reported by Halim Sahin).
+- Fixed an error message when parsing SCR values in diseqc.conf.
+- Fixed an unexpected RCS version tag in the newplugin script.
+- Fixed an endless loop in the DrawEllipse() functions for very small ellipses (reported
+  by Stefan Braun).
+- Fixed a crash in the LCARS skin's main menu in case there is no current channel
+  (reported by Dominique Dumont).
+- Added basic support for positioners to control steerable satellite dishes (based on
+  a patch from Seppo Ingalsuo and Ales Jurik).
+  + Supports GotoN (aka "DiSEqC 1.2") and GotoX (aka "USALS").
+  + The new DiSEqC command code 'P' can be used to instruct a positioner to move the
+    dish to the required satellite position. When a 'P' code is processed, further
+    execution of the remaining DiSEqC sequence (if any) is postponed until the positioner
+    has reached the new satellite position.
+  + The new special source value of "S360E" can be used in diseqc.conf to indicate that
+    an entry using a positioner can move the dish to any requested position within its
+    range. Think of it as "full circle".
+  + The devices a particular cDiseqc or cScr applies to are now stored directly in each
+    cDiseqc or cScr, respectively.
+  + A plugin can implement a custom positioner control (see PLUGINS.html, section "Positioners").
+  + The new function cSkinDisplayChannel::SetPositioner() can be implemented by skins to
+    show the user a progress display when the dish is being moved. The default implementation
+    calls SetMessage() with a string indicating the new position the dish is being moved to.
+    The LCARS skin shows a progress bar indicating the movement of the dish.
+  + The new parameters "Site latitude", "Site longitude", "Positioner speed", and
+    "Positioner swing" in the "Setup/LNB" menu can be used to configure the necessary
+    values for a steerable dish.
+  + The cDvbTuner now has a new status tsPositioning, in which it waits until a steerable
+    dish has reached its target position. Parsing SI data is paused until the target
+    position has been reached.
+- The LCARS skin now shows the source value of the current channel in its channel display.
+- Fixed asserting free disk space in the cutter.
+- No longer trying to delete old recordings in AssertFreeDiskSpace() if the given
+  Priority is less than 1.
+- Fixed handling LIRC events in case repeated events are lost.
+- Fixed a possible crash when shutting down VDR while subtitles are being displayed
+  (reported by Ville Skytt�).
+- cDevice::IsPrimaryDevice() now also checks whether the primary device actually has
+  a decoder and returns false otherwise. This should improve device allocation on
+  systems that are only used as a receiver and don't actually display anything.
+- Increased the value of MAXRETRIES to 20 to reduce the probability of disturbances
+  in transfer mode.
+- All bonded devices (except for the master) now turn off their LNB power completely
+  to avoid problems when receiving vertically polarized transponders (suggested by
+  Manfred V�lkel and Oliver Endriss).
+- Reverted the change from version 1.5.7 that made all logging go to LOG_ERR (thanks
+  to Christopher Reimer).
+- Added Begin/EndSegmentTransfer() to the EPG handler interface (thanks to J�rg Wendel).
+- The code for distributing recordings over several video directories is now
+  deprecated and disabled by default.
+  You can re-enable this feature by removing the comment sign ('//') from the beginning
+  of the line
+  //#define DEPRECATED_DISTRIBUTED_VIDEODIR // Code enclosed with this macro is ...
+  in the file videodir.c. Note, though, that this can only be a temporary workaround.
+  This feature will be completely removed in one of the next developer versions.
+  Distributing the video directory over several disks was a useful feature in times
+  when disks were still relatively small, but it also caused serious problems in case
+  one of the disks failed. Nowadays hard disks come in sizes measured in terabytes,
+  and tools like "mhddfs" can be used to combine several disks to form one large volume.
+  A recommended method for a relatively safe disk setup in a VDR system is to use two
+  1TB (or larger) disks and use them as a RAID-1 (mirrored). That way, if one disk
+  fails, you can replace it without data loss.
diff --git a/INSTALL b/INSTALL
index dd0c999..f3a831f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -325,38 +325,9 @@ Note that the file system need not be 64-bit proof, since the 'vdr'
 program splits video files into chunks of about 2GB. You should use
 a disk with several gigabytes of free space. One GB can store roughly
 half an hour of SD video data, or 10 minutes of HD video.
-
-If you have more than one disk and don't want to combine them to form
-one large logical volume, you can set up several video directories as
-mount points for these disks. All of these directories must have the
-same basic name and must end with a numeric part, which starts at 0 for
-the main directory and has increasing values for the rest of the
-directories. For example
-
-   /srv/vdr/video0
-   /srv/vdr/video1
-   /srv/vdr/video2
-
-would be a setup with three directories. You can use more than one
-numeric digit:
-
-   /mnt/MyVideos/vdr.00
-   /mnt/MyVideos/vdr.01
-   /mnt/MyVideos/vdr.02
-   ...
-   /mnt/MyVideos/vdr.11
-
-would set up twelve disks (wow, what a machine that would be!).
-
-To use such a multi directory setup, you need to add the '-v' option
-with the name of the basic directory when running 'vdr':
-
-   vdr -v /srv/vdr/video0
-
-WARNING: Using multiple disks to form one large video directory this way
-is deprecated and will be removed from VDR in a future version! Either
-use one of today's large terabyte disks (preferably with a backup disk
-in a RAID-1 array), or use something like "mhddfs".
+Either use one of today's large terabyte disks (preferably with a backup disk
+in a RAID-1 array), or use something like "mhddfs" to group several disks
+into one large volume.
 
 Note that you should not copy any non-VDR files into the video directory,
 since this might cause a lot of unnecessary disk access when VDR cleans up those
diff --git a/MANUAL b/MANUAL
index cce2b0a..e698085 100644
--- a/MANUAL
+++ b/MANUAL
@@ -776,6 +776,28 @@ Version 2.0
                          are connected to the same sat cable must be set to the same
                          number here.
 
+  Use dish positioner = no
+                         By default, the 'P' command code in DiSEqC command sequences
+                         is ignored. Set this parameter to 'yes' if you are using a
+                         satellite dish positioner.
+
+  Site latitude (degrees) = 0
+  Site longitude (degrees) = 0
+                         Set these to the latitude and longitude of your dish's
+                         location if you use a satellite dish positioner. Use the
+                         "Green" key to switch between north/south and east/west,
+                         respectively.
+
+  Max. positioner swing (degrees) = 65
+                         Defines the maximum angle by which the positioner can move
+                         the dish away from due south (or north) in either direction.
+                         The valid range is 0...90.
+
+  Positioner speed (degrees/s) = 1.5
+                         Defines the speed at which the positioner moves the dish.
+                         The valid range is 0.1...180. This value is used to calculate
+                         how long it takes the positioner to reach the target position.
+
   CAM:
 
   n CAM Name             Shows the CAM slots that are present in this system, where
diff --git a/Make.config.template b/Make.config.template
index 2bc0a8f..9b1c4dd 100644
--- a/Make.config.template
+++ b/Make.config.template
@@ -6,7 +6,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: Make.config.template 2.19 2013/02/18 10:55:39 kls Exp $
+# $Id: Make.config.template 3.0 2013/02/18 10:55:39 kls Exp $
 
 ### The C compiler and options:
 
diff --git a/Make.global b/Make.global
index e259402..665cc28 100644
--- a/Make.global
+++ b/Make.global
@@ -4,7 +4,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: Make.global 1.2 2012/12/29 12:03:01 kls Exp $
+# $Id: Make.global 3.0 2012/12/29 12:03:01 kls Exp $
 
 # This is just a dummy file for plugins that use old style (version 1.7.33
 # or earlier) Makefiles.
diff --git a/Makefile b/Makefile
index d24d08f..eccec7f 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: Makefile 2.54 2013/03/11 15:01:01 kls Exp $
+# $Id: Makefile 3.1 2013/04/14 12:18:08 kls Exp $
 
 .DELETE_ON_ERROR:
 
@@ -68,7 +68,7 @@ SILIB    = $(LSIDIR)/libsi.a
 
 OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o\
        dvbplayer.o dvbspu.o dvbsubtitle.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\
-       lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o\
+       lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o positioner.o\
        receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\
        skinclassic.o skinlcars.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\
        timers.o tools.o transfer.o vdr.o videodir.o
diff --git a/PLUGINS.html b/PLUGINS.html
index d864fe2..454eae2 100644
--- a/PLUGINS.html
+++ b/PLUGINS.html
@@ -31,14 +31,14 @@ modified {
 <div class="center">
 <h1>The VDR Plugin System</h1>
 
-<b>Version 2.0</b>
+<b>Version 2.1</b>
 <p>
 Copyright © 2013 Klaus Schmidinger<br>
 <a href="mailto:vdr at tvdr.de">vdr at tvdr.de</a><br>
 <a href="http://www.tvdr.de">www.tvdr.de</a>
 </div>
 <div class="center">
-<modified>Important modifications introduced since version 1.6 are marked like this.</modified>
+<modified>Important modifications introduced since version 2.0 are marked like this.</modified>
 </div>
 <p>
 VDR provides an easy to use plugin interface that allows additional functionality
@@ -82,7 +82,7 @@ structures and allows it to hook itself into specific areas to perform special a
 <li><a href="#Wakeup">Wakeup</a>
 <li><a href="#Setup parameters">Setup parameters</a>
 <li><a href="#The Setup menu">The Setup menu</a>
-<li><modified><a href="#Additional files">Additional files</modified></a>
+<li><a href="#Additional files">Additional files</a>
 <li><a href="#Internationalization">Internationalization</a>
 <li><a href="#Custom services">Custom services</a>
 <li><a href="#SVDRP commands">SVDRP commands</a>
@@ -99,10 +99,11 @@ structures and allows it to hook itself into specific areas to perform special a
 <li><a href="#Skins">Skins</a>
 <li><a href="#Themes">Themes</a>
 <li><a href="#Devices">Devices</a>
+<li><modified><a href="#Positioners">Positioners</a></modified>
 <li><a href="#Audio">Audio</a>
 <li><a href="#Remote Control">Remote Control</a>
 <li><a href="#Conditional Access">Conditional Access</a>
-<li><modified><a href="#Electronic Program Guide">Electronic Program Guide</modified></a>
+<li><a href="#Electronic Program Guide">Electronic Program Guide</a>
 </ul>
 </ul>
 
@@ -173,15 +174,13 @@ The <tt>src</tt> directory contains one subdirectory for each plugin, which carr
 the name of that plugin (in the above example that would be <tt>hello</tt>).
 What's inside the individual source directory of a
 plugin is entirely up to the author of that plugin. The only prerequisites are
-that there is a <tt>Makefile</tt> that provides the targets <tt>all</tt><modified>, <tt>install</tt></modified> and
+that there is a <tt>Makefile</tt> that provides the targets <tt>all</tt>, <tt>install</tt> and
 <tt>clean</tt>, and that a call to <tt>make all</tt> actually produces a dynamically
 loadable library file for that plugin (we'll get to the details later).
-<modified>
 The dynamically loadable library file for the plugin shall be located directly under
 the plugin's source directory.
 See the section <a href="#Initializing a new plugin directory">Initializing a new plugin directory</a>
 for how to generate an example Makefile.
-</modified>
 <p>
 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
@@ -891,70 +890,51 @@ You can first assign the temporary values to the global variables and then do th
 your setup parameters and use that one to copy all parameters with one single statement
 (like VDR does with its cSetup class).
 
-<hr><h2><modified><a name="Additional files">Additional files</a></modified></h2>
+<hr><h2><a name="Additional files">Additional files</a></h2>
 
 <div class="blurb">I want my own stuff!</div><p>
 
-<modified>
 There may be situations where a plugin requires files of its own. While the plugin is
 free to store such files anywhere it sees fit, it might be a good idea to put them in a common
 place, preferably where such data already exists.
-</modified>
 <p>
-<modified>
 <i>configuration files</i>, maybe for data that can't be stored in the simple
 <a href="#Setup parameters">setup parameters</a> of VDR, or maybe because it needs to
 launch other programs that simply need a separate configuration file.
-</modified>
 <p>
-<modified>
 <i>cache files</i>, to store data so that future requests for that data can be served faster. The data
 that is stored within a cache might be values that have been computed earlier or duplicates of
 original values that are stored elsewhere.
-</modified>
 <p>
-<modified>
 <i>resource files</i>, for providing additional files, like pictures, movie clips or channel logos.
-</modified>
 <p>
-<modified>
 Therefore VDR provides the functions
 
 <p><table><tr><td class="code"><pre>
-<modified>
 const char *ConfigDirectory(const char *PluginName = NULL);
 const char *CacheDirectory(const char *PluginName = NULL);
 const char *ResourceDirectory(const char *PluginName = NULL);
-</modified>
 </pre></td></tr></table><p>
 
-<modified>
 each of which returns a string containing the directory that VDR uses for its own
 files (defined through the options in the call to VDR), extended by
-</modified>
 <tt>"/plugins"</tt>. So assuming the VDR configuration directory is <tt>/video</tt>
 (the default if no <tt><b>-c</b></tt> or <tt><b>-v</b></tt> option is given),
 a call to <tt>ConfigDirectory()</tt> will return <tt>/video/plugins</tt>. The first
 call to <tt>ConfigDirectory()</tt> will automatically make sure that the <tt>plugins</tt>
 subdirectory will exist. If, for some reason, this cannot be achieved, <tt>NULL</tt>
 will be returned.
-<modified>
 The behavior of <tt>CacheDirectory()</tt> and <tt>ResourceDirectory()</tt> is similar.
-</modified>
 <p>
 The additional <tt>plugins</tt> directory is used to keep files from plugins apart
 from those of VDR itself, making sure there will be no name clashes. If a plugin
-<modified>
 needs only one extra file, it is suggested that this file be named <tt>name.*</tt>,
 where <i>name</i> shall be the name of the plugin.
-</modified>
 <p>
 If a plugin needs more than one such file, it is suggested that the plugin stores
 these in a subdirectory of its own, named after the plugin. To easily get such a name
-<modified>
 the functions can be given an additional string that will be appended to the returned
 directory name, as in
-</modified>
 
 <p><table><tr><td class="code"><pre>
 const char *MyConfigDir = ConfigDirectory(Name());
@@ -965,16 +945,12 @@ plugin's name. Again, VDR will make sure that the requested directory will exist
 (or return <tt>NULL</tt> in case of an error).
 <p>
 <b>
-<modified>
 The returned strings are statically allocated and will be overwritten by subsequent calls!
-</modified>
 </b>
 <p>
-<modified>
 The <tt>ConfigDirectory()</tt>, <tt>CacheDirectory()</tt> and <tt>ResourceDirectory()</tt>
 functions are static member functions of the <tt>cPlugin</tt> class. This allows them to be
 called even from outside any member function of the derived plugin class, by writing
-</modified>
 
 <p><table><tr><td class="code"><pre>
 const char *MyConfigDir = cPlugin::ConfigDirectory();
@@ -1265,10 +1241,10 @@ If a plugin wants to get informed on various events in VDR, it can derive a clas
 
 class cMyStatusMonitor : public cStatus {
 protected:
-  virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber<modified>, bool LiveView</modified>);
+  virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView);
   };
 
-void cMyStatusMonitor::ChannelSwitch(const cDevice *Device, int ChannelNumber<modified>, bool LiveView</modified>)
+void cMyStatusMonitor::ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView)
 {
   if (ChannelNumber)
      dsyslog("channel switched to %d on DVB %d", ChannelNumber, Device->CardIndex());
@@ -1525,13 +1501,11 @@ public:
   cMyReceiver(int Pid);
   };
 
-<modified>
 cMyReceiver::cMyReceiver(int Pid)
 :cReceiver(NULL, -1)
 {
   AddPid(Pid);
 }
-</modified>
 
 cMyReceiver::~cMyReceiver()
 {
@@ -1557,7 +1531,7 @@ The above example sets up a receiver that wants to receive data from only one
 PID (for example the Teletext PID). In order to not interfere with other recording
 operations, it sets its priority to <tt>-1</tt> (any negative value will allow
 a <tt>cReceiver</tt> to be detached from its <tt>cDevice</tt> at any time
-<modified>in favor of a timer recording or live viewing</modified>).
+in favor of a timer recording or live viewing).
 <p>
 Once a <tt>cReceiver</tt> has been created, it needs to be <i>attached</i> to
 a <tt>cDevice</tt>:
@@ -1573,9 +1547,7 @@ the receiver is attached to the device that actually receives the current live
 video stream (this may be different from the primary device in case of <i>Transfer
 Mode</i>).
 <p>
-<modified>
 The <tt>cReceiver</tt> must be detached from its device before it is deleted.
-</modified>
 
 <hr><h2><a name="Filters">Filters</a></h2>
 
@@ -1853,7 +1825,7 @@ If the new device can receive, it most likely needs to provide a way of
 selecting which channel it shall tune to:
 
 <p><table><tr><td class="code"><pre>
-<modified>virtual int NumProvidedSystems(void) const;</modified>
+virtual int NumProvidedSystems(void) const;
 virtual bool ProvidesSource(int Source) const;
 virtual bool ProvidesTransponder(const cChannel *Channel) const;
 virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
@@ -1902,7 +1874,7 @@ virtual bool HasDecoder(void) const;
 virtual bool CanReplay(void) const;
 virtual bool SetPlayMode(ePlayMode PlayMode);
 virtual int64_t GetSTC(void);
-<modified>virtual bool IsPlayingVideo(void) const;</modified>
+virtual bool IsPlayingVideo(void) const;
 virtual bool HasIBPTrickSpeed(void);
 virtual void TrickSpeed(int Speed);
 virtual void Clear(void);
@@ -1931,7 +1903,7 @@ the functions
 
 <p><table><tr><td class="code"><pre>
 virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
-<modified>virtual int ReadFilter(int Handle, void *Buffer, size_t Length);</modified>
+virtual int ReadFilter(int Handle, void *Buffer, size_t Length);
 virtual void CloseFilter(int Handle);
 </pre></td></tr></table><p>
 
@@ -1987,7 +1959,6 @@ user - whether this goes through OSD facilities of the physical device (like
 a "full featured" DVB card) or through a graphics adapter that overlays its
 output with the video signal, doesn't matter.
 <p>
-<div class="modified">
 In order to be able to determine the proper size of the OSD, the device
 should implement the function
 
@@ -1996,7 +1967,6 @@ virtual void GetOsdSize(int &Width, int &Height, double &Aspect);
 </pre></td></tr></table><p>
 
 By default, an OSD size of 720x480 with an aspect ratio of 1.0 is assumed.
-</div modified>
 
 <p>
 <b>Initializing new devices</b>
@@ -2017,8 +1987,6 @@ Nothing needs to be done to shut down the devices. VDR will automatically
 shut down (delete) all devices when the program terminates. It is therefore
 important that the devices are created on the heap, using the <tt>new</tt>
 operator!
-
-<div class="modified">
 <p>
 <b>Device hooks</b>
 <p>
@@ -2056,6 +2024,48 @@ new cMyDeviceHook;
 </pre></td></tr></table><p>
 
 and shall not delete this object. It will be automatically deleted when the program ends.
+
+<div class="modified">
+<hr><h2><a name="Positioners">Positioners</a></h2>
+
+<div class="blurb">Now you see me - now you don't!</div><p>
+
+If you are using a positioner (also known as "motor" or "rotor") to move your
+satellite dish to receive various satellites, you will be using the 'P' command
+in the <tt>diseqc.conf</tt> file. This command sends the necessary data to the
+positioner to move the dish to the satellite's orbital position. By default VDR
+uses its builtin DiSEqC positioner control. If your positioner requires a different
+method of controlling (like maybe via a serial link), you can derive a class
+from <tt>cPositioner</tt>, as in
+
+<p><table><tr><td class="code"><pre>
+#include <vdr/positioner.h>
+
+class cMyPositioner : public cPositioner {
+private:
+  void SendDiseqc(uint8_t *Codes, int NumCodes);
+public:
+  cMyPositioner(void);
+  virtual void Drive(ePositionerDirection Direction);
+  virtual void Step(ePositionerDirection Direction, uint Steps = 1);
+  virtual void Halt(void);
+  virtual void SetLimit(ePositionerDirection Direction);
+  virtual void DisableLimits(void);
+  virtual void EnableLimits(void);
+  virtual void StorePosition(uint Number);
+  virtual void RecalcPositions(uint Number);
+  virtual void GotoPosition(uint Number, int Longitude);
+  virtual void GotoAngle(int Longitude);
+  };
+</pre></td></tr></table><p>
+
+See the implementation of <tt>cDiseqcPositioner</tt> in <tt>diseqc.c</tt> for details.
+<p>
+You should create your derived positioner object in the
+<a href="#Getting started"><tt>Start()</tt></a> function of your plugin.
+Note that the object has to be created on the heap (using <tt>new</tt>),
+and you shall not delete it at any point (it will be deleted automatically
+when the program ends).
 </div modified>
 
 <hr><h2><a name="Audio">Audio</a></h2>
@@ -2222,12 +2232,10 @@ Put(uint64 Code, bool Repeat = false, bool Release = false);
 
 The other parameters have the same meaning as in the first version of this function.
 <p>
-<modified>
 If your remote control has a repeat function that automatically repeats key events
 if a key is held pressed down for a while, your derived class should use the global
 parameters <tt>Setup.RcRepeatDelay</tt> and <tt>Setup.RcRepeatDelta</tt> to allow
 users to configure the behavior of this function.
-</modified>
 
 <hr><h2><a name="Conditional Access">Conditional Access</a></h2>
 
@@ -2264,7 +2272,6 @@ virtual bool Assign(cDevice *Device, bool Query = false);
 
 See the description of this function in <tt>ci.h</tt> for details.
 
-<div class="modified">
 <hr><h2><a name="Electronic Program Guide">Electronic Program Guide</a></h2>
 
 <div class="blurb">The grass is always greener on the other side...</div><p>
@@ -2294,7 +2301,6 @@ where <tt>DescriptionFromDatabase()</tt> would derive the description of the
 to signal VDR that no other EPG handlers shall be queried after this one.
 <p>
 See <tt>VDR/epg.h</tt> for details.
-</div modified>
 
 </body>
 </html>
diff --git a/PLUGINS/src/dvbhddevice/HISTORY b/PLUGINS/src/dvbhddevice/HISTORY
index d21abac..d22f14d 100644
--- a/PLUGINS/src/dvbhddevice/HISTORY
+++ b/PLUGINS/src/dvbhddevice/HISTORY
@@ -75,3 +75,8 @@ VDR Plugin 'dvbhddevice' Revision History
 2013-04-11: Version 2.0.1
 
 - Fixed aspect ratio and position of scaled video.
+
+2013-08-23: Version 2.1.1
+
+- Fixed aspect ratio and position of scaled video.
+- Added yellow button in main menu to send CEC TV-Off command.
diff --git a/PLUGINS/src/dvbhddevice/dvbhddevice.c b/PLUGINS/src/dvbhddevice/dvbhddevice.c
index d82b848..cfd71bb 100644
--- a/PLUGINS/src/dvbhddevice/dvbhddevice.c
+++ b/PLUGINS/src/dvbhddevice/dvbhddevice.c
@@ -10,7 +10,7 @@
 #include "menu.h"
 #include "setup.h"
 
-static const char *VERSION        = "2.0.1";
+static const char *VERSION        = "2.1.1";
 static const char *DESCRIPTION    = trNOOP("HD Full Featured DVB device");
 static const char *MAINMENUENTRY  = "dvbhddevice";
 
diff --git a/PLUGINS/src/dvbhddevice/menu.c b/PLUGINS/src/dvbhddevice/menu.c
index e8fd867..b7d35cf 100644
--- a/PLUGINS/src/dvbhddevice/menu.c
+++ b/PLUGINS/src/dvbhddevice/menu.c
@@ -13,7 +13,7 @@ cHdffMenu::cHdffMenu(HDFF::cHdffCmdIf * pHdffCmdIf)
 {
     mVideoConversionItem = new cOsdItem("", osUnknown, false);
     Add(mVideoConversionItem);
-    SetHelp(tr("Video Conversion"), tr("TV on"));
+    SetHelp(tr("Video Conversion"), tr("TV on"), tr("TV off"));
     SetVideoConversion();
 }
 
@@ -38,6 +38,11 @@ eOSState cHdffMenu::ProcessKey(eKeys key)
                 state = osEnd;
                 break;
 
+            case kYellow:
+                mHdffCmdIf->CmdHdmiSendCecCommand(HDFF_CEC_COMMAND_TV_OFF);
+                state = osEnd;
+                break;
+
             case kOk:
                 state = osEnd;
                 break;
diff --git a/PLUGINS/src/dvbhddevice/po/de_DE.po b/PLUGINS/src/dvbhddevice/po/de_DE.po
index f884567..34b19a7 100644
--- a/PLUGINS/src/dvbhddevice/po/de_DE.po
+++ b/PLUGINS/src/dvbhddevice/po/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: vdr-dvbhddevice 0.0.4\n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2012-11-13 20:08+0100\n"
+"POT-Creation-Date: 2013-08-23 12:10+0200\n"
 "PO-Revision-Date: 2011-04-25 21:44+0200\n"
 "Last-Translator: Christoph Haubrich\n"
 "Language-Team: <see README>\n"
@@ -25,6 +25,9 @@ msgstr "Bildanpassung"
 msgid "TV on"
 msgstr "TV ein"
 
+msgid "TV off"
+msgstr "TV aus"
+
 msgid "Automatic"
 msgstr "automatisch"
 
diff --git a/PLUGINS/src/dvbhddevice/po/fi_FI.po b/PLUGINS/src/dvbhddevice/po/fi_FI.po
index 7d32953..9bd9a39 100644
--- a/PLUGINS/src/dvbhddevice/po/fi_FI.po
+++ b/PLUGINS/src/dvbhddevice/po/fi_FI.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: vdr-dvbhddevice 0.0.4\n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2012-11-13 20:08+0100\n"
+"POT-Creation-Date: 2013-08-23 12:10+0200\n"
 "PO-Revision-Date: 2011-04-25 21:44+0200\n"
 "Last-Translator: Rolf Ahrenberg\n"
 "Language-Team: Finnish <vdr at linuxtv.org>\n"
@@ -25,6 +25,9 @@ msgstr "Näyttömuoto"
 msgid "TV on"
 msgstr "TV päälle"
 
+msgid "TV off"
+msgstr ""
+
 msgid "Automatic"
 msgstr "automaattinen"
 
diff --git a/PLUGINS/src/dvbhddevice/po/it_IT.po b/PLUGINS/src/dvbhddevice/po/it_IT.po
index be712b2..2d895c6 100644
--- a/PLUGINS/src/dvbhddevice/po/it_IT.po
+++ b/PLUGINS/src/dvbhddevice/po/it_IT.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: vdr-dvbhddevice 0.0.4\n"
 "Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2012-11-13 20:08+0100\n"
+"POT-Creation-Date: 2013-08-23 12:10+0200\n"
 "PO-Revision-Date: 2013-02-18 23:42+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian at tiscali.it>\n"
 "Language-Team:  <see README>\n"
@@ -29,6 +29,9 @@ msgstr "Conversione video"
 msgid "TV on"
 msgstr "TV accesa"
 
+msgid "TV off"
+msgstr ""
+
 msgid "Automatic"
 msgstr "Automatica"
 
diff --git a/PLUGINS/src/dvbsddevice/HISTORY b/PLUGINS/src/dvbsddevice/HISTORY
index 4dd75d2..cb6753a 100644
--- a/PLUGINS/src/dvbsddevice/HISTORY
+++ b/PLUGINS/src/dvbsddevice/HISTORY
@@ -45,3 +45,8 @@ VDR Plugin 'dvbsddevice' Revision History
 2013-03-31: Version 2.0.0
 
 - Official release.
+
+2013-08-22: Version 2.0.1
+
+- Fixed handling the -o option (short form of --outputonly; problem reported by
+  Mario Edelmann).
diff --git a/PLUGINS/src/dvbsddevice/Makefile b/PLUGINS/src/dvbsddevice/Makefile
index f7e73b2..5a4635e 100644
--- a/PLUGINS/src/dvbsddevice/Makefile
+++ b/PLUGINS/src/dvbsddevice/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.20 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/dvbsddevice/dvbsddevice.c b/PLUGINS/src/dvbsddevice/dvbsddevice.c
index cdc0783..3f57f23 100644
--- a/PLUGINS/src/dvbsddevice/dvbsddevice.c
+++ b/PLUGINS/src/dvbsddevice/dvbsddevice.c
@@ -3,14 +3,14 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: dvbsddevice.c 1.10 2013/03/31 09:30:18 kls Exp $
+ * $Id: dvbsddevice.c 3.1 2013/08/22 08:20:18 kls Exp $
  */
 
 #include <getopt.h>
 #include <vdr/plugin.h>
 #include "dvbsdffdevice.h"
 
-static const char *VERSION        = "2.0.0";
+static const char *VERSION        = "2.0.1";
 static const char *DESCRIPTION    = "SD Full Featured DVB device";
 
 class cPluginDvbsddevice : public cPlugin {
@@ -48,7 +48,7 @@ bool cPluginDvbsddevice::ProcessArgs(int argc, char *argv[])
      };
 
   int c;
-  while ((c = getopt_long(argc, argv, "", long_options, NULL)) != -1) {
+  while ((c = getopt_long(argc, argv, "o", long_options, NULL)) != -1) {
         switch (c) {
           case 'o': probe->SetOutputOnly(true);
                     break;
diff --git a/PLUGINS/src/dvbsddevice/dvbsdffdevice.c b/PLUGINS/src/dvbsddevice/dvbsdffdevice.c
index 4e98cdd..02e6306 100644
--- a/PLUGINS/src/dvbsddevice/dvbsdffdevice.c
+++ b/PLUGINS/src/dvbsddevice/dvbsdffdevice.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: dvbsdffdevice.c 2.35 2013/02/17 13:16:18 kls Exp $
+ * $Id: dvbsdffdevice.c 3.0 2013/02/17 13:16:18 kls Exp $
  */
 
 #include "dvbsdffdevice.h"
diff --git a/PLUGINS/src/dvbsddevice/dvbsdffdevice.h b/PLUGINS/src/dvbsddevice/dvbsdffdevice.h
index bbf2ec2..10289e9 100644
--- a/PLUGINS/src/dvbsddevice/dvbsdffdevice.h
+++ b/PLUGINS/src/dvbsddevice/dvbsdffdevice.h
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: dvbsdffdevice.h 2.16 2013/02/17 13:16:29 kls Exp $
+ * $Id: dvbsdffdevice.h 3.0 2013/02/17 13:16:29 kls Exp $
  */
 
 #ifndef __DVBSDFFDEVICE_H
diff --git a/PLUGINS/src/dvbsddevice/dvbsdffosd.c b/PLUGINS/src/dvbsddevice/dvbsdffosd.c
index 46c65e0..1a8caf8 100644
--- a/PLUGINS/src/dvbsddevice/dvbsdffosd.c
+++ b/PLUGINS/src/dvbsddevice/dvbsdffosd.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: dvbsdffosd.c 2.3 2011/04/17 12:55:09 kls Exp $
+ * $Id: dvbsdffosd.c 3.0 2011/04/17 12:55:09 kls Exp $
  */
 
 #include "dvbsdffosd.h"
diff --git a/PLUGINS/src/dvbsddevice/dvbsdffosd.h b/PLUGINS/src/dvbsddevice/dvbsdffosd.h
index bf12343..b832208 100644
--- a/PLUGINS/src/dvbsddevice/dvbsdffosd.h
+++ b/PLUGINS/src/dvbsddevice/dvbsdffosd.h
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: dvbsdffosd.h 2.2 2012/12/03 13:43:55 kls Exp $
+ * $Id: dvbsdffosd.h 3.0 2012/12/03 13:43:55 kls Exp $
  */
 
 #ifndef __DVBSDFFODF_H
diff --git a/PLUGINS/src/epgtableid0/Makefile b/PLUGINS/src/epgtableid0/Makefile
index 6190e62..31b7cea 100644
--- a/PLUGINS/src/epgtableid0/Makefile
+++ b/PLUGINS/src/epgtableid0/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.13 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/epgtableid0/epgtableid0.c b/PLUGINS/src/epgtableid0/epgtableid0.c
index 1aef2a7..2715ce7 100644
--- a/PLUGINS/src/epgtableid0/epgtableid0.c
+++ b/PLUGINS/src/epgtableid0/epgtableid0.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: epgtableid0.c 1.4 2013/03/31 09:30:18 kls Exp $
+ * $Id: epgtableid0.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <vdr/epg.h>
diff --git a/PLUGINS/src/hello/Makefile b/PLUGINS/src/hello/Makefile
index 4bdd5c9..a312681 100644
--- a/PLUGINS/src/hello/Makefile
+++ b/PLUGINS/src/hello/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.18 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/hello/hello.c b/PLUGINS/src/hello/hello.c
index 21f9383..b0b4ff7 100644
--- a/PLUGINS/src/hello/hello.c
+++ b/PLUGINS/src/hello/hello.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: hello.c 2.6 2013/03/31 09:30:18 kls Exp $
+ * $Id: hello.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <getopt.h>
diff --git a/PLUGINS/src/osddemo/Makefile b/PLUGINS/src/osddemo/Makefile
index 9b7e2c1..65b2a48 100644
--- a/PLUGINS/src/osddemo/Makefile
+++ b/PLUGINS/src/osddemo/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.16 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/osddemo/osddemo.c b/PLUGINS/src/osddemo/osddemo.c
index f88f776..8435a86 100644
--- a/PLUGINS/src/osddemo/osddemo.c
+++ b/PLUGINS/src/osddemo/osddemo.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: osddemo.c 2.12 2013/03/31 09:30:18 kls Exp $
+ * $Id: osddemo.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <vdr/osd.h>
diff --git a/PLUGINS/src/pictures/HISTORY b/PLUGINS/src/pictures/HISTORY
index a9995d7..4b1db67 100644
--- a/PLUGINS/src/pictures/HISTORY
+++ b/PLUGINS/src/pictures/HISTORY
@@ -87,3 +87,7 @@ VDR Plugin 'pictures' Revision History
 2013-03-31: Version 2.0.0
 
 - Official release.
+
+2013-07-01:
+
+- Added option -x to pic2mpg.
diff --git a/PLUGINS/src/pictures/Makefile b/PLUGINS/src/pictures/Makefile
index 3081e27..8810368 100644
--- a/PLUGINS/src/pictures/Makefile
+++ b/PLUGINS/src/pictures/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.18 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/pictures/entry.c b/PLUGINS/src/pictures/entry.c
index 8c124b5..ce2a3e2 100644
--- a/PLUGINS/src/pictures/entry.c
+++ b/PLUGINS/src/pictures/entry.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: entry.c 2.1 2012/02/17 14:00:28 kls Exp $
+ * $Id: entry.c 3.0 2012/02/17 14:00:28 kls Exp $
  */
 
 #include "entry.h"
diff --git a/PLUGINS/src/pictures/entry.h b/PLUGINS/src/pictures/entry.h
index 60b7773..9de4dd3 100644
--- a/PLUGINS/src/pictures/entry.h
+++ b/PLUGINS/src/pictures/entry.h
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: entry.h 2.0 2008/01/06 12:30:50 kls Exp $
+ * $Id: entry.h 3.0 2008/01/06 12:30:50 kls Exp $
  */
 
 #ifndef _ENTRY_H
diff --git a/PLUGINS/src/pictures/menu.c b/PLUGINS/src/pictures/menu.c
index 8c51d52..567f9e7 100644
--- a/PLUGINS/src/pictures/menu.c
+++ b/PLUGINS/src/pictures/menu.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: menu.c 2.0 2008/01/13 11:35:18 kls Exp $
+ * $Id: menu.c 3.0 2008/01/13 11:35:18 kls Exp $
  */
 
 #include "menu.h"
diff --git a/PLUGINS/src/pictures/menu.h b/PLUGINS/src/pictures/menu.h
index 9090fd0..585b0d5 100644
--- a/PLUGINS/src/pictures/menu.h
+++ b/PLUGINS/src/pictures/menu.h
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: menu.h 2.0 2008/01/12 11:22:52 kls Exp $
+ * $Id: menu.h 3.0 2008/01/12 11:22:52 kls Exp $
  */
 
 #ifndef _MENU_H
diff --git a/PLUGINS/src/pictures/pic2mpg b/PLUGINS/src/pictures/pic2mpg
index 2ba8de7..8bb6c2e 100755
--- a/PLUGINS/src/pictures/pic2mpg
+++ b/PLUGINS/src/pictures/pic2mpg
@@ -7,7 +7,7 @@
 #
 # See the README file for copyright information and how to reach the author.
 #
-# $Id: pic2mpg 2.5 2013/02/17 13:17:13 kls Exp $
+# $Id: pic2mpg 3.1 2013/07/01 08:33:38 kls Exp $
 
 use File::Path;
 use File::Spec;
@@ -23,9 +23,10 @@ Options: -f             Force conversion
          -o percent     overscan in percent
          -s size        Screen size (WIDTHxHEIGHT, default is 1920x1080)
          -v num         Verbose (0=none, 1=list files, 2=detailed)
+         -x dir[,...]   eXclude the given directories
 };
 
-getopts("fho:s:v:") || die $Usage;
+getopts("fho:s:v:x:") || die $Usage;
 
 die $Usage if $opt_h;
 
@@ -33,6 +34,7 @@ $Force     = $opt_f;
 $Overscan  = $opt_o || 0;
 $Size      = $opt_s || "1920x1080";
 $Verbose   = $opt_v;
+ at Exclude   = split(',', $opt_x || "");
 
 $ListFiles = $Verbose >= 1;
 $Detailed  = $Verbose >= 2;
@@ -85,7 +87,11 @@ chdir($PICDIR) || die "$PICDIR: $!\n";
 @Pictures = `find -type f | sort`;
 chomp(@Pictures);
 
+PIC:
 for $pic (@Pictures) {
+    for (@Exclude) {
+        next PIC if ($pic =~ /\/$_\//);
+        }
     my $mpg = "$MPGDIR/$pic.mpg";
     if ($Force || !-e $mpg || -M $mpg > -M $pic) {
        (my $dir = $mpg) =~ s/\/[^\/]*$//;
diff --git a/PLUGINS/src/pictures/pictures.c b/PLUGINS/src/pictures/pictures.c
index 7a46a5f..77c2eb0 100644
--- a/PLUGINS/src/pictures/pictures.c
+++ b/PLUGINS/src/pictures/pictures.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: pictures.c 2.9 2013/03/31 09:30:18 kls Exp $
+ * $Id: pictures.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <getopt.h>
diff --git a/PLUGINS/src/pictures/player.c b/PLUGINS/src/pictures/player.c
index 6048d4c..f2e4e5f 100644
--- a/PLUGINS/src/pictures/player.c
+++ b/PLUGINS/src/pictures/player.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: player.c 2.2 2012/04/28 11:58:15 kls Exp $
+ * $Id: player.c 3.0 2012/04/28 11:58:15 kls Exp $
  */
 
 #include "player.h"
diff --git a/PLUGINS/src/pictures/player.h b/PLUGINS/src/pictures/player.h
index 7a0b401..cf18d35 100644
--- a/PLUGINS/src/pictures/player.h
+++ b/PLUGINS/src/pictures/player.h
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: player.h 2.1 2012/04/28 11:56:01 kls Exp $
+ * $Id: player.h 3.0 2012/04/28 11:56:01 kls Exp $
  */
 
 #ifndef _PLAYER_H
diff --git a/PLUGINS/src/rcu/Makefile b/PLUGINS/src/rcu/Makefile
index 3dbecdd..f56236a 100644
--- a/PLUGINS/src/rcu/Makefile
+++ b/PLUGINS/src/rcu/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 1.13 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/rcu/rcu.c b/PLUGINS/src/rcu/rcu.c
index 17b538a..d7a83e7 100644
--- a/PLUGINS/src/rcu/rcu.c
+++ b/PLUGINS/src/rcu/rcu.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: rcu.c 1.5 2013/03/31 09:30:18 kls Exp $
+ * $Id: rcu.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <getopt.h>
diff --git a/PLUGINS/src/servicedemo/Makefile b/PLUGINS/src/servicedemo/Makefile
index e5ba5f5..ec4adcd 100644
--- a/PLUGINS/src/servicedemo/Makefile
+++ b/PLUGINS/src/servicedemo/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.14 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/servicedemo/svccli.c b/PLUGINS/src/servicedemo/svccli.c
index eb671ac..5f0c83c 100644
--- a/PLUGINS/src/servicedemo/svccli.c
+++ b/PLUGINS/src/servicedemo/svccli.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: svccli.c 2.4 2013/03/31 09:30:18 kls Exp $
+ * $Id: svccli.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <stdlib.h>
diff --git a/PLUGINS/src/servicedemo/svcsvr.c b/PLUGINS/src/servicedemo/svcsvr.c
index 252a4a2..12a1272 100644
--- a/PLUGINS/src/servicedemo/svcsvr.c
+++ b/PLUGINS/src/servicedemo/svcsvr.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: svcsvr.c 2.4 2013/03/31 09:30:18 kls Exp $
+ * $Id: svcsvr.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <stdlib.h>
diff --git a/PLUGINS/src/skincurses/Makefile b/PLUGINS/src/skincurses/Makefile
index fa0ce41..d2a4e47 100644
--- a/PLUGINS/src/skincurses/Makefile
+++ b/PLUGINS/src/skincurses/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.18 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/skincurses/skincurses.c b/PLUGINS/src/skincurses/skincurses.c
index 8a4da96..4b59df6 100644
--- a/PLUGINS/src/skincurses/skincurses.c
+++ b/PLUGINS/src/skincurses/skincurses.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: skincurses.c 2.13 2013/03/31 09:30:18 kls Exp $
+ * $Id: skincurses.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <ncurses.h>
diff --git a/PLUGINS/src/status/Makefile b/PLUGINS/src/status/Makefile
index 8f6e26f..c719e29 100644
--- a/PLUGINS/src/status/Makefile
+++ b/PLUGINS/src/status/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.15 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/status/status.c b/PLUGINS/src/status/status.c
index e9e3ae7..5c81faa 100644
--- a/PLUGINS/src/status/status.c
+++ b/PLUGINS/src/status/status.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: status.c 2.4 2013/03/31 09:30:18 kls Exp $
+ * $Id: status.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <vdr/plugin.h>
diff --git a/PLUGINS/src/svdrpdemo/Makefile b/PLUGINS/src/svdrpdemo/Makefile
index 2e39140..cdae2d1 100644
--- a/PLUGINS/src/svdrpdemo/Makefile
+++ b/PLUGINS/src/svdrpdemo/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a Video Disk Recorder plugin
 #
-# $Id: Makefile 2.15 2013/01/12 13:45:01 kls Exp $
+# $Id: Makefile 3.0 2013/01/12 13:45:01 kls Exp $
 
 # The official name of this plugin.
 # This name will be used in the '-P...' option of VDR to load the plugin.
diff --git a/PLUGINS/src/svdrpdemo/svdrpdemo.c b/PLUGINS/src/svdrpdemo/svdrpdemo.c
index a1a2766..ac9ae4c 100644
--- a/PLUGINS/src/svdrpdemo/svdrpdemo.c
+++ b/PLUGINS/src/svdrpdemo/svdrpdemo.c
@@ -3,7 +3,7 @@
  *
  * See the README file for copyright information and how to reach the author.
  *
- * $Id: svdrpdemo.c 2.3 2013/03/31 09:30:18 kls Exp $
+ * $Id: svdrpdemo.c 3.0 2013/03/31 09:30:18 kls Exp $
  */
 
 #include <vdr/plugin.h>
diff --git a/audio.c b/audio.c
index abffa3a..ebb98ed 100644
--- a/audio.c
+++ b/audio.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: audio.c 2.2 2010/05/16 13:30:11 kls Exp $
+ * $Id: audio.c 3.0 2010/05/16 13:30:11 kls Exp $
  */
 
 #include "audio.h"
diff --git a/audio.h b/audio.h
index f99a84a..37d0b51 100644
--- a/audio.h
+++ b/audio.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: audio.h 2.1 2008/07/06 11:39:21 kls Exp $
+ * $Id: audio.h 3.0 2008/07/06 11:39:21 kls Exp $
  */
 
 #ifndef __AUDIO_H
diff --git a/channels.c b/channels.c
index 4c04608..c205f84 100644
--- a/channels.c
+++ b/channels.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: channels.c 2.24 2012/07/14 12:34:47 kls Exp $
+ * $Id: channels.c 3.0 2012/07/14 12:34:47 kls Exp $
  */
 
 #include "channels.h"
diff --git a/channels.h b/channels.h
index 815cb47..3f9867b 100644
--- a/channels.h
+++ b/channels.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: channels.h 2.16 2012/06/17 11:21:33 kls Exp $
+ * $Id: channels.h 3.0 2012/06/17 11:21:33 kls Exp $
  */
 
 #ifndef __CHANNELS_H
diff --git a/ci.c b/ci.c
index 9a4a829..ba0c344 100644
--- a/ci.c
+++ b/ci.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: ci.c 2.12 2013/02/17 13:17:28 kls Exp $
+ * $Id: ci.c 3.0 2013/02/17 13:17:28 kls Exp $
  */
 
 #include "ci.h"
diff --git a/ci.h b/ci.h
index 74e0270..4fe44c7 100644
--- a/ci.h
+++ b/ci.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: ci.h 2.2 2012/02/29 10:24:27 kls Exp $
+ * $Id: ci.h 3.0 2012/02/29 10:24:27 kls Exp $
  */
 
 #ifndef __CI_H
diff --git a/config.c b/config.c
index 7a153cb..591d2ce 100644
--- a/config.c
+++ b/config.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.c 2.38 2013/03/18 08:57:50 kls Exp $
+ * $Id: config.c 3.1 2013/05/23 12:41:06 kls Exp $
  */
 
 #include "config.h"
@@ -389,6 +389,12 @@ cSetup::cSetup(void)
   LnbFrequLo =  9750;
   LnbFrequHi = 10600;
   DiSEqC = 0;
+  UsePositioner = 0;
+  SiteLat = 0;
+  SiteLon = 0;
+  PositionerSpeed = 15;
+  PositionerSwing = 65;
+  PositionerLastLon = 0;
   SetSystemTime = 0;
   TimeSource = 0;
   TimeTransponder = 0;
@@ -594,6 +600,12 @@ bool cSetup::Parse(const char *Name, const char *Value)
   else if (!strcasecmp(Name, "LnbFrequLo"))          LnbFrequLo         = atoi(Value);
   else if (!strcasecmp(Name, "LnbFrequHi"))          LnbFrequHi         = atoi(Value);
   else if (!strcasecmp(Name, "DiSEqC"))              DiSEqC             = atoi(Value);
+  else if (!strcasecmp(Name, "UsePositioner"))       UsePositioner      = atoi(Value);
+  else if (!strcasecmp(Name, "SiteLat"))             SiteLat            = atoi(Value);
+  else if (!strcasecmp(Name, "SiteLon"))             SiteLon            = atoi(Value);
+  else if (!strcasecmp(Name, "PositionerSpeed"))     PositionerSpeed    = atoi(Value);
+  else if (!strcasecmp(Name, "PositionerSwing"))     PositionerSwing    = atoi(Value);
+  else if (!strcasecmp(Name, "PositionerLastLon"))   PositionerLastLon  = atoi(Value);
   else if (!strcasecmp(Name, "SetSystemTime"))       SetSystemTime      = atoi(Value);
   else if (!strcasecmp(Name, "TimeSource"))          TimeSource         = cSource::FromString(Value);
   else if (!strcasecmp(Name, "TimeTransponder"))     TimeTransponder    = atoi(Value);
@@ -703,6 +715,12 @@ bool cSetup::Save(void)
   Store("LnbFrequLo",         LnbFrequLo);
   Store("LnbFrequHi",         LnbFrequHi);
   Store("DiSEqC",             DiSEqC);
+  Store("UsePositioner",      UsePositioner);
+  Store("SiteLat",            SiteLat);
+  Store("SiteLon",            SiteLon);
+  Store("PositionerSpeed",    PositionerSpeed);
+  Store("PositionerSwing",    PositionerSwing);
+  Store("PositionerLastLon",  PositionerLastLon);
   Store("SetSystemTime",      SetSystemTime);
   Store("TimeSource",         cSource::ToString(TimeSource));
   Store("TimeTransponder",    TimeTransponder);
diff --git a/config.h b/config.h
index d99e2d1..6d1c0da 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.h 2.76.1.2 2013/04/27 10:18:08 kls Exp $
+ * $Id: config.h 3.2 2013/05/23 12:40:19 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -22,13 +22,13 @@
 
 // VDR's own version number:
 
-#define VDRVERSION  "2.0.2"
-#define VDRVERSNUM   20002  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "2.1.1"
+#define VDRVERSNUM   20101  // Version * 10000 + Major * 100 + Minor
 
 // The plugin API's version number:
 
-#define APIVERSION  "2.0.0"
-#define APIVERSNUM   20000  // Version * 10000 + Major * 100 + Minor
+#define APIVERSION  "2.1.1"
+#define APIVERSNUM   20101  // 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
@@ -266,6 +266,12 @@ public:
   int LnbFrequLo;
   int LnbFrequHi;
   int DiSEqC;
+  int UsePositioner;
+  int SiteLat;
+  int SiteLon;
+  int PositionerSpeed;
+  int PositionerSwing;
+  int PositionerLastLon;
   int SetSystemTime;
   int TimeSource;
   int TimeTransponder;
diff --git a/cutter.c b/cutter.c
index 6e5e662..5d007c4 100644
--- a/cutter.c
+++ b/cutter.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: cutter.c 2.25.1.1 2013/05/02 09:21:18 kls Exp $
+ * $Id: cutter.c 3.2 2013/08/21 13:15:24 kls Exp $
  */
 
 #include "cutter.h"
@@ -556,6 +556,8 @@ bool cCuttingThread::ProcessSequence(int LastEndIndex, int BeginIndex, int EndIn
       bool Independent;
       int Length;
       if (LoadFrame(Index, Buffer, Independent, Length)) {
+         // Make sure there is enough disk space:
+         AssertFreeDiskSpace(-1);
          bool CutIn = !SeamlessBegin && Index == BeginIndex;
          bool CutOut = !SeamlessEnd && Index == EndIndex - 1;
          bool DeletedFrame = false;
@@ -608,8 +610,6 @@ void cCuttingThread::Action(void)
               cCondWait::SleepMs(100);
               continue;
               }
-           // Make sure there is enough disk space:
-           AssertFreeDiskSpace(-1);
            // Determine the actual begin and end marks, skipping any marks at the same position:
            cMark *EndMark = fromMarks.GetNextEnd(BeginMark);
            // Process the current sequence:
diff --git a/cutter.h b/cutter.h
index f48ae3f..6821fd4 100644
--- a/cutter.h
+++ b/cutter.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: cutter.h 2.3 2012/02/16 12:05:33 kls Exp $
+ * $Id: cutter.h 3.0 2012/02/16 12:05:33 kls Exp $
  */
 
 #ifndef __CUTTER_H
diff --git a/device.c b/device.c
index e0fe84a..a5afcfc 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.c 2.74.1.1 2013/04/05 10:47:38 kls Exp $
+ * $Id: device.c 3.3 2013/08/22 10:28:55 kls Exp $
  */
 
 #include "device.h"
@@ -118,6 +118,8 @@ cDevice::~cDevice()
   DetachAllReceivers();
   delete liveSubtitle;
   delete dvbSubtitleConverter;
+  if (this == primaryDevice)
+     primaryDevice = NULL;
 }
 
 bool cDevice::WaitForAllDevicesReady(int Timeout)
@@ -362,7 +364,6 @@ void cDevice::SetCamSlot(cCamSlot *CamSlot)
 void cDevice::Shutdown(void)
 {
   deviceHooks.Clear();
-  primaryDevice = NULL;
   for (int i = 0; i < numDevices; i++) {
       delete device[i];
       device[i] = NULL;
@@ -665,6 +666,11 @@ int cDevice::NumProvidedSystems(void) const
   return 0;
 }
 
+const cPositioner *cDevice::Positioner(void) const
+{
+  return NULL;
+}
+
 int cDevice::SignalStrength(void) const
 {
   return -1;
diff --git a/device.h b/device.h
index fd010d4..d4d50d4 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: device.h 2.47 2013/02/16 15:20:01 kls Exp $
+ * $Id: device.h 3.2 2013/08/22 11:57:34 kls Exp $
  */
 
 #ifndef __DEVICE_H
@@ -17,6 +17,7 @@
 #include "filter.h"
 #include "nit.h"
 #include "pat.h"
+#include "positioner.h"
 #include "remux.h"
 #include "ringbuffer.h"
 #include "sdt.h"
@@ -196,7 +197,7 @@ protected:
          ///< A derived class must call the MakePrimaryDevice() function of its
          ///< base class.
 public:
-  bool IsPrimaryDevice(void) const { return this == primaryDevice; }
+  bool IsPrimaryDevice(void) const { return this == primaryDevice && HasDecoder(); }
   int CardIndex(void) const { return cardIndex; }
          ///< Returns the card index of this device (0 ... MAXDEVICES - 1).
   int DeviceNumber(void) const;
@@ -273,6 +274,11 @@ public:
          ///< actually provide channels must implement this function.
          ///< The result of this function is used when selecting a device, in order
          ///< to avoid devices that provide more than one system.
+  virtual const cPositioner *Positioner(void) const;
+         ///< Returns a pointer to the positioner (if any) this device has used to
+         ///< move the satellite dish to the requested position (only applies to DVB-S
+         ///< devices). If no positioner is involved, or this is not a DVB-S device,
+         ///< NULL will be returned.
   virtual int SignalStrength(void) const;
          ///< Returns the "strength" of the currently received signal.
          ///< This is a value in the range 0 (no signal at all) through
diff --git a/diseqc.c b/diseqc.c
index 97da936..86ee61f 100644
--- a/diseqc.c
+++ b/diseqc.c
@@ -4,24 +4,37 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: diseqc.c 2.9.1.1 2013/05/02 09:33:12 kls Exp $
+ * $Id: diseqc.c 3.2 2013/08/21 09:26:11 kls Exp $
  */
 
 #include "diseqc.h"
 #include <ctype.h>
+#include <linux/dvb/frontend.h>
+#include <sys/ioctl.h>
 #include "sources.h"
 #include "thread.h"
 
-static bool ParseDeviceNumbers(const char *s, int &Devices)
+#define ALL_DEVICES (~0) // all bits set to '1'
+#define MAX_DEVICES 32   // each bit in a 32-bit integer represents one device
+
+static int CurrentDevices = 0;
+
+static bool IsDeviceNumbers(const char *s)
+{
+  return *s && s[strlen(s) - 1] == ':';
+}
+
+static bool ParseDeviceNumbers(const char *s)
 {
-  if (*s && s[strlen(s) - 1] == ':') {
+  if (IsDeviceNumbers(s)) {
+     CurrentDevices = 0;
      const char *p = s;
      while (*p && *p != ':') {
            char *t = NULL;
            int d = strtol(p, &t, 10);
            p = t;
-           if (0 < d && d < 31)
-              Devices |= (1 << d - 1);
+           if (0 < d && d <= MAX_DEVICES)
+              CurrentDevices |= (1 << d - 1);
            else {
               esyslog("ERROR: invalid device number %d in '%s'", d, s);
               return false;
@@ -31,6 +44,107 @@ static bool ParseDeviceNumbers(const char *s, int &Devices)
   return true;
 }
 
+// --- cDiseqcPositioner -----------------------------------------------------
+
+// See http://www.eutelsat.com/files/live/sites/eutelsatv2/files/contributed/satellites/pdf/Diseqc/associated%20docs/positioner_appli_notice.pdf
+
+cDiseqcPositioner::cDiseqcPositioner(void)
+{
+  SetCapabilities(pcCanDrive |
+                  pcCanStep |
+                  pcCanHalt |
+                  pcCanSetLimits |
+                  pcCanDisableLimits |
+                  pcCanEnableLimits |
+                  pcCanStorePosition |
+                  pcCanRecalcPositions |
+                  pcCanGotoPosition |
+                  pcCanGotoAngle
+                  );
+}
+
+void cDiseqcPositioner::SendDiseqc(uint8_t *Codes, int NumCodes)
+{
+  struct dvb_diseqc_master_cmd cmd;
+  NumCodes = min(NumCodes, int(sizeof(cmd.msg) - 2));
+  cmd.msg_len = 0;
+  cmd.msg[cmd.msg_len++] = 0xE0;
+  cmd.msg[cmd.msg_len++] = 0x31;
+  for (int i = 0; i < NumCodes; i++)
+      cmd.msg[cmd.msg_len++] = Codes[i];
+  CHECK(ioctl(Frontend(), FE_DISEQC_SEND_MASTER_CMD, &cmd));
+}
+
+void cDiseqcPositioner::Drive(ePositionerDirection Direction)
+{
+  uint8_t Code[] = { uint8_t(Direction == pdLeft ? 0x68 : 0x69), 0x00 };
+  SendDiseqc(Code, 2);
+}
+
+void cDiseqcPositioner::Step(ePositionerDirection Direction, uint Steps)
+{
+  if (Steps == 0)
+     return;
+  uint8_t Code[] = { uint8_t(Direction == pdLeft ? 0x68 : 0x69), 0xFF };
+  Code[1] -= min(Steps, uint(0x7F)) - 1;
+  SendDiseqc(Code, 2);
+}
+
+void cDiseqcPositioner::Halt(void)
+{
+  uint8_t Code[] = { 0x60 };
+  SendDiseqc(Code, 1);
+}
+
+void cDiseqcPositioner::SetLimit(ePositionerDirection Direction)
+{
+  uint8_t Code[] = { uint8_t(Direction == pdLeft ? 0x66 : 0x67) };
+  SendDiseqc(Code, 1);
+}
+
+void cDiseqcPositioner::DisableLimits(void)
+{
+  uint8_t Code[] = { 0x63 };
+  SendDiseqc(Code, 1);
+}
+
+void cDiseqcPositioner::EnableLimits(void)
+{
+  uint8_t Code[] = { 0x6A, 0x00 };
+  SendDiseqc(Code, 2);
+}
+
+void cDiseqcPositioner::StorePosition(uint Number)
+{
+  uint8_t Code[] = { 0x6A, uint8_t(Number) };
+  SendDiseqc(Code, 2);
+}
+
+void cDiseqcPositioner::RecalcPositions(uint Number)
+{
+  uint8_t Code[] = { 0x6F, uint8_t(Number), 0x00, 0x00 };
+  SendDiseqc(Code, 4);
+}
+
+void cDiseqcPositioner::GotoPosition(uint Number, int Longitude)
+{
+  uint8_t Code[] = { 0x6B, uint8_t(Number) };
+  SendDiseqc(Code, 2);
+  cPositioner::GotoPosition(Number, Longitude);
+}
+
+void cDiseqcPositioner::GotoAngle(int Longitude)
+{
+  uint8_t Code[] = { 0x6E, 0x00, 0x00 };
+  int Angle = CalcHourAngle(Longitude);
+  int a = abs(Angle);
+  Code[1] = a / 10 / 16;
+  Code[2] = a / 10 % 16 * 16 + a % 10 * 16 / 10;
+  Code[1] |= (Angle < 0) ? 0xE0 : 0xD0;
+  SendDiseqc(Code, 3);
+  cPositioner::GotoAngle(Longitude);
+}
+
 // --- cScr ------------------------------------------------------------------
 
 cScr::cScr(void)
@@ -44,10 +158,9 @@ cScr::cScr(void)
 
 bool cScr::Parse(const char *s)
 {
-  if (!ParseDeviceNumbers(s, devices))
-     return false;
-  if (devices)
-     return true;
+  if (IsDeviceNumbers(s))
+     return ParseDeviceNumbers(s);
+  devices = CurrentDevices;
   bool result = false;
   int fields = sscanf(s, "%d %u %d", &channel, &userBand, &pin);
   if (fields == 2 || fields == 3) {
@@ -68,16 +181,17 @@ bool cScr::Parse(const char *s)
 
 cScrs Scrs;
 
+bool cScrs::Load(const char *FileName, bool AllowComments, bool MustExist)
+{
+  CurrentDevices = ALL_DEVICES;
+  return cConfig<cScr>::Load(FileName, AllowComments, MustExist);
+}
+
 cScr *cScrs::GetUnused(int Device)
 {
   cMutexLock MutexLock(&mutex);
-  int Devices = 0;
   for (cScr *p = First(); p; p = Next(p)) {
-      if (p->Devices()) {
-         Devices = p->Devices();
-         continue;
-         }
-      if (Devices && !(Devices & (1 << Device - 1)))
+      if (!IsBitSet(p->Devices(), Device - 1))
          continue;
       if (!p->Used()) {
         p->SetUsed(true);
@@ -96,6 +210,7 @@ cDiseqc::cDiseqc(void)
   slof = 0;
   polarization = 0;
   lof = 0;
+  position = -1;
   scrBank = -1;
   commands = NULL;
   parsing = false;
@@ -108,10 +223,9 @@ cDiseqc::~cDiseqc()
 
 bool cDiseqc::Parse(const char *s)
 {
-  if (!ParseDeviceNumbers(s, devices))
-     return false;
-  if (devices)
-     return true;
+  if (IsDeviceNumbers(s))
+     return ParseDeviceNumbers(s);
+  devices = CurrentDevices;
   bool result = false;
   char *sourcebuf = NULL;
   int fields = sscanf(s, "%a[^ ] %d %c %d %a[^\n]", &sourcebuf, &slof, &polarization, &lof, &commands);
@@ -178,6 +292,28 @@ const char *cDiseqc::Wait(const char *s) const
   return NULL;
 }
 
+const char *cDiseqc::GetPosition(const char *s) const
+{
+  if (!*s || !isdigit(*s)) {
+     position = 0;
+     return s;
+     }
+  char *p = NULL;
+  errno = 0;
+  int n = strtol(s, &p, 10);
+  if (!errno && p != s && n >= 0 && n < 0xFF) {
+     if (parsing) {
+        if (position < 0)
+           position = n;
+        else
+           esyslog("ERROR: more than one position in '%s'", s - 1);
+        }
+     return p;
+     }
+  esyslog("ERROR: invalid satellite position in '%s'", s - 1);
+  return NULL;
+}
+
 const char *cDiseqc::GetScrBank(const char *s) const
 {
   char *p = NULL;
@@ -250,8 +386,12 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Code
           case 'V': return daVoltage18;
           case 'A': return daMiniA;
           case 'B': return daMiniB;
-          case 'W': *CurrentAction = Wait(*CurrentAction); break;
-          case 'S': *CurrentAction = GetScrBank(*CurrentAction); break;
+          case 'W': *CurrentAction = Wait(*CurrentAction); return daWait;
+          case 'P': *CurrentAction = GetPosition(*CurrentAction);
+                    if (Setup.UsePositioner)
+                       return position ? daPositionN : daPositionA;
+                    break;
+          case 'S': *CurrentAction = GetScrBank(*CurrentAction); return daScr;
           case '[': *CurrentAction = GetCodes(*CurrentAction, Codes, MaxCodes);
                     if (*CurrentAction) {
                        if (Scr && Frequency) {
@@ -261,7 +401,8 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Code
                        return daCodes;
                        }
                     break;
-          default: return daNone;
+          default:  esyslog("ERROR: unknown diseqc code '%c'", *(*CurrentAction - 1));
+                    return daNone;
           }
         }
   return daNone;
@@ -271,17 +412,18 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Code
 
 cDiseqcs Diseqcs;
 
+bool cDiseqcs::Load(const char *FileName, bool AllowComments, bool MustExist)
+{
+  CurrentDevices = ALL_DEVICES;
+  return cConfig<cDiseqc>::Load(FileName, AllowComments, MustExist);
+}
+
 const cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polarization, const cScr **Scr) const
 {
-  int Devices = 0;
   for (const cDiseqc *p = First(); p; p = Next(p)) {
-      if (p->Devices()) {
-         Devices = p->Devices();
-         continue;
-         }
-      if (Devices && !(Devices & (1 << Device - 1)))
+      if (!IsBitSet(p->Devices(), Device - 1))
          continue;
-      if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) {
+      if (cSource::Matches(p->Source(), Source) && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) {
          if (p->IsScr() && Scr && !*Scr) {
             *Scr = Scrs.GetUnused(Device);
             if (*Scr)
diff --git a/diseqc.conf b/diseqc.conf
index 2895c43..4ae1cfe 100644
--- a/diseqc.conf
+++ b/diseqc.conf
@@ -5,6 +5,9 @@
 # satellite slof polarization lof command...
 #
 # satellite:      one of the 'S' codes defined in sources.conf
+#                 the special value 'S360E' means that this entry uses a positioner
+#                 (command 'P') that can move the dish to any requested satellite
+#                 position withing its range
 # slof:           switch frequency of LNB; the first entry with
 #                 an slof greater than the actual transponder
 #                 frequency will be used
@@ -18,7 +21,9 @@
 #   V         voltage high (18V)
 #   A         mini A
 #   B         mini B
-#   Sn        Satellite channel routing code sequence for bank n follows
+#   Pn        use positioner to move dish to satellite position n (or to the
+#             satellite's orbital position, if no position number is given)
+#   Sn        satellite channel routing code sequence for bank n follows
 #   Wnn       wait nn milliseconds (nn may be any positive integer number)
 #   [xx ...]  hex code sequence (max. 6)
 #
@@ -88,3 +93,10 @@ S13.0E  99999 H 10600  t V W15 [E0 10 38 F7] W15 B W15 T
 # S13.0E  99999 V 10600  t V W10 S5 [E0 10 5A 00 00] W10 v
 # S13.0E  11700 H  9750  t V W10 S6 [E0 10 5A 00 00] W10 v
 # S13.0E  99999 H 10600  t V W10 S7 [E0 10 5A 00 00] W10 v
+#
+# Positioner for steerable dish:
+#
+# S360E  11700 V  9750  t V W20 P W20 t v
+# S360E  99999 V 10600  t V W20 P W20 T v
+# S360E  11700 H  9750  t V W20 P W20 t V
+# S360E  99999 H 10600  t V W20 P W20 T V
diff --git a/diseqc.h b/diseqc.h
index 6e9058c..eef36a6 100644
--- a/diseqc.h
+++ b/diseqc.h
@@ -4,15 +4,33 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: diseqc.h 2.5 2011/09/17 13:15:17 kls Exp $
+ * $Id: diseqc.h 3.1 2013/06/12 11:52:17 kls Exp $
  */
 
 #ifndef __DISEQC_H
 #define __DISEQC_H
 
 #include "config.h"
+#include "positioner.h"
 #include "thread.h"
 
+class cDiseqcPositioner : public cPositioner {
+private:
+  void SendDiseqc(uint8_t *Codes, int NumCodes);
+public:
+  cDiseqcPositioner(void);
+  virtual void Drive(ePositionerDirection Direction);
+  virtual void Step(ePositionerDirection Direction, uint Steps = 1);
+  virtual void Halt(void);
+  virtual void SetLimit(ePositionerDirection Direction);
+  virtual void DisableLimits(void);
+  virtual void EnableLimits(void);
+  virtual void StorePosition(uint Number);
+  virtual void RecalcPositions(uint Number);
+  virtual void GotoPosition(uint Number, int Longitude);
+  virtual void GotoAngle(int Longitude);
+  };
+
 class cScr : public cListObject {
 private:
   int devices;
@@ -35,6 +53,7 @@ class cScrs : public cConfig<cScr> {
 private:
   cMutex mutex;
 public:
+  bool Load(const char *FileName, bool AllowComments = false, bool MustExist = false);
   cScr *GetUnused(int Device);
   };
 
@@ -50,8 +69,11 @@ public:
     daVoltage18,
     daMiniA,
     daMiniB,
+    daPositionN,
+    daPositionA,
     daScr,
     daCodes,
+    daWait,
     };
   enum { MaxDiseqcCodes = 6 };
 private:
@@ -60,12 +82,14 @@ private:
   int slof;
   char polarization;
   int lof;
+  mutable int position;
   mutable int scrBank;
   char *commands;
   bool parsing;
   uint SetScrFrequency(uint SatFrequency, const cScr *Scr, uint8_t *Codes) const;
   int SetScrPin(const cScr *Scr, uint8_t *Codes) const;
   const char *Wait(const char *s) const;
+  const char *GetPosition(const char *s) const;
   const char *GetScrBank(const char *s) const;
   const char *GetCodes(const char *s, uchar *Codes = NULL, uint8_t *MaxCodes = NULL) const;
 public:
@@ -89,16 +113,31 @@ public:
       ///< Frequency must be the frequency the tuner will be tuned to, and will be
       ///< set to the proper SCR frequency upon return (if SCR is used).
   int Devices(void) const { return devices; }
+      ///< Returns an integer where each bit represents one of the system's devices.
+      ///< If a bit is set, this DiSEqC sequence applies to the corresponding device.
   int Source(void) const { return source; }
+      ///< Returns the satellite source this DiSEqC sequence applies to.
   int Slof(void) const { return slof; }
+      ///< Returns the switch frequency of the LNB this DiSEqC sequence applies to.
   char Polarization(void) const { return polarization; }
+      ///< Returns the signal polarization this DiSEqC sequence applies to.
   int Lof(void) const { return lof; }
-  bool IsScr() const { return scrBank >= 0; }
+      ///< Returns the local oscillator frequency of the LNB this DiSEqC sequence applies to.
+  int Position(void) const { return position; }
+      ///< Indicates which positioning mode to use in order to move the dish to a given
+      ///< satellite position. -1 means "no positioning" (i.e. fixed dish); 0 means the
+      ///< positioner can be moved to any arbitrary satellite position (within its
+      ///< limits); and a positive number means "move the dish to the position stored
+      ///< under the given number".
+  bool IsScr(void) const { return scrBank >= 0; }
+      ///< Returns true if this DiSEqC sequence uses Satellite Channel Routing.
   const char *Commands(void) const { return commands; }
+      ///< Returns a pointer to the actual commands of this DiSEqC sequence.
   };
 
 class cDiseqcs : public cConfig<cDiseqc> {
 public:
+  bool Load(const char *FileName, bool AllowComments = false, bool MustExist = false);
   const cDiseqc *Get(int Device, int Source, int Frequency, char Polarization, const cScr **Scr) const;
       ///< Selects a DiSEqC entry suitable for the given Device and tuning parameters.
       ///< If this DiSEqC entry requires SCR and the given *Scr is NULL
diff --git a/dvbci.c b/dvbci.c
index 5289bbd..38668a6 100644
--- a/dvbci.c
+++ b/dvbci.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbci.c 2.0 2007/01/04 12:49:10 kls Exp $
+ * $Id: dvbci.c 3.0 2007/01/04 12:49:10 kls Exp $
  */
 
 #include "dvbci.h"
diff --git a/dvbci.h b/dvbci.h
index adbe40d..f74703c 100644
--- a/dvbci.h
+++ b/dvbci.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbci.h 2.0 2006/11/26 11:19:42 kls Exp $
+ * $Id: dvbci.h 3.0 2006/11/26 11:19:42 kls Exp $
  */
 
 #ifndef __DVBCI_H
diff --git a/dvbdevice.c b/dvbdevice.c
index 2e19925..c61fb17 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.c 2.88.1.1 2013/04/09 13:42:26 kls Exp $
+ * $Id: dvbdevice.c 3.3 2013/08/23 09:19:43 kls Exp $
  */
 
 #include "dvbdevice.h"
@@ -284,7 +284,7 @@ bool cDvbTransponderParameters::Parse(const char *s)
 class cDvbTuner : public cThread {
 private:
   static cMutex bondMutex;
-  enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
+  enum eTunerStatus { tsIdle, tsSet, tsPositioning, tsTuned, tsLocked };
   int frontendType;
   const cDvbDevice *device;
   int fd_frontend;
@@ -295,6 +295,9 @@ private:
   time_t lastTimeoutReport;
   cChannel channel;
   const cDiseqc *lastDiseqc;
+  int diseqcOffset;
+  int lastSource;
+  cPositioner *positioner;
   const cScr *scr;
   bool lnbPowerTurnedOn;
   eTunerStatus tunerStatus;
@@ -309,6 +312,7 @@ private:
   bool IsBondedMaster(void) const { return !bondedTuner || bondedMaster; }
   void ClearEventQueue(void) const;
   bool GetFrontendStatus(fe_status_t &Status) const;
+  cPositioner *GetPositioner(void);
   void ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency);
   void ResetToneAndVoltage(void);
   bool SetFrontend(void);
@@ -325,6 +329,7 @@ public:
   bool IsTunedTo(const cChannel *Channel) const;
   void SetChannel(const cChannel *Channel);
   bool Locked(int TimeoutMs = 0);
+  const cPositioner *Positioner(void) const { return positioner; }
   int GetSignalStrength(void) const;
   int GetSignalQuality(void) const;
   };
@@ -343,6 +348,9 @@ cDvbTuner::cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int
   lockTimeout = 0;
   lastTimeoutReport = 0;
   lastDiseqc = NULL;
+  diseqcOffset = 0;
+  lastSource = 0;
+  positioner = NULL;
   scr = NULL;
   lnbPowerTurnedOn = false;
   tunerStatus = tsIdle;
@@ -482,6 +490,7 @@ void cDvbTuner::SetChannel(const cChannel *Channel)
      cMutexLock MutexLock(&mutex);
      if (!IsTunedTo(Channel))
         tunerStatus = tsSet;
+     diseqcOffset = 0;
      channel = *Channel;
      lastTimeoutReport = 0;
      newSet.Broadcast();
@@ -662,6 +671,15 @@ static unsigned int FrequencyToHz(unsigned int f)
   return f;
 }
 
+cPositioner *cDvbTuner::GetPositioner(void)
+{
+  if (!positioner) {
+     positioner = cPositioner::GetPositioner();
+     positioner->SetFrontend(fd_frontend);
+     }
+  return positioner;
+}
+
 void cDvbTuner::ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency)
 {
   if (!lnbPowerTurnedOn) {
@@ -673,23 +691,47 @@ void cDvbTuner::ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency)
      Mutex.Lock();
   struct dvb_diseqc_master_cmd cmd;
   const char *CurrentAction = NULL;
-  for (;;) {
+  cPositioner *Positioner = NULL;
+  bool Break = false;
+  for (int i = 0; !Break; i++) {
       cmd.msg_len = sizeof(cmd.msg);
       cDiseqc::eDiseqcActions da = Diseqc->Execute(&CurrentAction, cmd.msg, &cmd.msg_len, scr, Frequency);
-      if (da == cDiseqc::daNone)
+      if (da == cDiseqc::daNone) {
+         diseqcOffset = 0;
          break;
+         }
+      bool d = i >= diseqcOffset;
       switch (da) {
-        case cDiseqc::daToneOff:   CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
-        case cDiseqc::daToneOn:    CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
-        case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
-        case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
-        case cDiseqc::daMiniA:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
-        case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
-        case cDiseqc::daCodes:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break;
+        case cDiseqc::daToneOff:   if (d) CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
+        case cDiseqc::daToneOn:    if (d) CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
+        case cDiseqc::daVoltage13: if (d) CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
+        case cDiseqc::daVoltage18: if (d) CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
+        case cDiseqc::daMiniA:     if (d) CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
+        case cDiseqc::daMiniB:     if (d) CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+        case cDiseqc::daCodes:     if (d) CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break;
+        case cDiseqc::daPositionN: if ((Positioner = GetPositioner()) != NULL) {
+                                      if (d) {
+                                         Positioner->GotoPosition(Diseqc->Position(), cSource::Position(channel.Source()));
+                                         Break = Positioner->IsMoving();
+                                         }
+                                      }
+                                   break;
+        case cDiseqc::daPositionA: if ((Positioner = GetPositioner()) != NULL) {
+                                      if (d) {
+                                         Positioner->GotoAngle(cSource::Position(channel.Source()));
+                                         Break = Positioner->IsMoving();
+                                         }
+                                      }
+                                   break;
+        case cDiseqc::daScr:
+        case cDiseqc::daWait:      break;
         default: esyslog("ERROR: unknown diseqc command %d", da);
         }
+      if (Break)
+         diseqcOffset = i + 1;
       }
-  if (scr)
+  positioner = Positioner;
+  if (scr && !Break)
      ResetToneAndVoltage(); // makes sure we don't block the bus!
   if (Diseqc->IsScr())
      Mutex.Unlock();
@@ -697,7 +739,7 @@ void cDvbTuner::ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency)
 
 void cDvbTuner::ResetToneAndVoltage(void)
 {
-  CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13));
+  CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, bondedTuner ? SEC_VOLTAGE_OFF : SEC_VOLTAGE_13));
   CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF));
 }
 
@@ -752,7 +794,7 @@ bool cDvbTuner::SetFrontend(void)
      if (Setup.DiSEqC) {
         if (const cDiseqc *diseqc = Diseqcs.Get(device->CardIndex() + 1, channel.Source(), frequency, dtp.Polarization(), &scr)) {
            frequency -= diseqc->Lof();
-           if (diseqc != lastDiseqc || diseqc->IsScr()) {
+           if (diseqc != lastDiseqc || diseqc->IsScr() || diseqc->Position() >= 0 && channel.Source() != lastSource) {
               if (IsBondedMaster()) {
                  ExecuteDiseqc(diseqc, &frequency);
                  if (frequency == 0)
@@ -761,6 +803,7 @@ bool cDvbTuner::SetFrontend(void)
               else
                  ResetToneAndVoltage();
               lastDiseqc = diseqc;
+              lastSource = channel.Source();
               }
            }
         else {
@@ -877,15 +920,30 @@ void cDvbTuner::Action(void)
         int WaitTime = 1000;
         switch (tunerStatus) {
           case tsIdle:
-               break;
+               break; // we want the TimedWait() below!
           case tsSet:
-               tunerStatus = SetFrontend() ? tsTuned : tsIdle;
-               Timer.Set(tuneTimeout + (scr ? rand() % SCR_RANDOM_TIMEOUT : 0));
+               tunerStatus = SetFrontend() ? tsPositioning : tsIdle;
                continue;
+          case tsPositioning:
+               if (positioner) {
+                  if (positioner->IsMoving())
+                     break; // we want the TimedWait() below!
+                  else if (diseqcOffset) {
+                     lastDiseqc = NULL;
+                     tunerStatus = tsSet; // have it process the rest of the DiSEqC sequence
+                     continue;
+                     }
+                  }
+               tunerStatus = tsTuned;
+               Timer.Set(tuneTimeout + (scr ? rand() % SCR_RANDOM_TIMEOUT : 0));
+               if (positioner)
+                  continue;
+               // otherwise run directly into tsTuned...
           case tsTuned:
                if (Timer.TimedOut()) {
                   tunerStatus = tsSet;
                   lastDiseqc = NULL;
+                  lastSource = 0;
                   if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these
                      isyslog("frontend %d/%d timed out while tuning to channel %d, tp %d", adapter, frontend, channel.Number(), channel.Transponder());
                      lastTimeoutReport = time(NULL);
@@ -893,10 +951,12 @@ void cDvbTuner::Action(void)
                   continue;
                   }
                WaitTime = 100; // allows for a quick change from tsTuned to tsLocked
+               // run into tsLocked...
           case tsLocked:
                if (Status & FE_REINIT) {
                   tunerStatus = tsSet;
                   lastDiseqc = NULL;
+                  lastSource = 0;
                   isyslog("frontend %d/%d was reinitialized", adapter, frontend);
                   lastTimeoutReport = 0;
                   continue;
@@ -1357,7 +1417,7 @@ void cDvbDevice::UnBond(void)
 bool cDvbDevice::BondingOk(const cChannel *Channel, bool ConsiderOccupied) const
 {
   cMutexLock MutexLock(&bondMutex);
-  if (bondedDevice)
+  if (bondedDevice || Positioner())
      return dvbTuner && dvbTuner->BondingOk(Channel, ConsiderOccupied);
   return true;
 }
@@ -1539,6 +1599,11 @@ int cDvbDevice::NumProvidedSystems(void) const
   return numDeliverySystems + numModulations;
 }
 
+const cPositioner *cDvbDevice::Positioner(void) const
+{
+  return dvbTuner ? dvbTuner->Positioner() : NULL;
+}
+
 int cDvbDevice::SignalStrength(void) const
 {
   return dvbTuner ? dvbTuner->GetSignalStrength() : -1;
diff --git a/dvbdevice.h b/dvbdevice.h
index 76b8665..7a54d8c 100644
--- a/dvbdevice.h
+++ b/dvbdevice.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbdevice.h 2.29.1.1 2013/04/09 13:43:33 kls Exp $
+ * $Id: dvbdevice.h 3.2 2013/06/01 11:36:18 kls Exp $
  */
 
 #ifndef __DVBDEVICE_H
@@ -233,6 +233,7 @@ public:
   virtual bool ProvidesChannel(const cChannel *Channel, int Priority = IDLEPRIORITY, bool *NeedsDetachReceivers = NULL) const;
   virtual bool ProvidesEIT(void) const;
   virtual int NumProvidedSystems(void) const;
+  virtual const cPositioner *Positioner(void) const;
   virtual int SignalStrength(void) const;
   virtual int SignalQuality(void) const;
   virtual const cChannel *GetCurrentlyTunedTransponder(void) const;
diff --git a/dvbplayer.c b/dvbplayer.c
index dc206a3..316ea94 100644
--- a/dvbplayer.c
+++ b/dvbplayer.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbplayer.c 2.35 2013/03/08 13:44:19 kls Exp $
+ * $Id: dvbplayer.c 3.0 2013/03/08 13:44:19 kls Exp $
  */
 
 #include "dvbplayer.h"
diff --git a/dvbplayer.h b/dvbplayer.h
index e2f2082..7c75951 100644
--- a/dvbplayer.h
+++ b/dvbplayer.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: dvbplayer.h 2.1 2012/02/19 11:40:36 kls Exp $
+ * $Id: dvbplayer.h 3.0 2012/02/19 11:40:36 kls Exp $
  */
 
 #ifndef __DVBPLAYER_H
diff --git a/dvbspu.c b/dvbspu.c
index 6b3c216..da18d0a 100644
--- a/dvbspu.c
+++ b/dvbspu.c
@@ -8,7 +8,7 @@
  *
  * parts of this file are derived from the OMS program.
  *
- * $Id: dvbspu.c 2.11 2013/02/22 15:25:16 kls Exp $
+ * $Id: dvbspu.c 3.0 2013/02/22 15:25:16 kls Exp $
  */
 
 #include "dvbspu.h"
diff --git a/dvbspu.h b/dvbspu.h
index 5c7cc0a..9fa3947 100644
--- a/dvbspu.h
+++ b/dvbspu.h
@@ -8,7 +8,7 @@
  *
  * parts of this file are derived from the OMS program.
  *
- * $Id: dvbspu.h 2.6 2013/01/20 10:15:47 kls Exp $
+ * $Id: dvbspu.h 3.0 2013/01/20 10:15:47 kls Exp $
  */
 
 #ifndef __DVBSPU_H
diff --git a/dvbsubtitle.c b/dvbsubtitle.c
index 9facc86..89abc70 100644
--- a/dvbsubtitle.c
+++ b/dvbsubtitle.c
@@ -7,7 +7,7 @@
  * Original author: Marco Schluessler <marco at lordzodiac.de>
  * With some input from the "subtitle plugin" by Pekka Virtanen <pekka.virtanen at sci.fi>
  *
- * $Id: dvbsubtitle.c 2.34 2013/02/22 15:25:25 kls Exp $
+ * $Id: dvbsubtitle.c 3.0 2013/02/22 15:25:25 kls Exp $
  */
 
 #include "dvbsubtitle.h"
diff --git a/dvbsubtitle.h b/dvbsubtitle.h
index 8de9f63..79b1d06 100644
--- a/dvbsubtitle.h
+++ b/dvbsubtitle.h
@@ -6,7 +6,7 @@
  *
  * Original author: Marco Schluessler <marco at lordzodiac.de>
  *
- * $Id: dvbsubtitle.h 2.7 2012/03/11 13:34:12 kls Exp $
+ * $Id: dvbsubtitle.h 3.0 2012/03/11 13:34:12 kls Exp $
  */
 
 #ifndef __DVBSUBTITLE_H
diff --git a/eit.c b/eit.c
index 73c4fa9..a3cf341 100644
--- a/eit.c
+++ b/eit.c
@@ -8,7 +8,7 @@
  * Robert Schneider <Robert.Schneider at web.de> and Rolf Hakenes <hakenes at hippomi.de>.
  * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg at gmx.de>.
  *
- * $Id: eit.c 2.23 2012/12/04 11:10:10 kls Exp $
+ * $Id: eit.c 3.1 2013/08/23 10:52:27 kls Exp $
  */
 
 #include "eit.h"
@@ -46,6 +46,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
      return;
      }
 
+  EpgHandlers.BeginSegmentTransfer(channel, OnlyRunningStatus);
   bool handledExternally = EpgHandlers.HandledExternally(channel);
   cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channel, true);
 
@@ -310,6 +311,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
      Schedules->SetModified(pSchedule);
      }
   Channels.Unlock();
+  EpgHandlers.EndSegmentTransfer(Modified, OnlyRunningStatus);
 }
 
 // --- cTDT ------------------------------------------------------------------
diff --git a/eit.h b/eit.h
index b552372..ec30253 100644
--- a/eit.h
+++ b/eit.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: eit.h 2.1 2010/01/03 15:28:34 kls Exp $
+ * $Id: eit.h 3.0 2010/01/03 15:28:34 kls Exp $
  */
 
 #ifndef __EIT_H
diff --git a/eitscan.c b/eitscan.c
index 027bf44..77f15c6 100644
--- a/eitscan.c
+++ b/eitscan.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: eitscan.c 2.7 2012/04/07 14:39:28 kls Exp $
+ * $Id: eitscan.c 3.0 2012/04/07 14:39:28 kls Exp $
  */
 
 #include "eitscan.h"
diff --git a/eitscan.h b/eitscan.h
index 2dd24d7..25658b6 100644
--- a/eitscan.h
+++ b/eitscan.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: eitscan.h 2.1 2012/03/07 13:54:16 kls Exp $
+ * $Id: eitscan.h 3.0 2012/03/07 13:54:16 kls Exp $
  */
 
 #ifndef __EITSCAN_H
diff --git a/epg.c b/epg.c
index 5fb49ae..e16f978 100644
--- a/epg.c
+++ b/epg.c
@@ -7,7 +7,7 @@
  * Original version (as used in VDR before 1.3.0) written by
  * Robert Schneider <Robert.Schneider at web.de> and Rolf Hakenes <hakenes at hippomi.de>.
  *
- * $Id: epg.c 2.23 2013/02/17 14:12:07 kls Exp $
+ * $Id: epg.c 3.1 2013/08/23 10:46:33 kls Exp $
  */
 
 #include "epg.h"
@@ -1537,3 +1537,19 @@ void cEpgHandlers::DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t
       }
   Schedule->DropOutdated(SegmentStart, SegmentEnd, TableID, Version);
 }
+
+void cEpgHandlers::BeginSegmentTransfer(const cChannel *Channel, bool OnlyRunningStatus)
+{
+  for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+      if (eh->BeginSegmentTransfer(Channel, OnlyRunningStatus))
+         return;
+      }
+}
+
+void cEpgHandlers::EndSegmentTransfer(bool Modified, bool OnlyRunningStatus)
+{
+  for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+      if (eh->EndSegmentTransfer(Modified, OnlyRunningStatus))
+         return;
+      }
+}
diff --git a/epg.h b/epg.h
index 3a7df77..65fbcbf 100644
--- a/epg.h
+++ b/epg.h
@@ -7,7 +7,7 @@
  * Original version (as used in VDR before 1.3.0) written by
  * Robert Schneider <Robert.Schneider at web.de> and Rolf Hakenes <hakenes at hippomi.de>.
  *
- * $Id: epg.h 2.15 2012/09/24 12:53:53 kls Exp $
+ * $Id: epg.h 3.1 2013/08/23 10:50:05 kls Exp $
  */
 
 #ifndef __EPG_H
@@ -273,6 +273,12 @@ public:
   virtual bool DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version) { return false; }
           ///< Takes a look at all EPG events between SegmentStart and SegmentEnd and
           ///< drops outdated events.
+  virtual bool BeginSegmentTransfer(const cChannel *Channel, bool OnlyRunningStatus) { return false; }
+          ///< Called directly after IgnoreChannel() before any other handler method is called.
+          ///< Designed to give handlers the possibility to prepare a database transaction.
+  virtual bool EndSegmentTransfer(bool Modified, bool OnlyRunningStatus) { return false; }
+          ///< Called after the segment data has been processed.
+          ///< At this point handlers should close/commit/rollback any pending database transactions.
   };
 
 class cEpgHandlers : public cList<cEpgHandler> {
@@ -295,6 +301,8 @@ public:
   void HandleEvent(cEvent *Event);
   void SortSchedule(cSchedule *Schedule);
   void DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version);
+  void BeginSegmentTransfer(const cChannel *Channel, bool OnlyRunningStatus);
+  void EndSegmentTransfer(bool Modified, bool OnlyRunningStatus);
   };
 
 extern cEpgHandlers EpgHandlers;
diff --git a/epg2html b/epg2html
index 1b1a251..34f9521 100755
--- a/epg2html
+++ b/epg2html
@@ -12,7 +12,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: epg2html 2.2 2013/03/04 13:02:20 kls Exp $
+# $Id: epg2html 3.0 2013/03/04 13:02:20 kls Exp $
 
 @Index = ();
 ($Charset = $ENV{LANG}) =~ s/^[^.]*\.?(.*)/$1/;
diff --git a/filter.c b/filter.c
index 4de6785..72590f7 100644
--- a/filter.c
+++ b/filter.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: filter.c 2.0 2004/01/11 13:31:34 kls Exp $
+ * $Id: filter.c 3.0 2004/01/11 13:31:34 kls Exp $
  */
 
 #include "filter.h"
diff --git a/filter.h b/filter.h
index b85ab07..a00ece5 100644
--- a/filter.h
+++ b/filter.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: filter.h 2.0 2004/01/11 13:31:59 kls Exp $
+ * $Id: filter.h 3.0 2004/01/11 13:31:59 kls Exp $
  */
 
 #ifndef __FILTER_H
diff --git a/font.c b/font.c
index c6400d4..dee26c2 100644
--- a/font.c
+++ b/font.c
@@ -6,7 +6,7 @@
  *
  * BiDi support by Osama Alrawab <alrawab at hotmail.com> @2008 Tripoli-Libya.
  *
- * $Id: font.c 2.13.1.1 2013/04/07 14:54:15 kls Exp $
+ * $Id: font.c 3.1 2013/04/07 14:42:13 kls Exp $
  */
 
 #include "font.h"
diff --git a/font.h b/font.h
index 86bd8b3..8174ae9 100644
--- a/font.h
+++ b/font.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: font.h 2.7 2013/02/17 13:17:42 kls Exp $
+ * $Id: font.h 3.0 2013/02/17 13:17:42 kls Exp $
  */
 
 #ifndef __FONT_H
diff --git a/i18n.c b/i18n.c
index f010b6b..f26c96b 100644
--- a/i18n.c
+++ b/i18n.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: i18n.c 2.5 2012/09/01 10:53:43 kls Exp $
+ * $Id: i18n.c 3.0 2012/09/01 10:53:43 kls Exp $
  */
 
 /*
diff --git a/i18n.h b/i18n.h
index 03deb6f..c3f1fc7 100644
--- a/i18n.h
+++ b/i18n.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: i18n.h 2.1 2012/03/11 14:07:45 kls Exp $
+ * $Id: i18n.h 3.0 2012/03/11 14:07:45 kls Exp $
  */
 
 #ifndef __I18N_H
diff --git a/interface.c b/interface.c
index 82091d9..992c5e3 100644
--- a/interface.c
+++ b/interface.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: interface.c 2.2 2012/11/19 12:21:43 kls Exp $
+ * $Id: interface.c 3.0 2012/11/19 12:21:43 kls Exp $
  */
 
 #include "interface.h"
diff --git a/interface.h b/interface.h
index 9e10f40..b9082bd 100644
--- a/interface.h
+++ b/interface.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: interface.h 2.0 2004/05/01 11:11:13 kls Exp $
+ * $Id: interface.h 3.0 2004/05/01 11:11:13 kls Exp $
  */
 
 #ifndef __INTERFACE_H
diff --git a/keys.c b/keys.c
index 2b4198d..284858c 100644
--- a/keys.c
+++ b/keys.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: keys.c 2.2 2012/12/04 12:52:52 kls Exp $
+ * $Id: keys.c 3.0 2012/12/04 12:52:52 kls Exp $
  */
 
 #include "keys.h"
diff --git a/keys.h b/keys.h
index 9a79dd6..4586548 100644
--- a/keys.h
+++ b/keys.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: keys.h 2.2 2012/12/04 12:51:25 kls Exp $
+ * $Id: keys.h 3.0 2012/12/04 12:51:25 kls Exp $
  */
 
 #ifndef __KEYS_H
diff --git a/libsi/Makefile b/libsi/Makefile
index dff5ca9..2219af6 100644
--- a/libsi/Makefile
+++ b/libsi/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for a libsi
 #
-# $Id: Makefile 2.4 2012/12/18 13:35:54 kls Exp $
+# $Id: Makefile 3.0 2012/12/18 13:35:54 kls Exp $
 
 ### The archiver options:
 
diff --git a/libsi/descriptor.c b/libsi/descriptor.c
index 07429b5..b680c35 100644
--- a/libsi/descriptor.c
+++ b/libsi/descriptor.c
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: descriptor.c 2.4 2012/01/11 11:35:17 kls Exp $
+ *   $Id: descriptor.c 3.0 2012/01/11 11:35:17 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
diff --git a/libsi/descriptor.h b/libsi/descriptor.h
index 3025876..0115c1d 100644
--- a/libsi/descriptor.h
+++ b/libsi/descriptor.h
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: descriptor.h 2.4 2012/01/11 11:35:17 kls Exp $
+ *   $Id: descriptor.h 3.0 2012/01/11 11:35:17 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
diff --git a/libsi/gendescr b/libsi/gendescr
index 8af5c69..b0628fb 100755
--- a/libsi/gendescr
+++ b/libsi/gendescr
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 
-# $Id: gendescr 2.0 2003/12/13 10:40:53 kls Exp $
+# $Id: gendescr 3.0 2003/12/13 10:40:53 kls Exp $
 
 print "Name (ohne ...Descriptor):";
 $name=<STDIN>;
diff --git a/libsi/headers.h b/libsi/headers.h
index 85c83b2..a15d92f 100644
--- a/libsi/headers.h
+++ b/libsi/headers.h
@@ -10,7 +10,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: headers.h 2.5 2012/06/09 14:37:24 kls Exp $
+ *   $Id: headers.h 3.0 2012/06/09 14:37:24 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
diff --git a/libsi/section.c b/libsi/section.c
index 8c86f46..d7a4292 100644
--- a/libsi/section.c
+++ b/libsi/section.c
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: section.c 2.0 2006/04/14 10:53:44 kls Exp $
+ *   $Id: section.c 3.0 2006/04/14 10:53:44 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
diff --git a/libsi/section.h b/libsi/section.h
index 5b70a22..133fba3 100644
--- a/libsi/section.h
+++ b/libsi/section.h
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: section.h 2.1 2012/02/26 13:58:26 kls Exp $
+ *   $Id: section.h 3.0 2012/02/26 13:58:26 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
diff --git a/libsi/si.c b/libsi/si.c
index 80d34d1..d7ed1d9 100644
--- a/libsi/si.c
+++ b/libsi/si.c
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: si.c 2.8 2012/09/29 14:44:20 kls Exp $
+ *   $Id: si.c 3.0 2012/09/29 14:44:20 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
diff --git a/libsi/si.h b/libsi/si.h
index 8e4255e..7155043 100644
--- a/libsi/si.h
+++ b/libsi/si.h
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: si.h 2.6 2012/10/15 11:56:06 kls Exp $
+ *   $Id: si.h 3.0 2012/10/15 11:56:06 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
diff --git a/libsi/util.c b/libsi/util.c
index 36a80d0..4da1917 100644
--- a/libsi/util.c
+++ b/libsi/util.c
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: util.c 2.0 2006/02/18 11:17:50 kls Exp $
+ *   $Id: util.c 3.0 2006/02/18 11:17:50 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
diff --git a/libsi/util.h b/libsi/util.h
index a7f5d60..019c4a8 100644
--- a/libsi/util.h
+++ b/libsi/util.h
@@ -6,7 +6,7 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
- *   $Id: util.h 2.3 2012/02/26 13:58:26 kls Exp $
+ *   $Id: util.h 3.0 2012/02/26 13:58:26 kls Exp $
  *                                                                         *
  ***************************************************************************/
 
diff --git a/lirc.c b/lirc.c
index e8d0be1..e02f229 100644
--- a/lirc.c
+++ b/lirc.c
@@ -6,7 +6,7 @@
  *
  * LIRC support added by Carsten Koch <Carsten.Koch at icem.de>  2000-06-16.
  *
- * $Id: lirc.c 2.5 2013/02/11 15:25:42 kls Exp $
+ * $Id: lirc.c 3.1 2013/08/22 09:22:14 kls Exp $
  */
 
 #include "lirc.h"
@@ -111,6 +111,7 @@ void cLircRemote::Action(void)
            else if (LastTime.Elapsed() < (uint)Setup.RcRepeatDelta)
               continue; // skip same keys coming in too fast
            else {
+              pressed = true;
               repeat = true;
               timeout = Delta * 10 / 9;
               }
diff --git a/lirc.h b/lirc.h
index fb6745f..070aa3d 100644
--- a/lirc.h
+++ b/lirc.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: lirc.h 2.0 2006/01/27 16:00:19 kls Exp $
+ * $Id: lirc.h 3.0 2006/01/27 16:00:19 kls Exp $
  */
 
 #ifndef __LIRC_H
diff --git a/menu.c b/menu.c
index f43dec5..e466ae0 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.c 2.82.1.2 2013/04/27 10:32:28 kls Exp $
+ * $Id: menu.c 3.3 2013/08/21 10:45:11 kls Exp $
  */
 
 #include "menu.h"
@@ -2971,6 +2971,14 @@ void cMenuSetupLNB::Setup(void)
          }
      }
 
+  Add(new cMenuEditBoolItem(tr("Setup.LNB$Use dish positioner"), &data.UsePositioner));
+  if (data.UsePositioner) {
+     Add(new cMenuEditIntxItem(tr("Setup.LNB$Site latitude (degrees)"), &data.SiteLat, -900, 900, 10, tr("South"), tr("North")));
+     Add(new cMenuEditIntxItem(tr("Setup.LNB$Site longitude (degrees)"), &data.SiteLon, -1800, 1800, 10, tr("West"), tr("East")));
+     Add(new cMenuEditIntxItem(tr("Setup.LNB$Max. positioner swing (degrees)"), &data.PositionerSwing, 0, 900, 10));
+     Add(new cMenuEditIntxItem(tr("Setup.LNB$Positioner speed (degrees/s)"), &data.PositionerSpeed, 1, 1800, 10));
+     }
+
   SetCurrent(Get(current));
   Display();
 }
@@ -2978,6 +2986,7 @@ void cMenuSetupLNB::Setup(void)
 eOSState cMenuSetupLNB::ProcessKey(eKeys Key)
 {
   int oldDiSEqC = data.DiSEqC;
+  int oldUsePositioner = data.UsePositioner;
   bool DeviceBondingsChanged = false;
   if (Key == kOk) {
      cString NewDeviceBondings = satCableNumbers.ToString();
@@ -2986,7 +2995,7 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys Key)
      }
   eOSState state = cMenuSetupBase::ProcessKey(Key);
 
-  if (Key != kNone && data.DiSEqC != oldDiSEqC)
+  if (Key != kNone && (data.DiSEqC != oldDiSEqC || data.UsePositioner != oldUsePositioner))
      Setup();
   else if (DeviceBondingsChanged)
      cDvbDevice::BondDevices(data.DeviceBondings);
@@ -3625,6 +3634,7 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched)
   displayChannel = Skins.Current()->DisplayChannel(withInfo);
   number = 0;
   timeout = Switched || Setup.TimeoutRequChInfo;
+  positioner = NULL;
   channel = Channels.GetByNumber(Number);
   lastPresent = lastFollowing = NULL;
   if (channel) {
@@ -3646,6 +3656,7 @@ cDisplayChannel::cDisplayChannel(eKeys FirstKey)
   lastTime.Set();
   withInfo = Setup.ShowInfoOnChSwitch;
   displayChannel = Skins.Current()->DisplayChannel(withInfo);
+  positioner = NULL;
   channel = Channels.GetByNumber(cDevice::CurrentChannel());
   ProcessKey(FirstKey);
 }
@@ -3853,7 +3864,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
             return osEnd;
             }
     };
-  if (!timeout || lastTime.Elapsed() < (uint64_t)(Setup.ChannelInfoTime * 1000)) {
+  if (positioner || !timeout || lastTime.Elapsed() < (uint64_t)(Setup.ChannelInfoTime * 1000)) {
      if (Key == kNone && !number && group < 0 && !NewChannel && channel && channel->Number() != cDevice::CurrentChannel()) {
         // makes sure a channel switch through the SVDRP CHAN command is displayed
         channel = Channels.GetByNumber(cDevice::CurrentChannel());
@@ -3861,13 +3872,24 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
         lastTime.Set();
         }
      DisplayInfo();
-     displayChannel->Flush();
      if (NewChannel) {
         SetTrackDescriptions(NewChannel->Number()); // to make them immediately visible in the channel display
         Channels.SwitchTo(NewChannel->Number());
         SetTrackDescriptions(NewChannel->Number()); // switching the channel has cleared them
         channel = NewChannel;
         }
+     const cPositioner *Positioner = cDevice::ActualDevice()->Positioner();
+     bool PositionerMoving = Positioner && Positioner->IsMoving();
+     SetNeedsFastResponse(PositionerMoving);
+     if (!PositionerMoving) {
+        if (positioner)
+           lastTime.Set(); // to keep the channel display up a few seconds after the target position has been reached
+        Positioner = NULL;
+        }
+     if (Positioner || positioner) // making sure we call SetPositioner(NULL) if there is a switch from "with" to "without" positioner
+        displayChannel->SetPositioner(Positioner);
+     positioner = Positioner;
+     displayChannel->Flush();
      return osContinue;
      }
   return osEnd;
diff --git a/menu.h b/menu.h
index 196c038..db17f98 100644
--- a/menu.h
+++ b/menu.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.h 2.13 2012/12/07 13:44:13 kls Exp $
+ * $Id: menu.h 3.1 2013/06/01 13:44:57 kls Exp $
  */
 
 #ifndef __MENU_H
@@ -120,6 +120,7 @@ private:
   cTimeMs lastTime;
   int number;
   bool timeout;
+  const cPositioner *positioner;
   cChannel *channel;
   const cEvent *lastPresent;
   const cEvent *lastFollowing;
diff --git a/menuitems.c b/menuitems.c
index f7ec776..4eea6ba 100644
--- a/menuitems.c
+++ b/menuitems.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menuitems.c 2.16 2013/02/15 14:20:29 kls Exp $
+ * $Id: menuitems.c 3.1 2013/05/24 10:26:01 kls Exp $
  */
 
 #include "menuitems.h"
@@ -51,14 +51,14 @@ void cMenuEditItem::SetHelp(const char *Red, const char *Green, const char *Yell
   helpDisplayed = false;
 }
 
-bool cMenuEditItem::DisplayHelp(void)
+bool cMenuEditItem::DisplayHelp(bool Current)
 {
   bool HasHelp = helpRed || helpGreen || helpYellow || helpBlue;
-  if (HasHelp && !helpDisplayed) {
+  if (HasHelp && !helpDisplayed && Current) {
      cSkinDisplay::Current()->SetButtons(helpRed, helpGreen, helpYellow, helpBlue);
      cStatus::MsgOsdHelpKeys(helpRed, helpGreen, helpYellow, helpBlue);
-     helpDisplayed = true;
      }
+  helpDisplayed = Current;
   return HasHelp;
 }
 
@@ -223,6 +223,50 @@ eOSState cMenuEditNumItem::ProcessKey(eKeys Key)
   return state;
 }
 
+// --- cMenuEditIntxItem -----------------------------------------------------
+
+cMenuEditIntxItem::cMenuEditIntxItem(const char *Name, int *Value, int Min, int Max, int Factor, const char *NegString, const char *PosString)
+:cMenuEditIntItem(Name, Value, Min, Max)
+{
+  factor = ::max(Factor, 1);
+  negString = NegString;
+  posString = PosString;
+  Set();
+}
+
+void cMenuEditIntxItem::SetHelpKeys(void)
+{
+  if (negString && posString)
+     SetHelp(NULL, (*value < 0) ? posString : negString);
+}
+
+void cMenuEditIntxItem::Set(void)
+{
+  const char *s = (*value < 0) ? negString : posString;
+  int v = *value;
+  if (negString && posString)
+     v = abs(v);
+  SetValue(cString::sprintf(s ? "%.*f %s" : "%.*f", factor / 10, double(v) / factor, s));
+  SetHelpKeys();
+}
+
+eOSState cMenuEditIntxItem::ProcessKey(eKeys Key)
+{
+  eOSState state = cMenuEditIntItem::ProcessKey(Key);
+  if (state == osUnknown) {
+     switch (Key) {
+       case kGreen: if (negString && posString) {
+                       *value = -*value;
+                       Set();
+                       state = osContinue;
+                       }
+                    break;
+       default: ;
+       }
+     }
+  return state;
+}
+
 // --- cMenuEditPrcItem ------------------------------------------------------
 
 cMenuEditPrcItem::cMenuEditPrcItem(const char *Name, double *Value, double Min, double Max, int Decimals)
diff --git a/menuitems.h b/menuitems.h
index ffe9957..2a30b46 100644
--- a/menuitems.h
+++ b/menuitems.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menuitems.h 2.8 2012/03/13 11:19:11 kls Exp $
+ * $Id: menuitems.h 3.1 2013/05/24 10:19:55 kls Exp $
  */
 
 #ifndef __MENUITEMS_H
@@ -27,7 +27,7 @@ public:
   cMenuEditItem(const char *Name);
   ~cMenuEditItem();
   void SetValue(const char *Value);
-  bool DisplayHelp(void);
+  bool DisplayHelp(bool Current);
   };
 
 class cMenuEditIntItem : public cMenuEditItem {
@@ -70,6 +70,17 @@ public:
   virtual eOSState ProcessKey(eKeys Key);
   };
 
+class cMenuEditIntxItem : public cMenuEditIntItem {
+private:
+  int factor;
+  const char *negString, *posString;
+  void SetHelpKeys(void);
+  virtual void Set(void);
+public:
+  cMenuEditIntxItem(const char *Name, int *Value, int Min = INT_MIN, int Max = INT_MAX, int Factor = 1, const char *NegString = NULL, const char *PosString = NULL);
+  virtual eOSState ProcessKey(eKeys Key);
+  };
+
 class cMenuEditPrcItem : public cMenuEditItem {
 protected:
   double *value;
diff --git a/newplugin b/newplugin
index 1e9e910..150649c 100755
--- a/newplugin
+++ b/newplugin
@@ -12,7 +12,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: newplugin 2.17.1.1 2013/05/02 10:04:06 kls Exp $
+# $Id: newplugin 3.1 2013/05/02 10:06:09 kls Exp $
 
 $PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin <name>\n";
 
diff --git a/nit.c b/nit.c
index 8998861..e3bf419 100644
--- a/nit.c
+++ b/nit.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: nit.c 2.10 2013/03/07 09:42:29 kls Exp $
+ * $Id: nit.c 3.0 2013/03/07 09:42:29 kls Exp $
  */
 
 #include "nit.h"
diff --git a/nit.h b/nit.h
index e93f5bf..700db9a 100644
--- a/nit.h
+++ b/nit.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: nit.h 2.0 2007/06/10 08:50:21 kls Exp $
+ * $Id: nit.h 3.0 2007/06/10 08:50:21 kls Exp $
  */
 
 #ifndef __NIT_H
diff --git a/osd.c b/osd.c
index 45d4419..c266092 100644
--- a/osd.c
+++ b/osd.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osd.c 2.38.1.1 2013/05/18 12:41:48 kls Exp $
+ * $Id: osd.c 3.1 2013/05/18 12:33:16 kls Exp $
  */
 
 #include "osd.h"
diff --git a/osd.h b/osd.h
index 777a652..600cc7a 100644
--- a/osd.h
+++ b/osd.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osd.h 2.20 2013/02/12 13:39:08 kls Exp $
+ * $Id: osd.h 3.0 2013/02/12 13:39:08 kls Exp $
  */
 
 #ifndef __OSD_H
diff --git a/osdbase.c b/osdbase.c
index fafa9c7..baadc0e 100644
--- a/osdbase.c
+++ b/osdbase.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osdbase.c 2.7 2012/12/07 09:50:47 kls Exp $
+ * $Id: osdbase.c 3.1 2013/05/24 10:19:31 kls Exp $
  */
 
 #include "osdbase.h"
@@ -286,7 +286,7 @@ void cOsdMenu::DisplayCurrent(bool Current)
      if (!Current)
         item->SetFresh(true); // leaving the current item resets 'fresh'
      if (cMenuEditItem *MenuEditItem = dynamic_cast<cMenuEditItem *>(item)) {
-        if (!MenuEditItem->DisplayHelp())
+        if (!MenuEditItem->DisplayHelp(Current))
            DisplayHelp();
         else
            helpDisplayed = false;
diff --git a/osdbase.h b/osdbase.h
index 4635184..636766a 100644
--- a/osdbase.h
+++ b/osdbase.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: osdbase.h 2.5 2012/12/07 09:49:35 kls Exp $
+ * $Id: osdbase.h 3.0 2012/12/07 09:49:35 kls Exp $
  */
 
 #ifndef __OSDBASE_H
diff --git a/pat.c b/pat.c
index a7791e2..5ed6bd9 100644
--- a/pat.c
+++ b/pat.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: pat.c 2.19 2012/11/25 14:12:21 kls Exp $
+ * $Id: pat.c 3.0 2012/11/25 14:12:21 kls Exp $
  */
 
 #include "pat.h"
diff --git a/pat.h b/pat.h
index 08da051..a93c875 100644
--- a/pat.h
+++ b/pat.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: pat.h 2.3 2013/02/16 15:20:24 kls Exp $
+ * $Id: pat.h 3.0 2013/02/16 15:20:24 kls Exp $
  */
 
 #ifndef __PAT_H
diff --git a/player.c b/player.c
index 5c95f4e..5fc4dbf 100644
--- a/player.c
+++ b/player.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: player.c 2.2 2012/04/28 11:52:50 kls Exp $
+ * $Id: player.c 3.0 2012/04/28 11:52:50 kls Exp $
  */
 
 #include "player.h"
diff --git a/player.h b/player.h
index 01bc958..05ba518 100644
--- a/player.h
+++ b/player.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: player.h 2.6 2012/04/28 13:04:17 kls Exp $
+ * $Id: player.h 3.0 2012/04/28 13:04:17 kls Exp $
  */
 
 #ifndef __PLAYER_H
diff --git a/plugin.c b/plugin.c
index db16d08..650f923 100644
--- a/plugin.c
+++ b/plugin.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: plugin.c 2.4 2012/09/01 13:10:27 kls Exp $
+ * $Id: plugin.c 3.0 2012/09/01 13:10:27 kls Exp $
  */
 
 #include "plugin.h"
diff --git a/plugin.h b/plugin.h
index 3502741..d04274a 100644
--- a/plugin.h
+++ b/plugin.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: plugin.h 2.2 2012/09/01 13:08:54 kls Exp $
+ * $Id: plugin.h 3.0 2012/09/01 13:08:54 kls Exp $
  */
 
 #ifndef __PLUGIN_H
diff --git a/po/ar.po b/po/ar.po
index 54c3f3c..1676dcb 100644
--- a/po/ar.po
+++ b/po/ar.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-02-03 16:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2008-10-16 11:16-0400\n"
 "Last-Translator: Osama Alrawab <alrawab at hotmail.com>\n"
 "Language-Team: Arabic <ar at li.org>\n"
@@ -997,6 +997,33 @@ msgstr "Device %d connected to sat cable"
 msgid "Setup.LNB$own"
 msgstr "own"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "اعادة تشغيل الكامة"
 
@@ -1334,6 +1361,10 @@ msgstr "بث حى"
 msgid "PLAY"
 msgstr "عرض"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG شاشة "
 
diff --git a/po/ca_ES.po b/po/ca_ES.po
index 89d6556..0362cd8 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2008-03-02 19:02+0100\n"
 "Last-Translator: Luca Olivetti <luca at ventoso.org>\n"
 "Language-Team: Catalan <vdr at linuxtv.org>\n"
@@ -996,6 +996,33 @@ msgstr "Dispositiu %d connectat a cable sat
 msgid "Setup.LNB$own"
 msgstr "propi"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Reiniciar CAM"
 
@@ -1333,6 +1360,10 @@ msgstr "EN DIRECTE"
 msgid "PLAY"
 msgstr "REPRODUIR"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "Quadres ST:TNG"
 
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index 5409f08..2bd4a8e 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2010-05-06 11:00+0200\n"
 "Last-Translator: Aleš Juřík <ajurik at quick.cz>\n"
 "Language-Team: Czech <vdr at linuxtv.org>\n"
@@ -996,6 +996,33 @@ msgstr "Zařízení %d připojeno k sat. kabelu"
 msgid "Setup.LNB$own"
 msgstr "vlastní"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Reset CAMu"
 
@@ -1333,6 +1360,10 @@ msgstr "ŽIVĚ"
 msgid "PLAY"
 msgstr "PŘEHRÁVÁNÍ"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG konzola"
 
diff --git a/po/da_DK.po b/po/da_DK.po
index 4069a7b..edd0f5f 100644
--- a/po/da_DK.po
+++ b/po/da_DK.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Mogens Elneff <mogens at elneff.dk>\n"
 "Language-Team: Danish <vdr at linuxtv.org>\n"
@@ -993,6 +993,33 @@ msgstr ""
 msgid "Setup.LNB$own"
 msgstr ""
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM nulstil"
 
@@ -1330,6 +1357,10 @@ msgstr ""
 msgid "PLAY"
 msgstr ""
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG konsol"
 
diff --git a/po/de_DE.po b/po/de_DE.po
index 0e24ab2..4cc8e84 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2010-01-16 16:46+0100\n"
 "Last-Translator: Klaus Schmidinger <vdr at tvdr.de>\n"
 "Language-Team: German <vdr at linuxtv.org>\n"
@@ -993,6 +993,33 @@ msgstr "Device %d angeschlossen an Sat-Kabel"
 msgid "Setup.LNB$own"
 msgstr "eigenes"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr "Antennen-Positionierer benutzen"
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr "Standort L�ngengrad"
+
+msgid "South"
+msgstr "S�d"
+
+msgid "North"
+msgstr "Nord"
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr "Standort Breitengrad"
+
+msgid "West"
+msgstr "West"
+
+msgid "East"
+msgstr "Ost"
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr "Max. Positionier-Winkel (Grad)"
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr "Max. Positionier-Geschwindigkeit (Grad/s)"
+
 msgid "CAM reset"
 msgstr "CAM zur�ckgesetzt"
 
@@ -1330,6 +1357,10 @@ msgstr "LIVE"
 msgid "PLAY"
 msgstr "WIEDERGABE"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr "Antenne wird auf %.1f gedreht..."
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG-Konsolen"
 
diff --git a/po/el_GR.po b/po/el_GR.po
index b61174e..8df5b78 100644
--- a/po/el_GR.po
+++ b/po/el_GR.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Dimitrios Dimitrakos <mail at dimitrios.de>\n"
 "Language-Team: Greek <vdr at linuxtv.org>\n"
@@ -993,6 +993,33 @@ msgstr ""
 msgid "Setup.LNB$own"
 msgstr ""
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr ""
 
@@ -1330,6 +1357,10 @@ msgstr ""
 msgid "PLAY"
 msgstr ""
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "������ ST:TNG"
 
diff --git a/po/es_ES.po b/po/es_ES.po
index fba8c21..023871e 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2008-03-02 19:02+0100\n"
 "Last-Translator: Luca Olivetti <luca at ventoso.org>\n"
 "Language-Team: Spanish <vdr at linuxtv.org>\n"
@@ -994,6 +994,33 @@ msgstr "Dispositivo %d conectado a cable sat
 msgid "Setup.LNB$own"
 msgstr "propio"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Reset CAM"
 
@@ -1331,6 +1358,10 @@ msgstr "EN DIRECTO"
 msgid "PLAY"
 msgstr "REPRODUCIR"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "Paneles ST:TNG"
 
diff --git a/po/et_EE.po b/po/et_EE.po
index 333f0b0..8539f17 100644
--- a/po/et_EE.po
+++ b/po/et_EE.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Arthur Konovalov <artlov at gmail.com>\n"
 "Language-Team: Estonian <vdr at linuxtv.org>\n"
@@ -993,6 +993,33 @@ msgstr "DVB seade %d ühendatud SAT-kaabliga"
 msgid "Setup.LNB$own"
 msgstr "oma"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM taaskäivitamine"
 
@@ -1330,6 +1357,10 @@ msgstr "LIVE"
 msgid "PLAY"
 msgstr "ESITUS"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG Panels"
 
diff --git a/po/fi_FI.po b/po/fi_FI.po
index f44dd72..84c50a6 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2007-08-15 15:52+0200\n"
 "Last-Translator: Matti Lehtimäki <matti.lehtimaki at gmail.com>\n"
 "Language-Team: Finnish <vdr at linuxtv.org>\n"
@@ -997,6 +997,33 @@ msgstr "DVB-sovitin %d kytketty SAT-kaapeliin"
 msgid "Setup.LNB$own"
 msgstr "oma"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM nollaus"
 
@@ -1334,6 +1361,10 @@ msgstr "LIVE"
 msgid "PLAY"
 msgstr "TOISTO"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG konsoli"
 
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 6228d7f..a4eda2f 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -17,7 +17,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-02-24 12:56+0100\n"
 "Last-Translator: Dominique Plu <dplu at free.fr>\n"
 "Language-Team: French <vdr at linuxtv.org>\n"
@@ -1003,6 +1003,33 @@ msgstr "Le périphérique %d est connecté au câble satellite"
 msgid "Setup.LNB$own"
 msgstr "Propriétaire"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM réinitialisé"
 
@@ -1340,6 +1367,10 @@ msgstr "DIRECT"
 msgid "PLAY"
 msgstr "LECTURE"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "Consoles ST:TNG"
 
diff --git a/po/hr_HR.po b/po/hr_HR.po
index 3925422..baafe9d 100644
--- a/po/hr_HR.po
+++ b/po/hr_HR.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2008-03-17 19:00+0100\n"
 "Last-Translator: Adrian Caval <anrxc at sysphere.org>\n"
 "Language-Team: Croatian <vdr at linuxtv.org>\n"
@@ -995,6 +995,33 @@ msgstr ""
 msgid "Setup.LNB$own"
 msgstr ""
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Ponovno pokreni CAM"
 
@@ -1332,6 +1359,10 @@ msgstr ""
 msgid "PLAY"
 msgstr ""
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG Panele"
 
diff --git a/po/hu_HU.po b/po/hu_HU.po
index e4f8594..b3c17b0 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-03-01 19:22+0200\n"
 "Last-Translator: István Füley <ifuley at tigercomp.ro>\n"
 "Language-Team: Hungarian <vdr at linuxtv.org>\n"
@@ -997,6 +997,33 @@ msgstr "Fejkábel a %d. tunerhez"
 msgid "Setup.LNB$own"
 msgstr "saját"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM újraindítás"
 
@@ -1334,6 +1361,10 @@ msgstr "ÉLŐ"
 msgid "PLAY"
 msgstr "LEJÁTSZÁS"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG Konzol"
 
diff --git a/po/it_IT.po b/po/it_IT.po
index 281434c..e579885 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-02-11 23:46+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian at tiscali.it>\n"
 "Language-Team: Italian <vdr at linuxtv.org>\n"
@@ -1000,6 +1000,33 @@ msgstr "Periferica %d connessa al cavo sat"
 msgid "Setup.LNB$own"
 msgstr "propria"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Reimposta la CAM"
 
@@ -1337,6 +1364,10 @@ msgstr "DAL VIVO"
 msgid "PLAY"
 msgstr "RIPRODUCI"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "Consolle ST:TNG"
 
diff --git a/po/lt_LT.po b/po/lt_LT.po
index dba4224..34e273c 100644
--- a/po/lt_LT.po
+++ b/po/lt_LT.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2010-10-30 11:55+0200\n"
 "Last-Translator: Valdemaras Pipiras <varas at ambernet.lt>\n"
 "Language-Team: Lithuanian <vdr at linuxtv.org>\n"
@@ -993,6 +993,33 @@ msgstr "Įrenginys %d prijungtas prie sat kabelio"
 msgid "Setup.LNB$own"
 msgstr "savas"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Dekodavimo modulis (CAM) perkrautas"
 
@@ -1330,6 +1357,10 @@ msgstr "GYVAI"
 msgid "PLAY"
 msgstr "GROTI"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG Skydeliai"
 
diff --git a/po/mk_MK.po b/po/mk_MK.po
index b9f56a2..a398b3c 100644
--- a/po/mk_MK.po
+++ b/po/mk_MK.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2012-11-19 15:18+0100\n"
 "Last-Translator: Dimitar Petrovski <dimeptr at gmail.com>\n"
 "Language-Team: Macedonian <en at li.org>\n"
@@ -994,6 +994,33 @@ msgstr "Уред %d поврзан со сателитски кабел"
 msgid "Setup.LNB$own"
 msgstr "свој"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Рестартирај CAM"
 
@@ -1331,6 +1358,10 @@ msgstr "ЖИВО"
 msgid "PLAY"
 msgstr "ПУШТИ"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG Панели"
 
diff --git a/po/nl_NL.po b/po/nl_NL.po
index 8766f34..e9b9a00 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -12,7 +12,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2008-02-26 17:20+0100\n"
 "Last-Translator: Cedric Dewijs <cedric.dewijs at telfort.nl>\n"
 "Language-Team: Dutch <vdr at linuxtv.org>\n"
@@ -998,6 +998,33 @@ msgstr "Apparaat %d verbionden met sat. kabel"
 msgid "Setup.LNB$own"
 msgstr "eigen"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM herstarten"
 
@@ -1335,6 +1362,10 @@ msgstr "LIVE"
 msgid "PLAY"
 msgstr "AFSPELEN"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG Consoles"
 
diff --git a/po/nn_NO.po b/po/nn_NO.po
index 4f6668c..a05410f 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Truls Slevigen <truls at slevigen.no>\n"
 "Language-Team: Norwegian Nynorsk <vdr at linuxtv.org>\n"
@@ -994,6 +994,33 @@ msgstr ""
 msgid "Setup.LNB$own"
 msgstr ""
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr ""
 
@@ -1331,6 +1358,10 @@ msgstr ""
 msgid "PLAY"
 msgstr ""
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr ""
 
diff --git a/po/pl_PL.po b/po/pl_PL.po
index c11c656..f240894 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2008-03-09 12:59+0100\n"
 "Last-Translator: Marek Nazarko <mnazarko at gmail.com>\n"
 "Language-Team: Polish <vdr at linuxtv.org>\n"
@@ -995,6 +995,33 @@ msgstr "Urz
 msgid "Setup.LNB$own"
 msgstr "W�asny"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM zresetowany"
 
@@ -1332,6 +1359,10 @@ msgstr "NA 
 msgid "PLAY"
 msgstr "ODTWARZA"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "Panel ST:TNG"
 
diff --git a/po/pt_PT.po b/po/pt_PT.po
index ffd3fec..7dde8c5 100644
--- a/po/pt_PT.po
+++ b/po/pt_PT.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2010-03-28 22:49+0100\n"
 "Last-Translator: Cris Silva <hudokkow at gmail.com>\n"
 "Language-Team: Portuguese <vdr at linuxtv.org>\n"
@@ -994,6 +994,33 @@ msgstr ""
 msgid "Setup.LNB$own"
 msgstr ""
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Reiniciar CAM"
 
@@ -1331,6 +1358,10 @@ msgstr ""
 msgid "PLAY"
 msgstr ""
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "Consola ST:TNG"
 
diff --git a/po/ro_RO.po b/po/ro_RO.po
index 3214a2e..f49c452 100644
--- a/po/ro_RO.po
+++ b/po/ro_RO.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-02-09 23:01+0100\n"
 "Last-Translator: Lucian Muresan <lucianm at users.sorceforge.net>\n"
 "Language-Team: Romanian <vdr at linuxtv.org>\n"
@@ -995,6 +995,33 @@ msgstr "Receptorul %d conectat la cablul de satelit"
 msgid "Setup.LNB$own"
 msgstr "propriu"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Resetare CAM"
 
@@ -1332,6 +1359,10 @@ msgstr "LIVE"
 msgid "PLAY"
 msgstr "REDARE"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "Cons. ST:TNG"
 
diff --git a/po/ru_RU.po b/po/ru_RU.po
index eecc89e..7856560 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-03-10 17:13+0100\n"
 "Last-Translator: Oleg Roitburd <oroitburd at gmail.com>\n"
 "Language-Team: Russian <vdr at linuxtv.org>\n"
@@ -994,6 +994,33 @@ msgstr "
 msgid "Setup.LNB$own"
 msgstr "����"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM ����������"
 
@@ -1331,6 +1358,10 @@ msgstr "LIVE"
 msgid "PLAY"
 msgstr "���������������"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG ������"
 
diff --git a/po/sk_SK.po b/po/sk_SK.po
index 46dc3ae..6e849b0 100644
--- a/po/sk_SK.po
+++ b/po/sk_SK.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-02-03 16:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-03-04 21:24+0100\n"
 "Last-Translator: Milan Hrala <hrala.milan at gmail.com>\n"
 "Language-Team: Slovak <vdr at linuxtv.org>\n"
@@ -993,6 +993,33 @@ msgstr "Zariadenie %d je pripojen
 msgid "Setup.LNB$own"
 msgstr "vlastn�"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Resetnutie CAMu"
 
@@ -1330,6 +1357,10 @@ msgstr "NA
 msgid "PLAY"
 msgstr "PREHR�VA SA"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG panely"
 
diff --git a/po/sl_SI.po b/po/sl_SI.po
index 842157e..6e9ca32 100644
--- a/po/sl_SI.po
+++ b/po/sl_SI.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-03-04 12:46+0100\n"
 "Last-Translator: Matjaz Thaler <matjaz.thaler at guest.arnes.si>\n"
 "Language-Team: Slovenian <vdr at linuxtv.org>\n"
@@ -994,6 +994,33 @@ msgstr "Naprava %d priklju
 msgid "Setup.LNB$own"
 msgstr "lastni"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Reset CAM-a"
 
@@ -1331,6 +1358,10 @@ msgstr "V 
 msgid "PLAY"
 msgstr "PREDVAJAJ"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG Konsola"
 
diff --git a/po/sr_RS.po b/po/sr_RS.po
index 2968b91..12586f7 100644
--- a/po/sr_RS.po
+++ b/po/sr_RS.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-03-16 15:05+0100\n"
 "Last-Translator: Zoran Turalija <zoran.turalija at gmail.com>\n"
 "Language-Team: Serbian <vdr at linuxtv.org>\n"
@@ -994,6 +994,33 @@ msgstr "Ure
 msgid "Setup.LNB$own"
 msgstr "sopstven"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Ponovno pokreni CAM"
 
@@ -1331,6 +1358,10 @@ msgstr "U
 msgid "PLAY"
 msgstr "REPRODUKCIJA"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG paneli"
 
diff --git a/po/sv_SE.po b/po/sv_SE.po
index 15a49ee..58492c4 100644
--- a/po/sv_SE.po
+++ b/po/sv_SE.po
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-02-18 17:04+0100\n"
 "Last-Translator: Richard Lithvall <r-vdr at boomer.se>\n"
 "Language-Team: Swedish <vdr at linuxtv.org>\n"
@@ -997,6 +997,33 @@ msgstr "Enhet %d ansluten till satellitkabel"
 msgid "Setup.LNB$own"
 msgstr "�gare"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM omstart"
 
@@ -1334,6 +1361,10 @@ msgstr "LIVE"
 msgid "PLAY"
 msgstr "SPELA"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG"
 
diff --git a/po/tr_TR.po b/po/tr_TR.po
index 54956de..d920180 100644
--- a/po/tr_TR.po
+++ b/po/tr_TR.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2008-02-28 00:33+0100\n"
 "Last-Translator: Oktay Yolge�en <oktay_73 at yahoo.de>\n"
 "Language-Team: Turkish <vdr at linuxtv.org>\n"
@@ -993,6 +993,33 @@ msgstr ""
 msgid "Setup.LNB$own"
 msgstr ""
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM s�f�rland�"
 
@@ -1330,6 +1357,10 @@ msgstr ""
 msgid "PLAY"
 msgstr ""
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG paneli"
 
diff --git a/po/uk_UA.po b/po/uk_UA.po
index 7626d8d..829921d 100644
--- a/po/uk_UA.po
+++ b/po/uk_UA.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-03-04 14:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-02-09 16:00+0100\n"
 "Last-Translator: Yarema aka Knedlyk <yupadmin at gmail.com>\n"
 "Language-Team: Ukrainian <vdr at linuxtv.org>\n"
@@ -994,6 +994,33 @@ msgstr "Пристрій %d під’єднано до сателітарног
 msgid "Setup.LNB$own"
 msgstr "власне"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "Перезавантаження CAM"
 
@@ -1331,6 +1358,10 @@ msgstr "ЕФІР"
 msgid "PLAY"
 msgstr "ПРОГРАВАННЯ"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG панелі"
 
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 98e3f98..8ba5e4d 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.0.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2013-02-03 16:46+0100\n"
+"POT-Creation-Date: 2013-06-10 12:16+0200\n"
 "PO-Revision-Date: 2013-03-04 14:52+0800\n"
 "Last-Translator: NFVDR <nfvdr at live.com>\n"
 "Language-Team: Chinese (simplified) <nfvdr at live.com>\n"
@@ -995,6 +995,33 @@ msgstr "设备%d卫星连接线"
 msgid "Setup.LNB$own"
 msgstr "所有"
 
+msgid "Setup.LNB$Use dish positioner"
+msgstr ""
+
+msgid "Setup.LNB$Site latitude (degrees)"
+msgstr ""
+
+msgid "South"
+msgstr ""
+
+msgid "North"
+msgstr ""
+
+msgid "Setup.LNB$Site longitude (degrees)"
+msgstr ""
+
+msgid "West"
+msgstr ""
+
+msgid "East"
+msgstr ""
+
+msgid "Setup.LNB$Max. positioner swing (degrees)"
+msgstr ""
+
+msgid "Setup.LNB$Positioner speed (degrees/s)"
+msgstr ""
+
 msgid "CAM reset"
 msgstr "CAM重置"
 
@@ -1332,6 +1359,10 @@ msgstr "现场"
 msgid "PLAY"
 msgstr "播放"
 
+#, c-format
+msgid "Moving dish to %.1f..."
+msgstr ""
+
 msgid "ST:TNG Panels"
 msgstr "ST:TNG 面板"
 
diff --git a/positioner.c b/positioner.c
new file mode 100644
index 0000000..7adcc73
--- /dev/null
+++ b/positioner.c
@@ -0,0 +1,140 @@
+/*
+ * positioner.c: Steerable dish positioning
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * For an explanation (in German) of the theory behind the calculations see
+ * http://www.vdr-portal.de/board17-developer/board97-vdr-core/p1154305-grundlagen-und-winkelberechnungen-f%C3%BCr-h-h-diseqc-motor-antennenanlagen
+ *
+ * $Id: positioner.c 3.1 2013/08/21 11:02:52 kls Exp $
+ */
+
+#include "positioner.h"
+#include <math.h>
+#include "config.h"
+
+#define SAT_EARTH_RATIO    0.1513 // the Earth's radius, divided by the distance from the Earth's center to the satellite
+#define SAT_VISIBILITY_LAT 810    // the absolute latitude beyond which no satellite can be seen (degrees * 10)
+
+#define RAD(x) ((x) * M_PI / 1800)
+#define DEG(x) ((x) * 1800 / M_PI)
+
+cPositioner *cPositioner::positioner = NULL;
+
+cPositioner::cPositioner(void)
+{
+  capabilities = pcCanNothing;
+  frontend = -1;
+  targetLongitude = lastLongitude = Setup.PositionerLastLon;
+  targetHourAngle = lastHourAngle = CalcHourAngle(lastLongitude);
+  swingTime = 0;
+  delete positioner;
+  positioner = this;
+}
+
+cPositioner::~cPositioner()
+{
+  positioner = NULL;
+}
+
+int cPositioner::NormalizeAngle(int Angle)
+{
+  while (Angle < -1800)
+        Angle += 3600;
+  while (Angle > 1800)
+        Angle -= 3600;
+  return Angle;
+}
+
+int cPositioner::CalcHourAngle(int Longitude)
+{
+  double Delta = RAD(Longitude - Setup.SiteLon);
+  double Lat = RAD(Setup.SiteLat);
+  int Sign = Setup.SiteLat >= 0 ? -1 : 1; // angles to the right are positive, angles to the left are negative
+  return Sign * round(DEG(atan2(sin(Delta), cos(Delta) - cos(Lat) * SAT_EARTH_RATIO)));
+}
+
+int cPositioner::CalcLongitude(int HourAngle)
+{
+  double Lat = RAD(Setup.SiteLat);
+  double Lon = RAD(Setup.SiteLon);
+  double Alpha = RAD(HourAngle);
+  double Delta = Alpha - asin(sin(M_PI - Alpha) * cos(Lat) * SAT_EARTH_RATIO);
+  int Sign = Setup.SiteLat >= 0 ? 1 : -1;
+  return NormalizeAngle(round(DEG(Lon - Sign * Delta)));
+}
+
+int cPositioner::HorizonLongitude(ePositionerDirection Direction)
+{
+  double Delta;
+  if (abs(Setup.SiteLat) < SAT_VISIBILITY_LAT)
+     Delta = acos(SAT_EARTH_RATIO / cos(RAD(Setup.SiteLat)));
+  else
+     Delta = RAD(145);
+  if ((Setup.SiteLat >= 0) != (Direction == pdLeft))
+     Delta = -Delta;
+  return NormalizeAngle(round(DEG(RAD(Setup.SiteLon) + Delta)));
+}
+
+int cPositioner::HardLimitLongitude(ePositionerDirection Direction) const
+{
+  return CalcLongitude(Direction == pdLeft ? -Setup.PositionerSwing : Setup.PositionerSwing);
+}
+
+void cPositioner::StartMovementTimer(int Longitude)
+{
+  if (Setup.PositionerSpeed <= 0)
+     return;
+  cMutexLock MutexLock(&mutex);
+  lastLongitude = CurrentLongitude(); // in case the dish was already in motion
+  targetLongitude = Longitude;
+  lastHourAngle = CalcHourAngle(lastLongitude);
+  targetHourAngle = CalcHourAngle(targetLongitude);
+  swingTime = abs(targetHourAngle - lastHourAngle) * 1000 / Setup.PositionerSpeed; // time (ms) it takes to move the dish from lastHourAngle to targetHourAngle
+  movementStart.Set();
+  Setup.PositionerLastLon = targetLongitude;
+}
+
+void cPositioner::GotoPosition(uint Number, int Longitude)
+{
+  if (Longitude != targetLongitude)
+     dsyslog("moving positioner to position %d, longitude %d", Number, Longitude);
+  StartMovementTimer(Longitude);
+}
+
+void cPositioner::GotoAngle(int Longitude)
+{
+  if (Longitude != targetLongitude)
+     dsyslog("moving positioner to longitude %d", Longitude);
+  StartMovementTimer(Longitude);
+}
+
+int cPositioner::CurrentLongitude(void) const
+{
+  cMutexLock MutexLock(&mutex);
+  if (targetLongitude != lastLongitude) {
+     int Elapsed = movementStart.Elapsed(); // it's important to make this 'int', otherwise the expression below yields funny results
+     if (swingTime <= Elapsed)
+        lastLongitude = targetLongitude;
+     else
+        return CalcLongitude(lastHourAngle + (targetHourAngle - lastHourAngle) * Elapsed / swingTime);
+     }
+  return lastLongitude;
+}
+
+bool cPositioner::IsMoving(void) const
+{
+  cMutexLock MutexLock(&mutex);
+  return CurrentLongitude() != targetLongitude;
+}
+
+cPositioner *cPositioner::GetPositioner(void)
+{
+  return positioner;
+}
+
+void cPositioner::DestroyPositioner(void)
+{
+  delete positioner;
+}
diff --git a/positioner.h b/positioner.h
new file mode 100644
index 0000000..6e019ed
--- /dev/null
+++ b/positioner.h
@@ -0,0 +1,171 @@
+/*
+ * positioner.h: Steerable dish positioning
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: positioner.h 3.1 2013/06/10 14:27:14 kls Exp $
+ */
+
+#ifndef __POSITIONER_H
+#define __POSITIONER_H
+
+#include "thread.h"
+#include "tools.h"
+
+/// A steerable satellite dish generally points to the south on the northern hemisphere,
+/// and to the north on the southern hemisphere (unless you're located directly on the
+/// equator, in which case the general direction is "up"). Therefore, moving the dish
+/// "east" or "west" means something different on either hemisphere. From the local dish
+/// motor's point of view, it makes more sense to speak of turning the dish "left" or
+/// "right", which is independent of the actual hemisphere the dish is located in.
+/// In the cPositioner class context, when a dish on the northern hemisphere moves "east",
+/// it is considered to be moving "left". Imagine standing behind the dish and looking
+/// towards the satellites, and clearly "east" is "left". On the southern hemisphere
+/// the same move to the "left" would go to the "west". So on the hardware level it is
+/// clear what "left" and "right" means. The user interface may present different labels
+/// to the viewer, depending on the hemisphere the dish is on.
+/// All angles in this context are given in "degrees * 10", which allows for an angular
+/// resolution of 0.1 degrees.
+
+class cPositioner {
+private:
+  mutable cMutex mutex;
+  static cPositioner *positioner;
+  int capabilities;
+  int frontend; // file descriptor of the DVB frontend
+  mutable int lastLongitude; // the longitude the dish has last been moved to
+  int targetLongitude; // the longitude the dish is supposed to be moved to
+  mutable int lastHourAngle; // the hour angle the positioner has last been moved to
+  int targetHourAngle; // the hour angle the positioner is supposed to be moved to
+  int swingTime;
+  cTimeMs movementStart;
+protected:
+  cPositioner(void);
+  virtual ~cPositioner();
+  void SetCapabilities(int Capabilities) { capabilities = Capabilities; }
+      ///< A derived class shall call this function in its constructor to set the
+      ///< capability flags it supports.
+  int Frontend(void) const { return frontend; }
+      ///< Returns the file descriptor of the DVB frontend the positioner is
+      ///< connected to. If the positioner is not connected to any DVB device,
+      ///< -1 will be returned.
+  static int CalcHourAngle(int Longitude);
+      ///< Takes the longitude and latitude of the dish location from the system
+      ///< setup and the given Longitude to calculate the "hour angle" to which to move
+      ///< the dish to in order to point to the satellite at orbital position Longitude.
+      ///< An hour angle of zero means the dish shall point directly towards the
+      ///< celestial equator (which is south on the northern hemisphere, and north on
+      ///< the southern hemisphere). Negative values mean that the dish needs to be
+      ///< moved to the left (as seen from behind the dish), while positive values
+      ///< require a movement to the right.
+  static int CalcLongitude(int HourAngle);
+      ///< Returns the longitude of the satellite position the dish points at when the
+      ///< positioner is moved to the given HourAngle.
+  void StartMovementTimer(int Longitude);
+      ///< Starts a timer that estimates how long it will take to move the dish from
+      ///< the current position to the one given by Longitude. The default implementation
+      ///< of CurrentLongitude() uses this timer.
+public:
+  enum ePositionerCapabilities {
+    pcCanNothing         = 0x0000,
+    pcCanDrive           = 0x0001,
+    pcCanStep            = 0x0002,
+    pcCanHalt            = 0x0004,
+    pcCanSetLimits       = 0x0008,
+    pcCanDisableLimits   = 0x0010,
+    pcCanEnableLimits    = 0x0020,
+    pcCanStorePosition   = 0x0040,
+    pcCanRecalcPositions = 0x0080,
+    pcCanGotoPosition    = 0x0100,
+    pcCanGotoAngle       = 0x0200,
+    };
+  enum ePositionerDirection { pdLeft, pdRight };
+  static int NormalizeAngle(int Angle);
+          ///< Normalizes the given Angle into the range -1800...1800.
+  int Capabilities(void) const { return capabilities; }
+          ///< Returns a flag word defining all the things this positioner is
+          ///< capable of.
+  void SetFrontend(int Frontend) { frontend = Frontend; }
+          ///< This function is called whenever the positioner is connected to
+          ///< a DVB frontend.
+  static int HorizonLongitude(ePositionerDirection Direction);
+          ///< Returns the longitude of the satellite position that is just at the
+          ///< horizon when looking in the given Direction. Note that this function
+          ///< only delivers reasonable values for site latitudes between +/-81 degrees.
+          ///< Beyond these limits (i.e. near the north or south pole) a constant value
+          ///< of +/-14.5 degrees (integer value 145) will be returned.
+  int HardLimitLongitude(ePositionerDirection Direction) const;
+          ///< Returns the longitude of the positioner's hard limit in the given
+          ///< Direction. Note that the value returned here may be larger (or smaller,
+          ///< depending on the Direction) than that returned by HorizonLongitude(),
+          ///< which would mean that it lies below that horizon.
+  int LastLongitude(void) const { return lastLongitude; }
+          ///< Returns the longitude the dish has last been moved to.
+  int TargetLongitude(void) const { return targetLongitude; }
+          ///< Returns the longitude the dish is supposed to be moved to. Once the target
+          ///< longitude has been reached, this is the same as the value returned by
+          ///< CurrentLongitude().
+  virtual cString Error(void) const { return NULL; }
+          ///< Returns a short, single line string indicating an error condition (if
+          ///< the positioner is able to report any errors).
+          ///< NULL means there is no error.
+  virtual void Drive(ePositionerDirection Direction) {}
+          ///< Continuously move the dish to the given Direction until Halt() is
+          ///< called or it hits the soft or hard limit.
+  virtual void Step(ePositionerDirection Direction, uint Steps = 1) {}
+          ///< Move the dish the given number of Steps in the given Direction.
+          ///< The maximum number of steps a particular positioner can do in a single
+          ///< call may be limited.
+          ///< A "step" is the smallest possible movement the positioner can make, which
+          ///< is typically 0.1 degrees.
+  virtual void Halt(void) {}
+          ///< Stop any ongoing motion of the dish.
+  virtual void SetLimit(ePositionerDirection Direction) {}
+          ///< Set the soft limit of the dish movement in the given Direction to the
+          ///< current position.
+  virtual void DisableLimits(void) {}
+          ///< Disables the soft limits for the dish movement.
+  virtual void EnableLimits(void) {}
+          ///< Enables the soft limits for the dish movement.
+  virtual void StorePosition(uint Number) {}
+          ///< Store the current position as a satellite position with the given Number.
+          ///< Number can be in the range 1...255. However, a particular positioner
+          ///< may only have a limited number of satellite positions it can store.
+  virtual void RecalcPositions(uint Number) {}
+          ///< Take the difference betwen the current actual position of the dish and
+          ///< the position stored with teh given Number, and apply the difference to
+          ///< all stored positions.
+  virtual void GotoPosition(uint Number, int Longitude);
+          ///< Move the dish to the satellite position stored under the given Number.
+          ///< Number must be one of the values previously used with StorePosition().
+          ///< The special value 0 shall move the dish to a "reference position",
+          ///< which usually is due south (or north, if you're on the southern hemisphere).
+          ///< Longitude will be used to calculate how long it takes to move the dish
+          ///< from its current position to the given Longitude.
+          ///< A derived class must call the base class function to have the target
+          ///< longitude stored.
+  virtual void GotoAngle(int Longitude);
+          ///< Move the dish to the given angular position. Longitude can be in the range
+          ///< -1800...+1800. A positive sign indicates a position east of Greenwich,
+          ///< while western positions have a negative sign. The absolute value is in
+          ///< "degrees * 10", which allows for a resolution of 1/10 of a degree.
+          ///< A derived class must call the base class function to have the target
+          ///< longitude stored.
+  virtual int CurrentLongitude(void) const;
+          ///< Returns the longitude the dish currently points to. If the dish is in motion,
+          ///< this may be an estimate based on the angular speed of the positioner.
+          ///< The default implementation takes the last and target longitude as well as
+          ///< the rotation speed of the positioner to calculate the estimated current
+          ///< longitude the dish points to.
+  virtual bool IsMoving(void) const;
+          ///< Returns true if the dish is currently moving as a result of a call to
+          ///< GotoPosition() or GotoAngle().
+  static cPositioner *GetPositioner(void);
+          ///< Returns a previously created positioner. If no plugin has created
+          ///< a positioner, there will always be the default DiSEqC positioner.
+  static void DestroyPositioner(void);
+          ///< Destroys a previously created positioner.
+  };
+
+#endif //__POSITIONER_H
diff --git a/receiver.c b/receiver.c
index bde60e4..909c44b 100644
--- a/receiver.c
+++ b/receiver.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: receiver.c 2.7 2012/06/02 13:20:38 kls Exp $
+ * $Id: receiver.c 3.0 2012/06/02 13:20:38 kls Exp $
  */
 
 #include "receiver.h"
diff --git a/receiver.h b/receiver.h
index 775dabd..59e6d33 100644
--- a/receiver.h
+++ b/receiver.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: receiver.h 2.9 2012/09/02 09:27:20 kls Exp $
+ * $Id: receiver.h 3.0 2012/09/02 09:27:20 kls Exp $
  */
 
 #ifndef __RECEIVER_H
diff --git a/recorder.c b/recorder.c
index a9cc8c9..047dd19 100644
--- a/recorder.c
+++ b/recorder.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recorder.c 2.17 2012/09/22 11:53:57 kls Exp $
+ * $Id: recorder.c 3.0 2012/09/22 11:53:57 kls Exp $
  */
 
 #include "recorder.h"
diff --git a/recorder.h b/recorder.h
index 05cc42b..250e99f 100644
--- a/recorder.h
+++ b/recorder.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recorder.h 2.3 2010/12/27 11:17:04 kls Exp $
+ * $Id: recorder.h 3.0 2010/12/27 11:17:04 kls Exp $
  */
 
 #ifndef __RECORDER_H
diff --git a/recording.c b/recording.c
index b1ca9c5..eb3b466 100644
--- a/recording.c
+++ b/recording.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.c 2.91.1.1 2013/04/11 08:20:03 kls Exp $
+ * $Id: recording.c 3.2 2013/08/21 13:03:38 kls Exp $
  */
 
 #include "recording.h"
@@ -178,34 +178,38 @@ void AssertFreeDiskSpace(int Priority, bool Force)
               return; // the next call will actually remove it
            }
         // No "deleted" files to remove, so let's see if we can delete a recording:
-        isyslog("...no deleted recording found, trying to delete an old recording...");
-        cThreadLock RecordingsLock(&Recordings);
-        if (Recordings.Count()) {
-           cRecording *r = Recordings.First();
-           cRecording *r0 = NULL;
-           while (r) {
-                 if (r->IsOnVideoDirectoryFileSystem()) { // only delete recordings that will actually increase the free video disk space
-                    if (!r->IsEdited() && r->Lifetime() < MAXLIFETIME) { // edited recordings and recordings with MAXLIFETIME live forever
-                       if ((r->Lifetime() == 0 && Priority > r->Priority()) || // the recording has no guaranteed lifetime and the new recording has higher priority
-                           (r->Lifetime() > 0 && (time(NULL) - r->Start()) / SECSINDAY >= r->Lifetime())) { // the recording's guaranteed lifetime has expired
-                          if (r0) {
-                             if (r->Priority() < r0->Priority() || (r->Priority() == r0->Priority() && r->Start() < r0->Start()))
-                                r0 = r; // in any case we delete the one with the lowest priority (or the older one in case of equal priorities)
+        if (Priority > 0) {
+           isyslog("...no deleted recording found, trying to delete an old recording...");
+           cThreadLock RecordingsLock(&Recordings);
+           if (Recordings.Count()) {
+              cRecording *r = Recordings.First();
+              cRecording *r0 = NULL;
+              while (r) {
+                    if (r->IsOnVideoDirectoryFileSystem()) { // only delete recordings that will actually increase the free video disk space
+                       if (!r->IsEdited() && r->Lifetime() < MAXLIFETIME) { // edited recordings and recordings with MAXLIFETIME live forever
+                          if ((r->Lifetime() == 0 && Priority > r->Priority()) || // the recording has no guaranteed lifetime and the new recording has higher priority
+                              (r->Lifetime() > 0 && (time(NULL) - r->Start()) / SECSINDAY >= r->Lifetime())) { // the recording's guaranteed lifetime has expired
+                             if (r0) {
+                                if (r->Priority() < r0->Priority() || (r->Priority() == r0->Priority() && r->Start() < r0->Start()))
+                                   r0 = r; // in any case we delete the one with the lowest priority (or the older one in case of equal priorities)
+                                }
+                             else
+                                r0 = r;
                              }
-                          else
-                             r0 = r;
                           }
                        }
+                    r = Recordings.Next(r);
                     }
-                 r = Recordings.Next(r);
+              if (r0 && r0->Delete()) {
+                 Recordings.Del(r0);
+                 return;
                  }
-           if (r0 && r0->Delete()) {
-              Recordings.Del(r0);
-              return;
               }
+           // Unable to free disk space, but there's nothing we can do about that...
+           isyslog("...no old recording found, giving up");
            }
-        // Unable to free disk space, but there's nothing we can do about that...
-        isyslog("...no old recording found, giving up");
+        else
+           isyslog("...no deleted recording found, priority %d too low to trigger deleting an old recording", Priority);
         Skins.QueueMessage(mtWarning, tr("Low disk space!"), 5, -1);
         }
      LastFreeDiskCheck = time(NULL);
diff --git a/recording.h b/recording.h
index ff3119d..2b76762 100644
--- a/recording.h
+++ b/recording.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.h 2.46 2013/03/04 14:01:23 kls Exp $
+ * $Id: recording.h 3.0 2013/03/04 14:01:23 kls Exp $
  */
 
 #ifndef __RECORDING_H
diff --git a/remote.c b/remote.c
index f3d90c9..e886bf3 100644
--- a/remote.c
+++ b/remote.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remote.c 2.8 2013/02/03 15:44:55 kls Exp $
+ * $Id: remote.c 3.0 2013/02/03 15:44:55 kls Exp $
  */
 
 #include "remote.h"
diff --git a/remote.h b/remote.h
index d453b2f..3407c54 100644
--- a/remote.h
+++ b/remote.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remote.h 2.1 2013/02/03 14:34:56 kls Exp $
+ * $Id: remote.h 3.0 2013/02/03 14:34:56 kls Exp $
  */
 
 #ifndef __REMOTE_H
diff --git a/remux.c b/remux.c
index 587d7e5..3c07789 100644
--- a/remux.c
+++ b/remux.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remux.c 2.75 2013/03/03 10:37:58 kls Exp $
+ * $Id: remux.c 3.0 2013/03/03 10:37:58 kls Exp $
  */
 
 #include "remux.h"
diff --git a/remux.h b/remux.h
index 67eda4c..8a4b306 100644
--- a/remux.h
+++ b/remux.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: remux.h 2.37 2013/01/20 11:43:59 kls Exp $
+ * $Id: remux.h 3.0 2013/01/20 11:43:59 kls Exp $
  */
 
 #ifndef __REMUX_H
diff --git a/ringbuffer.c b/ringbuffer.c
index abe7899..e2921be 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -7,7 +7,7 @@
  * Parts of this file were inspired by the 'ringbuffy.c' from the
  * LinuxDVB driver (see linuxtv.org).
  *
- * $Id: ringbuffer.c 2.5 2012/09/22 11:26:49 kls Exp $
+ * $Id: ringbuffer.c 3.0 2012/09/22 11:26:49 kls Exp $
  */
 
 #include "ringbuffer.h"
diff --git a/ringbuffer.h b/ringbuffer.h
index 1fff611..a975742 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: ringbuffer.h 2.5 2013/02/16 15:20:37 kls Exp $
+ * $Id: ringbuffer.h 3.0 2013/02/16 15:20:37 kls Exp $
  */
 
 #ifndef __RINGBUFFER_H
diff --git a/runvdr.template b/runvdr.template
index 2f6fd87..63f2830 100755
--- a/runvdr.template
+++ b/runvdr.template
@@ -20,7 +20,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: runvdr.template 2.2 2011/04/17 12:34:30 kls Exp $
+# $Id: runvdr.template 3.0 2011/04/17 12:34:30 kls Exp $
 
 VDRPRG="./vdr"
 
diff --git a/sdt.c b/sdt.c
index 5f2502b..f79187e 100644
--- a/sdt.c
+++ b/sdt.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sdt.c 2.5 2010/05/16 14:23:21 kls Exp $
+ * $Id: sdt.c 3.0 2010/05/16 14:23:21 kls Exp $
  */
 
 #include "sdt.h"
diff --git a/sdt.h b/sdt.h
index 2566672..6b3f24f 100644
--- a/sdt.h
+++ b/sdt.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sdt.h 2.0 2004/01/05 14:30:14 kls Exp $
+ * $Id: sdt.h 3.0 2004/01/05 14:30:14 kls Exp $
  */
 
 #ifndef __SDT_H
diff --git a/sections.c b/sections.c
index 991499b..833639a 100644
--- a/sections.c
+++ b/sections.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sections.c 2.2 2012/10/04 12:21:59 kls Exp $
+ * $Id: sections.c 3.0 2012/10/04 12:21:59 kls Exp $
  */
 
 #include "sections.h"
diff --git a/sections.h b/sections.h
index 3b00c8b..7cb833c 100644
--- a/sections.h
+++ b/sections.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sections.h 2.0 2005/08/13 11:23:55 kls Exp $
+ * $Id: sections.h 3.0 2005/08/13 11:23:55 kls Exp $
  */
 
 #ifndef __SECTIONS_H
diff --git a/shutdown.c b/shutdown.c
index 445ed6f..0a36a15 100644
--- a/shutdown.c
+++ b/shutdown.c
@@ -6,7 +6,7 @@
  *
  * Original version written by Udo Richter <udo_richter at gmx.de>.
  *
- * $Id: shutdown.c 2.1 2013/02/18 10:33:26 kls Exp $
+ * $Id: shutdown.c 3.0 2013/02/18 10:33:26 kls Exp $
  */
 
 #include "shutdown.h"
diff --git a/shutdown.h b/shutdown.h
index bf2a2a4..5e4af29 100644
--- a/shutdown.h
+++ b/shutdown.h
@@ -6,7 +6,7 @@
  *
  * Original version written by Udo Richter <udo_richter at gmx.de>.
  *
- * $Id: shutdown.h 2.1 2013/02/18 10:35:27 kls Exp $
+ * $Id: shutdown.h 3.0 2013/02/18 10:35:27 kls Exp $
  */
 
 #ifndef __SHUTDOWN_H
diff --git a/skinclassic.c b/skinclassic.c
index b9919d8..fa38431 100644
--- a/skinclassic.c
+++ b/skinclassic.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinclassic.c 2.10 2013/03/03 15:26:09 kls Exp $
+ * $Id: skinclassic.c 3.0 2013/03/03 15:26:09 kls Exp $
  */
 
 #include "skinclassic.h"
diff --git a/skinclassic.h b/skinclassic.h
index 60878e4..005901b 100644
--- a/skinclassic.h
+++ b/skinclassic.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinclassic.h 2.0 2005/01/02 14:38:56 kls Exp $
+ * $Id: skinclassic.h 3.0 2005/01/02 14:38:56 kls Exp $
  */
 
 #ifndef __SKINCLASSIC_H
diff --git a/skinlcars.c b/skinlcars.c
index 3ed8225..23eafa1 100644
--- a/skinlcars.c
+++ b/skinlcars.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinlcars.c 2.21.1.1 2013/05/19 12:08:52 kls Exp $
+ * $Id: skinlcars.c 3.3 2013/08/18 13:45:36 kls Exp $
  */
 
 // "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures,
@@ -27,6 +27,7 @@
 #include "font.h"
 #include "menu.h"
 #include "osd.h"
+#include "positioner.h"
 #include "themes.h"
 #include "videodir.h"
 
@@ -299,6 +300,44 @@ static void DrawDeviceSignal(cOsd *Osd, const cDevice *Device, int x0, int y0, i
      }
 }
 
+static void DrawDevicePosition(cOsd *Osd, const cPositioner *Positioner, int x0, int y0, int x1, int y1, int &LastCurrent)
+{
+  int HorizonLeft = Positioner->HorizonLongitude(cPositioner::pdLeft);
+  int HorizonRight = Positioner->HorizonLongitude(cPositioner::pdRight);
+  int HardLimitLeft = cPositioner::NormalizeAngle(HorizonLeft - Positioner->HardLimitLongitude(cPositioner::pdLeft));
+  int HardLimitRight = cPositioner::NormalizeAngle(Positioner->HardLimitLongitude(cPositioner::pdRight) - HorizonRight);
+  int HorizonDelta = cPositioner::NormalizeAngle(HorizonLeft - HorizonRight);
+  int Current = cPositioner::NormalizeAngle(HorizonLeft - Positioner->CurrentLongitude());
+  int Target = cPositioner::NormalizeAngle(HorizonLeft - Positioner->TargetLongitude());
+  int d = (y1 - y0) / 2;
+  int w = x1 - x0 - 2 * d;
+  int l = max(x0 + d, x0 + d + w * HardLimitLeft / HorizonDelta);
+  int r = min(x1 - d, x1 - d - w * HardLimitRight / HorizonDelta) - 1;
+  int c = constrain(x0 + d + w * Current / HorizonDelta, l, r);
+  int t = constrain(x0 + d + w * Target / HorizonDelta, l, r);
+  if (c == LastCurrent)
+     return;
+  if (c > t)
+     swap(c, t);
+  tColor ColorRange, ColorMove;
+  if (TwoColors) {
+     ColorRange = Theme.Color(clrChannelFrameBg);
+     ColorMove = Theme.Color(clrBackground);
+     }
+  else {
+     ColorRange = Theme.Color(clrChannelFrameBg);
+     ColorMove = Theme.Color(clrDeviceBg);
+     }
+  Osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, Theme.Color(clrBackground));
+  Osd->DrawEllipse(l - d, y0, l, y1 - 1, ColorRange, 7);
+  Osd->DrawRectangle(l, y0, r, y1 - 1, ColorRange);
+  Osd->DrawEllipse(r, y0, r + d, y1 - 1, ColorRange, 5);
+  Osd->DrawEllipse(c - d, y0, c, y1 - 1, ColorMove, 7);
+  Osd->DrawRectangle(c, y0, t, y1 - 1, ColorMove);
+  Osd->DrawEllipse(t, y0, t + d, y1 - 1, ColorMove, 5);
+  LastCurrent = c;
+}
+
 // --- cSkinLCARSDisplayChannel ----------------------------------------------
 
 class cSkinLCARSDisplayChannel : public cSkinDisplayChannel {
@@ -317,6 +356,7 @@ private:
   bool initial;
   cString lastDate;
   int lastSeen;
+  int lastCurrentPosition;
   int lastDeviceNumber;
   cString lastDeviceType;
   cCamSlot *lastCamSlot;
@@ -336,6 +376,7 @@ public:
   virtual void SetChannel(const cChannel *Channel, int Number);
   virtual void SetEvents(const cEvent *Present, const cEvent *Following);
   virtual void SetMessage(eMessageType Type, const char *Text);
+  virtual void SetPositioner(const cPositioner *Positioner);
   virtual void Flush(void);
   };
 
@@ -352,6 +393,7 @@ cSkinLCARSDisplayChannel::cSkinLCARSDisplayChannel(bool WithInfo)
   initial = true;
   present = NULL;
   lastSeen = -1;
+  lastCurrentPosition = -1;
   lastDeviceNumber = -1;
   lastCamSlot = NULL;
   lastSignalStrength = -1;
@@ -458,6 +500,8 @@ void cSkinLCARSDisplayChannel::DrawTrack(void)
 
 void cSkinLCARSDisplayChannel::DrawSeen(int Current, int Total)
 {
+  if (lastCurrentPosition >= 0)
+     return; // to not interfere with SetPositioner()
   int Seen = (Total > 0) ? min(xc07 - xc06, int((xc07 - xc06) * double(Current) / Total)) : 0;
   if (initial || Seen != lastSeen) {
      int y0 = yc11 - ShowSeenExtent;
@@ -532,8 +576,13 @@ void cSkinLCARSDisplayChannel::SetChannel(const cChannel *Channel, int Number)
   osd->DrawText(xc00, yc00, ChNumber, Theme.Color(clrChannelFrameFg), frameColor, tallFont, xc02 - xc00, yc02 - yc00, taTop | taRight | taBorder);
   osd->DrawText(xc03, yc00, ChName, Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xi - xc03 - lineHeight, 0, taTop | taLeft);
   lastSignalDisplay = 0;
-  if (withInfo)
+  if (withInfo) {
+     if (Channel) {
+        int x = xc00 + (yc10 - yc09); // compensate for the arc
+        osd->DrawText(x, yc07, cSource::ToString(Channel->Source()), Theme.Color(clrChannelFrameFg), frameColor, cFont::GetFont(fontOsd), xc02 - x, yc10 - yc07, taTop | taRight | taBorder);
+        }
      DrawDevice();
+     }
 }
 
 void cSkinLCARSDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
@@ -587,6 +636,20 @@ void cSkinLCARSDisplayChannel::SetMessage(eMessageType Type, const char *Text)
      }
 }
 
+void cSkinLCARSDisplayChannel::SetPositioner(const cPositioner *Positioner)
+{
+  if (Positioner) {
+     int y0 = yc11 - ShowSeenExtent;
+     int y1 = yc11 + lineHeight / 2 - Gap / 2;
+     DrawDevicePosition(osd, Positioner, xc06, y0, xc07, y1, lastCurrentPosition);
+     }
+  else {
+     lastCurrentPosition = -1;
+     initial = true; // to have DrawSeen() refresh the progress bar
+     }
+  return;
+}
+
 void cSkinLCARSDisplayChannel::Flush(void)
 {
   if (withInfo) {
@@ -854,7 +917,7 @@ cSkinLCARSDisplayMenu::cSkinLCARSDisplayMenu(void)
   xb12 = xb08 + w;
   xb11 = xb12 - Gap;
   xb13 = xb12 + lineHeight / 2;
-  xb14 = xb13 + Gap;;
+  xb14 = xb13 + Gap;
 
   // The color buttons in the main menu:
   int r = lineHeight;
@@ -1345,6 +1408,8 @@ void cSkinLCARSDisplayMenu::DrawLive(const cChannel *Channel)
   if (initial || Channel != lastChannel) {
      osd->DrawText(xa00, yt00, itoa(Channel->Number()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), tallFont, xa02 - xa00, yt02 - yt00, taTop | taRight | taBorder);
      osd->DrawText(xa03, yt00, Channel->Name(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft);
+     int x = xa00 + (yc03 - yc02); // compensate for the arc
+     osd->DrawText(x, yc00, cSource::ToString(Channel->Source()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), cFont::GetFont(fontOsd), xa02 - x, yc03 - yc00, taTop | taRight | taBorder);
      lastChannel = Channel;
      DrawSeen(0, 0);
      }
diff --git a/skinlcars.h b/skinlcars.h
index 71117f6..abab018 100644
--- a/skinlcars.h
+++ b/skinlcars.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinlcars.h 2.1 2012/04/15 13:17:35 kls Exp $
+ * $Id: skinlcars.h 3.0 2012/04/15 13:17:35 kls Exp $
  */
 
 #ifndef __SKINLCARS_H
diff --git a/skins.c b/skins.c
index 5fb85a7..8d00e8d 100644
--- a/skins.c
+++ b/skins.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skins.c 2.10 2012/06/02 11:44:14 kls Exp $
+ * $Id: skins.c 3.1 2013/08/18 12:07:22 kls Exp $
  */
 
 #include "skins.h"
@@ -63,6 +63,22 @@ cSkinDisplay::~cSkinDisplay()
   current = NULL;
 }
 
+// --- cSkinDisplayChannel ---------------------------------------------------
+
+cSkinDisplayChannel::cSkinDisplayChannel(void)
+{
+  positioner = NULL;
+}
+
+void cSkinDisplayChannel::SetPositioner(const cPositioner *Positioner)
+{
+  if (positioner && Positioner != positioner)
+     SetMessage(mtInfo, NULL);
+  positioner = Positioner;
+  if (positioner)
+     SetMessage(mtInfo, cString::sprintf(tr("Moving dish to %.1f..."), double(positioner->TargetLongitude()) / 10));
+}
+
 // --- cSkinDisplayMenu ------------------------------------------------------
 
 cSkinDisplayMenu::cSkinDisplayMenu(void)
diff --git a/skins.h b/skins.h
index c9750b8..47a03fc 100644
--- a/skins.h
+++ b/skins.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skins.h 2.9 2012/12/21 11:09:13 kls Exp $
+ * $Id: skins.h 3.1 2013/08/21 10:29:10 kls Exp $
  */
 
 #ifndef __SKINS_H
@@ -14,6 +14,7 @@
 #include "epg.h"
 #include "keys.h"
 #include "osd.h"
+#include "positioner.h"
 #include "recording.h"
 #include "themes.h"
 #include "thread.h"
@@ -52,7 +53,10 @@ class cSkinDisplayChannel : public cSkinDisplay {
        ///< This class is used to display the current channel, together with
        ///< the present and following EPG event. How and to what extent this
        ///< is done is totally up to the derived class.
+private:
+  const cPositioner *positioner;
 public:
+  cSkinDisplayChannel(void);
   virtual void SetChannel(const cChannel *Channel, int Number) = 0;
        ///< Sets the current channel to Channel. If Number is not 0, the
        ///< user is in the process of entering a channel number, which must
@@ -65,6 +69,17 @@ public:
        ///< to determine, e.g., the colors for displaying the Text.
        ///< If Text is NULL, any previously displayed message must be removed, and
        ///< any previous contents overwritten by the message must be restored.
+  virtual void SetPositioner(const cPositioner *Positioner);
+       ///< Sets the Positioner used to move the satellite dish. The skin may use the
+       ///< data provided by Positioner to implement some form of progress display,
+       ///< since moving the dish may take a while. This function will only be called
+       ///< if the device receiving the current live channel actually uses a positioner,
+       ///< and it will be called with NULL once the dish has reached its target
+       ///< position (or the user switches to a channel that doesn't require positioning
+       ///< the dish). While the dish is moving, SetPositioner() is called repeatedly,
+       ///< so the skin has a chance to update the progress display.
+       ///< The default implementation calls SetMessage() with a text that indicates
+       ///< that the dish is being moved to a new position.
   /*TODO
   SetButtons
     Red    = Video options
diff --git a/skinsttng.c b/skinsttng.c
index 39a831a..6cde7cd 100644
--- a/skinsttng.c
+++ b/skinsttng.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinsttng.c 2.17 2013/03/03 15:29:28 kls Exp $
+ * $Id: skinsttng.c 3.0 2013/03/03 15:29:28 kls Exp $
  */
 
 // "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures
diff --git a/skinsttng.h b/skinsttng.h
index cef3b91..f29262d 100644
--- a/skinsttng.h
+++ b/skinsttng.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinsttng.h 2.0 2005/01/02 14:39:29 kls Exp $
+ * $Id: skinsttng.h 3.0 2005/01/02 14:39:29 kls Exp $
  */
 
 #ifndef __SKINSTTNG_H
diff --git a/sourceparams.c b/sourceparams.c
index 0431789..2f7b4e8 100644
--- a/sourceparams.c
+++ b/sourceparams.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sourceparams.c 1.2 2010/03/06 11:13:39 kls Exp $
+ * $Id: sourceparams.c 3.0 2010/03/06 11:13:39 kls Exp $
  */
 
 #include "sourceparams.h"
diff --git a/sourceparams.h b/sourceparams.h
index be04b56..9f98bd0 100644
--- a/sourceparams.h
+++ b/sourceparams.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sourceparams.h 1.1 2010/02/28 11:58:03 kls Exp $
+ * $Id: sourceparams.h 3.0 2010/02/28 11:58:03 kls Exp $
  */
 
 #ifndef __SOURCEPARAMS_H
diff --git a/sources.c b/sources.c
index 44bf7d0..ffaee98 100644
--- a/sources.c
+++ b/sources.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sources.c 2.2 2010/02/28 15:15:39 kls Exp $
+ * $Id: sources.c 3.4 2013/05/23 10:20:28 kls Exp $
  */
 
 #include "sources.h"
@@ -37,17 +37,29 @@ bool cSource::Parse(const char *s)
   return code != stNone && description && *description;
 }
 
+bool cSource::Matches(int Code1, int Code2)
+{
+  if (Code1 == (stSat | st_Any))
+     return IsSat(Code2);
+  return Code1 == Code2;
+}
+
+int cSource::Position(int Code)
+{
+  int n = (Code & st_Pos);
+  if (n > 0x00007FFF)
+     n |= 0xFFFF0000;
+  return n;
+}
+
 cString cSource::ToString(int Code)
 {
   char buffer[16];
   char *q = buffer;
   *q++ = (Code & st_Mask) >> 24;
-  int n = (Code & st_Pos);
-  if (n > 0x00007FFF)
-     n |= 0xFFFF0000;
-  if (n) {
+  if (int n = Position(Code)) {
      q += snprintf(q, sizeof(buffer) - 2, "%u.%u", abs(n) / 10, abs(n) % 10); // can't simply use "%g" here since the silly 'locale' messes up the decimal point
-     *q++ = (n < 0) ? 'E' : 'W';
+     *q++ = (n < 0) ? 'W' : 'E';
      }
   *q = 0;
   return buffer;
@@ -69,8 +81,8 @@ int cSource::FromString(const char *s)
                                      break;
                    case '.':         dot = true;
                                      break;
-                   case 'E':         neg = true; // fall through to 'W'
-                   case 'W':         if (!dot)
+                   case 'W':         neg = true; // fall through to 'E'
+                   case 'E':         if (!dot)
                                         pos *= 10;
                                      break;
                    default: esyslog("ERROR: unknown source character '%c'", *s);
@@ -84,7 +96,7 @@ int cSource::FromString(const char *s)
         return code;
         }
      else
-       esyslog("ERROR: unknown source key '%c'", *s);
+        esyslog("ERROR: unknown source key '%c'", *s);
      }
   return stNone;
 }
@@ -93,9 +105,9 @@ int cSource::FromData(eSourceType SourceType, int Position, bool East)
 {
   int code = SourceType;
   if (SourceType == stSat) {
-     if (East)
+     if (!East)
         Position = -Position;
-     code |= (Position & st_Pos);;
+     code |= (Position & st_Pos);
      }
   return code;
 }
diff --git a/sources.conf b/sources.conf
index c7f76d1..09ecdeb 100644
--- a/sources.conf
+++ b/sources.conf
@@ -179,6 +179,8 @@ S135W   AMC 10
 S137W   AMC 7
 S139W   AMC 8
 
+S360E   Any satellite
+
 # Cable
 
 C       DVB-C
diff --git a/sources.h b/sources.h
index 516a3ed..8c2fdfb 100644
--- a/sources.h
+++ b/sources.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: sources.h 2.4 2012/06/17 11:19:23 kls Exp $
+ * $Id: sources.h 3.2 2013/08/21 10:27:32 kls Exp $
  */
 
 #ifndef __SOURCES_H
@@ -22,6 +22,7 @@ public:
     stTerr  = ('T' << 24),
     st_Mask = 0xFF000000,
     st_Pos  = 0x0000FFFF,
+    st_Any  = 0x00000E10, // 3600 - special value indicating "any position"
     };
 private:
   int code;
@@ -31,8 +32,22 @@ public:
   cSource(char Source, const char *Description);
   ~cSource();
   int Code(void) const { return code; }
+  int Position(void) { return Position(code); }
+      ///< Returns the orbital position of the satellite in case this is a DVB-S
+      ///< source (zero otherwise). The returned value is in the range -1800...+1800,
+      ///< except for the special value 3600, which indicates "any position". This is
+      ///< used with positioners that can move the dish to any requested satellite
+      ///< within their range.
+      ///< A positive sign indicates a position east of Greenwich, while western
+      ///< positions have a negative sign. The absolute value is in "degrees * 10",
+      ///< which allows for a resolution of 1/10 of a degree.
   const char *Description(void) const { return description; }
   bool Parse(const char *s);
+  static bool Matches(int Code1, int Code2);
+      ///< Returns true if Code2 matches Code1. This is simply a check whether the
+      ///< two codes are equal, except for the special case that Code1 is stSat|st_Any,
+      ///< in which case it matches any Code2 that is stSat.
+  static int Position(int Code);
   static char ToChar(int Code) { return (Code & st_Mask) >> 24; }
   static cString ToString(int Code);
   static int FromString(const char *s);
diff --git a/spu.c b/spu.c
index 9e38eec..8394abf 100644
--- a/spu.c
+++ b/spu.c
@@ -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.c 2.0 2008/02/10 14:06:48 kls Exp $
+ * $Id: spu.c 3.0 2008/02/10 14:06:48 kls Exp $
  */
 
 #include "spu.h"
diff --git a/spu.h b/spu.h
index 3a8ab3e..8945b44 100644
--- a/spu.h
+++ b/spu.h
@@ -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 2.0 2006/04/17 12:48:55 kls Exp $
+ * $Id: spu.h 3.0 2006/04/17 12:48:55 kls Exp $
  */
 
 #ifndef __SPU_VDR_H
diff --git a/status.c b/status.c
index b0a6aba..835a0e1 100644
--- a/status.c
+++ b/status.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: status.c 2.1 2012/03/07 14:17:24 kls Exp $
+ * $Id: status.c 3.0 2012/03/07 14:17:24 kls Exp $
  */
 
 #include "status.h"
diff --git a/status.h b/status.h
index 6319165..983ee31 100644
--- a/status.h
+++ b/status.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: status.h 2.1 2012/03/07 14:16:57 kls Exp $
+ * $Id: status.h 3.0 2012/03/07 14:16:57 kls Exp $
  */
 
 #ifndef __STATUS_H
diff --git a/summary2info b/summary2info
index fc633f9..6baf4e7 100755
--- a/summary2info
+++ b/summary2info
@@ -10,7 +10,7 @@
 # See the main source file 'vdr.c' for copyright information and
 # how to reach the author.
 #
-# $Id: summary2info 2.1 2011/12/04 14:17:35 kls Exp $
+# $Id: summary2info 3.0 2011/12/04 14:17:35 kls Exp $
 
 $VideoDir = $ARGV[0] || die "please provide the name of the video directory\n";
 
diff --git a/svdrp.c b/svdrp.c
index 8a50dae..1cb87e4 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -10,7 +10,7 @@
  * and interact with the Video Disk Recorder - or write a full featured
  * graphical interface that sits on top of an SVDRP connection.
  *
- * $Id: svdrp.c 2.24 2013/02/17 13:18:01 kls Exp $
+ * $Id: svdrp.c 3.0 2013/02/17 13:18:01 kls Exp $
  */
 
 #include "svdrp.h"
diff --git a/svdrp.h b/svdrp.h
index 5ec9bc7..fcba1fb 100644
--- a/svdrp.h
+++ b/svdrp.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: svdrp.h 2.3 2012/04/26 10:30:06 kls Exp $
+ * $Id: svdrp.h 3.0 2012/04/26 10:30:06 kls Exp $
  */
 
 #ifndef __SVDRP_H
diff --git a/themes.c b/themes.c
index 88c7005..ccc2164 100644
--- a/themes.c
+++ b/themes.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: themes.c 2.2 2012/02/17 13:57:32 kls Exp $
+ * $Id: themes.c 3.0 2012/02/17 13:57:32 kls Exp $
  */
 
 #include "themes.h"
diff --git a/themes.h b/themes.h
index e51464f..1bb9cf1 100644
--- a/themes.h
+++ b/themes.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: themes.h 2.1 2012/10/07 11:11:43 kls Exp $
+ * $Id: themes.h 3.0 2012/10/07 11:11:43 kls Exp $
  */
 
 #ifndef __THEMES_H
diff --git a/thread.c b/thread.c
index 80fe588..080f4b7 100644
--- a/thread.c
+++ b/thread.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: thread.c 2.7.1.1 2013/04/11 08:59:26 kls Exp $
+ * $Id: thread.c 3.1 2013/04/10 14:37:37 kls Exp $
  */
 
 #include "thread.h"
diff --git a/thread.h b/thread.h
index d79e15a..1d10e68 100644
--- a/thread.h
+++ b/thread.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: thread.h 2.4 2013/02/16 15:20:44 kls Exp $
+ * $Id: thread.h 3.1 2013/04/11 08:47:31 kls Exp $
  */
 
 #ifndef __THREAD_H
@@ -182,7 +182,6 @@ public:
        ///< Returns true if any I/O throttling object is currently active.
   };
 
-
 // cPipe implements a pipe that closes all unnecessary file descriptors in
 // the child process.
 
diff --git a/timers.c b/timers.c
index 9a880e1..4d63e8c 100644
--- a/timers.c
+++ b/timers.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: timers.c 2.18 2013/03/29 15:37:16 kls Exp $
+ * $Id: timers.c 3.0 2013/03/29 15:37:16 kls Exp $
  */
 
 #include "timers.h"
diff --git a/timers.h b/timers.h
index 8910c10..4ce1cff 100644
--- a/timers.h
+++ b/timers.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: timers.h 2.7 2013/03/11 10:35:53 kls Exp $
+ * $Id: timers.h 3.0 2013/03/11 10:35:53 kls Exp $
  */
 
 #ifndef __TIMERS_H
diff --git a/tools.c b/tools.c
index ab46d02..d881827 100644
--- a/tools.c
+++ b/tools.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.c 2.29 2012/12/08 11:16:30 kls Exp $
+ * $Id: tools.c 3.1 2013/05/07 08:48:00 kls Exp $
  */
 
 #include "tools.h"
@@ -691,12 +691,12 @@ void cTimeMs::Set(int Ms)
   begin = Now() + Ms;
 }
 
-bool cTimeMs::TimedOut(void)
+bool cTimeMs::TimedOut(void) const
 {
   return Now() >= begin;
 }
 
-uint64_t cTimeMs::Elapsed(void)
+uint64_t cTimeMs::Elapsed(void) const
 {
   return Now() - begin;
 }
diff --git a/tools.h b/tools.h
index d6a778e..9cfd152 100644
--- a/tools.h
+++ b/tools.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.h 2.24 2013/02/17 13:18:06 kls Exp $
+ * $Id: tools.h 3.2 2013/08/23 10:32:51 kls Exp $
  */
 
 #ifndef __TOOLS_H
@@ -31,9 +31,9 @@ typedef unsigned char uchar;
 
 extern int SysLogLevel;
 
-#define esyslog(a...) void( (SysLogLevel > 0) ? syslog_with_tid(LOG_ERR, a) : void() )
-#define isyslog(a...) void( (SysLogLevel > 1) ? syslog_with_tid(LOG_ERR, a) : void() )
-#define dsyslog(a...) void( (SysLogLevel > 2) ? syslog_with_tid(LOG_ERR, a) : void() )
+#define esyslog(a...) void( (SysLogLevel > 0) ? syslog_with_tid(LOG_ERR,   a) : void() )
+#define isyslog(a...) void( (SysLogLevel > 1) ? syslog_with_tid(LOG_INFO,  a) : void() )
+#define dsyslog(a...) void( (SysLogLevel > 2) ? syslog_with_tid(LOG_DEBUG, a) : void() )
 
 #define LOG_ERROR         esyslog("ERROR (%s,%d): %m", __FILE__, __LINE__)
 #define LOG_ERROR_STR(s)  esyslog("ERROR (%s,%d): %s: %m", __FILE__, __LINE__, s)
@@ -64,6 +64,8 @@ void syslog_with_tid(int priority, const char *format, ...) __attribute__ ((form
 #define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF))
 int BCD2INT(int x);
 
+#define IsBitSet(v, b) ((v) & (1 << (b))) // checks if the bit at index b is set in v, where the least significant bit has index 0
+
 // Unfortunately there are no platform independent macros for unaligned
 // access, so we do it this way:
 
@@ -330,8 +332,8 @@ public:
       ///< time.
   static uint64_t Now(void);
   void Set(int Ms = 0);
-  bool TimedOut(void);
-  uint64_t Elapsed(void);
+  bool TimedOut(void) const;
+  uint64_t Elapsed(void) const;
   };
 
 class cReadLine {
diff --git a/transfer.c b/transfer.c
index 653e93b..eb07e82 100644
--- a/transfer.c
+++ b/transfer.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: transfer.c 2.8 2013/03/01 09:50:15 kls Exp $
+ * $Id: transfer.c 3.1 2013/08/22 12:33:02 kls Exp $
  */
 
 #include "transfer.h"
@@ -35,7 +35,7 @@ void cTransfer::Activate(bool On)
      cPlayer::Detach();
 }
 
-#define MAXRETRIES     5 // max. number of retries for a single TS packet
+#define MAXRETRIES    20 // max. number of retries for a single TS packet
 #define RETRYWAIT      5 // time (in ms) between two retries
 
 void cTransfer::Receive(uchar *Data, int Length)
diff --git a/transfer.h b/transfer.h
index 47a3398..ce74898 100644
--- a/transfer.h
+++ b/transfer.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: transfer.h 2.4 2013/03/01 09:49:46 kls Exp $
+ * $Id: transfer.h 3.0 2013/03/01 09:49:46 kls Exp $
  */
 
 #ifndef __TRANSFER_H
diff --git a/vdr.1 b/vdr.1
index 6c37cc0..52ab434 100644
--- a/vdr.1
+++ b/vdr.1
@@ -8,7 +8,7 @@
 .\" License as specified in the file COPYING that comes with the
 .\" vdr distribution.
 .\"
-.\" $Id: vdr.1 2.17 2013/03/15 10:44:54 kls Exp $
+.\" $Id: vdr.1 3.0 2013/03/15 10:44:54 kls Exp $
 .\"
 .TH vdr 1 "31 Mar 2013" "2.0" "Video Disk Recorder"
 .SH NAME
diff --git a/vdr.5 b/vdr.5
index b54b294..4c273a8 100644
--- a/vdr.5
+++ b/vdr.5
@@ -8,7 +8,7 @@
 .\" License as specified in the file COPYING that comes with the
 .\" vdr distribution.
 .\"
-.\" $Id: vdr.5 2.36 2013/03/29 10:25:56 kls Exp $
+.\" $Id: vdr.5 3.1 2013/08/11 13:50:42 kls Exp $
 .\"
 .TH vdr 5 "31 Mar 2013" "2.0" "Video Disk Recorder Files"
 .SH NAME
@@ -483,6 +483,7 @@ l l.
 \fBV\fR at voltage high (18V)
 \fBA\fR at mini A
 \fBB\fR at mini B
+\fBPn\fR at use positioner to move dish to satellite position n (or to the satellite's orbital position, if no position number is given)
 \fBSn\fR at Satellite channel routing code sequence for bank n follows
 \fBWnn\fR at wait nn milliseconds (nn may be any positive integer number)
 \fB[xx ...]\fR at hex code sequence (max. 6)
diff --git a/vdr.c b/vdr.c
index c63eeca..bf581a6 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
  *
  * The project's page is at http://www.tvdr.de
  *
- * $Id: vdr.c 2.57 2013/03/15 10:44:54 kls Exp $
+ * $Id: vdr.c 3.1 2013/06/10 14:28:43 kls Exp $
  */
 
 #include <getopt.h>
@@ -800,6 +800,11 @@ int main(int argc, char *argv[])
   if (AudioCommand)
      new cExternalAudio(AudioCommand);
 
+  // Positioner:
+
+  if (!cPositioner::GetPositioner()) // no plugin has created a positioner
+     new cDiseqcPositioner;
+
   // Channel:
 
   if (!cDevice::WaitForAllDevicesReady(DEVICEREADYTIMEOUT))
@@ -1400,6 +1405,7 @@ Exit:
      Setup.Save();
      }
   cDevice::Shutdown();
+  cPositioner::DestroyPositioner();
   EpgHandlers.Clear();
   PluginManager.Shutdown(true);
   cSchedules::Cleanup(true);
diff --git a/videodir.c b/videodir.c
index d39ab05..9ad31b6 100644
--- a/videodir.c
+++ b/videodir.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: videodir.c 2.4 2012/09/30 12:06:33 kls Exp $
+ * $Id: videodir.c 3.1 2013/08/23 12:28:06 kls Exp $
  */
 
 #include "videodir.h"
@@ -19,6 +19,8 @@
 #include "recording.h"
 #include "tools.h"
 
+//#define DEPRECATED_DISTRIBUTED_VIDEODIR // Code enclosed with this macro is deprecated and will be removed in a future version
+
 const char *VideoDirectory = VIDEODIR;
 
 void SetVideoDirectory(const char *Directory)
@@ -27,43 +29,60 @@ void SetVideoDirectory(const char *Directory)
 }
 
 class cVideoDirectory {
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
 private:
   char *name, *stored, *adjusted;
   int length, number, digits;
+#endif
 public:
   cVideoDirectory(void);
   ~cVideoDirectory();
   int FreeMB(int *UsedMB = NULL);
-  const char *Name(void) { return name ? name : VideoDirectory; }
+  const char *Name(void) { return
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
+                                  name ? name :
+#endif
+                                                VideoDirectory; }
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
   const char *Stored(void) { return stored; }
   int Length(void) { return length; }
   bool IsDistributed(void) { return name != NULL; }
   bool Next(void);
   void Store(void);
   const char *Adjust(const char *FileName);
+#endif
   };
 
 cVideoDirectory::cVideoDirectory(void)
 {
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
   length = strlen(VideoDirectory);
   name = (VideoDirectory[length - 1] == '0') ? strdup(VideoDirectory) : NULL;
   stored = adjusted = NULL;
   number = -1;
   digits = 0;
+#endif
 }
 
 cVideoDirectory::~cVideoDirectory()
 {
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
   free(name);
   free(stored);
   free(adjusted);
+#endif
 }
 
 int cVideoDirectory::FreeMB(int *UsedMB)
 {
-  return FreeDiskSpaceMB(name ? name : VideoDirectory, UsedMB);
+  return FreeDiskSpaceMB(
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
+                         name ? name :
+#endif
+                                       VideoDirectory, UsedMB);
 }
 
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
 bool cVideoDirectory::Next(void)
 {
   if (name) {
@@ -107,6 +126,7 @@ const char *cVideoDirectory::Adjust(const char *FileName)
      }
   return NULL;
 }
+#endif
 
 cUnbufferedFile *OpenVideoFile(const char *FileName, int Flags)
 {
@@ -118,6 +138,7 @@ cUnbufferedFile *OpenVideoFile(const char *FileName, int Flags)
      errno = ENOENT; // must set 'errno' - any ideas for a better value?
      return NULL;
      }
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
   // Are we going to create a new file?
   if ((Flags & O_CREAT) != 0) {
      cVideoDirectory Dir;
@@ -143,6 +164,7 @@ cUnbufferedFile *OpenVideoFile(const char *FileName, int Flags)
            }
         }
      }
+#endif
   cUnbufferedFile *File = cUnbufferedFile::Create(ActualFileName, Flags, DEFFILEMODE);
   if (ActualFileName != FileName)
      free((char *)ActualFileName);
@@ -176,6 +198,7 @@ bool RemoveVideoFile(const char *FileName)
 bool VideoFileSpaceAvailable(int SizeMB)
 {
   cVideoDirectory Dir;
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
   if (Dir.IsDistributed()) {
      if (Dir.FreeMB() >= SizeMB * 2) // base directory needs additional space
         return true;
@@ -185,6 +208,7 @@ bool VideoFileSpaceAvailable(int SizeMB)
            }
      return false;
      }
+#endif
   return Dir.FreeMB() >= SizeMB;
 }
 
@@ -193,11 +217,15 @@ int VideoDiskSpace(int *FreeMB, int *UsedMB)
   int free = 0, used = 0;
   int deleted = DeletedRecordings.TotalFileSizeMB();
   cVideoDirectory Dir;
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
   do {
+#endif
      int u;
      free += Dir.FreeMB(&u);
      used += u;
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
      } while (Dir.Next());
+#endif
   if (deleted > used)
      deleted = used; // let's not get beyond 100%
   free += deleted;
@@ -232,18 +260,26 @@ cString PrefixVideoFileName(const char *FileName, char Prefix)
 void RemoveEmptyVideoDirectories(const char *IgnoreFiles[])
 {
   cVideoDirectory Dir;
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
   do {
+#endif
      RemoveEmptyDirectories(Dir.Name(), false, IgnoreFiles);
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
      } while (Dir.Next());
+#endif
 }
 
 bool IsOnVideoDirectoryFileSystem(const char *FileName)
 {
   cVideoDirectory Dir;
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
   do {
+#endif
      if (EntriesOnSameFileSystem(Dir.Name(), FileName))
         return true;
+#ifdef DEPRECATED_DISTRIBUTED_VIDEODIR
      } while (Dir.Next());
+#endif
   return false;
 }
 
diff --git a/videodir.h b/videodir.h
index a25ac31..35c1a55 100644
--- a/videodir.h
+++ b/videodir.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: videodir.h 2.3 2012/09/30 11:01:15 kls Exp $
+ * $Id: videodir.h 3.0 2012/09/30 11:01:15 kls Exp $
  */
 
 #ifndef __VIDEODIR_H

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr.git



More information about the pkg-vdr-dvb-changes mailing list