From patchwork Thu Dec 8 11:52:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ales Jurik X-Patchwork-Id: 12911 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1RYcZd-0004gN-Np for vdr@linuxtv.org; Thu, 08 Dec 2011 12:55:38 +0100 X-tubIT-Incoming-IP: 194.228.2.86 Received: from smtp-out1.iol.cz ([194.228.2.86]) by mail.tu-berlin.de (exim-4.75/mailfrontend-4) with esmtp for id 1RYcZd-0002nN-Az; Thu, 08 Dec 2011 12:55:37 +0100 Received: from antivir3.iol.cz (antivir3.iplanet.iol.cz [192.168.30.206]) by smtp-out1.iol.cz (Postfix) with ESMTP id E151438E49C; Thu, 8 Dec 2011 12:55:35 +0100 (CET) Received: from localhost (antivir3.iol.cz [127.0.0.1]) by antivir3.iol.cz (Postfix) with ESMTP id D52E54AC035; Thu, 8 Dec 2011 12:55:35 +0100 (CET) X-Virus-Scanned: amavisd-new at iol.cz Received: from antivir3.iol.cz ([127.0.0.1]) by localhost (antivir3.iol.cz [127.0.0.1]) (amavisd-new, port 10124) with LMTP id oNdtm87+4DJ0; Thu, 8 Dec 2011 12:55:35 +0100 (CET) Received: from port3.iol.cz (unknown [192.168.30.93]) by antivir3.iol.cz (Postfix) with ESMTP id B256B4AC02E; Thu, 8 Dec 2011 12:55:35 +0100 (CET) X-SBRS: None X-SBRS-none: None X-RECVLIST: MTA-OUT-QUICK X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: As4TAJSk4E5YZ3gv/2dsb2JhbAAMN4V/oiaFZVEpFBYYAwIBAgFLAQwIAQG/Eos7BI4ShlmFa4w8 Received: from unknown (HELO [10.0.1.101]) ([88.103.120.47]) by port3.iol.cz with ESMTP; 08 Dec 2011 12:55:34 +0100 Message-ID: <4EE0A4FD.2020603@quick.cz> Date: Thu, 08 Dec 2011 12:52:29 +0100 From: Ales Jurik User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:8.0) Gecko/20111204 Thunderbird/8.0 MIME-Version: 1.0 To: VDR Mailing List , Seppo Ingalsuo X-PMX-Version: 5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2011.12.8.114215 X-PMX-Spam: Gauge=XIIII, Probability=14%, Report=' OBFUSCATING_HTML 1.2, MIME_TEXT_ONLY_MP_MIXED 0.05, MSGID_ADDED_BY_MTA 0.05, BODYTEXTP_SIZE_3000_LESS 0, BODY_SIZE_10000_PLUS 0, NO_URI_FOUND 0, __BAT_BOUNDARY 0, __CT 0, __CTYPE_HAS_BOUNDARY 0, __CTYPE_MULTIPART 0, __CTYPE_MULTIPART_MIXED 0, __HAS_MSGID 0, __INT_PROD_MOTORBIKE 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __MOZILLA_MSGID 0, __SANE_MSGID 0, __TO_MALFORMED_2 0, __USER_AGENT 0' X-LSpam-Score: -6.9 (------) X-LSpam-Report: No, score=-6.9 required=5.0 tests=BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_HI=-5 autolearn=ham Subject: [vdr] [PATCH] GOTOXX patch for vdr-1.7.22 X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.13 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Dec 2011 11:55:38 -0000 Status: O X-Status: X-Keywords: X-UID: 25451 Hi all, here is patch for using motor with vdr-1.7.22. As the diseqc subsystem changed quite a lot in 1.7.22 please report any problem. I'm using/testing it together with vtuner devices (NessieDVB) and cascade of diseqc switches: 1. DVB device: vtuner(PC) <-> LAN <-> NessieDVB <-> motor <-> uncomm.switch <-> comm. switch) 2. DVB device: vtuner(PC) <-> LAN <-> NessieDVB <-> uncomm.switch <-> comm. switch) I'm using it together with VDR capability of dedicated and undedicated sources to some cards and it works for me without problems. I do not have possibility to test it together with real DVB cards inside PC, so any remarks are welcomed. My diseqc.conf looks like: # ONLY SWITCHES 1 2: S19.2E 11700 V 9750 t v W30 [E0 10 39 F0] W30 [E0 10 38 F0] W30 t S19.2E 99999 V 10600 t v W30 [E0 10 39 F0] W30 [E0 10 38 F1] W30 T S19.2E 11700 H 9750 t V W30 [E0 10 39 F0] W30 [E0 10 38 F2] W30 t S19.2E 99999 H 10600 t V W30 [E0 10 39 F0] W30 [E0 10 38 F3] W30 T S13.0E 11700 V 9750 t v W30 [E0 10 39 F0] W30 [E0 10 38 F4] W30 t S13.0E 99999 V 10600 t v W30 [E0 10 39 F0] W30 [E0 10 38 F5] W30 T S13.0E 11700 H 9750 t V W30 [E0 10 39 F0] W30 [E0 10 38 F6] W30 t S13.0E 99999 H 10600 t V W30 [E0 10 39 F0] W30 [E0 10 38 F7] W30 T .... # MOTOR + SWITCHES 1: S1.0W 11700 V 9750 t V G [E0 10 39 F1] v W30 [E0 10 38 FC] W30 v t S1.0W 99999 V 10600 t V G [E0 10 39 F1] v W30 [E0 10 38 FD] W30 v T S1.0W 11700 H 9750 t V G [E0 10 39 F1] V W30 [E0 10 38 FE] W30 V t S1.0W 99999 H 10600 t V G [E0 10 39 F1] V W30 [E0 10 38 FF] W30 V T S9.0E 11700 V 9750 t V G [E0 10 39 F1] v W30 [E0 10 38 FC] W30 v t S9.0E 99999 V 10600 t V G [E0 10 39 F1] v W30 [E0 10 38 FD] W30 v T S9.0E 11700 H 9750 t V G [E0 10 39 F1] V W30 [E0 10 38 FE] W30 V t S9.0E 99999 H 10600 t V G [E0 10 39 F1] V W30 [E0 10 38 FF] W30 V T .... Enjoy, Ales diff -rupN vdr-1.7.22//config.c vdr-1.7.22_gotoxx_patched//config.c --- vdr-1.7.22//config.c 2011-12-03 16:21:30.000000000 +0100 +++ vdr-1.7.22_gotoxx_patched//config.c 2011-12-08 12:08:20.482922647 +0100 @@ -389,6 +389,12 @@ cSetup::cSetup(void) LnbFrequLo = 9750; LnbFrequHi = 10600; DiSEqC = 0; + UseGotox = 0; + GotoxSpeed = 100; + GotoxRepeat = 0; + GotoxSN = 0; GotoxLat = 613; GotoxEW = 1; GotoxLong = 236; // Somewhere at Tampere, Finland :^) + GotoxMaxSwing = 60; + GotoxPrevSource = 0; SetSystemTime = 0; TimeSource = 0; TimeTransponder = 0; @@ -583,6 +589,15 @@ bool cSetup::Parse(const char *Name, con 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, "UseGotox")) UseGotox = atoi(Value); + else if (!strcasecmp(Name, "GotoxSpeed")) GotoxSpeed = atoi(Value); + else if (!strcasecmp(Name, "GotoxRepeat")) GotoxRepeat = atoi(Value); + else if (!strcasecmp(Name, "GotoxSN")) GotoxSN = atoi(Value); + else if (!strcasecmp(Name, "GotoxLat")) GotoxLat = atoi(Value); + else if (!strcasecmp(Name, "GotoxEW")) GotoxEW = atoi(Value); + else if (!strcasecmp(Name, "GotoxLong")) GotoxLong = atoi(Value); + else if (!strcasecmp(Name, "GotoxMaxSwing")) GotoxMaxSwing = atoi(Value); + else if (!strcasecmp(Name, "GotoxPrevSource")) GotoxPrevSource = 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); @@ -680,6 +695,15 @@ bool cSetup::Save(void) Store("LnbFrequLo", LnbFrequLo); Store("LnbFrequHi", LnbFrequHi); Store("DiSEqC", DiSEqC); + Store("UseGotox", UseGotox); + Store("GotoxSpeed", GotoxSpeed); + Store("GotoxRepeat", GotoxRepeat); + Store("GotoxSN", GotoxSN); + Store("GotoxLat", GotoxLat); + Store("GotoxEW", GotoxEW); + Store("GotoxLong", GotoxLong); + Store("GotoxMaxSwing", GotoxMaxSwing); + Store("GotoxPrevSource", GotoxPrevSource); Store("SetSystemTime", SetSystemTime); Store("TimeSource", cSource::ToString(TimeSource)); Store("TimeTransponder", TimeTransponder); diff -rupN vdr-1.7.22//config.h vdr-1.7.22_gotoxx_patched//config.h --- vdr-1.7.22//config.h 2011-12-03 15:19:52.000000000 +0100 +++ vdr-1.7.22_gotoxx_patched//config.h 2011-12-08 12:08:20.494922647 +0100 @@ -248,6 +248,15 @@ public: int LnbFrequLo; int LnbFrequHi; int DiSEqC; + int GotoxRepeat; + int GotoxSN; + int GotoxEW; + int GotoxSpeed; + int GotoxLat; + int GotoxLong; + int GotoxMaxSwing; + int UseGotox; + int GotoxPrevSource; int SetSystemTime; int TimeSource; int TimeTransponder; diff -rupN vdr-1.7.22//diseqc.c vdr-1.7.22_gotoxx_patched//diseqc.c --- vdr-1.7.22//diseqc.c 2011-09-17 16:13:31.000000000 +0200 +++ vdr-1.7.22_gotoxx_patched//diseqc.c 2011-12-08 12:08:20.495922647 +0100 @@ -250,6 +250,7 @@ cDiseqc::eDiseqcActions cDiseqc::Execute case 'V': return daVoltage18; case 'A': return daMiniA; case 'B': return daMiniB; + case 'G': return daGotoX; case 'W': *CurrentAction = Wait(*CurrentAction); break; case 'S': *CurrentAction = GetScrBank(*CurrentAction); break; case '[': *CurrentAction = GetCodes(*CurrentAction, Codes, MaxCodes); @@ -267,6 +268,22 @@ cDiseqc::eDiseqcActions cDiseqc::Execute return daNone; } +cDiseqc::eDiseqcActions cDiseqc::TestForGotoXX(const char **CurrentAction) const +{ + if (!*CurrentAction) + *CurrentAction = commands; + while (*CurrentAction && **CurrentAction) { + switch (*(*CurrentAction)++) { + case ' ': break; + case 'G': return daGotoX; + default: return daNone; + } + } + return daNone; +} + + + // --- cDiseqcs -------------------------------------------------------------- cDiseqcs Diseqcs; diff -rupN vdr-1.7.22//diseqc.h vdr-1.7.22_gotoxx_patched//diseqc.h --- vdr-1.7.22//diseqc.h 2011-09-17 15:15:17.000000000 +0200 +++ vdr-1.7.22_gotoxx_patched//diseqc.h 2011-12-08 12:08:20.495922647 +0100 @@ -50,6 +50,7 @@ public: daVoltage18, daMiniA, daMiniB, + daGotoX, daScr, daCodes, }; @@ -88,6 +89,7 @@ public: ///< be a pointer returned from a previous call to cDiseqcs::Get(). ///< 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). + eDiseqcActions TestForGotoXX(const char **CurrentAction) const; int Devices(void) const { return devices; } int Source(void) const { return source; } int Slof(void) const { return slof; } diff -rupN vdr-1.7.22//dvbdevice.c vdr-1.7.22_gotoxx_patched//dvbdevice.c --- vdr-1.7.22//dvbdevice.c 2011-12-03 16:24:27.000000000 +0100 +++ vdr-1.7.22_gotoxx_patched//dvbdevice.c 2011-12-08 12:10:21.273920511 +0100 @@ -15,9 +15,11 @@ #include #include #include +#include #include "channels.h" #include "diseqc.h" #include "dvbci.h" +#include "skins.h" #include "menuitems.h" #include "sourceparams.h" @@ -271,6 +273,7 @@ private: fe_delivery_system frontendType; cChannel channel; const cDiseqc *lastDiseqc; + int lastSource; const cScr *scr; eTunerStatus tunerStatus; cMutex mutex; @@ -283,6 +286,7 @@ private: void ClearEventQueue(void) const; bool GetFrontendStatus(fe_status_t &Status) const; void ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency); + bool TestDiseqcForGotoXX(const cDiseqc *Diseqc); void ResetToneAndVoltage(void); bool SetFrontend(void); virtual void Action(void); @@ -316,6 +320,7 @@ cDvbTuner::cDvbTuner(const cDvbDevice *D lockTimeout = 0; lastTimeoutReport = 0; lastDiseqc = NULL; + lastSource = 0; scr = NULL; tunerStatus = tsIdle; bondedTuner = NULL; @@ -455,6 +460,97 @@ bool cDvbTuner::IsTunedTo(const cChannel return strcmp(channel.Parameters(), Channel->Parameters()) == 0; } +void HandleGotox(int fd_frontend, int new_source) +{ + + int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E }; + int satlong; + int satprev; + float waitseconds = 0; + float waitmaximum = 60; + + if (Setup.UseGotox == 0) + return; + + // Check if zapped into new source position? + if (new_source != Setup.GotoxPrevSource) { + if ((new_source & 0xFF000000) != 0x53000000) + return; // Fail, not S type source + satlong = (new_source & 0x00000FFFF); + satprev = (Setup.GotoxPrevSource & 0x0000FFFF); + if (new_source & 0x00008000) { + satlong ^= 0x0000FFFF; satlong++; satlong *= (-1); + } + if (Setup.GotoxPrevSource & 0x00008000) { + satprev ^= 0x0000FFFF; satprev++; satprev *= (-1); + } + if (Setup.GotoxSpeed > 0) { + waitseconds = fabs(satlong-satprev)/(float)(Setup.GotoxSpeed); + waitmaximum = 10*(float)(Setup.GotoxMaxSwing)/(float)(Setup.GotoxSpeed); + if (waitseconds < 0.0) waitseconds = 0.0; // Should not happen but ... + if (waitseconds > waitmaximum) waitseconds = 2 + waitmaximum; // Limit wait time to +2s over dish max. move + } + int Long=Setup.GotoxEW ? -Setup.GotoxLong : Setup.GotoxLong; + int Lat=Setup.GotoxSN ? -Setup.GotoxLat : Setup.GotoxLat; + double azimuth=M_PI+atan(tan((satlong-Long)*M_PI/1800)/sin(Lat*M_PI/1800)); + double x=acos(cos((satlong-Long)*M_PI/1800)*cos(Lat*M_PI/1800)); + double elevation=atan((cos(x)-0.1513)/sin(x)); + double SatHourangle=180+atan((-cos(elevation)*sin(azimuth))/(sin(elevation)*cos(Lat*M_PI/1800) + -cos(elevation)*sin(Lat*M_PI/1800)*cos(azimuth)))*180/M_PI; + int tmp=(int)(fabs(180-SatHourangle)*10); + tmp=(tmp/10)*0x10 + gotoXTable[ tmp % 10 ]; + int p2=(tmp%0x0100); + int p1=(tmp/0x0100); + if (SatHourangle < 180) + p1 |= 0xe0; + else + p1 |= 0xd0; + + dsyslog("DiSEqC GotoX %d (%d) -> %d (%d), wait time %4.1fs", + satprev, Setup.GotoxPrevSource, satlong, new_source, waitseconds); + +#if 1 + // Set high LNB voltage and tone off, then wait > 15ms + CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); + CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); + cCondWait::SleepMs(20); + + // Send 1st GotoX command, then wait > 15ms + uchar gotox_bytes[5] = { 0xe0, 0x31, 0x6e, p1, p2}; + struct dvb_diseqc_master_cmd gotox_cmd; + memcpy(gotox_cmd.msg, gotox_bytes, 5); + gotox_cmd.msg_len = 5; + CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd)); + cCondWait::SleepMs(20); + + // Send repeated GotoX command, then wait > 15ms + if (Setup.GotoxRepeat) { + gotox_bytes[0] = 0xe1; + memcpy(gotox_cmd.msg, gotox_bytes, 5); + CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd)); + cCondWait::SleepMs(20); + } + + { + char mess_move[60]; + snprintf(mess_move,sizeof(mess_move),"Moving dish to %d.%d%s - %ds", \ + (new_source & 0x0800)?-satlong/10:satlong/10, \ + (new_source & 0x0800)?-satlong%10:satlong%10, \ + (new_source & 0x0800)?"E":"W", (int)waitseconds); + // Wait for dish movement and display message approx. for that time + Skins.QueueMessage(mtWarning, mess_move, int(1 + waitseconds - Setup.ChannelInfoTime), 0); + while (waitseconds > 0.0) { + cCondWait::SleepMs(100); // 100ms + waitseconds = waitseconds - 100e-3; + } + } +#endif + + Setup.GotoxPrevSource = new_source; + dsyslog("DiSEqC GotoX done."); + } +} + void cDvbTuner::SetChannel(const cChannel *Channel) { if (Channel) { @@ -648,6 +744,7 @@ void cDvbTuner::ExecuteDiseqc(const cDis 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::daGotoX: HandleGotox(fd_frontend, channel.Source()); break; case cDiseqc::daCodes: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break; default: esyslog("ERROR: unknown diseqc command %d", da); } @@ -656,6 +753,21 @@ void cDvbTuner::ExecuteDiseqc(const cDis ResetToneAndVoltage(); // makes sure we don't block the bus! } +bool cDvbTuner::TestDiseqcForGotoXX(const cDiseqc *Diseqc) +{ + struct dvb_diseqc_master_cmd cmd; + const char *CurrentAction = NULL; + for (;;) { + cmd.msg_len = sizeof(cmd.msg); + cDiseqc::eDiseqcActions da = Diseqc->TestForGotoXX(&CurrentAction); + if (da == cDiseqc::daNone) + break; + if (da == cDiseqc::daGotoX) + return true; + } + return false; +} + void cDvbTuner::ResetToneAndVoltage(void) { CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); @@ -691,7 +803,8 @@ 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() || \ + ((TestDiseqcForGotoXX(diseqc) && (channel.Source() != lastSource )))) { if (GetBondedMaster() == this) { ExecuteDiseqc(diseqc, &frequency); if (frequency == 0) @@ -700,6 +813,7 @@ bool cDvbTuner::SetFrontend(void) else ResetToneAndVoltage(); lastDiseqc = diseqc; + lastSource = channel.Source(); } } else { @@ -708,6 +822,10 @@ bool cDvbTuner::SetFrontend(void) } } else { + // Send GotoX DiSEqC command if activated in vdr setup. Then wait with high LNB voltage + // estimated time for dish movement + HandleGotox(fd_frontend, channel.Source()); + int tone = SEC_TONE_OFF; if (frequency < (unsigned int)Setup.LnbSLOF) { frequency -= Setup.LnbFrequLo; @@ -824,6 +942,7 @@ void cDvbTuner::Action(void) 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); @@ -837,6 +956,7 @@ void cDvbTuner::Action(void) if (Status & FE_REINIT) { tunerStatus = tsSet; lastDiseqc = NULL; + lastSource = 0; isyslog("frontend %d/%d was reinitialized", adapter, frontend); lastTimeoutReport = 0; continue; diff -rupN vdr-1.7.22//menu.c vdr-1.7.22_gotoxx_patched//menu.c --- vdr-1.7.22//menu.c 2011-12-04 15:52:38.000000000 +0100 +++ vdr-1.7.22_gotoxx_patched//menu.c 2011-12-08 12:08:20.499922647 +0100 @@ -2925,6 +2925,15 @@ void cMenuSetupLNB::Setup(void) } } + Add(new cMenuEditBoolItem(tr("Setup.LNB$Use GotoX dish positioning"), &data.UseGotox)); + if (data.UseGotox) { + Add(new cMenuEditBoolItem(tr("Setup.LNB$Repeat GotoX commands"), &data.GotoxRepeat)); + Add(new cMenuEditIntpItem(tr("Setup.LNB$Latitude"), &data.GotoxLat,0,900,&data.GotoxSN,tr("North"),tr("South"))); + Add(new cMenuEditIntpItem(tr("Setup.LNB$Longitude"), &data.GotoxLong,0,1800,&data.GotoxEW,tr("West"),tr("East"))); + Add(new cMenuEditIntItem(tr("Setup.LNB$GotoxMaxSwing"), &data.GotoxMaxSwing,0,180)); + Add(new cMenuEditIntdItem(tr("Setup.LNB$Rotor speed (deg/s)"), &data.GotoxSpeed, 1, 100)); + } + SetCurrent(Get(current)); Display(); } @@ -2932,6 +2941,7 @@ void cMenuSetupLNB::Setup(void) eOSState cMenuSetupLNB::ProcessKey(eKeys Key) { int oldDiSEqC = data.DiSEqC; + int oldUseGotox = data.UseGotox; bool DeviceBondingsChanged = false; if (Key == kOk) { cString NewDeviceBondings = satCableNumbers.ToString(); @@ -2944,6 +2954,10 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys Setup(); else if (DeviceBondingsChanged) cDvbDevice::BondDevices(data.DeviceBondings); + + if (Key != kNone && data.UseGotox != oldUseGotox) + Setup(); + return state; } diff -rupN vdr-1.7.22//menuitems.c vdr-1.7.22_gotoxx_patched//menuitems.c --- vdr-1.7.22//menuitems.c 2011-08-12 15:19:40.000000000 +0200 +++ vdr-1.7.22_gotoxx_patched//menuitems.c 2011-12-08 12:08:20.501922647 +0100 @@ -1132,3 +1132,122 @@ void cMenuSetupPage::SetupStore(const ch if (plugin) plugin->SetupStore(Name, Value); } + +// cMenuEditIntpItem & cMenuEditIntdItem for GotoX function + +void cMenuEditIntpItem::Set(void) +{ + char buf[16]; + snprintf(buf, sizeof(buf), "%d.%d %s", *value/10, *value % 10, *value2 ? trueString : falseString); + SetValue(buf); +} + +void cMenuEditIntdItem::Set(void) +{ + char buf[16]; + snprintf(buf, sizeof(buf), "%d.%d", *value/10, *value % 10); + SetValue(buf); +} + + +cMenuEditIntpItem::cMenuEditIntpItem(const char *Name, int *Value, int Min, int Max,int *Value2, const char *FalseString,const char *TrueString):cMenuEditIntItem(Name, Value, Min, Max) +{ + value = Value; + value2= Value2; + trueString = TrueString; + falseString = FalseString; + min = Min; + max = Max; + Set(); +} + +cMenuEditIntdItem::cMenuEditIntdItem(const char *Name, int *Value, int Min, int Max):cMenuEditIntItem(Name, Value, Min, Max) +{ + value = Value; + min = Min; + max = Max; + Set(); +} + +eOSState cMenuEditIntpItem::ProcessKey(eKeys Key) +{ + eOSState state = cMenuEditItem::ProcessKey(Key); + if (state == osUnknown) + { + int newValue = *value; + int newValue2= *value2; + Key = NORMALKEY(Key); + switch (Key) { + case kNone : break; + case k0...k9: + if (fresh) + { + *value = 0; + fresh = false; + } + newValue = *value * 10 + (Key - k0); + break; + case kLeft : + newValue2 = 0; + fresh = true; + break; + case kRight : + newValue2 = 1; + fresh = true; + break; + default : + if (*value < min) { *value = min; Set(); } + if (*value > max) { *value = max; Set(); } + return state; + } + if ((!fresh || min <= newValue) && newValue <= max) + { + *value = newValue; + *value2 = newValue2; + Set(); + } + state = osContinue; + } + return state; +} + +eOSState cMenuEditIntdItem::ProcessKey(eKeys Key) +{ + eOSState state = cMenuEditItem::ProcessKey(Key); + if (state == osUnknown) + { + int newValue = *value; + Key = NORMALKEY(Key); + switch (Key) { + case kNone : break; + case k0...k9: + if (fresh) + { + *value = 0; + fresh = false; + } + newValue = *value * 10 + (Key - k0); + break; + case kLeft : + newValue = *value - 1; + fresh = true; + break; + case kRight : + newValue = *value + 1; + fresh = true; + break; + default : + if (*value < min) { *value = min; Set(); } + if (*value > max) { *value = max; Set(); } + return state; + } + if ((!fresh || min <= newValue) && newValue <= max) + { + *value = newValue; + Set(); + } + state = osContinue; + } + return state; +} + diff -rupN vdr-1.7.22//menuitems.h vdr-1.7.22_gotoxx_patched//menuitems.h --- vdr-1.7.22//menuitems.h 2011-06-13 15:46:03.000000000 +0200 +++ vdr-1.7.22_gotoxx_patched//menuitems.h 2011-12-08 12:08:20.502922647 +0100 @@ -204,4 +204,22 @@ public: void SetPlugin(cPlugin *Plugin); }; +class cMenuEditIntpItem : public cMenuEditIntItem { +protected: + virtual void Set(void); + const char *falseString, *trueString; + int *value2; +public: + cMenuEditIntpItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX, int *Value2=0, const char *FalseString = "", const char *TrueSting = NULL); + virtual eOSState ProcessKey(eKeys Key); +}; + +class cMenuEditIntdItem : public cMenuEditIntItem { +protected: + virtual void Set(void); +public: + cMenuEditIntdItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX); + virtual eOSState ProcessKey(eKeys Key); +}; + #endif //__MENUITEMS_H