From cd10b439d0465afa6bce38188a4e9d8a5e74d859 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Wed, 21 Aug 2013 11:02:52 +0200 Subject: [PATCH] Added basic support for positioners to control steerable satellite dishes --- CONTRIBUTORS | 4 ++ HISTORY | 28 +++++++- MANUAL | 22 ++++++ Makefile | 4 +- PLUGINS.html | 44 ++++++++++++ config.c | 20 +++++- config.h | 12 +++- device.c | 7 +- device.h | 8 ++- diseqc.c | 200 +++++++++++++++++++++++++++++++++++++++++++-------- diseqc.conf | 14 +++- diseqc.h | 43 ++++++++++- dvbdevice.c | 99 ++++++++++++++++++++----- dvbdevice.h | 3 +- menu.c | 30 ++++++-- menu.h | 3 +- menuitems.c | 52 ++++++++++++-- menuitems.h | 15 +++- osdbase.c | 4 +- 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 +++++++++++++++++++++++++++++++++++++++++++ skinlcars.c | 69 +++++++++++++++++- skins.c | 18 ++++- skins.h | 17 ++++- sources.c | 9 ++- sources.conf | 2 + sources.h | 12 +++- tools.c | 6 +- tools.h | 8 ++- vdr.5 | 3 +- vdr.c | 8 ++- 59 files changed, 1883 insertions(+), 116 deletions(-) create mode 100644 positioner.c create mode 100644 positioner.h diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ff1780ef..21d4ec10 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -2696,6 +2696,7 @@ Ales Jurik 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 for translating OSD texts to the Swedish language @@ -3155,3 +3156,6 @@ Jochen Dolze Dominique Dumont for reporting a crash in the LCARS skin's main menu in case there is no current channel + +Seppo Ingalsuo + for a patch that was used as a base for implementing support for positioners diff --git a/HISTORY b/HISTORY index 0c0c9e75..0cdc691d 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). @@ -7813,7 +7813,7 @@ Video Disk Recorder Revision History - Fixed a crash in the LCARS skin's main menu in case there is no current channel (reported by Dominique Dumont). -2013-05-19: Version 2.1.1 +2013-08-21: Version 2.1.1 - Fixed initializing cDevice::keepTracks. - Fixed an endless loop in cTextWrapper::Set() in case the given Width is smaller than @@ -7844,3 +7844,27 @@ Video Disk Recorder Revision History 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. diff --git a/MANUAL b/MANUAL index cce2b0a5..e698085d 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/Makefile b/Makefile index d24d08fd..0d990bb2 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/05/23 10:10:00 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 0141c563..454eae2d 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -99,6 +99,7 @@ structures and allows it to hook itself into specific areas to perform special a
  • Skins
  • Themes
  • Devices +
  • Positioners
  • Audio
  • Remote Control
  • Conditional Access @@ -2024,6 +2025,49 @@ new cMyDeviceHook; and shall not delete this object. It will be automatically deleted when the program ends. +
    +

    Positioners

    + +
    Now you see me - now you don't!

    + +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 diseqc.conf 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 cPositioner, as in + +

    +#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);
    +  };
    +

    + +See the implementation of cDiseqcPositioner in diseqc.c for details. +

    +You should create your derived positioner object in the +Start() function of your plugin. +Note that the object has to be created on the heap (using new), +and you shall not delete it at any point (it will be deleted automatically +when the program ends). +

    +

    Audio

    "The stereo effect may only be experienced if stereo equipment is used!"

    diff --git a/config.c b/config.c index 7a153cb1..591d2ceb 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 9324ebc1..6d1c0da4 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 3.1 2013/04/05 10:27:16 kls Exp $ + * $Id: config.h 3.2 2013/05/23 12:40:19 kls Exp $ */ #ifndef __CONFIG_H @@ -27,8 +27,8 @@ // 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/device.c b/device.c index b84fee02..7ff24edd 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 3.1 2013/04/05 10:05:33 kls Exp $ + * $Id: device.c 3.2 2013/06/01 11:34:11 kls Exp $ */ #include "device.h" @@ -665,6 +665,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 fd010d41..5c334490 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.1 2013/06/01 11:35:23 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" @@ -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 0db87616..86ee61fe 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 3.1 2013/05/02 09:30:33 kls Exp $ + * $Id: diseqc.c 3.2 2013/08/21 09:26:11 kls Exp $ */ #include "diseqc.h" #include +#include +#include #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) { - if (*s && s[strlen(s) - 1] == ':') { + return *s && s[strlen(s) - 1] == ':'; +} + +static bool ParseDeviceNumbers(const char *s) +{ + 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::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::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(); + if (!IsBitSet(p->Devices(), Device - 1)) continue; - } - if (Devices && !(Devices & (1 << 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 2895c43e..4ae1cfe3 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 6e9058c2..eef36a6a 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 { 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 { 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/dvbdevice.c b/dvbdevice.c index b2dd17ad..9504834d 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 3.1 2013/04/08 22:13:35 kls Exp $ + * $Id: dvbdevice.c 3.2 2013/08/17 13:52:05 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(); @@ -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 4c6d8487..7a54d8cf 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 3.1 2013/04/08 22:13:35 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/menu.c b/menu.c index dcfaecca..e466ae0f 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 3.2 2013/04/27 10:25:51 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 196c0385..db17f983 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 f7ec7761..4eea6bab 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 ffe99570..2a30b465 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/osdbase.c b/osdbase.c index fafa9c77..baadc0e6 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(item)) { - if (!MenuEditItem->DisplayHelp()) + if (!MenuEditItem->DisplayHelp(Current)) DisplayHelp(); else helpDisplayed = false; diff --git a/po/ar.po b/po/ar.po index 54c3f3c4..1676dcbe 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: \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 \n" "Language-Team: Arabic \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 89d65568..0362cd83 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: \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 \n" "Language-Team: Catalan \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 5409f089..2bd4a8e4 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: \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 \n" "Language-Team: Czech \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 4069a7b4..edd0f5f4 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: \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 \n" "Language-Team: Danish \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 0e24ab22..4cc8e844 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: \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 \n" "Language-Team: German \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 Lngengrad" + +msgid "South" +msgstr "Sd" + +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 zurckgesetzt" @@ -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 b61174e5..8df5b786 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: \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 \n" "Language-Team: Greek \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 fba8c21d..023871ec 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: \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 \n" "Language-Team: Spanish \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 333f0b0b..8539f17e 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: \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 \n" "Language-Team: Estonian \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 f44dd72f..84c50a63 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: \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 \n" "Language-Team: Finnish \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 6228d7f4..a4eda2fb 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: \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 \n" "Language-Team: French \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 3925422b..baafe9d5 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: \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 \n" "Language-Team: Croatian \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 e4f8594c..b3c17b0c 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: \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 \n" "Language-Team: Hungarian \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 281434c9..e579885f 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: \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 \n" "Language-Team: Italian \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 dba42240..34e273c7 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: \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 \n" "Language-Team: Lithuanian \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 b9f56a25..a398b3ca 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: \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 \n" "Language-Team: Macedonian \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 8766f344..e9b9a001 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: \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 \n" "Language-Team: Dutch \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 4f6668c6..a05410fa 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: \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 \n" "Language-Team: Norwegian Nynorsk \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 c11c6561..f240894f 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: \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 \n" "Language-Team: Polish \n" @@ -995,6 +995,33 @@ msgstr "Urz msgid "Setup.LNB$own" msgstr "Wasny" +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 ffd3fecb..7dde8c56 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: \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 \n" "Language-Team: Portuguese \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 3214a2e9..f49c4523 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: \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 \n" "Language-Team: Romanian \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 eecc89e6..78565601 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: \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 \n" "Language-Team: Russian \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 46dc3ae1..6e849b0b 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: \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 \n" "Language-Team: Slovak \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 "PREHRVA 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 842157ed..6e9ca323 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: \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 \n" "Language-Team: Slovenian \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 2968b913..12586f77 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: \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 \n" "Language-Team: Serbian \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 15a49ee7..58492c49 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: \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 \n" "Language-Team: Swedish \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 54956de1..d9201803 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: \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 Yolgeen \n" "Language-Team: Turkish \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 sfrland" @@ -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 7626d8db..829921d4 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: \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 \n" "Language-Team: Ukrainian \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 98e3f98b..8ba5e4dd 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: \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 \n" "Language-Team: Chinese (simplified) \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 00000000..7adcc735 --- /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 +#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 00000000..6e019ed6 --- /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/skinlcars.c b/skinlcars.c index 7201e6bf..23eafa10 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 3.2 2013/05/19 12:04:09 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) { @@ -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/skins.c b/skins.c index 5fb85a72..8d00e8d4 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 c9750b82..47a03fc8 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/sources.c b/sources.c index 780c1fdc..ffaee98a 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 3.3 2013/05/23 09:41:54 kls Exp $ + * $Id: sources.c 3.4 2013/05/23 10:20:28 kls Exp $ */ #include "sources.h" @@ -37,6 +37,13 @@ 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); diff --git a/sources.conf b/sources.conf index c7f76d1f..09ecdebe 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 e40b2b1d..8c2fdfb8 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 3.1 2013/04/11 10:23:16 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; @@ -33,12 +34,19 @@ public: 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. + ///< 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); diff --git a/tools.c b/tools.c index 57f10283..f690fb8a 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/07 09:00:00 kls Exp $ + * $Id: tools.c 3.1 2013/05/23 10:10: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 d6a778e6..9618efa2 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.1 2013/08/21 08:49:48 kls Exp $ */ #ifndef __TOOLS_H @@ -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/vdr.5 b/vdr.5 index b54b2945..4c273a87 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@voltage high (18V) \fBA\fR@mini A \fBB\fR@mini B +\fBPn\fR@use positioner to move dish to satellite position n (or to the satellite's orbital position, if no position number is given) \fBSn\fR@Satellite channel routing code sequence for bank n follows \fBWnn\fR@wait nn milliseconds (nn may be any positive integer number) \fB[xx ...]\fR@hex code sequence (max. 6) diff --git a/vdr.c b/vdr.c index c63eecaa..bf581a6e 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 @@ -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);