diff options
| author | root <root@elwms02.(none)> | 2010-04-06 17:58:16 +0200 |
|---|---|---|
| committer | root <root@elwms02.(none)> | 2010-04-06 17:58:16 +0200 |
| commit | b0e043bce24d58896dd6bbec46fc7f5fb8bec595 (patch) | |
| tree | 3dab97cfc9217fcf91e0c7b0bc7bdd75cc833e94 /vdr/extensions | |
| parent | 0e7005fcc7483c01aa102fbea358c5ac65a48d62 (diff) | |
| download | x-vdr-b0e043bce24d58896dd6bbec46fc7f5fb8bec595.tar.gz x-vdr-b0e043bce24d58896dd6bbec46fc7f5fb8bec595.tar.bz2 | |
Update auf VDR 1.7.14
Diffstat (limited to 'vdr/extensions')
| -rw-r--r-- | vdr/extensions/vdr-1.7.0-ext_h264-s2ng-speedup.diff | 5483 | ||||
| -rw-r--r-- | vdr/extensions/vdr-1.7.0_extensions.diff | 28873 | ||||
| -rw-r--r-- | vdr/extensions/vdr-1.7.5_extensions.diff | 23830 |
3 files changed, 0 insertions, 58186 deletions
diff --git a/vdr/extensions/vdr-1.7.0-ext_h264-s2ng-speedup.diff b/vdr/extensions/vdr-1.7.0-ext_h264-s2ng-speedup.diff deleted file mode 100644 index b9e1beb..0000000 --- a/vdr/extensions/vdr-1.7.0-ext_h264-s2ng-speedup.diff +++ /dev/null @@ -1,5483 +0,0 @@ -diff -ruNp vdr-1.7.0-extensions/channels.c vdr-1.7.0-ext-h264-s2ng-speedup/channels.c ---- vdr-1.7.0-extensions/channels.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/channels.c 2009-04-12 23:52:16.000000000 +0200 -@@ -4,7 +4,7 @@ - * See the main source file 'vdr.c' for copyright information and - * how to reach the author. - * -- * $Id: channels.c 2.2 2008/04/12 13:49:12 kls Exp $ -+ * $Id: channels.c 2.5 2009/04/10 11:29:55 kls Exp $ - */ - - #include "channels.h" -@@ -24,114 +24,86 @@ - // --- Channel Parameter Maps ------------------------------------------------ - - const tChannelParameterMap InversionValues[] = { -- { 0, DVBFE_INVERSION_OFF, trNOOP("off") }, -- { 1, DVBFE_INVERSION_ON, trNOOP("on") }, -- { 999, DVBFE_INVERSION_AUTO }, -+ { 0, INVERSION_OFF, trNOOP("off") }, -+ { 1, INVERSION_ON, trNOOP("on") }, -+ { 999, INVERSION_AUTO, trNOOP("auto") }, - { -1 } - }; - - const tChannelParameterMap BandwidthValues[] = { -- { 5, DVBFE_BANDWIDTH_5_MHZ, "5 MHz" }, -- { 6, DVBFE_BANDWIDTH_6_MHZ, "6 MHz" }, -- { 7, DVBFE_BANDWIDTH_7_MHZ, "7 MHz" }, -- { 8, DVBFE_BANDWIDTH_8_MHZ, "8 MHz" }, -- { 999, DVBFE_BANDWIDTH_AUTO }, -+ { 6, 6000000, "6 MHz" }, -+ { 7, 7000000, "7 MHz" }, -+ { 8, 8000000, "8 MHz" }, - { -1 } - }; - - const tChannelParameterMap CoderateValues[] = { -- { 0, DVBFE_FEC_NONE, trNOOP("none") }, -- { 12, DVBFE_FEC_1_2, "1/2" }, -- { 13, DVBFE_FEC_1_3, "1/3" }, -- { 14, DVBFE_FEC_1_4, "1/4" }, -- { 23, DVBFE_FEC_2_3, "2/3" }, -- { 25, DVBFE_FEC_2_5, "2/5" }, -- { 34, DVBFE_FEC_3_4, "3/4" }, -- { 35, DVBFE_FEC_3_5, "3/5" }, -- { 45, DVBFE_FEC_4_5, "4/5" }, -- { 56, DVBFE_FEC_5_6, "5/6" }, -- { 67, DVBFE_FEC_6_7, "6/7" }, -- { 78, DVBFE_FEC_7_8, "7/8" }, -- { 89, DVBFE_FEC_8_9, "8/9" }, -- { 910, DVBFE_FEC_9_10, "9/10" }, -- { 999, DVBFE_FEC_AUTO }, -+ { 0, FEC_NONE, trNOOP("none") }, -+ { 12, FEC_1_2, "1/2" }, -+ { 23, FEC_2_3, "2/3" }, -+ { 34, FEC_3_4, "3/4" }, -+ { 35, FEC_3_5, "3/5" }, -+ { 45, FEC_4_5, "4/5" }, -+ { 56, FEC_5_6, "5/6" }, -+ { 67, FEC_6_7, "6/7" }, -+ { 78, FEC_7_8, "7/8" }, -+ { 89, FEC_8_9, "8/9" }, -+ { 910, FEC_9_10, "9/10" }, -+ { 999, FEC_AUTO, trNOOP("auto") }, - { -1 } - }; - - const tChannelParameterMap ModulationValues[] = { -- { 0, DVBFE_MOD_NONE, trNOOP("none") }, -- { 4, DVBFE_MOD_QAM4, "QAM4" }, -- { 16, DVBFE_MOD_QAM16, "QAM16" }, -- { 32, DVBFE_MOD_QAM32, "QAM32" }, -- { 64, DVBFE_MOD_QAM64, "QAM64" }, -- { 128, DVBFE_MOD_QAM128, "QAM128" }, -- { 256, DVBFE_MOD_QAM256, "QAM256" }, -- { 512, DVBFE_MOD_QAM512, "QAM512" }, -- {1024, DVBFE_MOD_QAM1024, "QAM1024" }, -- { 1, DVBFE_MOD_BPSK, "BPSK" }, -- { 2, DVBFE_MOD_QPSK, "QPSK" }, -- { 3, DVBFE_MOD_OQPSK, "OQPSK" }, -- { 5, DVBFE_MOD_8PSK, "8PSK" }, -- { 6, DVBFE_MOD_16APSK, "16APSK" }, -- { 7, DVBFE_MOD_32APSK, "32APSK" }, -- { 8, DVBFE_MOD_OFDM, "OFDM" }, -- { 9, DVBFE_MOD_COFDM, "COFDM" }, -- { 10, DVBFE_MOD_VSB8, "VSB8" }, -- { 11, DVBFE_MOD_VSB16, "VSB16" }, -- { 998, DVBFE_MOD_QAMAUTO, "QAMAUTO" }, -- { 999, DVBFE_MOD_AUTO }, -+ { 16, QAM_16, "QAM16" }, -+ { 32, QAM_32, "QAM32" }, -+ { 64, QAM_64, "QAM64" }, -+ { 128, QAM_128, "QAM128" }, -+ { 256, QAM_256, "QAM256" }, -+ { 2, QPSK, "QPSK" }, -+ { 5, PSK_8, "8PSK" }, -+ { 6, APSK_16, "16APSK" }, -+ { 10, VSB_8, "VSB8" }, -+ { 11, VSB_16, "VSB16" }, -+ { 998, QAM_AUTO, "QAMAUTO" }, - { -1 } - }; - - const tChannelParameterMap SystemValues[] = { -- { 0, DVBFE_DELSYS_DVBS, "DVB-S" }, -- { 1, DVBFE_DELSYS_DVBS2, "DVB-S2" }, -+ { 0, SYS_DVBS, "DVB-S" }, -+ { 1, SYS_DVBS2, "DVB-S2" }, - { -1 } - }; - - const tChannelParameterMap TransmissionValues[] = { -- { 2, DVBFE_TRANSMISSION_MODE_2K, "2K" }, -- { 4, DVBFE_TRANSMISSION_MODE_4K, "4K" }, -- { 8, DVBFE_TRANSMISSION_MODE_8K, "8K" }, -- { 999, DVBFE_TRANSMISSION_MODE_AUTO }, -+ { 2, TRANSMISSION_MODE_2K, "2K" }, -+ { 8, TRANSMISSION_MODE_8K, "8K" }, -+ { 999, TRANSMISSION_MODE_AUTO, trNOOP("auto") }, - { -1 } - }; - - const tChannelParameterMap GuardValues[] = { -- { 4, DVBFE_GUARD_INTERVAL_1_4, "1/4" }, -- { 8, DVBFE_GUARD_INTERVAL_1_8, "1/8" }, -- { 16, DVBFE_GUARD_INTERVAL_1_16, "1/16" }, -- { 32, DVBFE_GUARD_INTERVAL_1_32, "1/32" }, -- { 999, DVBFE_GUARD_INTERVAL_AUTO }, -+ { 4, GUARD_INTERVAL_1_4, "1/4" }, -+ { 8, GUARD_INTERVAL_1_8, "1/8" }, -+ { 16, GUARD_INTERVAL_1_16, "1/16" }, -+ { 32, GUARD_INTERVAL_1_32, "1/32" }, -+ { 999, GUARD_INTERVAL_AUTO, trNOOP("auto") }, - { -1 } - }; - - const tChannelParameterMap HierarchyValues[] = { -- { 0, DVBFE_HIERARCHY_OFF, trNOOP("off") }, -- { 1, DVBFE_HIERARCHY_ON, trNOOP("on") }, -- { 999, DVBFE_HIERARCHY_AUTO }, -- { -1 } -- }; -- --const tChannelParameterMap AlphaValues[] = { -- { 0, 0 }, -- { 1, DVBFE_ALPHA_1 }, -- { 2, DVBFE_ALPHA_2 }, -- { 4, DVBFE_ALPHA_4 }, -- { -1 } -- }; -- --const tChannelParameterMap PriorityValues[] = { -- { 0, DVBFE_STREAM_PRIORITY_HP, trNOOP("high") }, -- { 1, DVBFE_STREAM_PRIORITY_LP, trNOOP("low") }, -+ { 0, HIERARCHY_NONE, trNOOP("none") }, -+ { 1, HIERARCHY_1, "1" }, -+ { 2, HIERARCHY_2, "2" }, -+ { 4, HIERARCHY_4, "4" }, -+ { 999, HIERARCHY_AUTO, trNOOP("auto") }, - { -1 } - }; - - const tChannelParameterMap RollOffValues[] = { -- { 0, DVBFE_ROLLOFF_UNKNOWN }, -- { 20, DVBFE_ROLLOFF_20, "0.20" }, -- { 25, DVBFE_ROLLOFF_25, "0.25" }, -- { 35, DVBFE_ROLLOFF_35, "0.35" }, -+ { 0, ROLLOFF_AUTO, trNOOP("auto") }, -+ { 20, ROLLOFF_20, "0.20" }, -+ { 25, ROLLOFF_25, "0.25" }, -+ { 35, ROLLOFF_35, "0.35" }, - { -1 } - }; - -@@ -223,22 +195,20 @@ cChannel::cChannel(void) - pluginParam = strdup(""); - #endif /* PLUGINPARAM */ - memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__); -- inversion = DVBFE_INVERSION_AUTO; -- bandwidth = DVBFE_BANDWIDTH_AUTO; -- coderateH = DVBFE_FEC_AUTO; -- coderateL = DVBFE_FEC_AUTO; -- modulation = DVBFE_MOD_AUTO; -- system = DVBFE_DELSYS_DVBS; -- transmission = DVBFE_TRANSMISSION_MODE_AUTO; -- guard = DVBFE_GUARD_INTERVAL_AUTO; -- hierarchy = DVBFE_HIERARCHY_AUTO; -- alpha = 0; -- priority = DVBFE_STREAM_PRIORITY_HP; -- rollOff = DVBFE_ROLLOFF_UNKNOWN; -+ inversion = INVERSION_AUTO; -+ bandwidth = 8000000; -+ coderateH = FEC_AUTO; -+ coderateL = FEC_AUTO; -+ modulation = QPSK; -+ system = SYS_DVBS; -+ transmission = TRANSMISSION_MODE_AUTO; -+ guard = GUARD_INTERVAL_AUTO; -+ hierarchy = HIERARCHY_AUTO; -+ rollOff = ROLLOFF_AUTO; - modification = CHANNELMOD_NONE; - schedule = NULL; - linkChannels = NULL; -- refChannel = NULL; -+ refChannels = NULL; - } - - cChannel::cChannel(const cChannel &Channel) -@@ -252,28 +222,26 @@ cChannel::cChannel(const cChannel &Chann - #endif /* PLUGINPARAM */ - schedule = NULL; - linkChannels = NULL; -- refChannel = NULL; -+ refChannels = NULL; - *this = Channel; - } - - cChannel::~cChannel() - { -- delete linkChannels; -- linkChannels = NULL; // more than one channel can link to this one, so we need the following loop -- for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { -- if (Channel->linkChannels) { -- for (cLinkChannel *lc = Channel->linkChannels->First(); lc; lc = Channel->linkChannels->Next(lc)) { -- if (lc->Channel() == this) { -- Channel->linkChannels->Del(lc); -- break; -- } -- } -- if (Channel->linkChannels->Count() == 0) { -- delete Channel->linkChannels; -- Channel->linkChannels = NULL; -- } -- } -- } -+ if (linkChannels) { -+ // in all channels which we link to remove the reference to us -+ for (cLinkChannel *lc = linkChannels->First(); lc; lc = linkChannels->Next(lc)) -+ lc->Channel()->DelRefChannel(this); -+ delete linkChannels; -+ linkChannels = NULL; -+ } -+ if (refChannels) { -+ // in all channels which reference us remove their link to us -+ for (cLinkChannel *lc = refChannels->First(); lc; lc = refChannels->Next(lc)) -+ lc->Channel()->DelLinkChannel(this); -+ delete refChannels; -+ refChannels = NULL; -+ } - free(name); - free(shortName); - free(provider); -@@ -350,8 +318,6 @@ void cChannel::CopyTransponderData(const - transmission = Channel->transmission; - guard = Channel->guard; - hierarchy = Channel->hierarchy; -- alpha = Channel->alpha; -- priority = Channel->priority; - rollOff = Channel->rollOff; - #ifdef USE_PLUGINPARAM - if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, Channel->pluginParam); -@@ -430,9 +396,9 @@ bool cChannel::SetCableTransponderData(i - return true; - } - --bool cChannel::SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CoderateH, int CoderateL, int Guard, int Transmission, int Alpha, int Priority) -+bool cChannel::SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CoderateH, int CoderateL, int Guard, int Transmission) - { -- if (source != Source || frequency != Frequency || bandwidth != Bandwidth || modulation != Modulation || hierarchy != Hierarchy || coderateH != CoderateH || coderateL != CoderateL || guard != Guard || transmission != Transmission || alpha != Alpha || priority != Priority) { -+ if (source != Source || frequency != Frequency || bandwidth != Bandwidth || modulation != Modulation || hierarchy != Hierarchy || coderateH != CoderateH || coderateL != CoderateL || guard != Guard || transmission != Transmission) { - cString OldTransponderData = TransponderDataToString(); - source = Source; - frequency = Frequency; -@@ -443,8 +409,6 @@ bool cChannel::SetTerrTransponderData(in - coderateL = CoderateL; - guard = Guard; - transmission = Transmission; -- alpha = Alpha; -- priority = Priority; - schedule = NULL; - if (Number()) { - dsyslog("changing transponder data of channel %d from %s to %s", Number(), *OldTransponderData, *TransponderDataToString()); -@@ -558,10 +522,10 @@ static int IntArrayToString(char *s, con - return q - s; - } - --void cChannel::SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid) -+void cChannel::SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid) - { - int mod = CHANNELMOD_NONE; -- if (vpid != Vpid || ppid != Ppid || tpid != Tpid) -+ if (vpid != Vpid || ppid != Ppid || vtype != Vtype || tpid != Tpid) - mod |= CHANNELMOD_PIDS; - int m = IntArraysDiffer(apids, Apids, alangs, ALangs) | IntArraysDiffer(dpids, Dpids, dlangs, DLangs) | IntArraysDiffer(spids, Spids, slangs, SLangs); - if (m & STRDIFF) -@@ -595,9 +559,10 @@ void cChannel::SetPids(int Vpid, int Ppi - q = NewSpidsBuf; - q += IntArrayToString(q, Spids, 10, SLangs); - *q = 0; -- dsyslog("changing pids of channel %d from %d+%d:%s:%s:%d to %d+%d:%s:%s:%d", Number(), vpid, ppid, OldApidsBuf, OldSpidsBuf, tpid, Vpid, Ppid, NewApidsBuf, NewSpidsBuf, Tpid); -+ dsyslog("changing pids of channel %d from %d+%d=%d:%s:%s:%d to %d+%d=%d:%s:%s:%d", Number(), vpid, ppid, vtype, OldApidsBuf, OldSpidsBuf, tpid, Vpid, Ppid, Vtype, NewApidsBuf, NewSpidsBuf, Tpid); - vpid = Vpid; - ppid = Ppid; -+ vtype = Vtype; - for (int i = 0; i < MAXAPIDS; i++) { - apids[i] = Apids[i]; - strn0cpy(alangs[i], ALangs[i], MAXLANGCODE2); -@@ -674,7 +639,7 @@ void cChannel::SetLinkChannels(cLinkChan - q += sprintf(q, "linking channel %d from", Number()); - if (linkChannels) { - for (cLinkChannel *lc = linkChannels->First(); lc; lc = linkChannels->Next(lc)) { -- lc->Channel()->SetRefChannel(NULL); -+ lc->Channel()->DelRefChannel(this); - q += sprintf(q, " %d", lc->Channel()->Number()); - } - delete linkChannels; -@@ -685,7 +650,7 @@ void cChannel::SetLinkChannels(cLinkChan - linkChannels = LinkChannels; - if (linkChannels) { - for (cLinkChannel *lc = linkChannels->First(); lc; lc = linkChannels->Next(lc)) { -- lc->Channel()->SetRefChannel(this); -+ lc->Channel()->AddRefChannel(this); - q += sprintf(q, " %d", lc->Channel()->Number()); - //dsyslog("link %4d -> %4d: %s", Number(), lc->Channel()->Number(), lc->Channel()->Name()); - } -@@ -695,9 +660,39 @@ void cChannel::SetLinkChannels(cLinkChan - dsyslog(buffer); - } - --void cChannel::SetRefChannel(cChannel *RefChannel) -+void cChannel::AddRefChannel(cChannel *RefChannel) -+{ -+ if (!refChannels) -+ refChannels = new cLinkChannels; -+ refChannels->Add(new cLinkChannel(RefChannel)); -+} -+ -+void cChannel::DelRefChannel(cChannel *RefChannel) -+{ -+ for (cLinkChannel *lc = refChannels->First(); lc; lc = refChannels->Next(lc)) { -+ if (lc->Channel() == RefChannel) { -+ refChannels->Del(lc); -+ if (refChannels->Count() <= 0) { -+ delete refChannels; -+ refChannels = NULL; -+ } -+ return; -+ } -+ } -+} -+ -+void cChannel::DelLinkChannel(cChannel *LinkChannel) - { -- refChannel = RefChannel; -+ for (cLinkChannel *lc = linkChannels->First(); lc; lc = linkChannels->Next(lc)) { -+ if (lc->Channel() == LinkChannel) { -+ linkChannels->Del(lc); -+ if (linkChannels->Count() <= 0) { -+ delete linkChannels; -+ linkChannels = NULL; -+ } -+ return; -+ } -+ } - } - - static int PrintParameter(char *p, char Name, int Value) -@@ -726,7 +721,6 @@ cString cChannel::ParametersToString(voi - char *q = buffer; - *q = 0; - ST(" S ") q += sprintf(q, "%c", polarization); -- ST(" T") q += PrintParameter(q, 'A', MapToUser(alpha, AlphaValues)); - ST(" T") q += PrintParameter(q, 'B', MapToUser(bandwidth, BandwidthValues)); - ST("CST") q += PrintParameter(q, 'C', MapToUser(coderateH, CoderateValues)); - ST(" T") q += PrintParameter(q, 'D', MapToUser(coderateL, CoderateValues)); -@@ -734,7 +728,6 @@ cString cChannel::ParametersToString(voi - ST("CST") q += PrintParameter(q, 'I', MapToUser(inversion, InversionValues)); - ST("CST") q += PrintParameter(q, 'M', MapToUser(modulation, ModulationValues)); - ST(" S ") q += PrintParameter(q, 'O', MapToUser(rollOff, RollOffValues)); -- ST(" T") q += PrintParameter(q, 'P', MapToUser(priority, PriorityValues)); - ST(" S ") q += PrintParameter(q, 'S', MapToUser(system, SystemValues)); - ST(" T") q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues)); - ST(" T") q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues)); -@@ -760,6 +753,13 @@ static const char *ParseParameter(const - return NULL; - } - -+static const char *SkipDigits(const char *s) -+{ -+ while (*++s && isdigit(*s)) -+ ; -+ return s; -+} -+ - bool cChannel::StringToParameters(const char *s) - { - #ifdef USE_PLUGINPARAM -@@ -768,7 +768,7 @@ bool cChannel::StringToParameters(const - while (s && *s) { - #endif /* PLUGINPARAM */ - switch (toupper(*s)) { -- case 'A': s = ParseParameter(s, alpha, AlphaValues); break; -+ case 'A': s = SkipDigits(s); break; // for compatibility with the "multiproto" approach - may be removed in future versions - case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break; - case 'C': s = ParseParameter(s, coderateH, CoderateValues); break; - case 'D': s = ParseParameter(s, coderateL, CoderateValues); break; -@@ -777,14 +777,14 @@ bool cChannel::StringToParameters(const - case 'I': s = ParseParameter(s, inversion, InversionValues); break; - case 'L': polarization = *s++; break; - case 'M': s = ParseParameter(s, modulation, ModulationValues); break; -- case 'Z':// for compatibility with the original DVB-S2 patch - may be removed in future versions - case 'O': s = ParseParameter(s, rollOff, RollOffValues); break; -- case 'P': s = ParseParameter(s, priority, PriorityValues); break; -+ case 'P': s = SkipDigits(s); break; // for compatibility with the "multiproto" approach - may be removed in future versions - case 'R': polarization = *s++; break; - case 'S': s = ParseParameter(s, system, SystemValues); break; - case 'T': s = ParseParameter(s, transmission, TransmissionValues); break; - case 'V': polarization = *s++; break; - case 'Y': s = ParseParameter(s, hierarchy, HierarchyValues); break; -+ case 'Z': s = SkipDigits(s); break; // for compatibility with the original DVB-S2 patch - may be removed in future versions - default: esyslog("ERROR: unknown parameter key '%c'", *s); - return false; - } -@@ -816,6 +816,8 @@ cString cChannel::ToText(const cChannel - q += snprintf(q, sizeof(vpidbuf), "%d", Channel->vpid); - if (Channel->ppid && Channel->ppid != Channel->vpid) - q += snprintf(q, sizeof(vpidbuf) - (q - vpidbuf), "+%d", Channel->ppid); -+ if (Channel->vpid && Channel->vtype) -+ q += snprintf(q, sizeof(vpidbuf) - (q - vpidbuf), "=%d", Channel->vtype); - *q = 0; - const int BufferSize = (MAXAPIDS + MAXDPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia - char apidbuf[BufferSize]; -@@ -877,6 +879,7 @@ bool cChannel::Parse(const char *s) - tpid = 0; - } - vpid = ppid = 0; -+ vtype = 2; // default is MPEG-2 - apids[0] = 0; - dpids[0] = 0; - ok = false; -@@ -887,16 +890,20 @@ bool cChannel::Parse(const char *s) - ok = StringToParameters(parambuf) && (source = cSource::FromString(sourcebuf)) >= 0; - #endif /* PLUGINPARAM */ - -- char *p = strchr(vpidbuf, '+'); -- if (p) -+ char *p; -+ if ((p = strchr(vpidbuf, '=')) != NULL) { -+ *p++ = 0; -+ if (sscanf(p, "%d", &vtype) != 1) -+ return false; -+ } -+ if ((p = strchr(vpidbuf, '+')) != NULL) { - *p++ = 0; -- if (sscanf(vpidbuf, "%d", &vpid) != 1) -- return false; -- if (p) { - if (sscanf(p, "%d", &ppid) != 1) - return false; - } -- else -+ if (sscanf(vpidbuf, "%d", &vpid) != 1) -+ return false; -+ if (!ppid) - ppid = vpid; - - char *dpidbuf = strchr(apidbuf, ';'); -@@ -1057,14 +1064,72 @@ bool cChannels::Load(const char *FileNam - return false; - } - -+void cChannels::ClearChannelHashes(void) -+{ -+ channelsHashSid.Clear(); -+ channelsHashNidTid.Clear(); -+} -+ - void cChannels::HashChannel(cChannel *Channel) - { - channelsHashSid.Add(Channel, Channel->Sid()); -+ channelsHashNidTid.Add(Channel, HashKeyNidTid(Channel->Nid(), Channel->Tid())); - } - - void cChannels::UnhashChannel(cChannel *Channel) - { - channelsHashSid.Del(Channel, Channel->Sid()); -+ channelsHashNidTid.Del(Channel, HashKeyNidTid(Channel->Nid(), Channel->Tid())); -+} -+ -+unsigned int cChannels::HashKeyNidTid(unsigned short Nid, unsigned short Tid) -+{ -+ return Nid << 16 | Tid; -+} -+ -+cIterator<cChannel> cChannels::GetChannelsBySourceNidTid(int Source, unsigned short Nid, unsigned short Tid) -+{ -+ class cIteratorImplSourceNidTid : public cIteratorImpl { -+ private: -+ cList<cHashObject> *hashList; -+ cHashObject *current; -+ int source; -+ unsigned short nid; -+ unsigned short tid; -+ cChannel *FindMatchingChannel(bool reverse, bool reset = false) { -+ if (!hashList || (!current && !reset)) -+ return NULL; -+ while (true) { -+ if (reset) { -+ reset = false; -+ current = reverse ? hashList->Last() : hashList->First(); -+ } -+ else -+ current = reverse ? hashList->Prev(current) : hashList->Next(current); -+ if (!current) -+ break; -+ cChannel *Channel = (cChannel *)current->Object(); -+ if (Channel->Source() == source && Channel->Nid() == nid && Channel->Tid() == tid) -+ return Channel; -+ } -+ return NULL; -+ } -+ public: -+ cIteratorImplSourceNidTid(cList<cHashObject> *HashList, int Source, unsigned short Nid, unsigned short Tid) { -+ hashList = HashList; -+ source = Source; -+ nid = Nid; -+ tid = Tid; -+ current = NULL; -+ } -+ virtual void *First(void) { return FindMatchingChannel(false, true); } -+ virtual void *Last(void) { return FindMatchingChannel(true, true); } -+ virtual void *Prev(void) { return FindMatchingChannel(true); } -+ virtual void *Next(void) { return FindMatchingChannel(false); } -+ virtual void *Current(void) const { return current ? (cChannel *)current->Object() : NULL; } -+ }; -+ -+ return cIterator<cChannel>(new cIteratorImplSourceNidTid(channelsHashNidTid.GetList(HashKeyNidTid(Nid, Tid)), Source, Nid, Tid)); - } - - int cChannels::GetNextGroup(int Idx) -@@ -1101,7 +1166,7 @@ int cChannels::GetPrevNormal(int Idx) - - void cChannels::ReNumber(void) - { -- channelsHashSid.Clear(); -+ ClearChannelHashes(); - maxNumber = 0; - int Number = 1; - for (cChannel *channel = First(); channel; channel = Next(channel)) { -diff -ruNp vdr-1.7.0-extensions/channels.h vdr-1.7.0-ext-h264-s2ng-speedup/channels.h ---- vdr-1.7.0-extensions/channels.h 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/channels.h 2009-04-12 23:52:16.000000000 +0200 -@@ -4,7 +4,7 @@ - * See the main source file 'vdr.c' for copyright information and - * how to reach the author. - * -- * $Id: channels.h 2.2 2008/04/12 13:46:50 kls Exp $ -+ * $Id: channels.h 2.4 2008/11/22 13:35:52 kls Exp $ - */ - - #ifndef __CHANNELS_H -@@ -66,8 +66,6 @@ extern const tChannelParameterMap System - extern const tChannelParameterMap TransmissionValues[]; - extern const tChannelParameterMap GuardValues[]; - extern const tChannelParameterMap HierarchyValues[]; --extern const tChannelParameterMap AlphaValues[]; --extern const tChannelParameterMap PriorityValues[]; - extern const tChannelParameterMap RollOffValues[]; - - struct tChannelID { -@@ -127,6 +125,7 @@ private: - int srate; - int vpid; - int ppid; -+ int vtype; - int apids[MAXAPIDS + 1]; // list is zero-terminated - char alangs[MAXAPIDS][MAXLANGCODE2]; - int dpids[MAXDPIDS + 1]; // list is zero-terminated -@@ -151,17 +150,18 @@ private: - int transmission; - int guard; - int hierarchy; -- int alpha; -- int priority; - int rollOff; - int __EndData__; - int modification; - mutable const cSchedule *schedule; - cLinkChannels *linkChannels; -- cChannel *refChannel; -+ cLinkChannels *refChannels; - cString TransponderDataToString(void) const; - cString ParametersToString(void) const; - bool StringToParameters(const char *s); -+ void AddRefChannel(cChannel *RefChannel); -+ void DelRefChannel(cChannel *RefChannel); -+ void DelLinkChannel(cChannel *RefChannel); - public: - cChannel(void); - cChannel(const cChannel &Channel); -@@ -184,6 +184,7 @@ public: - int Srate(void) const { return srate; } - int Vpid(void) const { return vpid; } - int Ppid(void) const { return ppid; } -+ int Vtype(void) const { return vtype; } - const int *Apids(void) const { return apids; } - const int *Dpids(void) const { return dpids; } - const int *Spids(void) const { return spids; } -@@ -213,11 +214,10 @@ public: - int Transmission(void) const { return transmission; } - int Guard(void) const { return guard; } - int Hierarchy(void) const { return hierarchy; } -- int Alpha(void) const { return alpha; } -- int Priority(void) const { return priority; } - int RollOff(void) const { return rollOff; } - const cLinkChannels* LinkChannels(void) const { return linkChannels; } -- const cChannel *RefChannel(void) const { return refChannel; } -+ const cChannel *RefChannel(void) const { return refChannels ? refChannels->Last()->Channel() : 0; } -+ const cLinkChannels* RefChannels(void) const { return refChannels; } - #ifdef USE_PLUGINPARAM - bool IsPlug(void) const { return cSource::IsPlug(source); } - #endif /* PLUGINPARAM */ -@@ -233,18 +233,50 @@ public: - #endif /* PLUGINPARAM */ - bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation, int System, int RollOff); - bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH); -- bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission, int Alpha, int Priority); -+ bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission); - void SetId(int Nid, int Tid, int Sid, int Rid = 0); - void SetName(const char *Name, const char *ShortName, const char *Provider); - void SetPortalName(const char *PortalName); - #ifdef USE_PLUGINPARAM - void SetPluginParam(const char *PluginParam); - #endif /* PLUGINPARAM */ -- void SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); -+ void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); - void SetCaIds(const int *CaIds); // list must be zero-terminated - void SetCaDescriptors(int Level); - void SetLinkChannels(cLinkChannels *LinkChannels); -- void SetRefChannel(cChannel *RefChannel); -+ }; -+ -+class cIteratorImpl { -+private: -+ int refCount; -+ cIteratorImpl(const cIteratorImpl &); -+ const cIteratorImpl &operator =(const cIteratorImpl &); -+public: -+ cIteratorImpl(void) { refCount = 0; } -+ virtual ~cIteratorImpl() {} -+ virtual int AddRef(void) { return ++refCount; } -+ virtual int DelRef(void) { int RefCount = --refCount; if (RefCount <= 0) delete this; return RefCount; } -+ virtual void *First(void) = 0; -+ virtual void *Last(void) = 0; -+ virtual void *Prev(void) = 0; -+ virtual void *Next(void) = 0; -+ virtual void *Current(void) const = 0; -+ }; -+ -+template <class T> class cIterator -+{ -+private: -+ cIteratorImpl *impl; -+public: -+ cIterator(cIteratorImpl *Impl) { impl = Impl; impl->AddRef(); } -+ cIterator(const cIterator &rhs) { impl = rhs.impl; impl->AddRef(); } -+ ~cIterator() { impl->DelRef(); } -+ const cIterator &operator =(const cIterator &rhs) { rhs.impl->AddRef(); impl->DelRef(); impl = rhs.impl; return *this; } -+ T *First(void) const { return (T *)impl->First(); } -+ T *Last(void) const { return (T *)impl->Last(); } -+ T *Prev(void) const { return (T *)impl->Prev(); } -+ T *Next(void) const { return (T *)impl->Next(); } -+ T *Current(void) const { return (T *)impl->Current(); } - }; - - class cChannels : public cRwLock, public cConfig<cChannel> { -@@ -253,7 +285,10 @@ private: - int modified; - int beingEdited; - cHash<cChannel> channelsHashSid; -+ cHash<cChannel> channelsHashNidTid; - void DeleteDuplicateChannels(void); -+ void ClearChannelHashes(void); -+ static unsigned int HashKeyNidTid(unsigned short Nid, unsigned short Tid); - public: - cChannels(void); - bool Load(const char *FileName, bool AllowComments = false, bool MustExist = false); -@@ -268,6 +303,7 @@ public: - cChannel *GetByServiceID(int Source, int Transponder, unsigned short ServiceID); - cChannel *GetByChannelID(tChannelID ChannelID, bool TryWithoutRid = false, bool TryWithoutPolarization = false); - cChannel *GetByTransponderID(tChannelID ChannelID); -+ cIterator<cChannel> GetChannelsBySourceNidTid(int Source, unsigned short Nid, unsigned short Tid); - int BeingEdited(void) { return beingEdited; } - void IncBeingEdited(void) { beingEdited++; } - void DecBeingEdited(void) { beingEdited--; } -diff -ruNp vdr-1.7.0-extensions/config.c vdr-1.7.0-ext-h264-s2ng-speedup/config.c ---- vdr-1.7.0-extensions/config.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/config.c 2009-04-12 23:57:23.000000000 +0200 -@@ -326,9 +326,6 @@ cSetup::cSetup(void) - ChannelBlockerMode = 0; - ChannelBlockerList = strdup(""); - #endif /* DVBSETUP */ --#ifdef USE_SYNCEARLY -- UseSyncEarlyPatch = 0; --#endif /* SYNCEARLY */ - ChannelInfoPos = 0; - ChannelInfoTime = 5; - OSDLeft = 54; -@@ -393,9 +390,12 @@ cSetup::cSetup(void) - noEPGList = strdup(""); - #endif /* NOEPG */ - #ifdef USE_LIRCSETTINGS -+ LircPushFreq = 3; - LircRepeatDelay = 350; -- LircRepeatFreq = 100; -+ LircRepeatFreq = 10; - LircRepeatTimeout = 500; -+ LircReconnectDelay = 3000; -+ LircPriorityBoost = 0; - #endif /* LIRCSETTINGS */ - #ifdef USE_LIEMIEXT - ShowRecDate = 1; -@@ -684,9 +684,6 @@ bool cSetup::Parse(const char *Name, con - ChannelBlockerList = strdup(Value ? Value : ""); - } - #endif /* DVBSETUP */ --#ifdef USE_SYNCEARLY -- else if (!strcasecmp(Name, "UseSyncEarlyPatch")) UseSyncEarlyPatch = atoi(Value); --#endif /* SYNCEARLY */ - else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value); - else if (!strcasecmp(Name, "ChannelInfoTime")) ChannelInfoTime = atoi(Value); - else if (!strcasecmp(Name, "OSDLeft")) OSDLeft = atoi(Value); -@@ -753,9 +750,12 @@ bool cSetup::Parse(const char *Name, con - } - #endif /* NOEPG */ - #ifdef USE_LIRCSETTINGS -+ else if (!strcasecmp(Name, "LircPushFreq")) LircPushFreq = atoi(Value); - else if (!strcasecmp(Name, "LircRepeatDelay")) LircRepeatDelay = atoi(Value); - else if (!strcasecmp(Name, "LircRepeatFreq")) LircRepeatFreq = atoi(Value); - else if (!strcasecmp(Name, "LircRepeatTimeout")) LircRepeatTimeout = atoi(Value); -+ else if (!strcasecmp(Name, "LircReconnectDelay")) LircReconnectDelay = atoi(Value); -+ else if (!strcasecmp(Name, "LircPriorityBoost")) LircPriorityBoost = atoi(Value); - #endif /* LIRCSETTINGS */ - #ifdef USE_LIEMIEXT - else if (!strcasecmp(Name, "ShowRecDate")) ShowRecDate = atoi(Value); -@@ -916,9 +916,6 @@ bool cSetup::Save(void) - Store("ChannelBlockerMode", ChannelBlockerMode); - Store("ChannelBlockerList", ChannelBlockerList); - #endif /* DVBSETUP */ --#ifdef USE_SYNCEARLY -- Store("UseSyncEarlyPatch", UseSyncEarlyPatch); --#endif /* SYNCEARLY */ - Store("ChannelInfoPos", ChannelInfoPos); - Store("ChannelInfoTime", ChannelInfoTime); - Store("OSDLeft", OSDLeft); -@@ -982,9 +979,12 @@ bool cSetup::Save(void) - Store("noEPGList", noEPGList); - #endif /* NOEPG */ - #ifdef USE_LIRCSETTINGS -+ Store("LircPushFreq", LircPushFreq); - Store("LircRepeatDelay", LircRepeatDelay); - Store("LircRepeatFreq", LircRepeatFreq); - Store("LircRepeatTimeout", LircRepeatTimeout); -+ Store("LircReconnectDelay", LircReconnectDelay); -+ Store("LircPriorityBoost", LircPriorityBoost); - #endif /* LIRCSETTINGS */ - #ifdef USE_LIEMIEXT - Store("ShowRecDate", ShowRecDate); -diff -ruNp vdr-1.7.0-extensions/config.h vdr-1.7.0-ext-h264-s2ng-speedup/config.h ---- vdr-1.7.0-extensions/config.h 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/config.h 2009-04-12 23:57:23.000000000 +0200 -@@ -336,9 +336,6 @@ public: - int ChannelBlocker; - int ChannelBlockerMode; - #endif /* DVBSETUP */ --#ifdef USE_SYNCEARLY -- int UseSyncEarlyPatch; --#endif /* SYNCEARLY */ - int ChannelInfoPos; - int ChannelInfoTime; - int OSDLeft, OSDTop, OSDWidth, OSDHeight; -@@ -398,9 +395,12 @@ public: - int noEPGMode; - #endif /* NOEPG */ - #ifdef USE_LIRCSETTINGS -+ int LircPushFreq; - int LircRepeatDelay; - int LircRepeatFreq; - int LircRepeatTimeout; -+ int LircReconnectDelay; -+ int LircPriorityBoost; - #endif /* LIRCSETTINGS */ - #ifdef USE_LIEMIEXT - int ShowRecDate, ShowRecTime, ShowRecLength, ShowProgressBar, MenuCmdPosition; -diff -ruNp vdr-1.7.0-extensions/device.c vdr-1.7.0-ext-h264-s2ng-speedup/device.c ---- vdr-1.7.0-extensions/device.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/device.c 2009-04-12 23:57:23.000000000 +0200 -@@ -1110,11 +1110,7 @@ eSetChannelResult cDevice::SetChannel(co - } - for (int i = 0; i < MAXSPIDS; i++) - SetAvailableTrack(ttSubtitle, i, Channel->Spid(i), Channel->Slang(i)); --#ifdef USE_SYNCEARLY -- if ((Setup.UseSyncEarlyPatch && (!NeedsTransferMode || GetCurrentAudioTrack() == ttNone)) || (!Setup.UseSyncEarlyPatch && !NeedsTransferMode)) --#else -- if (!NeedsTransferMode) --#endif /* SYNCEARLY */ -+ if (!NeedsTransferMode || GetCurrentAudioTrack() == ttNone) - EnsureAudioTrack(true); - EnsureSubtitleTrack(); - } -diff -ruNp vdr-1.7.0-extensions/dvbdevice.c vdr-1.7.0-ext-h264-s2ng-speedup/dvbdevice.c ---- vdr-1.7.0-extensions/dvbdevice.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/dvbdevice.c 2009-04-13 12:28:52.000000000 +0200 -@@ -4,13 +4,13 @@ - * See the main source file 'vdr.c' for copyright information and - * how to reach the author. - * -- * $Id: dvbdevice.c 2.2 2008/04/13 14:15:35 kls Exp $ -+ * $Id: dvbdevice.c 2.14 2009/04/10 09:54:24 kls Exp $ - */ - - #include "dvbdevice.h" - #include <errno.h> - #include <limits.h> --#include <linux/videodev.h> -+#include <linux/videodev2.h> - #include <linux/dvb/audio.h> - #include <linux/dvb/dmx.h> - #include <linux/dvb/frontend.h> -@@ -79,7 +79,7 @@ private: - int tuneTimeout; - int lockTimeout; - time_t lastTimeoutReport; -- dvbfe_delsys frontendType; -+ fe_delivery_system frontendType; - cChannel channel; - const char *diseqcCommands; - eTunerStatus tunerStatus; -@@ -93,7 +93,7 @@ private: - bool SetFrontend(void); - virtual void Action(void); - public: -- cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType); -+ cDvbTuner(int Fd_Frontend, int CardIndex, fe_delivery_system FrontendType); - virtual ~cDvbTuner(); - bool IsTunedTo(const cChannel *Channel) const; - void Set(const cChannel *Channel, bool Tune); -@@ -103,7 +103,7 @@ public: - bool Locked(int TimeoutMs = 0); - }; - --cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType) -+cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_delivery_system FrontendType) - { - fd_frontend = Fd_Frontend; - #ifdef USE_ROTOR -@@ -116,7 +116,7 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, in - lastTimeoutReport = 0; - diseqcCommands = NULL; - tunerStatus = tsIdle; -- if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) -+ if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) - CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power - SetDescription("tuner on device %d", cardIndex + 1); - Start(); -@@ -139,7 +139,6 @@ bool cDvbTuner::IsTunedTo(const cChannel - char Type = **cSource::ToString(Channel->Source()); - #define ST(s, p) if (strchr(s, Type)) if (channel.p() != Channel->p()) return false; - // Polarization is already checked as part of the Transponder. -- ST(" T", Alpha); - ST(" T", Bandwidth); - ST("CST", CoderateH); - ST(" T", CoderateL); -@@ -147,8 +146,8 @@ bool cDvbTuner::IsTunedTo(const cChannel - ST("CST", Inversion); - ST("CST", Modulation); - ST(" S ", RollOff); -- ST(" T", Priority); - ST(" S ", System); -+ ST("CS ", Srate); - ST(" T", Transmission); - ST(" T", Hierarchy); - return true; -@@ -180,7 +179,7 @@ bool cDvbTuner::Locked(int TimeoutMs) - bool cDvbTuner::SendDiseqcCmd(dvb_diseqc_master_cmd cmd) - { - cMutexLock MutexLock(&mutex); -- if ((!DVBFE_DELSYS_DVBS & !DVBFE_DELSYS_DVBS2) || SendDiseqc) -+ if ((!SYS_DVBS & !SYS_DVBS2) || SendDiseqc) - return false; - diseqc_cmd = cmd; - SendDiseqc = true; -@@ -217,10 +216,27 @@ static unsigned int FrequencyToHz(unsign - - bool cDvbTuner::SetFrontend(void) - { -- dvbfe_params Frontend; -+#define MAXFRONTENDCMDS 16 -+#define SETCMD(c, d) { Frontend[CmdSeq.num].cmd = (c);\ -+ Frontend[CmdSeq.num].u.data = (d);\ -+ if (CmdSeq.num++ > MAXFRONTENDCMDS) {\ -+ esyslog("ERROR: too many tuning commands on frontend %d", cardIndex);\ -+ return false;\ -+ }\ -+ } -+ dtv_property Frontend[MAXFRONTENDCMDS]; - memset(&Frontend, 0, sizeof(Frontend)); -+ dtv_properties CmdSeq; -+ memset(&CmdSeq, 0, sizeof(CmdSeq)); -+ CmdSeq.props = Frontend; -+ SETCMD(DTV_CLEAR, 0); -+ if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) { -+ esyslog("ERROR: frontend %d: %m", cardIndex); -+ return false; -+ } -+ CmdSeq.num = 0; - -- if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) { -+ if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) { - unsigned int frequency = channel.Frequency(); - if (Setup.DiSEqC) { - cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization()); -@@ -277,85 +293,78 @@ bool cDvbTuner::SetFrontend(void) - } - frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF - -- Frontend.delivery = dvbfe_delsys(channel.System()); -- Frontend.frequency = frequency * 1000UL; -- Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); -- if (Frontend.delivery == DVBFE_DELSYS_DVBS) { -- Frontend.delsys.dvbs.modulation = dvbfe_modulation(channel.Modulation()); -- Frontend.delsys.dvbs.symbol_rate = channel.Srate() * 1000UL; -- Frontend.delsys.dvbs.fec = dvbfe_fec(channel.CoderateH()); -+ // DVB-S/DVB-S2 (common parts) -+ SETCMD(DTV_DELIVERY_SYSTEM, channel.System()); -+ SETCMD(DTV_FREQUENCY, frequency * 1000UL); -+ SETCMD(DTV_MODULATION, channel.Modulation()); -+ SETCMD(DTV_SYMBOL_RATE, channel.Srate() * 1000UL); -+ SETCMD(DTV_INNER_FEC, channel.CoderateH()); -+ SETCMD(DTV_INVERSION, channel.Inversion()); -+ if (channel.System() == SYS_DVBS2) { -+ if (frontendType == SYS_DVBS2) { -+ // DVB-S2 -+ SETCMD(DTV_PILOT, PILOT_AUTO); -+ SETCMD(DTV_ROLLOFF, channel.RollOff()); -+ } -+ else { -+ esyslog("ERROR: frontend %d doesn't provide DVB-S2", cardIndex); -+ return false; -+ } - } - else { -- Frontend.delsys.dvbs2.modulation = dvbfe_modulation(channel.Modulation()); -- Frontend.delsys.dvbs2.symbol_rate = channel.Srate() * 1000UL; -- Frontend.delsys.dvbs2.fec = dvbfe_fec(channel.CoderateH()); -- Frontend.delsys.dvbs2.rolloff = dvbfe_rolloff(channel.RollOff()); -+ // DVB-S -+ SETCMD(DTV_ROLLOFF, ROLLOFF_35); // DVB-S always has a ROLLOFF of 0.35 - } - - tuneTimeout = DVBS_TUNE_TIMEOUT; - lockTimeout = DVBS_LOCK_TIMEOUT; -- -- dvbfe_info feinfo; -- feinfo.delivery = Frontend.delivery; -- CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system -- } -- else if (frontendType & DVBFE_DELSYS_DVBC) { -- Frontend.delivery = DVBFE_DELSYS_DVBC; -- Frontend.frequency = FrequencyToHz(channel.Frequency()); -- Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); -- Frontend.delsys.dvbc.symbol_rate = channel.Srate() * 1000UL; -- Frontend.delsys.dvbc.fec = dvbfe_fec(channel.CoderateH()); -- Frontend.delsys.dvbc.modulation = dvbfe_modulation(channel.Modulation()); -+ } -+ else if (frontendType == SYS_DVBC_ANNEX_AC || frontendType == SYS_DVBC_ANNEX_B) { -+ // DVB-C -+ SETCMD(DTV_DELIVERY_SYSTEM, frontendType); -+ SETCMD(DTV_FREQUENCY, FrequencyToHz(channel.Frequency())); -+ SETCMD(DTV_INVERSION, channel.Inversion()); -+ SETCMD(DTV_SYMBOL_RATE, channel.Srate() * 1000UL); -+ SETCMD(DTV_INNER_FEC, channel.CoderateH()); -+ SETCMD(DTV_MODULATION, channel.Modulation()); - - tuneTimeout = DVBC_TUNE_TIMEOUT; - lockTimeout = DVBC_LOCK_TIMEOUT; -- -- dvbfe_info feinfo; -- feinfo.delivery = Frontend.delivery; -- CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system - } - #ifdef USE_ATSC -- else if (frontendType & DVBFE_DELSYS_ATSC) { -- // Frequency and symbol rate: -+ else if (frontendType == SYS_ATSC) { -+ // ATSC -+ SETCMD(DTV_DELIVERY_SYSTEM, frontendType); -+ SETCMD(DTV_FREQUENCY, FrequencyToHz(channel.Frequency())); -+ SETCMD(DTV_INVERSION, channel.Inversion()); -+ SETCMD(DTV_MODULATION, channel.Modulation()); - -- Frontend.frequency = FrequencyToHz(channel.Frequency()); -- Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); -- Frontend.delsys.atsc.modulation = dvbfe_modulation(channel.Modulation()); -- -- tuneTimeout = DVBC_TUNE_TIMEOUT; -- lockTimeout = DVBC_LOCK_TIMEOUT; -- -- dvbfe_info feinfo; -- feinfo.delivery = Frontend.delivery; -- CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system -+ tuneTimeout = DVBT_TUNE_TIMEOUT; -+ lockTimeout = DVBT_LOCK_TIMEOUT; - } - #endif /* ATSC */ -- else if (frontendType & DVBFE_DELSYS_DVBT) { -- Frontend.delivery = DVBFE_DELSYS_DVBT; -- Frontend.frequency = FrequencyToHz(channel.Frequency()); -- Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); -- Frontend.delsys.dvbt.bandwidth = dvbfe_bandwidth(channel.Bandwidth()); -- Frontend.delsys.dvbt.code_rate_HP = dvbfe_fec(channel.CoderateH()); -- Frontend.delsys.dvbt.code_rate_LP = dvbfe_fec(channel.CoderateL()); -- Frontend.delsys.dvbt.constellation = dvbfe_modulation(channel.Modulation()); -- Frontend.delsys.dvbt.transmission_mode = dvbfe_transmission_mode(channel.Transmission()); -- Frontend.delsys.dvbt.guard_interval = dvbfe_guard_interval(channel.Guard()); -- Frontend.delsys.dvbt.hierarchy = dvbfe_hierarchy(channel.Hierarchy()); -- Frontend.delsys.dvbt.alpha = dvbfe_alpha(channel.Alpha()); -- Frontend.delsys.dvbt.priority = dvbfe_stream_priority(channel.Priority()); -+ else if (frontendType == SYS_DVBT) { -+ // DVB-T -+ SETCMD(DTV_DELIVERY_SYSTEM, frontendType); -+ SETCMD(DTV_FREQUENCY, FrequencyToHz(channel.Frequency())); -+ SETCMD(DTV_INVERSION, channel.Inversion()); -+ SETCMD(DTV_BANDWIDTH_HZ, channel.Bandwidth()); -+ SETCMD(DTV_CODE_RATE_HP, channel.CoderateH()); -+ SETCMD(DTV_CODE_RATE_LP, channel.CoderateL()); -+ SETCMD(DTV_MODULATION, channel.Modulation()); -+ SETCMD(DTV_TRANSMISSION_MODE, channel.Transmission()); -+ SETCMD(DTV_GUARD_INTERVAL, channel.Guard()); -+ SETCMD(DTV_HIERARCHY, channel.Hierarchy()); - - tuneTimeout = DVBT_TUNE_TIMEOUT; - lockTimeout = DVBT_LOCK_TIMEOUT; -- -- dvbfe_info feinfo; -- feinfo.delivery = Frontend.delivery; -- CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system - } - else { - esyslog("ERROR: attempt to set channel with unknown DVB frontend type"); - return false; - } -- if (ioctl(fd_frontend, DVBFE_SET_PARAMS, &Frontend) < 0) { -+ SETCMD(DTV_TUNE, 0); -+ if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) { - esyslog("ERROR: frontend %d: %m", cardIndex); - return false; - } -@@ -433,13 +442,22 @@ int cDvbDevice::devVideoOffset = -1; - int cDvbDevice::setTransferModeForDolbyDigital = 1; - - const char *DeliverySystems[] = { -- "DVBS", -+ "UNDEFINED", -+ "DVB-C", -+ "DVB-C", -+ "DVB-T", - "DSS", -- "DVBS2", -- "DVBC", -- "DVBT", -- "DVBH", -+ "DVB-S", -+ "DVB-S2", -+ "DVB-H", -+ "ISDBT", -+ "ISDBS", -+ "ISDBC", - "ATSC", -+ "ATSCMH", -+ "DMBTH", -+ "CMMB", -+ "DAB", - NULL - }; - -@@ -447,7 +465,7 @@ cDvbDevice::cDvbDevice(int n) - { - ciAdapter = NULL; - dvbTuner = NULL; -- frontendType = DVBFE_DELSYS_DUMMY; -+ frontendType = SYS_UNDEFINED; - numProvidedSystems = 0; - spuDecoder = NULL; - digitalAudio = false; -@@ -510,30 +528,29 @@ cDvbDevice::cDvbDevice(int n) - // We only check the devices that must be present - the others will be checked before accessing them://XXX - - if (fd_frontend >= 0) { -- if (ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0) { -- const char **DeliverySystem = DeliverySystems; -- cString ds; -+ if (ioctl(fd_frontend, FE_GET_INFO, &frontendInfo) >= 0) { - #ifdef USE_DVBSETUP - if (Setup.ChannelBlockerMode == 4) -- frontendType = n == Setup.PrimaryDVB - 1 ? DVBFE_DELSYS_DUMMY : frontendType; -+ frontendType = (n == Setup.PrimaryDVB - 1) ? SYS_UNDEFINED : frontendType; -+ else - #endif /* DVBSETUP */ -- for (int i = 0; i < 32; i++) { -- if (frontendType & (1u << i)) { -- numProvidedSystems++; -- if (*DeliverySystem) -- ds = cString::sprintf("%s %s", *ds ? *ds : "", *DeliverySystem); -- else -- esyslog("ERROR: unknown delivery system %d", i); -- } -- if (*DeliverySystem) -- DeliverySystem++; -- } -- if (*ds) -- isyslog("device %d provides:%s", CardIndex() + 1, *ds); -- dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType); -+ switch (frontendInfo.type) { -+ case FE_QPSK: frontendType = (frontendInfo.caps & FE_CAN_2G_MODULATION) ? SYS_DVBS2 : SYS_DVBS; break; -+ case FE_OFDM: frontendType = SYS_DVBT; break; -+ case FE_QAM: frontendType = SYS_DVBC_ANNEX_AC; break; -+ case FE_ATSC: frontendType = SYS_ATSC; break; -+ default: esyslog("ERROR: unknown frontend type %d on device %d", frontendInfo.type, CardIndex() + 1); -+ } - } - else - LOG_ERROR; -+ if (frontendType != SYS_UNDEFINED) { -+ numProvidedSystems++; -+ if (frontendType == SYS_DVBS2) -+ numProvidedSystems++; -+ isyslog("device %d provides %s (\"%s\")", CardIndex() + 1, DeliverySystems[frontendType], frontendInfo.name); -+ dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType); -+ } - } - else - esyslog("ERROR: can't open DVB device %d", n); -@@ -631,69 +648,103 @@ uchar *cDvbDevice::GrabImage(int &Size, - int videoDev = open(buffer, O_RDWR); - if (videoDev >= 0) { - uchar *result = NULL; -- struct video_mbuf mbuf; -- if (ioctl(videoDev, VIDIOCGMBUF, &mbuf) == 0) { -- int msize = mbuf.size; -- unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0); -- if (mem && mem != (unsigned char *)-1) { -- // set up the size and RGB -- struct video_capability vc; -- if (ioctl(videoDev, VIDIOCGCAP, &vc) == 0) { -- struct video_mmap vm; -- vm.frame = 0; -- if ((SizeX > 0) && (SizeX <= vc.maxwidth) && -- (SizeY > 0) && (SizeY <= vc.maxheight)) { -- vm.width = SizeX; -- vm.height = SizeY; -- } -- else { -- vm.width = vc.maxwidth; -- vm.height = vc.maxheight; -- } -- vm.format = VIDEO_PALETTE_RGB24; -- if (ioctl(videoDev, VIDIOCMCAPTURE, &vm) == 0 && ioctl(videoDev, VIDIOCSYNC, &vm.frame) == 0) { -- // make RGB out of BGR: -- int memsize = vm.width * vm.height; -- unsigned char *mem1 = mem; -- for (int i = 0; i < memsize; i++) { -- unsigned char tmp = mem1[2]; -- mem1[2] = mem1[0]; -- mem1[0] = tmp; -- mem1 += 3; -- } -- -- if (Quality < 0) -- Quality = 100; -- -- dsyslog("grabbing to %s %d %d %d", Jpeg ? "JPEG" : "PNM", Quality, vm.width, vm.height); -- if (Jpeg) { -- // convert to JPEG: -- result = RgbToJpeg(mem, vm.width, vm.height, Size, Quality); -- if (!result) -- esyslog("ERROR: failed to convert image to JPEG"); -- } -- else { -- // convert to PNM: -- char buf[32]; -- snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", vm.width, vm.height); -- int l = strlen(buf); -- int bytes = memsize * 3; -- Size = l + bytes; -- result = MALLOC(uchar, Size); -- if (result) { -- memcpy(result, buf, l); -- memcpy(result + l, mem, bytes); -+ // set up the size and RGB -+ v4l2_format fmt; -+ memset(&fmt, 0, sizeof(fmt)); -+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ fmt.fmt.pix.width = SizeX; -+ fmt.fmt.pix.height = SizeY; -+ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; -+ fmt.fmt.pix.field = V4L2_FIELD_ANY; -+ if (ioctl(videoDev, VIDIOC_S_FMT, &fmt) == 0) { -+ v4l2_requestbuffers reqBuf; -+ memset(&reqBuf, 0, sizeof(reqBuf)); -+ reqBuf.count = 2; -+ reqBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ reqBuf.memory = V4L2_MEMORY_MMAP; -+ if (ioctl(videoDev, VIDIOC_REQBUFS, &reqBuf) >= 0) { -+ v4l2_buffer mbuf; -+ memset(&mbuf, 0, sizeof(mbuf)); -+ mbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ mbuf.memory = V4L2_MEMORY_MMAP; -+ if (ioctl(videoDev, VIDIOC_QUERYBUF, &mbuf) == 0) { -+ int msize = mbuf.length; -+ unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0); -+ if (mem && mem != (unsigned char *)-1) { -+ v4l2_buffer buf; -+ memset(&buf, 0, sizeof(buf)); -+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ buf.memory = V4L2_MEMORY_MMAP; -+ buf.index = 0; -+ if (ioctl(videoDev, VIDIOC_QBUF, &buf) == 0) { -+ v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ if (ioctl (videoDev, VIDIOC_STREAMON, &type) == 0) { -+ memset(&buf, 0, sizeof(buf)); -+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ buf.memory = V4L2_MEMORY_MMAP; -+ buf.index = 0; -+ if (ioctl(videoDev, VIDIOC_DQBUF, &buf) == 0) { -+ if (ioctl(videoDev, VIDIOC_STREAMOFF, &type) == 0) { -+ // make RGB out of BGR: -+ int memsize = fmt.fmt.pix.width * fmt.fmt.pix.height; -+ unsigned char *mem1 = mem; -+ for (int i = 0; i < memsize; i++) { -+ unsigned char tmp = mem1[2]; -+ mem1[2] = mem1[0]; -+ mem1[0] = tmp; -+ mem1 += 3; -+ } -+ -+ if (Quality < 0) -+ Quality = 100; -+ -+ dsyslog("grabbing to %s %d %d %d", Jpeg ? "JPEG" : "PNM", Quality, fmt.fmt.pix.width, fmt.fmt.pix.height); -+ if (Jpeg) { -+ // convert to JPEG: -+ result = RgbToJpeg(mem, fmt.fmt.pix.width, fmt.fmt.pix.height, Size, Quality); -+ if (!result) -+ esyslog("ERROR: failed to convert image to JPEG"); -+ } -+ else { -+ // convert to PNM: -+ char buf[32]; -+ snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", fmt.fmt.pix.width, fmt.fmt.pix.height); -+ int l = strlen(buf); -+ int bytes = memsize * 3; -+ Size = l + bytes; -+ result = MALLOC(uchar, Size); -+ if (result) { -+ memcpy(result, buf, l); -+ memcpy(result + l, mem, bytes); -+ } -+ else -+ esyslog("ERROR: failed to convert image to PNM"); -+ } -+ } -+ else -+ esyslog("ERROR: video device VIDIOC_STREAMOFF failed"); -+ } -+ else -+ esyslog("ERROR: video device VIDIOC_DQBUF failed"); - } - else -- esyslog("ERROR: failed to convert image to PNM"); -+ esyslog("ERROR: video device VIDIOC_STREAMON failed"); - } -+ else -+ esyslog("ERROR: video device VIDIOC_QBUF failed"); -+ munmap(mem, msize); - } -+ else -+ esyslog("ERROR: failed to memmap video device"); - } -- munmap(mem, msize); -+ else -+ esyslog("ERROR: video device VIDIOC_QUERYBUF failed"); - } - else -- esyslog("ERROR: failed to memmap video device"); -+ esyslog("ERROR: video device VIDIOC_REQBUFS failed"); - } -+ else -+ esyslog("ERROR: video device VIDIOC_S_FMT failed"); - close(videoDev); - return result; - } -@@ -861,7 +912,7 @@ bool cDvbDevice::ProvidesSource(int Sour - { - int type = Source & cSource::st_Mask; - #ifdef USE_SOURCECAPS -- if (Setup.SourceCapsSet && type == cSource::stSat && (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2))) { -+ if (Setup.SourceCapsSet && type == cSource::stSat && (frontendType == SYS_DVBS || frontendType == SYS_DVBS2)) { - for (int i = 0; i < MAXSOURCECAPS; i++) - if (sourceCaps[i] == Source) - return true; -@@ -870,13 +921,13 @@ bool cDvbDevice::ProvidesSource(int Sour - else - #endif /* SOURCECAPS */ - return type == cSource::stNone -- || type == cSource::stCable && (frontendType & DVBFE_DELSYS_DVBC) -+ || type == cSource::stCable && (frontendType == SYS_DVBC_ANNEX_AC || frontendType == SYS_DVBC_ANNEX_B) -+ || type == cSource::stSat && (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) - #ifdef USE_ATSC -- || type == cSource::stCable && (frontendType & DVBFE_DELSYS_ATSC) -- || type == cSource::stTerr && (frontendType & DVBFE_DELSYS_ATSC) -+ || type == cSource::stTerr && (frontendType == SYS_DVBT || frontendType == SYS_ATSC); -+#else -+ || type == cSource::stTerr && (frontendType == SYS_DVBT); - #endif /* ATSC */ -- || type == cSource::stSat && (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) -- || type == cSource::stTerr && (frontendType & DVBFE_DELSYS_DVBT); - } - - bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const -@@ -901,7 +952,7 @@ bool cDvbDevice::ProvidesTransponder(con - return false; // doesn't provide source - if (!cSource::IsSat(Channel->Source())) - return true; // source is sufficient for non sat -- if (!(frontendType & Channel->System())) -+ if (frontendType == SYS_DVBS && Channel->System() == SYS_DVBS2) - return false; // requires modulation system which frontend doesn't provide - return !Setup.DiSEqC || Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); - } -@@ -1240,8 +1291,10 @@ void cDvbDevice::Play(void) - CHECK(ioctl(fd_audio, AUDIO_CONTINUE)); - } - else { -- if (fd_audio >= 0) -+ if (fd_audio >= 0) { - CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true)); -+ CHECK(ioctl(fd_audio, AUDIO_CONTINUE)); -+ } - if (fd_video >= 0) - CHECK(ioctl(fd_video, VIDEO_CONTINUE)); - } -@@ -1255,8 +1308,10 @@ void cDvbDevice::Freeze(void) - CHECK(ioctl(fd_audio, AUDIO_PAUSE)); - } - else { -- if (fd_audio >= 0) -+ if (fd_audio >= 0) { - CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false)); -+ CHECK(ioctl(fd_audio, AUDIO_PAUSE)); -+ } - if (fd_video >= 0) - CHECK(ioctl(fd_video, VIDEO_FREEZE)); - } -@@ -1274,7 +1329,13 @@ void cDvbDevice::Mute(void) - - void cDvbDevice::StillPicture(const uchar *Data, int Length) - { -- if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) { -+ if (!Data || Length < TS_SIZE) -+ return; -+ if (Data[0] == 0x47) { -+ // TS data -+ cDevice::StillPicture(Data, Length); -+ } -+ else if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) { - // PES data - char *buf = MALLOC(char, Length); - if (!buf) -@@ -1369,6 +1430,16 @@ int cDvbDevice::PlayAudio(const uchar *D - return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10); - } - -+int cDvbDevice::PlayTsVideo(const uchar *Data, int Length) -+{ -+ return WriteAllOrNothing(fd_video, Data, Length, 1000, 10); -+} -+ -+int cDvbDevice::PlayTsAudio(const uchar *Data, int Length) -+{ -+ return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10); -+} -+ - bool cDvbDevice::OpenDvr(void) - { - CloseDvr(); -diff -ruNp vdr-1.7.0-extensions/dvbdevice.h vdr-1.7.0-ext-h264-s2ng-speedup/dvbdevice.h ---- vdr-1.7.0-extensions/dvbdevice.h 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/dvbdevice.h 2009-04-12 13:37:59.000000000 +0200 -@@ -4,7 +4,7 @@ - * See the main source file 'vdr.c' for copyright information and - * how to reach the author. - * -- * $Id: dvbdevice.h 2.1 2008/04/12 11:20:48 kls Exp $ -+ * $Id: dvbdevice.h 2.3 2008/12/06 13:31:12 kls Exp $ - */ - - #ifndef __DVBDEVICE_H -@@ -15,8 +15,8 @@ - #include "device.h" - #include "dvbspu.h" - --#if DVB_API_VERSION != 3 || DVB_API_VERSION_MINOR != 3 --#error VDR requires Linux DVB driver API version 3.3! -+#if DVB_API_VERSION != 5 || DVB_API_VERSION_MINOR != 0 -+#error VDR requires Linux DVB driver API version 5.0! - #endif - - #define MAXDVBDEVICES 8 -@@ -35,8 +35,9 @@ public: - ///< Must be called before accessing any DVB functions. - ///< \return True if any devices are available. - private: -- dvbfe_delsys frontendType; -+ dvb_frontend_info frontendInfo; - int numProvidedSystems; -+ fe_delivery_system frontendType; - int fd_osd, fd_audio, fd_video, fd_dvr, fd_stc, fd_ca; - protected: - virtual void MakePrimaryDevice(bool On); -@@ -141,6 +142,8 @@ protected: - virtual bool SetPlayMode(ePlayMode PlayMode); - virtual int PlayVideo(const uchar *Data, int Length); - virtual int PlayAudio(const uchar *Data, int Length, uchar Id); -+ virtual int PlayTsVideo(const uchar *Data, int Length); -+ virtual int PlayTsAudio(const uchar *Data, int Length); - public: - virtual int64_t GetSTC(void); - virtual void TrickSpeed(int Speed); -diff -ruNp vdr-1.7.0-extensions/dvbplayer.c vdr-1.7.0-ext-h264-s2ng-speedup/dvbplayer.c ---- vdr-1.7.0-extensions/dvbplayer.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/dvbplayer.c 2009-04-12 23:57:23.000000000 +0200 -@@ -185,8 +185,8 @@ bool cNonBlockingFileReader::WaitForData - - #define PLAYERBUFSIZE MEGABYTE(1) - --// The number of frames to back up when resuming an interrupted replay session: --#define RESUMEBACKUP (10 * FRAMESPERSEC) -+// The number of seconds to back up when resuming an interrupted replay session: -+#define RESUMEBACKUP 10 - - class cDvbPlayer : public cPlayer, cThread { - private: -@@ -202,6 +202,7 @@ private: - cFileName *fileName; - cIndexFile *index; - cUnbufferedFile *replayFile; -+ int framesPerSec; - bool eof; - bool firstPacket; - ePlayModes playMode; -@@ -231,6 +232,7 @@ public: - void Goto(int Position, bool Still = false); - virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false); - virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed); -+ int GetFramesPerSec(void) { return framesPerSec; } - }; - - #define MAX_VIDEO_SLOWMOTION 63 // max. arg to pass to VIDEO_SLOWMOTION // TODO is this value correct? -@@ -263,6 +265,7 @@ cDvbPlayer::cDvbPlayer(const char *FileN - replayFile = fileName->Open(); - if (!replayFile) - return; -+ framesPerSec = replayFile->GetFramesPerSec(); - ringBuffer = new cRingBufferFrame(PLAYERBUFSIZE); - // Create the index file: - index = new cIndexFile(FileName, false); -@@ -385,7 +388,7 @@ bool cDvbPlayer::Save(void) - if (Setup.PlayJump && marks.First() && abs(Index - marks.First()->position) <= RESUMEBACKUP) - Index = 0; - #endif /* JUMPPLAY */ -- Index -= RESUMEBACKUP; -+ Index -= RESUMEBACKUP * GetFramesPerSec(); - if (Index > 0) - Index = index->GetNextIFrame(Index, false); - else -@@ -407,127 +410,6 @@ void cDvbPlayer::Activate(bool On) - Cancel(9); - } - --#ifdef USE_DVBPLAYER --// --- BEGIN fix for I frames ------------------------------------------- --// --// Prior to the introduction of cVideoRepacker, VDR didn't start a new --// PES packet when a new frame started. So, it was likely that the tail --// of an I frame was at the beginning of the packet which started the --// following B frame. Due to the organisation of VDR's index file, VDR --// typically didn't read the tail of the I frame and therefore caused --// softdevice plugins to not render such a frame as it was incomplete, --// e. g. when moving cutting marks. --// --// The following code tries to fix incomplete I frames for recordings --// made prior to the introdcution of cVideoRepacker, to be able to --// edit cutting marks for example with softdevice plugins like vdr-xine. --// -- --static uchar *findStartCode(uchar *Data, int Length, int &PesPayloadOffset) --{ -- uchar *limit = Data + Length; -- if (AnalyzePesHeader(Data, Length, PesPayloadOffset) <= phInvalid) -- return 0; // neither MPEG1 nor MPEG2 -- -- Data += PesPayloadOffset + 3; // move to video payload and skip 00 00 01 -- while (Data < limit) { -- // possible start codes that appear before/after picture data -- // 00 00 01 B3: sequence header code -- // 00 00 01 B8: group start code -- // 00 00 01 00: picture start code -- // 00 00 01 B7: sequence end code -- if (0x01 == Data[-1] && (0xB3 == Data[0] || 0xB8 == Data[0] || 0x00 == Data[0] || 0xB7 == Data[0]) && 0x00 == Data[-2] && 0x00 == Data[-3]) -- return Data - 3; -- Data++; -- } -- -- return 0; --} -- --static void fixIFrameHead(uchar *Data, int Length) --{ -- int pesPayloadOffset = 0; -- uchar *p = findStartCode(Data, Length, pesPayloadOffset); -- if (!p) { -- esyslog("fixIframeHead: start code not found!\n"); -- return; -- } -- -- Data += pesPayloadOffset; // move to video payload -- if (Data < p) -- memset(Data, 0, p - Data); // zero preceeding bytes --} -- --static int fixIFrameTail(uchar *Data, int Length) --{ -- int pesPayloadOffset = 0; -- uchar *p = findStartCode(Data, Length, pesPayloadOffset); -- if (!p) { -- esyslog("fixIframeTail: start code not found!\n"); -- return Length; -- } -- -- // is this PES packet required? -- uchar *videoPayload = Data + pesPayloadOffset; -- if (videoPayload >= p) -- return 0; // no -- -- // adjust PES length -- int lenPES = (p - Data); -- Data[4] = (lenPES - 6) >> 8; -- Data[5] = (lenPES - 6) & 0xFF; -- -- return lenPES; --} -- --#define IPACKS 2048 // originally defined in remux.c -- --static void fixIFrame(uchar *Data, int &Length, const int OriginalLength) --{ -- int done = 0; -- -- while (done < Length) { -- if (0x00 != Data[0] || 0x00 != Data[1] || 0x01 != Data[2]) { -- esyslog("fixIFrame: PES start code not found at offset %d (data length: %d, original length: %d)!", done, Length, OriginalLength); -- if (Length > OriginalLength) // roll back additional data -- Length = OriginalLength; -- return; -- } -- -- int lenPES = 6 + Data[4] * 256 + Data[5]; -- if (0xBA == Data[3]) { // pack header has fixed length -- if (0x00 == (0xC0 & Data[4])) -- lenPES = 12; // MPEG1 -- else -- lenPES = 14 + (Data[13] & 0x07); // MPEG2 -- } -- else if (0xB9 == Data[3]) // stream end has fixed length -- lenPES = 4; -- else if (0xE0 == (0xF0 & Data[3])) { // video packet -- int todo = Length - done; -- int bite = (lenPES < todo) ? lenPES : todo; -- if (0 == done) // first packet -- fixIFrameHead(Data, bite); -- else if (done >= OriginalLength) { // last packet -- Length = done + fixIFrameTail(Data, bite); -- return; -- } -- } -- else if (0 == done && 0xC0 == (0xE0 & Data[3])) { -- // if the first I frame packet is an audio packet then this is a radio recording: don't touch it! -- if (Length > OriginalLength) // roll back additional data -- Length = OriginalLength; -- return; -- } -- -- done += lenPES; -- Data += lenPES; -- } --} -- --// --- END fix for I frames --------------------------------------------- --#endif /* DVBPLAYER */ -- - void cDvbPlayer::Action(void) - { - uchar *b = NULL; -@@ -540,7 +422,7 @@ void cDvbPlayer::Action(void) - - readIndex = Resume(); - if (readIndex >= 0) -- isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true)); -+ isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true, GetFramesPerSec())); - - #ifdef USE_JUMPPLAY - if (Setup.PlayJump && readIndex <= 0 && marks.First() && index) { -@@ -550,7 +432,7 @@ void cDvbPlayer::Action(void) - if (index->Get(Index, &FileNumber, &FileOffset) && - NextFile(FileNumber, FileOffset)) { - isyslog("PlayJump: start replay at first mark %d (%s)", -- Index, *IndexToHMSF(Index, true)); -+ Index, *IndexToHMSF(Index, true, GetFramesPerSec())); - readIndex = Index; - } - } -@@ -599,9 +481,6 @@ void cDvbPlayer::Action(void) - if (!NextFile(FileNumber, FileOffset)) { - readIndex = Index; - continue; --#ifdef USE_DVBPLAYER -- Length += IPACKS; // fixIFrame needs next video packet --#endif /* DVBPLAYER */ - } - } - else { -@@ -688,10 +567,6 @@ void cDvbPlayer::Action(void) - int r = nonBlockingFileReader->Read(replayFile, b, Length); - if (r > 0) { - WaitingForData = false; --#ifdef USE_DVBPLAYER -- if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) -- fixIFrame(b, r, Length - IPACKS); --#endif /* DVBPLAYER */ - readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer - b = NULL; - } -@@ -933,7 +808,7 @@ void cDvbPlayer::SkipSeconds(int Seconds - Empty(); - int Index = writeIndex; - if (Index >= 0) { -- Index = max(Index + Seconds * FRAMESPERSEC, 0); -+ Index = max(Index + Seconds * GetFramesPerSec(), 0); - if (Index > 0) - Index = index->GetNextIFrame(Index, false, NULL, NULL, NULL, true); - if (Index >= 0) -@@ -954,15 +829,9 @@ void cDvbPlayer::Goto(int Index, bool St - int FileOffset, Length; - Index = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset, &Length); - if (Index >= 0 && NextFile(FileNumber, FileOffset) && Still) { --#ifdef USE_DVBPLAYER -- Length += IPACKS; // fixIFrame needs next video packet --#endif /* DVBPLAYER */ - uchar b[MAXFRAMESIZE + 4 + 5 + 4]; - int r = ReadFrame(replayFile, b, Length, sizeof(b)); - if (r > 0) { --#ifdef USE_DVBPLAYER -- fixIFrame(b, r, Length - IPACKS); --#endif /* DVBPLAYER */ - if (playMode == pmPause) - DevicePlay(); - // append sequence end code to get the image shown immediately with softdevices -@@ -986,7 +855,8 @@ void cDvbPlayer::Goto(int Index, bool St - b[r++] = 0x00; - b[r++] = 0x00; - b[r++] = 0x01; -- b[r++] = 0xB7; -+ b[r] = (cRemux::IsFrameH264(b, r) ? 10 : 0xB7); -+ r++; - } - DeviceStillPicture(b, r); - } -@@ -1106,3 +976,10 @@ void cDvbPlayerControl::Goto(int Positio - if (player) - player->Goto(Position, Still); - } -+ -+int cDvbPlayerControl::GetFramesPerSec() -+{ -+ if (player) -+ return player->GetFramesPerSec(); -+ return FRAMESPERSEC; -+} -diff -ruNp vdr-1.7.0-extensions/dvbplayer.h vdr-1.7.0-ext-h264-s2ng-speedup/dvbplayer.h ---- vdr-1.7.0-extensions/dvbplayer.h 2002-06-23 12:13:51.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/dvbplayer.h 2009-04-12 23:57:23.000000000 +0200 -@@ -54,6 +54,8 @@ public: - void Goto(int Index, bool Still = false); - // Positions to the given index and displays that frame as a still picture - // if Still is true. -+ int GetFramesPerSec(); -+ // Returns the number of frames per second for the current recording. - }; - - #endif //__DVBPLAYER_H -diff -ruNp vdr-1.7.0-extensions/epg.c vdr-1.7.0-ext-h264-s2ng-speedup/epg.c ---- vdr-1.7.0-extensions/epg.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/epg.c 2009-04-12 23:57:23.000000000 +0200 -@@ -1420,6 +1420,7 @@ cSchedule *cSchedules::AddSchedule(tChan - if (!p) { - p = new cSchedule(ChannelID); - Add(p); -+ HashSchedule(p); - cChannel *channel = Channels.GetByChannelID(ChannelID); - if (channel) - channel->schedule = p; -@@ -1430,10 +1431,14 @@ cSchedule *cSchedules::AddSchedule(tChan - const cSchedule *cSchedules::GetSchedule(tChannelID ChannelID) const - { - ChannelID.ClrRid(); -- for (cSchedule *p = First(); p; p = Next(p)) { -- if (p->ChannelID() == ChannelID) -- return p; -- } -+ cList<cHashObject> *list = schedulesHash.GetList(HashKey(ChannelID)); -+ if (list) { -+ for (cHashObject *hobj = list->First(); hobj; hobj = list->Next(hobj)) { -+ cSchedule *p = (cSchedule *)hobj->Object(); -+ if (p->ChannelID() == ChannelID) -+ return p; -+ } -+ } - return NULL; - } - -@@ -1449,7 +1454,23 @@ const cSchedule *cSchedules::GetSchedule - if (Channel->schedule == &DummySchedule && AddIfMissing) { - cSchedule *Schedule = new cSchedule(Channel->GetChannelID()); - ((cSchedules *)this)->Add(Schedule); -+ ((cSchedules *)this)->HashSchedule(Schedule); - Channel->schedule = Schedule; - } - return Channel->schedule != &DummySchedule? Channel->schedule : NULL; - } -+ -+void cSchedules::HashSchedule(cSchedule *Schedule) -+{ -+ schedulesHash.Add(Schedule, HashKey(Schedule->ChannelID().ClrRid())); -+} -+ -+void cSchedules::UnhashSchedule(cSchedule *Schedule) -+{ -+ schedulesHash.Del(Schedule, HashKey(Schedule->ChannelID().ClrRid())); -+} -+ -+unsigned int cSchedules::HashKey(tChannelID ChannelID) -+{ -+ return (unsigned int)((ChannelID.Nid() << 16 | ChannelID.Source()) ^ (ChannelID.Tid() << 16 | ChannelID.Sid()) ^ ChannelID.Rid()); -+} -diff -ruNp vdr-1.7.0-extensions/epg.h vdr-1.7.0-ext-h264-s2ng-speedup/epg.h ---- vdr-1.7.0-extensions/epg.h 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/epg.h 2009-04-12 23:57:23.000000000 +0200 -@@ -199,11 +199,15 @@ class cSchedules : public cList<cSchedul - friend class cSchedulesLock; - private: - cRwLock rwlock; -+ cHash<cSchedule> schedulesHash; - static cSchedules schedules; - static const char *epgDataFileName; - static time_t lastCleanup; - static time_t lastDump; - static time_t modified; -+ void HashSchedule(cSchedule *Schedule); -+ void UnhashSchedule(cSchedule *Schedule); -+ static unsigned int HashKey(tChannelID ChannelID); - public: - static void SetEpgDataFileName(const char *FileName); - static const cSchedules *Schedules(cSchedulesLock &SchedulesLock); -diff -ruNp vdr-1.7.0-extensions/h264parser.c vdr-1.7.0-ext-h264-s2ng-speedup/h264parser.c ---- vdr-1.7.0-extensions/h264parser.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/h264parser.c 2009-04-12 23:57:23.000000000 +0200 -@@ -0,0 +1,461 @@ -+/* -+ * h264parser.c: a minimalistic H.264 video stream parser -+ * -+ * See the main source file 'vdr.c' for copyright information and -+ * how to reach the author. -+ * -+ * The code was originally written by Reinhard Nissl <rnissl@gmx.de>, -+ * and adapted to the VDR coding style by Klaus.Schmidinger@cadsoft.de. -+ */ -+ -+#include "tools.h" -+#include "h264parser.h" -+ -+namespace H264 -+{ -+ // --- cContext ------------------------------------------------------------ -+ -+ int cContext::GetFramesPerSec(void) const -+ { -+ const cSequenceParameterSet *SPS = ActiveSPS(); -+ const cSliceHeader *SH = CurrentSlice(); -+ if (!SH || !SPS->timing_info_present_flag || !SPS->time_scale || !SPS->num_units_in_tick) -+ return -1; -+ uint32_t DeltaTfiDivisor; -+ if (SPS->pic_struct_present_flag) { -+ if (!SPS->pic_timing_sei.Defined()) -+ return -1; -+ switch (SPS->pic_timing_sei.pic_struct) { -+ case 1: -+ case 2: -+ DeltaTfiDivisor = 1; -+ break; -+ case 0: -+ case 3: -+ case 4: -+ DeltaTfiDivisor = 2; -+ break; -+ case 5: -+ case 6: -+ DeltaTfiDivisor = 3; -+ break; -+ case 7: -+ DeltaTfiDivisor = 4; -+ break; -+ case 8: -+ DeltaTfiDivisor = 6; -+ break; -+ default: -+ return -1; -+ } -+ } -+ else if (!SH->field_pic_flag) -+ DeltaTfiDivisor = 2; -+ else -+ DeltaTfiDivisor = 1; -+ -+ double FPS = (double)SPS->time_scale / SPS->num_units_in_tick / DeltaTfiDivisor / (SH->field_pic_flag ? 2 : 1); -+ int FramesPerSec = (int)FPS; -+ if ((FPS - FramesPerSec) >= 0.5) -+ FramesPerSec++; -+ return FramesPerSec; -+ } -+ -+ // --- cSimpleBuffer ------------------------------------------------------- -+ -+ cSimpleBuffer::cSimpleBuffer(int Size) -+ { -+ size = Size; -+ data = new uchar[size]; -+ avail = 0; -+ gotten = 0; -+ } -+ -+ cSimpleBuffer::~cSimpleBuffer() -+ { -+ delete [] data; -+ } -+ -+ int cSimpleBuffer::Put(const uchar *Data, int Count) -+ { -+ if (Count < 0) { -+ if (avail + Count < 0) -+ Count = 0 - avail; -+ if (avail + Count < gotten) -+ Count = gotten - avail; -+ avail += Count; -+ return Count; -+ } -+ if (avail + Count > size) -+ Count = size - avail; -+ memcpy(data + avail, Data, Count); -+ avail += Count; -+ return Count; -+ } -+ -+ uchar *cSimpleBuffer::Get(int &Count) -+ { -+ Count = gotten = avail; -+ return data; -+ } -+ -+ void cSimpleBuffer::Del(int Count) -+ { -+ if (Count < 0) -+ return; -+ if (Count > gotten) { -+ esyslog("ERROR: invalid Count in H264::cSimpleBuffer::Del: %d (limited to %d)", Count, gotten); -+ Count = gotten; -+ } -+ if (Count < avail) -+ memmove(data, data + Count, avail - Count); -+ avail -= Count; -+ gotten = 0; -+ } -+ -+ void cSimpleBuffer::Clear(void) -+ { -+ avail = gotten = 0; -+ } -+ -+ // --- cParser ------------------------------------------------------------- -+ -+ cParser::cParser(bool OmitPicTiming) -+ : nalUnitDataBuffer(1000) -+ { -+ // the above buffer size of 1000 bytes wont hold a complete NAL unit but -+ // should be sufficient for the relevant part used for parsing. -+ omitPicTiming = OmitPicTiming; // only necessary to determine frames per second -+ Reset(); -+ } -+ -+ void cParser::Reset(void) -+ { -+ context = cContext(); -+ nalUnitDataBuffer.Clear(); -+ syncing = true; -+ } -+ -+ void cParser::ParseSequenceParameterSet(uint8_t *Data, int Count) -+ { -+ cSequenceParameterSet SPS; -+ -+ cBitReader br(Data + 1, Count - 1); -+ uint32_t profile_idc = br.u(8); -+ /* uint32_t constraint_set0_flag = */ br.u(1); -+ /* uint32_t constraint_set1_flag = */ br.u(1); -+ /* uint32_t constraint_set2_flag = */ br.u(1); -+ /* uint32_t constraint_set3_flag = */ br.u(1); -+ /* uint32_t reserved_zero_4bits = */ br.u(4); -+ /* uint32_t level_idc = */ br.u(8); -+ SPS.seq_parameter_set_id = br.ue(); -+ if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 144) { -+ uint32_t chroma_format_idc = br.ue(); -+ if (chroma_format_idc == 3) { -+ /* uint32_t residual_colour_transform_flag = */ br.u(1); -+ } -+ /* uint32_t bit_depth_luma_minus8 = */ br.ue(); -+ /* uint32_t bit_depth_chroma_minus8 = */ br.ue(); -+ /* uint32_t qpprime_y_zero_transform_bypass_flag = */ br.u(1); -+ uint32_t seq_scaling_matrix_present_flag = br.u(1); -+ if (seq_scaling_matrix_present_flag) { -+ for (int i = 0; i < 8; i++) { -+ uint32_t seq_scaling_list_present_flag = br.u(1); -+ if (seq_scaling_list_present_flag) { -+ int sizeOfScalingList = (i < 6) ? 16 : 64; -+ int lastScale = 8; -+ int nextScale = 8; -+ for (int j = 0; j < sizeOfScalingList; j++) { -+ if (nextScale != 0) { -+ int32_t delta_scale = br.se(); -+ nextScale = (lastScale + delta_scale + 256) % 256; -+ } -+ lastScale = (nextScale == 0) ? lastScale : nextScale; -+ } -+ } -+ } -+ } -+ } -+ SPS.log2_max_frame_num_minus4(br.ue()); -+ SPS.pic_order_cnt_type = br.ue(); -+ if (SPS.pic_order_cnt_type == 0) -+ SPS.log2_max_pic_order_cnt_lsb_minus4(br.ue()); -+ else if (SPS.pic_order_cnt_type == 1) { -+ SPS.delta_pic_order_always_zero_flag = br.u(1); -+ /* int32_t offset_for_non_ref_pic = */ br.se(); -+ /* int32_t offset_for_top_to_bottom_field = */ br.se(); -+ uint32_t num_ref_frames_in_pic_order_cnt_cycle = br.ue(); -+ for (uint32_t i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) { -+ /* int32_t offset_for_ref_frame = */ br.se(); -+ } -+ } -+ /* uint32_t num_ref_frames = */ br.ue(); -+ /* uint32_t gaps_in_frame_num_value_allowed_flag = */ br.u(1); -+ /* uint32_t pic_width_in_mbs_minus1 = */ br.ue(); -+ /* uint32_t pic_height_in_map_units_minus1 = */ br.ue(); -+ SPS.frame_mbs_only_flag = br.u(1); -+ -+ if (!omitPicTiming) { -+ if (!SPS.frame_mbs_only_flag) { -+ /* uint32_t mb_adaptive_frame_field_flag = */ br.u(1); -+ } -+ /* uint32_t direct_8x8_inference_flag = */ br.u(1); -+ uint32_t frame_cropping_flag = br.u(1); -+ if (frame_cropping_flag) { -+ /* uint32_t frame_crop_left_offset = */ br.ue(); -+ /* uint32_t frame_crop_right_offset = */ br.ue(); -+ /* uint32_t frame_crop_top_offset = */ br.ue(); -+ /* uint32_t frame_crop_bottom_offset = */ br.ue(); -+ } -+ uint32_t vui_parameters_present_flag = br.u(1); -+ if (vui_parameters_present_flag) { -+ uint32_t aspect_ratio_info_present_flag = br.u(1); -+ if (aspect_ratio_info_present_flag) { -+ uint32_t aspect_ratio_idc = br.u(8); -+ const uint32_t Extended_SAR = 255; -+ if (aspect_ratio_idc == Extended_SAR) { -+ /* uint32_t sar_width = */ br.u(16); -+ /* uint32_t sar_height = */ br.u(16); -+ } -+ } -+ uint32_t overscan_info_present_flag = br.u(1); -+ if (overscan_info_present_flag) { -+ /* uint32_t overscan_appropriate_flag = */ br.u(1); -+ } -+ uint32_t video_signal_type_present_flag = br.u(1); -+ if (video_signal_type_present_flag) { -+ /* uint32_t video_format = */ br.u(3); -+ /* uint32_t video_full_range_flag = */ br.u(1); -+ uint32_t colour_description_present_flag = br.u(1); -+ if (colour_description_present_flag) { -+ /* uint32_t colour_primaries = */ br.u(8); -+ /* uint32_t transfer_characteristics = */ br.u(8); -+ /* uint32_t matrix_coefficients = */ br.u(8); -+ } -+ } -+ uint32_t chroma_loc_info_present_flag = br.u(1); -+ if (chroma_loc_info_present_flag) { -+ /* uint32_t chroma_sample_loc_type_top_field = */ br.ue(); -+ /* uint32_t chroma_sample_loc_type_bottom_field = */ br.ue(); -+ } -+ SPS.timing_info_present_flag = br.u(1); -+ if (SPS.timing_info_present_flag) { -+ SPS.num_units_in_tick = br.u(32); -+ SPS.time_scale = br.u(32); -+ SPS.fixed_frame_rate_flag = br.u(1); -+ } -+ SPS.nal_hrd_parameters_present_flag = br.u(1); -+ if (SPS.nal_hrd_parameters_present_flag) -+ hrd_parameters(SPS, br); -+ SPS.vcl_hrd_parameters_present_flag = br.u(1); -+ if (SPS.vcl_hrd_parameters_present_flag) -+ hrd_parameters(SPS, br); -+ if (SPS.nal_hrd_parameters_present_flag || SPS.vcl_hrd_parameters_present_flag) { -+ /* uint32_t low_delay_hrd_flag = */ br.u(1); -+ } -+ SPS.pic_struct_present_flag = br.u(1); -+ } -+ } -+ -+ context.Define(SPS); -+ } -+ -+ void cParser::hrd_parameters(cSequenceParameterSet &SPS, cBitReader &br) -+ { -+ uint32_t cpb_cnt_minus1 = br.ue(); -+ /* uint32_t bit_rate_scale = */ br.u(4); -+ /* uint32_t cpb_size_scale = */ br.u(4); -+ for (uint32_t i = 0; i <= cpb_cnt_minus1; i++) { -+ /* uint32_t bit_rate_value_minus1 = */ br.ue(); -+ /* uint32_t cpb_size_value_minus1 = */ br.ue(); -+ /* uint32_t cbr_flag = */ br.u(1); -+ } -+ /* uint32_t initial_cpb_removal_delay_length_minus1 = */ br.u(5); -+ SPS.cpb_removal_delay_length_minus1(br.u(5)); -+ SPS.dpb_output_delay_length_minus1(br.u(5)); -+ /* uint32_t time_offset_length = */ br.u(5); -+ } -+ -+ void cParser::ParsePictureParameterSet(uint8_t *Data, int Count) -+ { -+ cPictureParameterSet PPS; -+ -+ cBitReader br(Data + 1, Count - 1); -+ PPS.pic_parameter_set_id = br.ue(); -+ PPS.seq_parameter_set_id = br.ue(); -+ /* uint32_t entropy_coding_mode_flag = */ br.u(1); -+ PPS.pic_order_present_flag = br.u(1); -+ -+ context.Define(PPS); -+ } -+ -+ void cParser::ParseSlice(uint8_t *Data, int Count) -+ { -+ cSliceHeader SH; -+ -+ cBitReader br(Data + 1, Count - 1); -+ SH.nal_ref_idc(Data[0] >> 5); -+ SH.nal_unit_type(Data[0] & 0x1F); -+ /* uint32_t first_mb_in_slice = */ br.ue(); -+ SH.slice_type = br.ue(); -+ SH.pic_parameter_set_id = br.ue(); -+ -+ context.ActivatePPS(SH.pic_parameter_set_id); -+ const cSequenceParameterSet *SPS = context.ActiveSPS(); -+ -+ SH.frame_num = br.u(SPS->log2_max_frame_num()); -+ if (!SPS->frame_mbs_only_flag) { -+ SH.field_pic_flag = br.u(1); -+ if (SH.field_pic_flag) -+ SH.bottom_field_flag = br.u(1); -+ } -+ if (SH.nal_unit_type() == 5) -+ SH.idr_pic_id = br.ue(); -+ if (SPS->pic_order_cnt_type == 0) { -+ SH.pic_order_cnt_lsb = br.u(SPS->log2_max_pic_order_cnt_lsb()); -+ const cPictureParameterSet *PPS = context.ActivePPS(); -+ if (PPS->pic_order_present_flag && !SH.field_pic_flag) -+ SH.delta_pic_order_cnt_bottom = br.se(); -+ } -+ if (SPS->pic_order_cnt_type == 1 && !SPS->delta_pic_order_always_zero_flag) { -+ SH.delta_pic_order_cnt[0] = br.se(); -+ const cPictureParameterSet *PPS = context.ActivePPS(); -+ if (PPS->pic_order_present_flag && !SH.field_pic_flag) -+ SH.delta_pic_order_cnt[1] = br.se(); -+ } -+ -+ context.Define(SH); -+ } -+ -+ void cParser::ParseSEI(uint8_t *Data, int Count) -+ { -+ // currently only used to determine frames per second -+ if (omitPicTiming) -+ return; -+ cBitReader br(Data + 1, Count - 1); -+ do -+ sei_message(br); -+ while (br.GetBytesAvail()); -+ } -+ -+ void cParser::sei_message(cBitReader &br) -+ { -+ uint32_t payloadType = 0; -+ while (1) { -+ uint32_t last_payload_type_byte = br.u(8); -+ payloadType += last_payload_type_byte; -+ if (last_payload_type_byte != 0xFF) -+ break; -+ } -+ uint32_t payloadSize = 0; -+ while (1) { -+ uint32_t last_payload_size_byte = br.u(8); -+ payloadSize += last_payload_size_byte; -+ if (last_payload_size_byte != 0xFF) -+ break; -+ } -+ sei_payload(payloadType, payloadSize, br); -+ } -+ -+ void cParser::sei_payload(uint32_t payloadType, uint32_t payloadSize, cBitReader &br) -+ { -+ const cBitReader::cBookMark BookMark = br.BookMark(); -+ switch (payloadType) { -+ case 0: -+ buffering_period(payloadSize, br); -+ break; -+ case 1: -+ pic_timing(payloadSize, br); -+ break; -+ } -+ // instead of dealing with trailing bits in each message -+ // go back to start of message and skip it completely -+ br.BookMark(BookMark); -+ reserved_sei_message(payloadSize, br); -+ } -+ -+ void cParser::buffering_period(uint32_t payloadSize, cBitReader &br) -+ { -+ uint32_t seq_parameter_set_id = br.ue(); -+ -+ context.ActivateSPS(seq_parameter_set_id); -+ } -+ -+ void cParser::pic_timing(uint32_t payloadSize, cBitReader &br) -+ { -+ cPictureTiming PT; -+ -+ const cSequenceParameterSet *SPS = context.ActiveSPS(); -+ if (!SPS) -+ return; -+ uint32_t CpbDpbDelaysPresentFlag = SPS->nal_hrd_parameters_present_flag || SPS->vcl_hrd_parameters_present_flag; -+ if (CpbDpbDelaysPresentFlag) { -+ /* uint32_t cpb_removal_delay = */ br.u(SPS->cpb_removal_delay_length()); -+ /* uint32_t dpb_output_delay = */ br.u(SPS->dpb_output_delay_length()); -+ } -+ if (SPS->pic_struct_present_flag) { -+ PT.pic_struct = br.u(4); -+ } -+ -+ context.Define(PT); -+ } -+ -+ void cParser::reserved_sei_message(uint32_t payloadSize, cBitReader &br) -+ { -+ for (uint32_t i = 0; i < payloadSize; i++) { -+ /* uint32_t reserved_sei_message_payload_byte = */ br.u(8); -+ } -+ } -+ -+ void cParser::PutNalUnitData(const uchar *Data, int Count) -+ { -+ int n = nalUnitDataBuffer.Put(Data, Count); -+ // typically less than a complete NAL unit are needed for parsing the -+ // relevant data, so simply ignore the overflow condition. -+ if (false && n != Count) -+ esyslog("ERROR: H264::cParser::PutNalUnitData(): NAL unit data buffer overflow"); -+ } -+ -+ void cParser::Process() -+ { -+ // nalUnitDataBuffer contains the head of the current NAL unit -- let's parse it -+ int Count = 0; -+ uchar *Data = nalUnitDataBuffer.Get(Count); -+ if (Data && Count >= 4) { -+ if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01) { -+ int nal_unit_type = Data[3] & 0x1F; -+ try { -+ switch (nal_unit_type) { -+ case 1: // coded slice of a non-IDR picture -+ case 2: // coded slice data partition A -+ case 5: // coded slice of an IDR picture -+ ParseSlice(Data + 3, Count - 3); -+ break; -+ case 6: // supplemental enhancement information (SEI) -+ ParseSEI(Data + 3, Count - 3); -+ break; -+ case 7: // sequence parameter set -+ syncing = false; // from now on, we should get reliable results -+ ParseSequenceParameterSet(Data + 3, Count - 3); -+ break; -+ case 8: // picture parameter set -+ ParsePictureParameterSet(Data + 3, Count - 3); -+ break; -+ } -+ } -+ catch (cException *e) { -+ if (!syncing) // suppress typical error messages while syncing -+ esyslog(e->Message()); -+ delete e; -+ } -+ } -+ else if (!syncing) -+ esyslog("ERROR: H264::cParser::Process(): NAL unit data buffer content is invalid"); -+ } -+ else if (!syncing) -+ esyslog("ERROR: H264::cParser::Process(): NAL unit data buffer content is too short"); -+ // reset the buffer for the next NAL unit -+ nalUnitDataBuffer.Clear(); -+ } -+} -+ -diff -ruNp vdr-1.7.0-extensions/h264parser.h vdr-1.7.0-ext-h264-s2ng-speedup/h264parser.h ---- vdr-1.7.0-extensions/h264parser.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/h264parser.h 2009-04-12 23:57:23.000000000 +0200 -@@ -0,0 +1,397 @@ -+/* -+ * h264parser.h: a minimalistic H.264 video stream parser -+ * -+ * See the main source file 'vdr.c' for copyright information and -+ * how to reach the author. -+ */ -+ -+#ifndef __H264PARSER_H -+#define __H264PARSER_H -+ -+namespace H264 -+{ -+ // --- cException ---------------------------------------------------------- -+ -+ class cException { -+ private: -+ cString message; -+ public: -+ cException(const cString &Message) { message = Message; } -+ const cString &Message(void) const { return message; } -+ }; -+ -+ // --- cBitReader ---------------------------------------------------------- -+ -+ class cBitReader { -+ public: -+ class cBookMark { -+ private: -+ uint8_t *data; -+ int count; -+ uint32_t bits; -+ uint32_t bitsAvail; -+ int countZeros; -+ cBookMark(void) {} -+ friend class cBitReader; -+ }; -+ private: -+ cBookMark bm; -+ uint8_t NextByte(void); -+ uint32_t ReadBits(uint32_t n); -+ public: -+ cBitReader(uint8_t *Data, int Count); -+ uint32_t u(uint32_t n) { return ReadBits(n); } // read n bits as unsigned number -+ uint32_t ue(void); // read Exp-Golomb coded unsigned number -+ int32_t se(void); // read Exp-Golomb coded signed number -+ uint32_t GetBitsAvail(void) { return (bm.bitsAvail & 0x07); } -+ bool GetBytesAvail(void) { return (bm.count > 0); } -+ const cBookMark BookMark(void) const { return bm; } -+ void BookMark(const cBookMark &b) { bm = b; } -+ }; -+ -+ inline cBitReader::cBitReader(unsigned char *Data, int Count) -+ { -+ bm.data = Data; -+ bm.count = Count; -+ bm.bitsAvail = 0; -+ bm.countZeros = 0; -+ } -+ -+ inline uint8_t cBitReader::NextByte(void) -+ { -+ if (bm.count < 1) // there is no more data left in this NAL unit -+ throw new cException("ERROR: H264::cBitReader::NextByte(): premature end of data"); -+ // detect 00 00 00, 00 00 01 and 00 00 03 and handle them -+ if (*bm.data == 0x00) { -+ if (bm.countZeros >= 3) // 00 00 00: the current NAL unit should have been terminated already before this sequence -+ throw new cException("ERROR: H264::cBitReader::NextByte(): premature end of data"); -+ // increase the zero counter as we have a zero byte -+ bm.countZeros++; -+ } -+ else { -+ if (bm.countZeros >= 2) { -+ if (*bm.data == 0x01) // 00 00 01: the current NAL unit should have been terminated already before this sequence -+ throw new cException("ERROR: H264::cBitReader::NextByte(): premature end of data"); -+ if (*bm.data == 0x03) { -+ // 00 00 03 xx: the emulation prevention byte 03 needs to be removed and xx must be returned -+ if (bm.count < 2) -+ throw new cException("ERROR: H264::cBitReader::NextByte(): premature end of data"); -+ // drop 03 and xx will be returned below -+ bm.count--; -+ bm.data++; -+ } -+ } -+ // reset the zero counter as we had a non zero byte -+ bm.countZeros = 0; -+ } -+ bm.count--; -+ return *bm.data++; -+ } -+ -+ inline uint32_t cBitReader::ReadBits(uint32_t n) -+ { -+ // fill the "shift register" bits with sufficient data -+ while (n > bm.bitsAvail) { -+ bm.bits <<= 8; -+ bm.bits |= NextByte(); -+ bm.bitsAvail += 8; -+ if (bm.bitsAvail > 24) { // a further turn will overflow bitbuffer -+ if (n <= bm.bitsAvail) -+ break; // service non overflowing request -+ if (n <= 32) // split overflowing reads into concatenated reads -+ return (ReadBits(16) << 16) | ReadBits(n - 16); -+ // cannot read more than 32 bits at once -+ throw new cException("ERROR: H264::cBitReader::ReadBits(): bitbuffer overflow"); -+ } -+ } -+ // return n most significant bits -+ bm.bitsAvail -= n; -+ return (bm.bits >> bm.bitsAvail) & (((uint32_t)1 << n) - 1); -+ } -+ -+ inline uint32_t cBitReader::ue(void) -+ { -+ // read and decode an Exp-Golomb coded unsigned number -+ // -+ // bitstring resulting number -+ // 1 0 -+ // 0 1 x 1 ... 2 -+ // 0 0 1 x y 3 ... 6 -+ // 0 0 0 1 x y z 7 ... 14 -+ // ... -+ int LeadingZeroBits = 0; -+ while (ReadBits(1) == 0) -+ LeadingZeroBits++; -+ if (LeadingZeroBits == 0) -+ return 0; -+ if (LeadingZeroBits >= 32) -+ throw new cException("ERROR: H264::cBitReader::ue(): overflow"); -+ return ((uint32_t)1 << LeadingZeroBits) - 1 + ReadBits(LeadingZeroBits); -+ } -+ -+ inline int32_t cBitReader::se(void) -+ { -+ // read and decode an Exp-Golomb coded signed number -+ // -+ // unsigned value resulting signed value -+ // 0 0 -+ // 1 +1 -+ // 2 -1 -+ // 3 +2 -+ // 4 -2 -+ // ... -+ uint32_t r = ue(); -+ if (r > 0xFFFFFFFE) -+ throw new cException("ERROR: H264::cBitReader::se(): overflow"); -+ return (1 - 2 * (r & 1)) * ((r + 1) / 2); -+ } -+ -+ // --- cPictureTiming ------------------------------------------------------ -+ -+ class cPictureTiming { -+ private: -+ friend class cContext; -+ bool defined; -+ public: -+ cPictureTiming(void) { memset(this, 0, sizeof (*this)); } -+ bool Defined(void) const { return defined; } -+ uint32_t pic_struct; -+ }; -+ -+ // --- cSequenceParameterSet ----------------------------------------------- -+ -+ class cSequenceParameterSet { -+ private: -+ friend class cContext; -+ bool defined; -+ uint32_t log2MaxFrameNum; -+ uint32_t log2MaxPicOrderCntLsb; -+ uint32_t cpbRemovalDelayLength; -+ uint32_t dpbOutputDelayLength; -+ public: -+ cSequenceParameterSet(void); -+ bool Defined(void) { return defined; } -+ void log2_max_frame_num_minus4(uint32_t Value) { log2MaxFrameNum = Value + 4; } -+ uint32_t log2_max_frame_num_minus4(void) const { return log2MaxFrameNum - 4; } -+ uint32_t log2_max_frame_num(void) const { return log2MaxFrameNum; } -+ void log2_max_pic_order_cnt_lsb_minus4(uint32_t Value) { log2MaxPicOrderCntLsb = Value + 4; } -+ uint32_t log2_max_pic_order_cnt_lsb_minus4(void) const { return log2MaxPicOrderCntLsb - 4; } -+ uint32_t log2_max_pic_order_cnt_lsb(void) const { return log2MaxPicOrderCntLsb; } -+ void cpb_removal_delay_length_minus1(uint32_t Value) { cpbRemovalDelayLength = Value + 1; } -+ uint32_t cpb_removal_delay_length_minus1(void) const { return cpbRemovalDelayLength - 1; } -+ uint32_t cpb_removal_delay_length(void) const { return cpbRemovalDelayLength; } -+ void dpb_output_delay_length_minus1(uint32_t Value) { dpbOutputDelayLength = Value + 1; } -+ uint32_t dpb_output_delay_length_minus1(void) const { return dpbOutputDelayLength - 1; } -+ uint32_t dpb_output_delay_length(void) const { return dpbOutputDelayLength; } -+ uint32_t seq_parameter_set_id; -+ uint32_t pic_order_cnt_type; -+ uint32_t delta_pic_order_always_zero_flag; -+ uint32_t frame_mbs_only_flag; -+ uint32_t timing_info_present_flag; -+ uint32_t num_units_in_tick; -+ uint32_t time_scale; -+ uint32_t fixed_frame_rate_flag; -+ uint32_t nal_hrd_parameters_present_flag; -+ uint32_t vcl_hrd_parameters_present_flag; -+ uint32_t pic_struct_present_flag; -+ cPictureTiming pic_timing_sei; -+ }; -+ -+ inline cSequenceParameterSet::cSequenceParameterSet(void) -+ { -+ memset(this, 0, sizeof (*this)); -+ log2_max_frame_num_minus4(0); -+ log2_max_pic_order_cnt_lsb_minus4(0); -+ cpb_removal_delay_length_minus1(23); -+ dpb_output_delay_length_minus1(23); -+ } -+ -+ // --- cPictureParameterSet ------------------------------------------------ -+ -+ class cPictureParameterSet { -+ private: -+ friend class cContext; -+ bool defined; -+ public: -+ cPictureParameterSet(void) { memset(this, 0, sizeof (*this)); } -+ bool Defined(void) { return defined; } -+ uint32_t pic_parameter_set_id; -+ uint32_t seq_parameter_set_id; -+ uint32_t pic_order_present_flag; -+ }; -+ -+ // --- cSliceHeader -------------------------------------------------------- -+ -+ class cSliceHeader { -+ private: -+ friend class cContext; -+ bool defined; -+ bool isFirstSliceOfCurrentAccessUnit; -+ uint32_t picOrderCntType; -+ uint32_t nalRefIdc; -+ uint32_t nalUnitType; -+ public: -+ cSliceHeader(void) { memset(this, 0, sizeof (*this)); } -+ bool Defined(void) const { return defined; } -+ bool IsFirstSliceOfCurrentAccessUnit(void) const { return isFirstSliceOfCurrentAccessUnit; } -+ void nal_ref_idc(uint32_t Value) { nalRefIdc = Value; } -+ uint32_t nal_ref_idc(void) const { return nalRefIdc; } -+ void nal_unit_type(uint32_t Value) { nalUnitType = Value; } -+ uint32_t nal_unit_type(void) const { return nalUnitType; } -+ uint32_t slice_type; -+ uint32_t pic_parameter_set_id; -+ uint32_t frame_num; -+ uint32_t field_pic_flag; -+ uint32_t bottom_field_flag; -+ uint32_t idr_pic_id; -+ uint32_t pic_order_cnt_lsb; -+ int32_t delta_pic_order_cnt_bottom; -+ int32_t delta_pic_order_cnt[2]; -+ enum eAccessUnitType { -+ Frame = 0, -+ TopField, -+ BottomField -+ }; -+ eAccessUnitType GetAccessUnitType() const { return (eAccessUnitType)(field_pic_flag + bottom_field_flag); } -+ }; -+ -+ // --- cContext ------------------------------------------------------------ -+ -+ class cContext { -+ private: -+ cSequenceParameterSet spsStore[32]; -+ cPictureParameterSet ppsStore[256]; -+ cSequenceParameterSet *sps; // active Sequence Parameter Set -+ cPictureParameterSet *pps; // active Picture Parameter Set -+ cSliceHeader sh; -+ public: -+ cContext(void) { sps = 0; pps = 0; } -+ void Define(cSequenceParameterSet &SPS); -+ void Define(cPictureParameterSet &PPS); -+ void Define(cSliceHeader &SH); -+ void Define(cPictureTiming &PT); -+ void ActivateSPS(uint32_t ID); -+ void ActivatePPS(uint32_t ID); -+ const cSequenceParameterSet *ActiveSPS(void) const { return sps; } -+ const cPictureParameterSet *ActivePPS(void) const { return pps; } -+ const cSliceHeader *CurrentSlice(void) const { return sh.Defined() ? &sh : 0; } -+ int GetFramesPerSec(void) const; -+ }; -+ -+ inline void cContext::ActivateSPS(uint32_t ID) -+ { -+ if (ID >= (sizeof (spsStore) / sizeof (*spsStore))) -+ throw new cException("ERROR: H264::cContext::ActivateSPS(): id out of range"); -+ if (!spsStore[ID].Defined()) -+ throw new cException("ERROR: H264::cContext::ActivateSPS(): requested SPS is undefined"); -+ sps = &spsStore[ID]; -+ } -+ -+ inline void cContext::ActivatePPS(uint32_t ID) -+ { -+ if (ID >= (sizeof (ppsStore) / sizeof (*ppsStore))) -+ throw new cException("ERROR: H264::cContext::ActivatePPS(): id out of range"); -+ if (!ppsStore[ID].Defined()) -+ throw new cException("ERROR: H264::cContext::ActivatePPS(): requested PPS is undefined"); -+ pps = &ppsStore[ID]; -+ ActivateSPS(pps->seq_parameter_set_id); -+ } -+ -+ inline void cContext::Define(cSequenceParameterSet &SPS) -+ { -+ if (SPS.seq_parameter_set_id >= (sizeof (spsStore) / sizeof (*spsStore))) -+ throw new cException("ERROR: H264::cContext::DefineSPS(): id out of range"); -+ SPS.defined = true; -+ spsStore[SPS.seq_parameter_set_id] = SPS; -+ } -+ -+ inline void cContext::Define(cPictureParameterSet &PPS) -+ { -+ if (PPS.pic_parameter_set_id >= (sizeof (ppsStore) / sizeof (*ppsStore))) -+ throw new cException("ERROR: H264::cContext::DefinePPS(): id out of range"); -+ PPS.defined = true; -+ ppsStore[PPS.pic_parameter_set_id] = PPS; -+ } -+ -+ inline void cContext::Define(cSliceHeader &SH) -+ { -+ SH.defined = true; -+ SH.picOrderCntType = ActiveSPS()->pic_order_cnt_type; -+ -+ // ITU-T Rec. H.264 (03/2005): 7.4.1.2.4 -+ SH.isFirstSliceOfCurrentAccessUnit = !sh.Defined() -+ || (sh.frame_num != SH.frame_num) -+ || (sh.pic_parameter_set_id != SH.pic_parameter_set_id) -+ || (sh.field_pic_flag != SH.field_pic_flag) -+ || (sh.bottom_field_flag != SH.bottom_field_flag) -+ || (sh.nalRefIdc != SH.nalRefIdc -+ && (sh.nalRefIdc == 0 || SH.nalRefIdc == 0)) -+ || (sh.picOrderCntType == 0 && SH.picOrderCntType == 0 -+ && (sh.pic_order_cnt_lsb != SH.pic_order_cnt_lsb -+ || sh.delta_pic_order_cnt_bottom != SH.delta_pic_order_cnt_bottom)) -+ || (sh.picOrderCntType == 1 && SH.picOrderCntType == 1 -+ && (sh.delta_pic_order_cnt[0] != SH.delta_pic_order_cnt[0] -+ || sh.delta_pic_order_cnt[1] != SH.delta_pic_order_cnt[1])) -+ || (sh.nalUnitType != SH.nalUnitType -+ && (sh.nalUnitType == 5 || SH.nalUnitType == 5)) -+ || (sh.nalUnitType == 5 && SH.nalUnitType == 5 -+ && sh.idr_pic_id != SH.idr_pic_id); -+ -+ sh = SH; -+ } -+ -+ inline void cContext::Define(cPictureTiming &PT) -+ { -+ PT.defined = true; -+ ((cSequenceParameterSet *)ActiveSPS())->pic_timing_sei = PT; -+ } -+ -+ // --- cSimpleBuffer ------------------------------------------------------- -+ -+ class cSimpleBuffer { -+ private: -+ uchar *data; -+ int size; -+ int avail; -+ int gotten; -+ public: -+ cSimpleBuffer(int Size); -+ ~cSimpleBuffer(); -+ int Size(void) { return size; } -+ int Available(void) { return avail; } -+ int Free(void) { return size - avail; } -+ int Put(const uchar *Data, int Count); -+ uchar *Get(int &Count); -+ void Del(int Count); -+ void Clear(void); -+ }; -+ -+ // --- cParser ------------------------------------------------------------- -+ -+ class cParser { -+ private: -+ bool syncing; -+ bool omitPicTiming; -+ cContext context; -+ cSimpleBuffer nalUnitDataBuffer; -+ void hrd_parameters(cSequenceParameterSet &SPS, cBitReader &br); -+ void ParseSequenceParameterSet(uint8_t *Data, int Count); -+ void ParsePictureParameterSet(uint8_t *Data, int Count); -+ void ParseSlice(uint8_t *Data, int Count); -+ void reserved_sei_message(uint32_t payloadSize, cBitReader &br); -+ void pic_timing(uint32_t payloadSize, cBitReader &br); -+ void buffering_period(uint32_t payloadSize, cBitReader &br); -+ void sei_payload(uint32_t payloadType, uint32_t payloadSize, cBitReader &br); -+ void sei_message(cBitReader &br); -+ void ParseSEI(uint8_t *Data, int Count); -+ public: -+ cParser(bool OmitPicTiming = true); -+ const cContext &Context(void) const { return context; } -+ void PutNalUnitData(const uchar *Data, int Count); -+ void Reset(void); -+ void Process(void); -+ }; -+} -+ -+#endif // __H264PARSER_H -+ -diff -ruNp vdr-1.7.0-extensions/libsi/util.c vdr-1.7.0-ext-h264-s2ng-speedup/libsi/util.c ---- vdr-1.7.0-extensions/libsi/util.c 2006-02-18 12:17:50.000000000 +0100 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/libsi/util.c 2009-04-12 23:57:23.000000000 +0200 -@@ -219,58 +219,73 @@ time_t DVBTime::getDuration(unsigned cha - - //taken and adapted from libdtv, (c) Rolf Hakenes - // CRC32 lookup table for polynomial 0x04c11db7 -+// swapped bytes to avoid one shift operation in CRC loop (c) Reinhard Nissl - u_int32_t CRC32::crc_table[256] = { -- 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, -- 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, -- 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, -- 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, -- 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, -- 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, -- 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, -- 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, -- 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, -- 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, -- 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, -- 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, -- 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, -- 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, -- 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, -- 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, -- 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, -- 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, -- 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, -- 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, -- 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, -- 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, -- 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, -- 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, -- 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, -- 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, -- 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, -- 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, -- 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, -- 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, -- 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, -- 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, -- 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, -- 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, -- 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, -- 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, -- 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, -- 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, -- 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, -- 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, -- 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, -- 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, -- 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4}; -+ 0x00000000, 0xb71dc104, 0x6e3b8209, 0xd926430d, 0xdc760413, 0x6b6bc517, -+ 0xb24d861a, 0x0550471e, 0xb8ed0826, 0x0ff0c922, 0xd6d68a2f, 0x61cb4b2b, -+ 0x649b0c35, 0xd386cd31, 0x0aa08e3c, 0xbdbd4f38, 0x70db114c, 0xc7c6d048, -+ 0x1ee09345, 0xa9fd5241, 0xacad155f, 0x1bb0d45b, 0xc2969756, 0x758b5652, -+ 0xc836196a, 0x7f2bd86e, 0xa60d9b63, 0x11105a67, 0x14401d79, 0xa35ddc7d, -+ 0x7a7b9f70, 0xcd665e74, 0xe0b62398, 0x57abe29c, 0x8e8da191, 0x39906095, -+ 0x3cc0278b, 0x8bdde68f, 0x52fba582, 0xe5e66486, 0x585b2bbe, 0xef46eaba, -+ 0x3660a9b7, 0x817d68b3, 0x842d2fad, 0x3330eea9, 0xea16ada4, 0x5d0b6ca0, -+ 0x906d32d4, 0x2770f3d0, 0xfe56b0dd, 0x494b71d9, 0x4c1b36c7, 0xfb06f7c3, -+ 0x2220b4ce, 0x953d75ca, 0x28803af2, 0x9f9dfbf6, 0x46bbb8fb, 0xf1a679ff, -+ 0xf4f63ee1, 0x43ebffe5, 0x9acdbce8, 0x2dd07dec, 0x77708634, 0xc06d4730, -+ 0x194b043d, 0xae56c539, 0xab068227, 0x1c1b4323, 0xc53d002e, 0x7220c12a, -+ 0xcf9d8e12, 0x78804f16, 0xa1a60c1b, 0x16bbcd1f, 0x13eb8a01, 0xa4f64b05, -+ 0x7dd00808, 0xcacdc90c, 0x07ab9778, 0xb0b6567c, 0x69901571, 0xde8dd475, -+ 0xdbdd936b, 0x6cc0526f, 0xb5e61162, 0x02fbd066, 0xbf469f5e, 0x085b5e5a, -+ 0xd17d1d57, 0x6660dc53, 0x63309b4d, 0xd42d5a49, 0x0d0b1944, 0xba16d840, -+ 0x97c6a5ac, 0x20db64a8, 0xf9fd27a5, 0x4ee0e6a1, 0x4bb0a1bf, 0xfcad60bb, -+ 0x258b23b6, 0x9296e2b2, 0x2f2bad8a, 0x98366c8e, 0x41102f83, 0xf60dee87, -+ 0xf35da999, 0x4440689d, 0x9d662b90, 0x2a7bea94, 0xe71db4e0, 0x500075e4, -+ 0x892636e9, 0x3e3bf7ed, 0x3b6bb0f3, 0x8c7671f7, 0x555032fa, 0xe24df3fe, -+ 0x5ff0bcc6, 0xe8ed7dc2, 0x31cb3ecf, 0x86d6ffcb, 0x8386b8d5, 0x349b79d1, -+ 0xedbd3adc, 0x5aa0fbd8, 0xeee00c69, 0x59fdcd6d, 0x80db8e60, 0x37c64f64, -+ 0x3296087a, 0x858bc97e, 0x5cad8a73, 0xebb04b77, 0x560d044f, 0xe110c54b, -+ 0x38368646, 0x8f2b4742, 0x8a7b005c, 0x3d66c158, 0xe4408255, 0x535d4351, -+ 0x9e3b1d25, 0x2926dc21, 0xf0009f2c, 0x471d5e28, 0x424d1936, 0xf550d832, -+ 0x2c769b3f, 0x9b6b5a3b, 0x26d61503, 0x91cbd407, 0x48ed970a, 0xfff0560e, -+ 0xfaa01110, 0x4dbdd014, 0x949b9319, 0x2386521d, 0x0e562ff1, 0xb94beef5, -+ 0x606dadf8, 0xd7706cfc, 0xd2202be2, 0x653deae6, 0xbc1ba9eb, 0x0b0668ef, -+ 0xb6bb27d7, 0x01a6e6d3, 0xd880a5de, 0x6f9d64da, 0x6acd23c4, 0xddd0e2c0, -+ 0x04f6a1cd, 0xb3eb60c9, 0x7e8d3ebd, 0xc990ffb9, 0x10b6bcb4, 0xa7ab7db0, -+ 0xa2fb3aae, 0x15e6fbaa, 0xccc0b8a7, 0x7bdd79a3, 0xc660369b, 0x717df79f, -+ 0xa85bb492, 0x1f467596, 0x1a163288, 0xad0bf38c, 0x742db081, 0xc3307185, -+ 0x99908a5d, 0x2e8d4b59, 0xf7ab0854, 0x40b6c950, 0x45e68e4e, 0xf2fb4f4a, -+ 0x2bdd0c47, 0x9cc0cd43, 0x217d827b, 0x9660437f, 0x4f460072, 0xf85bc176, -+ 0xfd0b8668, 0x4a16476c, 0x93300461, 0x242dc565, 0xe94b9b11, 0x5e565a15, -+ 0x87701918, 0x306dd81c, 0x353d9f02, 0x82205e06, 0x5b061d0b, 0xec1bdc0f, -+ 0x51a69337, 0xe6bb5233, 0x3f9d113e, 0x8880d03a, 0x8dd09724, 0x3acd5620, -+ 0xe3eb152d, 0x54f6d429, 0x7926a9c5, 0xce3b68c1, 0x171d2bcc, 0xa000eac8, -+ 0xa550add6, 0x124d6cd2, 0xcb6b2fdf, 0x7c76eedb, 0xc1cba1e3, 0x76d660e7, -+ 0xaff023ea, 0x18ede2ee, 0x1dbda5f0, 0xaaa064f4, 0x738627f9, 0xc49be6fd, -+ 0x09fdb889, 0xbee0798d, 0x67c63a80, 0xd0dbfb84, 0xd58bbc9a, 0x62967d9e, -+ 0xbbb03e93, 0x0cadff97, 0xb110b0af, 0x060d71ab, 0xdf2b32a6, 0x6836f3a2, -+ 0x6d66b4bc, 0xda7b75b8, 0x035d36b5, 0xb440f7b1}; -+ -+inline void swap_bytes(u_int32_t &crc) -+{ -+ unsigned char a = crc >> 24; -+ unsigned char b = crc >> 16; -+ unsigned char c = crc >> 8; -+ unsigned char d = crc; -+ -+ crc = ((d << 8 | c) << 8 | b) << 8 | a; -+} - - u_int32_t CRC32::crc32 (const char *d, int len, u_int32_t crc) - { - register int i; - const unsigned char *u=(unsigned char*)d; // Saves '& 0xff' - -+ swap_bytes(crc); -+ - for (i=0; i<len; i++) -- crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *u++)]; -+ crc = (crc >> 8) ^ crc_table[(unsigned char)crc ^ *u++]; -+ -+ swap_bytes(crc); - - return crc; - } -diff -ruNp vdr-1.7.0-extensions/lirc.c vdr-1.7.0-ext-h264-s2ng-speedup/lirc.c ---- vdr-1.7.0-extensions/lirc.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/lirc.c 2009-04-12 23:57:23.000000000 +0200 -@@ -71,17 +71,48 @@ void cLircRemote::Action(void) - bool repeat = false; - int timeout = -1; - -+#ifdef USE_LIRCSETTINGS -+ if (Setup.LircPriorityBoost) -+ SetPriority(GetPriority() - Setup.LircPriorityBoost); -+#endif /* LIRCSETTINGS */ - while (Running() && f >= 0) { - - bool ready = cFile::FileReady(f, timeout); -+#ifdef USE_LIRCSETTINGS -+ int ret = -1; -+ if (ready) { -+ // read one line of the line oriented lirc protocol -+ for (ret = 0; ret < (int)sizeof(buf); ret++) { -+ int ch = readchar(f); -+ if (ch < 0) { -+ ret = -1; -+ break; -+ } -+ if (ch == '\n') { -+ buf[ret++] = '\0'; -+ break; -+ } -+ buf[ret] = ch; -+ } -+ } -+#else - int ret = ready ? safe_read(f, buf, sizeof(buf)) : -1; -+#endif /* LIRCSETTINGS */ - - if (ready && ret <= 0 ) { -+#ifdef USE_LIRCSETTINGS -+ esyslog("ERROR: lircd connection broken, trying to reconnect every %.1f seconds", float(Setup.LircReconnectDelay) / 1000); -+#else - esyslog("ERROR: lircd connection broken, trying to reconnect every %.1f seconds", float(RECONNECTDELAY) / 1000); -+#endif /* LIRCSETTINGS */ - close(f); - f = -1; - while (Running() && f < 0) { -+#ifdef USE_LIRCSETTINGS -+ cCondWait::SleepMs(Setup.LircReconnectDelay); -+#else - cCondWait::SleepMs(RECONNECTDELAY); -+#endif /* LIRCSETTINGS */ - if (Connect()) { - isyslog("reconnected to lircd"); - break; -@@ -98,7 +129,7 @@ void cLircRemote::Action(void) - } - if (count == 0) { - #ifdef USE_LIRCSETTINGS -- if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < (unsigned int)Setup.LircRepeatDelay) -+ if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < (1000 / (unsigned int)Setup.LircPushFreq)) - #else - if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < REPEATDELAY) - #endif /* LIRCSETTINGS */ -@@ -112,7 +143,7 @@ void cLircRemote::Action(void) - } - else { - #ifdef USE_LIRCSETTINGS -- if (LastTime.Elapsed() < (unsigned int)Setup.LircRepeatFreq) -+ if (LastTime.Elapsed() < (1000 / (unsigned int)Setup.LircRepeatFreq)) - #else - if (LastTime.Elapsed() < REPEATFREQ) - #endif /* LIRCSETTINGS */ -diff -ruNp vdr-1.7.0-extensions/Make.config.template vdr-1.7.0-ext-h264-s2ng-speedup/Make.config.template ---- vdr-1.7.0-extensions/Make.config.template 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/Make.config.template 2009-04-12 23:57:23.000000000 +0200 -@@ -59,7 +59,6 @@ CUTTIME = 1 - DDEPGENTRY = 1 - #DELTIMESHIFTREC = 1 - DOLBYINREC = 1 --#DVBPLAYER = 1 - #DVBSETUP = 1 - #DVDARCHIVE = 1 - #DVDCHAPJUMP = 1 -@@ -90,7 +89,6 @@ SETTIME = 1 - #SOURCECAPS = 1 - #SORTRECORDS = 1 - #STREAMDEVEXT = 1 --#SYNCEARLY = 1 - #TIMERCMD = 1 - #TIMERINFO = 1 - #TTXTSUBS = 1 -@@ -149,10 +147,6 @@ ifdef DOLBYINREC - DEFINES += -DUSE_DOLBYINREC - endif - --ifdef DVBPLAYER --DEFINES += -DUSE_DVBPLAYER --endif -- - ifdef DVBSETUP - DEFINES += -DUSE_DVBSETUP - endif -@@ -269,10 +263,6 @@ ifdef STREAMDEVEXT - DEFINES += -DUSE_STREAMDEVEXT - endif - --ifdef SYNCEARLY --DEFINES += -DUSE_SYNCEARLY --endif -- - ifdef TIMERCMD - DEFINES += -DUSE_TIMERCMD - endif -diff -ruNp vdr-1.7.0-extensions/Makefile vdr-1.7.0-ext-h264-s2ng-speedup/Makefile ---- vdr-1.7.0-extensions/Makefile 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/Makefile 2009-04-12 23:57:23.000000000 +0200 -@@ -41,7 +41,7 @@ OBJS = audio.o channels.o ci.o config.o - lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o rcu.o\ - receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\ - skinclassic.o skins.o skinsttng.o sources.o spu.o status.o svdrp.o themes.o thread.o\ -- timers.o tools.o transfer.o vdr.o videodir.o -+ timers.o tools.o transfer.o vdr.o videodir.o h264parser.o - - ifdef WAREAGLEICON - OBJS += iconpatch.o -diff -ruNp vdr-1.7.0-extensions/menu.c vdr-1.7.0-ext-h264-s2ng-speedup/menu.c ---- vdr-1.7.0-extensions/menu.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/menu.c 2009-04-12 23:57:23.000000000 +0200 -@@ -249,17 +249,17 @@ void cMenuEditChannel::Setup(void) - Add(new cMenuEditStrItem( tr("Name"), name, sizeof(name))); - Add(new cMenuEditSrcItem( tr("Source"), &data.source)); - Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency)); -- Add(new cMenuEditIntItem( tr("Vpid"), &data.vpid, 0, 0x1FFF)); -- Add(new cMenuEditIntItem( tr("Ppid"), &data.ppid, 0, 0x1FFF)); -+ Add(new cMenuEditIntItem( tr("Vpid"), &data.vpid, 0, 0x1FFF)); -+ Add(new cMenuEditIntItem( tr("Ppid"), &data.ppid, 0, 0x1FFF)); - Add(new cMenuEditIntItem( tr("Apid1"), &data.apids[0], 0, 0x1FFF)); - Add(new cMenuEditIntItem( tr("Apid2"), &data.apids[1], 0, 0x1FFF)); - Add(new cMenuEditIntItem( tr("Dpid1"), &data.dpids[0], 0, 0x1FFF)); - Add(new cMenuEditIntItem( tr("Dpid2"), &data.dpids[1], 0, 0x1FFF)); - Add(new cMenuEditIntItem( tr("Spid1"), &data.spids[0], 0, 0x1FFF)); - Add(new cMenuEditIntItem( tr("Spid2"), &data.spids[1], 0, 0x1FFF)); -- Add(new cMenuEditIntItem( tr("Tpid"), &data.tpid, 0, 0x1FFF)); -+ Add(new cMenuEditIntItem( tr("Tpid"), &data.tpid, 0, 0x1FFF)); - Add(new cMenuEditCaItem( tr("CA"), &data.caids[0])); -- Add(new cMenuEditIntItem( tr("Sid"), &data.sid, 1, 0xFFFF)); -+ Add(new cMenuEditIntItem( tr("Sid"), &data.sid, 1, 0xFFFF)); - /* XXX not yet used - Add(new cMenuEditIntItem( tr("Nid"), &data.nid, 0)); - Add(new cMenuEditIntItem( tr("Tid"), &data.tid, 0)); -@@ -280,8 +280,6 @@ void cMenuEditChannel::Setup(void) - #ifdef USE_PLUGINPARAM - ST("P ") Add(new cMenuEditStrItem( tr("Parameters"), pluginParam, sizeof(pluginParam), tr(FileNameChars))); - #endif /* PLUGINPARAM */ -- ST(" T") Add(new cMenuEditMapItem( tr("Alpha"), &data.alpha, AlphaValues)); -- ST(" T") Add(new cMenuEditMapItem( tr("Priority"), &data.priority, PriorityValues)); - ST(" S ") Add(new cMenuEditMapItem( tr("Rolloff"), &data.rollOff, RollOffValues)); - - SetCurrent(Get(current)); -@@ -3341,9 +3339,6 @@ void cMenuSetupDVB::Setup(void) - Add(new cMenuEditStraItem(tr("Setup.DVB$Channel Blocker"), &data.ChannelBlocker, 7, ChannelBlockers)); - Add(new cMenuEditStraItem(tr("Setup.DVB$Channel Blocker Filter Mode"), &data.ChannelBlockerMode, 4, ChannelBlockerModes)); - #endif /* DVBSETUP */ --#ifdef USE_SYNCEARLY -- Add(new cMenuEditBoolItem(tr("Setup.DVB$Use Sync Early Patch"), &data.UseSyncEarlyPatch)); --#endif /* SYNCEARLY */ - - SetCurrent(Get(current)); - Display(); -@@ -3849,9 +3844,12 @@ void cMenuSetupMisc::Setup(void) - #endif /* VOLCTRL */ - Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Emergency exit"), &data.EmergencyExit)); - #ifdef USE_LIRCSETTINGS -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc push freq"), &data.LircPushFreq, 0, 100)); - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat delay"), &data.LircRepeatDelay, 0, 1000)); -- Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat freq"), &data.LircRepeatFreq, 0, 1000)); -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat freq"), &data.LircRepeatFreq, 0, 100)); - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat timeout"), &data.LircRepeatTimeout, 0, 5000)); -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc reconnect delay"), &data.LircReconnectDelay, 0, 9999)); -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc priority boost"), &data.LircPriorityBoost, 0, 100)); - #endif /* LIRCSETTINGS */ - } - -@@ -5891,7 +5889,7 @@ bool cReplayControl::ShowProgress(bool I - lastCurrent = lastTotal = -1; - } - if (Total != lastTotal) { -- displayReplay->SetTotal(IndexToHMSF(Total)); -+ displayReplay->SetTotal(IndexToHMSF(Total, false, GetFramesPerSec())); - if (!Initial) - displayReplay->Flush(); - } -@@ -5899,7 +5897,7 @@ bool cReplayControl::ShowProgress(bool I - displayReplay->SetProgress(Current, Total); - if (!Initial) - displayReplay->Flush(); -- displayReplay->SetCurrent(IndexToHMSF(Current, displayFrames)); -+ displayReplay->SetCurrent(IndexToHMSF(Current, displayFrames, GetFramesPerSec())); - displayReplay->Flush(); - lastCurrent = Current; - } -@@ -5932,8 +5930,8 @@ void cReplayControl::TimeSearchProcess(e - { - #define STAY_SECONDS_OFF_END 10 - int Seconds = (timeSearchTime >> 24) * 36000 + ((timeSearchTime & 0x00FF0000) >> 16) * 3600 + ((timeSearchTime & 0x0000FF00) >> 8) * 600 + (timeSearchTime & 0x000000FF) * 60; -- int Current = (lastCurrent / FRAMESPERSEC); -- int Total = (lastTotal / FRAMESPERSEC); -+ int Current = (lastCurrent / GetFramesPerSec()); -+ int Total = (lastTotal / GetFramesPerSec()); - switch (Key) { - case k0 ... k9: - if (timeSearchPos < 4) { -@@ -5960,7 +5958,7 @@ void cReplayControl::TimeSearchProcess(e - case kDown: - case kOk: - Seconds = min(Total - STAY_SECONDS_OFF_END, Seconds); -- Goto(Seconds * FRAMESPERSEC, Key == kDown || Key == kPause || Key == kOk); -+ Goto(Seconds * GetFramesPerSec(), Key == kDown || Key == kPause || Key == kOk); - timeSearchActive = false; - break; - default: -@@ -6139,7 +6137,7 @@ void cReplayControl::EditTest(void) - #endif /* JUMPPLAY */ - m = marks.Next(m); - if (m) { -- Goto(m->position - SecondsToFrames(3)); -+ Goto(m->position - SecondsToFrames(3, GetFramesPerSec())); - Play(); - } - } -diff -ruNp vdr-1.7.0-extensions/nit.c vdr-1.7.0-ext-h264-s2ng-speedup/nit.c ---- vdr-1.7.0-extensions/nit.c 2008-04-12 14:06:40.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/nit.c 2009-04-12 23:52:16.000000000 +0200 -@@ -4,7 +4,7 @@ - * See the main source file 'vdr.c' for copyright information and - * how to reach the author. - * -- * $Id: nit.c 2.1 2008/04/12 12:06:40 kls Exp $ -+ * $Id: nit.c 2.3 2008/12/20 10:57:50 kls Exp $ - */ - - #include "nit.h" -@@ -127,13 +127,13 @@ void cNitFilter::Process(u_short Pid, u_ - int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 100; - static char Polarizations[] = { 'h', 'v', 'l', 'r' }; - char Polarization = Polarizations[sd->getPolarization()]; -- static int CodeRates[] = { DVBFE_FEC_NONE, DVBFE_FEC_1_2, DVBFE_FEC_2_3, DVBFE_FEC_3_4, DVBFE_FEC_5_6, DVBFE_FEC_7_8, DVBFE_FEC_8_9, DVBFE_FEC_3_5, DVBFE_FEC_4_5, DVBFE_FEC_9_10, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_NONE }; -+ static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_8_9, FEC_3_5, FEC_4_5, FEC_9_10, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE }; - int CodeRate = CodeRates[sd->getFecInner()]; -- static int Modulations[] = { DVBFE_MOD_AUTO, DVBFE_MOD_QPSK, DVBFE_MOD_8PSK, DVBFE_MOD_QAM16 }; -+ static int Modulations[] = { QAM_AUTO, QPSK, PSK_8, QAM_16 }; - int Modulation = Modulations[sd->getModulationType()]; -- int System = sd->getModulationSystem() ? DVBFE_DELSYS_DVBS2 : DVBFE_DELSYS_DVBS; -- static int RollOffs[] = { DVBFE_ROLLOFF_35, DVBFE_ROLLOFF_25, DVBFE_ROLLOFF_20, DVBFE_ROLLOFF_UNKNOWN }; -- int RollOff = sd->getModulationSystem() ? RollOffs[sd->getRollOff()] : DVBFE_ROLLOFF_UNKNOWN; -+ int System = sd->getModulationSystem() ? SYS_DVBS2 : SYS_DVBS; -+ static int RollOffs[] = { ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_AUTO }; -+ int RollOff = sd->getModulationSystem() ? RollOffs[sd->getRollOff()] : ROLLOFF_AUTO; - int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10; - if (ThisNIT >= 0) { - for (int n = 0; n < NumFrequencies; n++) { -@@ -147,21 +147,20 @@ void cNitFilter::Process(u_short Pid, u_ - } - if (Setup.UpdateChannels >= 5) { - bool found = false; -- for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { -- if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) { -- int transponder = Channel->Transponder(); -- found = true; -- if (!ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), transponder)) { -- for (int n = 0; n < NumFrequencies; n++) { -- if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], Polarization), transponder)) { -- Frequency = Frequencies[n]; -- break; -- } -+ cIterator<cChannel> ChannelIterator = Channels.GetChannelsBySourceNidTid(Source, ts.getOriginalNetworkId(), ts.getTransportStreamId()); -+ for (cChannel *Channel = ChannelIterator.First(); Channel; Channel = ChannelIterator.Next()) { -+ int transponder = Channel->Transponder(); -+ found = true; -+ if (!ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), transponder)) { -+ for (int n = 0; n < NumFrequencies; n++) { -+ if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], Polarization), transponder)) { -+ Frequency = Frequencies[n]; -+ break; - } -- } -- if (ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Transponder())) // only modify channels if we're actually receiving this transponder -- Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate, Modulation, System, RollOff); -+ } - } -+ if (ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Transponder())) // only modify channels if we're actually receiving this transponder -+ Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate, Modulation, System, RollOff); - } - if (!found) { - for (int n = 0; n < NumFrequencies; n++) { -@@ -181,9 +180,9 @@ void cNitFilter::Process(u_short Pid, u_ - int Source = cSource::FromData(cSource::stCable); - int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 10; - //XXX FEC_outer??? -- static int CodeRates[] = { DVBFE_FEC_NONE, DVBFE_FEC_1_2, DVBFE_FEC_2_3, DVBFE_FEC_3_4, DVBFE_FEC_5_6, DVBFE_FEC_7_8, DVBFE_FEC_8_9, DVBFE_FEC_3_5, DVBFE_FEC_4_5, DVBFE_FEC_9_10, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_NONE }; -+ static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_8_9, FEC_3_5, FEC_4_5, FEC_9_10, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE }; - int CodeRate = CodeRates[sd->getFecInner()]; -- static int Modulations[] = { DVBFE_MOD_NONE, DVBFE_MOD_QAM16, DVBFE_MOD_QAM32, DVBFE_MOD_QAM64, DVBFE_MOD_QAM128, DVBFE_MOD_QAM256, QAM_AUTO }; -+ static int Modulations[] = { QPSK, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO }; - int Modulation = Modulations[min(sd->getModulation(), 6)]; - int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10; - if (ThisNIT >= 0) { -@@ -198,21 +197,20 @@ void cNitFilter::Process(u_short Pid, u_ - } - if (Setup.UpdateChannels >= 5) { - bool found = false; -- for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { -- if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) { -- int transponder = Channel->Transponder(); -- found = true; -- if (!ISTRANSPONDER(Frequency / 1000, transponder)) { -- for (int n = 0; n < NumFrequencies; n++) { -- if (ISTRANSPONDER(Frequencies[n] / 1000, transponder)) { -- Frequency = Frequencies[n]; -- break; -- } -+ cIterator<cChannel> ChannelIterator = Channels.GetChannelsBySourceNidTid(Source, ts.getOriginalNetworkId(), ts.getTransportStreamId()); -+ for (cChannel *Channel = ChannelIterator.First(); Channel; Channel = ChannelIterator.Next()) { -+ int transponder = Channel->Transponder(); -+ found = true; -+ if (!ISTRANSPONDER(Frequency / 1000, transponder)) { -+ for (int n = 0; n < NumFrequencies; n++) { -+ if (ISTRANSPONDER(Frequencies[n] / 1000, transponder)) { -+ Frequency = Frequencies[n]; -+ break; - } -- } -- if (ISTRANSPONDER(Frequency / 1000, Transponder())) // only modify channels if we're actually receiving this transponder -- Channel->SetCableTransponderData(Source, Frequency, Modulation, SymbolRate, CodeRate); -+ } - } -+ if (ISTRANSPONDER(Frequency / 1000, Transponder())) // only modify channels if we're actually receiving this transponder -+ Channel->SetCableTransponderData(Source, Frequency, Modulation, SymbolRate, CodeRate); - } - if (!found) { - for (int n = 0; n < NumFrequencies; n++) { -@@ -231,22 +229,19 @@ void cNitFilter::Process(u_short Pid, u_ - SI::TerrestrialDeliverySystemDescriptor *sd = (SI::TerrestrialDeliverySystemDescriptor *)d; - int Source = cSource::FromData(cSource::stTerr); - int Frequency = Frequencies[0] = sd->getFrequency() * 10; -- static int Bandwidths[] = { DVBFE_BANDWIDTH_8_MHZ, DVBFE_BANDWIDTH_7_MHZ, DVBFE_BANDWIDTH_6_MHZ, DVBFE_BANDWIDTH_5_MHZ, DVBFE_BANDWIDTH_AUTO, DVBFE_BANDWIDTH_AUTO, DVBFE_BANDWIDTH_AUTO, DVBFE_BANDWIDTH_AUTO }; -+ static int Bandwidths[] = { 8000000, 7000000, 6000000, 0, 0, 0, 0, 0 }; - int Bandwidth = Bandwidths[sd->getBandwidth()]; -- static int Constellations[] = { DVBFE_MOD_QPSK, DVBFE_MOD_QAM16, DVBFE_MOD_QAM64, DVBFE_MOD_AUTO }; -+ static int Constellations[] = { QPSK, QAM_16, QAM_64, QAM_AUTO }; - int Constellation = Constellations[sd->getConstellation()]; -- static int CodeRates[] = { DVBFE_FEC_1_2, DVBFE_FEC_2_3, DVBFE_FEC_3_4, DVBFE_FEC_5_6, DVBFE_FEC_7_8, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO, DVBFE_FEC_AUTO }; -+ static int Hierarchies[] = { HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, HIERARCHY_4, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO }; -+ int Hierarchy = Hierarchies[sd->getHierarchy()]; -+ static int CodeRates[] = { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO }; - int CodeRateHP = CodeRates[sd->getCodeRateHP()]; - int CodeRateLP = CodeRates[sd->getCodeRateLP()]; -- static int GuardIntervals[] = { DVBFE_GUARD_INTERVAL_1_32, DVBFE_GUARD_INTERVAL_1_16, DVBFE_GUARD_INTERVAL_1_8, DVBFE_GUARD_INTERVAL_1_4 }; -+ static int GuardIntervals[] = { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4 }; - int GuardInterval = GuardIntervals[sd->getGuardInterval()]; -- static int TransmissionModes[] = { DVBFE_TRANSMISSION_MODE_2K, DVBFE_TRANSMISSION_MODE_8K, DVBFE_TRANSMISSION_MODE_4K, DVBFE_TRANSMISSION_MODE_AUTO }; -+ static int TransmissionModes[] = { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_AUTO, TRANSMISSION_MODE_AUTO }; - int TransmissionMode = TransmissionModes[sd->getTransmissionMode()]; -- static int Priorities[] = { DVBFE_STREAM_PRIORITY_LP, DVBFE_STREAM_PRIORITY_HP }; -- int Priority = Priorities[sd->getPriority()]; -- static int Alphas[] = { 0, DVBFE_ALPHA_1, DVBFE_ALPHA_2, DVBFE_ALPHA_4 }; -- int Alpha = Alphas[sd->getHierarchy() & 3]; -- int Hierarchy = Alpha ? DVBFE_HIERARCHY_ON : DVBFE_HIERARCHY_OFF; - if (ThisNIT >= 0) { - for (int n = 0; n < NumFrequencies; n++) { - if (ISTRANSPONDER(Frequencies[n] / 1000000, Transponder())) { -@@ -259,32 +254,31 @@ void cNitFilter::Process(u_short Pid, u_ - } - if (Setup.UpdateChannels >= 5) { - bool found = false; -- for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { -- if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) { -- int transponder = Channel->Transponder(); -- found = true; -- if (!ISTRANSPONDER(Frequency / 1000000, transponder)) { -- for (int n = 0; n < NumFrequencies; n++) { -- if (ISTRANSPONDER(Frequencies[n] / 1000000, transponder)) { -- Frequency = Frequencies[n]; -- break; -- } -+ cIterator<cChannel> ChannelIterator = Channels.GetChannelsBySourceNidTid(Source, ts.getOriginalNetworkId(), ts.getTransportStreamId()); -+ for (cChannel *Channel = ChannelIterator.First(); Channel; Channel = ChannelIterator.Next()) { -+ int transponder = Channel->Transponder(); -+ found = true; -+ if (!ISTRANSPONDER(Frequency / 1000000, transponder)) { -+ for (int n = 0; n < NumFrequencies; n++) { -+ if (ISTRANSPONDER(Frequencies[n] / 1000000, transponder)) { -+ Frequency = Frequencies[n]; -+ break; - } -- } -- if (ISTRANSPONDER(Frequency / 1000000, Transponder())) // only modify channels if we're actually receiving this transponder -- Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode, Alpha, Priority); -+ } - } -+ if (ISTRANSPONDER(Frequency / 1000000, Transponder())) // only modify channels if we're actually receiving this transponder -+ Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode); - } - if (!found) { - for (int n = 0; n < NumFrequencies; n++) { - cChannel *Channel = new cChannel; - Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0); -- if (Channel->SetTerrTransponderData(Source, Frequencies[n], Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode, Alpha, Priority)) -+ if (Channel->SetTerrTransponderData(Source, Frequencies[n], Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode)) - EITScanner.AddTransponder(Channel); - else - delete Channel; - } -- } -+ } - } - } - break; -diff -ruNp vdr-1.7.0-extensions/osd.c vdr-1.7.0-ext-h264-s2ng-speedup/osd.c ---- vdr-1.7.0-extensions/osd.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/osd.c 2009-04-12 23:57:23.000000000 +0200 -@@ -220,6 +220,8 @@ bool cBitmap::Contains(int x, int y) con - - bool cBitmap::Covers(int x1, int y1, int x2, int y2) const - { -+ if (x1 > x2 || y1 > y2) // sanity check -+ return false; - x1 -= x0; - y1 -= y0; - x2 -= x0; -@@ -229,6 +231,8 @@ bool cBitmap::Covers(int x1, int y1, int - - bool cBitmap::Intersects(int x1, int y1, int x2, int y2) const - { -+ if (x1 > x2 || y1 > y2) // sanity check -+ return false; - x1 -= x0; - y1 -= y0; - x2 -= x0; -@@ -397,15 +401,20 @@ bool cBitmap::SetXpm(const char *const X - void cBitmap::SetIndex(int x, int y, tIndex Index) - { - if (bitmap) { -- if (0 <= x && x < width && 0 <= y && y < height) { -- if (bitmap[width * y + x] != Index) { -- bitmap[width * y + x] = Index; -- if (dirtyX1 > x) dirtyX1 = x; -- if (dirtyY1 > y) dirtyY1 = y; -- if (dirtyX2 < x) dirtyX2 = x; -- if (dirtyY2 < y) dirtyY2 = y; -- } -- } -+ if (0 <= x && x < width && 0 <= y && y < height) -+ SetIndexInternal(x, y, Index); -+ } -+} -+ -+void cBitmap::SetIndexInternal(int x, int y, tIndex Index) -+{ -+ // this function relies on existing bitmap and valid coordinates -+ if (bitmap[width * y + x] != Index) { -+ bitmap[width * y + x] = Index; -+ if (dirtyX1 > x) dirtyX1 = x; -+ if (dirtyY1 > y) dirtyY1 = y; -+ if (dirtyX2 < x) dirtyX2 = x; -+ if (dirtyY2 < y) dirtyY2 = y; - } - } - -@@ -413,37 +422,147 @@ void cBitmap::DrawPixel(int x, int y, tC - { - x -= x0; - y -= y0; -- if (0 <= x && x < width && 0 <= y && y < height) -- SetIndex(x, y, Index(Color)); -+ if (bitmap && 0 <= x && x < width && 0 <= y && y < height) -+ SetIndexInternal(x, y, Index(Color)); - } - - void cBitmap::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool ReplacePalette, bool Overlay) - { - if (bitmap && Bitmap.bitmap && Intersects(x, y, x + Bitmap.Width() - 1, y + Bitmap.Height() - 1)) { -- if (Covers(x, y, x + Bitmap.Width() - 1, y + Bitmap.Height() - 1)) -+ bool Covered = Covers(x, y, x + Bitmap.Width() - 1, y + Bitmap.Height() - 1); -+ if (Covered) - Reset(); - x -= x0; - y -= y0; -- if (ReplacePalette && Covers(x + x0, y + y0, x + x0 + Bitmap.Width() - 1, y + y0 + Bitmap.Height() - 1)) { -+ // determine valid destination area [x1,x2]x[y1,y2] to avoid range checks inside the loops -+ int x1 = max(0, x), x2 = min(0 + width , x + Bitmap.width) - 1; -+ int y1 = max(0, y), y2 = min(0 + height, y + Bitmap.height) - 1; -+ -+#define FOR_Y_LOOP0 \ -+ tIndex *pRowSrc = &Bitmap.bitmap[Bitmap.width * (y1 - y) + (x1 - x)]; \ -+ tIndex *pRowDst = &bitmap[width * y1 + x1]; \ -+ for (int &yy = y1, ye = min(y2, dirtyY1 - 1); yy <= ye; yy++, pRowDst += width, pRowSrc += Bitmap.width) -+ -+#define FOR_Y_LOOP1 \ -+ tIndex *pRowSrc = &Bitmap.bitmap[Bitmap.width * (y2 - y) + (x1 - x)]; \ -+ tIndex *pRowDst = &bitmap[width * y2 + x1]; \ -+ for (int &yy = y2, ye = max(y1, dirtyY2 + 1); yy >= ye; yy--, pRowDst -= width, pRowSrc -= Bitmap.width) -+ -+#define DETECT_DIRTY_AREA_Y(Reverse, TransferCondition, TransferOperation) \ -+ do { \ -+ FOR_Y_LOOP##Reverse { \ -+ tIndex *pSrc = pRowSrc; \ -+ tIndex *pDst = pRowDst; \ -+ bool GotDirty = false; \ -+ for (int xx = x1; xx <= x2; xx++) { \ -+ if (TransferCondition) { \ -+ if (*pDst != TransferOperation) { \ -+ GotDirty = true; \ -+ if (dirtyX1 > xx) dirtyX1 = xx; \ -+ if (dirtyX2 < xx) dirtyX2 = xx; \ -+ } \ -+ } \ -+ pSrc++; \ -+ pDst++; \ -+ } \ -+ if (GotDirty) { \ -+ if (dirtyY1 > yy) dirtyY1 = yy; \ -+ if (dirtyY2 < yy) dirtyY2 = yy; \ -+ break; \ -+ } \ -+ } \ -+ } \ -+ while (false) -+ -+#define FOR_X_LOOP0 \ -+ tIndex *pColSrc = &Bitmap.bitmap[Bitmap.width * (y1 - y) + (x1 - x)]; \ -+ tIndex *pColDst = &bitmap[width * y1 + x1]; \ -+ for (int &xx = x1, xe = min(x2, dirtyX1 - 1); xx <= xe; xx++, pColDst++, pColSrc++) -+ -+#define FOR_X_LOOP1 \ -+ tIndex *pColSrc = &Bitmap.bitmap[Bitmap.width * (y1 - y) + (x2 - x)]; \ -+ tIndex *pColDst = &bitmap[width * y1 + x2]; \ -+ for (int &xx = x2, xe = max(x1, dirtyX2 + 1); xx >= xe; xx--, pColDst--, pColSrc--) -+ -+#define DETECT_DIRTY_AREA_X(Reverse, TransferCondition, TransferOperation) \ -+ do { \ -+ FOR_X_LOOP##Reverse { \ -+ tIndex *pSrc = pColSrc; \ -+ tIndex *pDst = pColDst; \ -+ bool GotDirty = false; \ -+ for (int yy = y1; yy <= y2; yy++) { \ -+ if (TransferCondition) { \ -+ if (*pDst != TransferOperation) { \ -+ GotDirty = true; \ -+ if (dirtyX1 > xx) dirtyX1 = xx; \ -+ if (dirtyX2 < xx) dirtyX2 = xx; \ -+ break; \ -+ } \ -+ } \ -+ pSrc += Bitmap.width; \ -+ pDst += width; \ -+ } \ -+ if (GotDirty) \ -+ break; \ -+ } \ -+ } \ -+ while (false) -+ -+#define DRAW_BITMAP(TransferCondition, TransferOperation, CanUseMemCpy) \ -+ do { \ -+ DETECT_DIRTY_AREA_Y(0, TransferCondition, TransferOperation); /* above */ \ -+ DETECT_DIRTY_AREA_Y(1, TransferCondition, TransferOperation); /* below */ \ -+ if (y2 < y1) /* nothing dirty */ \ -+ return; \ -+ DETECT_DIRTY_AREA_X(0, TransferCondition, TransferOperation); /* left */ \ -+ DETECT_DIRTY_AREA_X(1, TransferCondition, TransferOperation); /* right */ \ -+ /* process dirty area now */ \ -+ tIndex *pRowSrc = &Bitmap.bitmap[Bitmap.width * (y1 - y) + (x1 - x)]; \ -+ tIndex *pRowDst = &bitmap[width * y1 + x1]; \ -+ int n = sizeof(tIndex) * (x2 - x1 + 1); \ -+ for (int yy = y1; yy <= y2; yy++) { \ -+ tIndex *pSrc = pRowSrc; \ -+ tIndex *pDst = pRowDst; \ -+ if (CanUseMemCpy) \ -+ memcpy(pDst, pSrc, n); \ -+ else { \ -+ for (int xx = x1; xx <= x2; xx++) { \ -+ if (TransferCondition) \ -+ *pDst = TransferOperation; \ -+ pSrc++; \ -+ pDst++; \ -+ } \ -+ } \ -+ pRowSrc += Bitmap.width; \ -+ pRowDst += width; \ -+ } \ -+ } \ -+ while (false) -+ -+ if (ReplacePalette && Covered) { - Replace(Bitmap); -- for (int ix = 0; ix < Bitmap.width; ix++) { -- for (int iy = 0; iy < Bitmap.height; iy++) { -- if (!Overlay || Bitmap.bitmap[Bitmap.width * iy + ix] != 0) -- SetIndex(x + ix, y + iy, Bitmap.bitmap[Bitmap.width * iy + ix]); -- } -- } -+ if (Overlay) -+ DRAW_BITMAP(*pSrc != 0, *pSrc, false); -+ else -+ DRAW_BITMAP(true, *pSrc, true); - } - else { - tIndexes Indexes; - Take(Bitmap, &Indexes, ColorFg, ColorBg); -- for (int ix = 0; ix < Bitmap.width; ix++) { -- for (int iy = 0; iy < Bitmap.height; iy++) { -- if (!Overlay || Bitmap.bitmap[Bitmap.width * iy + ix] != 0) -- SetIndex(x + ix, y + iy, Indexes[int(Bitmap.bitmap[Bitmap.width * iy + ix])]); -- } -- } -+ if (Overlay) -+ DRAW_BITMAP(*pSrc != 0, Indexes[(int)*pSrc], false); -+ else -+ DRAW_BITMAP(true, Indexes[(int)*pSrc], false); - } - } -+ -+#undef DRAW_BITMAP -+#undef DETECT_DIRTY_AREA_Y -+#undef FOR_Y_LOOP0 -+#undef FOR_Y_LOOP1 -+#undef DETECT_DIRTY_AREA_X -+#undef FOR_X_LOOP0 -+#undef FOR_X_LOOP1 - } - - void cBitmap::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment) -@@ -505,10 +624,91 @@ void cBitmap::DrawRectangle(int x1, int - x2 = min(x2, width - 1); - y2 = min(y2, height - 1); - tIndex c = Index(Color); -- for (int y = y1; y <= y2; y++) -- for (int x = x1; x <= x2; x++) -- SetIndex(x, y, c); -+ -+#define FOR_Y_LOOP0 \ -+ tIndex *pRowDst = &bitmap[width * y1 + x1]; \ -+ for (int &yy = y1, ye = min(y2, dirtyY1 - 1); yy <= ye; yy++, pRowDst += width) -+ -+#define FOR_Y_LOOP1 \ -+ tIndex *pRowDst = &bitmap[width * y2 + x1]; \ -+ for (int &yy = y2, ye = max(y1, dirtyY2 + 1); yy >= ye; yy--, pRowDst -= width) -+ -+#define DETECT_DIRTY_AREA_Y(Reverse) \ -+ do { \ -+ FOR_Y_LOOP##Reverse { \ -+ tIndex *pDst = pRowDst; \ -+ bool GotDirty = false; \ -+ for (int xx = x1; xx <= x2; xx++) { \ -+ if (*pDst != c) { \ -+ GotDirty = true; \ -+ if (dirtyX1 > xx) dirtyX1 = xx; \ -+ if (dirtyX2 < xx) dirtyX2 = xx; \ -+ } \ -+ pDst++; \ -+ } \ -+ if (GotDirty) { \ -+ if (dirtyY1 > yy) dirtyY1 = yy; \ -+ if (dirtyY2 < yy) dirtyY2 = yy; \ -+ break; \ -+ } \ -+ } \ -+ } \ -+ while (false) -+ -+#define FOR_X_LOOP0 \ -+ tIndex *pColDst = &bitmap[width * y1 + x1]; \ -+ for (int &xx = x1, xe = min(x2, dirtyX1 - 1); xx <= xe; xx++, pColDst++) -+ -+#define FOR_X_LOOP1 \ -+ tIndex *pColDst = &bitmap[width * y1 + x2]; \ -+ for (int &xx = x2, xe = max(x1, dirtyX2 + 1); xx >= xe; xx--, pColDst--) -+ -+#define DETECT_DIRTY_AREA_X(Reverse) \ -+ do { \ -+ FOR_X_LOOP##Reverse { \ -+ tIndex *pDst = pColDst; \ -+ bool GotDirty = false; \ -+ for (int yy = y1; yy <= y2; yy++) { \ -+ if (*pDst != c) { \ -+ GotDirty = true; \ -+ if (dirtyX1 > xx) dirtyX1 = xx; \ -+ if (dirtyX2 < xx) dirtyX2 = xx; \ -+ break; \ -+ } \ -+ pDst += width; \ -+ } \ -+ if (GotDirty) \ -+ break; \ -+ } \ -+ } \ -+ while (false) -+ -+ DETECT_DIRTY_AREA_Y(0); /* above */ -+ DETECT_DIRTY_AREA_Y(1); /* below */ -+ if (y2 < y1) /* nothing dirty */ -+ return; -+ DETECT_DIRTY_AREA_X(0); /* left */ -+ DETECT_DIRTY_AREA_X(1); /* right */ -+ // now fill only dirty area of rectangle -+ tIndex *pRowDst = &bitmap[width * y1 + x1]; -+ tIndex *pDst = pRowDst; -+ for (int x = x1; x <= x2; x++) -+ *pDst++ = c; -+ // copy the single line above to all other lines -+ tIndex *pRowSrc = pRowDst; -+ int n = sizeof(tIndex) * (x2 - x1 + 1); -+ for (int y = y1 + 1; y <= y2; y++) { -+ pRowDst += width; -+ memcpy(pRowDst, pRowSrc, n); -+ } - } -+ -+#undef DETECT_DIRTY_AREA_Y -+#undef FOR_Y_LOOP0 -+#undef FOR_Y_LOOP1 -+#undef DETECT_DIRTY_AREA_X -+#undef FOR_X_LOOP0 -+#undef FOR_X_LOOP1 - } - - void cBitmap::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants) -diff -ruNp vdr-1.7.0-extensions/osd.h vdr-1.7.0-ext-h264-s2ng-speedup/osd.h ---- vdr-1.7.0-extensions/osd.h 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/osd.h 2009-04-12 23:57:23.000000000 +0200 -@@ -135,6 +135,7 @@ private: - int x0, y0; - int width, height; - int dirtyX1, dirtyY1, dirtyX2, dirtyY2; -+ void SetIndexInternal(int x, int y, tIndex Index); - public: - cBitmap(int Width, int Height, int Bpp, int X0 = 0, int Y0 = 0); - ///< Creates a bitmap with the given Width, Height and color depth (Bpp). -diff -ruNp vdr-1.7.0-extensions/pat.c vdr-1.7.0-ext-h264-s2ng-speedup/pat.c ---- vdr-1.7.0-extensions/pat.c 2008-04-12 15:34:50.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/pat.c 2008-07-06 16:01:32.000000000 +0200 -@@ -4,7 +4,7 @@ - * See the main source file 'vdr.c' for copyright information and - * how to reach the author. - * -- * $Id: pat.c 2.1 2008/04/12 13:34:50 kls Exp $ -+ * $Id: pat.c 2.2 2008/07/06 14:01:32 kls Exp $ - */ - - #include "pat.h" -@@ -328,7 +328,8 @@ void cPatFilter::Process(u_short Pid, u_ - // Scan the stream-specific loop: - SI::PMT::Stream stream; - int Vpid = 0; -- int Ppid = pmt.getPCRPid(); -+ int Ppid = 0; -+ int Vtype = 0; - int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated - int Dpids[MAXDPIDS + 1] = { 0 }; - int Spids[MAXSPIDS + 1] = { 0 }; -@@ -343,8 +344,10 @@ void cPatFilter::Process(u_short Pid, u_ - switch (stream.getStreamType()) { - case 1: // STREAMTYPE_11172_VIDEO - case 2: // STREAMTYPE_13818_VIDEO --//TODO case 0x1B: // MPEG4 -+ case 0x1B: // MPEG4 - Vpid = stream.getPid(); -+ Ppid = pmt.getPCRPid(); -+ Vtype = stream.getStreamType(); - break; - case 3: // STREAMTYPE_11172_AUDIO - case 4: // STREAMTYPE_13818_AUDIO -@@ -440,7 +443,7 @@ void cPatFilter::Process(u_short Pid, u_ - } - } - if (Setup.UpdateChannels >= 2) { -- Channel->SetPids(Vpid, Vpid ? Ppid : 0, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid); -+ Channel->SetPids(Vpid, Ppid, Vtype, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid); - Channel->SetCaIds(CaDescriptors->CaIds()); - } - Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors)); -diff -ruNp vdr-1.7.0-extensions/po/de_DE.po vdr-1.7.0-ext-h264-s2ng-speedup/po/de_DE.po ---- vdr-1.7.0-extensions/po/de_DE.po 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/po/de_DE.po 2009-04-12 23:57:23.000000000 +0200 -@@ -809,6 +809,9 @@ msgstr "Vor-/Rücklauf mit Rechts/Links" - msgid "Setup.Miscellaneous$only in progress display" - msgstr "nur in Fortschrittsanzeige" - -+msgid "Setup.Miscellaneous$Lirc push freq" -+msgstr "Lirc Druck Frequenz" -+ - msgid "Setup.Miscellaneous$Lirc repeat delay" - msgstr "Lirc Verzögerung" - -@@ -818,6 +821,12 @@ msgstr "Lirc Frequenz" - msgid "Setup.Miscellaneous$Lirc repeat timeout" - msgstr "Lirc Zeitbeschränkung" - -+msgid "Setup.Miscellaneous$Lirc reconnect delay" -+msgstr "Lirc Verbindungs Verzögerung" -+ -+msgid "Setup.Miscellaneous$Lirc priority boost" -+msgstr "Lirc Prioritäts Verstärkung" -+ - msgid "Plugins" - msgstr "Plugins" - -@@ -1170,9 +1179,6 @@ msgstr "ist primär" - msgid "has decoder + is primary" - msgstr "mit Decoder und primär" - --msgid "Setup.DVB$Use Sync Early Patch" --msgstr "Sync Early Patch benutzen" -- - msgid "Setup.LNB$DVB device %d uses LNB No." - msgstr "DVB-Empfänger %d nutzt LNB Nr." - -diff -ruNp vdr-1.7.0-extensions/recording.c vdr-1.7.0-ext-h264-s2ng-speedup/recording.c ---- vdr-1.7.0-extensions/recording.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/recording.c 2009-04-12 23:57:23.000000000 +0200 -@@ -2272,11 +2272,11 @@ cUnbufferedFile *cFileName::NextFile(voi - - // --- Index stuff ----------------------------------------------------------- - --cString IndexToHMSF(int Index, bool WithFrame) -+cString IndexToHMSF(int Index, bool WithFrame, int FramesPerSec) - { - char buffer[16]; -- int f = (Index % FRAMESPERSEC) + 1; -- int s = (Index / FRAMESPERSEC); -+ int f = (Index % FramesPerSec) + 1; -+ int s = (Index / FramesPerSec); - int m = s / 60 % 60; - int h = s / 3600; - s %= 60; -@@ -2284,17 +2284,17 @@ cString IndexToHMSF(int Index, bool With - return buffer; - } - --int HMSFToIndex(const char *HMSF) -+int HMSFToIndex(const char *HMSF, int FramesPerSec) - { - int h, m, s, f = 0; - if (3 <= sscanf(HMSF, "%d:%d:%d.%d", &h, &m, &s, &f)) -- return (h * 3600 + m * 60 + s) * FRAMESPERSEC + f - 1; -+ return (h * 3600 + m * 60 + s) * FramesPerSec + f - 1; - return 0; - } - --int SecondsToFrames(int Seconds) -+int SecondsToFrames(int Seconds, int FramesPerSec) - { -- return Seconds * FRAMESPERSEC; -+ return Seconds * FramesPerSec; - } - - // --- ReadFrame ------------------------------------------------------------- -diff -ruNp vdr-1.7.0-extensions/recording.h vdr-1.7.0-ext-h264-s2ng-speedup/recording.h ---- vdr-1.7.0-extensions/recording.h 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/recording.h 2009-04-12 23:57:23.000000000 +0200 -@@ -349,11 +349,11 @@ public: - cUnbufferedFile *NextFile(void); - }; - --cString IndexToHMSF(int Index, bool WithFrame = false); -+cString IndexToHMSF(int Index, bool WithFrame = false, int FramesPerSec = FRAMESPERSEC); - // Converts the given index to a string, optionally containing the frame number. --int HMSFToIndex(const char *HMSF); -+int HMSFToIndex(const char *HMSF, int FramesPerSec = FRAMESPERSEC); - // Converts the given string (format: "hh:mm:ss.ff") to an index. --int SecondsToFrames(int Seconds); //XXX+ ->player??? -+int SecondsToFrames(int Seconds, int FramesPerSec = FRAMESPERSEC); //XXX+ ->player??? - // Returns the number of frames corresponding to the given number of seconds. - - int ReadFrame(cUnbufferedFile *f, uchar *b, int Length, int Max); -diff -ruNp vdr-1.7.0-extensions/remux.c vdr-1.7.0-ext-h264-s2ng-speedup/remux.c ---- vdr-1.7.0-extensions/remux.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/remux.c 2009-04-12 23:57:23.000000000 +0200 -@@ -19,6 +19,8 @@ - #include "channels.h" - #include "shutdown.h" - #include "tools.h" -+#include "recording.h" -+#include "h264parser.h" - - ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader) - { -@@ -100,8 +102,9 @@ protected: - int suppressedLogMessages; - bool LogAllowed(void); - void DroppedData(const char *Reason, int Count) { LOG("%s (dropped %d bytes)", Reason, Count); } -+ virtual int Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded); - public: -- static int Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded); -+ static int PutAllOrNothing(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded); - cRepacker(void); - virtual ~cRepacker() {} - virtual void Reset(void) { initiallySyncing = true; } -@@ -138,6 +141,11 @@ bool cRepacker::LogAllowed(void) - - int cRepacker::Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded) - { -+ return PutAllOrNothing(ResultBuffer, Data, Count, CapacityNeeded); -+} -+ -+int cRepacker::PutAllOrNothing(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded) -+{ - if (CapacityNeeded >= Count && ResultBuffer->Free() < CapacityNeeded) { - esyslog("ERROR: possible result buffer overflow, dropped %d out of %d byte", CapacityNeeded, CapacityNeeded); - return 0; -@@ -156,7 +164,7 @@ protected: - int packetTodo; - uchar fragmentData[6 + 65535 + 3]; - int fragmentLen; -- uchar pesHeader[6 + 3 + 255 + 3]; -+ uchar pesHeader[6 + 3 + 255 + 5 + 3]; // 5: H.264 AUD - int pesHeaderLen; - uchar pesHeaderBackup[6 + 3 + 255]; - int pesHeaderBackupLen; -@@ -164,7 +172,7 @@ protected: - uint32_t localScanner; - int localStart; - bool PushOutPacket(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count); -- virtual int QuerySnoopSize() { return 4; } -+ virtual int QuerySnoopSize(void) { return 4; } - virtual void Reset(void); - }; - -@@ -238,8 +246,139 @@ bool cCommonRepacker::PushOutPacket(cRin - return true; - } - -+// --- cAudGenerator --------------------------------------------------------- -+ -+class cAudGenerator { -+private: -+ H264::cSimpleBuffer buffer; -+ int overflowByteCount; -+ H264::cSliceHeader::eAccessUnitType accessUnitType; -+ int sliceTypes; -+public: -+ cAudGenerator(void); -+ void CollectSliceType(const H264::cSliceHeader *SH); -+ int CollectData(const uchar *Data, int Count); -+ void Generate(cRingBufferLinear *const ResultBuffer); -+}; -+ -+cAudGenerator::cAudGenerator() -+ : buffer(MAXFRAMESIZE) -+{ -+ overflowByteCount = 0; -+ accessUnitType = H264::cSliceHeader::Frame; -+ sliceTypes = 0; -+} -+ -+int cAudGenerator::CollectData(const uchar *Data, int Count) -+{ -+ // buffer frame data until AUD can be generated -+ int n = buffer.Put(Data, Count); -+ overflowByteCount += (Count - n); -+ // always report "success" as an error message will be shown in Generate() -+ return Count; -+} -+ -+void cAudGenerator::CollectSliceType(const H264::cSliceHeader *SH) -+{ -+ if (!SH) -+ return; -+ // remember type of current access unit -+ accessUnitType = SH->GetAccessUnitType(); -+ // translate slice_type into part of primary_pic_type and merge them -+ switch (SH->slice_type) { -+ case 2: // I -+ case 7: // I only => I -+ sliceTypes |= 0x10000; -+ break; -+ case 0: // P -+ case 5: // P only => I, P -+ sliceTypes |= 0x11000; -+ break; -+ case 1: // B -+ case 6: // B only => I, P, B -+ sliceTypes |= 0x11100; -+ break; -+ case 4: // SI -+ case 9: // SI only => SI -+ sliceTypes |= 0x00010; -+ break; -+ case 3: // SP -+ case 8: // SP only => SI, SP -+ sliceTypes |= 0x00011; -+ break; -+ } -+} -+ -+void cAudGenerator::Generate(cRingBufferLinear *const ResultBuffer) -+{ -+ int primary_pic_type; -+ // translate the merged primary_pic_type parts into primary_pic_type -+ switch (sliceTypes) { -+ case 0x10000: // I -+ primary_pic_type = 0; -+ break; -+ case 0x11000: // I, P -+ primary_pic_type = 1; -+ break; -+ case 0x11100: // I, P, B -+ primary_pic_type = 2; -+ break; -+ case 0x00010: // SI -+ primary_pic_type = 3; -+ break; -+ case 0x00011: // SI, SP -+ primary_pic_type = 4; -+ break; -+ case 0x10010: // I, SI -+ primary_pic_type = 5; -+ break; -+ case 0x11011: // I, SI, P, SP -+ case 0x10011: // I, SI, SP -+ case 0x11010: // I, SI, P -+ primary_pic_type = 6; -+ break; -+ case 0x11111: // I, SI, P, SP, B -+ case 0x11110: // I, SI, P, B -+ primary_pic_type = 7; -+ break; -+ default: -+ primary_pic_type = -1; // frame without slices? -+ } -+ // drop an incorrect frame -+ if (primary_pic_type < 0) -+ esyslog("ERROR: cAudGenerator::Generate(): dropping frame without slices"); -+ else { -+ // drop a partitial frame -+ if (overflowByteCount > 0) -+ esyslog("ERROR: cAudGenerator::Generate(): frame exceeds MAXFRAMESIZE bytes (required size: %d bytes), dropping frame", buffer.Size() + overflowByteCount); -+ else { -+ int Count; -+ uchar *Data = buffer.Get(Count); -+ int PesPayloadOffset = 0; -+ AnalyzePesHeader(Data, Count, PesPayloadOffset); -+ // enter primary_pic_type into AUD -+ Data[ PesPayloadOffset + 4 ] |= primary_pic_type << 5; -+ // mangle the "start code" to pass the information that this access unit is a -+ // bottom field to ScanVideoPacket() where this modification will be reverted. -+ if (accessUnitType == H264::cSliceHeader::BottomField) -+ Data[ PesPayloadOffset + 3 ] |= 0x80; -+ // store the buffered frame -+ cRepacker::PutAllOrNothing(ResultBuffer, Data, Count, Count); -+ } -+ } -+ // prepare for next run -+ buffer.Clear(); -+ overflowByteCount = 0; -+ sliceTypes = 0; -+} -+ - // --- cVideoRepacker -------------------------------------------------------- - -+#define IPACKS 2048 -+#define SC_SEQUENCE 0xB3 // "sequence header code" -+#define SC_GROUP 0xB8 // "group start code" -+#define SC_PICTURE 0x00 // "picture start code" -+ - class cVideoRepacker : public cCommonRepacker { - private: - enum eState { -@@ -248,37 +387,243 @@ private: - scanPicture - }; - int state; -- void HandleStartCode(const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel); -+ bool framePicture; -+ bool pictureExtensionAhead; -+ bool collectChunkData; -+ H264::cSimpleBuffer chunkData; -+ H264::cParser *h264Parser; -+ bool &h264; -+ int sliceSeen; -+ bool audSeen; -+ cAudGenerator *audGenerator; -+ const uchar *startCodeLocations[(IPACKS + 3) / 4]; -+ int startCodeLocationCount; -+ int startCodeLocationIndex; -+ bool startCodeLocationsPrepared; -+ void CheckAudGeneration(bool SliceNalUnitType, bool SyncPoint, const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel); -+ void PushOutCurrentFrameAndStartNewPacket(const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel); -+ void HandleNalUnit(const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel, const uchar *&NalPayload); -+ void HandleStartCode(const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel, const uchar *&ChunkPayload); - inline bool ScanDataForStartCodeSlow(const uchar *const Data); - inline bool ScanDataForStartCodeFast(const uchar *&Data, const uchar *Limit); -- inline bool ScanDataForStartCode(const uchar *&Data, int &Done, int &Todo); -+ inline bool ScanDataForStartCode(const uchar *&Data, int &Done, int &Todo, int PesPayloadOffset); - inline void AdjustCounters(const int Delta, int &Done, int &Todo); - inline bool ScanForEndOfPictureSlow(const uchar *&Data); - inline bool ScanForEndOfPictureFast(const uchar *&Data, const uchar *Limit); - inline bool ScanForEndOfPicture(const uchar *&Data, const uchar *Limit); -+ inline void PushStartCodeLocation(const uchar *Data); -+ inline const uchar *PeekStartCodeLocation(void); -+ inline const uchar *PullStartCodeLocation(void); -+ void CollectData(const uchar *Data, int Count); -+ void BeginCollectingPictureExtension(void); -+ void EndCollectingPictureExtension(void); -+ bool DetermineFramePicture(void); -+ void GenerateFieldPicturesHint(bool FramePicture, const uchar *const Data, const uchar AndMask, const uchar OrMask); -+ void SwitchToMpeg12(void); -+protected: -+ virtual int Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded); - public: -- cVideoRepacker(void); -+ cVideoRepacker(bool &H264); -+ ~cVideoRepacker(); - virtual void Reset(void); - virtual void Repack(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count); - virtual int BreakAt(const uchar *Data, int Count); - }; - --cVideoRepacker::cVideoRepacker(void) --{ -+cVideoRepacker::cVideoRepacker(bool &H264) -+: chunkData(1024) -+, h264(H264) -+{ -+ // assume H.264 -- we'll fallback to MPEG1/2 when necessary -+ h264 = true; -+ h264Parser = (H264 ? new H264::cParser() : 0); -+ audGenerator = 0; - Reset(); - } - -+cVideoRepacker::~cVideoRepacker() -+{ -+ delete h264Parser; -+ delete audGenerator; -+} -+ - void cVideoRepacker::Reset(void) - { - cCommonRepacker::Reset(); -+ if (h264Parser) -+ h264Parser->Reset(); - scanner = 0xFFFFFFFF; - state = syncing; -+ framePicture = true; -+ pictureExtensionAhead = false; -+ collectChunkData = false; -+ chunkData.Clear(); -+ sliceSeen = -1; -+ audSeen = false; -+ delete audGenerator; -+ audGenerator = 0; -+ startCodeLocationCount = 0; -+ startCodeLocationsPrepared = false; - } - --void cVideoRepacker::HandleStartCode(const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel) -+void cVideoRepacker::SwitchToMpeg12(void) - { -- // synchronisation is detected some bytes after frame start. -- const int SkippedBytesLimit = 4; -+ if (!h264Parser) -+ return; -+ dsyslog("cVideoRepacker: switching to MPEG1/2 mode"); -+ delete h264Parser; -+ h264Parser = 0; -+ delete audGenerator; -+ audGenerator = 0; -+ h264 = false; -+} -+ -+int cVideoRepacker::Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded) -+{ -+ if (!audGenerator) -+ return cCommonRepacker::Put(ResultBuffer, Data, Count, CapacityNeeded); -+ -+ return audGenerator->CollectData(Data, Count); -+} -+ -+void cVideoRepacker::CollectData(const uchar *Data, int Count) -+{ -+ if (h264Parser) -+ h264Parser->PutNalUnitData(Data, Count); -+ else if (collectChunkData) -+ chunkData.Put(Data, Count); -+} -+ -+void cVideoRepacker::HandleNalUnit(const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel, const uchar *&NalPayload) -+{ -+ // check whether we need to fall back to MPEG1/2 -+ if (initiallySyncing) { -+ switch (*Data) { -+ case SC_SEQUENCE: -+ case SC_GROUP: -+ case SC_PICTURE: -+ // the above start codes do not appear in H.264 so let's switch to MPEG1/2 -+ SwitchToMpeg12(); -+ // delegate startcode to appropriate handler -+ HandleStartCode(Data, ResultBuffer, Payload, StreamID, MpegLevel, NalPayload); -+ return; -+ } -+ } -+ -+ // valid NAL units start with a zero bit -+ if (*Data & 0x80) { -+ LOG("cVideoRepacker: found invalid NAL unit: stream seems to be scrambled or not demultiplexed"); -+ return; -+ } -+ -+ // collect NAL unit's remaining data and process it -+ CollectData(NalPayload, Data - 3 - NalPayload); -+ h264Parser->Process(); -+ -+ // which kind of NAL unit have we got? -+ const int nal_unit_type = *Data & 0x1F; -+ switch (nal_unit_type) { -+ case 1: // coded slice of a non-IDR picture -+ case 2: // coded slice data partition A -+ case 5: // coded slice of an IDR picture -+ CheckAudGeneration(true, false, Data, ResultBuffer, Payload, StreamID, MpegLevel); -+ break; -+ case 3: // coded slice data partition B -+ case 4: // coded slice data partition C -+ case 19: // coded slice of an auxiliary coded picture without partitioning -+ break; -+ case 6: // supplemental enhancement information (SEI) -+ case 7: // sequence parameter set -+ case 8: // picture parameter set -+ case 10: // end of sequence -+ case 11: // end of stream -+ case 13: // sequence parameter set extension -+ CheckAudGeneration(false, nal_unit_type == 7, Data, ResultBuffer, Payload, StreamID, MpegLevel); -+ break; -+ case 12: // filler data -+ break; -+ case 14 ... 18: // reserved -+ CheckAudGeneration(false, false, Data, ResultBuffer, Payload, StreamID, MpegLevel); -+ case 20 ... 23: // reserved -+ LOG("cVideoRepacker: found reserved NAL unit type: stream seems to be scrambled"); -+ break; -+ case 0: // unspecified -+ case 24 ... 31: // unspecified -+ LOG("cVideoRepacker: found unspecified NAL unit type: stream seems to be scrambled"); -+ break; -+ case 9: { // access unit delimiter -+ audSeen = true; -+ CheckAudGeneration(false, true, Data, ResultBuffer, Payload, StreamID, MpegLevel); -+ // mangle the "start code" to pass the information "the next access unit will be the -+ // second field of the current frame" to ScanVideoPacket() where this modification -+ // will be reverted. -+ const H264::cSliceHeader *SH = h264Parser->Context().CurrentSlice(); -+ GenerateFieldPicturesHint(!SH || SH->GetAccessUnitType() == H264::cSliceHeader::Frame, Data, 0xFF, 0x80); -+ } -+ break; -+ } -+ -+ // collect 0x00 0x00 0x01 for current NAL unit -+ static const uchar InitPayload[3] = { 0x00, 0x00, 0x01 }; -+ CollectData(InitPayload, sizeof (InitPayload)); -+ NalPayload = Data; -+} -+ -+void cVideoRepacker::GenerateFieldPicturesHint(bool FramePicture, const uchar *const Data, const uchar AndMask, const uchar OrMask) -+{ -+ if (FramePicture) -+ framePicture = true; -+ else { -+ framePicture ^= true; // toggle between frame/first field and second field -+ if (!framePicture) { -+ // the last picture was a field so set a hint for this second field -+ *(uchar *)Data &= AndMask; -+ *(uchar *)Data |= OrMask; -+ } -+ } -+} -+ -+void cVideoRepacker::CheckAudGeneration(bool SliceNalUnitType, bool SyncPoint, const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel) -+{ -+ // we cannot generate anything until we have reached the synchronisation point -+ if (sliceSeen < 0 && !SyncPoint) -+ return; -+ // detect transition from slice to non-slice NAL units -+ const bool WasSliceSeen = (sliceSeen != false); -+ const bool IsSliceSeen = SliceNalUnitType; -+ sliceSeen = IsSliceSeen; -+ // collect slice types for AUD generation -+ if (WasSliceSeen && audGenerator) -+ audGenerator->CollectSliceType(h264Parser->Context().CurrentSlice()); -+ // handle access unit delimiter at the transition from slice to non-slice NAL units -+ if (WasSliceSeen && !IsSliceSeen) { -+ // an Access Unit Delimiter indicates that the current picture is done. So let's -+ // push out the current frame to start a new packet for the next picture. -+ PushOutCurrentFrameAndStartNewPacket(Data, ResultBuffer, Payload, StreamID, MpegLevel); -+ if (state == findPicture) { -+ // go on with scanning the picture data -+ state++; -+ } -+ // generate the AUD and push out the buffered frame -+ if (audGenerator) { -+ audGenerator->Generate(ResultBuffer); -+ if (audSeen) { -+ // we nolonger need to generate AUDs as they are part of the stream -+ delete audGenerator; -+ audGenerator = 0; -+ } -+ } -+ else if (!audSeen) // we do need to generate AUDs -+ audGenerator = new cAudGenerator; -+ } -+} -+ -+void cVideoRepacker::HandleStartCode(const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel, const uchar *&ChunkPayload) -+{ -+ // collect chunk's remaining data -+ CollectData(ChunkPayload, Data - 3 - ChunkPayload); -+ // currently, only picture extension is collected, so end collecting now -+ EndCollectingPictureExtension(); - - // which kind of start code have we got? - switch (*Data) { -@@ -292,71 +637,25 @@ void cVideoRepacker::HandleStartCode(con - case 0xB4: // sequence error code - LOG("cVideoRepacker: found sequence error code: stream seems to be damaged"); - case 0xB2: // user data start code -+ break; - case 0xB5: // extension start code -+ if (pictureExtensionAhead) { -+ pictureExtensionAhead = false; -+ // mangle the "start code" to pass the information "the next access unit will be the -+ // second field of the current frame" to ScanVideoPacket() where this modification -+ // will be reverted. -+ GenerateFieldPicturesHint(DetermineFramePicture(), Data, 0x00, 0xB9); -+ BeginCollectingPictureExtension(); -+ } - break; -- case 0xB7: // sequence end code -- case 0xB3: // sequence header code -- case 0xB8: // group start code - case 0x00: // picture start code -- if (state == scanPicture) { -- // the above start codes indicate that the current picture is done. So -- // push out the packet to start a new packet for the next picuture. If -- // the byte count get's negative then the current buffer ends in a -- // partitial start code that must be stripped off, as it shall be put -- // in the next packet. -- PushOutPacket(ResultBuffer, Payload, Data - 3 - Payload); -- // go on with syncing to the next picture -- state = syncing; -- } -- if (state == syncing) { -- if (initiallySyncing) // omit report for the typical initial case -- initiallySyncing = false; -- else if (skippedBytes > SkippedBytesLimit) // report that syncing dropped some bytes -- LOG("cVideoRepacker: skipped %d bytes to sync on next picture", skippedBytes - SkippedBytesLimit); -- skippedBytes = 0; -- // if there is a PES header available, then use it ... -- if (pesHeaderBackupLen > 0) { -- // ISO 13818-1 says: -- // In the case of video, if a PTS is present in a PES packet header -- // it shall refer to the access unit containing the first picture start -- // code that commences in this PES packet. A picture start code commences -- // in PES packet if the first byte of the picture start code is present -- // in the PES packet. -- memcpy(pesHeader, pesHeaderBackup, pesHeaderBackupLen); -- pesHeaderLen = pesHeaderBackupLen; -- pesHeaderBackupLen = 0; -- } -- else { -- // ... otherwise create a continuation PES header -- pesHeaderLen = 0; -- pesHeader[pesHeaderLen++] = 0x00; -- pesHeader[pesHeaderLen++] = 0x00; -- pesHeader[pesHeaderLen++] = 0x01; -- pesHeader[pesHeaderLen++] = StreamID; // video stream ID -- pesHeader[pesHeaderLen++] = 0x00; // length still unknown -- pesHeader[pesHeaderLen++] = 0x00; // length still unknown -- -- if (MpegLevel == phMPEG2) { -- pesHeader[pesHeaderLen++] = 0x80; -- pesHeader[pesHeaderLen++] = 0x00; -- pesHeader[pesHeaderLen++] = 0x00; -- } -- else -- pesHeader[pesHeaderLen++] = 0x0F; -- } -- // append the first three bytes of the start code -- pesHeader[pesHeaderLen++] = 0x00; -- pesHeader[pesHeaderLen++] = 0x00; -- pesHeader[pesHeaderLen++] = 0x01; -- // the next packet's payload will begin with the fourth byte of -- // the start code (= the actual code) -- Payload = Data; -- // as there is no length information available, assume the -- // maximum we can hold in one PES packet -- packetTodo = maxPacketSize - pesHeaderLen; -- // go on with finding the picture data -- state++; -- } -+ pictureExtensionAhead = true; -+ case 0xB8: // group start code -+ case 0xB3: // sequence header code -+ case 0xB7: // sequence end code -+ // the above start codes indicate that the current picture is done. So let's -+ // push out the current frame to start a new packet for the next picture. -+ PushOutCurrentFrameAndStartNewPacket(Data, ResultBuffer, Payload, StreamID, MpegLevel); - break; - case 0x01 ... 0xAF: // slice start codes - if (state == findPicture) { -@@ -365,6 +664,116 @@ void cVideoRepacker::HandleStartCode(con - } - break; - } -+ -+ // collect 0x00 0x00 0x01 for current chunk -+ static const uchar InitPayload[3] = { 0x00, 0x00, 0x01 }; -+ CollectData(InitPayload, sizeof (InitPayload)); -+ ChunkPayload = Data; -+} -+ -+void cVideoRepacker::BeginCollectingPictureExtension(void) -+{ -+ chunkData.Clear(); -+ collectChunkData = true; -+} -+ -+void cVideoRepacker::EndCollectingPictureExtension(void) -+{ -+ collectChunkData = false; -+} -+ -+bool cVideoRepacker::DetermineFramePicture(void) -+{ -+ bool FieldPicture = false; -+ int Count; -+ uchar *Data = chunkData.Get(Count); -+ if (Data && Count >= 7) { -+ if (!Data[0] && !Data[1] && Data[2] == 0x01 && (Data[3] == 0xB5 || Data[3] == 0xB9)) { // extension startcode or hint -+ if ((Data[4] & 0xF0) == 0x80) { // picture coding extension -+ int picture_structure = Data[6] & 0x03; -+ FieldPicture = picture_structure == 0x01 || picture_structure == 0x02; -+ } -+ } -+ } -+if (FieldPicture) fprintf(stderr, "----- MPEG2 field picture detected ---------------------------\n"); -+ return !FieldPicture; -+} -+ -+void cVideoRepacker::PushOutCurrentFrameAndStartNewPacket(const uchar *const Data, cRingBufferLinear *const ResultBuffer, const uchar *&Payload, const uchar StreamID, const ePesHeader MpegLevel) -+{ -+ // synchronisation is detected some bytes after frame start. -+ const int SkippedBytesLimit = 4; -+ -+ if (state == scanPicture) { -+ // picture data has been found so let's push out the current frame. -+ // If the byte count get's negative then the current buffer ends in a -+ // partitial start code that must be stripped off, as it shall be put -+ // in the next packet. -+ PushOutPacket(ResultBuffer, Payload, Data - 3 - Payload); -+ // go on with syncing to the next picture -+ state = syncing; -+ } -+ // when already synced to a picture, just go on collecting data -+ if (state != syncing) -+ return; -+ // we're synced to a picture so prepare a new packet -+ if (initiallySyncing) { // omit report for the typical initial case -+ initiallySyncing = false; -+ isyslog("cVideoRepacker: operating in %s mode", h264Parser ? "H.264" : "MPEG1/2"); -+ } -+ else if (skippedBytes > SkippedBytesLimit) // report that syncing dropped some bytes -+ LOG("cVideoRepacker: skipped %d bytes to sync on next picture", skippedBytes - SkippedBytesLimit); -+ skippedBytes = 0; -+ // if there is a PES header available, then use it ... -+ if (pesHeaderBackupLen > 0) { -+ // ISO 13818-1 says: -+ // In the case of video, if a PTS is present in a PES packet header -+ // it shall refer to the access unit containing the first picture start -+ // code that commences in this PES packet. A picture start code commences -+ // in PES packet if the first byte of the picture start code is present -+ // in the PES packet. -+ memcpy(pesHeader, pesHeaderBackup, pesHeaderBackupLen); -+ pesHeaderLen = pesHeaderBackupLen; -+ pesHeaderBackupLen = 0; -+ } -+ else { -+ // ... otherwise create a continuation PES header -+ pesHeaderLen = 0; -+ pesHeader[pesHeaderLen++] = 0x00; -+ pesHeader[pesHeaderLen++] = 0x00; -+ pesHeader[pesHeaderLen++] = 0x01; -+ pesHeader[pesHeaderLen++] = StreamID; // video stream ID -+ pesHeader[pesHeaderLen++] = 0x00; // length still unknown -+ pesHeader[pesHeaderLen++] = 0x00; // length still unknown -+ -+ if (MpegLevel == phMPEG2) { -+ pesHeader[pesHeaderLen++] = 0x80; -+ pesHeader[pesHeaderLen++] = 0x00; -+ pesHeader[pesHeaderLen++] = 0x00; -+ } -+ else -+ pesHeader[pesHeaderLen++] = 0x0F; -+ } -+ // add an AUD in H.264 mode when not present in stream -+ if (h264Parser && !audSeen) { -+ pesHeader[pesHeaderLen++] = 0x00; -+ pesHeader[pesHeaderLen++] = 0x00; -+ pesHeader[pesHeaderLen++] = 0x01; -+ pesHeader[pesHeaderLen++] = 0x09; // access unit delimiter -+ pesHeader[pesHeaderLen++] = 0x10; // will be filled later -+ } -+ // append the first three bytes of the start code -+ pesHeader[pesHeaderLen++] = 0x00; -+ pesHeader[pesHeaderLen++] = 0x00; -+ pesHeader[pesHeaderLen++] = 0x01; -+ // the next packet's payload will begin with the fourth byte of -+ // the start code (= the actual code) -+ Payload = Data; -+ // as there is no length information available, assume the -+ // maximum we can hold in one PES packet -+ packetTodo = maxPacketSize - pesHeaderLen; -+ // go on with finding the picture data -+ state++; - } - - bool cVideoRepacker::ScanDataForStartCodeSlow(const uchar *const Data) -@@ -377,6 +786,13 @@ bool cVideoRepacker::ScanDataForStartCod - - bool cVideoRepacker::ScanDataForStartCodeFast(const uchar *&Data, const uchar *Limit) - { -+ // We enter here when it is safe to access at least 3 bytes before Data (e. g. -+ // the tail of a previous run) and one byte after Data (xx yy zz [aa] bb {cc}). -+ // On return, Data shall either point to the last valid byte of the block or to -+ // the byte qualifying the start code (00 00 01 [ss]). -+ // As we are searching for 0x01, we've to move pointers (xx yy [zz] aa {bb} cc) -+ // to find start code "aa" for example after a packet boundery. -+ Data--; - Limit--; - - while (Data < Limit && (Data = (const uchar *)memchr(Data, 0x01, Limit - Data))) { -@@ -394,29 +810,66 @@ bool cVideoRepacker::ScanDataForStartCod - return false; - } - --bool cVideoRepacker::ScanDataForStartCode(const uchar *&Data, int &Done, int &Todo) -+bool cVideoRepacker::ScanDataForStartCode(const uchar *&Data, int &Done, int &Todo, int PesPayloadOffset) - { -- const uchar *const DataOrig = Data; -- const int MinDataSize = 4; -+ const int ReasonableDataSizeForFastScanning = 12; - -- if (Todo < MinDataSize || (state != syncing && packetTodo < MinDataSize)) -- return ScanDataForStartCodeSlow(Data); -+ if (!startCodeLocationsPrepared) { -+ // use slow scanning until it is safe to use fast scanning -+ if (Done < PesPayloadOffset + 3) -+ return ScanDataForStartCodeSlow(Data); -+ -+ // process available data but not more than needed for the current packet -+ int Limit = Todo; -+ if (state != syncing && Limit > packetTodo) -+ Limit = packetTodo; -+ -+ // use slow scanning when there is not enough data left -+ if (Limit < ReasonableDataSizeForFastScanning) -+ return ScanDataForStartCodeSlow(Data); -+ -+ // it's reasonable to use fast scanning -+ const uchar *const DataOrig = Data; -+ bool FoundStartCode = ScanDataForStartCodeFast(Data, Data + Limit); -+ AdjustCounters(Data - DataOrig, Done, Todo); -+ return FoundStartCode; -+ } - -- int Limit = Todo; -- if (state != syncing && Limit > packetTodo) -- Limit = packetTodo; -+ // process available data but not more than needed for the current packet -+ const uchar *Limit = Data + Todo - 1; -+ if (state != syncing && Todo > packetTodo) { -+ if (packetTodo <= 0) // overfill phase -+ Limit = Data; // do a single ScanDataForStartCodeSlow() below -+ else -+ Limit = Data + packetTodo - 1; -+ } - -- if (ScanDataForStartCodeSlow(Data)) -- return true; -+ // prepare the "not found" case -+ bool FoundStartCode = false; -+ const uchar *const DataOrig = Data; -+ Data = Limit; - -- if (ScanDataForStartCodeSlow(++Data)) { -- AdjustCounters(1, Done, Todo); -- return true; -+ // get the next start code location which fits into the limit -+ const uchar *p = PeekStartCodeLocation(); -+ if (p && p <= Limit) { -+ Data = PullStartCodeLocation(); -+ FoundStartCode = true; - } -- ++Data; - -- bool FoundStartCode = ScanDataForStartCodeFast(Data, DataOrig + Limit); -- AdjustCounters(Data - DataOrig, Done, Todo); -+ // setup the scanner variable -+ int bite = Data - DataOrig; -+ if (bite <= 3) { -+ // to few data, need to do byte shifting -+ for (int i = 0; i <= bite; i++) -+ ScanDataForStartCodeSlow(DataOrig + i); -+ } -+ else { -+ // it's safe to access the last 4 bytes directly -+ uint32_t *Scanner = (uint32_t *)(Data - 3); -+ scanner = ntohl(*Scanner); -+ } -+ -+ AdjustCounters(bite, Done, Todo); - return FoundStartCode; - } - -@@ -458,14 +911,19 @@ void cVideoRepacker::Repack(cRingBufferL - const uchar *data = Data + done; - // remember start of the data - const uchar *payload = data; -- -+ const uchar *ChunkPayload = payload; -+ startCodeLocationIndex = 0; - while (todo > 0) { - // collect number of skipped bytes while syncing - if (state <= syncing) - skippedBytes++; - // did we reach a start code? -- if (ScanDataForStartCode(data, done, todo)) -- HandleStartCode(data, ResultBuffer, payload, Data[3], mpegLevel); -+ if (ScanDataForStartCode(data, done, todo, pesPayloadOffset)) { -+ if (h264Parser) -+ HandleNalUnit(data, ResultBuffer, payload, Data[3], mpegLevel, ChunkPayload); -+ else -+ HandleStartCode(data, ResultBuffer, payload, Data[3], mpegLevel, ChunkPayload); -+ } - // move on - data++; - done++; -@@ -568,31 +1026,75 @@ void cVideoRepacker::Repack(cRingBufferL - fragmentLen += bite; - } - } -+ // collect data as needed -+ CollectData(ChunkPayload, data - ChunkPayload); - // report that syncing dropped some bytes - if (skippedBytes > SkippedBytesLimit) { - if (!initiallySyncing) // omit report for the typical initial case - LOG("cVideoRepacker: skipped %d bytes while syncing on next picture", skippedBytes - SkippedBytesLimit); - skippedBytes = SkippedBytesLimit; - } -+ startCodeLocationCount = 0; -+} -+ -+void cVideoRepacker::PushStartCodeLocation(const uchar *Data) -+{ -+ startCodeLocations[startCodeLocationCount++] = Data; -+} -+ -+const uchar *cVideoRepacker::PeekStartCodeLocation() -+{ -+ if (startCodeLocationIndex < startCodeLocationCount) -+ return startCodeLocations[startCodeLocationIndex]; -+ return 0; -+} -+ -+const uchar *cVideoRepacker::PullStartCodeLocation() -+{ -+ const uchar *p = PeekStartCodeLocation(); -+ if (p != 0) -+ startCodeLocationIndex++; -+ return p; - } - - bool cVideoRepacker::ScanForEndOfPictureSlow(const uchar *&Data) - { - localScanner <<= 8; -+ if (localScanner != 0x00000100) { -+ localScanner |= *Data++; -+ return false; -+ } -+ PushStartCodeLocation(Data); - localScanner |= *Data++; - // check start codes which follow picture data -- switch (localScanner) { -- case 0x00000100: // picture start code -- case 0x000001B8: // group start code -- case 0x000001B3: // sequence header code -- case 0x000001B7: // sequence end code -- return true; -- } -+ if (h264Parser) { -+ int nal_unit_type = localScanner & 0x1F; -+ switch (nal_unit_type) { -+ case 9: // access unit delimiter -+ return true; -+ } -+ } -+ else { -+ switch (localScanner) { -+ case 0x00000100: // picture start code -+ case 0x000001B8: // group start code -+ case 0x000001B3: // sequence header code -+ case 0x000001B7: // sequence end code -+ return true; -+ } -+ } - return false; - } - - bool cVideoRepacker::ScanForEndOfPictureFast(const uchar *&Data, const uchar *Limit) - { -+ // We enter here when it is safe to access at least 3 bytes before Data (e. g. -+ // the tail of a previous run) and one byte after Data (xx yy zz [aa] bb {cc}). -+ // On return, Data shall either point to the first byte outside of the block or -+ // to the byte following the start code (00 00 01 ss [tt]). -+ // As we are searching for 0x01, we've to move pointers (xx yy [zz] aa {bb} cc) -+ // to find start code "aa" for example after a packet boundery. -+ Data--; - Limit--; - - while (Data < Limit && (Data = (const uchar *)memchr(Data, 0x01, Limit - Data))) { -@@ -600,16 +1102,29 @@ bool cVideoRepacker::ScanForEndOfPicture - Data += 3; - else { - localScanner = 0x00000100 | *++Data; -+ PushStartCodeLocation(Data); - // check start codes which follow picture data -- switch (localScanner) { -- case 0x00000100: // picture start code -- case 0x000001B8: // group start code -- case 0x000001B3: // sequence header code -- case 0x000001B7: // sequence end code -- Data++; -- return true; -- default: -- Data += 3; -+ if (h264Parser) { -+ int nal_unit_type = localScanner & 0x1F; -+ switch (nal_unit_type) { -+ case 9: // access unit delimiter -+ Data++; -+ return true; -+ default: -+ Data += 3; -+ } -+ } -+ else { -+ switch (localScanner) { -+ case 0x00000100: // picture start code -+ case 0x000001B8: // group start code -+ case 0x000001B3: // sequence header code -+ case 0x000001B7: // sequence end code -+ Data++; -+ return true; -+ default: -+ Data += 3; -+ } - } - } - } -@@ -622,57 +1137,55 @@ bool cVideoRepacker::ScanForEndOfPicture - - bool cVideoRepacker::ScanForEndOfPicture(const uchar *&Data, const uchar *Limit) - { -- const uchar *const DataOrig = Data; -- const int MinDataSize = 4; -- bool FoundEndOfPicture; -+ const int ReasonableDataSizeForFastScanning = 12; - -- if (Limit - Data <= MinDataSize) { -- FoundEndOfPicture = false; -- while (Data < Limit) { -+ const uchar *const ReasonableLimit = Limit - ReasonableDataSizeForFastScanning; -+ bool FoundEndOfPicture = false; -+ -+ while (Data < Limit) { -+ // use slow scanning until it is safe or reasonable to use fast scanning -+ if (localStart < 3 || Data >= ReasonableLimit) { -+ localStart++; - if (ScanForEndOfPictureSlow(Data)) { - FoundEndOfPicture = true; - break; - } - } -- } -- else { -- FoundEndOfPicture = true; -- if (!ScanForEndOfPictureSlow(Data)) { -- if (!ScanForEndOfPictureSlow(Data)) { -- if (!ScanForEndOfPictureFast(Data, Limit)) -- FoundEndOfPicture = false; -+ else { -+ const uchar *const DataOrig = Data; -+ FoundEndOfPicture = ScanForEndOfPictureFast(Data, Limit); -+ localStart += (Data - DataOrig); -+ break; - } - } -- } - -- localStart += (Data - DataOrig); - return FoundEndOfPicture; - } - - int cVideoRepacker::BreakAt(const uchar *Data, int Count) - { -- if (initiallySyncing) -- return -1; // fill the packet buffer completely until we have synced once -- - int PesPayloadOffset = 0; - - if (AnalyzePesHeader(Data, Count, PesPayloadOffset) <= phInvalid) - return -1; // not enough data for test - -- // just detect end of picture -- if (state == scanPicture) { -- // setup local scanner -- if (localStart < 0) { -- localScanner = scanner; -- localStart = 0; -- } -- // start where we've stopped at the last run -- const uchar *data = Data + PesPayloadOffset + localStart; -- const uchar *limit = Data + Count; -- // scan data -- if (ScanForEndOfPicture(data, limit)) -+ // setup local scanner -+ if (localStart < 0) { -+ localScanner = scanner; -+ localStart = 0; -+ } -+ // start where we've stopped at the last run -+ const uchar *data = Data + PesPayloadOffset + localStart; -+ const uchar *limit = Data + Count; -+ // scan data -+ startCodeLocationsPrepared = true; -+ if (ScanForEndOfPicture(data, limit)) { -+ // just detect end of picture -+ if (state == scanPicture && !initiallySyncing) - return data - Data; - } -+ if (initiallySyncing) -+ return -1; // fill the packet buffer completely until we have synced once - // just fill up packet and append next start code - return PesPayloadOffset + packetTodo + 4; - } -@@ -690,12 +1203,13 @@ private: - int frameTodo; - int frameSize; - int cid; -- static bool IsValidAudioHeader(uint32_t Header, bool Mpeg2, int *FrameSize = NULL); -+ static bool IsValidAudioHeader(uint32_t Header, bool Mpeg2, int *FrameSize = NULL, int *FrameDuration = NULL); - public: - cAudioRepacker(int Cid); - virtual void Reset(void); - virtual void Repack(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count); - virtual int BreakAt(const uchar *Data, int Count); -+ static int GetFrameDuration(const uchar *Data, int Count, int *TrackIndex = NULL); - }; - - int cAudioRepacker::bitRates[2][3][16] = { // all values are specified as kbits/s -@@ -711,6 +1225,25 @@ int cAudioRepacker::bitRates[2][3][16] = - } - }; - -+int cAudioRepacker::GetFrameDuration(const uchar *Data, int Count, int *TrackIndex) -+{ -+ int PesPayloadOffset = 0; -+ ePesHeader PH = AnalyzePesHeader(Data, Count, PesPayloadOffset); -+ if (PH < phMPEG1) -+ return -1; -+ -+ const uchar *Payload = Data + PesPayloadOffset; -+ const int PayloadCount = Count - PesPayloadOffset; -+ -+ int FrameDuration = -1; -+ if ((Data[3] & 0xE0) == 0xC0 && PayloadCount >= 4) { -+ if (IsValidAudioHeader(((Payload[0] << 8 | Payload[1]) << 8 | Payload[2]) << 8 | Payload[3], PH == phMPEG2, NULL, &FrameDuration) && TrackIndex) -+ *TrackIndex = Data[3] - 0xC0; -+ } -+ -+ return FrameDuration; -+} -+ - cAudioRepacker::cAudioRepacker(int Cid) - { - cid = Cid; -@@ -726,7 +1259,7 @@ void cAudioRepacker::Reset(void) - frameSize = 0; - } - --bool cAudioRepacker::IsValidAudioHeader(uint32_t Header, bool Mpeg2, int *FrameSize) -+bool cAudioRepacker::IsValidAudioHeader(uint32_t Header, bool Mpeg2, int *FrameSize, int *FrameDuration) - { - int syncword = (Header & 0xFFF00000) >> 20; - int id = (Header & 0x00080000) >> 19; -@@ -760,32 +1293,36 @@ bool cAudioRepacker::IsValidAudioHeader( - if (emphasis == 2) // reserved - return false; - -- if (FrameSize) { -- if (bitrate_index == 0) -- *FrameSize = 0; -- else { -- static int samplingFrequencies[2][4] = { // all values are specified in Hz -- { 44100, 48000, 32000, -1 }, // MPEG 1 -- { 22050, 24000, 16000, -1 } // MPEG 2 -- }; -- -- static int slots_per_frame[2][3] = { -- { 12, 144, 144 }, // MPEG 1, Layer I, II, III -- { 12, 144, 72 } // MPEG 2, Layer I, II, III -- }; -- -- int mpegIndex = 1 - id; -- int layerIndex = 3 - layer; -- -- // Layer I (i. e., layerIndex == 0) has a larger slot size -- int slotSize = (layerIndex == 0) ? 4 : 1; // bytes -- -- int br = 1000 * bitRates[mpegIndex][layerIndex][bitrate_index]; // bits/s -- int sf = samplingFrequencies[mpegIndex][sampling_frequency]; -- -- int N = slots_per_frame[mpegIndex][layerIndex] * br / sf; // slots -+ if (FrameSize || FrameDuration) { -+ static int samplingFrequencies[2][4] = { // all values are specified in Hz -+ { 44100, 48000, 32000, -1 }, // MPEG 1 -+ { 22050, 24000, 16000, -1 } // MPEG 2 -+ }; -+ -+ static int slots_per_frame[2][3] = { -+ { 12, 144, 144 }, // MPEG 1, Layer I, II, III -+ { 12, 144, 72 } // MPEG 2, Layer I, II, III -+ }; -+ -+ int mpegIndex = 1 - id; -+ int layerIndex = 3 - layer; -+ -+ // Layer I (i. e., layerIndex == 0) has a larger slot size -+ int slotSize = (layerIndex == 0) ? 4 : 1; // bytes -+ int sf = samplingFrequencies[mpegIndex][sampling_frequency]; -+ -+ if (FrameDuration) -+ *FrameDuration = 90000 * 8 * slotSize * slots_per_frame[mpegIndex][layerIndex] / sf; -+ -+ if (FrameSize) { -+ if (bitrate_index == 0) -+ *FrameSize = 0; -+ else { -+ int br = 1000 * bitRates[mpegIndex][layerIndex][bitrate_index]; // bits/s -+ int N = slots_per_frame[mpegIndex][layerIndex] * br / sf; // slots - -- *FrameSize = (N + padding_bit) * slotSize; // bytes -+ *FrameSize = (N + padding_bit) * slotSize; // bytes -+ } - } - } - -@@ -895,6 +1432,22 @@ void cAudioRepacker::Repack(cRingBufferL - todo--; - // do we have to start a new packet as the current is done? - if (frameTodo > 0) { -+ // try to skip most loops for continuous memory -+ int bite = frameTodo; // jump to next audio frame -+ if (bite > packetTodo) -+ bite = packetTodo; // jump only to next output packet -+ if (--bite > todo) -+ bite = todo; // jump only to next input packet -+ // is there enough payload available to load the scanner? -+ if (bite > 0 && done + bite - pesPayloadOffset >= 4) { -+ data += bite; -+ done += bite; -+ todo -= bite; -+ frameTodo -= bite; -+ packetTodo -= bite; -+ uint32_t *Scanner = (uint32_t *)(data - 4); -+ scanner = ntohl(*Scanner); -+ } - if (--frameTodo == 0) { - // the current audio frame is is done now. So push out the packet to - // start a new packet for the next audio frame. -@@ -1086,6 +1639,7 @@ public: - virtual void Reset(void); - virtual void Repack(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count); - virtual int BreakAt(const uchar *Data, int Count); -+ static int GetFrameDuration(const uchar *Data, int Count, int *TrackIndex = NULL); - }; - - // frameSizes are in words, i. e. multiply them by 2 to get bytes -@@ -1112,6 +1666,30 @@ int cDolbyRepacker::frameSizes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; - -+int cDolbyRepacker::GetFrameDuration(const uchar *Data, int Count, int *TrackIndex) -+{ -+ int PesPayloadOffset = 0; -+ ePesHeader PH = AnalyzePesHeader(Data, Count, PesPayloadOffset); -+ if (PH < phMPEG1) -+ return -1; -+ -+ const uchar *Payload = Data + PesPayloadOffset; -+ const int PayloadCount = Count - PesPayloadOffset; -+ -+ if (Data[3] == 0xBD && PayloadCount >= 9 && ((Payload[0] & 0xF0) == 0x80) && Payload[4] == 0x0B && Payload[5] == 0x77 && frameSizes[Payload[8]] > 0) { -+ if (TrackIndex) -+ *TrackIndex = Payload[0] - 0x80; -+ -+ static int samplingFrequencies[4] = { // all values are specified in Hz -+ 48000, 44100, 32000, -1 -+ }; -+ -+ return 90000 * 1536 / samplingFrequencies[Payload[8] >> 6]; -+ } -+ -+ return -1; -+} -+ - cDolbyRepacker::cDolbyRepacker(void) - { - pesHeader[0] = 0x00; -@@ -1521,7 +2099,7 @@ void cTS2PES::store(uint8_t *Data, int C - if (repacker) - repacker->Repack(resultBuffer, Data, Count); - else -- cRepacker::Put(resultBuffer, Data, Count, Count); -+ cRepacker::PutAllOrNothing(resultBuffer, Data, Count, Count); - } - - void cTS2PES::reset_ipack(void) -@@ -1848,10 +2426,7 @@ void cTS2PES::ts_to_pes(const uint8_t *B - // Enable this if you are having problems with signal quality. - // These are the errors I used to get with Nova-T when antenna - // was not positioned correcly (not transport errors). //tvr -- //dsyslog("TS continuity error (%d)", ccCounter); --#ifdef USE_DVBSETUP - dsyslog("TS continuity error (%d)", ccCounter); --#endif /* DVBSETUP */ - } - ccCounter = Buf[3] & CONT_CNT_MASK; - } -@@ -1883,6 +2458,58 @@ void cTS2PES::ts_to_pes(const uint8_t *B - #endif /* DVBSETUP */ - } - -+// --- cAudioIndexer --------------------------------------------------------- -+ -+class cAudioIndexer { -+private: -+ int frameTrack; -+ int frameDuration; -+ int64_t trackTime[MAXAPIDS + MAXDPIDS]; -+ int64_t nextIndexTime; -+ -+public: -+ cAudioIndexer(void); -+ void Clear(void); -+ void PrepareFrame(const uchar *Data, int Count, int Offset, uchar &PictureType); -+ void ProcessFrame(void); -+ }; -+ -+cAudioIndexer::cAudioIndexer(void) -+{ -+ Clear(); -+} -+ -+void cAudioIndexer::Clear(void) -+{ -+ memset(trackTime, 0, sizeof (trackTime)); -+ nextIndexTime = 0; -+ frameTrack = -1; -+} -+ -+void cAudioIndexer::PrepareFrame(const uchar *Data, int Count, int Offset, uchar &PictureType) -+{ -+ frameDuration = cRemux::GetAudioFrameDuration(Data + Offset, Count - Offset, &frameTrack); -+ if (frameDuration <= 0) -+ return; -+ -+ if (Data[Offset + 3] == 0xBD) -+ frameTrack += MAXAPIDS; -+ -+ PictureType = (trackTime[frameTrack] >= nextIndexTime) ? I_FRAME : NO_PICTURE; -+} -+ -+void cAudioIndexer::ProcessFrame(void) -+{ -+ if (frameTrack < 0) -+ return; -+ -+ if (trackTime[frameTrack] >= nextIndexTime) -+ nextIndexTime += 90000 / FRAMESPERSEC; -+ -+ trackTime[frameTrack] += frameDuration; -+ frameTrack = -1; -+} -+ - // --- cRingBufferLinearPes -------------------------------------------------- - - class cRingBufferLinearPes : public cRingBufferLinear { -@@ -1910,19 +2537,14 @@ int cRingBufferLinearPes::DataReady(cons - - #define RESULTBUFFERSIZE KILOBYTE(256) - --#ifdef USE_SYNCEARLY - cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure, bool SyncEarly) --#else --cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure) --#endif /* SYNCEARLY */ - { -+ h264 = false; - exitOnFailure = ExitOnFailure; - noVideo = VPid == 0 || VPid == 1 || VPid == 0x1FFF; - numUPTerrors = 0; - synced = false; --#ifdef USE_SYNCEARLY - syncEarly = SyncEarly; --#endif /* SYNCEARLY */ - skipped = 0; - numTracks = 0; - resultSkipped = 0; -@@ -1931,7 +2553,7 @@ cRemux::cRemux(int VPid, const int *APid - if (VPid) - #define TEST_cVideoRepacker - #ifdef TEST_cVideoRepacker -- ts2pes[numTracks++] = new cTS2PES(VPid, resultBuffer, IPACKS, 0xE0, 0x00, new cVideoRepacker); -+ ts2pes[numTracks++] = new cTS2PES(VPid, resultBuffer, IPACKS, 0xE0, 0x00, new cVideoRepacker(h264)); - #else - ts2pes[numTracks++] = new cTS2PES(VPid, resultBuffer, IPACKS, 0xE0); - #endif -@@ -1957,6 +2579,7 @@ cRemux::cRemux(int VPid, const int *APid - while (*SPids && numTracks < MAXTRACKS && n < MAXSPIDS) - ts2pes[numTracks++] = new cTS2PES(*SPids++, resultBuffer, IPACKS, 0x00, 0x20 + n++); - } -+ audioIndexer = (noVideo ? new cAudioIndexer : NULL); - } - - cRemux::~cRemux() -@@ -1964,6 +2587,18 @@ cRemux::~cRemux() - for (int t = 0; t < numTracks; t++) - delete ts2pes[t]; - delete resultBuffer; -+ delete audioIndexer; -+} -+ -+int cRemux::GetAudioFrameDuration(const uchar *Data, int Count, int *TrackIndex) -+{ -+ if (Count <= 4) -+ return -1; -+ -+ if (Data[3] == 0xBD) -+ return cDolbyRepacker::GetFrameDuration(Data, Count, TrackIndex); -+ -+ return cAudioRepacker::GetFrameDuration(Data, Count, TrackIndex); - } - - int cRemux::GetPid(const uchar *Data) -@@ -1981,12 +2616,33 @@ int cRemux::GetPacketLength(const uchar - return -1; - } - -+bool cRemux::IsFrameH264(const uchar *Data, int Length) -+{ -+ int PesPayloadOffset; -+ const uchar *limit = Data + Length; -+ if (AnalyzePesHeader(Data, Length, PesPayloadOffset) <= phInvalid) -+ return false; // neither MPEG1 nor MPEG2 -+ -+ Data += PesPayloadOffset + 3; // move to video payload and skip 00 00 01 -+ if (Data < limit) { -+ // cVideoRepacker ensures that in case of H264 we will see an access unit delimiter here -+ if (0x01 == Data[-1] && 9 == Data[0] && 0x00 == Data[-2] && 0x00 == Data[-3]) -+ return true; -+ } -+ -+ return false; -+} -+ - int cRemux::ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType) - { - // Scans the video packet starting at Offset and returns its length. - // If the return value is -1 the packet was not completely in the buffer. - int Length = GetPacketLength(Data, Count, Offset); - if (Length > 0) { -+#ifdef TEST_cVideoRepacker -+ bool FoundPicture = false; -+ bool FoundPictureCodingExtension = false; -+#endif - int PesPayloadOffset = 0; - if (AnalyzePesHeader(Data + Offset, Length, PesPayloadOffset) >= phMPEG1) { - const uchar *p = Data + Offset + PesPayloadOffset + 2; -@@ -1999,30 +2655,99 @@ int cRemux::ScanVideoPacket(const uchar - if (p[-2] || p[-1] || p[0] != 0x01) - pLimit = 0; // skip scanning: packet doesn't start with 0x000001 - else { -- switch (p[1]) { -- case SC_SEQUENCE: -- case SC_GROUP: -- case SC_PICTURE: -- break; -- default: // skip scanning: packet doesn't start a new sequence, group or picture -- pLimit = 0; -- } -+ if (h264) { -+ int nal_unit_type = p[1] & 0x1F; -+ switch (nal_unit_type) { -+ case 9: // access unit delimiter -+ // when the MSB in p[1] is set (which violates H.264) then this is a hint -+ // from cVideoRepacker that this second field of the current frame shall -+ // not be reported as picture. -+ if (p[1] & 0x80) -+ ((uchar *)p)[1] &= ~0x80; // revert the hint and fall through -+ else -+ break; -+ default: // skip scanning: packet doesn't start a new picture -+ pLimit = 0; -+ } -+ } -+ else { -+ switch (p[1]) { -+ case SC_SEQUENCE: -+ case SC_GROUP: -+ case SC_PICTURE: -+ break; -+ default: // skip scanning: packet doesn't start a new sequence, group or picture -+ pLimit = 0; -+ } -+ } - } - } - #endif - while (p < pLimit && (p = (const uchar *)memchr(p, 0x01, pLimit - p))) { - if (!p[-2] && !p[-1]) { // found 0x000001 -- switch (p[1]) { -- case SC_PICTURE: PictureType = (p[3] >> 3) & 0x07; -- return Length; -- } -+ if (h264) { -+ int nal_unit_type = p[1] & 0x1F; -+ switch (nal_unit_type) { -+ case 9: { // access unit delimiter -+ int primary_pic_type = p[2] >> 5; -+ switch (primary_pic_type) { -+ case 0: // I -+ case 3: // SI -+ case 5: // I, SI -+ PictureType = I_FRAME; -+ break; -+ case 1: // I, P -+ case 4: // SI, SP -+ case 6: // I, SI, P, SP -+ PictureType = P_FRAME; -+ break; -+ case 2: // I, P, B -+ case 7: // I, SI, P, SP, B -+ PictureType = B_FRAME; -+ break; -+ } -+ return Length; -+ } -+ } -+ } -+ else { -+ switch (p[1]) { -+ case SC_PICTURE: PictureType = (p[3] >> 3) & 0x07; -+#ifndef TEST_cVideoRepacker -+ return Length; -+#else -+ FoundPicture = true; -+ break; -+ case 0x01 ... 0xAF: // slice startcodes -+ break; -+ case 0xB5: // extension startcode -+ case 0xB9: // hint from cVideoRepacker -+ if (FoundPicture && p + 2 < pLimit && (p[2] & 0xF0) == 0x80) { // picture coding extension -+ FoundPictureCodingExtension = true; -+ // using 0xB9 instead of 0xB5 for an expected picture coding extension -+ // is a hint from cVideoRepacker that this second field of the current -+ // frame shall not be reported as picture. -+ if (p[1] == 0xB9) { -+ ((uchar *)p)[1] = 0xB5; // revert the hint -+ pLimit = 0; // return with NO_PICTURE below -+ } -+ else -+ return Length; -+ } -+ break; -+#endif -+ } -+ } - p += 4; // continue scanning after 0x01ssxxyy - } - else - p += 3; // continue scanning after 0x01xxyy - } - } -- PictureType = NO_PICTURE; -+#ifdef TEST_cVideoRepacker -+ if (!FoundPicture || FoundPictureCodingExtension) -+#endif -+ PictureType = NO_PICTURE; - return Length; - } - return -1; -@@ -2126,26 +2851,14 @@ uchar *cRemux::Get(int &Count, uchar *Pi - } - } - else if (!synced) { --#ifdef USE_SYNCEARLY - if (pt == I_FRAME || syncEarly) { --#else -- if (pt == I_FRAME) { --#endif /* SYNCEARLY */ - if (PictureType) - *PictureType = pt; - resultSkipped = i; // will drop everything before this position --#ifdef USE_SYNCEARLY -- if (!syncEarly) --#endif /* SYNCEARLY */ -- SetBrokenLink(data + i, l); - synced = true; --#ifdef USE_SYNCEARLY -- if (syncEarly) { -- if (pt == I_FRAME) // syncEarly: it's ok but there is no need to call SetBrokenLink() -- SetBrokenLink(data + i, l); -- else fprintf(stderr, "video: synced early\n"); -- } --#endif /* SYNCEARLY */ -+ if (pt == I_FRAME) // syncEarly: it's ok but there is no need to call SetBrokenLink() -+ SetBrokenLink(data + i, l); -+ else fprintf(stderr, "video: synced early\n"); - } - } - else if (Count) -@@ -2158,26 +2871,21 @@ uchar *cRemux::Get(int &Count, uchar *Pi - l = GetPacketLength(data, resultCount, i); - if (l < 0) - return resultData; --#ifdef USE_SYNCEARLY - if (noVideo || !synced && syncEarly) { -+ uchar pt = NO_PICTURE; -+ if (audioIndexer && !Count) -+ audioIndexer->PrepareFrame(data, resultCount, i, pt); - if (!synced) { - if (PictureType && noVideo) --#else -- if (noVideo) { -- if (!synced) { -- if (PictureType) --#endif /* SYNCEARLY */ -- *PictureType = I_FRAME; -+ *PictureType = pt; - resultSkipped = i; // will drop everything before this position - synced = true; --#ifdef USE_SYNCEARLY -- if (!noVideo && syncEarly) fprintf(stderr, "audio: synced early\n"); --#endif /* SYNCEARLY */ -+ if (!noVideo) fprintf(stderr, "audio: synced early\n"); - } - else if (Count) - return resultData; - else if (PictureType) -- *PictureType = I_FRAME; -+ *PictureType = pt; - } - } - if (synced) { -@@ -2198,6 +2906,8 @@ uchar *cRemux::Get(int &Count, uchar *Pi - void cRemux::Del(int Count) - { - resultBuffer->Del(Count); -+ if (audioIndexer && Count > 0) -+ audioIndexer->ProcessFrame(); - } - - void cRemux::Clear(void) -@@ -2205,6 +2915,8 @@ void cRemux::Clear(void) - for (int t = 0; t < numTracks; t++) - ts2pes[t]->Clear(); - resultBuffer->Clear(); -+ if (audioIndexer) -+ audioIndexer->Clear(); - synced = false; - skipped = 0; - resultSkipped = 0; -diff -ruNp vdr-1.7.0-extensions/remux.h vdr-1.7.0-ext-h264-s2ng-speedup/remux.h ---- vdr-1.7.0-extensions/remux.h 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/remux.h 2009-04-12 23:57:23.000000000 +0200 -@@ -33,35 +33,32 @@ ePesHeader AnalyzePesHeader(const uchar - #define MAXTRACKS 64 - - class cTS2PES; -+class cAudioIndexer; - - class cRemux { - private: - bool exitOnFailure; - bool noVideo; -+ bool h264; - int numUPTerrors; - bool synced; --#ifdef USE_SYNCEARLY - bool syncEarly; --#endif /* SYNCEARLY */ - int skipped; - cTS2PES *ts2pes[MAXTRACKS]; - int numTracks; - cRingBufferLinear *resultBuffer; - int resultSkipped; -+ cAudioIndexer *audioIndexer; - int GetPid(const uchar *Data); -+ int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType); - public: --#ifdef USE_SYNCEARLY - cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false, bool SyncEarly = false); --#else -- cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false); --#endif /* SYNCEARLY */ - ///< Creates a new remuxer for the given PIDs. VPid is the video PID, while - ///< APids, DPids and SPids are pointers to zero terminated lists of audio, - ///< dolby and subtitle PIDs (the pointers may be NULL if there is no such - ///< PID). If ExitOnFailure is true, the remuxer will initiate an "emergency -- ///< exit" in case of problems with the data stream. -- ///< If USE_SYNCEARLY is activated: SyncEarly causes cRemux to sync as soon -- ///< as a video or audio frame is seen. -+ ///< exit" in case of problems with the data stream. SyncEarly causes cRemux -+ ///< to sync as soon as a video or audio frame is seen. - ~cRemux(); - void SetTimeouts(int PutTimeout, int GetTimeout) { resultBuffer->SetTimeouts(PutTimeout, GetTimeout); } - ///< By default cRemux assumes that Put() and Get() are called from different -@@ -87,7 +84,8 @@ public: - ///< settings as they are. - static void SetBrokenLink(uchar *Data, int Length); - static int GetPacketLength(const uchar *Data, int Count, int Offset); -- static int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType); -+ static int GetAudioFrameDuration(const uchar *Data, int Count, int *TrackIndex = NULL); -+ static bool IsFrameH264(const uchar *Data, int Length); - }; - - #endif // __REMUX_H -diff -ruNp vdr-1.7.0-extensions/svdrp.c vdr-1.7.0-ext-h264-s2ng-speedup/svdrp.c ---- vdr-1.7.0-extensions/svdrp.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/svdrp.c 2009-04-12 23:57:23.000000000 +0200 -@@ -1362,8 +1362,10 @@ void cSVDRP::CmdPLAY(const char *Option) - int x = sscanf(option, "%d:%d:%d.%d", &h, &m, &s, &f); - if (x == 1) - pos = h; -- else if (x >= 3) -- pos = (h * 3600 + m * 60 + s) * FRAMESPERSEC + f - 1; -+ else if (x >= 3) { -+ int FramesPerSec = cUnbufferedFile::GetFramesPerSec(recording->FileName()); -+ pos = (h * 3600 + m * 60 + s) * FramesPerSec + f - 1; -+ } - } - cResumeFile resume(recording->FileName()); - if (pos <= 0) -diff -ruNp vdr-1.7.0-extensions/thread.c vdr-1.7.0-ext-h264-s2ng-speedup/thread.c ---- vdr-1.7.0-extensions/thread.c 2008-04-13 13:53:56.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/thread.c 2009-04-12 23:57:23.000000000 +0200 -@@ -219,9 +219,20 @@ cThread::~cThread() - free(description); - } - -+int cThread::GetPriority(void) -+{ -+ errno = 0; -+ int Priority = getpriority(PRIO_PROCESS, 0); -+ if (Priority == -1 && errno != 0) { -+ LOG_ERROR; -+ Priority = 0; -+ } -+ return Priority; -+} -+ - void cThread::SetPriority(int Priority) - { -- if (setpriority(PRIO_PROCESS, 0, Priority) < 0) -+ if (setpriority(PRIO_PROCESS, 0, max(-20, min(Priority, 19))) < 0) - LOG_ERROR; - } - -diff -ruNp vdr-1.7.0-extensions/thread.h vdr-1.7.0-ext-h264-s2ng-speedup/thread.h ---- vdr-1.7.0-extensions/thread.h 2007-02-24 17:13:28.000000000 +0100 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/thread.h 2009-04-12 23:57:23.000000000 +0200 -@@ -86,6 +86,7 @@ private: - static tThreadId mainThreadId; - static void *StartThread(cThread *Thread); - protected: -+ int GetPriority(void); - void SetPriority(int Priority); - void Lock(void) { mutex.Lock(); } - void Unlock(void) { mutex.Unlock(); } -diff -ruNp vdr-1.7.0-extensions/tools.c vdr-1.7.0-ext-h264-s2ng-speedup/tools.c ---- vdr-1.7.0-extensions/tools.c 2008-03-05 18:23:47.000000000 +0100 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/tools.c 2009-04-12 23:57:23.000000000 +0200 -@@ -27,6 +27,8 @@ extern "C" { - #include <utime.h> - #include "i18n.h" - #include "thread.h" -+#include "remux.h" -+#include "recording.h" - - int SysLogLevel = 3; - -@@ -82,6 +84,14 @@ ssize_t safe_write(int filedes, const vo - return p < 0 ? p : written; - } - -+int readchar(int filedes) -+{ -+ char c; -+ if (safe_read(filedes, &c, sizeof(c)) != 1) -+ return -1; -+ return c; -+} -+ - void writechar(int filedes, char c) - { - safe_write(filedes, &c, sizeof(c)); -@@ -140,11 +150,8 @@ char *strreplace(char *s, char c1, char - { - if (s) { - char *p = s; -- while (*p) { -- if (*p == c1) -- *p = c2; -- p++; -- } -+ while ((p = strchr(p, c1))) -+ *p++ = c2; - } - return s; - } -@@ -1630,6 +1637,112 @@ cUnbufferedFile *cUnbufferedFile::Create - return File; - } - -+int cUnbufferedFile::GetFramesPerSec(const char *FileName) -+{ -+ // use this constant as a fallback value -+ int FramesPerSec = FRAMESPERSEC; -+ // open the file an determine frames per second -+ cFileName fn(FileName, false); -+ cUnbufferedFile *f = fn.Open(); -+ if (f) { -+ FramesPerSec = f->GetFramesPerSec(); -+ fn.Close(); -+ } -+ return FramesPerSec; -+} -+ -+#define ADD_H264_SUPPORT 1 -+ -+#ifdef ADD_H264_SUPPORT -+#include "h264parser.h" -+#endif -+ -+int cUnbufferedFile::GetFramesPerSec(void) -+{ -+ // use this constant as a fallback value -+ int FramesPerSec = FRAMESPERSEC; -+ // rember current file position to restore later -+ off_t OrigPos = curpos; -+ // seek to the beginning and read a chunk of data -+ if (0 == Seek(0, SEEK_SET)) { -+ uchar Data[2048]; -+ ssize_t Count = Read(Data, sizeof(Data)); -+ if (Count > 0) { -+ // this chunk of data should actually be a PES packet -+ uchar *Limit = Data + Count; -+ int PesPayloadOffset = 0; -+ if (AnalyzePesHeader(Data, Count, PesPayloadOffset) >= phMPEG1) { -+ // we need a video stream -- radio recordings use the default -+ if ((Data[3] & 0xF0) == 0xE0) { -+ uchar *p = Data + PesPayloadOffset; -+#ifdef ADD_H264_SUPPORT -+ // check whether this is a H.264 video frame -+ if (cRemux::IsFrameH264(Data, Count)) { -+ // need to have a H264 parser since picture timing is rather complex -+ H264::cParser H264parser(false); -+ // send NAL units to parser until it is able to provide frames per second -+ while (p < Limit) { -+ // find next NAL unit -+ uchar *pNext = (uchar *)memmem(p + 4, Limit - (p + 4), "\x00\x00\x01", 3); -+ if (!pNext) // just pass the remainder -+ pNext = Limit; -+ H264parser.PutNalUnitData(p, pNext - p); -+ // process NAL unit and check for frames per second -+ H264parser.Process(); -+ int FPS = H264parser.Context().GetFramesPerSec(); -+ if (FPS != -1) { // there we are ;-) -+ FramesPerSec = FPS; -+fprintf(stderr, "FramesPerSec: %d\n", FramesPerSec); -+ break; -+ } -+ // continue with next NAL unit -+ p = pNext; -+ } -+ } -+ else { -+#endif -+ // thanks to cVideoRepacker, the payload starts with a sequence header -+ if (p + 12 <= Limit) { -+ if (p[0] == 0x00 && p[1] == 0x00 && p[2] == 0x01 && p[3] == 0xB3) { -+ uint32_t frame_rate_code = p[7] & 0x0F; -+ uint32_t frame_rate_extension_n = 0; -+ uint32_t frame_rate_extension_d = 0; -+ // now we need to have a look at the next startcode, -+ // as it might be a sequence extension -+ p = (uchar *)memmem(p + 12, Limit - (p + 12), "\x00\x00\x01", 3); -+ if (p && p + 4 < Limit && p[3] == 0xB5) { // extension start code -+ if (p + 5 < Limit && (p[4] >> 4) == 0x1) { // sequence extension -+ if (p + 10 < Limit) { -+ frame_rate_extension_n = (p[9] & 0x60) >> 5; -+ frame_rate_extension_d = (p[9] & 0x1F); -+ } -+ } -+ } -+ // calculate frame rate and round it for compatibility -+ if (0x1 <= frame_rate_code && frame_rate_code <= 0x8) { -+ static const int n[] = { -1, 24000, 24, 25, 30000, 30, 50, 60000, 60 }; -+ static const int d[] = { -1, 1001, 1, 1, 1001, 1, 1, 1001, 1 }; -+ double frame_rate = n[frame_rate_code] * (frame_rate_extension_n + 1) -+ / (double)(d[frame_rate_code] * (frame_rate_extension_d + 1)); -+ FramesPerSec = (int)frame_rate; -+ if (frame_rate - FramesPerSec > 0.5) -+ FramesPerSec++; -+fprintf(stderr, "FramesPerSec: %d\n", FramesPerSec); -+ } -+ } -+ } -+#ifdef ADD_H264_SUPPORT -+ } -+#endif -+ } -+ } -+ } -+ } -+ // restore original position -+ Seek(OrigPos, SEEK_SET); -+ return FramesPerSec; -+} -+ - // --- cLockFile ------------------------------------------------------------- - - #define LOCKFILENAME ".lock-vdr" -diff -ruNp vdr-1.7.0-extensions/tools.h vdr-1.7.0-ext-h264-s2ng-speedup/tools.h ---- vdr-1.7.0-extensions/tools.h 2008-02-17 14:41:27.000000000 +0100 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/tools.h 2009-04-12 23:57:23.000000000 +0200 -@@ -167,6 +167,7 @@ public: - - ssize_t safe_read(int filedes, void *buffer, size_t size); - ssize_t safe_write(int filedes, const void *buffer, size_t size); -+int readchar(int filedes); - void writechar(int filedes, char c); - int WriteAllOrNothing(int fd, const uchar *Data, int Length, int TimeoutMs = 0, int RetryMs = 0); - ///< Writes either all Data to the given file descriptor, or nothing at all. -@@ -353,6 +354,8 @@ public: - ssize_t Read(void *Data, size_t Size); - ssize_t Write(const void *Data, size_t Size); - static cUnbufferedFile *Create(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE); -+ static int GetFramesPerSec(const char *FileName); -+ int GetFramesPerSec(void); - }; - - class cLockFile { -diff -ruNp vdr-1.7.0-extensions/transfer.c vdr-1.7.0-ext-h264-s2ng-speedup/transfer.c ---- vdr-1.7.0-extensions/transfer.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/transfer.c 2009-04-12 23:57:23.000000000 +0200 -@@ -19,11 +19,7 @@ cTransfer::cTransfer(tChannelID ChannelI - ,cThread("transfer") - { - ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer"); --#ifdef USE_SYNCEARLY -- remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, false, Setup.UseSyncEarlyPatch); --#else -- remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids); --#endif /* SYNCEARLY */ -+ remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, false, true); - } - - cTransfer::~cTransfer() -diff -ruNp vdr-1.7.0-extensions/vdr.c vdr-1.7.0-ext-h264-s2ng-speedup/vdr.c ---- vdr-1.7.0-extensions/vdr.c 2009-04-09 20:48:48.000000000 +0200 -+++ vdr-1.7.0-ext-h264-s2ng-speedup/vdr.c 2009-04-12 23:57:23.000000000 +0200 -@@ -580,10 +580,6 @@ int main(int argc, char *argv[]) - printf(" DOLBYINREC\n"); - #endif /* DOLBYINREC */ - --#ifdef USE_DVBPLAYER -- printf(" DVBPLAYER\n"); --#endif /* DVBPLAYER */ -- - #ifdef USE_DVBSETUP - printf(" DVBSETUP\n"); - #endif /* DVBSETUP */ -@@ -704,10 +700,6 @@ int main(int argc, char *argv[]) - printf(" STREAMDEVEXT\n"); - #endif /* STREAMDEVEXT */ - --#ifdef USE_SYNCEARLY -- printf(" SYNCEARLY\n"); --#endif /* SYNCEARLY */ -- - #ifdef USE_TIMERCMD - printf(" TIMERCMD\n"); - #endif /* TIMERCMD */ diff --git a/vdr/extensions/vdr-1.7.0_extensions.diff b/vdr/extensions/vdr-1.7.0_extensions.diff deleted file mode 100644 index 680aa02..0000000 --- a/vdr/extensions/vdr-1.7.0_extensions.diff +++ /dev/null @@ -1,28873 +0,0 @@ -diff -ruNp vdr-1.7.0/channels.c vdr-1.7.0-extensions/channels.c ---- vdr-1.7.0/channels.c 2008-04-12 15:49:12.000000000 +0200 -+++ vdr-1.7.0-extensions/channels.c 2009-04-09 20:48:48.000000000 +0200 -@@ -13,6 +13,9 @@ - #include "device.h" - #include "epg.h" - #include "timers.h" -+#ifdef USE_STREAMDEVEXT -+#include "status.h" -+#endif /* STREAMDEVEXT */ - - // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d' - // format characters in order to allow any number of blanks after a numeric -@@ -216,6 +219,9 @@ cChannel::cChannel(void) - shortName = strdup(""); - provider = strdup(""); - portalName = strdup(""); -+#ifdef USE_PLUGINPARAM -+ pluginParam = strdup(""); -+#endif /* PLUGINPARAM */ - memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__); - inversion = DVBFE_INVERSION_AUTO; - bandwidth = DVBFE_BANDWIDTH_AUTO; -@@ -241,6 +247,9 @@ cChannel::cChannel(const cChannel &Chann - shortName = NULL; - provider = NULL; - portalName = NULL; -+#ifdef USE_PLUGINPARAM -+ pluginParam = NULL; -+#endif /* PLUGINPARAM */ - schedule = NULL; - linkChannels = NULL; - refChannel = NULL; -@@ -269,6 +278,9 @@ cChannel::~cChannel() - free(shortName); - free(provider); - free(portalName); -+#ifdef USE_PLUGINPARAM -+ free(pluginParam); -+#endif /* PLUGINPARAM */ - } - - cChannel& cChannel::operator= (const cChannel &Channel) -@@ -277,6 +289,9 @@ cChannel& cChannel::operator= (const cCh - shortName = strcpyrealloc(shortName, Channel.shortName); - provider = strcpyrealloc(provider, Channel.provider); - portalName = strcpyrealloc(portalName, Channel.portalName); -+#ifdef USE_PLUGINPARAM -+ pluginParam = strcpyrealloc(pluginParam, Channel.pluginParam); -+#endif /* PLUGINPARAM */ - memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__); - return *this; - } -@@ -338,6 +353,9 @@ void cChannel::CopyTransponderData(const - alpha = Channel->alpha; - priority = Channel->priority; - rollOff = Channel->rollOff; -+#ifdef USE_PLUGINPARAM -+ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, Channel->pluginParam); -+#endif /* PLUGINPARAM */ - } - } - -@@ -375,6 +393,24 @@ bool cChannel::SetSatTransponderData(int - return true; - } - -+#ifdef USE_PLUGINPARAM -+bool cChannel::SetPlugTransponderData(int Source, int Frequency, const char *PluginParam) -+{ -+ if (source != Source || frequency != Frequency || (strcmp(pluginParam, PluginParam) != 0)) { -+ if (Number()) { -+ dsyslog("changing transponder data of channel %d from %s:%d:%s to %s:%d:%s", Number(), *cSource::ToString(source), frequency, pluginParam, *cSource::ToString(Source), Frequency, PluginParam); -+ modification |= CHANNELMOD_TRANSP; -+ Channels.SetModified(); -+ } -+ source = Source; -+ frequency = Frequency; -+ pluginParam = strcpyrealloc(pluginParam, PluginParam); -+ schedule = NULL; -+ } -+ return true; -+} -+#endif /* PLUGINPARAM */ -+ - bool cChannel::SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH) - { - if (source != Source || frequency != Frequency || modulation != Modulation || srate != Srate || coderateH != CoderateH) { -@@ -447,6 +483,9 @@ void cChannel::SetName(const char *Name, - if (nn || ns || np) { - if (Number()) { - dsyslog("changing name of channel %d from '%s,%s;%s' to '%s,%s;%s'", Number(), name, shortName, provider, Name, ShortName, Provider); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(this, scMod); -+#endif /* STREAMDEVEXT */ - modification |= CHANNELMOD_NAME; - Channels.SetModified(); - } -@@ -472,6 +511,20 @@ void cChannel::SetPortalName(const char - } - } - -+#ifdef USE_PLUGINPARAM -+void cChannel::SetPluginParam(const char *PluginParam) -+{ -+ if (!isempty(PluginParam) && strcmp(pluginParam, PluginParam) != 0) { -+ if (Number()) { -+ dsyslog("changing plugin parameters of channel %d from '%s' to '%s'", Number(), pluginParam, PluginParam); -+ modification |= CHANNELMOD_TRANSP; -+ Channels.SetModified(); -+ } -+ pluginParam = strcpyrealloc(pluginParam, PluginParam); -+ } -+} -+#endif /* PLUGINPARAM */ -+ - #define STRDIFF 0x01 - #define VALDIFF 0x02 - -@@ -665,7 +718,11 @@ cString cChannel::ParametersToString(voi - if (isdigit(type)) - type = 'S'; - #define ST(s) if (strchr(s, type)) -+#ifdef USE_PLUGINPARAM -+ char buffer[256]; -+#else - char buffer[64]; -+#endif /* PLUGINPARAM */ - char *q = buffer; - *q = 0; - ST(" S ") q += sprintf(q, "%c", polarization); -@@ -681,6 +738,9 @@ cString cChannel::ParametersToString(voi - ST(" S ") q += PrintParameter(q, 'S', MapToUser(system, SystemValues)); - ST(" T") q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues)); - ST(" T") q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues)); -+#ifdef USE_PLUGINPARAM -+ ST("P ") snprintf(buffer, sizeof(buffer), "%s", pluginParam); -+#endif /* PLUGINPARAM */ - return buffer; - } - -@@ -702,7 +762,11 @@ static const char *ParseParameter(const - - bool cChannel::StringToParameters(const char *s) - { -+#ifdef USE_PLUGINPARAM -+ while (s && *s && !IsPlug()) { -+#else - while (s && *s) { -+#endif /* PLUGINPARAM */ - switch (toupper(*s)) { - case 'A': s = ParseParameter(s, alpha, AlphaValues); break; - case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break; -@@ -817,7 +881,11 @@ bool cChannel::Parse(const char *s) - dpids[0] = 0; - ok = false; - if (parambuf && sourcebuf && vpidbuf && apidbuf) { -+#ifdef USE_PLUGINPARAM -+ ok = ((source = cSource::FromString(sourcebuf)) >= 0) && StringToParameters(parambuf); -+#else - ok = StringToParameters(parambuf) && (source = cSource::FromString(sourcebuf)) >= 0; -+#endif /* PLUGINPARAM */ - - char *p = strchr(vpidbuf, '+'); - if (p) -@@ -908,6 +976,9 @@ bool cChannel::Parse(const char *s) - shortName = strcpyrealloc(shortName, p); - } - name = strcpyrealloc(name, namebuf); -+#ifdef USE_PLUGINPARAM -+ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, parambuf); -+#endif /* PLUGINPARAM */ - - free(parambuf); - free(sourcebuf); -@@ -1153,6 +1224,9 @@ cChannel *cChannels::NewChannel(const cC - NewChannel->SetName(Name, ShortName, Provider); - Add(NewChannel); - ReNumber(); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(NewChannel, scAdd); -+#endif /* STREAMDEVEXT */ - return NewChannel; - } - return NULL; -diff -ruNp vdr-1.7.0/channels.h vdr-1.7.0-extensions/channels.h ---- vdr-1.7.0/channels.h 2008-04-12 15:46:50.000000000 +0200 -+++ vdr-1.7.0-extensions/channels.h 2009-04-09 20:48:48.000000000 +0200 -@@ -118,6 +118,9 @@ private: - char *shortName; - char *provider; - char *portalName; -+#ifdef USE_PLUGINPARAM -+ char *pluginParam; -+#endif /* PLUGINPARAM */ - int __BeginData__; - int frequency; // MHz - int source; -@@ -174,6 +177,9 @@ public: - int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf' - int Transponder(void) const; ///< Returns the transponder frequency in MHz, plus the polarization in case of sat - static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization -+#ifdef USE_PLUGINPARAM -+ const char *PluginParam(void) const { return pluginParam; } -+#endif /* PLUGINPARAM */ - int Source(void) const { return source; } - int Srate(void) const { return srate; } - int Vpid(void) const { return vpid; } -@@ -212,6 +218,9 @@ public: - int RollOff(void) const { return rollOff; } - const cLinkChannels* LinkChannels(void) const { return linkChannels; } - const cChannel *RefChannel(void) const { return refChannel; } -+#ifdef USE_PLUGINPARAM -+ bool IsPlug(void) const { return cSource::IsPlug(source); } -+#endif /* PLUGINPARAM */ - bool IsCable(void) const { return cSource::IsCable(source); } - bool IsSat(void) const { return cSource::IsSat(source); } - bool IsTerr(void) const { return cSource::IsTerr(source); } -@@ -219,12 +228,18 @@ public: - bool HasTimer(void) const; - int Modification(int Mask = CHANNELMOD_ALL); - void CopyTransponderData(const cChannel *Channel); -+#ifdef USE_PLUGINPARAM -+ bool SetPlugTransponderData(int Source, int Frequency, const char *PluginParam); -+#endif /* PLUGINPARAM */ - bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation, int System, int RollOff); - bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH); - bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission, int Alpha, int Priority); - void SetId(int Nid, int Tid, int Sid, int Rid = 0); - void SetName(const char *Name, const char *ShortName, const char *Provider); - void SetPortalName(const char *PortalName); -+#ifdef USE_PLUGINPARAM -+ void SetPluginParam(const char *PluginParam); -+#endif /* PLUGINPARAM */ - void SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); - void SetCaIds(const int *CaIds); // list must be zero-terminated - void SetCaDescriptors(int Level); -diff -ruNp vdr-1.7.0/config.c vdr-1.7.0-extensions/config.c ---- vdr-1.7.0/config.c 2008-02-17 14:39:00.000000000 +0100 -+++ vdr-1.7.0-extensions/config.c 2009-04-09 20:48:48.000000000 +0200 -@@ -15,6 +15,9 @@ - #include "interface.h" - #include "plugin.h" - #include "recording.h" -+#ifdef USE_SOURCECAPS -+#include "sources.h" -+#endif /* SOURCECAPS */ - - // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d' - // format characters in order to allow any number of blanks after a numeric -@@ -28,18 +31,32 @@ cCommand::cCommand(void) - { - title = command = NULL; - confirm = false; -+#ifdef USE_CMDSUBMENU -+ nIndent = 0; -+ childs = NULL; -+#endif /* CMDSUBMENU */ - } - - cCommand::~cCommand() - { - free(title); - free(command); -+#ifdef USE_CMDSUBMENU -+ delete childs; -+#endif /* CMDSUBMENU */ - } - - bool cCommand::Parse(const char *s) - { - const char *p = strchr(s, ':'); - if (p) { -+#ifdef USE_CMDSUBMENU -+ nIndent = 0; -+ while (*s == '-') { -+ nIndent++; -+ s++; -+ } -+#endif /* CMDSUBMENU */ - int l = p - s; - if (l > 0) { - title = MALLOC(char, l + 1); -@@ -85,6 +102,20 @@ const char *cCommand::Execute(const char - return result; - } - -+#ifdef USE_CMDSUBMENU -+int cCommand::getChildCount(void) -+{ -+ return childs ? childs->Count() : 0; -+} -+ -+void cCommand::addChild(cCommand *newChild) -+{ -+ if (!childs) -+ childs = new cCommands(); -+ childs->AddConfig(newChild); -+} -+#endif /* CMDSUBMENU */ -+ - // --- cSVDRPhost ------------------------------------------------------------ - - cSVDRPhost::cSVDRPhost(void) -@@ -125,6 +156,26 @@ bool cSVDRPhost::Accepts(in_addr_t Addre - - cCommands Commands; - cCommands RecordingCommands; -+#ifdef USE_TIMERCMD -+cCommands TimerCommands; -+#endif /* TIMERCMD */ -+ -+#ifdef USE_CMDSUBMENU -+void cCommands::AddConfig(cCommand *Object) -+{ -+ if (!Object) -+ return; -+ //isyslog ("Indent %d %s\n", Object->getIndent(), Object->Title()); -+ for (int index = Count() - 1; index >= 0; index--) { -+ cCommand *parent = Get(index); -+ if (parent->getIndent() < Object->getIndent()) { -+ parent->addChild(Object); -+ return; -+ } -+ } -+ cConfig<cCommand>::Add(Object); -+} -+#endif /* CMDSUBMENU */ - - // --- cSVDRPhosts ----------------------------------------------------------- - -@@ -216,6 +267,12 @@ cSetup::cSetup(void) - strcpy(OSDLanguage, ""); // default is taken from environment - strcpy(OSDSkin, "sttng"); - strcpy(OSDTheme, "default"); -+#ifdef USE_WAREAGLEICON -+ WarEagleIcons = 1; -+#endif /* WAREAGLEICON */ -+#ifdef USE_VALIDINPUT -+ ShowValidInput = 0; -+#endif /* VALIDINPUT */ - PrimaryDVB = 1; - ShowInfoOnChSwitch = 1; - TimeoutRequChInfo = 1; -@@ -260,6 +317,18 @@ cSetup::cSetup(void) - VideoFormat = 0; - UpdateChannels = 5; - UseDolbyDigital = 1; -+#ifdef USE_DOLBYINREC -+ UseDolbyInRecordings = 1; -+#endif /* DOLBYINREC */ -+#ifdef USE_DVBSETUP -+ DolbyTransferFix = 1; -+ ChannelBlocker = 0; -+ ChannelBlockerMode = 0; -+ ChannelBlockerList = strdup(""); -+#endif /* DVBSETUP */ -+#ifdef USE_SYNCEARLY -+ UseSyncEarlyPatch = 0; -+#endif /* SYNCEARLY */ - ChannelInfoPos = 0; - ChannelInfoTime = 5; - OSDLeft = 54; -@@ -276,24 +345,143 @@ cSetup::cSetup(void) - FontSmlSize = 18; - FontFixSize = 20; - MaxVideoFileSize = MAXVIDEOFILESIZE; -+#ifdef USE_HARDLINKCUTTER -+ MaxRecordingSize = DEFAULTRECORDINGSIZE; -+#endif /* HARDLINKCUTTER */ - SplitEditedFiles = 0; -+#ifdef USE_HARDLINKCUTTER -+ HardLinkCutter = 0; -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ DelTimeshiftRec = 0; -+#endif /* DELTIMESHIFTREC */ - MinEventTimeout = 30; - MinUserInactivity = 300; - NextWakeupTime = 0; - MultiSpeedMode = 0; - ShowReplayMode = 0; -+#ifdef USE_DDEPGENTRY -+ DoubleEpgTimeDelta = 15; -+ DoubleEpgAction = 0; -+ MixEpgAction = 0; -+ DisableVPS = 0; -+#endif /* DDEPGENTRY */ - ResumeID = 0; -+#ifdef USE_JUMPPLAY -+ JumpPlay = 0; -+ PlayJump = 0; -+ PauseLastMark = 0; -+ ReloadMarks = 0; -+#endif /* JUMPPLAY */ -+#ifdef USE_SOURCECAPS -+ memset(SourceCaps, 0, sizeof SourceCaps); -+ SourceCapsSet = false; -+#endif /* SOURCECAPS */ - CurrentChannel = -1; - CurrentVolume = MAXVOLUME; - CurrentDolby = 0; - InitialChannel = 0; - InitialVolume = -1; -+#ifdef USE_VOLCTRL -+ LRVolumeControl = 0; -+ LRChannelGroups = 1; -+ LRForwardRewind = 1; -+#endif /* VOLCTRL */ - EmergencyExit = 1; -+#ifdef USE_NOEPG -+ noEPGMode = 0; -+ noEPGList = strdup(""); -+#endif /* NOEPG */ -+#ifdef USE_LIRCSETTINGS -+ LircRepeatDelay = 350; -+ LircRepeatFreq = 100; -+ LircRepeatTimeout = 500; -+#endif /* LIRCSETTINGS */ -+#ifdef USE_LIEMIEXT -+ ShowRecDate = 1; -+ ShowRecTime = 1; -+ ShowRecLength = 0; -+ ShowProgressBar = 0; -+ MenuCmdPosition = 0; -+ JumpSeconds = 60; -+ JumpSecondsSlow = 10; -+ ShowTimerStop = 1; -+ MainMenuTitle = 0; -+ strcpy(CustomMainMenuTitle, "Video Disk Recorder"); -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ RecordingsSortMode = 0; -+ RecordingsSortDirsFirst = 0; -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ CutterAutoDelete = 0; -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ CutTime = 1; -+#endif /* CUTTIME */ -+#ifdef USE_LIVEBUFFER -+ LiveBuffer = false; -+ KeepPaused = false; -+ LiveBufferSize = 100; -+ InRAM = false; -+ MemBufSize = 5; -+ ExtendBuffer = false; -+#endif /* LIVEBUFFER */ -+#ifdef USE_DVDARCHIVE -+ DvdDisplayMode = 1; -+ DvdDisplayZeros = 1; -+ DvdTrayMode = 0; -+ DvdSpeedLimit = 0; -+#endif /* DVDARCHIVE */ -+#ifdef USE_SOFTOSD -+ UseSoftOsd = 0; -+ SoftOsdRate = 50; -+ SoftOsdFadeinSteps = 6; -+ SoftOsdFadeoutSteps = 16; -+ SoftOsdPaletteOnly = 0; -+#endif /* SOFTOSD */ -+#ifdef USE_LNBSHARE -+ VerboseLNBlog = 0; -+ for (int i = 0; i < MAXDEVICES; i++) CardUsesLNBnr[i] = i + 1; -+#endif /* LNBSHARE */ -+#ifdef USE_DVLVIDPREFER -+ UseVidPrefer = 0; // default = disabled -+ nVidPrefer = 1; -+ for (int zz = 1; zz < DVLVIDPREFER_MAX; zz++) { -+ VidPreferPrio[ zz ] = 50; -+ VidPreferSize[ zz ] = 100; -+ } -+ VidPreferSize[ 0 ] = 800; -+ VidPreferPrio[ 0 ] = 50; -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLFRIENDLYFNAMES -+ UseFriendlyFNames = 0; // default = disabled -+#endif /* DVLFRIENDLYFNAMES */ -+} -+ -+#if defined (USE_DVBSETUP) || defined (USE_NOEPG) -+cSetup::~cSetup() -+{ -+#ifdef USE_DVBSETUP -+ free(ChannelBlockerList); -+#endif /* DVBSETUP */ -+#ifdef USE_NOEPG -+ free(noEPGList); -+#endif /* NOEPG */ - } -+#endif /* DVBSETUP + NOEPG */ - - cSetup& cSetup::operator= (const cSetup &s) - { - memcpy(&__BeginData__, &s.__BeginData__, (char *)&s.__EndData__ - (char *)&s.__BeginData__); -+#ifdef USE_DVBSETUP -+ free(ChannelBlockerList); -+ ChannelBlockerList = strdup(s.ChannelBlockerList); -+#endif /* DVBSETUP */ -+#ifdef USE_NOEPG -+ free(noEPGList); -+ noEPGList = strdup(s.noEPGList); -+#endif /* NOEPG */ - return *this; - } - -@@ -384,11 +572,62 @@ bool cSetup::ParseLanguages(const char * - return true; - } - -+#ifdef USE_SOURCECAPS -+void cSetup::StoreSourceCaps(const char *Name) -+{ -+ cSetupLine *l; -+ while ((l = Get(Name)) != NULL) -+ Del(l); -+ -+ for (int i = 0; i < MAXDEVICES; i++) { -+ char buffer[MAXSOURCECAPS*8]={0,}, *q = buffer; -+ int j = 0; -+ while (SourceCaps[i][j] && j < MAXSOURCECAPS) { -+ if (j==0) -+ q += snprintf(buffer, sizeof(buffer), "%i ", i+1); -+ q += snprintf(q, sizeof(buffer) - (q-buffer), "%s ", *cSource::ToString(SourceCaps[i][j++])); -+ } -+ if (*buffer) -+ Store(Name, buffer, NULL, true); -+ } -+} -+ -+bool cSetup::ParseSourceCaps(const char *Value) -+{ -+ char *p; -+ int d = strtol(Value, &p, 10)-1, i = 0; -+ while (p < Value+strlen(Value)) { -+ if (*p==0) return true; -+ if (isblank(*p)) ++p; -+ if (isalpha(*p)) { -+ int source = cSource::FromString(p); -+ if (source != cSource::stNone) { -+ SourceCaps[d][i++] = source; -+ SourceCapsSet = true; -+ } -+ else -+ return false; -+ while (!isblank(*p) && *p) -+ ++p; -+ if (i>MAXSOURCECAPS) -+ return false; -+ } -+ } -+ return true; -+} -+#endif /* SOURCECAPS */ -+ - bool cSetup::Parse(const char *Name, const char *Value) - { - if (!strcasecmp(Name, "OSDLanguage")) { strn0cpy(OSDLanguage, Value, sizeof(OSDLanguage)); I18nSetLocale(OSDLanguage); } - else if (!strcasecmp(Name, "OSDSkin")) Utf8Strn0Cpy(OSDSkin, Value, MaxSkinName); - else if (!strcasecmp(Name, "OSDTheme")) Utf8Strn0Cpy(OSDTheme, Value, MaxThemeName); -+#ifdef USE_WAREAGLEICON -+ else if (!strcasecmp(Name, "WarEagleIcons")) WarEagleIcons = atoi(Value); -+#endif /* WAREAGLEICON */ -+#ifdef USE_VALIDINPUT -+ else if (!strcasecmp(Name, "ShowValidInput")) ShowValidInput = atoi(Value); -+#endif /* VALIDINPUT */ - else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value); - else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value); - else if (!strcasecmp(Name, "TimeoutRequChInfo")) TimeoutRequChInfo = atoi(Value); -@@ -433,6 +672,21 @@ bool cSetup::Parse(const char *Name, con - else if (!strcasecmp(Name, "VideoFormat")) VideoFormat = atoi(Value); - else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value); - else if (!strcasecmp(Name, "UseDolbyDigital")) UseDolbyDigital = atoi(Value); -+#ifdef USE_DOLBYINREC -+ else if (!strcasecmp(Name, "UseDolbyInRecordings")) UseDolbyInRecordings = atoi(Value); -+#endif /* DOLBYINREC */ -+#ifdef USE_DVBSETUP -+ else if (!strcasecmp(Name, "DolbyTransferFix")) DolbyTransferFix = atoi(Value); -+ else if (!strcasecmp(Name, "ChannelBlocker")) ChannelBlocker = atoi(Value); -+ else if (!strcasecmp(Name, "ChannelBlockerMode")) ChannelBlockerMode = atoi(Value); -+ else if (!strcasecmp(Name, "ChannelBlockerList")) { -+ free(ChannelBlockerList); -+ ChannelBlockerList = strdup(Value ? Value : ""); -+ } -+#endif /* DVBSETUP */ -+#ifdef USE_SYNCEARLY -+ else if (!strcasecmp(Name, "UseSyncEarlyPatch")) UseSyncEarlyPatch = atoi(Value); -+#endif /* SYNCEARLY */ - else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value); - else if (!strcasecmp(Name, "ChannelInfoTime")) ChannelInfoTime = atoi(Value); - else if (!strcasecmp(Name, "OSDLeft")) OSDLeft = atoi(Value); -@@ -449,21 +703,152 @@ bool cSetup::Parse(const char *Name, con - else if (!strcasecmp(Name, "FontSmlSize")) FontSmlSize = atoi(Value); - else if (!strcasecmp(Name, "FontFixSize")) FontFixSize = atoi(Value); - else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value); -+#ifdef USE_HARDLINKCUTTER -+ else if (!strcasecmp(Name, "MaxRecordingSize")) MaxRecordingSize = atoi(Value); -+#endif /* HARDLINKCUTTER */ - else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value); -+#ifdef USE_HARDLINKCUTTER -+ else if (!strcasecmp(Name, "HardLinkCutter")) HardLinkCutter = atoi(Value); -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ else if (!strcasecmp(Name, "DelTimeshiftRec")) DelTimeshiftRec = atoi(Value); -+#endif /* DELTIMESHIFTREC */ - else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value); - else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value); - else if (!strcasecmp(Name, "NextWakeupTime")) NextWakeupTime = atoi(Value); - else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value); - else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value); -+#ifdef USE_DDEPGENTRY -+ else if (!strcasecmp(Name, "DoubleEpgTimeDelta")) DoubleEpgTimeDelta = atoi(Value); -+ else if (!strcasecmp(Name, "DoubleEpgAction")) DoubleEpgAction = atoi(Value); -+ else if (!strcasecmp(Name, "MixEpgAction")) MixEpgAction = atoi(Value); -+ else if (!strcasecmp(Name, "DisableVPS")) DisableVPS = atoi(Value); -+#endif /* DDEPGENTRY */ - else if (!strcasecmp(Name, "ResumeID")) ResumeID = atoi(Value); -+#ifdef USE_JUMPPLAY -+ else if (!strcasecmp(Name, "JumpPlay")) JumpPlay = atoi(Value); -+ else if (!strcasecmp(Name, "PlayJump")) PlayJump = atoi(Value); -+ else if (!strcasecmp(Name, "PauseLastMark")) PauseLastMark = atoi(Value); -+ else if (!strcasecmp(Name, "ReloadMarks")) ReloadMarks = atoi(Value); -+#endif /* JUMPPLAY */ -+#ifdef USE_SOURCECAPS -+ else if (!strcasecmp(Name, "SourceCaps")) return ParseSourceCaps(Value); -+#endif /* SOURCECAPS */ - else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value); - else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value); - else if (!strcasecmp(Name, "CurrentDolby")) CurrentDolby = atoi(Value); - else if (!strcasecmp(Name, "InitialChannel")) InitialChannel = atoi(Value); - else if (!strcasecmp(Name, "InitialVolume")) InitialVolume = atoi(Value); -+#ifdef USE_VOLCTRL -+ else if (!strcasecmp(Name, "LRVolumeControl")) LRVolumeControl = atoi(Value); -+ else if (!strcasecmp(Name, "LRChannelGroups")) LRChannelGroups = atoi(Value); -+ else if (!strcasecmp(Name, "LRForwardRewind")) LRForwardRewind = atoi(Value); -+#endif /* VOLCTRL */ - else if (!strcasecmp(Name, "EmergencyExit")) EmergencyExit = atoi(Value); -+#ifdef USE_NOEPG -+ else if (!strcasecmp(Name, "noEPGMode")) noEPGMode = atoi(Value); -+ else if (!strcasecmp(Name, "noEPGList")) { -+ free(noEPGList); -+ noEPGList = strdup(Value ? Value : ""); -+ } -+#endif /* NOEPG */ -+#ifdef USE_LIRCSETTINGS -+ else if (!strcasecmp(Name, "LircRepeatDelay")) LircRepeatDelay = atoi(Value); -+ else if (!strcasecmp(Name, "LircRepeatFreq")) LircRepeatFreq = atoi(Value); -+ else if (!strcasecmp(Name, "LircRepeatTimeout")) LircRepeatTimeout = atoi(Value); -+#endif /* LIRCSETTINGS */ -+#ifdef USE_LIEMIEXT -+ else if (!strcasecmp(Name, "ShowRecDate")) ShowRecDate = atoi(Value); -+ else if (!strcasecmp(Name, "ShowRecTime")) ShowRecTime = atoi(Value); -+ else if (!strcasecmp(Name, "ShowRecLength")) ShowRecLength = atoi(Value); -+ else if (!strcasecmp(Name, "ShowProgressBar")) ShowProgressBar = atoi(Value); -+ else if (!strcasecmp(Name, "MenuCmdPosition")) MenuCmdPosition = atoi(Value); -+ else if (!strcasecmp(Name, "JumpSeconds")) JumpSeconds = atoi(Value); -+ else if (!strcasecmp(Name, "JumpSecondsSlow")) JumpSecondsSlow = atoi(Value); -+ else if (!strcasecmp(Name, "ShowTimerStop")) ShowTimerStop = atoi(Value); -+ else if (!strcasecmp(Name, "MainMenuTitle")) MainMenuTitle = atoi(Value); -+ else if (!strcasecmp(Name, "CustomMainMenuTitle")) Utf8Strn0Cpy(CustomMainMenuTitle, Value, MaxTitleName); -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ else if (!strcasecmp(Name, "RecordingsSortMode")) RecordingsSortMode = atoi(Value); -+ else if (!strcasecmp(Name, "RecordingsSortDirsFirst")) RecordingsSortDirsFirst = atoi(Value); -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ else if (!strcasecmp(Name, "CutterAutoDelete")) CutterAutoDelete = atoi(Value); -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ else if (!strcasecmp(Name, "CutTime")) CutTime = atoi(Value); -+#endif /* CUTTIME */ -+#ifdef USE_LIVEBUFFER -+ else if (!strcasecmp(Name, "LiveBuffer")) LiveBuffer = atoi(Value); -+ else if (!strcasecmp(Name, "KeepPaused")) KeepPaused = atoi(Value); -+ else if (!strcasecmp(Name, "LiveBufferSize")) LiveBufferSize = atoi(Value); -+ else if (!strcasecmp(Name, "InRAM")) InRAM = atoi(Value); -+ else if (!strcasecmp(Name, "MemBufSize")) MemBufSize = atoi(Value); -+ else if (!strcasecmp(Name, "ExtendBuffer")) ExtendBuffer = atoi(Value); -+#endif /* LIVEBUFFER */ -+#ifdef USE_DVDARCHIVE -+ else if (!strcasecmp(Name, "DvdDisplayMode")) DvdDisplayMode = atoi(Value); -+ else if (!strcasecmp(Name, "DvdDisplayZeros")) DvdDisplayZeros = atoi(Value); -+ else if (!strcasecmp(Name, "DvdTrayMode")) DvdTrayMode = atoi(Value); -+ else if (!strcasecmp(Name, "DvdSpeedLimit")) DvdSpeedLimit = atoi(Value); -+#endif /* DVDARCHIVE */ -+#ifdef USE_SOFTOSD -+ else if (!strcasecmp(Name, "UseSoftOsd")) UseSoftOsd = atoi(Value); -+ else if (!strcasecmp(Name, "SoftOsdRate")) SoftOsdRate = atoi(Value); -+ else if (!strcasecmp(Name, "SoftOsdFadeinSteps")) SoftOsdFadeinSteps = atoi(Value); -+ else if (!strcasecmp(Name, "SoftOsdFadeoutSteps")) SoftOsdFadeoutSteps = atoi(Value); -+ else if (!strcasecmp(Name, "SoftOsdPaletteOnly")) SoftOsdPaletteOnly = atoi(Value); -+#endif /* SOFTOSD */ -+#ifdef USE_DVLVIDPREFER -+ else if (strcasecmp(Name, "UseVidPrefer") == 0) UseVidPrefer = atoi(Value); -+ else if (strcasecmp(Name, "nVidPrefer") == 0) nVidPrefer = atoi(Value); -+ else if (strstr(Name, "VidPrefer") == Name) { -+ char *x = (char *)&Name[ strlen(Name) - 1 ]; -+ int vN; -+ -+ if (isdigit(*x) != 0) { -+ while (isdigit(*x) != 0) -+ x--; -+ x++; -+ } -+ -+ vN = atoi(x); -+ if (vN < DVLVIDPREFER_MAX) { -+ if (strstr(Name, "VidPreferPrio") == Name) { -+ VidPreferPrio[ vN ] = atoi(Value); -+ if (VidPreferPrio[ vN ] > 99) -+ VidPreferPrio[ vN ] = 99; -+ } -+ else if (strstr(Name, "VidPreferSize") == Name) { -+ VidPreferSize[ vN ] = atoi(Value); -+ } -+ else -+ return false; -+ } -+ } -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLFRIENDLYFNAMES -+ else if (strcasecmp(Name, "UseFriendlyFNames") == 0) UseFriendlyFNames = atoi(Value); -+#endif /* DVLFRIENDLYFNAMES */ - else -+#ifdef USE_LNBSHARE -+ if (!strcasecmp(Name, "VerboseLNBlog")) VerboseLNBlog = atoi(Value); -+ else { -+ char tmp[20]; -+ bool result = false; -+ for (int i = 1; i <= MAXDEVICES; i++) { -+ sprintf(tmp, "Card%dusesLNBnr", i); -+ if (!strcasecmp(Name, tmp)) { -+ CardUsesLNBnr[i - 1] = atoi(Value); -+ result = true; -+ } -+ } -+ return result; -+ } -+#else - return false; -+#endif /* LNBSHARE */ - return true; - } - -@@ -472,6 +857,12 @@ bool cSetup::Save(void) - Store("OSDLanguage", OSDLanguage); - Store("OSDSkin", OSDSkin); - Store("OSDTheme", OSDTheme); -+#ifdef USE_WAREAGLEICON -+ Store("WarEagleIcons", WarEagleIcons); -+#endif /* WAREAGLEICON */ -+#ifdef USE_VALIDINPUT -+ Store("ShowValidInput", ShowValidInput); -+#endif /* VALIDINPUT */ - Store("PrimaryDVB", PrimaryDVB); - Store("ShowInfoOnChSwitch", ShowInfoOnChSwitch); - Store("TimeoutRequChInfo", TimeoutRequChInfo); -@@ -516,6 +907,18 @@ bool cSetup::Save(void) - Store("VideoFormat", VideoFormat); - Store("UpdateChannels", UpdateChannels); - Store("UseDolbyDigital", UseDolbyDigital); -+#ifdef USE_DOLBYINREC -+ Store("UseDolbyInRecordings", UseDolbyInRecordings); -+#endif /* DOLBYINREC */ -+#ifdef USE_DVBSETUP -+ Store("DolbyTransferFix", DolbyTransferFix); -+ Store("ChannelBlocker", ChannelBlocker); -+ Store("ChannelBlockerMode", ChannelBlockerMode); -+ Store("ChannelBlockerList", ChannelBlockerList); -+#endif /* DVBSETUP */ -+#ifdef USE_SYNCEARLY -+ Store("UseSyncEarlyPatch", UseSyncEarlyPatch); -+#endif /* SYNCEARLY */ - Store("ChannelInfoPos", ChannelInfoPos); - Store("ChannelInfoTime", ChannelInfoTime); - Store("OSDLeft", OSDLeft); -@@ -532,25 +935,164 @@ bool cSetup::Save(void) - Store("FontSmlSize", FontSmlSize); - Store("FontFixSize", FontFixSize); - Store("MaxVideoFileSize", MaxVideoFileSize); -+#ifdef USE_HARDLINKCUTTER -+ Store("MaxRecordingSize", MaxRecordingSize); -+#endif /* HARDLINKCUTTER */ - Store("SplitEditedFiles", SplitEditedFiles); -+#ifdef USE_HARDLINKCUTTER -+ Store("HardLinkCutter", HardLinkCutter); -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ Store("DelTimeshiftRec", DelTimeshiftRec); -+#endif /* DELTIMESHIFTREC */ - Store("MinEventTimeout", MinEventTimeout); - Store("MinUserInactivity", MinUserInactivity); - Store("NextWakeupTime", NextWakeupTime); -+#ifdef USE_DDEPGENTRY -+ Store("DoubleEpgAction", DoubleEpgAction); -+ Store("MixEpgAction", MixEpgAction); -+ Store("DisableVPS", DisableVPS); -+ Store("DoubleEpgTimeDelta", DoubleEpgTimeDelta); -+#endif /* DDEPGENTRY */ - Store("MultiSpeedMode", MultiSpeedMode); - Store("ShowReplayMode", ShowReplayMode); - Store("ResumeID", ResumeID); -+#ifdef USE_JUMPPLAY -+ Store("JumpPlay", JumpPlay); -+ Store("PlayJump", PlayJump); -+ Store("PauseLastMark", PauseLastMark); -+ Store("ReloadMarks", ReloadMarks); -+#endif /* JUMPPLAY */ -+#ifdef USE_SOURCECAPS -+ if (SourceCapsSet) StoreSourceCaps("SourceCaps"); -+#endif /* SOURCECAPS */ - Store("CurrentChannel", CurrentChannel); - Store("CurrentVolume", CurrentVolume); - Store("CurrentDolby", CurrentDolby); - Store("InitialChannel", InitialChannel); - Store("InitialVolume", InitialVolume); -+#ifdef USE_VOLCTRL -+ Store("LRVolumeControl", LRVolumeControl); -+ Store("LRChannelGroups", LRChannelGroups); -+ Store("LRForwardRewind", LRForwardRewind); -+#endif /* VOLCTRL */ - Store("EmergencyExit", EmergencyExit); -+#ifdef USE_NOEPG -+ Store("noEPGMode", noEPGMode); -+ Store("noEPGList", noEPGList); -+#endif /* NOEPG */ -+#ifdef USE_LIRCSETTINGS -+ Store("LircRepeatDelay", LircRepeatDelay); -+ Store("LircRepeatFreq", LircRepeatFreq); -+ Store("LircRepeatTimeout", LircRepeatTimeout); -+#endif /* LIRCSETTINGS */ -+#ifdef USE_LIEMIEXT -+ Store("ShowRecDate", ShowRecDate); -+ Store("ShowRecTime", ShowRecTime); -+ Store("ShowRecLength", ShowRecLength); -+ Store("ShowProgressBar", ShowProgressBar); -+ Store("MenuCmdPosition", MenuCmdPosition); -+ Store("JumpSeconds", JumpSeconds); -+ Store("JumpSecondsSlow", JumpSecondsSlow); -+ Store("ShowTimerStop", ShowTimerStop); -+ Store("MainMenuTitle", MainMenuTitle); -+ Store("CustomMainMenuTitle",CustomMainMenuTitle); -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ Store("RecordingsSortMode", RecordingsSortMode); -+ Store("RecordingsSortDirsFirst", RecordingsSortDirsFirst); -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ Store("CutterAutoDelete", CutterAutoDelete); -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ Store("CutTime", CutTime); -+#endif /* CUTTIME */ -+#ifdef USE_LIVEBUFFER -+ Store("LiveBuffer", LiveBuffer); -+ Store("KeepPaused", KeepPaused); -+ Store("LiveBufferSize", LiveBufferSize); -+ Store("InRAM", InRAM); -+ Store("MemBufSize", MemBufSize); -+ Store("ExtendBuffer", ExtendBuffer); -+#endif /* LIVEBUFFER */ -+#ifdef USE_DVDARCHIVE -+ Store("DvdDisplayMode", DvdDisplayMode); -+ Store("DvdDisplayZeros", DvdDisplayZeros); -+ Store("DvdTrayMode", DvdTrayMode); -+ Store("DvdSpeedLimit", DvdSpeedLimit); -+#endif /* DVDARCHIVE */ -+#ifdef USE_SOFTOSD -+ Store("UseSoftOsd", UseSoftOsd); -+ Store("SoftOsdRate", SoftOsdRate); -+ Store("SoftOsdFadeinSteps", SoftOsdFadeinSteps); -+ Store("SoftOsdFadeoutSteps", SoftOsdFadeoutSteps); -+ Store("SoftOsdPaletteOnly", SoftOsdPaletteOnly); -+#endif /* SOFTOSD */ -+#ifdef USE_LNBSHARE -+ Store("VerboseLNBlog", VerboseLNBlog); -+ char tmp[20]; -+ if (cDevice::NumDevices() > 1) { -+ for (int i = 1; i <= cDevice::NumDevices(); i++) { -+ sprintf(tmp, "Card%dusesLNBnr", i); -+ Store(tmp, CardUsesLNBnr[i - 1]); -+ } -+ } -+#endif /* LNBSHARE */ -+#ifdef USE_DVLVIDPREFER -+ Store ("UseVidPrefer", UseVidPrefer); -+ Store ("nVidPrefer", nVidPrefer); -+ -+ char vidBuf[32]; -+ for (int zz = 0; zz < nVidPrefer; zz++) { -+ sprintf(vidBuf, "VidPreferPrio%d", zz); -+ Store (vidBuf, VidPreferPrio[zz]); -+ sprintf(vidBuf, "VidPreferSize%d", zz); -+ Store (vidBuf, VidPreferSize[zz]); -+ } -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLFRIENDLYFNAMES -+ Store ("UseFriendlyFNames", UseFriendlyFNames); -+#endif /* DVLFRIENDLYFNAMES */ - - Sort(); - - if (cConfig<cSetupLine>::Save()) { - isyslog("saved setup to %s", FileName()); -+#ifdef USE_DVDARCHIVE -+ if (DvdDisplayMode >= 1) ::Recordings.Load(); -+#endif /* DVDARCHIVE */ - return true; - } - return false; - } -+ -+#ifdef USE_CMDRECCMDI18N -+bool LoadCommandsI18n(cCommands & cmds, const char *FileName, bool AllowComments, bool MustExist) -+{ -+ -+ bool bRet = true; -+ bool bLoadDefault = (bool)strcmp(Setup.OSDLanguage,"en_US"); -+ if (bLoadDefault) { -+ // attempt to load a translated file -+ char *FullPath = NULL; -+ asprintf(&FullPath, "%s.%s", FileName, Setup.OSDLanguage); -+ if (!cmds.Load((FullPath), AllowComments, true)) { -+ // require to exist, just to be able to log -+ // fallback -+ bLoadDefault = false; -+ esyslog("Failed to load translated '%s' for language (%s)", FullPath, Setup.OSDLanguage); -+ esyslog("Falling back to default '%s' (if any)", FileName); -+ } -+ free(FullPath); -+ } -+ if (!bLoadDefault) { -+ // let's do it the normal way -+ bRet = cmds.Load(FileName, AllowComments, MustExist); -+ } -+ // return status only for the default commands file -+ return bRet; -+} -+ -+#endif /* CMDRECCMDI18N */ -+ -diff -ruNp vdr-1.7.0/config.h vdr-1.7.0-extensions/config.h ---- vdr-1.7.0/config.h 2008-04-12 15:02:10.000000000 +0200 -+++ vdr-1.7.0-extensions/config.h 2009-04-09 20:48:48.000000000 +0200 -@@ -36,23 +36,74 @@ - // plugins to work with newer versions of the core VDR as long as no - // VDR header files have changed. - -+#define VDREXTENSIONS 70 -+ -+#ifdef USE_JUMPPLAY -+#define JUMPPLAYVERSNUM 100 -+#endif /* JUMPPLAY */ -+ -+#ifdef USE_LIEMIEXT -+#define LIEMIKUUTIO 121 -+#define MAXMAINMENUTITLE 4 -+#define MaxTitleName 64 -+#endif /* LIEMIEXT */ -+ -+#ifdef USE_CMDSUBMENU -+#define CMDSUBMENUVERSNUM 7 -+#endif /* CMDSUBMENU */ -+ -+#ifdef USE_MAINMENUHOOKS -+#define MAINMENUHOOKSVERSNUM 1.0 -+#endif /* MAINMENUHOOKS */ -+ -+#ifdef USE_PINPLUGIN -+#define PIN_PLUGIN_PATCH 120 -+#endif /* PINPLUGIN */ -+ -+#ifdef USE_PLUGINPARAM -+#define PLUGINPARAMPATCHVERSNUM 1 -+#endif /* PLUGINPARAM */ -+ - #define MAXPRIORITY 99 - #define MAXLIFETIME 99 - -+#ifdef USE_DVLVIDPREFER -+#define DVLVIDPREFER_MAX 12 -+#endif /* DVLVIDPREFER */ -+ - #define MINOSDWIDTH 480 - #define MAXOSDWIDTH 672 - #define MINOSDHEIGHT 324 - #define MAXOSDHEIGHT 567 - -+#ifdef USE_SOURCECAPS -+#define MAXDEVICES 16 // the maximum number of devices in the system -+#define MAXSOURCECAPS 128 // the maximum number of different sources per device -+#endif /* SOURCECAPS */ -+ -+#ifdef USE_LNBSHARE -+#ifndef MAXDEVICES -+#define MAXDEVICES 16 // the maximum number of devices in the system -+#endif -+#endif /* LNBSHARE */ -+ - #define MaxFileName 256 - #define MaxSkinName 16 - #define MaxThemeName 16 - -+#ifdef USE_CMDSUBMENU -+class cCommands; -+#endif /* CMDSUBMENU */ -+ - class cCommand : public cListObject { - private: - char *title; - char *command; - bool confirm; -+#ifdef USE_CMDSUBMENU -+ int nIndent; -+ cCommands *childs; -+#endif /* CMDSUBMENU */ - static char *result; - public: - cCommand(void); -@@ -61,6 +112,14 @@ public: - const char *Title(void) { return title; } - bool Confirm(void) { return confirm; } - const char *Execute(const char *Parameters = NULL); -+#ifdef USE_CMDSUBMENU -+ int getIndent(void) { return nIndent; } -+ void setIndent(int nNewIndent) { nIndent = nNewIndent; } -+ cCommands *getChilds(void) { return childs; } -+ int getChildCount(void); -+ bool hasChilds(void) { return getChildCount() > 0; } -+ void addChild(cCommand *newChild); -+#endif /* CMDSUBMENU */ - }; - - typedef uint32_t in_addr_t; //XXX from /usr/include/netinet/in.h (apparently this is not defined on systems with glibc < 2.2) -@@ -88,6 +147,9 @@ private: - public: - cConfig(void) { fileName = NULL; } - virtual ~cConfig() { free(fileName); } -+#ifdef USE_CMDSUBMENU -+ virtual void AddConfig(T *Object) { cList<T>::Add(Object); } -+#endif /* CMDSUBMENU */ - const char *FileName(void) { return fileName; } - bool Load(const char *FileName = NULL, bool AllowComments = false, bool MustExist = false) - { -@@ -117,7 +179,11 @@ public: - if (!isempty(s)) { - T *l = new T; - if (l->Parse(s)) -+#ifdef USE_CMDSUBMENU -+ AddConfig(l); -+#else - Add(l); -+#endif /* CMDSUBMENU */ - else { - esyslog("ERROR: error in %s, line %d", fileName, line); - delete l; -@@ -159,7 +225,14 @@ public: - } - }; - -+#ifdef USE_CMDSUBMENU -+class cCommands : public cConfig<cCommand> { -+public: -+ virtual void AddConfig(cCommand *Object); -+ }; -+#else - class cCommands : public cConfig<cCommand> {}; -+#endif /* CMDSUBMENU */ - - class cSVDRPhosts : public cConfig<cSVDRPhost> { - public: -@@ -168,6 +241,9 @@ public: - - extern cCommands Commands; - extern cCommands RecordingCommands; -+#ifdef USE_TIMERCMD -+extern cCommands TimerCommands; -+#endif /* TIMERCMD */ - extern cSVDRPhosts SVDRPhosts; - - class cSetupLine : public cListObject { -@@ -193,6 +269,10 @@ private: - void StoreLanguages(const char *Name, int *Values); - bool ParseLanguages(const char *Value, int *Values); - bool Parse(const char *Name, const char *Value); -+#ifdef USE_SOURCECAPS -+ void StoreSourceCaps(const char *Name); -+ bool ParseSourceCaps(const char *Value); -+#endif /* SOURCECAPS */ - cSetupLine *Get(const char *Name, const char *Plugin = NULL); - void Store(const char *Name, const char *Value, const char *Plugin = NULL, bool AllowMultiple = false); - void Store(const char *Name, int Value, const char *Plugin = NULL); -@@ -202,6 +282,12 @@ public: - char OSDLanguage[I18N_MAX_LOCALE_LEN]; - char OSDSkin[MaxSkinName]; - char OSDTheme[MaxThemeName]; -+#ifdef USE_WAREAGLEICON -+ int WarEagleIcons; -+#endif /* WAREAGLEICON */ -+#ifdef USE_VALIDINPUT -+ int ShowValidInput; -+#endif /* VALIDINPUT */ - int PrimaryDVB; - int ShowInfoOnChSwitch; - int TimeoutRequChInfo; -@@ -242,6 +328,17 @@ public: - int VideoFormat; - int UpdateChannels; - int UseDolbyDigital; -+#ifdef USE_DOLBYINREC -+ int UseDolbyInRecordings; -+#endif /* DOLBYINREC */ -+#ifdef USE_DVBSETUP -+ int DolbyTransferFix; -+ int ChannelBlocker; -+ int ChannelBlockerMode; -+#endif /* DVBSETUP */ -+#ifdef USE_SYNCEARLY -+ int UseSyncEarlyPatch; -+#endif /* SYNCEARLY */ - int ChannelInfoPos; - int ChannelInfoTime; - int OSDLeft, OSDTop, OSDWidth, OSDHeight; -@@ -255,20 +352,119 @@ public: - int FontSmlSize; - int FontFixSize; - int MaxVideoFileSize; -+#ifdef USE_HARDLINKCUTTER -+ int MaxRecordingSize; -+#endif /* HARDLINKCUTTER */ - int SplitEditedFiles; -+#ifdef USE_HARDLINKCUTTER -+ int HardLinkCutter; -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ int DelTimeshiftRec; -+#endif /* DELTIMESHIFTREC */ - int MinEventTimeout, MinUserInactivity; - time_t NextWakeupTime; - int MultiSpeedMode; - int ShowReplayMode; -+#ifdef USE_DDEPGENTRY -+ int DoubleEpgTimeDelta; -+ int DoubleEpgAction; -+ int MixEpgAction; -+ int DisableVPS; -+#endif /* DDEPGENTRY */ - int ResumeID; -+#ifdef USE_JUMPPLAY -+ int JumpPlay; -+ int PlayJump; -+ int PauseLastMark; -+ int ReloadMarks; -+#endif /* JUMPPLAY */ -+#ifdef USE_SOURCECAPS -+ int SourceCaps[MAXDEVICES][MAXSOURCECAPS]; -+ bool SourceCapsSet; -+#endif /* SOURCECAPS */ - int CurrentChannel; - int CurrentVolume; - int CurrentDolby; - int InitialChannel; - int InitialVolume; -+#ifdef USE_VOLCTRL -+ int LRVolumeControl; -+ int LRChannelGroups; -+ int LRForwardRewind; -+#endif /* VOLCTRL */ - int EmergencyExit; -+#ifdef USE_NOEPG -+ int noEPGMode; -+#endif /* NOEPG */ -+#ifdef USE_LIRCSETTINGS -+ int LircRepeatDelay; -+ int LircRepeatFreq; -+ int LircRepeatTimeout; -+#endif /* LIRCSETTINGS */ -+#ifdef USE_LIEMIEXT -+ int ShowRecDate, ShowRecTime, ShowRecLength, ShowProgressBar, MenuCmdPosition; -+ int JumpSeconds; -+ int JumpSecondsSlow; -+ int ShowTimerStop; -+ int MainMenuTitle; -+ char CustomMainMenuTitle[MaxTitleName]; -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ int RecordingsSortMode; -+ int RecordingsSortDirsFirst; -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ int CutterAutoDelete; -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ int CutTime; -+#endif /* CUTTIME */ -+#ifdef USE_LIVEBUFFER -+ int LiveBuffer; -+ int KeepPaused; -+ int LiveBufferSize; -+ int InRAM; -+ int MemBufSize; -+ int ExtendBuffer; -+#endif /* LIVEBUFFER */ -+#ifdef USE_DVDARCHIVE -+ int DvdDisplayMode; -+ int DvdDisplayZeros; -+ int DvdTrayMode; -+ int DvdSpeedLimit; -+#endif /* DVDARCHIVE */ -+#ifdef USE_SOFTOSD -+ int UseSoftOsd; -+ int SoftOsdRate; -+ int SoftOsdFadeinSteps; -+ int SoftOsdFadeoutSteps; -+ int SoftOsdPaletteOnly; -+#endif /* SOFTOSD */ -+#ifdef USE_LNBSHARE -+ int VerboseLNBlog; -+ int CardUsesLNBnr[MAXDEVICES]; -+#endif /* LNBSHARE */ -+#ifdef USE_DVLVIDPREFER -+ int UseVidPrefer; // 0 = VDR's default, 1 = use -+ int nVidPrefer; -+ int VidPreferPrio[DVLVIDPREFER_MAX]; -+ int VidPreferSize[DVLVIDPREFER_MAX]; -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLFRIENDLYFNAMES -+ int UseFriendlyFNames; -+#endif /* DVLFRIENDLYFNAMES */ - int __EndData__; -+#ifdef USE_DVBSETUP -+ char *ChannelBlockerList; -+#endif /* DVBSETUP */ -+#ifdef USE_NOEPG -+ char *noEPGList; // pointer not to be flat-copied -+#endif /* NOEPG */ - cSetup(void); -+#if defined (USE_DVBSETUP) || defined (USE_NOEPG) -+ ~cSetup(); -+#endif /* DVBSETUP + NOEPG */ - cSetup& operator= (const cSetup &s); - bool Load(const char *FileName); - bool Save(void); -@@ -276,4 +472,8 @@ public: - - extern cSetup Setup; - -+#ifdef USE_CMDRECCMDI18N -+bool LoadCommandsI18n(cCommands & cmds, const char *FileName = NULL, bool AllowComments = false, bool MustExist = false); -+#endif /* CMDRECCMDI18N */ -+ - #endif //__CONFIG_H -diff -ruNp vdr-1.7.0/cutter.c vdr-1.7.0-extensions/cutter.c ---- vdr-1.7.0/cutter.c 2008-01-13 13:22:21.000000000 +0100 -+++ vdr-1.7.0-extensions/cutter.c 2009-04-09 20:48:48.000000000 +0200 -@@ -15,6 +15,19 @@ - - // --- cCuttingThread -------------------------------------------------------- - -+#ifdef USE_CUTTERLIMIT -+#ifndef CUTTER_MAX_BANDWIDTH -+# define CUTTER_MAX_BANDWIDTH MEGABYTE(10) // 10 MB/s -+#endif -+#ifndef CUTTER_REL_BANDWIDTH -+# define CUTTER_REL_BANDWIDTH 75 // % -+#endif -+#ifndef CUTTER_PRIORITY -+# define CUTTER_PRIORITY sched_get_priority_min(SCHED_OTHER) -+#endif -+#define CUTTER_TIMESLICE 100 // ms -+#endif /* CUTTERLIMIT */ -+ - class cCuttingThread : public cThread { - private: - const char *error; -@@ -60,6 +73,22 @@ cCuttingThread::~cCuttingThread() - - void cCuttingThread::Action(void) - { -+#ifdef USE_CUTTERLIMIT -+#ifdef USE_HARDLINKCUTTER -+ if (!Setup.HardLinkCutter) -+#endif /* HARDLINKCUTTER */ -+ { -+ sched_param tmp; -+ tmp.sched_priority = CUTTER_PRIORITY; -+ if (!pthread_setschedparam(pthread_self(), SCHED_OTHER, &tmp)) -+ printf("cCuttingThread::Action: cant set priority\n"); -+ } -+ -+ int bytes = 0; -+ int __attribute__((unused)) burst_size = CUTTER_MAX_BANDWIDTH * CUTTER_TIMESLICE / 1000; // max bytes/timeslice -+ cTimeMs __attribute__((unused)) t; -+#endif /* CUTTERLIMIT */ -+ - cMark *Mark = fromMarks.First(); - if (Mark) { - fromFile = fromFileName->Open(); -@@ -71,6 +100,9 @@ void cCuttingThread::Action(void) - Mark = fromMarks.Next(Mark); - int FileSize = 0; - int CurrentFileNumber = 0; -+#ifdef USE_HARDLINKCUTTER -+ bool SkipThisSourceFile = false; -+#endif /* HARDLINKCUTTER */ - int LastIFrame = 0; - toMarks.Add(0); - toMarks.Save(); -@@ -88,12 +120,99 @@ void cCuttingThread::Action(void) - - // Read one frame: - -+#ifndef USE_HARDLINKCUTTER - if (fromIndex->Get(Index++, &FileNumber, &FileOffset, &PictureType, &Length)) { - if (FileNumber != CurrentFileNumber) { - fromFile = fromFileName->SetOffset(FileNumber, FileOffset); - fromFile->SetReadAhead(MEGABYTE(20)); - CurrentFileNumber = FileNumber; - } -+#else -+ if (!fromIndex->Get(Index++, &FileNumber, &FileOffset, &PictureType, &Length)) { -+ error = "index"; -+ break; -+ } -+ -+ if (FileNumber != CurrentFileNumber) { -+ fromFile = fromFileName->SetOffset(FileNumber, FileOffset); -+ fromFile->SetReadAhead(MEGABYTE(20)); -+ CurrentFileNumber = FileNumber; -+ if (SkipThisSourceFile) { -+ // At end of fast forward: Always skip to next file -+ toFile = toFileName->NextFile(); -+ if (!toFile) { -+ error = "toFile 4"; -+ break; -+ } -+ FileSize = 0; -+ SkipThisSourceFile = false; -+ } -+ -+ -+ if (Setup.HardLinkCutter && FileOffset == 0) { -+ // We are at the beginning of a new source file. -+ // Do we need to copy the whole file? -+ -+ // if !Mark && LastMark, then we're past the last cut-out and continue to next I-frame -+ // if !Mark && !LastMark, then there's just a cut-in, but no cut-out -+ // if Mark, then we're between a cut-in and a cut-out -+ -+ uchar MarkFileNumber; -+ int MarkFileOffset; -+ // Get file number of next cut mark -+ if (!Mark && !LastMark -+ || Mark -+ && fromIndex->Get(Mark->position, &MarkFileNumber, &MarkFileOffset) -+ && (MarkFileNumber != CurrentFileNumber)) { -+ // The current source file will be copied completely. -+ // Start new output file unless we did that already -+ if (FileSize != 0) { -+ toFile = toFileName->NextFile(); -+ if (!toFile) { -+ error = "toFile 3"; -+ break; -+ } -+ FileSize = 0; -+ } -+ -+ // Safety check that file has zero size -+ struct stat buf; -+ if (stat(toFileName->Name(), &buf) == 0) { -+ if (buf.st_size != 0) { -+ esyslog("cCuttingThread: File %s exists and has nonzero size", toFileName->Name()); -+ error = "nonzero file exist"; -+ break; -+ } -+ } -+ else if (errno != ENOENT) { -+ esyslog("cCuttingThread: stat failed on %s", toFileName->Name()); -+ error = "stat"; -+ break; -+ } -+ -+ // Clean the existing 0-byte file -+ toFileName->Close(); -+ cString ActualToFileName(ReadLink(toFileName->Name()), true); -+ unlink(ActualToFileName); -+ unlink(toFileName->Name()); -+ -+ // Try to create a hard link -+ if (HardLinkVideoFile(fromFileName->Name(), toFileName->Name())) { -+ // Success. Skip all data transfer for this file -+ SkipThisSourceFile = true; -+ cutIn = false; -+ toFile = NULL; // was deleted by toFileName->Close() -+ } -+ else { -+ // Fallback: Re-open the file if necessary -+ toFile = toFileName->Open(); -+ } -+ } -+ } -+ } -+ -+ if (!SkipThisSourceFile) { -+#endif /* HARDLINKCUTTER */ - if (fromFile) { - int len = ReadFrame(fromFile, buffer, Length, sizeof(buffer)); - if (len < 0) { -@@ -110,6 +229,7 @@ void cCuttingThread::Action(void) - break; - } - } -+#ifndef USE_HARDLINKCUTTER - else { - // Error, unless we're past the last cut-in and there's no cut-out - if (Mark || LastMark) -@@ -117,12 +237,17 @@ void cCuttingThread::Action(void) - break; - } - -+#endif /* HARDLINKCUTTER */ - // Write one frame: - - if (PictureType == I_FRAME) { // every file shall start with an I_FRAME - if (LastMark) // edited version shall end before next I-frame - break; -+#ifndef USE_HARDLINKCUTTER - if (FileSize > MEGABYTE(Setup.MaxVideoFileSize)) { -+#else -+ if (!SkipThisSourceFile && FileSize > toFileName->MaxFileSize()) { -+#endif /* HARDLINKCUTTER */ - toFile = toFileName->NextFile(); - if (!toFile) { - error = "toFile 1"; -@@ -132,12 +257,20 @@ void cCuttingThread::Action(void) - } - LastIFrame = 0; - -+#ifndef USE_HARDLINKCUTTER - if (cutIn) { -+#else -+ if (!SkipThisSourceFile && cutIn) { -+#endif /* HARDLINKCUTTER */ - cRemux::SetBrokenLink(buffer, Length); - cutIn = false; - } - } -+#ifndef USE_HARDLINKCUTTER - if (toFile->Write(buffer, Length) < 0) { -+#else -+ if (!SkipThisSourceFile && toFile->Write(buffer, Length) < 0) { -+#endif /* HARDLINKCUTTER */ - error = "safe_write"; - break; - } -@@ -172,8 +305,44 @@ void cCuttingThread::Action(void) - } - } - else -+#ifndef USE_HARDLINKCUTTER - LastMark = true; -+#else -+ LastMark = true; // After last cut-out: Write on until next I-frame, then exit -+#endif /* HARDLINKCUTTER */ -+ } -+#ifdef USE_CUTTERLIMIT -+#ifdef USE_HARDLINKCUTTER -+ if (!Setup.HardLinkCutter) { -+#endif /* HARDLINKCUTTER */ -+ bytes += Length; -+ if (bytes >= burst_size) { -+ int elapsed = t.Elapsed(); -+ int sleep = 0; -+ -+#if CUTTER_REL_BANDWIDTH > 0 && CUTTER_REL_BANDWIDTH < 100 -+ // stay under max. relative bandwidth -+ -+ sleep = (elapsed * 100 / CUTTER_REL_BANDWIDTH) - elapsed; -+ //if (sleep<=0 && elapsed<=2) sleep = 1; -+ //if (sleep) esyslog("cutter: relative bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE); -+#endif -+ // stay under max. absolute bandwidth -+ if (elapsed < CUTTER_TIMESLICE) { -+ sleep = max(CUTTER_TIMESLICE - elapsed, sleep); -+ //if (sleep) esyslog("cutter: absolute bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE); -+ } -+ -+ if (sleep>0) -+ cCondWait::SleepMs(sleep); -+ t.Set(); -+ bytes = 0; -+ } -+#ifdef USE_HARDLINKCUTTER - } -+#endif /* HARDLINKCUTTER */ -+#endif /* CUTTERLIMIT */ -+ - } - Recordings.TouchUpdate(); - } -@@ -183,18 +352,72 @@ void cCuttingThread::Action(void) - - // --- cCutter --------------------------------------------------------------- - -+#ifdef USE_CUTTERQUEUE -+#define WAIT_BEFORE_NEXT_CUT (10*1000) // 10 seconds -+ -+class cStringListObject : public cListObject { -+ public: -+ cStringListObject(const char *s) { str = strdup(s); } -+ ~cStringListObject() { free(str); } -+ -+ const char *Value() { return str; } -+ operator const char * () { return str; } -+ -+ private: -+ char *str; -+}; -+#endif /* CUTTERQUEUE */ -+ - char *cCutter::editedVersionName = NULL; - cCuttingThread *cCutter::cuttingThread = NULL; - bool cCutter::error = false; - bool cCutter::ended = false; -+#ifdef USE_CUTTERQUEUE -+cMutex *cCutter::cutterLock = new cMutex(); -+static uint64_t /*cCutter::*/lastCuttingEndTime = 0; -+static cList<cStringListObject> /**cCutter::*/cutterQueue /*= new cList<cStringListObject>*/; -+#endif /* CUTTERQUEUE */ - - bool cCutter::Start(const char *FileName) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+ if (FileName) { -+ /* Add file to queue. -+ * If cutter is still active, next cutting will be started -+ * when vdr.c:main calls cCutter::Active and previous cutting has -+ * been stopped > 10 s before -+ */ -+ cutterQueue.Add(new cStringListObject(FileName)); -+ } -+ if (cuttingThread) -+ return true; -+ /* cut next file from queue */ -+ if (!(cutterQueue.First())) -+ return false; -+ FileName = cutterQueue.First()->Value(); -+#endif /* CUTTERQUEUE */ - if (!cuttingThread) { - error = false; - ended = false; - cRecording Recording(FileName); -+#ifdef USE_CUTTIME -+ cMarks FromMarks; -+ FromMarks.Load(FileName); -+ cMark *First=FromMarks.First(); -+ if (First) Recording.SetStartTime(Recording.start+((First->position/FRAMESPERSEC+30)/60)*60); -+#endif /* CUTTIME */ - const char *evn = Recording.PrefixFileName('%'); -+#ifdef USE_CUTTERQUEUE -+ if (!(Recordings.GetByName(FileName))) { -+ // Should _not_ remove any cutted recordings -+ // (original recording already deleted ?) -+ // so, just pop item from queue and return. -+ esyslog("can't cut non-existing recording %s", FileName); -+ cutterQueue.Del(cutterQueue.First()); -+ return true; // might be already queued recording -+ } -+#endif /* CUTTERQUEUE */ - if (evn && RemoveVideoFile(evn) && MakeDirs(evn, true)) { - // XXX this can be removed once RenameVideoFile() follows symlinks (see videodir.c) - // remove a possible deleted recording with the same name to avoid symlink mixups: -@@ -220,6 +443,9 @@ bool cCutter::Start(const char *FileName - - void cCutter::Stop(void) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+#endif /* CUTTERQUEUE */ - bool Interrupted = cuttingThread && cuttingThread->Active(); - const char *Error = cuttingThread ? cuttingThread->Error() : NULL; - delete cuttingThread; -@@ -231,11 +457,20 @@ void cCutter::Stop(void) - esyslog("ERROR: '%s' during editing process", Error); - RemoveVideoFile(editedVersionName); //XXX what if this file is currently being replayed? - Recordings.DelByName(editedVersionName); -+#ifdef USE_CUTTERQUEUE -+ cutterQueue.Del(cutterQueue.First()); -+#endif /* CUTTERQUEUE */ - } -+#ifdef USE_CUTTERQUEUE -+ lastCuttingEndTime = cTimeMs::Now(); -+#endif /* CUTTERQUEUE */ - } - - bool cCutter::Active(void) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+#endif /* CUTTERQUEUE */ - if (cuttingThread) { - if (cuttingThread->Active()) - return true; -@@ -246,12 +481,40 @@ bool cCutter::Active(void) - free(editedVersionName); - editedVersionName = NULL; - ended = true; -+#ifdef USE_CUTTERQUEUE -+ if (Setup.CutterAutoDelete) { -+ /* Remove original (if cutting was successful) */ -+ if (!error) { -+ cRecording *recording = Recordings.GetByName(*cutterQueue.First()); -+ if (!recording) -+ esyslog("ERROR: Can't found '%s' after editing process", cutterQueue.First()->Value()); -+ else { -+ if (recording->Delete()) -+ Recordings.DelByName(recording->FileName()); -+ else -+ esyslog("ERROR: Can't delete '%s' after editing process", cutterQueue.First()->Value()); -+ } -+ } -+ lastCuttingEndTime = cTimeMs::Now(); -+ } -+ cutterQueue.Del(cutterQueue.First()); -+#endif /* CUTTERQUEUE */ -+ } -+#ifdef USE_CUTTERQUEUE -+ if (!cuttingThread && cutterQueue.First()) { -+ /* start next cutting from queue*/ -+ if (cTimeMs::Now() > lastCuttingEndTime + WAIT_BEFORE_NEXT_CUT) -+ Start(NULL); - } -+#endif /* CUTTERQUEUE */ - return false; - } - - bool cCutter::Error(void) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+#endif /* CUTTERQUEUE */ - bool result = error; - error = false; - return result; -@@ -259,6 +522,9 @@ bool cCutter::Error(void) - - bool cCutter::Ended(void) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+#endif /* CUTTERQUEUE */ - bool result = ended; - ended = false; - return result; -diff -ruNp vdr-1.7.0/cutter.h vdr-1.7.0-extensions/cutter.h ---- vdr-1.7.0/cutter.h 2002-06-22 12:03:15.000000000 +0200 -+++ vdr-1.7.0-extensions/cutter.h 2009-04-09 20:48:48.000000000 +0200 -@@ -11,6 +11,9 @@ - #define __CUTTER_H - - class cCuttingThread; -+#ifdef USE_CUTTERQUEUE -+class cMutex; -+#endif /* CUTTERQUEUE */ - - class cCutter { - private: -@@ -18,6 +21,9 @@ private: - static cCuttingThread *cuttingThread; - static bool error; - static bool ended; -+#ifdef USE_CUTTERQUEUE -+ static cMutex *cutterLock; -+#endif /* CUTTERQUEUE */ - public: - static bool Start(const char *FileName); - static void Stop(void); -diff -ruNp vdr-1.7.0/device.c vdr-1.7.0-extensions/device.c ---- vdr-1.7.0/device.c 2008-04-12 16:12:14.000000000 +0200 -+++ vdr-1.7.0-extensions/device.c 2009-04-09 20:48:48.000000000 +0200 -@@ -14,11 +14,22 @@ - #include "audio.h" - #include "channels.h" - #include "i18n.h" -+#ifdef USE_LIVEBUFFER -+#include "livebuffer.h" -+#endif /* LIVEBUFFER */ - #include "player.h" - #include "receiver.h" - #include "status.h" - #include "transfer.h" - -+#ifdef USE_LNBSHARE -+#include "diseqc.h" -+#endif /* LNBSHARE */ -+ -+#ifdef USE_CHANNELSCAN -+bool scanning_on_receiving_device = false; -+#endif /* CHANNELSCAN */ -+ - // --- cLiveSubtitle --------------------------------------------------------- - - #define LIVESUBTITLEBUFSIZE KILOBYTE(100) -@@ -228,6 +239,12 @@ cDevice::cDevice(void) - - SetVideoFormat(Setup.VideoFormat); - -+#ifdef USE_LNBSHARE -+ LNBstate = -1; -+ LNBnr = Setup.CardUsesLNBnr[cardIndex]; -+ LNBsource = NULL; -+#endif /* LNBSHARE */ -+ - mute = false; - volume = Setup.CurrentVolume; - -@@ -253,8 +270,15 @@ cDevice::cDevice(void) - for (int i = 0; i < MAXRECEIVERS; i++) - receiver[i] = NULL; - -+#ifdef USE_SOURCECAPS -+ if (numDevices < MAXDEVICES) { -+ device[numDevices++] = this; -+ SetSourceCaps(cardIndex); -+ } -+#else - if (numDevices < MAXDEVICES) - device[numDevices++] = this; -+#endif /* SOURCECAPS */ - else - esyslog("ERROR: too many devices!"); - } -@@ -290,6 +314,16 @@ void cDevice::SetUseDevice(int n) - useDevice |= (1 << n); - } - -+#ifdef USE_LNBSHARE -+void cDevice::SetLNBnr(void) -+{ -+ for (int i = 0; i < numDevices; i++) { -+ device[i]->LNBnr = Setup.CardUsesLNBnr[i]; -+ isyslog("LNB-sharing: setting device %d to use LNB %d", i, device[i]->LNBnr); -+ } -+} -+#endif /* LNBSHARE */ -+ - int cDevice::NextCardIndex(int n) - { - if (n > 0) { -@@ -350,6 +384,98 @@ cDevice *cDevice::ActualDevice(void) - return d; - } - -+#ifdef USE_LNBSHARE -+cDevice *cDevice::GetBadDevice(const cChannel *Channel) -+{ -+ if (!cSource::IsSat(Channel->Source())) -+ return NULL; -+ if (Setup.DiSEqC) { -+ cDiseqc *diseqc; -+ diseqc = Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); -+ -+ for (int i = 0; i < numDevices; i++) { -+ if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBsource() != (int*) diseqc) { -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Device check for channel %d on device %d. LNB or DiSEq conflict with device %d", LNBnr, Channel->Number(), this->DeviceNumber(), i); -+ return device[i]; -+ } -+ } -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Device check for for channel %d on device %d. OK", LNBnr, Channel->Number(), this->DeviceNumber()); -+ } -+ else { -+ char requiredState; -+ -+ if (Channel->Frequency() >= Setup.LnbSLOF) -+ requiredState = 1 ; -+ else -+ requiredState = 0; -+ -+ if (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') -+ requiredState += 2; -+ -+ for (int i = 0; i < numDevices; i++) { -+ if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBconf() != requiredState) { -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Device check for channel %d, LNBstate %d on device %d, current LNBstate %d. Conflict with device %d, LNBstate %d", LNBnr, Channel->Number(), requiredState, this->DeviceNumber(), LNBstate, i, device[i]->GetLNBconf()); -+ return device[i]; -+ } -+ } -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Device check for channel %d, LNBstate %d on device %d, current LNBstate %d. No other devices affected", LNBnr, Channel->Number(), requiredState, this->DeviceNumber(), LNBstate); -+ } -+ return NULL; -+} -+ -+int cDevice::GetMaxBadPriority(const cChannel *Channel) -+{ -+ if (!cSource::IsSat(Channel->Source())) return -2; -+ bool PrimaryIsBad = false; -+ int maxBadPriority = -2; -+ if (Setup.DiSEqC) { -+ cDiseqc *diseqc; -+ diseqc = Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); -+ -+ for (int i = 0; i < numDevices; i++) { -+ if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBsource() != (int*) diseqc) { -+ if (device[i]->Receiving() && device[i]->Priority() > maxBadPriority) { -+ maxBadPriority = device[i]->Priority(); -+ } -+ if (device[i]->IsPrimaryDevice()) { -+ PrimaryIsBad = true; -+ } -+ } -+ } -+ } -+ else { -+ char requiredState; -+ if (Channel->Frequency() >= Setup.LnbSLOF) -+ requiredState = 1 ; -+ else -+ requiredState = 0; -+ -+ if (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') -+ requiredState += 2; -+ -+ for (int i = 0; i < numDevices; i++) { -+ if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBconf() != requiredState) { -+ if (device[i]->Receiving() && device[i]->Priority() > maxBadPriority) -+ maxBadPriority = device[i]->Priority(); -+ if (device[i]->IsPrimaryDevice()) -+ PrimaryIsBad = true; -+ } -+ } -+ } -+ if (PrimaryIsBad && maxBadPriority == -2) -+ maxBadPriority = -1; -+ -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Request for channel %d on device %d. MaxBadPriority is %d", LNBnr, Channel->Number(), this->DeviceNumber(), maxBadPriority); -+ -+ return maxBadPriority; -+} -+#endif /* LNBSHARE */ -+ - cDevice *cDevice::GetDevice(int Index) - { - return (0 <= Index && Index < numDevices) ? device[Index] : NULL; -@@ -399,6 +525,10 @@ cDevice *cDevice::GetDevice(const cChann - cCamSlot *s = NULL; - - uint32_t Impact = 0xFFFFFFFF; // we're looking for a device with the least impact -+#ifdef USE_LNBSHARE -+ int badPriority; -+ uint imp2; -+#endif /* LNBSHARE */ - for (int j = 0; j < NumCamSlots || !NumUsableSlots; j++) { - if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) - continue; // there is no CAM available in this slot -@@ -423,6 +553,9 @@ cDevice *cDevice::GetDevice(const cChann - imp <<= 1; imp |= LiveView ? !device[i]->IsPrimaryDevice() || ndr : 0; // prefer the primary device for live viewing if we don't need to detach existing receivers - imp <<= 1; imp |= !device[i]->Receiving() && (device[i] != cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode - imp <<= 1; imp |= device[i]->Receiving(); // avoid devices that are receiving -+#ifdef USE_LIVEBUFFER -+ imp <<= 2; imp |= cLiveBufferManager::Impact(device[i], Channel, LiveView); -+#endif /* LIVEBUFFER */ - imp <<= 2; imp |= GetClippedNumProvidedSystems(2, device[i]) - 1; // avoid cards which support multiple delivery systems - imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device - imp <<= 8; imp |= min(max(device[i]->Priority() + MAXPRIORITY, 0), 0xFF); // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) -@@ -432,7 +565,31 @@ cDevice *cDevice::GetDevice(const cChann - imp <<= 1; imp |= NumUsableSlots ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels - imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards - imp <<= 1; imp |= NumUsableSlots ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel -+#ifdef USE_LNBSHARE -+ badPriority = device[i]->GetMaxBadPriority(Channel); -+ if (badPriority >= Priority || (badPriority == -1 && Priority < Setup.PrimaryLimit)) { -+ // channel is not available for the requested prioity -+ imp = 0xFFFFFFFF; -+ } -+ else { -+ switch (badPriority) { -+ case -2: // not affected by LNB-sharing -+ imp2 = 0; -+ break; -+ case -1: // the primary device would need a channel switch -+ imp += 1 << 17; -+ imp2 = 0xFFFFFFFF | 1 << 17; -+ break; -+ default: // a device receiving with lower priority would need to be stopped -+ imp += badPriority << 8; -+ imp2 = 0xFFFFFFFF | badPriority << 8; -+ break; -+ } -+ } -+ if (imp < Impact && imp2 < Impact) { -+#else - if (imp < Impact) { -+#endif /* LNBSHARE */ - // This device has less impact than any previous one, so we take it. - Impact = imp; - d = device[i]; -@@ -473,6 +630,18 @@ void cDevice::SetCamSlot(cCamSlot *CamSl - camSlot = CamSlot; - } - -+#ifdef USE_SOURCECAPS -+void cDevice::SetSourceCaps(int Index) -+{ -+ for (int d = 0; d < numDevices; d++) { -+ if (Index < 0 || Index == device[d]->CardIndex()) { -+ for (int i = 0; i < MAXSOURCECAPS; i++) -+ device[d]->sourceCaps[i] = Setup.SourceCaps[device[d]->CardIndex()][i]; -+ } -+ } -+} -+#endif /* SOURCECAPS */ -+ - void cDevice::Shutdown(void) - { - primaryDevice = NULL; -@@ -717,7 +886,11 @@ bool cDevice::ProvidesTransponder(const - bool cDevice::ProvidesTransponderExclusively(const cChannel *Channel) const - { - for (int i = 0; i < numDevices; i++) { -+#ifdef USE_LNBSHARE -+ if (device[i] && device[i] != this && device[i]->ProvidesTransponder(Channel) && device[i]->GetLNBnr() != LNBnr) -+#else - if (device[i] && device[i] != this && device[i]->ProvidesTransponder(Channel)) -+#endif /* LNBSHARE */ - return false; - } - return true; -@@ -745,6 +918,24 @@ bool cDevice::MaySwitchTransponder(void) - - bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView) - { -+#ifdef USE_LNBSHARE -+ cDevice *tmpDevice; -+ if (this->GetMaxBadPriority(Channel) >= 0) { -+ Skins.Message(mtInfo, tr("Channel locked by LNB!")); -+ return false; -+ } -+ while ((tmpDevice = GetBadDevice(Channel)) != NULL) { -+ if (tmpDevice->IsPrimaryDevice() && LiveView) -+ tmpDevice->SwitchChannelForced(Channel, true); -+ else -+ tmpDevice->SwitchChannelForced(Channel, false); -+ } -+ return SwitchChannelForced(Channel, LiveView); -+} -+ -+bool cDevice::SwitchChannelForced(const cChannel *Channel, bool LiveView) -+{ -+#endif /* LNBSHARE */ - if (LiveView) { - isyslog("switching to channel %d", Channel->Number()); - cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer -@@ -774,7 +965,14 @@ bool cDevice::SwitchChannel(int Directio - cChannel *channel; - while ((channel = Channels.GetByNumber(n, Direction)) != NULL) { - // try only channels which are currently available -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgChannelProtected(0, channel) == false) -+#endif /* PINPLUGIN */ -+#ifdef USE_LNBSHARE -+ if (PrimaryDevice()->GetMaxBadPriority(channel) < 0 && (GetDevice(channel, 0, true))) -+#else - if (GetDevice(channel, 0, true)) -+#endif /* LNBSHARE */ - break; - n = channel->Number() + Direction; - } -@@ -795,7 +993,18 @@ bool cDevice::SwitchChannel(int Directio - - eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) - { -+#ifdef USE_PINPLUGIN -+ // I hope 'LiveView = false' indicates a channel switch for recording, -+ // I really don't know, but it works ... -+ if (LiveView && cStatus::MsgChannelProtected(this, Channel) == true) -+ return scrNotAvailable; -+#endif /* PINPLUGIN */ -+ -+#ifdef USE_LIVEBUFFER -+ if (LiveView && !(Setup.LiveBuffer && dynamic_cast<cLivePlayer *>(player) != NULL)) { -+#else - if (LiveView) { -+#endif /* LIVEBUFFER */ - StopReplay(); - DELETENULL(liveSubtitle); - DELETENULL(dvbSubtitleConverter); -@@ -805,15 +1014,51 @@ eSetChannelResult cDevice::SetChannel(co - - bool NeedsTransferMode = Device != this; - -+#ifdef USE_LIVEBUFFER -+ if (LiveView && Setup.LiveBuffer) -+ NeedsTransferMode = true; -+#endif /* LIVEBUFFER */ -+ - eSetChannelResult Result = scrOk; - -+#ifdef USE_LNBSHARE -+ char requiredState; -+ if (Channel->Frequency() >= Setup.LnbSLOF) -+ requiredState = 1; -+ else -+ requiredState = 0; -+ -+ if (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') -+ requiredState += 2; -+ -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Switching device %d to channel %d", LNBnr, this->DeviceNumber(), Channel->Number()); -+#endif /* LNBSHARE */ -+ - // If this DVB card can't receive this channel, let's see if we can - // use the card that actually can receive it and transfer data from there: - - if (NeedsTransferMode) { - if (Device && CanReplay()) { -+#ifdef USE_LNBSHARE -+ if (Device->GetLNBnr() == LNBnr) { -+ if (LNBstate != requiredState || (Setup.DiSEqC && LNBsource != (int*) Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization())) ) { -+ if (IsPrimaryDevice()) -+ SetChannelDevice(Channel, true); -+ else -+ SetChannelDevice(Channel, false); -+ LNBstate = requiredState; -+ LNBsource = (int*) Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); -+ } -+ } -+#endif /* LNBSHARE */ - cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel - if (Device->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()! -+#ifdef USE_LIVEBUFFER -+ if (Setup.LiveBuffer) -+ cLiveBufferManager::ChannelSwitch(Device,Channel); -+ else -+#endif /* LIVEBUFFER */ - cControl::Launch(new cTransferControl(Device, Channel->GetChannelID(), Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids())); - else - Result = scrNoTransfer; -@@ -829,6 +1074,10 @@ eSetChannelResult cDevice::SetChannel(co - sectionHandler->SetStatus(false); - sectionHandler->SetChannel(NULL); - } -+#ifdef USE_LNBSHARE -+ LNBstate = requiredState; -+ LNBsource = (int*) Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); -+#endif /* LNBSHARE */ - // Tell the camSlot about the channel switch and add all PIDs of this - // channel to it, for possible later decryption: - if (camSlot) -@@ -861,7 +1110,11 @@ eSetChannelResult cDevice::SetChannel(co - } - for (int i = 0; i < MAXSPIDS; i++) - SetAvailableTrack(ttSubtitle, i, Channel->Spid(i), Channel->Slang(i)); -+#ifdef USE_SYNCEARLY -+ if ((Setup.UseSyncEarlyPatch && (!NeedsTransferMode || GetCurrentAudioTrack() == ttNone)) || (!Setup.UseSyncEarlyPatch && !NeedsTransferMode)) -+#else - if (!NeedsTransferMode) -+#endif /* SYNCEARLY */ - EnsureAudioTrack(true); - EnsureSubtitleTrack(); - } -@@ -1121,7 +1374,12 @@ void cDevice::EnsureSubtitleTrack(void) - int LanguagePreference = INT_MAX; // higher than the maximum possible value - for (int i = ttSubtitleFirst; i <= ttSubtitleLast; i++) { - const tTrackId *TrackId = GetTrack(eTrackType(i)); -+#ifdef USE_LIEMIEXT -+ if (TrackId && TrackId->id && (I18nIsPreferredLanguage(Setup.SubtitleLanguages, TrackId->language, LanguagePreference) || -+ ((i == ttSubtitleFirst + 8) && !(*TrackId->language) && (LanguagePreference == INT_MAX)))) -+#else - if (TrackId && TrackId->id && I18nIsPreferredLanguage(Setup.SubtitleLanguages, TrackId->language, LanguagePreference)) -+#endif /* LIEMIEXT */ - PreferredTrack = eTrackType(i); - } - // Make sure we're set to an available subtitle track: -@@ -1185,7 +1443,11 @@ bool cDevice::Replaying(void) const - - bool cDevice::Transferring(void) const - { -+#ifdef USE_LIVEBUFFER -+ return ActualDevice() != PrimaryDevice() || dynamic_cast<cLivePlayer *>(player) != NULL; // TODO -+#else - return ActualDevice() != PrimaryDevice(); -+#endif /* LIVEBUFFER */ - } - - bool cDevice::AttachPlayer(cPlayer *Player) -@@ -1310,7 +1572,11 @@ pre_1_3_19_PrivateStreamDetected: - w = PlaySubtitle(Start, d); - break; - case 0x80: // AC3 & DTS -+#ifdef USE_DOLBYINREC -+ if (Setup.UseDolbyInRecordings) { -+#else - if (Setup.UseDolbyDigital) { -+#endif /* DOLBYINREC */ - SetAvailableTrack(ttDolby, SubStreamIndex, SubStreamId); - if ((!VideoOnly || HasIBPTrickSpeed()) && SubStreamId == availableTracks[currentAudioTrack].id) { - w = PlayAudio(Start, d, SubStreamId); -diff -ruNp vdr-1.7.0/device.h vdr-1.7.0-extensions/device.h ---- vdr-1.7.0/device.h 2008-04-12 13:11:23.000000000 +0200 -+++ vdr-1.7.0-extensions/device.h 2009-04-09 20:48:48.000000000 +0200 -@@ -23,8 +23,13 @@ - #include "spu.h" - #include "thread.h" - #include "tools.h" -+#ifdef USE_ROTOR -+#include <linux/dvb/frontend.h> -+#endif /* ROTOR */ - -+#ifndef USE_SOURCECAPS - #define MAXDEVICES 16 // the maximum number of devices in the system -+#endif /* SOURCECAPS */ - #define MAXPIDHANDLES 64 // the maximum number of different PIDs per device - #define MAXRECEIVERS 16 // the maximum number of receivers per device - #define MAXVOLUME 255 -@@ -34,6 +39,10 @@ - #define TS_SYNC_BYTE 0x47 - #define PID_MASK_HI 0x1F - -+#ifdef USE_CHANNELSCAN -+extern bool scanning_on_receiving_device; -+#endif /* CHANNELSCAN */ -+ - enum eSetChannelResult { scrOk, scrNotAvailable, scrNoTransfer, scrFailed }; - - enum ePlayMode { pmNone, // audio/video from decoder -@@ -146,6 +155,35 @@ public: - ///< this device/CAM combination will be skipped in the next call to - ///< GetDevice(). - ///< See also ProvidesChannel(). -+#ifdef USE_SOURCECAPS -+ static void SetSourceCaps(int Index = -1); -+ ///< Sets the SourceCaps of the given device according to the Setup data. -+#endif /* SOURCECAPS */ -+#ifdef USE_LNBSHARE -+private: -+ char LNBstate; // Current frequency band and polarization of the DVB-tuner -+// cDiseqc *LNBsource; // can not #include "diseqc.h". A workaround follows: -+ int *LNBsource; // [DiSEqC] DiSEqC-Source -+ int LNBnr; // Number of LNB used -+public: -+ char GetLNBconf(void) { return LNBstate; } -+ int *GetLNBsource(void) { return LNBsource; } -+ int GetLNBnr(void) { return LNBnr; } -+ static void SetLNBnr(void); -+ cDevice *GetBadDevice(const cChannel *Channel); -+ ///< Returns NULL if there is no device which uses the same LNB or if -+ ///< all of those devices are tuned to the same frequency band and -+ ///< polarization as of the requested channel. -+ ///< Otherwise returns the first device found. -+ int GetMaxBadPriority(const cChannel *Channel); -+ ///< Returns the highest priority of all receiving devices which use -+ ///< the same LNB and are tuned to a different frequency band or -+ ///< polarization as of the requested channel. -+ ///< Returns -1 if there are no such devices, but the primary device -+ ///< would be affected by switching to the requested channel. -+ ///< Returns -2 if there are no such devices and the primary device -+ ///< would not be affected by switching to the requested channel. -+#endif /* LNBSHARE */ - static void SetAvoidDevice(cDevice *Device) { avoidDevice = Device; } - ///< Sets the given Device to be temporarily avoided in the next call to - ///< GetDevice(const cChannel, int, bool). -@@ -156,6 +194,9 @@ private: - static int nextCardIndex; - int cardIndex; - protected: -+#ifdef USE_SOURCECAPS -+ int sourceCaps[MAXSOURCECAPS]; -+#endif /* SOURCECAPS */ - cDevice(void); - virtual ~cDevice(); - virtual bool Ready(void); -@@ -243,17 +284,30 @@ public: - bool SwitchChannel(const cChannel *Channel, bool LiveView); - ///< Switches the device to the given Channel, initiating transfer mode - ///< if necessary. -+ -+#ifdef USE_LNBSHARE -+ bool SwitchChannelForced(const cChannel *Channel, bool LiveView); -+ ///< Switches the device to the given channel, initiating transfer mode -+ ///< if necessary. Forces the switch without taking care of the LNB configuration. -+#endif /* LNBSHARE */ -+ - static bool SwitchChannel(int Direction); - ///< Switches the primary device to the next available channel in the given - ///< Direction (only the sign of Direction is evaluated, positive values - ///< switch to higher channel numbers). - private: -+#ifndef USE_YAEPG - eSetChannelResult SetChannel(const cChannel *Channel, bool LiveView); - ///< Sets the device to the given channel (general setup). -+#endif /* YAEPG */ - protected: - virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); - ///< Sets the device to the given channel (actual physical setup). - public: -+#ifdef USE_YAEPG -+ eSetChannelResult SetChannel(const cChannel *Channel, bool LiveView); -+ ///< Sets the device to the given channel (general setup). -+#endif /* YAEPG */ - static int CurrentChannel(void) { return primaryDevice ? currentChannel : 0; } - ///< Returns the number of the current channel on the primary device. - static void SetCurrentChannel(const cChannel *Channel) { currentChannel = Channel ? Channel->Number() : 0; } -@@ -271,6 +325,9 @@ public: - virtual bool HasProgramme(void); - ///< Returns true if the device is currently showing any programme to - ///< the user, either through replaying or live. -+#ifdef USE_ROTOR -+ virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd) { return false; } -+#endif /* ROTOR */ - - // PID handle facilities - -diff -ruNp vdr-1.7.0/dvbdevice.c vdr-1.7.0-extensions/dvbdevice.c ---- vdr-1.7.0/dvbdevice.c 2008-04-13 16:15:35.000000000 +0200 -+++ vdr-1.7.0-extensions/dvbdevice.c 2009-04-09 20:48:48.000000000 +0200 -@@ -71,6 +71,9 @@ static int DvbOpen(const char *Name, int - class cDvbTuner : public cThread { - private: - enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked }; -+#ifdef USE_ROTOR -+ bool SendDiseqc; -+#endif /* ROTOR */ - int fd_frontend; - int cardIndex; - int tuneTimeout; -@@ -83,6 +86,9 @@ private: - cMutex mutex; - cCondVar locked; - cCondVar newSet; -+#ifdef USE_ROTOR -+ dvb_diseqc_master_cmd diseqc_cmd; -+#endif /* ROTOR */ - bool GetFrontendStatus(fe_status_t &Status, int TimeoutMs = 0); - bool SetFrontend(void); - virtual void Action(void); -@@ -91,12 +97,18 @@ public: - virtual ~cDvbTuner(); - bool IsTunedTo(const cChannel *Channel) const; - void Set(const cChannel *Channel, bool Tune); -+#ifdef USE_ROTOR -+ bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd); -+#endif /* ROTOR */ - bool Locked(int TimeoutMs = 0); - }; - - cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType) - { - fd_frontend = Fd_Frontend; -+#ifdef USE_ROTOR -+ SendDiseqc = false; -+#endif /* ROTOR */ - cardIndex = CardIndex; - frontendType = FrontendType; - tuneTimeout = 0; -@@ -164,6 +176,19 @@ bool cDvbTuner::Locked(int TimeoutMs) - return tunerStatus >= tsLocked; - } - -+#ifdef USE_ROTOR -+bool cDvbTuner::SendDiseqcCmd(dvb_diseqc_master_cmd cmd) -+{ -+ cMutexLock MutexLock(&mutex); -+ if ((!DVBFE_DELSYS_DVBS & !DVBFE_DELSYS_DVBS2) || SendDiseqc) -+ return false; -+ diseqc_cmd = cmd; -+ SendDiseqc = true; -+ newSet.Broadcast(); -+ return true; -+} -+#endif /* ROTOR */ -+ - bool cDvbTuner::GetFrontendStatus(fe_status_t &Status, int TimeoutMs) - { - if (TimeoutMs) { -@@ -225,6 +250,9 @@ bool cDvbTuner::SetFrontend(void) - } - } - diseqcCommands = diseqc->Commands(); -+#ifdef USE_DVBSETUP -+ isyslog("Sent DISEQC command: %s", diseqcCommands); -+#endif /* DVBSETUP */ - } - frequency -= diseqc->Lof(); - } -@@ -286,6 +314,22 @@ bool cDvbTuner::SetFrontend(void) - feinfo.delivery = Frontend.delivery; - CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system - } -+#ifdef USE_ATSC -+ else if (frontendType & DVBFE_DELSYS_ATSC) { -+ // Frequency and symbol rate: -+ -+ Frontend.frequency = FrequencyToHz(channel.Frequency()); -+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); -+ Frontend.delsys.atsc.modulation = dvbfe_modulation(channel.Modulation()); -+ -+ tuneTimeout = DVBC_TUNE_TIMEOUT; -+ lockTimeout = DVBC_LOCK_TIMEOUT; -+ -+ dvbfe_info feinfo; -+ feinfo.delivery = Frontend.delivery; -+ CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system -+ } -+#endif /* ATSC */ - else if (frontendType & DVBFE_DELSYS_DVBT) { - Frontend.delivery = DVBFE_DELSYS_DVBT; - Frontend.frequency = FrequencyToHz(channel.Frequency()); -@@ -328,6 +372,12 @@ void cDvbTuner::Action(void) - if (GetFrontendStatus(NewStatus, 10)) - Status = NewStatus; - cMutexLock MutexLock(&mutex); -+#ifdef USE_ROTOR -+ if (SendDiseqc) { -+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &diseqc_cmd)); -+ SendDiseqc = false; -+ } -+#endif /* ROTOR */ - switch (tunerStatus) { - case tsIdle: - break; -@@ -463,6 +513,10 @@ cDvbDevice::cDvbDevice(int n) - if (ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0) { - const char **DeliverySystem = DeliverySystems; - cString ds; -+#ifdef USE_DVBSETUP -+ if (Setup.ChannelBlockerMode == 4) -+ frontendType = n == Setup.PrimaryDVB - 1 ? DVBFE_DELSYS_DUMMY : frontendType; -+#endif /* DVBSETUP */ - for (int i = 0; i < 32; i++) { - if (frontendType & (1u << i)) { - numProvidedSystems++; -@@ -694,6 +748,13 @@ eVideoSystem cDvbDevice::GetVideoSystem( - - bool cDvbDevice::SetAudioBypass(bool On) - { -+#ifdef USE_DVBSETUP -+ if (Setup.DolbyTransferFix && On) { -+ cChannel *c=Channels.GetByNumber(cDevice::CurrentChannel()); -+ if (c->Ca(0) != 0) -+ return false; -+ } -+#endif /* DVBSETUP */ - if (setTransferModeForDolbyDigital != 1) - return false; - return ioctl(fd_audio, AUDIO_SET_BYPASS_MODE, On) == 0; -@@ -799,14 +860,43 @@ void cDvbDevice::TurnOffLiveMode(bool Li - bool cDvbDevice::ProvidesSource(int Source) const - { - int type = Source & cSource::st_Mask; -+#ifdef USE_SOURCECAPS -+ if (Setup.SourceCapsSet && type == cSource::stSat && (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2))) { -+ for (int i = 0; i < MAXSOURCECAPS; i++) -+ if (sourceCaps[i] == Source) -+ return true; -+ return false; -+ } -+ else -+#endif /* SOURCECAPS */ - return type == cSource::stNone - || type == cSource::stCable && (frontendType & DVBFE_DELSYS_DVBC) -+#ifdef USE_ATSC -+ || type == cSource::stCable && (frontendType & DVBFE_DELSYS_ATSC) -+ || type == cSource::stTerr && (frontendType & DVBFE_DELSYS_ATSC) -+#endif /* ATSC */ - || type == cSource::stSat && (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) - || type == cSource::stTerr && (frontendType & DVBFE_DELSYS_DVBT); - } - - bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const - { -+#ifdef USE_DVBSETUP -+ if (Setup.ChannelBlocker != 0) { -+ if ((Setup.ChannelBlockerMode == 0) || -+ (Setup.ChannelBlockerMode == 1 && HasDecoder()) || -+ (Setup.ChannelBlockerMode == 2 && IsPrimaryDevice()) || -+ (Setup.ChannelBlockerMode == 3 && IsPrimaryDevice() && HasDecoder())) { -+ if ((Setup.ChannelBlocker == 1 && cSource::IsCable(Channel->Source()) && Channel->Modulation() == QAM_256) || -+ (Setup.ChannelBlocker == 2 && cSource::IsCable(Channel->Source())) || -+ (Setup.ChannelBlocker == 3 && cSource::IsSat(Channel->Source())) || -+ (Setup.ChannelBlocker == 4 && strstr(::Setup.ChannelBlockerList, Channel->GetChannelID().ToString()) != NULL) || // blacklist -+ (Setup.ChannelBlocker == 5 && strstr(::Setup.ChannelBlockerList, Channel->GetChannelID().ToString()) == NULL) || // whitelist -+ (Setup.ChannelBlocker == 6)) -+ return false; -+ } -+ } -+#endif /* DVBSETUP */ - if (!ProvidesSource(Channel->Source())) - return false; // doesn't provide source - if (!cSource::IsSat(Channel->Source())) -@@ -818,10 +908,31 @@ bool cDvbDevice::ProvidesTransponder(con - - bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const - { -+#ifdef USE_DVBSETUP -+ if (Setup.ChannelBlocker != 0) { -+ if ((Setup.ChannelBlockerMode == 0) || -+ (Setup.ChannelBlockerMode == 1 && HasDecoder()) || -+ (Setup.ChannelBlockerMode == 2 && IsPrimaryDevice()) || -+ (Setup.ChannelBlockerMode == 3 && IsPrimaryDevice() && HasDecoder())) { -+ if ((Setup.ChannelBlocker == 1 && cSource::IsCable(Channel->Source()) && Channel->Modulation() == QAM_256) || -+ (Setup.ChannelBlocker == 2 && cSource::IsCable(Channel->Source())) || -+ (Setup.ChannelBlocker == 3 && cSource::IsSat(Channel->Source())) || -+ (Setup.ChannelBlocker == 4 && strstr(::Setup.ChannelBlockerList, Channel->GetChannelID().ToString()) != NULL) || // blacklist -+ (Setup.ChannelBlocker == 5 && strstr(::Setup.ChannelBlockerList, Channel->GetChannelID().ToString()) == NULL) || // whitelist -+ (Setup.ChannelBlocker == 6)) -+ return false; -+ } -+ } -+#endif /* DVBSETUP */ - bool result = false; - bool hasPriority = Priority < 0 || Priority > this->Priority(); - bool needsDetachReceivers = false; - -+#ifdef USE_ANALOGTV -+ if ((Channel->Ca(0) == 0xA0) || (Channel->Ca(0) == 0xA1) || (Channel->Ca(0) == 0xA2)) -+ return false; -+#endif /* ANALOGTV */ -+ - if (ProvidesTransponder(Channel)) { - result = hasPriority; - if (Priority >= 0 && Receiving(true)) { -@@ -882,7 +993,11 @@ bool cDvbDevice::SetChannelDevice(const - || pidHandlesVideo // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER - ); - -+#ifdef USE_LIVEBUFFER -+ bool StartTransferMode = IsPrimaryDevice() && !DoTune && !Setup.LiveBuffer -+#else - bool StartTransferMode = IsPrimaryDevice() && !DoTune -+#endif /* LIVEBUFFER */ - && (LiveView && HasPid(vpid ? vpid : apid) && (!pidHandlesVideo || (!pidHandlesAudio && (dpid ? pidHandles[ptAudio].pid != dpid : true)))// the PID is already set as DMX_PES_OTHER - || !LiveView && (pidHandlesVideo || pidHandlesAudio) // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER - ); -@@ -938,6 +1053,13 @@ bool cDvbDevice::HasLock(int TimeoutMs) - return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false; - } - -+#ifdef USE_ROTOR -+bool cDvbDevice::SendDiseqcCmd(dvb_diseqc_master_cmd cmd) -+{ -+ return dvbTuner->SendDiseqcCmd(cmd); -+} -+#endif /* ROTOR */ -+ - int cDvbDevice::GetAudioChannelDevice(void) - { - if (HasDecoder()) { -diff -ruNp vdr-1.7.0/dvbdevice.h vdr-1.7.0-extensions/dvbdevice.h ---- vdr-1.7.0/dvbdevice.h 2008-04-12 13:20:48.000000000 +0200 -+++ vdr-1.7.0-extensions/dvbdevice.h 2009-04-09 20:48:48.000000000 +0200 -@@ -73,6 +73,9 @@ protected: - virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); - public: - virtual bool HasLock(int TimeoutMs = 0); -+#ifdef USE_ROTOR -+ virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd); -+#endif /* ROTOR */ - - // PID handle facilities - -diff -ruNp vdr-1.7.0/dvbosd.c vdr-1.7.0-extensions/dvbosd.c ---- vdr-1.7.0/dvbosd.c 2007-09-16 10:55:54.000000000 +0200 -+++ vdr-1.7.0-extensions/dvbosd.c 2009-04-09 20:48:48.000000000 +0200 -@@ -20,12 +20,26 @@ - #define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 - #define MAXOSDMEMORY 92000 // number of bytes available to the OSD (for unmodified DVB cards) - -+#ifdef USE_SOFTOSD -+ #define SOFTOSD_MAXSIZE (720*576) -+ #define SOFTOSD_MINSIZE (720*64) -+#endif -+ - class cDvbOsd : public cOsd { - private: - int osdDev; - int osdMem; - bool shown; - void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL); -+#ifdef USE_SOFTOSD -+ int GetOsdSize() { -+ int OsdSize = 0; -+ cBitmap *Bitmap; -+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) -+ OsdSize += Bitmap->Width() * Bitmap->Height(); -+ return OsdSize; -+ } -+#endif - protected: - virtual void SetActive(bool On); - public: -@@ -76,6 +90,44 @@ void cDvbOsd::SetActive(bool On) - } - else if (shown) { - cBitmap *Bitmap; -+#ifdef USE_SOFTOSD -+ if (Setup.UseSoftOsd) { -+ if (SOFTOSD_MAXSIZE > GetOsdSize() && SOFTOSD_MINSIZE < GetOsdSize()) { -+ for (int fade = Setup.SoftOsdFadeoutSteps - 1; fade > 0; fade--) { -+ int64_t flush_start = cTimeMs::Now(); -+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { -+ Cmd(OSD_SetWindow, 0, i + 1); -+ int NumColors; -+ const tColor *Colors = Bitmap->Colors(NumColors); -+ if (Colors) { -+ tColor colors[NumColors]; -+ for (int i = 0; i < NumColors; i++) { -+ // convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way): -+ int alpha = (Colors[i] >> 24) & 0x000000FF; -+ alpha = (alpha * fade) / Setup.SoftOsdFadeoutSteps; -+ colors[i] = (alpha << 24) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); -+ } -+ Colors = colors; -+ Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors); -+ if (!Setup.SoftOsdPaletteOnly) { -+ //Cmd(OSD_SetBlock, Bitmap->Width(), 0, 0, Bitmap->Width() - 1, Bitmap->Height() - 1, Bitmap->Data(0, 0)); -+ Cmd(OSD_SetBlock, Bitmap->Width(), 0, 0, 0, 0, Bitmap->Data(0, 0)); -+ } -+ } -+ } -+ int flush_time = cTimeMs::Now() - flush_start; -+ dsyslog("SOFTOSD: FadeOut Step %d from %d FlushTime = %d ms", -+ Setup.SoftOsdFadeoutSteps - fade, Setup.SoftOsdFadeoutSteps - 1, flush_time); -+ int wait_time = 1000 / Setup.SoftOsdRate; -+ while (flush_time > wait_time && fade > 2) { -+ fade--; -+ flush_time -= wait_time; -+ } -+ cCondWait::SleepMs(wait_time-flush_time); -+ } -+ } -+ } -+#endif /* SOFTOSD */ - for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { - Cmd(OSD_SetWindow, 0, i + 1); - Cmd(OSD_Close); -@@ -83,6 +135,12 @@ void cDvbOsd::SetActive(bool On) - shown = false; - } - } -+#ifdef USE_YAEPG -+ if (vidWin.bpp != 0) { -+ Cmd(OSD_SetWindow, 0, 5); -+ Cmd(OSD_Close); -+ } -+#endif /* YAEPG */ - } - - eOsdError cDvbOsd::CanHandleAreas(const tArea *Areas, int NumAreas) -@@ -182,6 +240,12 @@ void cDvbOsd::Flush(void) - for (int i = 0; i < NumColors; i++) { - // convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way): - colors[i] = (Colors[i] & 0xFF000000) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); -+#ifdef USE_SOFTOSD -+ if (Setup.UseSoftOsd && !shown) { -+ if (SOFTOSD_MAXSIZE > GetOsdSize() && SOFTOSD_MINSIZE < GetOsdSize()) -+ colors[i] = 0; -+ } -+#endif /* SOFTOSD */ - } - Colors = colors; - //TODO end of stuff that should be fixed in the driver -@@ -198,6 +262,52 @@ void cDvbOsd::Flush(void) - Cmd(OSD_SetWindow, 0, i + 1); - Cmd(OSD_MoveWindow, 0, Left() + Bitmap->X0(), Top() + Bitmap->Y0()); - } -+#ifdef USE_YAEPG -+ if (vidWin.bpp != 0) { -+ Cmd(OSD_SetWindow, 0, 5); -+ Cmd(OSD_OpenRaw, vidWin.bpp, vidWin.x1, vidWin.y1, -+ vidWin.x2, vidWin.y2, (void *)0); -+ } -+#endif /* YAEPG */ -+#ifdef USE_SOFTOSD -+ if (Setup.UseSoftOsd) { -+ if (SOFTOSD_MAXSIZE > GetOsdSize() && SOFTOSD_MINSIZE < GetOsdSize()) { -+ for (int fade = 1; fade <= Setup.SoftOsdFadeinSteps; fade++) { -+ int64_t flush_start = cTimeMs::Now(); -+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { -+ Cmd(OSD_SetWindow, 0, i + 1); -+ int NumColors; -+ const tColor *Colors = Bitmap->Colors(NumColors); -+ if (Colors) { -+ tColor colors[NumColors]; -+ for (int i = 0; i < NumColors; i++) { -+ // convert AARRGGBB to AABBGGRR: -+ int alpha = (Colors[i]>>24) & 0x000000FF; -+ alpha = (alpha * fade) / Setup.SoftOsdFadeinSteps; -+ colors[i] = (alpha << 24) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); -+ } -+ Colors = colors; -+ Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors); -+ if (!Setup.SoftOsdPaletteOnly) { -+ //Cmd(OSD_SetBlock, Bitmap->Width(), 0, 0, Bitmap->Width() - 1, Bitmap->Height() - 1, Bitmap->Data(0, 0)); -+ Cmd(OSD_SetBlock, Bitmap->Width(), 0, 0, 0, 0, Bitmap->Data(0, 0)); -+ } -+ } -+ } -+ int flush_time = cTimeMs::Now() - flush_start; -+ dsyslog("SOFTOSD: FadeIn Step %d from %d FlushTime = %d ms", fade, Setup.SoftOsdFadeinSteps, flush_time); -+ int wait_time = 1000 / Setup.SoftOsdRate; -+ while (flush_time > wait_time && fade < Setup.SoftOsdFadeinSteps - 1) { -+ fade++; -+ flush_time -= wait_time; -+ } -+ if (fade == Setup.SoftOsdFadeinSteps) /* last step, don't wait */ -+ break; -+ cCondWait::SleepMs(wait_time - flush_time); -+ } -+ } -+ } -+#endif /* SOFTOSD */ - shown = true; - } - } -diff -ruNp vdr-1.7.0/dvbplayer.c vdr-1.7.0-extensions/dvbplayer.c ---- vdr-1.7.0/dvbplayer.c 2008-02-09 16:10:54.000000000 +0100 -+++ vdr-1.7.0-extensions/dvbplayer.c 2009-04-09 20:48:48.000000000 +0200 -@@ -14,6 +14,9 @@ - #include "ringbuffer.h" - #include "thread.h" - #include "tools.h" -+#ifdef USE_TTXTSUBS -+#include "vdrttxtsubshooks.h" -+#endif /* TTXTSUBS */ - - // --- cBackTrace ------------------------------------------------------------ - -@@ -193,6 +196,9 @@ private: - cNonBlockingFileReader *nonBlockingFileReader; - cRingBufferFrame *ringBuffer; - cBackTrace *backTrace; -+#ifdef USE_JUMPPLAY -+ cMarksReload marks; -+#endif /* JUMPPLAY */ - cFileName *fileName; - cIndexFile *index; - cUnbufferedFile *replayFile; -@@ -234,7 +240,11 @@ public: - int cDvbPlayer::Speeds[] = { 0, -2, -4, -8, 1, 2, 4, 12, 0 }; - - cDvbPlayer::cDvbPlayer(const char *FileName) -+#ifdef USE_JUMPPLAY -+:cThread("dvbplayer"), marks(FileName) -+#else - :cThread("dvbplayer") -+#endif /* JUMPPLAY */ - { - nonBlockingFileReader = NULL; - ringBuffer = NULL; -@@ -312,6 +322,35 @@ void cDvbPlayer::Empty(void) - firstPacket = true; - } - -+ -+#ifdef USE_TTXTSUBS -+static void StripExtendedPackets(uchar *b, int Length) -+{ -+ for (int i = 0; i < Length - 6; i++) { -+ if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) { -+ uchar c = b[i + 3]; -+ int l = b[i + 4] * 256 + b[i + 5] + 6; -+ switch (c) { -+ case 0xBD: // dolby -+ // EBU Teletext data, ETSI EN 300 472 -+ if (b[i + 8] == 0x24 && b[i + 45] >= 0x10 && b[i + 45] < 0x20) { -+ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData(&b[i], l); -+ // continue with deleting the data - otherwise it disturbs DVB replay -+ int n = l; -+ for (int j = i; j < Length && n--; j++) -+ b[j] = 0x00; -+ } -+ break; -+ default: -+ break; -+ } -+ if (l) -+ i += l - 1; // the loop increments, too! -+ } -+ } -+} -+#endif /* TTXTSUBS */ -+ - bool cDvbPlayer::NextFile(uchar FileNumber, int FileOffset) - { - if (FileNumber > 0) -@@ -341,6 +380,11 @@ bool cDvbPlayer::Save(void) - if (index) { - int Index = writeIndex; - if (Index >= 0) { -+#ifdef USE_JUMPPLAY -+ // set resume position to 0 if replay stops at the first mark -+ if (Setup.PlayJump && marks.First() && abs(Index - marks.First()->position) <= RESUMEBACKUP) -+ Index = 0; -+#endif /* JUMPPLAY */ - Index -= RESUMEBACKUP; - if (Index > 0) - Index = index->GetNextIFrame(Index, false); -@@ -363,16 +407,156 @@ void cDvbPlayer::Activate(bool On) - Cancel(9); - } - -+#ifdef USE_DVBPLAYER -+// --- BEGIN fix for I frames ------------------------------------------- -+// -+// Prior to the introduction of cVideoRepacker, VDR didn't start a new -+// PES packet when a new frame started. So, it was likely that the tail -+// of an I frame was at the beginning of the packet which started the -+// following B frame. Due to the organisation of VDR's index file, VDR -+// typically didn't read the tail of the I frame and therefore caused -+// softdevice plugins to not render such a frame as it was incomplete, -+// e. g. when moving cutting marks. -+// -+// The following code tries to fix incomplete I frames for recordings -+// made prior to the introdcution of cVideoRepacker, to be able to -+// edit cutting marks for example with softdevice plugins like vdr-xine. -+// -+ -+static uchar *findStartCode(uchar *Data, int Length, int &PesPayloadOffset) -+{ -+ uchar *limit = Data + Length; -+ if (AnalyzePesHeader(Data, Length, PesPayloadOffset) <= phInvalid) -+ return 0; // neither MPEG1 nor MPEG2 -+ -+ Data += PesPayloadOffset + 3; // move to video payload and skip 00 00 01 -+ while (Data < limit) { -+ // possible start codes that appear before/after picture data -+ // 00 00 01 B3: sequence header code -+ // 00 00 01 B8: group start code -+ // 00 00 01 00: picture start code -+ // 00 00 01 B7: sequence end code -+ if (0x01 == Data[-1] && (0xB3 == Data[0] || 0xB8 == Data[0] || 0x00 == Data[0] || 0xB7 == Data[0]) && 0x00 == Data[-2] && 0x00 == Data[-3]) -+ return Data - 3; -+ Data++; -+ } -+ -+ return 0; -+} -+ -+static void fixIFrameHead(uchar *Data, int Length) -+{ -+ int pesPayloadOffset = 0; -+ uchar *p = findStartCode(Data, Length, pesPayloadOffset); -+ if (!p) { -+ esyslog("fixIframeHead: start code not found!\n"); -+ return; -+ } -+ -+ Data += pesPayloadOffset; // move to video payload -+ if (Data < p) -+ memset(Data, 0, p - Data); // zero preceeding bytes -+} -+ -+static int fixIFrameTail(uchar *Data, int Length) -+{ -+ int pesPayloadOffset = 0; -+ uchar *p = findStartCode(Data, Length, pesPayloadOffset); -+ if (!p) { -+ esyslog("fixIframeTail: start code not found!\n"); -+ return Length; -+ } -+ -+ // is this PES packet required? -+ uchar *videoPayload = Data + pesPayloadOffset; -+ if (videoPayload >= p) -+ return 0; // no -+ -+ // adjust PES length -+ int lenPES = (p - Data); -+ Data[4] = (lenPES - 6) >> 8; -+ Data[5] = (lenPES - 6) & 0xFF; -+ -+ return lenPES; -+} -+ -+#define IPACKS 2048 // originally defined in remux.c -+ -+static void fixIFrame(uchar *Data, int &Length, const int OriginalLength) -+{ -+ int done = 0; -+ -+ while (done < Length) { -+ if (0x00 != Data[0] || 0x00 != Data[1] || 0x01 != Data[2]) { -+ esyslog("fixIFrame: PES start code not found at offset %d (data length: %d, original length: %d)!", done, Length, OriginalLength); -+ if (Length > OriginalLength) // roll back additional data -+ Length = OriginalLength; -+ return; -+ } -+ -+ int lenPES = 6 + Data[4] * 256 + Data[5]; -+ if (0xBA == Data[3]) { // pack header has fixed length -+ if (0x00 == (0xC0 & Data[4])) -+ lenPES = 12; // MPEG1 -+ else -+ lenPES = 14 + (Data[13] & 0x07); // MPEG2 -+ } -+ else if (0xB9 == Data[3]) // stream end has fixed length -+ lenPES = 4; -+ else if (0xE0 == (0xF0 & Data[3])) { // video packet -+ int todo = Length - done; -+ int bite = (lenPES < todo) ? lenPES : todo; -+ if (0 == done) // first packet -+ fixIFrameHead(Data, bite); -+ else if (done >= OriginalLength) { // last packet -+ Length = done + fixIFrameTail(Data, bite); -+ return; -+ } -+ } -+ else if (0 == done && 0xC0 == (0xE0 & Data[3])) { -+ // if the first I frame packet is an audio packet then this is a radio recording: don't touch it! -+ if (Length > OriginalLength) // roll back additional data -+ Length = OriginalLength; -+ return; -+ } -+ -+ done += lenPES; -+ Data += lenPES; -+ } -+} -+ -+// --- END fix for I frames --------------------------------------------- -+#endif /* DVBPLAYER */ -+ - void cDvbPlayer::Action(void) - { - uchar *b = NULL; - uchar *p = NULL; - int pc = 0; -+#ifdef USE_JUMPPLAY -+ bool cutIn = false; -+ int total = -1; -+#endif /* JUMPPLAY */ - - readIndex = Resume(); - if (readIndex >= 0) - isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true)); - -+#ifdef USE_JUMPPLAY -+ if (Setup.PlayJump && readIndex <= 0 && marks.First() && index) { -+ int Index = marks.First()->position; -+ uchar FileNumber; -+ int FileOffset; -+ if (index->Get(Index, &FileNumber, &FileOffset) && -+ NextFile(FileNumber, FileOffset)) { -+ isyslog("PlayJump: start replay at first mark %d (%s)", -+ Index, *IndexToHMSF(Index, true)); -+ readIndex = Index; -+ } -+ } -+ -+ bool LastMarkPause = false; -+#endif /* JUMPPLAY */ - nonBlockingFileReader = new cNonBlockingFileReader; - int Length = 0; - bool Sleep = false; -@@ -393,7 +577,11 @@ void cDvbPlayer::Action(void) - - // Read the next frame from the file: - -+#ifdef USE_JUMPPLAY -+ if (playMode != pmStill && playMode != pmPause && !LastMarkPause) { -+#else - if (playMode != pmStill && playMode != pmPause) { -+#endif /* JUMPPLAY */ - if (!readFrame && (replayFile || readIndex >= 0)) { - if (!nonBlockingFileReader->Reading()) { - if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) { -@@ -411,6 +599,9 @@ void cDvbPlayer::Action(void) - if (!NextFile(FileNumber, FileOffset)) { - readIndex = Index; - continue; -+#ifdef USE_DVBPLAYER -+ Length += IPACKS; // fixIFrame needs next video packet -+#endif /* DVBPLAYER */ - } - } - else { -@@ -438,6 +629,46 @@ void cDvbPlayer::Action(void) - uchar FileNumber; - int FileOffset; - readIndex++; -+#ifdef USE_JUMPPLAY -+ if (Setup.PlayJump || Setup.PauseLastMark) { -+ // check for end mark - jump to next mark or pause -+ marks.Reload(); -+ cMark *m = marks.Get(readIndex); -+ if (m && (m->Index() & 0x01) != 0) { -+ m = marks.Next(m); -+ int Index; -+ if (m) -+ Index = m->position; -+ else if (Setup.PauseLastMark) { -+ // pause at last mark -+ isyslog("PauseLastMark: pause at position %d (%s)", -+ readIndex, *IndexToHMSF(readIndex, true)); -+ LastMarkPause = true; -+ Index = -1; -+ } -+ else if (total == index->Last()) -+ // at last mark jump to end of recording -+ Index = index->Last() - 1; -+ else -+ // jump but stay off end of live-recordings -+ Index = index->GetNextIFrame(index->Last() - 150, true); -+ // don't jump in edited recordings -+ if (Setup.PlayJump && Index > readIndex && -+ Index > index->GetNextIFrame(readIndex, true)) { -+ isyslog("PlayJump: %d frames to %d (%s)", -+ Index - readIndex, Index, -+ *IndexToHMSF(Index, true)); -+ readIndex = Index; -+ cutIn = true; -+ } -+ } -+ } -+ // for detecting growing length of live-recordings -+ uchar PictureType; -+ if (index->Get(readIndex, &FileNumber, &FileOffset, &PictureType) && -+ PictureType == I_FRAME) -+ total = index->Last(); -+#endif /* JUMPPLAY */ - if (!(index->Get(readIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset))) { - readIndex = -1; - eof = true; -@@ -457,6 +688,10 @@ void cDvbPlayer::Action(void) - int r = nonBlockingFileReader->Read(replayFile, b, Length); - if (r > 0) { - WaitingForData = false; -+#ifdef USE_DVBPLAYER -+ if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) -+ fixIFrame(b, r, Length - IPACKS); -+#endif /* DVBPLAYER */ - readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer - b = NULL; - } -@@ -473,6 +708,12 @@ void cDvbPlayer::Action(void) - // Store the frame in the buffer: - - if (readFrame) { -+#ifdef USE_JUMPPLAY -+ if (cutIn) { -+ cRemux::SetBrokenLink(readFrame->Data(), readFrame->Count()); -+ cutIn = false; -+ } -+#endif /* JUMPPLAY */ - if (ringBuffer->Put(readFrame)) - readFrame = NULL; - } -@@ -503,6 +744,9 @@ void cDvbPlayer::Action(void) - } - } - if (p) { -+#ifdef USE_TTXTSUBS -+ StripExtendedPackets(p, pc); -+#endif /* TTXTSUBS */ - int w = PlayPes(p, pc, playMode != pmPlay); - if (w > 0) { - p += w; -@@ -521,8 +765,19 @@ void cDvbPlayer::Action(void) - p = NULL; - } - } -+#ifdef USE_JUMPPLAY -+ else { -+ if (LastMarkPause) { -+ LastMarkPause = false; -+ playMode = pmPause; -+ writeIndex = readIndex; -+ } -+ Sleep = true; -+ } -+#else - else - Sleep = true; -+#endif /* JUMPPLAY */ - } - } - -@@ -699,9 +954,15 @@ void cDvbPlayer::Goto(int Index, bool St - int FileOffset, Length; - Index = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset, &Length); - if (Index >= 0 && NextFile(FileNumber, FileOffset) && Still) { -+#ifdef USE_DVBPLAYER -+ Length += IPACKS; // fixIFrame needs next video packet -+#endif /* DVBPLAYER */ - uchar b[MAXFRAMESIZE + 4 + 5 + 4]; - int r = ReadFrame(replayFile, b, Length, sizeof(b)); - if (r > 0) { -+#ifdef USE_DVBPLAYER -+ fixIFrame(b, r, Length - IPACKS); -+#endif /* DVBPLAYER */ - if (playMode == pmPause) - DevicePlay(); - // append sequence end code to get the image shown immediately with softdevices -diff -ruNp vdr-1.7.0/eit.c vdr-1.7.0-extensions/eit.c ---- vdr-1.7.0/eit.c 2008-04-13 13:27:06.000000000 +0200 -+++ vdr-1.7.0-extensions/eit.c 2009-04-09 20:48:48.000000000 +0200 -@@ -17,13 +17,40 @@ - #include "libsi/section.h" - #include "libsi/descriptor.h" - -+#ifdef USE_SETTIME -+extern char *SetTime; -+#endif /* SETTIME */ -+ - // --- cEIT ------------------------------------------------------------------ - - class cEIT : public SI::EIT { - public: - cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bool OnlyRunningStatus = false); -+#ifdef USE_NOEPG -+private: -+ bool allowedEPG(tChannelID kanalID); -+#endif /* NOEPG */ - }; - -+#ifdef USE_NOEPG -+bool cEIT::allowedEPG(tChannelID kanalID) { -+ bool rc; -+ -+ if (Setup.noEPGMode == 1) { -+ rc = false; -+ if (strstr(::Setup.noEPGList,kanalID.ToString()) != NULL) -+ rc = true; -+ } -+ else { -+ rc = true; -+ if (strstr(::Setup.noEPGList,kanalID.ToString()) != NULL) -+ rc = false; -+ } -+ -+ return rc; -+} -+#endif /* NOEPG */ -+ - cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bool OnlyRunningStatus) - :SI::EIT(Data, false) - { -@@ -35,6 +62,14 @@ cEIT::cEIT(cSchedules *Schedules, int So - if (!channel) - return; // only collect data for known channels - -+#ifdef USE_NOEPG -+ // only use epg from channels not blocked by noEPG-patch -+ tChannelID kanalID; -+ kanalID = channel->GetChannelID(); -+ if (!allowedEPG(kanalID)) -+ return; -+#endif /* NOEPG */ -+ - cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channel, true); - - bool Empty = true; -@@ -71,8 +106,74 @@ cEIT::cEIT(cSchedules *Schedules, int So - // If the existing event has a zero table ID it was defined externally and shall - // not be overwritten. - if (pEvent->TableID() == 0x00) { -+#ifdef USE_DDEPGENTRY -+ if (pEvent->Version() == getVersionNumber()) { -+ if (Setup.MixEpgAction == 0) -+ continue; -+ //printf("in"); -+ //printf("%s", pEvent->GetTimeString()); -+ // to use the info of the original epg, update the extern one, -+ // if it has less info -+ SI::Descriptor *d; -+ SI::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL; -+ //SI::ExtendedEventDescriptor *eed = NULL; -+ SI::ShortEventDescriptor *ShortEventDescriptor = NULL; -+ //SI::ShortEventDescriptor *sed = NULL; -+ //SI::TimeShiftedEventDescriptor *tsed = NULL; -+ //cLinkChannels *LinkChannels = NULL; -+ for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2));) { -+ if (d->getDescriptorTag() == SI::ShortEventDescriptorTag) { -+ int LanguagePreferenceShort = -1; -+ SI::ShortEventDescriptor *sed = (SI::ShortEventDescriptor *)d; -+ if (I18nIsPreferredLanguage(Setup.EPGLanguages, sed->languageCode, LanguagePreferenceShort) || !ShortEventDescriptor) { -+ delete ShortEventDescriptor; -+ ShortEventDescriptor = sed; -+ d = NULL; // so that it is not deleted -+ } -+ } -+ else if (d->getDescriptorTag() == SI::ExtendedEventDescriptorTag) { -+ int LanguagePreferenceExt = -1; -+ bool UseExtendedEventDescriptor = false; -+ SI::ExtendedEventDescriptor *eed = (SI::ExtendedEventDescriptor *)d; -+ if (I18nIsPreferredLanguage(Setup.EPGLanguages, eed->languageCode, LanguagePreferenceExt) || !ExtendedEventDescriptors) { -+ delete ExtendedEventDescriptors; -+ ExtendedEventDescriptors = new SI::ExtendedEventDescriptors; -+ UseExtendedEventDescriptor = true; -+ } -+ if (UseExtendedEventDescriptor) { -+ ExtendedEventDescriptors->Add(eed); -+ d = NULL; // so that it is not deleted -+ } -+ if (eed->getDescriptorNumber() == eed->getLastDescriptorNumber()) -+ UseExtendedEventDescriptor = false; -+ } -+ delete d; -+ } -+ if (pEvent) { -+ if (ShortEventDescriptor) { -+ char buffer[256]; -+ if (ShortEventDescriptor->text.getText(buffer, sizeof(buffer)) && pEvent->ShortText() && (strlen(ShortEventDescriptor->text.getText(buffer, sizeof(buffer))) > strlen(pEvent->ShortText()))) { -+ pEvent->SetShortText(ShortEventDescriptor->text.getText(buffer, sizeof(buffer))); -+ pEvent->FixEpgBugs(); -+ } -+ } -+ if (ExtendedEventDescriptors) { -+ char buffer[ExtendedEventDescriptors->getMaximumTextLength(": ") + 1]; -+ //pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ")); -+ if (ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ") && pEvent->Description() && (strlen(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ")) > strlen(pEvent->Description()))) { -+ pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ")); -+ pEvent->FixEpgBugs(); -+ } -+ } -+ } -+ delete ExtendedEventDescriptors; -+ delete ShortEventDescriptor; -+ continue; -+ } -+#else - if (pEvent->Version() == getVersionNumber()) - continue; -+#endif /* DDEPGENTRY */ - HasExternalData = ExternalData = true; - } - // If the new event has a higher table ID, let's skip it. -@@ -97,7 +198,11 @@ cEIT::cEIT(cSchedules *Schedules, int So - if (newEvent) - pSchedule->AddEvent(newEvent); - if (Tid == 0x4E) { // we trust only the present/following info on the actual TS -+#ifdef USE_DDEPGENTRY -+ if (Setup.DisableVPS == 0 && SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning) -+#else - if (SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning) -+#endif /* DDEPGENTRY */ - pSchedule->SetRunningStatus(pEvent, SiEitEvent.getRunningStatus(), channel); - } - if (OnlyRunningStatus) -@@ -143,8 +248,46 @@ cEIT::cEIT(cSchedules *Schedules, int So - } - break; - case SI::ContentDescriptorTag: -+#ifdef USE_PARENTALRATING -+ { -+ int NumContents = 0; -+ uchar Contents[MAXEVCONTENTS + 1] = { 0 }; -+ SI::ContentDescriptor *cd = (SI::ContentDescriptor *)d; -+ SI::ContentDescriptor::Nibble Nibble; -+ for (SI::Loop::Iterator it3; cd->nibbleLoop.getNext(Nibble, it3); ) { -+ if (NumContents < MAXEVCONTENTS) { -+ Contents[NumContents] = ((Nibble.getContentNibbleLevel1() & 0xF) << 4) | (Nibble.getContentNibbleLevel2() & 0xF); -+ NumContents++; -+ } -+ } -+ pEvent->SetContents(Contents); -+ } -+#endif /* PARENTALRATING */ - break; - case SI::ParentalRatingDescriptorTag: -+#ifdef USE_PARENTALRATING -+ { -+ int LanguagePreferenceRating = -1; -+ SI::ParentalRatingDescriptor *prd = (SI::ParentalRatingDescriptor *)d; -+ SI::ParentalRatingDescriptor::Rating Rating; -+ for (SI::Loop::Iterator it3; prd->ratingLoop.getNext(Rating, it3); ) { -+ if (I18nIsPreferredLanguage(Setup.EPGLanguages, Rating.languageCode, LanguagePreferenceRating)) { -+ int rate = (Rating.getRating() & 0xFF); -+ switch (rate) { -+ case 0x01 ... 0x0F: // minimum age = rating + 3 years -+ rate += 3; -+ break; -+ case 0: // undefined -+ case 0x10 ... 0xFF: // defined by the broadcaster -+ default: -+ rate = 0; -+ break; -+ } -+ pEvent->SetParentalRating(rate); -+ } -+ } -+ } -+#endif /* PARENTALRATING */ - break; - case SI::PDCDescriptorTag: { - SI::PDCDescriptor *pd = (SI::PDCDescriptor *)d; -@@ -259,6 +402,62 @@ cEIT::cEIT(cSchedules *Schedules, int So - if (LinkChannels) - channel->SetLinkChannels(LinkChannels); - Modified = true; -+#ifdef USE_DDEPGENTRY -+ //to avoid double epg-entrys from ext and int epg sources :EW -+ if (pEvent && pEvent->TableID() != 0x00) { -+ cEvent *pPreviousEvent = (cEvent *)pSchedule->GetPreviousEvent(pEvent); -+ if (pPreviousEvent) { -+ if (Setup.DoubleEpgAction == 0) { -+ pPreviousEvent->SetStartTime(pEvent->StartTime()); -+ pPreviousEvent->SetDuration(pEvent->Duration()); -+ if (Setup.DisableVPS == 0) { -+ if (channel) -+ pPreviousEvent->SetRunningStatus(pEvent->RunningStatus(), channel); -+ else -+ pPreviousEvent->SetRunningStatus(pEvent->RunningStatus()); -+ } -+ // to use the info of the original epg, update the extern one, -+ // if it has less info -+ char buffer_short_intern[256]; -+ char buffer_short_extern[256]; -+ int len_short_intern = 0; -+ int len_short_extern = 0; -+ if (pEvent->ShortText()) -+ len_short_intern = snprintf (buffer_short_intern, sizeof(buffer_short_intern)-1, "%s", pEvent->ShortText()); -+ if (pPreviousEvent->ShortText()) -+ len_short_extern = snprintf (buffer_short_extern, sizeof(buffer_short_extern)-1, "%s", pPreviousEvent->ShortText()); -+ if (len_short_intern > 0) { -+ if (len_short_extern < 1) -+ pPreviousEvent->SetShortText(buffer_short_intern); -+ else if (len_short_intern > len_short_extern) -+ pPreviousEvent->SetShortText(buffer_short_intern); -+ } -+ if (pEvent->Description()) { -+ char buffer_title_intern[4096]; -+ char buffer_title_extern[4096]; -+ int len_title_intern = 0; -+ int len_title_extern = 0; -+ if (pEvent->Description()) -+ len_title_intern = snprintf (buffer_title_intern, sizeof(buffer_title_intern)-1, "%s", pEvent->Description()); -+ if (pPreviousEvent->Description()) -+ len_title_extern = snprintf (buffer_title_extern, sizeof(buffer_title_extern)-1, "%s", pPreviousEvent->Description()); -+ if (len_title_intern > 0) { -+ if (len_title_extern < 1) -+ pPreviousEvent->SetDescription(buffer_title_intern); -+ else if (len_title_intern > len_title_extern) -+ pPreviousEvent->SetDescription(buffer_title_intern); -+ } -+ } -+ if (pPreviousEvent->Vps() == 0 && pEvent->Vps() != 0) -+ pPreviousEvent->SetVps(pEvent->Vps()); -+ pSchedule->DelEvent(pEvent); -+ pPreviousEvent->FixEpgBugs(); -+ } -+ else -+ pSchedule->DelEvent(pPreviousEvent); -+ } -+ } -+#endif /* DDEPGENTRY */ - } - if (Empty && Tid == 0x4E && getSectionNumber() == 0) - // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running -@@ -296,10 +495,26 @@ cTDT::cTDT(const u_char *Data) - time_t sattim = getTime(); - time_t loctim = time(NULL); - -+#ifdef USE_SETTIME -+ char timestr[20]; -+ struct tm *ptm; -+ struct tm tm_r; -+ ptm = localtime_r(&sattim, &tm_r); -+#endif /* SETTIME */ -+ - int diff = abs(sattim - loctim); - if (diff > 2) { - mutex.Lock(); - if (abs(diff - lastDiff) < 3) { -+#ifdef USE_SETTIME -+ if (SetTime) { -+ strftime(timestr, 20, "%m%d%H%M%Y.%S", ptm); -+ cString cmd = cString::sprintf("%s %s %ld", SetTime, timestr, sattim); -+ dsyslog("Executing: %s", *cmd); -+ SystemExec(cmd); -+ } -+ else -+#endif /* SETTIME */ - if (stime(&sattim) == 0) - isyslog("system time changed from %s (%ld) to %s (%ld)", *TimeToString(loctim), loctim, *TimeToString(sattim), sattim); - else -diff -ruNp vdr-1.7.0/eitscan.c vdr-1.7.0-extensions/eitscan.c ---- vdr-1.7.0/eitscan.c 2006-01-07 15:10:17.000000000 +0100 -+++ vdr-1.7.0-extensions/eitscan.c 2009-04-09 20:48:48.000000000 +0200 -@@ -151,9 +151,17 @@ void cEITScanner::Process(void) - if (Device->ProvidesTransponder(Channel)) { - if (!Device->Receiving()) { - bool MaySwitchTransponder = Device->MaySwitchTransponder(); -+#ifdef USE_LNBSHARE -+ if (MaySwitchTransponder && Device->GetMaxBadPriority(Channel) == -2 || Device->ProvidesTransponderExclusively(Channel) && Device->GetMaxBadPriority(Channel) <= -1 && now - lastActivity > Setup.EPGScanTimeout * 3600) { -+#else - if (MaySwitchTransponder || Device->ProvidesTransponderExclusively(Channel) && now - lastActivity > Setup.EPGScanTimeout * 3600) { -+#endif /* LNBSHARE */ - if (!MaySwitchTransponder) { -+#ifdef USE_LNBSHARE -+ if ((Device == cDevice::ActualDevice() || Device->GetMaxBadPriority(Channel) == -1) && !currentChannel) { -+#else - if (Device == cDevice::ActualDevice() && !currentChannel) { -+#endif /* LNBSHARE */ - cDevice::PrimaryDevice()->StopReplay(); // stop transfer mode - currentChannel = Device->CurrentChannel(); - Skins.Message(mtInfo, tr("Starting EPG scan")); -diff -ruNp vdr-1.7.0/epg.c vdr-1.7.0-extensions/epg.c ---- vdr-1.7.0/epg.c 2008-02-16 17:09:12.000000000 +0100 -+++ vdr-1.7.0-extensions/epg.c 2009-04-09 20:48:48.000000000 +0200 -@@ -112,6 +112,11 @@ cEvent::cEvent(tEventID EventID) - components = NULL; - startTime = 0; - duration = 0; -+#ifdef USE_PARENTALRATING -+ for (int i = 0; i < MAXEVCONTENTS; i++) -+ contents[i] = 0; -+ parentalRating = 0; -+#endif /* PARENTALRATING */ - vps = 0; - SetSeen(); - } -@@ -200,6 +205,19 @@ void cEvent::SetDuration(int Duration) - duration = Duration; - } - -+#ifdef USE_PARENTALRATING -+void cEvent::SetContents(uchar *Contents) -+{ -+ for (int i = 0; i < MAXEVCONTENTS; i++) -+ contents[i] = Contents[i]; -+} -+ -+void cEvent::SetParentalRating(uchar ParentalRating) -+{ -+ parentalRating = ParentalRating; -+} -+#endif /* PARENTALRATING */ -+ - void cEvent::SetVps(time_t Vps) - { - vps = Vps; -@@ -255,6 +273,340 @@ cString cEvent::GetVpsString(void) const - return buf; - } - -+#ifdef USE_PARENTALRATING -+cString cEvent::GetContentsString(int i) const -+{ -+ cString str(""); -+ switch (contents[i] & 0xF0) { -+ case EVCONTENTMASK_MOVIEDRAMA: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Movie/Drama")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Detective/Thriller")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Adventure/Western/War")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Science Fiction/Fantasy/Horror")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Comedy")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Soap/Melodrama/Folkloric")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Romance")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Serious/Classical/Religious/Historical Movie/Drama")); -+ break; -+ case 0x08: -+ str = cString(tr("Content$Adult Movie/Drama")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_NEWSCURRENTAFFAIRS: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$News/Current Affairs")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$News/Weather Report")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$News Magazine")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Documentary")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Discussion/Inverview/Debate")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_SHOW: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Show/Game Show")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Game Show/Quiz/Contest")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Variety Show")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Talk Show")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_SPORTS: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Sports")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Special Event")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Sport Magazine")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Football")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Tennis/Squash")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Team Sports")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Athletics")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Motor Sport")); -+ break; -+ case 0x08: -+ str = cString(tr("Content$Water Sport")); -+ break; -+ case 0x09: -+ str = cString(tr("Content$Winter Sports")); -+ break; -+ case 0x0A: -+ str = cString(tr("Content$Equestrian")); -+ break; -+ case 0x0B: -+ str = cString(tr("Content$Martial Sports")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_CHILDRENYOUTH: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Children's/Youth Programmes")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Pre-school Children's Programmes")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Entertainment Programmes for 6 to 14")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Entertainment Programmes for 10 to 16")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Informational/Educational/School Programme")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Cartoons/Puppets")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_MUSICBALLETDANCE: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Music/Ballet/Dance")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Rock/Pop")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Serious/Classical Music")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Folk/Tradional Music")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Jazz")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Musical/Opera")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Ballet")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_ARTSCULTURE: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Arts/Culture")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Performing Arts")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Fine Arts")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Religion")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Popular Culture/Traditional Arts")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Literature")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Film/Cinema")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Experimental Film/Video")); -+ break; -+ case 0x08: -+ str = cString(tr("Content$Broadcasting/Press")); -+ break; -+ case 0x09: -+ str = cString(tr("Content$New Media")); -+ break; -+ case 0x0A: -+ str = cString(tr("Content$Arts/Culture Magazines")); -+ break; -+ case 0x0B: -+ str = cString(tr("Content$Fashion")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_SOCIALPOLITICALECONOMICS: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Social/Political/Economics")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Magazines/Reports/Documentary")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Economics/Social Advisory")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Remarkable People")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_EDUCATIONALSCIENCE: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Education/Science/Factual")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Nature/Animals/Environment")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Technology/Natural Sciences")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Medicine/Physiology/Psychology")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Foreign Countries/Expeditions")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Social/Spiritual Sciences")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Further Education")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Languages")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_LEISUREHOBBIES: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Leisure/Hobbies")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Tourism/Travel")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Handicraft")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Motoring")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Fitness & Health")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Cooking")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Advertisement/Shopping")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Gardening")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_SPECIAL: -+ switch (contents[i] & 0x0F) { -+ case 0x00: -+ str = cString(tr("Content$Original Language")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Black & White")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Unpublished")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Live Broadcast")); -+ break; -+ default: -+ str = cString(tr("Content$Special Characteristics")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_USERDEFINED: -+ switch (contents[i] & 0x0F) { -+ case 0x00: -+ str = cString(tr("Content$Drama")); // UK Freeview -+ break; -+ default: -+ break; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ return str; -+} -+ -+cString cEvent::GetParentalRatingString(void) const -+{ -+ if (parentalRating > 0) -+ return cString::sprintf(tr("Suitable for those aged %d and over"), parentalRating); -+ return NULL; -+} -+#endif /* PARENTALRATING */ -+ - void cEvent::Dump(FILE *f, const char *Prefix, bool InfoOnly) const - { - if (InfoOnly || startTime + duration + Setup.EPGLinger * 60 >= time(NULL)) { -@@ -742,6 +1094,28 @@ const cEvent *cSchedule::GetEventAround( - return pe; - } - -+#ifdef USE_DDEPGENTRY -+const cEvent *cSchedule::GetPreviousEvent(cEvent *Event) const -+{ -+ if (!Event || Event->Duration() == 0 || Event->StartTime() == 0) -+ return NULL; -+ // Returns either the event info to the previous/following event to the given EventID or, if that one can't be found NULL :EW -+ cEvent *pt = NULL; -+ int epgTimeDelta = Setup.DoubleEpgTimeDelta * 60 + 1; -+ for (pt = events.First(); pt; pt = events.Next(pt)) -+ if (pt && pt->TableID() == 0x00) -+ if ((Event->StartTime() - pt->StartTime()) > - epgTimeDelta && (Event->StartTime() - pt->StartTime()) < epgTimeDelta) { -+ if ((pt->Duration() + (pt->Duration()/ 5) + 1) > Event->Duration() && (pt->Duration() - (pt->Duration()/ 5) - 1) < Event->Duration()) -+ return pt; -+ else if (pt->Title() && Event->Title() && (strcmp(pt->Title(), ".") != 0 && strcmp(Event->Title(), ".") != 0)) { -+ if (strstr(pt->Title(), Event->Title()) != NULL || strstr(Event->Title(), pt->Title()) != NULL) -+ return pt; -+ } -+ } -+ return NULL; -+} -+#endif /* DDEPGENTRY */ -+ - void cSchedule::SetRunningStatus(cEvent *Event, int RunningStatus, cChannel *Channel) - { - hasRunning = false; -diff -ruNp vdr-1.7.0/epg.h vdr-1.7.0-extensions/epg.h ---- vdr-1.7.0/epg.h 2006-10-07 15:47:19.000000000 +0200 -+++ vdr-1.7.0-extensions/epg.h 2009-04-09 20:48:48.000000000 +0200 -@@ -50,6 +50,22 @@ class cSchedule; - - typedef u_int32_t tEventID; - -+#ifdef USE_PARENTALRATING -+#define MAXEVCONTENTS 4 -+#define EVCONTENTMASK_MOVIEDRAMA 0x10 -+#define EVCONTENTMASK_NEWSCURRENTAFFAIRS 0x20 -+#define EVCONTENTMASK_SHOW 0x30 -+#define EVCONTENTMASK_SPORTS 0x40 -+#define EVCONTENTMASK_CHILDRENYOUTH 0x50 -+#define EVCONTENTMASK_MUSICBALLETDANCE 0x60 -+#define EVCONTENTMASK_ARTSCULTURE 0x70 -+#define EVCONTENTMASK_SOCIALPOLITICALECONOMICS 0x80 -+#define EVCONTENTMASK_EDUCATIONALSCIENCE 0x90 -+#define EVCONTENTMASK_LEISUREHOBBIES 0xA0 -+#define EVCONTENTMASK_SPECIAL 0xB0 -+#define EVCONTENTMASK_USERDEFINED 0xF0 -+#endif /* PARENTALRATING */ -+ - class cEvent : public cListObject { - friend class cSchedule; - private: -@@ -64,6 +80,10 @@ private: - cComponents *components; // The stream components of this event - time_t startTime; // Start time of this event - int duration; // Duration of this event in seconds -+#ifdef USE_PARENTALRATING -+ uchar contents[MAXEVCONTENTS + 1]; // Contents of this event; list is zero-terminated -+ uchar parentalRating; // Parental rating of this event -+#endif /* PARENTALRATING */ - time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL) - time_t seen; // When this event was last seen in the data stream - public: -@@ -83,6 +103,10 @@ public: - time_t StartTime(void) const { return startTime; } - time_t EndTime(void) const { return startTime + duration; } - int Duration(void) const { return duration; } -+#ifdef USE_PARENTALRATING -+ uchar Contents(int i = 0) const { return (0 <= i && i < MAXEVCONTENTS) ? contents[i] : 0; } -+ uchar ParentalRating(void) const { return parentalRating; } -+#endif /* PARENTALRATING */ - time_t Vps(void) const { return vps; } - time_t Seen(void) const { return seen; } - bool SeenWithin(int Seconds) const { return time(NULL) - seen < Seconds; } -@@ -92,6 +116,10 @@ public: - cString GetTimeString(void) const; - cString GetEndTimeString(void) const; - cString GetVpsString(void) const; -+#ifdef USE_PARENTALRATING -+ cString GetContentsString(int i = 0) const; -+ cString GetParentalRatingString(void) const; -+#endif /* PARENTALRATING */ - void SetEventID(tEventID EventID); - void SetTableID(uchar TableID); - void SetVersion(uchar Version); -@@ -102,6 +130,10 @@ public: - void SetComponents(cComponents *Components); // Will take ownership of Components! - void SetStartTime(time_t StartTime); - void SetDuration(int Duration); -+#ifdef USE_PARENTALRATING -+ void SetContents(uchar *Contents); -+ void SetParentalRating(uchar ParentalRating); -+#endif /* PARENTALRATING */ - void SetVps(time_t Vps); - void SetSeen(void); - cString ToDescr(void) const; -@@ -137,6 +169,9 @@ public: - void DropOutdated(time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version); - void Cleanup(time_t Time); - void Cleanup(void); -+#ifdef USE_DDEPGENTRY -+ const cEvent *GetPreviousEvent(cEvent *Event) const; //:EW -+#endif /* DDEPGENTRY */ - cEvent *AddEvent(cEvent *Event); - void DelEvent(cEvent *Event); - void HashEvent(cEvent *Event); -diff -ruNp vdr-1.7.0/HISTORY-liemikuutio vdr-1.7.0-extensions/HISTORY-liemikuutio ---- vdr-1.7.0/HISTORY-liemikuutio 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/HISTORY-liemikuutio 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,108 @@ -+----------------------------------- -+Liemikuutio for Video Disc Recorder -+ -+Maintainer: Rolf Ahrenberg -+----------------------------------- -+ -+2006-01-08: Version 1.0 -+ -+- Based on enAIO with these original patches: -+ Simple recordings sorting by Walter@VDRPortal -+ Alternate rename recordings by Ralf Müller -+ Menu selection by Peter Dittmann -+ Recording length by Tobias Faust -+ -+2006-01-15: Version 1.1 -+ -+- Removed patches already found in vdr-1.3.39. -+ -+2006-01-25: Version 1.2 -+ -+- Added "Main menu command position" feature. -+ -+2006-02-05: Version 1.3 -+ -+- Improved menu selection response. -+ -+2006-04-18: Version 1.4 -+ -+- Added Estonian translation (Thanks to Arthur Konovalov). -+ -+2006-04-30: Version 1.5 -+ -+- Added progress bar view into "What's on now?" menu. -+ -+2006-06-06: Version 1.6 -+ -+- Added French translation (Thanks to ECLiPSE). -+ -+2006-06-14: Version 1.7 -+ -+- Fixed RENR crash. -+ -+2006-07-14: Version 1.8 -+ -+- Fixed RENR/OSD bug. -+ -+2006-08-27: Version 1.9 -+ -+- Some modifications to the recording length and rename recordings -+ patches (Thanks to Firefly). -+- Added k1_k3_jumps_20s patch by Petri Hintukainen. -+ -+2006-08-29: Version 1.10 -+ -+- The cRecording:Title() method now defaults to original formatting. -+ -+2006-09-04: Version 1.11 -+ -+- Removed unused variable from cRecording::Title() method (Thanks to -+ C.Y.M.). -+- Some modifications to the rename recordings patch (Thanks to Firefly). -+ -+2006-09-13: Version 1.12 -+ -+- More modifications to the rename recordings patch (Thanks to Firefly). -+ -+2006-10-01: Version 1.13 -+ -+- Removed unnecessary syslog printing (Thanks to Firefly). -+ -+2007-08-14: Version 1.14 -+ -+- Updated for vdr-1.5.7. -+ -+2007-10-16: Version 1.15 -+ -+- Added recmenu play patch (Thanks to Ville Skyttä). -+- Updated French translation (Thanks to ECLiPSE). -+ -+2007-11-04: Version 1.16 -+ -+- Updated for vdr-1.5.11. -+ -+2007-12-08: Version 1.17 -+ -+- Added binary skip patch. -+- Removed k1_k3_jumps_20s patch. -+ -+2008-02-17: Version 1.18 -+ -+- Updated for vdr-1.5.15. -+ -+2008-03-02: Version 1.19 -+ -+- Modified binary skip to use kPrev and kNext keys and the skip is now -+ always shortened after a direction change (Thanks to Timo Eskola). -+- Readded k1_k3_jumps_20s patch. -+ -+2008-04-04: Version 1.20 -+ -+- Added bitrate information into rename menu. -+- Readded the path editing support of rename recordings patch (Thanks -+ to Firefly). -+ -+2008-05-08: Version 1.21 -+ -+- Fixed rename recordings (Thanks to Firefly). -+- Added a DVB subtitles hack for old recordings (Thanks to Anssi Hannula). -diff -ruNp vdr-1.7.0/iconpatch.c vdr-1.7.0-extensions/iconpatch.c ---- vdr-1.7.0/iconpatch.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/iconpatch.c 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,31 @@ -+#ifdef USE_WAREAGLEICON -+ -+#include "iconpatch.h" -+ -+#include <langinfo.h> -+#include <locale.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+ -+bool IsLangUtf8(void) -+{ -+ char *CodeSet = NULL; -+ if (setlocale(LC_CTYPE, "")) -+ CodeSet = nl_langinfo(CODESET); -+ else { -+ char *LangEnv = getenv("LANG"); // last resort in case locale stuff isn't installed -+ if (LangEnv) { -+ CodeSet = strchr(LangEnv, '.'); -+ if (CodeSet) -+ CodeSet++; // skip the dot -+ } -+ } -+ -+ if (CodeSet && strcasestr(CodeSet, "UTF-8") != 0) -+ return true; -+ -+ return false; -+} -+ -+#endif /* WAREAGLEICON */ -diff -ruNp vdr-1.7.0/iconpatch.h vdr-1.7.0-extensions/iconpatch.h ---- vdr-1.7.0/iconpatch.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/iconpatch.h 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,73 @@ -+#ifdef USE_WAREAGLEICON -+/* -+ * iconpatch.h: Information of iconpatch -+ * -+ * Diese Datei ist die Übersichtsdatei für den Iconpatch. -+ * Hier werden kleine Infos abgelegt. -+ * Der Iconpatch ändert die Dateien: -+ * iconpatch.h -+ * menu.c -+ * recording.c -+ * fontosd.c -+ * -+ */ -+ -+// Iconpatch-Variablen - Anfang -+#define ICON_NUMBERSIGN "\x23" -+#define ICON_ASTERISK "\x2A" -+#define ICON_GREATER "\x3E" -+#define ICON_EXCLAM "\x21" -+#define ICON_PLUSMINUS "\xB1" -+ -+#define ICON_RESUME "\x80" -+#define ICON_DVD "\x81" -+#define ICON_FOLDER "\x82" -+#define ICON_BLANK "\x83" -+#define ICON_CUTTING "\x84" -+#define ICON_MOVE_FILE "\x85" -+#define ICON_MOVE_FOLDER "\x86" -+#define ICON_BAR_START "\x87" -+#define ICON_BAR_FILLED "\x88" -+#define ICON_BAR_CLEAR "\x89" -+#define ICON_BAR_END "\x8A" -+#define ICON_REC "\x8B" -+#define ICON_CLOCK "\x8C" -+#define ICON_TV_CRYPTED "\x8D" -+#define ICON_RADIO "\x8E" -+#define ICON_TV "\x8F" -+#define ICON_NEW "\x90" -+#define ICON_ARROW "\x91" -+#define ICON_RUNNING "\x92" -+#define ICON_VPS "\x93" -+#define ICON_CLOCK_UH "\x94" -+#define ICON_CLOCK_LH "\x95" -+ -+// UTF-8 Icons -+#define ICON_RESUME_UTF8 "\uE000" -+#define ICON_DVD_UTF8 "\uE001" -+#define ICON_FOLDER_UTF8 "\uE002" -+#define ICON_BLANK_UTF8 "\uE003" -+#define ICON_CUTTING_UTF8 "\uE004" -+#define ICON_MOVE_FILE_UTF8 "\uE005" -+#define ICON_MOVE_FOLDER_UTF8 "\uE006" -+#define ICON_BAR_START_UTF8 "\uE007" -+#define ICON_BAR_FILLED_UTF8 "\uE008" -+#define ICON_BAR_EMPTY_UTF8 "\uE009" -+#define ICON_BAR_CLOSE_UTF8 "\uE00A" -+#define ICON_REC_UTF8 "\uE00B" -+#define ICON_CLOCK_UTF8 "\uE00C" -+#define ICON_TV_CRYPTED_UTF8 "\uE00D" -+#define ICON_RADIO_UTF8 "\uE00E" -+#define ICON_TV_UTF8 "\uE00F" -+#define ICON_NEW_UTF8 "\uE010" -+#define ICON_ARROW_UTF8 "\uE011" -+#define ICON_RUNNING_UTF8 "\uE012" -+#define ICON_VPS_UTF8 "\uE013" -+#define ICON_CLOCK_UH_UTF8 "\uE014" -+#define ICON_CLOCK_LH_UTF8 "\uE015" -+ -+// Iconpatch-Variablen - Ende -+ -+bool IsLangUtf8(void); -+ -+#endif /* WAREAGLEICON */ -diff -ruNp vdr-1.7.0/keys.h vdr-1.7.0-extensions/keys.h ---- vdr-1.7.0/keys.h 2007-08-26 14:34:50.000000000 +0200 -+++ vdr-1.7.0-extensions/keys.h 2009-04-09 20:48:48.000000000 +0200 -@@ -71,6 +71,10 @@ enum eKeys { // "Up" and "Down" must be - #define kEditCut k2 - #define kEditTest k8 - -+#ifdef USE_DVDARCHIVE -+#define kDvdChapterJumpForward k6 -+#define kDvdChapterJumpBack k4 -+#endif /* DVDARCHIVE */ - #define RAWKEY(k) (eKeys((k) & ~k_Flags)) - #define ISRAWKEY(k) ((k) != kNone && ((k) & k_Flags) == 0) - #define NORMALKEY(k) (eKeys((k) & ~k_Repeat)) -diff -ruNp vdr-1.7.0/lirc.c vdr-1.7.0-extensions/lirc.c ---- vdr-1.7.0/lirc.c 2006-05-28 10:48:13.000000000 +0200 -+++ vdr-1.7.0-extensions/lirc.c 2009-04-09 20:48:48.000000000 +0200 -@@ -12,6 +12,9 @@ - #include "lirc.h" - #include <netinet/in.h> - #include <sys/socket.h> -+#ifdef USE_LIRCSETTINGS -+#include "config.h" -+#endif /* LIRCSETTINGS */ - - #define REPEATDELAY 350 // ms - #define REPEATFREQ 100 // ms -@@ -94,7 +97,11 @@ void cLircRemote::Action(void) - continue; - } - if (count == 0) { -+#ifdef USE_LIRCSETTINGS -+ if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < (unsigned int)Setup.LircRepeatDelay) -+#else - if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < REPEATDELAY) -+#endif /* LIRCSETTINGS */ - continue; // skip keys coming in too fast - if (repeat) - Put(LastKeyName, false, true); -@@ -104,18 +111,34 @@ void cLircRemote::Action(void) - timeout = -1; - } - else { -+#ifdef USE_LIRCSETTINGS -+ if (LastTime.Elapsed() < (unsigned int)Setup.LircRepeatFreq) -+#else - if (LastTime.Elapsed() < REPEATFREQ) -+#endif /* LIRCSETTINGS */ - continue; // repeat function kicks in after a short delay (after last key instead of first key) -+#ifdef USE_LIRCSETTINGS -+ if (FirstTime.Elapsed() < (unsigned int)Setup.LircRepeatDelay) -+#else - if (FirstTime.Elapsed() < REPEATDELAY) -+#endif /* LIRCSETTINGS */ - continue; // skip keys coming in too fast (for count != 0 as well) - repeat = true; -+#ifdef USE_LIRCSETTINGS -+ timeout = Setup.LircRepeatDelay; -+#else - timeout = REPEATDELAY; -+#endif /* LIRCSETTINGS */ - } - LastTime.Set(); - Put(KeyName, repeat); - } - else if (repeat) { // the last one was a repeat, so let's generate a release -+#ifdef USE_LIRCSETTINGS -+ if (LastTime.Elapsed() >= (unsigned int)Setup.LircRepeatTimeout) { -+#else - if (LastTime.Elapsed() >= REPEATTIMEOUT) { -+#endif /* LIRCSETTINGS */ - Put(LastKeyName, false, true); - repeat = false; - *LastKeyName = 0; -diff -ruNp vdr-1.7.0/livebuffer.c vdr-1.7.0-extensions/livebuffer.c ---- vdr-1.7.0/livebuffer.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/livebuffer.c 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,1912 @@ -+#ifdef USE_LIVEBUFFER -+#include "livebuffer.h" -+#include "menu.h" -+#include "recording.h" -+#include "transfer.h" -+ -+#define RECORDERBUFSIZE MEGABYTE(2) -+ -+// --- cFileName ------------------------------------------------------------- -+ -+#include <errno.h> -+#include <unistd.h> -+#include "videodir.h" -+ -+#define MAXFILESPERRECORDING 255 -+#define RECORDFILESUFFIX "/%03d.vdr" -+#define RECORDFILESUFFIXLEN 20 -+ -+cFileName64::cFileName64(const char *FileName, bool Record, bool Blocking) -+{ -+ file = NULL; -+ record = Record; -+ blocking = Blocking; -+ // Prepare the file name: -+ fileName = MALLOC(char, strlen(FileName) + RECORDFILESUFFIXLEN); -+ if (!fileName) { -+ esyslog("ERROR: can't copy file name '%s'", fileName); -+ return; -+ } -+ strcpy(fileName, FileName); -+ pFileNumber = fileName + strlen(fileName); -+ -+ fileNumber = 1; -+ while (true) { -+ sprintf(pFileNumber, RECORDFILESUFFIX, fileNumber); -+ if (record) { -+ if (access(fileName, F_OK) == 0) { -+ struct stat64 buf; -+ if (stat64(fileName, &buf) == 0) { -+ fileNumber++; -+ continue; -+ } -+ } -+ else if (errno != ENOENT) -+ LOG_ERROR_STR(fileName); -+ } -+ break; -+ } -+} -+ -+cFileName64::~cFileName64() -+{ -+ Close(); -+ free(fileName); -+} -+ -+void cFileName64::SetNumber(int Number) -+{ -+ fileNumber = Number; -+ sprintf(pFileNumber, RECORDFILESUFFIX, fileNumber); -+} -+ -+cUnbufferedFile64 *cFileName64::Open(void) -+{ -+ if (!file) { -+ int BlockingFlag = blocking ? 0 : O_NONBLOCK; -+ if (record) { -+ file = cUnbufferedFile64::Create(fileName, O_RDWR | O_CREAT | BlockingFlag); -+ if (!file) -+ LOG_ERROR_STR(fileName); -+ } -+ else { -+ if (access(fileName, R_OK) == 0) { -+ file = cUnbufferedFile64::Create(fileName, O_RDONLY | BlockingFlag); -+ if (!file) -+ LOG_ERROR_STR(fileName); -+ } -+ else if (errno != ENOENT) -+ LOG_ERROR_STR(fileName); -+ } -+ } -+ return file; -+} -+ -+void cFileName64::Close(void) -+{ -+ if (file) { -+ if (file->Close() < 0) -+ LOG_ERROR_STR(fileName); -+ delete file; -+ file = NULL; -+ } -+} -+ -+void cFileName64::CloseAndRemove(void) -+{ -+ Close(); -+ remove(fileName); -+} -+ -+// --- cUnbufferedFile64 ----------------------------------------------------- -+ -+#define USE_FADVISE -+ -+#define WRITE_BUFFER KILOBYTE(800) -+ -+cUnbufferedFile64::cUnbufferedFile64(void) -+{ -+ fd = -1; -+} -+ -+cUnbufferedFile64::~cUnbufferedFile64() -+{ -+ Close(); -+} -+ -+int cUnbufferedFile64::Open(const char *FileName, int Flags, mode_t Mode) -+{ -+ Close(); -+ fd = open64(FileName, Flags, Mode); -+ curpos = 0; -+#ifdef USE_FADVISE -+ begin = lastpos = ahead = 0; -+ cachedstart = 0; -+ cachedend = 0; -+ readahead = KILOBYTE(128); -+ written = 0; -+ totwritten = 0; -+ if (fd >= 0) -+ posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM); -+#endif -+ return fd; -+} -+ -+int cUnbufferedFile64::Close(void) -+{ -+#ifdef USE_FADVISE -+ if (fd >= 0) { -+ if (totwritten) -+ fdatasync(fd); -+ posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); -+ } -+#endif -+ int OldFd = fd; -+ fd = -1; -+ return close(OldFd); -+} -+ -+ -+#define FADVGRAN KILOBYTE(4) -+#define READCHUNK MEGABYTE(8) -+ -+int cUnbufferedFile64::FadviseDrop(off64_t Offset, off64_t Len) -+{ -+ return posix_fadvise64(fd, Offset - (FADVGRAN - 1), Len + (FADVGRAN - 1) * 2, POSIX_FADV_DONTNEED); -+} -+ -+ -+off64_t cUnbufferedFile64::Seek(off64_t Offset, int Whence) -+{ -+ if (Whence == SEEK_SET && Offset == curpos) -+ return curpos; -+ curpos = lseek64(fd, Offset, Whence); -+ return curpos; -+} -+ -+ssize_t cUnbufferedFile64::Read(void *Data, size_t Size) -+{ -+ if (fd >= 0) { -+#ifdef USE_FADVISE -+ off64_t jumped = curpos-lastpos; -+ if ((cachedstart < cachedend) && (curpos < cachedstart || curpos > cachedend)) { -+ FadviseDrop(cachedstart, cachedend-cachedstart); -+ cachedstart = curpos; -+ cachedend = curpos; -+ } -+ cachedstart = min(cachedstart, curpos); -+#endif -+ ssize_t bytesRead = safe_read(fd, Data, Size); -+#ifdef USE_FADVISE -+ if (bytesRead > 0) { -+ curpos += bytesRead; -+ cachedend = max(cachedend, curpos); -+ -+ if (jumped >= 0 && jumped <= (off64_t)readahead) { -+ if (ahead - curpos < (off64_t)(readahead / 2)) { -+ posix_fadvise64(fd, curpos, readahead, POSIX_FADV_WILLNEED); -+ ahead = curpos + readahead; -+ cachedend = max(cachedend, ahead); -+ } -+ if (readahead < Size * 32) { -+ readahead = Size * 32; -+ } -+ } -+ else -+ ahead = curpos; -+ } -+ -+ if (cachedstart < cachedend) { -+ if (curpos - cachedstart > READCHUNK * 2) { -+ FadviseDrop(cachedstart, curpos - READCHUNK - cachedstart); -+ cachedstart = curpos - READCHUNK; -+ } -+ else if (cachedend > ahead && cachedend - curpos > READCHUNK * 2) { -+ FadviseDrop(curpos + READCHUNK, cachedend - (curpos + READCHUNK)); -+ cachedend = curpos + READCHUNK; -+ } -+ } -+ lastpos = curpos; -+#endif -+ return bytesRead; -+ } -+ return -1; -+} -+ -+ssize_t cUnbufferedFile64::Write(const void *Data, size_t Size) -+{ -+ if (fd >=0) { -+ ssize_t bytesWritten = safe_write(fd, Data, Size); -+#ifdef USE_FADVISE -+ if (bytesWritten > 0) { -+ begin = min(begin, curpos); -+ curpos += bytesWritten; -+ written += bytesWritten; -+ lastpos = max(lastpos, curpos); -+ if (written > WRITE_BUFFER) { -+ if (lastpos > begin) { -+ off64_t headdrop = min(begin, (off64_t) WRITE_BUFFER * 2L); -+ posix_fadvise64(fd, begin - headdrop, lastpos - begin + headdrop, POSIX_FADV_DONTNEED); -+ } -+ begin = lastpos = curpos; -+ totwritten += written; -+ written = 0; -+ if (totwritten > MEGABYTE(32)) { -+ off64_t headdrop = min((off64_t) (curpos - totwritten), (off64_t) totwritten * 2L); -+ posix_fadvise64(fd, curpos - totwritten - headdrop, totwritten + headdrop, POSIX_FADV_DONTNEED); -+ totwritten = 0; -+ } -+ } -+ } -+#endif -+ return bytesWritten; -+ } -+ return -1; -+} -+ -+cUnbufferedFile64 *cUnbufferedFile64::Create(const char *FileName, int Flags, mode_t Mode) -+{ -+ cUnbufferedFile64 *File = new cUnbufferedFile64; -+ if (File->Open(FileName, Flags, Mode) < 0) { -+ delete File; -+ File = NULL; -+ } -+ return File; -+} -+ -+// --- cLiveIndex ------------------------------------------------------------ -+ -+cLiveIndex::cLiveIndex(int BufSize) -+{ -+ bufSize = BufSize; -+ headblock = tailblock = new block; -+ headblock->previous = headblock->next = headblock; -+ head = tail = 0; -+ blank = 0; -+ blockCount = 1; -+ writtenCount = delCount = 0; -+ lastWrittenSize = lastCount = 0; -+ fileSize = 0; -+ lastFrame = -1; -+ DPos = -1; -+ DCount = 0; -+ start = 0; -+ RwLock = new cRwLock(true); -+} -+ -+cLiveIndex::~cLiveIndex() -+{ -+ while (tailblock != headblock) { -+ block *n = tailblock->next; -+ delete tailblock; -+ tailblock = n; -+ } -+ delete headblock; -+ delete RwLock; -+} -+ -+void cLiveIndex::Add(uchar pt, int pos) -+{ -+ RwLock->Lock(true); -+ DCount=0; -+ DPos = pos; -+ headblock->Frame[head].offset = pos; -+ headblock->Frame[head].written = false; -+ headblock->Frame[head].pt = pt; -+ head++; -+ lastFrame++; -+ if (head == INDEXBLOCKSIZE) { -+ block* b = new block; -+ b->previous = headblock; -+ b->next = b; -+ headblock->next = b; -+ headblock = b; -+ head = 0; -+ blockCount++; -+ } -+ RwLock->Unlock(); -+} -+ -+void cLiveIndex::AddData(int pos) -+{ -+ RwLock->Lock(true); -+ DCount=pos-DPos; -+ RwLock->Unlock(); -+} -+ -+void cLiveIndex::Delete(off64_t FilePos) -+{ -+ RwLock->Lock(true); -+ if (tailblock->Frame[tail].offset <= FilePos) { -+ if (tailblock->Frame[tail].offset + MAXFRAMESIZE >= FilePos) { -+ int old_offset = tailblock->Frame[tail].offset; -+ while (tailblock->Frame[tail].written && tailblock->Frame[tail].offset < FilePos && tailblock->Frame[tail].offset >= old_offset) { -+ tail++; -+ delCount++; -+ if (tail == INDEXBLOCKSIZE) { -+ block *b = tailblock->next; -+ b->previous = b; -+ if (tailblock != headblock) -+ delete tailblock; -+ tailblock = b; -+ tail = 0; -+ blockCount--; -+ } -+ } -+ } -+ } -+ else { -+ if (tailblock->Frame[tail].offset - MAXFRAMESIZE > FilePos) { -+ int old_offset = tailblock->Frame[tail].offset; -+ while (tailblock->Frame[tail].written && (tailblock->Frame[tail].offset < FilePos || tailblock->Frame[tail].offset >= old_offset)) { -+ tail++; -+ delCount++; -+ if (tail == INDEXBLOCKSIZE) { -+ block *b = tailblock->next; -+ b->previous = b; -+ if (tailblock != headblock) -+ delete tailblock; -+ tailblock = b; -+ tail = 0; -+ blockCount--; -+ } -+ } -+ } -+ } -+ RwLock->Unlock(); -+} -+ -+int cLiveIndex::DelFirst(void) -+{ -+ RwLock->Lock(true); -+ tail++; -+ delCount++; -+ writtenCount++; -+ if (tail == INDEXBLOCKSIZE) { -+ block *b = tailblock->next; -+ b->previous = b; -+ if (tailblock != headblock) -+ delete tailblock; -+ tailblock = b; -+ tail = 0; -+ blockCount--; -+ } -+ int r = tailblock->Frame[tail].offset; -+ RwLock->Unlock(); -+ return r; -+} -+ -+void cLiveIndex::Clear(void) -+{ -+ RwLock->Lock(true); -+ while (tailblock != headblock) { -+ block *n = tailblock->next; -+ delete tailblock; -+ tailblock = n; -+ } -+ headblock->previous = headblock; -+ head = tail = blank = 0; -+ blockCount = 1; -+ writtenCount = delCount = 0; -+ DPos = -1; -+ DCount = 0; -+ start = 0; -+ lastFrame = -1; -+ lastWrittenSize = lastCount = 0; -+ fileSize = 0; -+ RwLock->Unlock(); -+} -+ -+int cLiveIndex::NextWrite(void) -+{ -+ RwLock->Lock(false); -+ block *b; -+ int i = GetFrame(&b,writtenCount); -+ int off = 0; -+ if (i+1 == INDEXBLOCKSIZE) -+ off = b->next->Frame[0].offset; -+ else -+ off = b->Frame[i+1].offset; -+ int r = 0; -+ if (off < b->Frame[i].offset) -+ r = bufSize - b->Frame[i].offset - blank; -+ else -+ r = off - b->Frame[i].offset; -+ RwLock->Unlock(); -+ return r; -+} -+ -+void cLiveIndex::WrittenTo(off64_t FilePos, int Count) -+{ -+ RwLock->Lock(true); -+ lastWrittenSize=Count; -+ block *b; -+ int i = GetFrame(&b, writtenCount); -+ writtenCount++; -+ if (FilePos == 0) { -+ if (i) -+ fileSize = b->Frame[i-1].offset + lastCount; -+ else if (b->previous != b) -+ fileSize = b->previous->Frame[INDEXBLOCKSIZE-1].offset + lastCount; -+ } -+ b->Frame[i].offset = FilePos; -+ b->Frame[i].written = true; -+ RwLock->Unlock(); -+ lastCount = Count; -+} -+ -+int cLiveIndex::GetFrame(block** Block, int Number) -+{ -+ int bc = 0; -+ int i = Number-delCount; -+ if (INDEXBLOCKSIZE-tail <= i) -+ bc = 1 + (i-INDEXBLOCKSIZE+tail)/INDEXBLOCKSIZE; -+ i-= bc*INDEXBLOCKSIZE-tail; -+ block *b = tailblock; -+ for (int j=0; j<bc; j++) -+ b = b->next; -+ *Block = b; -+ return i; -+} -+ -+off64_t cLiveIndex::GetOffset(int Number) -+{ -+ RwLock->Lock(false); -+ off64_t r = -1; -+ if (HasFrame(Number)) { -+ block *b; -+ int i = GetFrame(&b, Number); -+ r = b->Frame[i].offset; -+ } -+ else if (HasFrame(Number-1)) -+ r = DPos; -+ RwLock->Unlock(); -+ return r; -+} -+ -+int cLiveIndex::Size(int Number, uchar *PictureType) -+{ -+ int r = -1; -+ RwLock->Lock(false); -+ if (HasFrame(Number)) { -+ if (Number+1 == writtenCount) -+ r = lastWrittenSize; -+ else { -+ block *b; -+ int i = GetFrame(&b, Number); -+ if (PictureType) -+ *PictureType = b->Frame[i].pt; -+ off64_t off = 0; -+ if (i+1 == INDEXBLOCKSIZE) -+ off = b->next->Frame[0].offset; -+ else -+ off = b->Frame[i+1].offset; -+ if (off < b->Frame[i].offset) { -+ if (b->Frame[i].written) -+ r = fileSize - b->Frame[i].offset; -+ else -+ r = bufSize - b->Frame[i].offset - blank; -+ } -+ else -+ r = off - b->Frame[i].offset; -+ } -+ } -+ else if (HasFrame(Number-1) && DPos >= 0) -+ r = DCount; -+ RwLock->Unlock(); -+ return r; -+} -+ -+int cLiveIndex::GetNextIFrame(int Index, bool Forward) -+{ -+ int d = Forward ? 1 : -1; -+ Index += d; -+ while (Index >= delCount && Index < lastFrame) { -+ block *b; -+ RwLock->Lock(false); -+ int i = GetFrame(&b, Index); -+ uchar type = b->Frame[i].pt; -+ RwLock->Unlock(); -+ if (type == I_FRAME) -+ return Index; -+ Index +=d; -+ } -+ return -1; -+} -+ -+int cLiveIndex::FindIFrame(int64_t PTS, uchar *Buffer) -+{ -+ int r = -1; -+ RwLock->Lock(false); -+ int Index=writtenCount; -+ int64_t pts=0; -+ do { -+ Index = GetNextIFrame(Index, true); -+ if (Index < 0) -+ break; -+ block *b; -+ int i = GetFrame(&b, Index); -+ uchar *p = &Buffer[b->Frame[i].offset]; -+ if (p[0]==0x00 && p[1]==0x00 && p[2]==0x01 && (p[7] & 0x80) && p[3]>=0xC0 && p[3]<=0xEF) { -+ pts = (int64_t) (p[ 9] & 0x0E) << 29 ; -+ pts |= (int64_t) p[ 10] << 22 ; -+ pts |= (int64_t) (p[ 11] & 0xFE) << 14 ; -+ pts |= (int64_t) p[ 12] << 7 ; -+ pts |= (int64_t) (p[ 13] & 0xFE) >> 1 ; -+ } -+ } while (pts!=PTS); -+ if (pts==PTS) -+ r = Index; -+ RwLock->Unlock(); -+ return r; -+} -+ -+void cLiveIndex::Switched(void) -+{ -+ start = Last(); -+} -+ -+// --- cLiveFileReader ------------------------------------------------------- -+ -+cLiveFileReader::cLiveFileReader(const char *FileName, int Number) -+{ -+ fileName = new cFileName64(FileName, false); -+ fileName->SetNumber(Number); -+ readFile = fileName->Open(); -+ buffer = NULL; -+ filePos = 0; -+ Start(); -+} -+ -+cLiveFileReader::~cLiveFileReader() -+{ -+ Cancel(3); -+ delete fileName; -+} -+ -+void cLiveFileReader::Action(void) -+{ -+ while (Running()) { -+ Lock(); -+ if (buffer && !hasData) { -+ int r = readFile->Read(buffer + length, wanted - length); -+ if (r >= 0) { -+ length += r; -+ filePos += r; -+ if (length == wanted) -+ hasData = true; -+ } -+ else if (r < 0 && FATALERRNO) { -+ LOG_ERROR; -+ length = r; -+ hasData = true; -+ } -+ } -+ Unlock(); -+ newSet.Wait(1000); -+ } -+} -+ -+int cLiveFileReader::Read(uchar **Buffer, off64_t FilePos, int Size) -+{ -+ if (buffer && hasData) { -+ *Buffer = buffer; -+ buffer = NULL; -+ return length; -+ } -+ if (!buffer) { -+ uchar *b = MALLOC(uchar, Size); -+ if (filePos != FilePos) { -+ filePos = FilePos; -+ readFile->Seek(FilePos,0); -+ } -+ wanted = Size; -+ length = 0; -+ hasData = false; -+ buffer = b; -+ newSet.Signal(); -+ } -+ return -1; -+} -+ -+void cLiveFileReader::Clear(void) -+{ -+ Lock(); -+ delete buffer; -+ buffer = NULL; -+ Unlock(); -+} -+ -+// --- cLiveFileWriter ------------------------------------------------------- -+ -+cLiveFileWriter::cLiveFileWriter(const char *FileName) -+{ -+ MakeDirs(FileName, true); -+ SpinUpDisk(FileName); -+ fileName = new cFileName64(FileName, true); -+ writeFile = fileName->Open(); -+ buffer = NULL; -+ filePos = fileSize = 0; -+ lastCheck = time(NULL); -+ full = false; -+ Start(); -+} -+ -+cLiveFileWriter::~cLiveFileWriter() -+{ -+ Cancel(3); -+ fileName->CloseAndRemove(); -+ delete fileName; -+} -+ -+void cLiveFileWriter::Action(void) -+{ -+ while (Running()) { -+ Lock(); -+ if (buffer && !hasWritten) { -+ int r = writeFile->Write(buffer, wantWrite); -+ if (r >= 0) { -+ filePos += r; -+ hasWritten = true; -+ } -+ else if (r < 0 && FATALERRNO) { -+ LOG_ERROR; -+ hasWritten = true; -+ } -+ } -+ Unlock(); -+ newSet.Wait(1000); -+ } -+} -+ -+#define MINFREE 600 -+ -+bool cLiveFileWriter::LowDiskSpace() -+{ -+ if (!full && time (NULL) > lastCheck + 60 || full && filePos >= fileSize) { -+ int Free = FreeDiskSpaceMB(fileName->Name()); -+ lastCheck = time(NULL); -+ if (Free < MINFREE) -+ return true; -+ } -+ return false; -+} -+ -+off64_t cLiveFileWriter::Write(uchar *Buffer, int Size, bool Wait) -+{ -+ if (buffer && hasWritten) { -+ buffer = NULL; -+ return filePos; -+ } -+ if (!buffer) { -+ if (filePos + Size > (off64_t)Setup.LiveBufferSize*1024*1024 || LowDiskSpace()) { -+ fileSize = filePos > fileSize ? filePos : fileSize; -+ filePos = 0; -+ writeFile->Seek(0,0); -+ full = true; -+ } -+ if (Wait) { -+ writeFile->Write(Buffer, Size); -+ filePos += Size; -+ return filePos; -+ } -+ else { -+ wantWrite = Size; -+ hasWritten = false; -+ buffer = Buffer; -+ newSet.Signal(); -+ } -+ } -+ if (Wait) { -+ while (!hasWritten) -+ usleep(5); -+ buffer = NULL; -+ return filePos; -+ } -+ return -1; -+} -+ -+void cLiveFileWriter::Clear(void) -+{ -+ Lock(); -+ buffer = NULL; -+ filePos = 0; -+ full = false; -+ writeFile->Seek(0,0); -+ Unlock(); -+} -+ -+// --- cLiveCutterThread ----------------------------------------------------- -+ -+cLiveCutterThread::cLiveCutterThread(const char *FileName, int FileNumber, cLiveBuffer *LiveBuffer, int StartFrame, int EndFrame) -+{ -+ readFile = NULL; -+ -+ writeFileName = new cFileName64(FileName, true); -+ writeFileName->SetNumber(FileNumber); -+ writeFile = writeFileName->Open(); -+ -+ liveBuffer = LiveBuffer; -+ startFrame = StartFrame; -+ endFrame = EndFrame; -+ Start(); -+} -+ -+cLiveCutterThread::~cLiveCutterThread() -+{ -+ Cancel(3); -+ if (readFile) -+ readFileName->Close(); -+ writeFileName->Close(); -+} -+ -+void cLiveCutterThread::Action(void) -+{ -+ int Frame = startFrame; -+ int readPos = 0; -+ int writePos = 0; -+ while (Running() && Frame < endFrame) { -+ uchar pt; -+ liveBuffer->index->RwLock->Lock(false); -+ int size = liveBuffer->index->Size(Frame, &pt); -+ if (pt == I_FRAME && writePos > MEGABYTE(Setup.MaxVideoFileSize)) { -+ int Number = writeFileName->Number(); -+ writeFileName->Close(); -+ writeFileName->SetNumber(Number+1); -+ writeFile = writeFileName->Open(); -+ writePos = 0; -+ } -+ if (liveBuffer->index->IsWritten(Frame)) { -+ if (!readFile) { -+ readFileName = new cFileName64(liveBuffer->filestring, false); -+ readFileName->SetNumber(liveBuffer->fileWriter->FileNumber()); -+ readFile = readFileName->Open(); -+ } -+ uchar b[MAXFRAMESIZE]; -+ if (liveBuffer->index->GetOffset(Frame) != readPos) { -+ readPos = liveBuffer->index->GetOffset(Frame); -+ readFile->Seek(readPos,0); -+ } -+ int c = readFile->Read(b, size); -+ readPos += c; -+ writeFile->Write(b,c); -+ writePos+=size; -+ if (c != size) -+ writeFile->Seek(writePos,0); -+ } -+ else { -+ writeFile->Write(&liveBuffer->buffer[liveBuffer->index->GetOffset(Frame)], size); -+ writePos+=size; -+ } -+ liveBuffer->index->RwLock->Unlock(); -+ Frame++; -+ cCondWait::SleepMs(5); -+ } -+ if (readFile) -+ readFileName->Close(); -+ writeFileName->Close(); -+} -+ -+// --- cLiveBuffer ----------------------------------------------------------- -+ -+cLiveBuffer::cLiveBuffer(const char *FileName, cRemux *Remux, const cChannel *Channel, int Number) -+:cThread("livebuffer") -+{ -+ number = Number; -+ bufSize = (Setup.InRAM && Number == 0) ? MEGABYTE(Setup.MemBufSize) : LIVEBUFSIZE; -+ buffer = MALLOC(uchar, bufSize); -+ writeHD = !(Setup.InRAM && Number == 0); -+ lastRead = 0; -+ if (!buffer) { -+ dsyslog("Couldn't reserve memory for livebuffer\n"); -+ bufSize = LIVEBUFSIZE; -+ buffer = MALLOC(uchar, bufSize); -+ } -+ channel = Channel; -+ index = new cLiveIndex(bufSize); -+ remux = Remux; -+ filestring = strdup(FileName); -+ head = tail = blank = 0; -+ startFrame = -1; -+ liveCutter = NULL; -+ fileWriter = NULL; -+ fileReader = NULL; -+ if (writeHD) { -+ fileWriter = new cLiveFileWriter(FileName); -+ fileReader = new cLiveFileReader(FileName, fileWriter->FileNumber()); -+ } -+ status = 0; -+ Start(); -+} -+ -+cLiveBuffer::~cLiveBuffer() -+{ -+ Cancel(3); -+ delete liveCutter; -+ delete fileReader; -+ delete index; -+ delete fileWriter; -+ free(filestring); -+ free(buffer); -+} -+ -+void cLiveBuffer::SetStatus(int s) -+{ -+ if (s == -1 || status != 2 && s == 0) -+ status = 0; -+ if (status == 0 && s == 1) -+ status = 1; -+ if (s == 2) -+ status = 2; -+ if (s == -2 && status == 0) -+ status = -1; -+} -+ -+void cLiveBuffer::Write(bool Wait) -+{ -+ int wcount = index->NextWrite(); -+ off64_t pos=fileWriter->Write(&buffer[tail], wcount, Wait); -+ if (pos>=0) { -+ index->WrittenTo(pos-wcount, wcount); -+ tail += wcount; -+ if (tail + MAXFRAMESIZE > bufSize) { -+ tail = 0; -+ blank = 0; -+ index->SetBlank(blank); -+ } -+ if (fileWriter->Full()) -+ index->Delete(pos); -+ } -+} -+ -+void cLiveBuffer::Store(uchar *Data, int Count) -+{ -+ -+ if (pictureType != NO_PICTURE) { -+ if (head + MAXFRAMESIZE > bufSize) { -+ blank = bufSize - head; -+ head = 0; -+ index->SetBlank(blank); -+ } -+ index->Add(pictureType,head); -+ } -+ else -+ index->AddData(head); -+ memcpy(&buffer[head], Data, Count); -+ head += Count; -+ -+ int free = head >= tail ? max(tail,bufSize-head) : tail - head; -+ -+ while (free < MAXFRAMESIZE) { -+ if (writeHD) -+ Write(true); -+ else { -+ tail = index->DelFirst(); -+ if (tail == 0) { -+ blank = 0; -+ index->SetBlank(blank); -+ } -+ if (Setup.ExtendBuffer && lastRead < index->delCount+25 && status >= 0) { -+ writeHD = true; -+ fileWriter = new cLiveFileWriter(filestring); -+ fileReader = new cLiveFileReader(filestring, fileWriter->FileNumber()); -+ } -+ } -+ free = head >= tail ? max(tail,bufSize-head) : tail - head; -+ } -+} -+ -+void cLiveBuffer::Action(void) -+{ -+ while (Running()) { -+ int Count; -+ Lock(); -+ uchar *p = remux->Get(Count, &pictureType); -+ if (p) { -+ Store(p,Count); -+ remux->Del(Count); -+ } -+ Unlock(); -+ if (writeHD) { -+ int free = head >= tail ? max(tail,bufSize-head) : tail - head; -+ if (free < 2*MAXFRAMESIZE) -+ Write(false); -+ } -+ } -+ -+} -+ -+void cLiveBuffer::SetNewRemux(cRemux *Remux, const cChannel *Channel) -+{ -+ if (Channel != channel) { -+ index->Switched(); -+ } -+ channel = Channel; -+ if (!Remux) { -+ Cancel(3); -+ return; -+ } -+ if (fileReader) fileReader->Clear(); -+ if (!Running() && Remux) { -+ remux = Remux; -+ Start(); -+ } -+ else { -+ Cancel(-1); -+ Lock(); -+ if (writeHD && Setup.InRAM && number == 0 && !status) { -+ index->Clear(); -+ delete fileReader; fileReader = NULL; -+ delete fileWriter; fileWriter = NULL; -+ writeHD = false; -+ } -+ remux = Remux; -+ Unlock(); -+ Start(); -+ } -+} -+ -+int cLiveBuffer::GetFrame(uchar **Buffer, int Number, int Off) -+{ -+ if (!Buffer) { -+ if (fileReader) fileReader->Clear(); -+ return -1; -+ } -+ if (Number < FirstIndex()) -+ return -2; -+ if (!index->HasFrame(Number) && (Off < 0 || !index->HasFrame(Number-1))) -+ return -1; -+ lastRead = Number; -+ if (!index->IsWritten(Number)) { -+ index->RwLock->Lock(false); -+ int size=index->Size(Number); -+ int off = index->GetOffset(Number); -+ if (off >= 0) { -+ if (Off>=0) { -+ size -= Off; -+ off += Off; -+ } -+ if (size > 0) { -+ uchar *b = MALLOC(uchar, size); -+ *Buffer = b; -+ memcpy(b,&buffer[off],size); -+ } -+ if (!index->HasFrame(Number)) -+ size = -size; -+ } -+ else -+ size = -1; -+ index->RwLock->Unlock(); -+ return size; -+ } -+ else -+ return fileReader->Read(Buffer,index->GetOffset(Number),index->Size(Number)); -+ return -1; -+} -+ -+void cLiveBuffer::CreateIndexFile(const char *FileName, int64_t PTS, int EndFrame) -+{ -+ if (liveCutter) { -+ if (liveCutter->Active()) { -+ startFrame = -1; -+ return; -+ } -+ else { -+ delete liveCutter; -+ liveCutter = NULL; -+ } -+ } -+ if (startFrame < 0) -+ return; -+ cIndexFile *indexFile = new cIndexFile(FileName, true); -+ if (!indexFile) -+ return; -+ int endFrame = EndFrame ? EndFrame : index->FindIFrame(PTS, buffer); -+ int timeout = 0; -+ while (endFrame < 0 && timeout < 50) { -+ cCondWait::SleepMs(100); -+ endFrame = index->FindIFrame(PTS, buffer); -+ timeout++; -+ } -+ -+ char *data="LiveBuffer"; -+ cFileName fileName(FileName, true); -+ cUnbufferedFile *file = fileName.Open(); -+ file->Write(data,10); -+ int Number = fileName.Number(); -+ int FileOffset=0; -+ for (int Frame = startFrame; Frame < endFrame; Frame++) { -+ uchar pt; -+ int size = index->Size(Frame, &pt); -+ if (pt == I_FRAME && FileOffset > MEGABYTE(Setup.MaxVideoFileSize)) { -+ file = fileName.NextFile(); -+ file->Write(data,10); -+ FileOffset=0; -+ } -+ indexFile->Write(pt,fileName.Number(),FileOffset); -+ FileOffset+=size; -+ } -+ liveCutter = new cLiveCutterThread(FileName,Number,this,startFrame,endFrame); -+ startFrame = -1; -+ delete indexFile; -+} -+ -+// --- cLiveReceiver --------------------------------------------------------- -+ -+cLiveReceiver::cLiveReceiver(const cChannel *Channel) -+:cReceiver(Channel->GetChannelID(), -1, Channel->Vpid(), Channel->Apids(), Setup.UseDolbyDigital ? Channel->Dpids() : NULL, Channel->Spids()) -+{ -+ channel = Channel; -+ vpid = Channel->Vpid(); -+ for (int i = 0; i < MAXAPIDS; i++) -+ apids[i]=Channel->Apid(i); -+ for (int i = 0; i < MAXDPIDS; i++) -+ dpids[i]= Setup.UseDolbyDigital ? Channel->Dpid(i) : 0; -+ for (int i = 0; i < MAXSPIDS; i++) -+ spids[i]=Channel->Spid(i); -+ ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, TS_SIZE * 2, true, "Recorder"); -+ ringBuffer->SetTimeouts(0, 20); -+ remux = new cRemux(Channel->Vpid(), Channel->Apids(), Setup.UseDolbyDigital ? Channel->Dpids() : NULL, Channel->Spids()); -+ remux->SetTimeouts(0, 50); -+ attached = false; -+} -+ -+cLiveReceiver::~cLiveReceiver() -+{ -+ Detach(); -+ Cancel(3); -+ delete remux; -+ delete ringBuffer; -+} -+ -+void cLiveReceiver::Activate(bool On) -+{ -+ if (On) { -+ Start(); -+ attached = true; -+ } -+ else { -+ Cancel(-1); -+ attached = false; -+ } -+} -+ -+void cLiveReceiver::Receive(uchar *Data, int Length) -+{ -+ int p = ringBuffer->Put(Data, Length); -+ if (p != Length && Running()) -+ ringBuffer->ReportOverflow(Length - p); -+} -+ -+void cLiveReceiver::Action(void) -+{ -+ while (Running()) { -+ int r; -+ uchar *b = ringBuffer->Get(r); -+ if (b) { -+ int Count = remux->Put(b, r); -+ if (Count) -+ ringBuffer->Del(Count); -+ else -+ cCondWait::SleepMs(20); -+ } -+ } -+} -+ -+bool cLiveReceiver::IsReceiving(const cChannel *Channel) -+{ -+ if (vpid != Channel->Vpid()) -+ return false; -+ for (int i = 0; i < MAXAPIDS; i++) -+ if (apids[i] != Channel->Apid(i)) -+ return false; -+ for (int i = 0; i < MAXDPIDS && Setup.UseDolbyDigital; i++) -+ if (dpids[i] != Channel->Dpid(i)) -+ return false; -+ for (int i = 0; i < MAXSPIDS; i++) -+ if (spids[i] != Channel->Spid(i)) -+ return false; -+ -+ return true; -+} -+ -+// --- cLiveBackTrace -------------------------------------------------------- -+ -+#define AVG_FRAME_SIZE 15000 -+#define DVB_BUF_SIZE (256 * 1024) -+#define BACKTRACE_ENTRIES (DVB_BUF_SIZE / AVG_FRAME_SIZE + 20) -+ -+class cLiveBackTrace { -+private: -+ int index[BACKTRACE_ENTRIES]; -+ int length[BACKTRACE_ENTRIES]; -+ int pos, num; -+public: -+ cLiveBackTrace(void); -+ void Clear(void); -+ void Add(int Index, int Length); -+ int Get(bool Forward); -+ }; -+ -+cLiveBackTrace::cLiveBackTrace(void) -+{ -+ Clear(); -+} -+ -+void cLiveBackTrace::Clear(void) -+{ -+ pos = num = 0; -+} -+ -+void cLiveBackTrace::Add(int Index, int Length) -+{ -+ index[pos] = Index; -+ length[pos] = Length; -+ if (++pos >= BACKTRACE_ENTRIES) -+ pos = 0; -+ if (num < BACKTRACE_ENTRIES) -+ num++; -+} -+ -+int cLiveBackTrace::Get(bool Forward) -+{ -+ int p = pos; -+ int n = num; -+ int l = DVB_BUF_SIZE + (Forward ? 0 : 256 * 1024); -+ int i = -1; -+ -+ while (n && l > 0) { -+ if (--p < 0) -+ p = BACKTRACE_ENTRIES - 1; -+ i = index[p] - 1; -+ l -= length[p]; -+ n--; -+ } -+ return i; -+} -+ -+// --- cLivePlayer ----------------------------------------------------------- -+ -+#define PLAYERBUFSIZE MEGABYTE(1) -+ -+#define MAX_VIDEO_SLOWMOTION 63 -+#define NORMAL_SPEED 4 -+#define MAX_SPEEDS 3 -+#define SPEED_MULT 12 -+int cLivePlayer::Speeds[] = { 0, -2, -4, -8, 1, 2, 4, 12, 0 }; -+ -+cLivePlayer::cLivePlayer(cLiveBuffer *LiveBuffer) -+:cThread("liveplayer") -+{ -+ liveBuffer = LiveBuffer; -+ ringBuffer = new cRingBufferFrame(PLAYERBUFSIZE); -+ readIndex = writeIndex = -1; -+ readFrame = playFrame = NULL; -+ firstPacket = true; -+ playMode = pmPlay; -+ playDir = pdForward; -+ trickSpeed = NORMAL_SPEED; -+ Off = 0; -+ backTrace = new cLiveBackTrace; -+ liveBuffer->SetStatus(0); -+} -+ -+cLivePlayer::~cLivePlayer() -+{ -+ liveBuffer->SetStatus(-2); -+ Detach(); -+ Cancel(3); -+ liveBuffer->GetFrame(NULL,0); -+ delete readFrame; -+ delete backTrace; -+ delete ringBuffer; -+} -+ -+void cLivePlayer::TrickSpeed(int Increment) -+{ -+ int nts = trickSpeed + Increment; -+ if (Speeds[nts] == 1) { -+ trickSpeed = nts; -+ if (playMode == pmFast) -+ Play(); -+ else -+ Pause(); -+ } -+ else if (Speeds[nts]) { -+ trickSpeed = nts; -+ int Mult = (playMode == pmSlow && playDir == pdForward) ? 1 : SPEED_MULT; -+ int sp = (Speeds[nts] > 0) ? Mult / Speeds[nts] : -Speeds[nts] * Mult; -+ if (sp > MAX_VIDEO_SLOWMOTION) -+ sp = MAX_VIDEO_SLOWMOTION; -+ DeviceTrickSpeed(sp); -+ } -+} -+ -+void cLivePlayer::Empty(void) -+{ -+ LOCK_THREAD; -+ liveBuffer->GetFrame(NULL,0); -+ if ((readIndex = backTrace->Get(playDir == pdForward)) < 0) -+ readIndex = writeIndex; -+ delete readFrame; -+ readFrame = NULL; -+ playFrame = NULL; -+ ringBuffer->Clear(); -+ DeviceClear(); -+ backTrace->Clear(); -+ firstPacket = true; -+ Off = 0; -+} -+ -+void cLivePlayer::Activate(bool On) -+{ -+ if (On) -+ Start(); -+ else -+ Cancel(-1); -+} -+ -+void cLivePlayer::Action(void) -+{ -+ int PollTimeouts = 0; -+ uchar *b = NULL; -+ uchar **pb = &b; -+ uchar *p = NULL; -+ int pc = 0; -+ -+ if (liveBuffer->Stay()) -+ readIndex = liveBuffer->LastRead(); -+ else -+ readIndex = liveBuffer->LastIndex(); -+ -+ bool Sleep = false; -+ bool WaitingForData = false; -+ -+ while (Running()) { -+ if (Sleep) { -+ if (WaitingForData) -+ cCondWait::SleepMs(3); -+ else -+ cCondWait::SleepMs(3); -+ Sleep = false; -+ } -+ -+ cPoller Poller; -+ if (!DevicePoll(Poller, 100)) { -+ PollTimeouts++; -+ continue; -+ } -+ else -+ PollTimeouts = 0; -+ -+ if (PollTimeouts >= 6) { -+ DeviceClear(); -+ PlayPes(NULL, 0); -+ } -+ -+ LOCK_THREAD; -+ -+ if (playMode != pmStill && playMode != pmPause) { -+ if (!readFrame) { -+ if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) { -+ int Index = liveBuffer->GetNextIFrame(readIndex, playDir == pdForward); -+ if (Index < 0) { -+ if (!DeviceFlush(100)) -+ continue; -+ DevicePlay(); -+ playMode = pmPlay; -+ playDir = pdForward; -+ continue; -+ } -+ int r = liveBuffer->GetFrame(pb, Index); -+ if (r>0) { -+ readIndex = Index; -+ WaitingForData = false; -+ readFrame = new cFrame(b, -r, ftUnknown, readIndex); -+ b = NULL; -+ } -+ else -+ WaitingForData = true; -+ } -+ else { -+ int r=liveBuffer->GetFrame(pb, readIndex+1, Off); -+ if (r>0) -+ readIndex++; -+ if (r > 0 || r < -10) { -+ WaitingForData = false; -+ readFrame = new cFrame(b, -abs(r), ftUnknown, readIndex); -+ b = NULL; -+ if (r<0) -+ Off += -r; -+ else -+ Off = 0; -+ } -+ else if (r==-2) -+ readIndex = liveBuffer->GetNextIFrame(liveBuffer->FirstIndex(), true)-1; -+ else -+ WaitingForData = true; -+ } -+ } -+ if (readFrame) { -+ if (ringBuffer->Put(readFrame)) -+ readFrame = NULL; -+ } -+ } -+ else -+ Sleep = true; -+ if (!playFrame) { -+ playFrame = ringBuffer->Get(); -+ p = NULL; -+ pc = 0; -+ } -+ if (playFrame) { -+ if (!p) { -+ p = playFrame->Data(); -+ pc = playFrame->Count(); -+ if (p) { -+ if (firstPacket) { -+ PlayPes(NULL, 0); -+ cRemux::SetBrokenLink(p, pc); -+ firstPacket = false; -+ } -+ } -+ } -+ if (p) { -+ int w = PlayPes(p, pc, playMode != pmPlay); -+ if (w > 0) { -+ p += w; -+ pc -= w; -+ } -+ else { -+ if (w < 0 && FATALERRNO) { -+ LOG_ERROR; -+ break; -+ } -+ } -+ } -+ if (pc == 0) { -+ writeIndex = playFrame->Index(); -+ backTrace->Add(playFrame->Index(), playFrame->Count()); -+ ringBuffer->Drop(playFrame); -+ playFrame = NULL; -+ p = NULL; -+ } -+ } -+ else -+ Sleep = true; -+ } -+} -+ -+void cLivePlayer::Pause(void) -+{ -+ if (playMode == pmPause || playMode == pmStill) -+ Play(); -+ else { -+ liveBuffer->SetStatus(1); -+ LOCK_THREAD; -+ if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) -+ Empty(); -+ DeviceFreeze(); -+ playMode = pmPause; -+ } -+} -+ -+void cLivePlayer::Play(void) -+{ -+ if (playMode != pmPlay) { -+ liveBuffer->SetStatus(0); -+ LOCK_THREAD; -+ if (playMode == pmStill || playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) -+ Empty(); -+ DevicePlay(); -+ playMode = pmPlay; -+ playDir = pdForward; -+ } -+} -+ -+void cLivePlayer::Forward(void) -+{ -+ switch (playMode) { -+ case pmFast: -+ if (Setup.MultiSpeedMode) { -+ TrickSpeed(playDir == pdForward ? 1 : -1); -+ break; -+ } -+ else if (playDir == pdForward) { -+ Play(); -+ break; -+ } -+ case pmPlay: { -+ LOCK_THREAD; -+ Empty(); -+ DeviceMute(); -+ playMode = pmFast; -+ playDir = pdForward; -+ trickSpeed = NORMAL_SPEED; -+ TrickSpeed(Setup.MultiSpeedMode ? 1 : MAX_SPEEDS); -+ } -+ break; -+ case pmSlow: -+ if (Setup.MultiSpeedMode) { -+ TrickSpeed(playDir == pdForward ? -1 : 1); -+ break; -+ } -+ else if (playDir == pdForward) { -+ Pause(); -+ break; -+ } -+ case pmStill: -+ case pmPause: -+ DeviceMute(); -+ playMode = pmSlow; -+ playDir = pdForward; -+ trickSpeed = NORMAL_SPEED; -+ TrickSpeed(Setup.MultiSpeedMode ? -1 : -MAX_SPEEDS); -+ break; -+ } -+} -+ -+void cLivePlayer::Backward(void) -+{ -+ switch (playMode) { -+ case pmFast: -+ if (Setup.MultiSpeedMode) { -+ TrickSpeed(playDir == pdBackward ? 1 : -1); -+ break; -+ } -+ else if (playDir == pdBackward) { -+ Play(); -+ break; -+ } -+ case pmPlay: { -+ LOCK_THREAD; -+ Empty(); -+ DeviceMute(); -+ playMode = pmFast; -+ playDir = pdBackward; -+ trickSpeed = NORMAL_SPEED; -+ TrickSpeed(Setup.MultiSpeedMode ? 1 : MAX_SPEEDS); -+ } -+ break; -+ case pmSlow: -+ if (Setup.MultiSpeedMode) { -+ TrickSpeed(playDir == pdBackward ? -1 : 1); -+ break; -+ } -+ else if (playDir == pdBackward) { -+ Pause(); -+ break; -+ } -+ case pmStill: -+ case pmPause: { -+ LOCK_THREAD; -+ Empty(); -+ DeviceMute(); -+ playMode = pmSlow; -+ playDir = pdBackward; -+ trickSpeed = NORMAL_SPEED; -+ TrickSpeed(Setup.MultiSpeedMode ? -1 : -MAX_SPEEDS); -+ } -+ break; -+ } -+} -+ -+bool cLivePlayer::Stop(void) -+{ -+ liveBuffer->SetStatus(-1); -+ if (readIndex >= liveBuffer->LastIndex() - 25) -+ return false; -+ LOCK_THREAD; -+ Empty(); -+ readIndex = writeIndex = liveBuffer->GetNextIFrame(liveBuffer->LastIndex()-1, false)-1; -+ Play(); -+ return true; -+} -+ -+void cLivePlayer::SkipSeconds(int Seconds) -+{ -+ if (Seconds) { -+ LOCK_THREAD; -+ Empty(); -+ int Index = writeIndex; -+ if (Index >= 0) { -+ Index = max(Index + Seconds * FRAMESPERSEC, liveBuffer->FirstIndex()); -+ if (Index > liveBuffer->FirstIndex()) -+ Index = liveBuffer->GetNextIFrame(Index, false); -+ if (Index >= 0) -+ readIndex = writeIndex = Index - 1; -+ } -+ Play(); -+ } -+} -+ -+bool cLivePlayer::GetIndex(int &Current, int &Total, bool SnapToIFrame) -+{ -+ if (liveBuffer) { -+ if (playMode == pmStill) -+ Current = max(readIndex, 0); -+ else { -+ Current = max(writeIndex, 0); -+ // TODO SnapToIFrame -+ } -+ Total = liveBuffer->LastIndex() - liveBuffer->FirstIndex(); -+ Current -= liveBuffer->FirstIndex(); -+ return true; -+ } -+ Current = Total = -1; -+ return false; -+} -+ -+bool cLivePlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed) -+{ -+ Play = (playMode == pmPlay || playMode == pmFast); -+ Forward = (playDir == pdForward); -+ if (playMode == pmFast || playMode == pmSlow) -+ Speed = Setup.MultiSpeedMode ? abs(trickSpeed - NORMAL_SPEED) : 0 ; -+ else -+ Speed = -1; -+ return true; -+} -+ -+// --- cLiveBufferControl ---------------------------------------------------- -+ -+cLiveBufferControl::cLiveBufferControl(cLivePlayer *Player) -+:cControl(Player, true) -+{ -+ player = Player; -+ displayReplay = NULL; -+ visible = modeOnly = shown = false; -+ lastCurrent = lastTotal = -1; -+ lastPlay = lastForward = false; -+ lastSpeed = -2; -+ timeoutShow = 0; -+} -+ -+cLiveBufferControl::~cLiveBufferControl() -+{ -+ Hide(); -+ cTransferControl::receiverDevice = NULL; -+ cLiveBufferManager::livePlayer = NULL; -+ delete player; -+ cLiveBufferManager::liveControl = NULL; -+ if (!Setup.LiveBuffer) -+ cLiveBufferManager::Shutdown(); -+} -+ -+bool cLiveBufferControl::GetIndex(int &Current, int &Total, bool SnapToIFrame) -+{ -+ if (player) { -+ player->GetIndex(Current, Total, SnapToIFrame); -+ return true; -+ } -+ return false; -+ -+} -+ -+bool cLiveBufferControl::GetReplayMode(bool &Play, bool &Forward, int &Speed) -+{ -+ return player && player->GetReplayMode(Play, Forward, Speed); -+} -+ -+void cLiveBufferControl::ShowTimed(int Seconds) -+{ -+ if (modeOnly) -+ Hide(); -+ if (!visible) { -+ shown = ShowProgress(true); -+ timeoutShow = (shown && Seconds > 0) ? time(NULL) + Seconds : 0; -+ } -+} -+ -+void cLiveBufferControl::Show(void) -+{ -+ ShowTimed(); -+} -+ -+void cLiveBufferControl::Hide(void) -+{ -+ if (visible) { -+ delete displayReplay; -+ displayReplay = NULL; -+ SetNeedsFastResponse(false); -+ visible = false; -+ modeOnly = false; -+ lastPlay = lastForward = false; -+ lastSpeed = -2; // an invalid value -+// timeSearchActive = false; -+ } -+} -+ -+void cLiveBufferControl::ShowMode(void) -+{ -+ if (visible || Setup.ShowReplayMode && !cOsd::IsOpen()) { -+ bool Play, Forward; -+ int Speed; -+ if (GetReplayMode(Play, Forward, Speed) && (!visible || Play != lastPlay || Forward != lastForward || Speed != lastSpeed)) { -+ bool NormalPlay = (Play && Speed == -1); -+ -+ if (!visible) { -+ if (NormalPlay) -+ return; -+ visible = modeOnly = true; -+ displayReplay = Skins.Current()->DisplayReplay(modeOnly); -+ } -+ -+ if (modeOnly && !timeoutShow && NormalPlay) -+ timeoutShow = time(NULL) + 3; -+ displayReplay->SetMode(Play, Forward, Speed); -+ lastPlay = Play; -+ lastForward = Forward; -+ lastSpeed = Speed; -+ } -+ } -+} -+ -+bool cLiveBufferControl::ShowProgress(bool Initial) -+{ -+ int Current, Total; -+ -+ if (GetIndex(Current, Total) && Total > 0) { -+ if (!visible) { -+ displayReplay = Skins.Current()->DisplayReplay(modeOnly); -+ SetNeedsFastResponse(true); -+ visible = true; -+ } -+ if (Initial) { -+ lastCurrent = lastTotal = -1; -+ } -+ if (Total != lastTotal) { -+ displayReplay->SetTotal(IndexToHMSF(Total)); -+ if (!Initial) -+ displayReplay->Flush(); -+ } -+ if (Current != lastCurrent || Total != lastTotal) { -+ displayReplay->SetProgress(Current, Total); -+ if (!Initial) -+ displayReplay->Flush(); -+int displayFrames = false; -+ displayReplay->SetCurrent(IndexToHMSF(Current, displayFrames)); -+ displayReplay->Flush(); -+ lastCurrent = Current; -+ } -+ lastTotal = Total; -+ ShowMode(); -+ return true; -+ } -+ return false; -+} -+ -+eOSState cLiveBufferControl::ProcessKey(eKeys Key) -+{ -+ if (visible) { -+ if (timeoutShow && time(NULL) > timeoutShow) { -+ Hide(); -+ ShowMode(); -+ timeoutShow = 0; -+ } -+ else if (modeOnly) -+ ShowMode(); -+ else -+ shown = ShowProgress(!shown) || shown; -+ } -+ bool DoShowMode = true; -+ switch (Key) { -+ case kDown: if (!visible || modeOnly) -+ return osUnknown; -+ case kPause: if (player) -+ player->Pause(); -+ break; -+ case kPlay: if (visible && !modeOnly) { -+ Hide(); -+ DoShowMode = true; -+ } -+ else -+ Show(); -+ case kUp: if (Key == kUp && (!visible || modeOnly)) -+ return osUnknown; -+ if (player) -+ player->Play(); -+ break; -+ case kLeft|k_Release: -+ if (!visible || modeOnly) -+ return osUnknown; -+ case kFastRew|k_Release: -+ if (Setup.MultiSpeedMode) break; -+ case kLeft: if (Key == kLeft && (!visible || modeOnly)) -+ return osUnknown; -+ case kFastRew: if (player) -+ player->Backward(); -+ break; -+ case kRight|k_Release: -+ if (!visible || modeOnly) -+ return osUnknown; -+ case kFastFwd|k_Release: -+ if (Setup.MultiSpeedMode) break; -+ case kRight: if (Key == kRight && (!visible || modeOnly)) -+ return osUnknown; -+ case kFastFwd: if (player) -+ player->Forward(); -+ break; -+ case kGreen|k_Repeat: -+ case kGreen: if (visible && !modeOnly && player) -+ player->SkipSeconds(-60); -+ else -+ return osUnknown; -+ break; -+ case kYellow|k_Repeat: -+ case kYellow: if (visible && !modeOnly && player) -+ player->SkipSeconds(60); -+ else -+ return osUnknown; -+ break; -+ default: { -+ DoShowMode = false; -+ switch (Key) { -+ case kStop: if (player) -+ if (player->Stop()) -+ break; -+ return osUnknown; -+ case kBack: if (visible && !modeOnly && player) -+ Hide(); -+ else -+ return osUnknown; -+ break; -+ case kRecord: { -+ cTimer *timer = new cTimer(true); -+ int Current, Total; -+ GetIndex(Current,Total); -+ time_t start = time(NULL) - (Total - Current) / FRAMESPERSEC; -+ time_t t = start; -+ struct tm tm_r; -+ struct tm *now = localtime_r(&t, &tm_r); -+ timer->start = now->tm_hour * 100 + now->tm_min; -+ timer->stop = now->tm_hour * 60 + now->tm_min + Setup.InstantRecordTime; -+ timer->stop = (timer->stop / 60) * 100 + (timer->stop % 60); -+ if (timer->stop >= 2400) -+ timer->stop -= 2400; -+ timer->day = cTimer::SetTime(start, 0); -+ timer->channel = Channels.GetByNumber(cDevice::CurrentChannel()); -+ Timers.Add(timer); -+ Timers.SetModified(); -+ if (cRecordControls::Start(timer)) -+ Skins.Message(mtInfo, tr("Recording started")); -+ break; -+ } -+ default: return osUnknown; -+ } -+ } -+ } -+ if (DoShowMode) -+ ShowMode(); -+ return osContinue; -+} -+ -+// --- cLiveBufferManager ---------------------------------------------------- -+ -+cLiveReceiver *cLiveBufferManager::liveReceiver[MAXLIVEBUFFERS] = { NULL }; -+cLiveBuffer *cLiveBufferManager::liveBuffer[MAXLIVEBUFFERS] = { NULL }; -+cDevice *cLiveBufferManager::receiverDevice[MAXLIVEBUFFERS] = { NULL }; -+cLivePlayer *cLiveBufferManager::livePlayer = NULL; -+cLiveBufferControl *cLiveBufferManager::liveControl = NULL; -+ -+void cLiveBufferManager::ChannelSwitch(cDevice *ReceiverDevice, const cChannel *Channel) -+{ -+ int i; -+ for (i=0; i<MAXLIVEBUFFERS; i++) -+ if (liveBuffer[i] && liveBuffer[i]->Channel() == Channel) -+ break; -+ if (i == MAXLIVEBUFFERS) { -+ if (Setup.InRAM && !liveBuffer[0]) -+ i = 0; -+ else -+ for (i=0; i<MAXLIVEBUFFERS; i++) -+ if (liveBuffer[i] && (!liveBuffer[i]->Stay() || !liveReceiver[i]->IsAttached())) -+ break; -+ if (i == MAXLIVEBUFFERS) { -+ for (i = 0; i<MAXLIVEBUFFERS; i++) -+ if (!liveBuffer[i]) -+ break; -+ } -+ } -+ if (liveBuffer[i]) { -+ if (!(liveReceiver[i]->IsReceiving(Channel) && liveReceiver[i]->IsAttached())) { -+ cLiveReceiver *oldReceiver = liveReceiver[i]; -+ liveReceiver[i] = new cLiveReceiver(Channel); -+ ReceiverDevice->AttachReceiver(liveReceiver[i]); -+ liveBuffer[i]->SetNewRemux(liveReceiver[i]->remux, Channel); -+ delete oldReceiver; -+ receiverDevice[i] = ReceiverDevice; -+ } -+ else if (liveBuffer[i]->Stay()) -+ liveBuffer[i]->SetStatus(2); -+ } -+ else { -+ liveReceiver[i] = new cLiveReceiver(Channel); -+ ReceiverDevice->AttachReceiver(liveReceiver[i]); -+ receiverDevice[i] = ReceiverDevice; -+ char FileName[256]; -+ sprintf(FileName,"%s/LiveBuffer",BufferDirectory); -+ liveBuffer[i] = new cLiveBuffer(FileName,liveReceiver[i]->remux, Channel, i); -+ } -+ delete liveControl; -+ -+ cTransferControl::receiverDevice = receiverDevice[i]; -+ -+ livePlayer = new cLivePlayer(liveBuffer[i]); -+ cControl::Launch(liveControl = new cLiveBufferControl(livePlayer)); -+ -+ for (int j = 0; j < MAXLIVEBUFFERS; j++) -+ if (i!=j && liveBuffer[j] && !liveBuffer[j]->LiveCutterActive() && (!liveBuffer[j]->Stay() || !liveReceiver[j]->IsAttached())) { -+ delete liveBuffer[j]; -+ liveBuffer[j] = NULL; -+ delete liveReceiver[j]; -+ liveReceiver[j] = NULL; -+ } -+} -+ -+void cLiveBufferManager::Shutdown(void) -+{ -+ delete liveControl; -+ for (int i = 0; i < MAXLIVEBUFFERS; i++) { -+ delete liveBuffer[i]; -+ liveBuffer[i] = NULL; -+ delete liveReceiver[i]; -+ liveReceiver[i] = NULL; -+ } -+ char FileName[256]; -+ sprintf(FileName,"%s/LiveBuffer",BufferDirectory); -+ RemoveFileOrDir(FileName, true); -+} -+ -+cLiveBuffer *cLiveBufferManager::InLiveBuffer(cTimer *timer, int *StartFrame, int *EndFrame) -+{ -+ bool recstart = false; -+ if (timer && timer->HasFlags(tfRecording)) { -+ timer->SetFlags(tfhasLiveBuf); -+ recstart = true; -+ } -+ for (int i = 0; i < MAXLIVEBUFFERS; i++) -+ if (timer && timer->HasFlags(tfActive) && !timer->HasFlags(tfVps) && (!timer->HasFlags(tfhasLiveBuf) || recstart) && liveBuffer[i] && liveReceiver[i]->GetChannel() == timer->Channel()) { -+ int now = liveBuffer[i]->LastIndex(); -+ int first = liveBuffer[i]->FirstIndex() + 50; -+ if (now-first < 250) // Erst wenn LiveBuffer größer 10s -+ return NULL; -+ if (timer->StartTime() < time(NULL) && now-first > (time(NULL)-timer->StopTime())*FRAMESPERSEC) { -+ if (StartFrame) { -+ if ((time(NULL)-timer->StartTime())*FRAMESPERSEC < now - first) -+ *StartFrame = now - (time(NULL) - timer->StartTime())*FRAMESPERSEC; -+ else -+ *StartFrame = first; -+ } -+ if (EndFrame) { -+ if (time(NULL) > timer->StopTime()) -+ *EndFrame = now - (time(NULL) - timer->StopTime()) * FRAMESPERSEC; -+ else -+ *EndFrame = 0; -+ } -+ return liveBuffer[i]; -+ } -+ } -+ return NULL; -+} -+ -+int cLiveBufferManager::Impact(cDevice *device, const cChannel *Channel, bool LiveView) -+{ -+ if (!Setup.LiveBuffer) -+ return 0; -+ int r = 1; -+ for (int i=0; i < MAXLIVEBUFFERS; i++) -+ if (liveBuffer[i] && receiverDevice[i] == device) { -+ if (liveBuffer[i]->Stay() && liveReceiver[i]->IsAttached()) -+ if (liveBuffer[i]->Channel()->Transponder() != Channel->Transponder() || -+ liveBuffer[i]->Channel()->Source() != Channel->Source()) -+ r = 2; -+ } -+ return r; -+} -+ -+bool cLiveBufferManager::AllowsChannelSwitch(void) -+{ -+ return true; // return !liveBuffer || !liveBuffer->LiveCutterActive(); -+} -+#endif /* LIVEBUFFER */ -diff -ruNp vdr-1.7.0/livebuffer.h vdr-1.7.0-extensions/livebuffer.h ---- vdr-1.7.0/livebuffer.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/livebuffer.h 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,301 @@ -+#ifndef __LIVEBUFFER_H -+#define __LIVEBUFFER_H -+ -+#include "player.h" -+#include "receiver.h" -+#include "remux.h" -+#include "ringbuffer.h" -+#include "thread.h" -+ -+#define LIVEBUFSIZE MEGABYTE(5) -+ -+#define INDEXBLOCKSIZE 20000 -+ -+class cUnbufferedFile64 { -+private: -+ int fd; -+ off64_t curpos; -+ off64_t cachedstart; -+ off64_t cachedend; -+ off64_t begin; -+ off64_t lastpos; -+ off64_t ahead; -+ size_t readahead; -+ size_t written; -+ size_t totwritten; -+ int FadviseDrop(off64_t Offset, off64_t Len); -+public: -+ cUnbufferedFile64(void); -+ ~cUnbufferedFile64(); -+ int Open(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE); -+ int Close(void); -+ off64_t Seek(off64_t Offset, int Whence); -+ ssize_t Read(void *Data, size_t Size); -+ ssize_t Write(const void *Data, size_t Size); -+ static cUnbufferedFile64 *Create(const char *FileName, int Flags, mode_t Mode = DEFFILEMODE); -+ }; -+ -+class cFileName64 { -+private: -+ cUnbufferedFile64 *file; -+ int fileNumber; -+ char *fileName, *pFileNumber; -+ bool record; -+ bool blocking; -+public: -+ cFileName64(const char *FileName, bool Record, bool Blocking = false); -+ ~cFileName64(); -+ const char *Name(void) { return fileName; } -+ int Number(void) { return fileNumber; } -+ void SetNumber(int Number); -+ cUnbufferedFile64 *Open(void); -+ void Close(void); -+ void CloseAndRemove(void); -+ void Remove(void); -+ }; -+ -+class cLiveIndex { -+friend class cLiveCutterThread; -+friend class cLiveBuffer; -+private: -+ struct frame { -+ off64_t offset ; //:36; -+ bool written ; //:1 ; -+ uchar pt ; //:3 ; -+ }; -+ struct block { -+ frame Frame[INDEXBLOCKSIZE]; -+ block *previous, *next; -+ }; -+ block *headblock, *tailblock; -+ int blockCount; -+ int head, tail; -+ int blank; -+ int start; -+ int writtenCount, delCount; -+ int DPos, DCount; -+ int lastWrittenSize, lastCount; -+ off64_t fileSize; -+ int bufSize; -+ int lastFrame; -+ int GetFrame(block** Block, int Number); -+ cRwLock *RwLock; -+public: -+ cLiveIndex(int BufSize); -+ ~cLiveIndex(); -+ void Add(uchar pt, int pos); -+ void AddData(int pos); -+ void Delete(off64_t FilePos); -+ int DelFirst(void); -+ void Clear(void); -+ void SetBlank(int Blank) { RwLock->Lock(true); blank = Blank; RwLock->Unlock(); } -+ int NextWrite(); -+ void WrittenTo(off64_t FilePos, int Count); -+ bool HasFrame(int Number) { return lastFrame > Number && Number >=delCount; } -+ bool IsWritten(int Number) { return writtenCount > Number; } -+ off64_t GetOffset(int Number); -+ int Size(int Number, uchar *PictureType = NULL); -+ int GetNextIFrame(int Index, bool Forward); -+ int FindIFrame(int64_t PTS, uchar *Buffer); -+ void Switched(); -+ int Last(void) { return lastFrame+1; } -+ int First(void) { return start > delCount ? start : delCount; } -+}; -+ -+class cLiveFileReader : public cThread { -+private: -+ cFileName64 *fileName; -+ cUnbufferedFile64 *readFile; -+ cCondWait newSet; -+ off64_t filePos; -+ int hasData, length, wanted; -+ uchar *buffer; -+protected: -+ virtual void Action(void); -+public: -+ cLiveFileReader(const char *FileName, int Number); -+ ~cLiveFileReader(); -+ int Read(uchar **Buffer, off64_t FilePos, int Size); -+ void Clear(void); -+}; -+ -+class cLiveFileWriter : public cThread { -+private: -+ cFileName64 *fileName; -+ cUnbufferedFile64 *writeFile; -+ cCondWait newSet,written; -+ off64_t filePos,fileSize; -+ int hasWritten, length, wantWrite; -+ uchar *buffer; -+ time_t lastCheck; -+ bool full; -+ bool LowDiskSpace(void); -+protected: -+ virtual void Action(void); -+public: -+ cLiveFileWriter(const char *FileName); -+ ~cLiveFileWriter(); -+ off64_t Write(uchar *Buffer, int Size, bool Wait); -+ int FileNumber(void) { return fileName->Number(); } -+ void Clear(void); -+ bool Full(void) { return full; } -+}; -+ -+class cLiveBuffer; -+ -+class cLiveCutterThread : public cThread { -+private: -+ cFileName64 *readFileName, *writeFileName; -+ cUnbufferedFile64 *readFile, *writeFile; -+ cLiveBuffer *liveBuffer; -+ int startFrame, endFrame; -+protected: -+ virtual void Action(void); -+public: -+ cLiveCutterThread(const char *FileName, int FileNumber, cLiveBuffer *LiveBuffer, int StartFrame, int EndFrame); -+ ~cLiveCutterThread(); -+}; -+ -+class cLiveBuffer : public cThread { -+friend class cLiveCutterThread; -+private: -+ int number; -+ uchar *buffer; -+ int bufSize; -+ bool writeHD; -+ int lastRead; -+ int head, tail, blank; -+ cLiveIndex *index; -+ cRemux *remux; -+ cLiveFileWriter *fileWriter; -+ char *filestring; -+ uchar pictureType; -+ cLiveFileReader *fileReader; -+ int startFrame; -+ cLiveCutterThread *liveCutter; -+ const cChannel *channel; -+ int status; -+ void Write(bool Wait); -+ void Store(uchar *Data, int Count); -+protected: -+ virtual void Action(void); -+public: -+ cLiveBuffer(const char *FileName, cRemux *Remux, const cChannel *Channel, int Number); -+ virtual ~cLiveBuffer(); -+ void SetStatus(int s); -+ void SetNewRemux(cRemux *Remux, const cChannel *Channel); -+ int GetFrame(uchar **Buffer, int Number, int Off = -1); -+ int GetNextIFrame(int Index, bool Forward) { return index->GetNextIFrame(Index,Forward); } -+ int LastIndex(void) { return index->Last(); } -+ int FirstIndex(void) { return index->First(); } -+ int LastRead(void) { return lastRead; } -+ void CreateIndexFile(const char *FileName, int64_t PTS, int EndFrame = 0); -+ void SetStartFrame(int StartFrame) { startFrame = StartFrame; } -+ bool LiveCutterActive(void) { return liveCutter && liveCutter->Active(); } -+ const cChannel* Channel(void) { return channel; } -+ bool Stay(void) { return status>0 && Setup.KeepPaused; }; -+}; -+ -+class cLiveBackTrace; -+ -+class cLivePlayer : public cPlayer, public cThread { -+private: -+ enum ePlayModes { pmPlay, pmPause, pmSlow, pmFast, pmStill }; -+ enum ePlayDirs { pdForward, pdBackward }; -+ static int Speeds[]; -+ ePlayModes playMode; -+ ePlayDirs playDir; -+ int trickSpeed; -+ cLiveBuffer *liveBuffer; -+ cRingBufferFrame *ringBuffer; -+ cLiveBackTrace *backTrace; -+ int readIndex, writeIndex; -+ cFrame *readFrame; -+ cFrame *playFrame; -+ int Off; -+ bool firstPacket; -+ void TrickSpeed(int Increment); -+ void Empty(void); -+protected: -+ virtual void Activate(bool On); -+ virtual void Action(void); -+public: -+ cLivePlayer(cLiveBuffer *LiveBuffer); -+ virtual ~cLivePlayer(); -+ void Pause(void); -+ void Play(void); -+ void Forward(void); -+ void Backward(void); -+ bool Stop(void); -+ void SkipSeconds(int Seconds); -+ virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false); -+ virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed); -+}; -+ -+class cLiveReceiver : public cReceiver, cThread { -+friend class cLiveBufferManager; -+friend class cLiveBufferControl; -+private: -+ cRingBufferLinear *ringBuffer; -+ cRemux *remux; -+ const cChannel *channel; -+ bool attached; -+ int vpid; -+ int apids[MAXAPIDS]; -+ int dpids[MAXDPIDS]; -+ int spids[MAXSPIDS]; -+protected: -+ virtual void Activate(bool On); -+ virtual void Receive(uchar *Data, int Length); -+ virtual void Action(void); -+public: -+ cLiveReceiver(const cChannel *Channel); -+ virtual ~cLiveReceiver(); -+ const cChannel *GetChannel() { return channel; } -+ bool IsReceiving(const cChannel *Channel); -+ bool IsAttached() { return attached; } -+ }; -+ -+class cLiveBufferControl : public cControl { -+private: -+ cSkinDisplayReplay *displayReplay; -+ cLivePlayer *player; -+ bool visible, modeOnly, shown; -+ int lastCurrent, lastTotal; -+ bool lastPlay, lastForward; -+ int lastSpeed; -+ time_t timeoutShow; -+ void ShowTimed(int Seconds = 0); -+ void ShowMode(void); -+ bool ShowProgress(bool Initial); -+public: -+ cLiveBufferControl(cLivePlayer *Player); -+ ~cLiveBufferControl(); -+ bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false); -+ bool GetReplayMode(bool &Play, bool &Forward, int &Speed); -+ virtual eOSState ProcessKey(eKeys Key); -+ virtual void Show(void); -+ virtual void Hide(void); -+ bool Visible(void) { return visible; } -+ }; -+ -+#define MAXLIVEBUFFERS 16 -+ -+class cLiveBufferManager { -+friend class cLiveBufferControl; -+private: -+ static cLiveReceiver* liveReceiver[MAXLIVEBUFFERS]; -+ static cLiveBuffer* liveBuffer[MAXLIVEBUFFERS]; -+ static cDevice* receiverDevice[MAXLIVEBUFFERS]; -+ static cLivePlayer* livePlayer; -+ static cLiveBufferControl* liveControl; -+public: -+ static void ChannelSwitch(cDevice *ReceiverDevice, const cChannel *Channel); -+ static void Shutdown(void); -+ static cLiveBufferControl *GetLiveBufferControl(void) { return liveControl; } -+ static cLiveBuffer *InLiveBuffer(cTimer *timer, int *StartFrame = NULL, int *EndFrame = NULL); -+ static int Impact(cDevice *device, const cChannel *Channel, bool LiveView); -+ static bool AllowsChannelSwitch(void); -+}; -+ -+#endif //__LIVEBUFFER_H -diff -ruNp vdr-1.7.0/mainmenuitemsprovider.h vdr-1.7.0-extensions/mainmenuitemsprovider.h ---- vdr-1.7.0/mainmenuitemsprovider.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/mainmenuitemsprovider.h 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,62 @@ -+#ifdef USE_MENUORG -+/* -+ * vdr-menuorg - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2007 - 2008 Tobias Grimm <vdr@e-tobi.net> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ * $Id$ -+ * -+ */ -+ -+#ifndef __MAINMENUITEMSPROVIDER_H -+#define __MAINMENUITEMSPROVIDER_H -+ -+#include <vector> -+ -+class cOsdItem; -+class cOsdMenu; -+ -+class IMenuItemDefinition -+{ -+ public: -+ virtual ~IMenuItemDefinition() {}; -+ virtual bool IsCustomOsdItem() = 0; -+ virtual bool IsPluginItem() = 0; -+ virtual bool IsSeparatorItem() = 0; -+ virtual cOsdItem* CustomOsdItem() = 0; -+ virtual const char* PluginMenuEntry() = 0; -+ virtual bool IsSelected() = 0; -+ virtual int PluginIndex() = 0; -+}; -+ -+typedef std::vector<IMenuItemDefinition*> MenuItemDefinitions; -+ -+#define MENU_ITEMS_PROVIDER_SERVICE_ID "MenuOrgPatch-v0.4.2::MainMenuItemsProvider" -+ -+class IMainMenuItemsProvider -+{ -+ public: -+ virtual ~IMainMenuItemsProvider() {}; -+ virtual bool IsCustomMenuAvailable() = 0; -+ virtual MenuItemDefinitions* MainMenuItems() = 0; -+ virtual void EnterRootMenu() = 0; -+ virtual void EnterSubMenu(cOsdItem* item) = 0; -+ virtual bool LeaveSubMenu() = 0; -+ virtual cOsdMenu* Execute(cOsdItem* item) = 0; -+}; -+ -+#endif //__MAINMENUITEMSPROVIDER_H -+#endif /* MENUORG */ -diff -ruNp vdr-1.7.0/Make.config.template vdr-1.7.0-extensions/Make.config.template ---- vdr-1.7.0/Make.config.template 2008-01-13 13:54:09.000000000 +0100 -+++ vdr-1.7.0-extensions/Make.config.template 2009-04-09 20:48:48.000000000 +0200 -@@ -41,8 +41,262 @@ RCU_DEVICE = /dev/ttyS1 - ## Define if you want vdr to not run as root - #VDR_USER = vdr - -+### VDR-Extensions: -+# Comment the patches you don't need -+# DVDCHAPJUMP needs DVDARCHIVE enabled -+# DVDARCHIVE needs LIEMIEXT enabled -+# SORTRECORDS needs LIEMIEXT enabled -+# you can only enable MENUORG or SETUP -+ -+#ANALOGTV = 1 -+#ATSC = 1 -+#CHANNELSCAN = 1 -+CMDRECCMDI18N = 1 -+CMDSUBMENU = 1 -+#CUTTERLIMIT = 1 -+#CUTTERQUEUE = 1 -+CUTTIME = 1 -+DDEPGENTRY = 1 -+#DELTIMESHIFTREC = 1 -+DOLBYINREC = 1 -+#DVBPLAYER = 1 -+#DVBSETUP = 1 -+#DVDARCHIVE = 1 -+#DVDCHAPJUMP = 1 -+#DVLFRIENDLYFNAMES = 1 -+#DVLRECSCRIPTADDON = 1 -+#DVLVIDPREFER = 1 -+#EM84XX = 1 -+#GRAPHTFT = 1 -+#HARDLINKCUTTER = 1 -+JUMPPLAY = 1 -+LIEMIEXT = 1 -+#LIRCSETTINGS = 1 -+#LIVEBUFFER = 1 -+#LNBSHARE = 1 -+#MAINMENUHOOKS = 1 -+#MENUORG = 1 -+#NOEPG = 1 -+#OSDMAXITEMS = 1 -+#PARENTALRATING = 1 -+#PINPLUGIN = 1 -+PLUGINAPI = 1 -+PLUGINMISSING = 1 -+#PLUGINPARAM = 1 -+#ROTOR = 1 -+SETTIME = 1 -+#SETUP = 1 -+#SOFTOSD = 1 -+#SOURCECAPS = 1 -+#SORTRECORDS = 1 -+#STREAMDEVEXT = 1 -+#SYNCEARLY = 1 -+#TIMERCMD = 1 -+#TIMERINFO = 1 -+#TTXTSUBS = 1 -+#VALIDINPUT = 1 -+#VOLCTRL = 1 -+WAREAGLEICON = 1 -+#YAEPG = 1 -+ - ### You don't need to touch the following: - - ifdef DVBDIR - INCLUDES += -I$(DVBDIR)/include - endif -+ -+ifdef ANALOGTV -+DEFINES += -DUSE_ANALOGTV -+endif -+ -+ifdef ATSC -+DEFINES += -DUSE_ATSC -+endif -+ -+ifdef CHANNELSCAN -+DEFINES += -DUSE_CHANNELSCAN -+endif -+ -+ifdef CMDRECCMDI18N -+DEFINES += -DUSE_CMDRECCMDI18N -+endif -+ -+ifdef CMDSUBMENU -+DEFINES += -DUSE_CMDSUBMENU -+endif -+ -+ifdef CUTTERLIMIT -+DEFINES += -DUSE_CUTTERLIMIT -+endif -+ -+ifdef CUTTERQUEUE -+DEFINES += -DUSE_CUTTERQUEUE -+endif -+ -+ifdef CUTTIME -+DEFINES += -DUSE_CUTTIME -+endif -+ -+ifdef DDEPGENTRY -+DEFINES += -DUSE_DDEPGENTRY -+endif -+ -+ifdef DELTIMESHIFTREC -+DEFINES += -DUSE_DELTIMESHIFTREC -+endif -+ -+ifdef DOLBYINREC -+DEFINES += -DUSE_DOLBYINREC -+endif -+ -+ifdef DVBPLAYER -+DEFINES += -DUSE_DVBPLAYER -+endif -+ -+ifdef DVBSETUP -+DEFINES += -DUSE_DVBSETUP -+endif -+ -+ifdef DVDARCHIVE -+ifdef LIEMIEXT -+DEFINES += -DUSE_DVDARCHIVE -+endif -+endif -+ -+ifdef DVLRECSCRIPTADDON -+DEFINES += -DUSE_DVLRECSCRIPTADDON -+endif -+ -+ifdef DVLVIDPREFER -+DEFINES += -DUSE_DVLVIDPREFER -+endif -+ -+ifdef DVLFRIENDLYFNAMES -+DEFINES += -DUSE_DVLFRIENDLYFNAMES -+endif -+ -+ifdef EM84XX -+DEFINES += -DUSE_EM84XX -+endif -+ -+ifdef GRAPHTFT -+DEFINES += -DUSE_GRAPHTFT -+endif -+ -+ifdef HARDLINKCUTTER -+DEFINES += -DUSE_HARDLINKCUTTER -+endif -+ -+ifdef JUMPPLAY -+DEFINES += -DUSE_JUMPPLAY -+endif -+ -+ifdef LIEMIEXT -+DEFINES += -DUSE_LIEMIEXT -+endif -+ -+ifdef LIRCSETTINGS -+DEFINES += -DUSE_LIRCSETTINGS -+endif -+ -+ifdef LIVEBUFFER -+DEFINES += -DUSE_LIVEBUFFER -+endif -+ -+ifdef LNBSHARE -+DEFINES += -DUSE_LNBSHARE -+endif -+ -+ifdef MAINMENUHOOKS -+DEFINES += -DUSE_MAINMENUHOOKS -+endif -+ -+ifdef MENUORG -+DEFINES += -DUSE_MENUORG -+else -+ifdef SETUP -+DEFINES += -DUSE_SETUP -+endif -+endif -+ -+ifdef NOEPG -+DEFINES += -DUSE_NOEPG -+endif -+ -+ifdef OSDMAXITEMS -+DEFINES += -DUSE_OSDMAXITEMS -+endif -+ -+ifdef PARENTALRATING -+DEFINES += -DUSE_PARENTALRATING -+endif -+ -+ifdef PINPLUGIN -+DEFINES += -DUSE_PINPLUGIN -+endif -+ -+ifdef PLUGINMISSING -+DEFINES += -DUSE_PLUGINMISSING -+endif -+ -+ifdef PLUGINPARAM -+DEFINES += -DUSE_PLUGINPARAM -+endif -+ -+ifdef ROTOR -+DEFINES += -DUSE_ROTOR -+endif -+ -+ifdef SETTIME -+DEFINES += -DUSE_SETTIME -+endif -+ -+ifdef SOFTOSD -+DEFINES += -DUSE_SOFTOSD -+endif -+ -+ifdef SOURCECAPS -+DEFINES += -DUSE_SOURCECAPS -+endif -+ -+ifdef SORTRECORDS -+ifdef LIEMIEXT -+DEFINES += -DUSE_SORTRECORDS -+endif -+endif -+ -+ifdef STREAMDEVEXT -+DEFINES += -DUSE_STREAMDEVEXT -+endif -+ -+ifdef SYNCEARLY -+DEFINES += -DUSE_SYNCEARLY -+endif -+ -+ifdef TIMERCMD -+DEFINES += -DUSE_TIMERCMD -+endif -+ -+ifdef TIMERINFO -+DEFINES += -DUSE_TIMERINFO -+endif -+ -+ifdef TTXTSUBS -+DEFINES += -DUSE_TTXTSUBS -+endif -+ -+ifdef VALIDINPUT -+DEFINES += -DUSE_VALIDINPUT -+endif -+ -+ifdef VOLCTRL -+DEFINES += -DUSE_VOLCTRL -+endif -+ -+ifdef WAREAGLEICON -+DEFINES += -DUSE_WAREAGLEICON -+endif -+ -+ifdef YAEPG -+DEFINES += -DUSE_YAEPG -+endif -diff -ruNp vdr-1.7.0/Makefile vdr-1.7.0-extensions/Makefile ---- vdr-1.7.0/Makefile 2008-02-29 22:43:03.000000000 +0100 -+++ vdr-1.7.0-extensions/Makefile 2009-04-09 20:48:48.000000000 +0200 -@@ -43,6 +43,22 @@ OBJS = audio.o channels.o ci.o config.o - skinclassic.o skins.o skinsttng.o sources.o spu.o status.o svdrp.o themes.o thread.o\ - timers.o tools.o transfer.o vdr.o videodir.o - -+ifdef WAREAGLEICON -+OBJS += iconpatch.o -+endif -+ -+ifdef LIVEBUFFER -+OBJS += livebuffer.o -+endif -+ -+ifdef SETUP -+OBJS += tinystr.o tinyxml.o tinyxmlerror.o tinyxmlparser.o submenu.o -+endif -+ -+ifdef TTXTSUBS -+OBJS += vdrttxtsubshooks.o -+endif -+ - ifndef NO_KBD - DEFINES += -DREMOTE_KBD - endif -@@ -75,6 +91,14 @@ ifdef VFAT - DEFINES += -DVFAT - endif - -+ifdef DVDARCHIVE -+ifdef DVDCHAPJUMP -+LIBS += -ldvdread -+INCLUDES += -I/usr/include/dvdread -+DEFINES += -DUSE_DVDCHAPJUMP -+endif -+endif -+ - all: vdr i18n - - # Implicit rules: -@@ -140,6 +164,26 @@ include-dir: - - # Plugins: - -+ifdef PLUGINAPI -+DEFINES += -DUSE_PLUGINAPI -+plugins: include-dir -+ @failed="";\ -+ noapiv="";\ -+ for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do\ -+ echo "Plugin $$i:";\ -+ if ! grep -q "\$$(LIBDIR)/.*\$$(APIVERSION)" "$(PLUGINDIR)/src/$$i/Makefile" ; then\ -+ sed -i -e s/VDRVERSION/APIVERSION/g $(PLUGINDIR)/src/$$i/Makefile;\ -+ if ! grep -q "\$$(LIBDIR)/.*\$$(APIVERSION)" "$(PLUGINDIR)/src/$$i/Makefile" ; then\ -+ echo "ERROR: plugin $$i doesn't honor APIVERSION - not compiled!";\ -+ noapiv="$$noapiv $$i";\ -+ continue;\ -+ fi;\ -+ fi;\ -+ $(MAKE) -C "$(PLUGINDIR)/src/$$i" all || failed="$$failed $$i";\ -+ done;\ -+ if [ -n "$$noapiv" ] ; then echo; echo "*** plugins without APIVERSION:$$noapiv"; echo; fi;\ -+ if [ -n "$$failed" ] ; then echo; echo "*** failed plugins:$$failed"; echo; fi -+else - plugins: include-dir - @failed="";\ - noapiv="";\ -@@ -154,6 +198,7 @@ plugins: include-dir - done;\ - if [ -n "$$noapiv" ] ; then echo; echo "*** plugins without APIVERSION:$$noapiv"; echo; fi;\ - if [ -n "$$failed" ] ; then echo; echo "*** failed plugins:$$failed"; echo; exit 1; fi -+endif - - clean-plugins: - @for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do $(MAKE) -C "$(PLUGINDIR)/src/$$i" clean; done -diff -ruNp vdr-1.7.0/MANUAL vdr-1.7.0-extensions/MANUAL ---- vdr-1.7.0/MANUAL 2008-02-24 11:09:17.000000000 +0100 -+++ vdr-1.7.0-extensions/MANUAL 2009-04-09 20:48:48.000000000 +0200 -@@ -813,6 +813,30 @@ Version 1.6 - 0 resulting in a file named 'resume.vdr', and any other - value resulting in 'resume.n.vdr'. - -+ Jump&Play = no Turns playing on or off after jumping forward to the -+ next editing mark with the '9' key. -+ -+ Play&Jump = no Turns automatic jumping over commercial breaks on or -+ off. This includes jumping to the first mark, if the -+ replay starts at the beginning of a recording - and -+ stopping the replay at the last mark. -+ With this setting enabled, the behaviour of the '8' -+ key during replay is changed too. It moves the actual -+ replay position not only three seconds before the -+ next "start" mark, but also before the next "end" -+ mark. This can be used to test, if the editing marks -+ are correctly positioned for a "smooth" jump over a -+ commercial break. -+ -+ Pause at last mark = no -+ Turns pausing of replay at the last editing mark on or -+ off. -+ -+ Reload marks = no Turns reloading of editing marks on or off. This can -+ be used if an external programme adjusts the editing -+ marks, e.g. noad in online mode. The marks are reloaded -+ in 10 seconds intervals. -+ - Miscellaneous: - - Min. event timeout = 30 -diff -ruNp vdr-1.7.0/menu.c vdr-1.7.0-extensions/menu.c ---- vdr-1.7.0/menu.c 2008-04-12 13:37:17.000000000 +0200 -+++ vdr-1.7.0-extensions/menu.c 2009-04-09 20:48:48.000000000 +0200 -@@ -8,11 +8,17 @@ - */ - - #include "menu.h" -+#ifdef USE_WAREAGLEICON -+#include "iconpatch.h" -+#endif /* WAREAGLEICON */ - #include <ctype.h> - #include <limits.h> - #include <stdio.h> - #include <stdlib.h> - #include <string.h> -+#ifdef USE_LIEMIEXT -+#include <math.h> -+#endif /* LIEMIEXT */ - #include "channels.h" - #include "config.h" - #include "cutter.h" -@@ -28,7 +34,17 @@ - #include "themes.h" - #include "timers.h" - #include "transfer.h" -+#ifdef USE_TTXTSUBS -+#include "vdrttxtsubshooks.h" -+#endif /* TTXTSUBS */ - #include "videodir.h" -+#ifdef USE_MENUORG -+#include "menuorgpatch.h" -+#endif /* MENUORG */ -+ -+#ifdef USE_CMDRECCMDI18N -+extern const char *ConfigDirectory; -+#endif /* MENUORG */ - - #define MAXWAIT4EPGINFO 3 // seconds - #define MODETIMEOUT 3 // seconds -@@ -189,10 +205,16 @@ private: - cChannel *channel; - cChannel data; - char name[256]; -+#ifdef USE_PLUGINPARAM -+ char pluginParam[256]; -+#endif /* PLUGINPARAM */ - void Setup(void); - public: - cMenuEditChannel(cChannel *Channel, bool New = false); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuEditChannel"; } -+#endif /* GRAPHTFT */ - }; - - cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New) -@@ -221,6 +243,9 @@ void cMenuEditChannel::Setup(void) - - // Parameters for all types of sources: - strn0cpy(name, data.name, sizeof(name)); -+#ifdef USE_PLUGINPARAM -+ strn0cpy(pluginParam, data.pluginParam, sizeof(pluginParam)); -+#endif /* PLUGINPARAM */ - Add(new cMenuEditStrItem( tr("Name"), name, sizeof(name))); - Add(new cMenuEditSrcItem( tr("Source"), &data.source)); - Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency)); -@@ -252,6 +277,9 @@ void cMenuEditChannel::Setup(void) - ST(" T") Add(new cMenuEditMapItem( tr("Transmission"), &data.transmission, TransmissionValues)); - ST(" T") Add(new cMenuEditMapItem( tr("Guard"), &data.guard, GuardValues)); - ST(" T") Add(new cMenuEditMapItem( tr("Hierarchy"), &data.hierarchy, HierarchyValues)); -+#ifdef USE_PLUGINPARAM -+ ST("P ") Add(new cMenuEditStrItem( tr("Parameters"), pluginParam, sizeof(pluginParam), tr(FileNameChars))); -+#endif /* PLUGINPARAM */ - ST(" T") Add(new cMenuEditMapItem( tr("Alpha"), &data.alpha, AlphaValues)); - ST(" T") Add(new cMenuEditMapItem( tr("Priority"), &data.priority, PriorityValues)); - ST(" S ") Add(new cMenuEditMapItem( tr("Rolloff"), &data.rollOff, RollOffValues)); -@@ -269,9 +297,15 @@ eOSState cMenuEditChannel::ProcessKey(eK - if (Key == kOk) { - if (Channels.HasUniqueChannelID(&data, channel)) { - data.name = strcpyrealloc(data.name, name); -+#ifdef USE_PLUGINPARAM -+ data.pluginParam = strcpyrealloc(data.pluginParam, pluginParam); -+#endif /* PLUGINPARAM */ - if (channel) { - *channel = data; - isyslog("edited channel %d %s", channel->Number(), *data.ToText()); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(channel, scMod); -+#endif /* STREAMDEVEXT */ - state = osBack; - } - else { -@@ -280,6 +314,9 @@ eOSState cMenuEditChannel::ProcessKey(eK - Channels.Add(channel); - Channels.ReNumber(); - isyslog("added channel %d %s", channel->Number(), *data.ToText()); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(channel, scAdd); -+#endif /* STREAMDEVEXT */ - state = osUser1; - } - Channels.SetModified(true); -@@ -342,6 +379,16 @@ void cMenuChannelItem::Set(void) - if (!channel->GroupSep()) { - if (sortMode == csmProvider) - buffer = cString::sprintf("%d\t%s - %s", channel->Number(), channel->Provider(), channel->Name()); -+#ifdef USE_WAREAGLEICON -+ else if (Setup.WarEagleIcons) { -+ if (channel->Vpid() == 1 || channel->Vpid() == 0) -+ buffer = cString::sprintf("%d\t%s %-30s", channel->Number(), IsLangUtf8() ? ICON_RADIO_UTF8 : ICON_RADIO, channel->Name()); -+ else if (channel->Ca() == 0) -+ buffer = cString::sprintf("%d\t%s %-30s", channel->Number(), IsLangUtf8() ? ICON_TV_UTF8 : ICON_TV, channel->Name()); -+ else -+ buffer = cString::sprintf("%d\t%s %-30s", channel->Number(), IsLangUtf8() ? ICON_TV_CRYPTED_UTF8 : ICON_TV_CRYPTED, channel->Name()); -+ } -+#endif /* WAREAGLEICON */ - else - buffer = cString::sprintf("%d\t%s", channel->Number(), channel->Name()); - } -@@ -372,6 +419,9 @@ public: - cMenuChannels(void); - ~cMenuChannels(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuChannels"; } -+#endif /* GRAPHTFT */ - }; - - cMenuChannels::cMenuChannels(void) -@@ -501,6 +551,9 @@ eOSState cMenuChannels::Delete(void) - Propagate(); - Channels.SetModified(true); - isyslog("channel %d deleted", DeletedChannel); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(NULL, scDel); -+#endif /* STREAMDEVEXT */ - if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { - if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) - Channels.SwitchTo(CurrentChannel->Number()); -@@ -526,6 +579,9 @@ void cMenuChannels::Move(int From, int T - Propagate(); - Channels.SetModified(true); - isyslog("channel %d moved to %d", FromNumber, ToNumber); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(ToChannel, scMod); -+#endif /* STREAMDEVEXT */ - if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { - if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) - Channels.SwitchTo(CurrentChannel->Number()); -@@ -638,14 +694,47 @@ cMenuEditTimer::cMenuEditTimer(cTimer *T - data.SetFlags(tfActive); - channel = data.Channel()->Number(); - Add(new cMenuEditBitItem( tr("Active"), &data.flags, tfActive)); -+#ifdef USE_PINPLUGIN -+ if (cOsd::pinValid) Add(new cMenuEditChanItem(tr("Channel"), &channel)); -+ else { -+ cString buf = cString::sprintf("%s\t%s", tr("Channel"), Channels.GetByNumber(channel)->Name()); -+ Add(new cOsdItem(buf)); -+ } -+#else - Add(new cMenuEditChanItem(tr("Channel"), &channel)); -+#endif /* PINPLUGIN */ - Add(new cMenuEditDateItem(tr("Day"), &data.day, &data.weekdays)); - Add(new cMenuEditTimeItem(tr("Start"), &data.start)); - Add(new cMenuEditTimeItem(tr("Stop"), &data.stop)); - Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps)); - Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY)); - Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME)); -+#ifdef USE_PINPLUGIN -+ if (cOsd::pinValid || !data.fskProtection) Add(new cMenuEditBoolItem(tr("Childlock"),&data.fskProtection)); -+ else { -+ cString buf = cString::sprintf("%s\t%s", tr("Childlock"), data.fskProtection ? tr("yes") : tr("no")); -+ Add(new cOsdItem(buf)); -+ } -+#endif /* PINPLUGIN */ -+#ifdef USE_LIEMIEXT -+ char* p = strrchr(data.file, '~'); -+ if (p) { -+ p++; -+ Utf8Strn0Cpy(name, p, sizeof(name)); -+ Utf8Strn0Cpy(path, data.file, sizeof(path)); -+ p = strrchr(path, '~'); -+ if (p) -+ p[0] = 0; -+ } -+ else { -+ Utf8Strn0Cpy(name, data.file, sizeof(name)); -+ Utf8Strn0Cpy(path, "", sizeof(path)); -+ } -+ Add(new cMenuEditStrItem(tr("File"), name, sizeof(name), tr(FileNameChars))); -+ Add(new cMenuEditRecPathItem(tr("Path"), path, sizeof(path))); -+#else - Add(new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file))); -+#endif /* LIEMIEXT */ - SetFirstDayItem(); - } - Timers.IncBeingEdited(); -@@ -685,6 +774,12 @@ eOSState cMenuEditTimer::ProcessKey(eKey - Skins.Message(mtError, tr("*** Invalid Channel ***")); - break; - } -+#ifdef USE_LIEMIEXT -+ if (strlen(path)) -+ snprintf(data.file, sizeof(data.file), "%s~%s", path, name); -+ else -+ snprintf(data.file, sizeof(data.file), "%s", name); -+#endif /* LIEMIEXT */ - if (!*data.file) - strcpy(data.file, data.Channel()->ShortName(true)); - if (timer) { -@@ -712,13 +807,37 @@ eOSState cMenuEditTimer::ProcessKey(eKey - return state; - } - -+#ifdef USE_TIMERCMD -+// --- cMenuCommands --------------------------------------------------------- -+// declaration shifted so it can be used in cMenuTimers -+class cMenuCommands : public cOsdMenu { -+private: -+ cCommands *commands; -+ char *parameters; -+ eOSState Execute(void); -+public: -+ cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters = NULL); -+ virtual ~cMenuCommands(); -+ virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuCommands"; } -+#endif /* GRAPHTFT - passt das so? */ -+ }; -+#endif /* TIMERCMD */ -+ - // --- cMenuTimerItem -------------------------------------------------------- - - class cMenuTimerItem : public cOsdItem { - private: - cTimer *timer; -+#ifdef USE_TIMERINFO -+ char diskStatus; -+#endif /* TIMERINFO */ - public: - cMenuTimerItem(cTimer *Timer); -+#ifdef USE_TIMERINFO -+ void SetDiskStatus(char DiskStatus); -+#endif /* TIMERINFO */ - virtual int Compare(const cListObject &ListObject) const; - virtual void Set(void); - cTimer *Timer(void) { return timer; } -@@ -727,6 +846,9 @@ public: - cMenuTimerItem::cMenuTimerItem(cTimer *Timer) - { - timer = Timer; -+#ifdef USE_TIMERINFO -+ diskStatus = ' '; -+#endif /* TIMERINFO */ - Set(); - } - -@@ -752,8 +874,56 @@ void cMenuTimerItem::Set(void) - strftime(buffer, sizeof(buffer), "%Y%m%d", &tm_r); - day = buffer; - } -+#ifdef USE_LIEMIEXT -+ if (!Setup.ShowTimerStop) { -+#ifdef USE_TIMERINFO -+#ifdef USE_WAREAGLEICON -+ SetText(cString::sprintf("%c%s\t%d\t%s%s%s\t%02d:%02d\t%s", -+#else -+ SetText(cString::sprintf("%c%c\t%d\t%s%s%s\t%02d:%02d\t%s", -+#endif /* WAREAGLEICON */ -+ diskStatus, -+#else -+#ifdef USE_WAREAGLEICON -+ SetText(cString::sprintf("%s\t%d\t%s%s%s\t%02d:%02d\t%s", -+#else -+ SetText(cString::sprintf("%c\t%d\t%s%s%s\t%02d:%02d\t%s", -+#endif /* WAREAGLEICON */ -+#endif /* TIMERINFO */ -+#ifdef USE_WAREAGLEICON -+ !(timer->HasFlags(tfActive)) ? " " : timer->FirstDay() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_ARROW_UTF8 : ICON_ARROW : "!" : timer->Recording() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_REC_UTF8 : ICON_REC : "#" : Setup.WarEagleIcons ? IsLangUtf8() ? ICON_CLOCK_UTF8 : ICON_CLOCK : ">", -+#else -+ !(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>', -+#endif /* WAREAGLEICON */ -+ timer->Channel()->Number(), -+ *name, -+ *name && **name ? " " : "", -+ *day, -+ timer->Start() / 100, -+ timer->Start() % 100, -+ timer->File())); -+ } -+ else { -+#endif /* LIEMIEXT */ -+#ifdef USE_TIMERINFO -+#ifdef USE_WAREAGLEICON -+ SetText(cString::sprintf("%c%s\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", -+#else -+ SetText(cString::sprintf("%c%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", -+#endif /* WAREAGLEICON */ -+ diskStatus, -+#else -+#ifdef USE_WAREAGLEICON -+ SetText(cString::sprintf("%s\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", -+#else - SetText(cString::sprintf("%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", -+#endif /* WAREAGLEICON */ -+#endif /* TIMERINFO */ -+#ifdef USE_WAREAGLEICON -+ !(timer->HasFlags(tfActive)) ? " " : timer->FirstDay() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_ARROW_UTF8 : ICON_ARROW : "!" : timer->Recording() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_REC_UTF8 : ICON_REC : "#" : Setup.WarEagleIcons ? IsLangUtf8() ? ICON_CLOCK_UTF8 : ICON_CLOCK : ">", -+#else - !(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>', -+#endif /* WAREAGLEICON */ - timer->Channel()->Number(), - *name, - *name && **name ? " " : "", -@@ -763,8 +933,64 @@ void cMenuTimerItem::Set(void) - timer->Stop() / 100, - timer->Stop() % 100, - timer->File())); -+#ifdef USE_LIEMIEXT -+ } -+#endif /* LIEMIEXT */ -+} -+ -+#ifdef USE_TIMERINFO -+void cMenuTimerItem::SetDiskStatus(char DiskStatus) -+{ -+ diskStatus = DiskStatus; -+ Set(); -+} -+ -+// --- cTimerEntry ----------------------------------------------------------- -+ -+class cTimerEntry : public cListObject { -+private: -+ cMenuTimerItem *item; -+ const cTimer *timer; -+ time_t start; -+public: -+ cTimerEntry(cMenuTimerItem *item) : item(item), timer(item->Timer()), start(timer->StartTime()) {} -+ cTimerEntry(const cTimer *timer, time_t start) : item(NULL), timer(timer), start(start) {} -+ virtual int Compare(const cListObject &ListObject) const; -+ bool active(void) const { return timer->HasFlags(tfActive); } -+ time_t startTime(void) const { return start; } -+ int priority(void) const { return timer->Priority(); } -+ int duration(void) const; -+ bool repTimer(void) const { return !timer->IsSingleEvent(); } -+ bool isDummy(void) const { return item == NULL; } -+ const cTimer *Timer(void) const { return timer; } -+ void SetDiskStatus(char DiskStatus); -+ }; -+ -+int cTimerEntry::Compare(const cListObject &ListObject) const -+{ -+ cTimerEntry *entry = (cTimerEntry *)&ListObject; -+ int r = startTime() - entry->startTime(); -+ if (r == 0) -+ r = entry->priority() - priority(); -+ return r; - } - -+int cTimerEntry::duration(void) const -+{ -+ int dur = (timer->Stop() / 100 * 60 + timer->Stop() % 100) - -+ (timer->Start() / 100 * 60 + timer->Start() % 100); -+ if (dur < 0) -+ dur += 24 * 60; -+ return dur; -+} -+ -+void cTimerEntry::SetDiskStatus(char DiskStatus) -+{ -+ if (item) -+ item->SetDiskStatus(DiskStatus); -+} -+#endif /* TIMERINFO */ -+ - // --- cMenuTimers ----------------------------------------------------------- - - class cMenuTimers : public cOsdMenu { -@@ -777,14 +1003,31 @@ private: - eOSState Info(void); - cTimer *CurrentTimer(void); - void SetHelpKeys(void); -+#ifdef USE_TIMERINFO -+ void ActualiseDiskStatus(void); -+ bool actualiseDiskStatus; -+#endif /* TIMERINFO */ -+#ifdef USE_TIMERCMD -+ eOSState Commands(eKeys Key = kNone); -+#endif /* TIMERCMD */ - public: - cMenuTimers(void); - virtual ~cMenuTimers(); -+#ifdef USE_TIMERINFO -+ virtual void Display(void); -+#endif /* TIMERINFO */ - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuTimers"; } -+#endif /* GRAPHTFT */ - }; - - cMenuTimers::cMenuTimers(void) -+#ifdef USE_TIMERINFO -+:cOsdMenu(tr("Timers"), 3, CHNUMWIDTH, 10, 6, 6) -+#else - :cOsdMenu(tr("Timers"), 2, CHNUMWIDTH, 10, 6, 6) -+#endif /* TIMERINFO */ - { - helpKeys = -1; - for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) { -@@ -795,6 +1038,9 @@ cMenuTimers::cMenuTimers(void) - SetCurrent(First()); - SetHelpKeys(); - Timers.IncBeingEdited(); -+#ifdef USE_TIMERINFO -+ actualiseDiskStatus = true; -+#endif /* TIMERINFO */ - } - - cMenuTimers::~cMenuTimers() -@@ -833,7 +1079,11 @@ eOSState cMenuTimers::OnOff(void) - timer->OnOff(); - timer->SetEventFromSchedule(); - RefreshCurrent(); -+#ifdef USE_TIMERINFO -+ Display(); -+#else - DisplayCurrent(true); -+#endif /* TIMERINFO */ - if (timer->FirstDay()) - isyslog("timer %s first day set to %s", *timer->ToDescr(), *timer->PrintFirstDay()); - else -@@ -892,6 +1142,117 @@ eOSState cMenuTimers::Info(void) - return osContinue; - } - -+#ifdef USE_TIMERCMD -+#define CHECK_2PTR_NULL(x_,y_) ((x_)? ((y_)? y_:""):"") -+ -+eOSState cMenuTimers::Commands(eKeys Key) -+{ -+ if (HasSubMenu() || Count() == 0) -+ return osContinue; -+ cTimer *ti = CurrentTimer(); -+ if (ti) { -+ const cEvent *pEvent = ti->Event(); -+ int iRecNumber=0; -+ -+ if (!pEvent) { -+ Timers.SetEvents(); -+ pEvent = ti->Event(); -+ } -+ if (pEvent) { -+ // create a dummy recording to get the real filename -+ cRecording *rc_dummy = new cRecording(ti, pEvent); -+ Recordings.Load(); -+ cRecording *rc = Recordings.GetByName(rc_dummy->FileName()); -+ -+ delete rc_dummy; -+ if (rc) -+ iRecNumber=rc->Index() + 1; -+ } -+ // TODO: Geht das so...? -+ // Parameter format TimerNumber 'ChannelId' Start Stop 'Titel' 'Subtitel' 'file' RecNumer -+ // 1 2 3 4 5 6 7 8 -+ cString parameter = cString::sprintf("%d '%s' %d %d '%s' '%s' '%s' %d", ti->Index(), -+ *ti->Channel()->GetChannelID().ToString(), -+ (int)ti->StartTime(), -+ (int)ti->StopTime(), -+ CHECK_2PTR_NULL(pEvent, pEvent->Title()), -+ CHECK_2PTR_NULL(pEvent, pEvent->ShortText()), -+ ti->File(), -+ iRecNumber); -+ isyslog("timercmd: %s", *parameter); -+ cMenuCommands *menu; -+ eOSState state = AddSubMenu(menu = new cMenuCommands(tr("Timer commands"), &TimerCommands, parameter)); -+ if (Key != kNone) -+ state = menu->ProcessKey(Key); -+ return state; -+ } -+ return osContinue; -+} -+#endif /* TIMERCMD */ -+ -+#ifdef USE_TIMERINFO -+void cMenuTimers::ActualiseDiskStatus(void) -+{ -+ if (!actualiseDiskStatus || !Count()) -+ return; -+ -+ // compute free disk space -+ int freeMB, freeMinutes, runshortMinutes; -+ VideoDiskSpace(&freeMB); -+ freeMinutes = int(double(freeMB) * 1.1 / MB_PER_MINUTE); // overestimate by 10 percent -+ runshortMinutes = freeMinutes / 5; // 20 Percent -+ -+ // fill entries list -+ cTimerEntry *entry; -+ cList<cTimerEntry> entries; -+ for (cOsdItem *item = First(); item; item = Next(item)) -+ entries.Add(new cTimerEntry((cMenuTimerItem *)item)); -+ -+ // search last start time -+ time_t last = 0; -+ for (entry = entries.First(); entry; entry = entries.Next(entry)) -+ last = max(entry->startTime(), last); -+ -+ // add entries for repeating timers -+ for (entry = entries.First(); entry; entry = entries.Next(entry)) -+ if (entry->repTimer() && !entry->isDummy()) -+ for (time_t start = cTimer::IncDay(entry->startTime(), 1); -+ start <= last; -+ start = cTimer::IncDay(start, 1)) -+ if (entry->Timer()->DayMatches(start)) -+ entries.Add(new cTimerEntry(entry->Timer(), start)); -+ -+ // set the disk-status -+ entries.Sort(); -+ for (entry = entries.First(); entry; entry = entries.Next(entry)) { -+ char status = ' '; -+ if (entry->active()) { -+ freeMinutes -= entry->duration(); -+ status = freeMinutes > runshortMinutes ? '+' : freeMinutes > 0 ? '~' /* ± 177 +/- */ : '-'; -+ } -+ entry->SetDiskStatus(status); -+#ifdef DEBUG_TIMER_INFO -+ dsyslog("timer-info: %c | %d | %s | %s | %3d | %+5d -> %+5d", -+ status, -+ entry->startTime(), -+ entry->active() ? "aktiv " : "n.akt.", -+ entry->repTimer() ? entry->isDummy() ? " dummy " : "mehrmalig" : "einmalig ", -+ entry->duration(), -+ entry->active() ? freeMinutes + entry->duration() : freeMinutes, -+ freeMinutes); -+#endif -+ } -+ -+ actualiseDiskStatus = false; -+} -+ -+void cMenuTimers::Display(void) -+{ -+ ActualiseDiskStatus(); -+ cOsdMenu::Display(); -+} -+#endif /* TIMERINFO */ -+ - eOSState cMenuTimers::ProcessKey(eKeys Key) - { - int TimerNumber = HasSubMenu() ? Count() : -1; -@@ -900,18 +1261,40 @@ eOSState cMenuTimers::ProcessKey(eKeys K - if (state == osUnknown) { - switch (Key) { - case kOk: return Edit(); -+#ifdef USE_TIMERINFO -+ case kRed: actualiseDiskStatus = true; -+ state = OnOff(); break; // must go through SetHelpKeys()! -+#else - case kRed: state = OnOff(); break; // must go through SetHelpKeys()! -+#endif /* TIMERINFO */ - case kGreen: return New(); -+#ifdef USE_TIMERINFO -+ case kYellow: actualiseDiskStatus = true; -+ state = Delete(); break; -+#else - case kYellow: state = Delete(); break; -+#endif /* TIMERINFO */ - case kInfo: - case kBlue: return Info(); - break; -+#ifdef USE_TIMERCMD -+ case k1...k9: return Commands(Key); -+ case k0: return (TimerCommands.Count()? Commands():osContinue); -+#endif /* TIMERCMD */ - default: break; - } - } -+#ifdef USE_TIMERINFO -+ if (TimerNumber >= 0 && !HasSubMenu()) { -+ if (Timers.Get(TimerNumber)) // a newly created timer was confirmed with Ok -+ Add(new cMenuTimerItem(Timers.Get(TimerNumber)), true); -+ Sort(); -+ actualiseDiskStatus = true; -+#else - if (TimerNumber >= 0 && !HasSubMenu() && Timers.Get(TimerNumber)) { - // a newly created timer was confirmed with Ok - Add(new cMenuTimerItem(Timers.Get(TimerNumber)), true); -+#endif /* TIMERINFO */ - Display(); - } - if (Key != kNone) -@@ -941,6 +1324,9 @@ void cMenuEvent::Display(void) - { - cOsdMenu::Display(); - DisplayMenu()->SetEvent(event); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdSetEvent(event); -+#endif /* GRAPHTFT */ - if (event->Description()) - cStatus::MsgOsdTextItem(event->Description()); - } -@@ -988,7 +1374,12 @@ public: - const cChannel *channel; - bool withDate; - int timerMatch; -+#ifdef USE_LIEMIEXT -+ bool withBar; -+ cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL, bool WithDate = false, bool WithBar = false); -+#else - cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL, bool WithDate = false); -+#endif /* LIEMIEXT */ - static void SetSortMode(eScheduleSortMode SortMode) { sortMode = SortMode; } - static void IncSortMode(void) { sortMode = eScheduleSortMode((sortMode == ssmAllAll) ? ssmAllThis : sortMode + 1); } - static eScheduleSortMode SortMode(void) { return sortMode; } -@@ -998,12 +1389,19 @@ public: - - cMenuScheduleItem::eScheduleSortMode cMenuScheduleItem::sortMode = ssmAllThis; - -+#ifdef USE_LIEMIEXT -+cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel, bool WithDate, bool WithBar) -+#else - cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel, bool WithDate) -+#endif /* LIEMIEXT */ - { - event = Event; - channel = Channel; - withDate = WithDate; - timerMatch = tmNone; -+#ifdef USE_LIEMIEXT -+ withBar = WithBar; -+#endif /* LIEMIEXT */ - Update(true); - } - -@@ -1018,7 +1416,29 @@ int cMenuScheduleItem::Compare(const cLi - return r; - } - -+#ifdef USE_LIEMIEXT -+static const char * const ProgressBar[7] = -+{ -+ "[ ]", -+ "[| ]", -+ "[|| ]", -+ "[||| ]", -+ "[|||| ]", -+ "[||||| ]", -+ "[||||||]" -+}; -+#endif /* LIEMIEXT */ -+ -+#ifdef USE_WAREAGLEICON -+static const char *TimerMatchChars[9] = -+{ -+ " ", "t", "T", -+ ICON_BLANK, ICON_CLOCK_UH, ICON_CLOCK, -+ ICON_BLANK_UTF8, ICON_CLOCK_UH_UTF8, ICON_CLOCK_UTF8 -+}; -+#else - static const char *TimerMatchChars = " tT"; -+#endif /* WAREAGLEICON */ - - bool cMenuScheduleItem::Update(bool Force) - { -@@ -1027,17 +1447,54 @@ bool cMenuScheduleItem::Update(bool Forc - Timers.GetMatch(event, &timerMatch); - if (Force || timerMatch != OldTimerMatch) { - cString buffer; -+#ifdef USE_WAREAGLEICON -+ const char *t = Setup.WarEagleIcons ? IsLangUtf8() ? TimerMatchChars[timerMatch+6] : TimerMatchChars[timerMatch+3] : TimerMatchChars[timerMatch]; -+ const char *v = event->Vps() && (event->Vps() - event->StartTime()) ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_VPS_UTF8 : ICON_VPS : "V" : " "; -+ const char *r = event->SeenWithin(30) && event->IsRunning() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_RUNNING_UTF8 : ICON_RUNNING : "*" : " "; -+#else - char t = TimerMatchChars[timerMatch]; - char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' '; - char r = event->SeenWithin(30) && event->IsRunning() ? '*' : ' '; -+#endif /* WAREAGLEICON */ - const char *csn = channel ? channel->ShortName(true) : NULL; - cString eds = event->GetDateString(); - if (channel && withDate) -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%d\t%.*s\t%.*s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); -+#else - buffer = cString::sprintf("%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ - else if (channel) -+#ifdef USE_LIEMIEXT -+ if (Setup.ShowProgressBar && withBar) { -+ int progress = (int)roundf( (float)(time(NULL) - event->StartTime()) / (float)(event->Duration()) * 6.0 ); -+ if (progress < 0) progress = 0; -+ else if (progress > 6) progress = 6; -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), ProgressBar[progress], t, v, r, event->Title()); -+#else -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), ProgressBar[progress], t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ -+ } -+ else -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); -+#else -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ -+#else -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); -+#else - buffer = cString::sprintf("%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ -+#endif /* LIEMIEXT */ - else -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%.*s\t%s\t%s%s%s\t%s", Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); -+#else - buffer = cString::sprintf("%.*s\t%s\t%c%c%c\t%s", Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ - SetText(buffer); - result = true; - } -@@ -1063,13 +1520,21 @@ public: - static void SetCurrentChannel(int ChannelNr) { currentChannel = ChannelNr; } - static const cEvent *ScheduleEvent(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return now ? "MenuWhatsOnNow" : "MenuWhatsOnNext"; } -+ virtual void Display(void); -+#endif /* GRAPHTFT */ - }; - - int cMenuWhatsOn::currentChannel = 0; - const cEvent *cMenuWhatsOn::scheduleEvent = NULL; - - cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr) -+#ifdef USE_LIEMIEXT -+:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6, 4, 4) -+#else - :cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6, 4) -+#endif /* LIEMIEXT */ - { - now = Now; - helpKeys = -1; -@@ -1081,7 +1546,11 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedu - if (Schedule) { - const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent(); - if (Event) -+#ifdef USE_LIEMIEXT -+ Add(new cMenuScheduleItem(Event, Channel, false, Now), Channel->Number() == CurrentChannelNr); -+#else - Add(new cMenuScheduleItem(Event, Channel), Channel->Number() == CurrentChannelNr); -+#endif /* LIEMIEXT */ - } - } - } -@@ -1090,6 +1559,20 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedu - SetHelpKeys(); - } - -+#ifdef USE_GRAPHTFT -+void cMenuWhatsOn::Display(void) -+{ -+ cOsdMenu::Display(); -+ -+ if (Count() > 0) { -+ int ni = 0; -+ for (cOsdItem *item = First(); item; item = Next(item)) { -+ cStatus::MsgOsdEventItem(((cMenuScheduleItem*)item)->event, item->Text(), ni++, Count()); -+ } -+ } -+} -+#endif /* GRAPHTFT */ -+ - bool cMenuWhatsOn::Update(void) - { - bool result = false; -@@ -1230,6 +1713,10 @@ public: - cMenuSchedule(void); - virtual ~cMenuSchedule(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSchedule"; } -+ virtual void Display(void); -+#endif /* GRAPHTFT */ - }; - - cMenuSchedule::cMenuSchedule(void) -@@ -1255,6 +1742,20 @@ cMenuSchedule::~cMenuSchedule() - cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared - } - -+#ifdef USE_GRAPHTFT -+void cMenuSchedule::Display(void) -+{ -+ cOsdMenu::Display(); -+ -+ if (Count() > 0) { -+ int ni = 0; -+ for (cOsdItem *item = First(); item; item = Next(item)) { -+ cStatus::MsgOsdEventItem(((cMenuScheduleItem*)item)->event, item->Text(), ni++, Count()); -+ } -+ } -+} -+#endif /* GRAPHTFT */ -+ - void cMenuSchedule::PrepareScheduleAllThis(const cEvent *Event, const cChannel *Channel) - { - Clear(); -@@ -1488,6 +1989,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys - - // --- cMenuCommands --------------------------------------------------------- - -+#ifndef USE_TIMERCMD - class cMenuCommands : public cOsdMenu { - private: - cCommands *commands; -@@ -1497,7 +1999,11 @@ public: - cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters = NULL); - virtual ~cMenuCommands(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuCommands"; } -+#endif /* GRAPHTFT */ - }; -+#endif /* TIMERCMD */ - - cMenuCommands::cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters) - :cOsdMenu(Title) -@@ -1519,6 +2025,12 @@ eOSState cMenuCommands::Execute(void) - cCommand *command = commands->Get(Current()); - if (command) { - bool confirmed = true; -+#ifdef USE_CMDSUBMENU -+ if (command->hasChilds()) { -+ AddSubMenu(new cMenuCommands(command->Title(), command->getChilds(), parameters)); -+ return osContinue; -+ } -+#endif /* CMDSUBMENU */ - if (command->Confirm()) - confirmed = Interface->Confirm(cString::sprintf("%s?", command->Title())); - if (confirmed) { -@@ -1569,6 +2081,9 @@ public: - cMenuCam(cCamSlot *CamSlot); - virtual ~cMenuCam(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuCam"; } -+#endif /* GRAPHTFT */ - }; - - cMenuCam::cMenuCam(cCamSlot *CamSlot) -@@ -1748,6 +2263,9 @@ public: - cMenuRecording(const cRecording *Recording, bool WithButtons = false); - virtual void Display(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuRecording"; } -+#endif /* GRAPHTFT */ - }; - - cMenuRecording::cMenuRecording(const cRecording *Recording, bool WithButtons) -@@ -1763,6 +2281,9 @@ void cMenuRecording::Display(void) - { - cOsdMenu::Display(); - DisplayMenu()->SetRecording(recording); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdSetRecording(recording); -+#endif /* GRAPHTFT */ - if (recording->Info()->Description()) - cStatus::MsgOsdTextItem(recording->Info()->Description()); - } -@@ -1823,7 +2344,11 @@ cMenuRecordingItem::cMenuRecordingItem(c - fileName = strdup(Recording->FileName()); - name = NULL; - totalEntries = newEntries = 0; -+#ifdef USE_LIEMIEXT -+ SetText(Recording->Title('\t', true, Level, false)); -+#else - SetText(Recording->Title('\t', true, Level)); -+#endif /* LIEMIEXT */ - if (*Text() == '\t') - name = strdup(Text() + 2); // 'Text() + 2' to skip the two '\t' - } -@@ -1839,13 +2364,203 @@ void cMenuRecordingItem::IncrementCounte - totalEntries++; - if (New) - newEntries++; -+#ifdef USE_LIEMIEXT -+#ifdef USE_WAREAGLEICON -+ switch (Setup.ShowRecTime + Setup.ShowRecDate + Setup.ShowRecLength) { -+ case 0: -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s %s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, name)); -+ else -+ SetText(cString::sprintf("%s", name)); -+ break; -+ case 1: -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s %d\t%s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, totalEntries, name)); -+ else -+ SetText(cString::sprintf("%d\t%s", totalEntries, name)); -+ break; -+ case 2: -+ default: -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s (%d/%d)\t%s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, totalEntries, newEntries, name)); -+ else -+ SetText(cString::sprintf("%d\t%d\t%s", totalEntries, newEntries, name)); -+ break; -+ case 3: -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s (%d/%d)\t\t%s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, totalEntries, newEntries, name)); -+ else -+ SetText(cString::sprintf("%d\t%d\t\t%s", totalEntries, newEntries, name)); -+ break; -+ } -+#else -+ switch (Setup.ShowRecTime + Setup.ShowRecDate + Setup.ShowRecLength) { -+ case 0: -+ SetText(cString::sprintf("%s", name)); -+ break; -+ case 1: -+ SetText(cString::sprintf("%d\t%s", totalEntries, name)); -+ break; -+ case 2: -+ default: -+ SetText(cString::sprintf("%d\t%d\t%s", totalEntries, newEntries, name)); -+ break; -+ case 3: -+ SetText(cString::sprintf("%d\t%d\t\t%s", totalEntries, newEntries, name)); -+ break; -+ } -+#endif /* WAREAGLEICON */ -+#else -+#ifdef USE_WAREAGLEICON -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s (%d/%d)\t%s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, totalEntries, newEntries, name)); -+ else -+#endif /* WAREAGLEICON */ - SetText(cString::sprintf("%d\t%d\t%s", totalEntries, newEntries, name)); -+#endif /* LIEMIEXT */ - } - -+#ifdef USE_LIEMIEXT -+// --- cMenuRenameRecording -------------------------------------------------- -+ -+class cMenuRenameRecording : public cOsdMenu { -+private: -+ int lifetime; -+ int priority; -+ char name[MaxFileName]; -+ char path[MaxFileName]; -+ cOsdItem *marksItem, *resumeItem; -+ bool isResume, isMarks; -+ cRecording *recording; -+public: -+ cMenuRenameRecording(cRecording *Recording); -+ virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuRenameRecording"; } -+#endif /* GRAPHTFT */ -+}; -+ -+cMenuRenameRecording::cMenuRenameRecording(cRecording *Recording) -+:cOsdMenu(tr("Rename recording"), 12) -+{ -+ cMarks marks; -+ -+ recording = Recording; -+ priority = recording->priority; -+ lifetime = recording->lifetime; -+ -+ char* p = strrchr(recording->Name(), '~'); -+ if (p) { -+ p++; -+ Utf8Strn0Cpy(name, p, sizeof(name)); -+ Utf8Strn0Cpy(path, recording->Name(), sizeof(path)); -+ p = strrchr(path, '~'); -+ if (p) -+ p[0] = 0; -+ } -+ else { -+ Utf8Strn0Cpy(name, recording->Name(), sizeof(name)); -+ Utf8Strn0Cpy(path, "", sizeof(path)); -+ } -+ Add(new cMenuEditStrItem(tr("Name"), name, sizeof(name), tr(FileNameChars))); -+ Add(new cMenuEditRecPathItem(tr("Path"), path, sizeof(path) )); -+ Add(new cMenuEditIntItem(tr("Priority"), &priority, 0, MAXPRIORITY )); -+ Add(new cMenuEditIntItem(tr("Lifetime"), &lifetime, 0, MAXLIFETIME )); -+ -+ Add(new cOsdItem("", osUnknown, false)); -+ -+ Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Date"), *DayDateTime(recording->start)), osUnknown, false)); -+ -+ cChannel *channel = Channels.GetByChannelID(((cRecordingInfo *)recording->Info())->ChannelID()); -+ if (channel) -+ Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Channel"), *ChannelString(channel, 0)), osUnknown, false)); -+ -+ cIndexFile *index = new cIndexFile(recording->FileName(), false); -+ int recLen = 0; -+ if (index) { -+ recLen = index->Last() / FRAMESPERSEC; -+ Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Length"), *IndexToHMSF(index->Last())), osUnknown, false)); -+ delete index; -+ } -+ -+ int dirSize = DirSizeMB(recording->FileName()); -+ cString bitRate = recLen ? cString::sprintf(" (%.2f MBit/s)", 8.0 * dirSize / recLen) : cString(""); -+ Add(new cOsdItem((dirSize > 9999) ? cString::sprintf("%s:\t%.2f GB%s", tr("Size"), dirSize / 1024.0, *bitRate) : cString::sprintf("%s:\t%d MB%s", tr("Size"), dirSize, *bitRate), osUnknown, false)); -+ -+ Add(new cOsdItem("", osUnknown, false)); -+ -+ isMarks = marks.Load(recording->FileName()) && marks.Count(); -+ marksItem = new cOsdItem(tr("Delete marks information?"), osUser1, isMarks); -+ Add(marksItem); -+ -+ cResumeFile ResumeFile(recording->FileName()); -+ isResume = (ResumeFile.Read() != -1); -+ resumeItem = new cOsdItem(tr("Delete resume information?"), osUser2, isResume); -+ Add(resumeItem); -+} -+ -+eOSState cMenuRenameRecording::ProcessKey(eKeys Key) -+{ -+ eOSState state = cOsdMenu::ProcessKey(Key); -+ -+ if (state == osUnknown) { -+ if (Key == kOk) { -+ char buffer[MaxFileName]; -+ if (Utf8StrLen(path)) -+ snprintf(buffer, sizeof(buffer), "%s~%s", path, name); -+ else -+ snprintf(buffer, sizeof(buffer), "%s", name); -+ if (recording->Rename(buffer, &priority, &lifetime)) { -+ Recordings.ChangeState(); -+ Recordings.TouchUpdate(); -+ return osRecordings; -+ } -+ else -+ Skins.Message(mtError, tr("Error while accessing recording!")); -+ } -+ return osContinue; -+ } -+ else if (state == osUser1) { -+ if (isMarks && Interface->Confirm(tr("Delete marks information?"))) { -+ cMarks marks; -+ marks.Load(recording->FileName()); -+ cMark *mark = marks.First(); -+ while (mark) { -+ cMark *nextmark = marks.Next(mark); -+ marks.Del(mark); -+ mark = nextmark; -+ } -+ marks.Save(); -+ isMarks = false; -+ marksItem->SetSelectable(isMarks); -+ SetCurrent(First()); -+ Display(); -+ } -+ return osContinue; -+ } -+ else if (state == osUser2) { -+ if (isResume && Interface->Confirm(tr("Delete resume information?"))) { -+ cResumeFile ResumeFile(recording->FileName()); -+ ResumeFile.Delete(); -+ isResume = false; -+ resumeItem->SetSelectable(isResume); -+ SetCurrent(First()); -+ Display(); -+ } -+ return osContinue; -+ } -+ return state; -+} -+#endif /* LIEMIEXT */ -+ - // --- cMenuRecordings ------------------------------------------------------- - - cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus) -+#ifdef USE_LIEMIEXT -+:cOsdMenu(Base ? Base : tr("Recordings"), 9, 7, 7) -+#else - :cOsdMenu(Base ? Base : tr("Recordings"), 9, 7) -+#endif /* LIEMIEXT */ - { - base = Base ? strdup(Base) : NULL; - level = Setup.RecordingDirs ? Level : -1; -@@ -1922,7 +2637,12 @@ void cMenuRecordings::Set(bool Refresh) - for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { - if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == '~')) { - cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level); -+#ifdef USE_PINPLUGIN -+ if ((*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) -+ && (!cStatus::MsgReplayProtected(GetRecording(Item), Item->Name(), base, Item->IsDirectory(), true))) { -+#else - if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) { -+#endif /* PINPLUGIN */ - Add(Item); - LastItem = Item; - free(LastItemText); -@@ -1972,13 +2692,43 @@ eOSState cMenuRecordings::Play(void) - { - cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); - if (ri) { -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgReplayProtected(GetRecording(ri), ri->Name(), base, ri->IsDirectory()) == true) -+ return osContinue; -+#endif /* PINPLUGIN */ - if (ri->IsDirectory()) - Open(); - else { - cRecording *recording = GetRecording(ri); - if (recording) { -+#ifdef USE_DVDARCHIVE -+ int mountRet = MOUNT_DVD_REPLAY; -+ if (recording->IsOnlyOnDvd()) { -+ mountRet = recording->MountDvd(); -+ } -+ if (mountRet == MOUNT_DVD_REPLAY) { -+ cReplayControl::SetRecording(recording->FileName(), recording->Title()); -+ return osReplay; -+ } -+ else if (mountRet == MOUNT_DVD_LAUNCH_DVD_PLUGIN) { -+ //launch DVD plugin here -+ cPlugin *p = cPluginManager::GetPlugin("dvd"); -+ cOsdObject *osd = NULL; -+ if (p) { -+ osd = p->MainMenuAction(); -+ delete osd; -+ osd = NULL; -+ return osEnd; -+ } -+ else { -+ Skins.Message(mtError, tr("DVD plugin is not installed!")); -+ Skins.Flush(); -+ } -+ } -+#else - cReplayControl::SetRecording(recording->FileName(), recording->Title()); - return osReplay; -+#endif /* DVDARCHIVE */ - } - } - } -@@ -2076,12 +2826,34 @@ eOSState cMenuRecordings::Commands(eKeys - return osContinue; - } - -+#ifdef USE_LIEMIEXT -+eOSState cMenuRecordings::Rename(void) -+{ -+ if (HasSubMenu() || Count() == 0) -+ return osContinue; -+ cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); -+ if (ri && !ri->IsDirectory()) { -+ cRecording *recording = GetRecording(ri); -+ if (recording) -+ return AddSubMenu(new cMenuRenameRecording(recording)); -+ } -+ return osContinue; -+} -+#endif /* LIEMIEXT */ -+ - eOSState cMenuRecordings::ProcessKey(eKeys Key) - { - bool HadSubMenu = HasSubMenu(); - eOSState state = cOsdMenu::ProcessKey(Key); - - if (state == osUnknown) { -+#ifdef USE_SORTRECORDS -+ const char *RecordingsSortModeTexts[MAXSORTMODES]; -+ RecordingsSortModeTexts[0] = tr("main dir alphabetically, subdirs flexible"); -+ RecordingsSortModeTexts[1] = tr("main dir by date, subdirs flexible"); -+ RecordingsSortModeTexts[2] = tr("all alphabetically"); -+ RecordingsSortModeTexts[3] = tr("all by date"); -+#endif /* SORTRECORDS */ - switch (Key) { - case kPlay: - case kOk: return Play(); -@@ -2090,7 +2862,26 @@ eOSState cMenuRecordings::ProcessKey(eKe - case kYellow: return Delete(); - case kInfo: - case kBlue: return Info(); -+#ifdef USE_SORTRECORDS -+ case k0: Setup.RecordingsSortMode = ++Setup.RecordingsSortMode % MAXSORTMODES; -+ Set(true); -+ Skins.Message(mtStatus, cString::sprintf("%s %d: %s", tr("Sorting"), Setup.RecordingsSortMode, RecordingsSortModeTexts[Setup.RecordingsSortMode])); -+ return osContinue; -+ case k1...k7: return Commands(Key); -+ case k8: return Rename(); -+ case k9: Recordings.ToggleSortOrder(); -+ Set(true); -+ return osContinue; -+#elif defined (USE_LIEMIEXT) -+ case k0: DirOrderState = !DirOrderState; -+ Set(true); -+ return osContinue; -+ case k8: return Rename(); -+ case k9: -+ case k1...k7: return Commands(Key); -+#else - case k1...k9: return Commands(Key); -+#endif /* LIEMIEXT & SORTRECORDS */ - case kNone: if (Recordings.StateChanged(recordingsState)) - Set(true); - break; -@@ -2139,6 +2930,9 @@ void cMenuSetupBase::Store(void) - class cMenuSetupOSD : public cMenuSetupBase { - private: - const char *useSmallFontTexts[3]; -+#ifdef USE_LIEMIEXT -+ const char *mainMenuTitle[MAXMAINMENUTITLE]; -+#endif /* LIEMIEXT */ - int osdLanguageIndex; - int numSkins; - int originalSkinIndex; -@@ -2154,6 +2948,9 @@ public: - cMenuSetupOSD(void); - virtual ~cMenuSetupOSD(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupOsd"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupOSD::cMenuSetupOSD(void) -@@ -2189,12 +2986,21 @@ void cMenuSetupOSD::Set(void) - useSmallFontTexts[0] = tr("never"); - useSmallFontTexts[1] = tr("skin dependent"); - useSmallFontTexts[2] = tr("always"); -+#ifdef USE_LIEMIEXT -+ mainMenuTitle[0]=tr("default"); -+ mainMenuTitle[1]=tr("VDR - text"); -+ mainMenuTitle[2]=tr("text"); -+ mainMenuTitle[3]=tr("VDR - version"); -+#endif /* LIEMIEXT */ - Clear(); - SetSection(tr("OSD")); - Add(new cMenuEditStraItem(tr("Setup.OSD$Language"), &osdLanguageIndex, I18nNumLanguagesWithLocale(), &I18nLanguages()->At(0))); - Add(new cMenuEditStraItem(tr("Setup.OSD$Skin"), &skinIndex, numSkins, skinDescriptions)); - if (themes.NumThemes()) - Add(new cMenuEditStraItem(tr("Setup.OSD$Theme"), &themeIndex, themes.NumThemes(), themes.Descriptions())); -+#ifdef USE_WAREAGLEICON -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$WarEagle icons"), &data.WarEagleIcons)); -+#endif /* WAREAGLEICON */ - Add(new cMenuEditIntItem( tr("Setup.OSD$Left"), &data.OSDLeft, 0, MAXOSDWIDTH)); - Add(new cMenuEditIntItem( tr("Setup.OSD$Top"), &data.OSDTop, 0, MAXOSDHEIGHT)); - Add(new cMenuEditIntItem( tr("Setup.OSD$Width"), &data.OSDWidth, MINOSDWIDTH, MAXOSDWIDTH)); -@@ -2216,6 +3022,24 @@ void cMenuSetupOSD::Set(void) - Add(new cMenuEditBoolItem(tr("Setup.OSD$Scroll wraps"), &data.MenuScrollWrap)); - Add(new cMenuEditBoolItem(tr("Setup.OSD$Menu key closes"), &data.MenuKeyCloses)); - Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs)); -+#ifdef USE_LIEMIEXT -+ Add(new cMenuEditStraItem(tr("Setup.OSD$Main menu title"), &data.MainMenuTitle, MAXMAINMENUTITLE, mainMenuTitle)); -+ if (data.MainMenuTitle == 1 || data.MainMenuTitle == 2) -+ Add(new cMenuEditStrItem(tr("Setup.OSD$- Text"), data.CustomMainMenuTitle, sizeof(data.CustomMainMenuTitle))); -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$Main menu command position"), &data.MenuCmdPosition, tr("bottom"), tr("top"))); -+#endif /* LIEMIEXT */ -+#ifdef USE_VALIDINPUT -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$Show valid input"), &data.ShowValidInput)); -+#endif /* VALIDINPUT */ -+#ifdef USE_SOFTOSD -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$Use SoftOSD"), &data.UseSoftOsd)); -+ if (data.UseSoftOsd) { -+ Add(new cMenuEditIntItem( tr("Setup.OSD$SoftOSD Rate"), &data.SoftOsdRate, 10, 100)); -+ Add(new cMenuEditIntItem( tr("Setup.OSD$SoftOSD FadeIn Steps"), &data.SoftOsdFadeinSteps, 1, 100)); -+ Add(new cMenuEditIntItem( tr("Setup.OSD$SoftOSD FadeOut Steps"), &data.SoftOsdFadeoutSteps, 1, 100)); -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$SoftOSD Palette Only"), &data.SoftOsdPaletteOnly)); -+ } -+#endif /* SOFTOSD */ - SetCurrent(Get(current)); - Display(); - } -@@ -2264,6 +3088,12 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys - - int oldSkinIndex = skinIndex; - int oldOsdLanguageIndex = osdLanguageIndex; -+#ifdef USE_LIEMIEXT -+ int oldMainMenuTitle = data.MainMenuTitle; -+#endif /* LIEMIEXT */ -+#ifdef USE_SOFTOSD -+ bool newUseSoftOsd = data.UseSoftOsd; -+#endif /* SOFTOSD */ - eOSState state = cMenuSetupBase::ProcessKey(Key); - - if (ModifiedApperance) -@@ -2286,6 +3116,25 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys - Set(); - I18nSetLanguage(OriginalOSDLanguage); - } -+ -+#ifdef USE_LIEMIEXT -+ if (data.MainMenuTitle != oldMainMenuTitle) -+ Set(); -+#endif /* LIEMIEXT */ -+#ifdef USE_SOFTOSD -+ if (data.UseSoftOsd != newUseSoftOsd) -+ Set(); -+#endif /* SOFTOSD */ -+#ifdef USE_CMDRECCMDI18N -+ if (Key == kOk) { -+ // try to load translated command files if available, otherwise fallback to defaults -+ LoadCommandsI18n(Commands,AddDirectory(ConfigDirectory, "commands.conf"), true); -+ LoadCommandsI18n(RecordingCommands, AddDirectory(ConfigDirectory,"reccmds.conf"), true); -+#ifdef USE_TIMERCMD -+ LoadCommandsI18n(TimerCommands, AddDirectory(ConfigDirectory, "timercmds.conf"), true); -+#endif /* TIMERCMD */ -+ } -+#endif /* CMDRECCMDI18N */ - return state; - } - -@@ -2293,12 +3142,18 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys - - class cMenuSetupEPG : public cMenuSetupBase { - private: -+#ifdef USE_NOEPG -+ const char *noEPGModes[2]; -+#endif /* NOEPG */ - int originalNumLanguages; - int numLanguages; - void Setup(void); - public: - cMenuSetupEPG(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupEpg"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupEPG::cMenuSetupEPG(void) -@@ -2315,11 +3170,19 @@ void cMenuSetupEPG::Setup(void) - { - int current = Current(); - -+#ifdef USE_NOEPG -+ noEPGModes[0] = tr("Blacklist"); -+ noEPGModes[1] = tr("Whitelist"); -+#endif /* NOEPG */ -+ - Clear(); - - Add(new cMenuEditIntItem( tr("Setup.EPG$EPG scan timeout (h)"), &data.EPGScanTimeout)); - Add(new cMenuEditIntItem( tr("Setup.EPG$EPG bugfix level"), &data.EPGBugfixLevel, 0, MAXEPGBUGFIXLEVEL)); - Add(new cMenuEditIntItem( tr("Setup.EPG$EPG linger time (min)"), &data.EPGLinger, 0)); -+#ifdef USE_LIEMIEXT -+ Add(new cMenuEditBoolItem(tr("Setup.EPG$Show progress bar"), &data.ShowProgressBar)); -+#endif /* LIEMIEXT */ - Add(new cMenuEditBoolItem(tr("Setup.EPG$Set system time"), &data.SetSystemTime)); - if (data.SetSystemTime) - Add(new cMenuEditTranItem(tr("Setup.EPG$Use time from transponder"), &data.TimeTransponder, &data.TimeSource)); -@@ -2328,6 +3191,15 @@ void cMenuSetupEPG::Setup(void) - for (int i = 0; i < numLanguages; i++) - // TRANSLATORS: note the singular! - Add(new cMenuEditStraItem(tr("Setup.EPG$Preferred language"), &data.EPGLanguages[i], I18nLanguages()->Size(), &I18nLanguages()->At(0))); -+#ifdef USE_DDEPGENTRY -+ Add(new cMenuEditIntItem( tr("Setup.EPG$Period for double EPG search(min)"), &data.DoubleEpgTimeDelta)); -+ Add(new cMenuEditBoolItem(tr("Setup.EPG$Extern double Epg entry"), &data.DoubleEpgAction, tr("adjust"), tr("delete"))); -+ Add(new cMenuEditBoolItem(tr("Setup.EPG$Mix intern and extern EPG"), &data.MixEpgAction)); -+ Add(new cMenuEditBoolItem(tr("Setup.EPG$Disable running VPS event"), &data.DisableVPS)); -+#endif /* DDEPGENTRY */ -+#ifdef USE_NOEPG -+ Add(new cMenuEditStraItem(tr("Setup.EPG$Mode of noEPG-Patch"), &data.noEPGMode, 2, noEPGModes)); -+#endif /* NOEPG */ - - SetCurrent(Get(current)); - Display(); -@@ -2384,6 +3256,10 @@ eOSState cMenuSetupEPG::ProcessKey(eKeys - - class cMenuSetupDVB : public cMenuSetupBase { - private: -+#ifdef USE_DVBSETUP -+ const char *ChannelBlockers[7]; -+ const char *ChannelBlockerModes[4]; -+#endif /* DVBSETUP */ - int originalNumAudioLanguages; - int numAudioLanguages; - int originalNumSubtitleLanguages; -@@ -2394,6 +3270,9 @@ private: - public: - cMenuSetupDVB(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupDvb"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupDVB::cMenuSetupDVB(void) -@@ -2422,6 +3301,21 @@ void cMenuSetupDVB::Setup(void) - { - int current = Current(); - -+#ifdef USE_DVBSETUP -+ ChannelBlockers[0] = tr("none"); -+ ChannelBlockers[1] = tr("qam256"); -+ ChannelBlockers[2] = tr("dvb-c"); -+ ChannelBlockers[3] = tr("dvb-s"); -+ ChannelBlockers[4] = tr("blacklist"); -+ ChannelBlockers[5] = tr("whitelist"); -+ ChannelBlockers[6] = tr("all"); -+ -+ ChannelBlockerModes[0] = tr("none"); -+ ChannelBlockerModes[1] = tr("has decoder"); -+ ChannelBlockerModes[2] = tr("is primary"); -+ ChannelBlockerModes[3] = tr("has decoder + is primary"); -+#endif /* DVBSETUP */ -+ - Clear(); - - Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDevice::NumDevices())); -@@ -2442,6 +3336,14 @@ void cMenuSetupDVB::Setup(void) - Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9)); - Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10)); - } -+#ifdef USE_DVBSETUP -+ Add(new cMenuEditBoolItem(tr("Setup.DVB$Use AC3-Transfer Fix"), &data.DolbyTransferFix)); -+ Add(new cMenuEditStraItem(tr("Setup.DVB$Channel Blocker"), &data.ChannelBlocker, 7, ChannelBlockers)); -+ Add(new cMenuEditStraItem(tr("Setup.DVB$Channel Blocker Filter Mode"), &data.ChannelBlockerMode, 4, ChannelBlockerModes)); -+#endif /* DVBSETUP */ -+#ifdef USE_SYNCEARLY -+ Add(new cMenuEditBoolItem(tr("Setup.DVB$Use Sync Early Patch"), &data.UseSyncEarlyPatch)); -+#endif /* SYNCEARLY */ - - SetCurrent(Get(current)); - Display(); -@@ -2523,6 +3425,9 @@ private: - public: - cMenuSetupLNB(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupLnb"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupLNB::cMenuSetupLNB(void) -@@ -2537,6 +3442,23 @@ void cMenuSetupLNB::Setup(void) - - Clear(); - -+#ifdef USE_LNBSHARE -+ int numSatDevices = 0; -+ for (int i = 0; i < cDevice::NumDevices(); i++) { -+ if (cDevice::GetDevice(i)->ProvidesSource(cSource::stSat)) numSatDevices++; -+ } -+ if (numSatDevices > 1) { -+ char tmp[30]; -+ for (int i = 1; i <= cDevice::NumDevices(); i++) { -+ if (cDevice::GetDevice(i - 1)->ProvidesSource(cSource::stSat)) { -+ sprintf( tmp, tr("Setup.LNB$DVB device %d uses LNB No."), i); -+ Add(new cMenuEditIntItem( tmp, &data.CardUsesLNBnr[i - 1], 1, numSatDevices )); -+ } -+ } -+ } -+ Add(new cMenuEditBoolItem(tr("Setup.LNB$Log LNB usage"), &data.VerboseLNBlog)); -+#endif /* LNBSHARE */ -+ - Add(new cMenuEditBoolItem(tr("Setup.LNB$Use DiSEqC"), &data.DiSEqC)); - if (!data.DiSEqC) { - Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"), &data.LnbSLOF)); -@@ -2553,6 +3475,10 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys - int oldDiSEqC = data.DiSEqC; - eOSState state = cMenuSetupBase::ProcessKey(Key); - -+#ifdef USE_LNBSHARE -+ if (Key == kOk) cDevice::SetLNBnr(); -+#endif /* LNBSHARE */ -+ - if (Key != kNone && data.DiSEqC != oldDiSEqC) - Setup(); - return state; -@@ -2603,6 +3529,9 @@ private: - public: - cMenuSetupCAM(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupCam"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupCAM::cMenuSetupCAM(void) -@@ -2676,12 +3605,73 @@ eOSState cMenuSetupCAM::ProcessKey(eKeys - // --- cMenuSetupRecord ------------------------------------------------------ - - class cMenuSetupRecord : public cMenuSetupBase { -+#ifdef USE_SORTRECORDS -+private: -+ const char *RecordingsSortModeTexts[MAXSORTMODES]; -+#endif /* SORTRECORDS */ -+#ifdef USE_DELTIMESHIFTREC -+private: -+ const char *DelTimeshiftRecValues[3]; -+#endif /* DELTIMESHIFTREC */ - public: - cMenuSetupRecord(void); -+#ifdef USE_DVLVIDPREFER -+ eOSState ProcessKey(eKeys key); -+ -+private: -+ void Set(void); -+ -+ int tmpNVidPrefer, -+ tmpUseVidPrefer; -+#endif /* DVLVIDPREFER */ - }; - -+#ifdef USE_DVLVIDPREFER - cMenuSetupRecord::cMenuSetupRecord(void) - { -+ Set(); -+} -+ -+eOSState cMenuSetupRecord::ProcessKey(eKeys key) -+{ -+ eOSState s = cMenuSetupBase::ProcessKey(key);; -+ -+ if (key != kNone) { -+ if (tmpNVidPrefer != data.nVidPrefer || tmpUseVidPrefer != data.UseVidPrefer) { -+ int cur = Current(); -+ -+ tmpNVidPrefer = data.nVidPrefer; -+ tmpUseVidPrefer = data.UseVidPrefer; -+ -+ Clear(); -+ Set(); -+ SetCurrent(Get(cur)); -+ Display(); -+ cMenuSetupBase::ProcessKey(kNone); -+ return osContinue; -+ } -+ } -+ return s; -+} -+ -+#else -+cMenuSetupRecord::cMenuSetupRecord(void) -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLVIDPREFER -+void cMenuSetupRecord::Set(void) -+#endif /* DVLVIDPREFER */ -+{ -+#ifdef USE_SORTRECORDS -+ RecordingsSortModeTexts[0] = tr("main dir alphabetically, subdirs flexible"); -+ RecordingsSortModeTexts[1] = tr("main dir by date, subdirs flexible"); -+ RecordingsSortModeTexts[2] = tr("all alphabetically"); -+ RecordingsSortModeTexts[3] = tr("all by date"); -+#endif /* SORTRECORDS */ -+#ifdef USE_DELTIMESHIFTREC -+ DelTimeshiftRecValues[0] = tr("request"); -+ DelTimeshiftRecValues[1] = tr("no"); -+ DelTimeshiftRecValues[2] = tr("yes"); -+#endif /* DELTIMESHIFTREC */ - SetSection(tr("Recording")); - Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at start (min)"), &data.MarginStart)); - Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at stop (min)"), &data.MarginStop)); -@@ -2690,14 +3680,61 @@ cMenuSetupRecord::cMenuSetupRecord(void) - Add(new cMenuEditIntItem( tr("Setup.Recording$Default lifetime (d)"), &data.DefaultLifetime, 0, MAXLIFETIME)); - Add(new cMenuEditIntItem( tr("Setup.Recording$Pause priority"), &data.PausePriority, 0, MAXPRIORITY)); - Add(new cMenuEditIntItem( tr("Setup.Recording$Pause lifetime (d)"), &data.PauseLifetime, 0, MAXLIFETIME)); -+#ifdef USE_DOLBYINREC -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Record Dolby Digital"), &data.UseDolbyInRecordings)); -+#endif /* DOLBYINREC */ -+#ifdef USE_DVLVIDPREFER -+ tmpNVidPrefer = data.nVidPrefer; -+ tmpUseVidPrefer = data.UseVidPrefer; -+ -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Video directory policy"), &data.UseVidPrefer)); -+ if (data.UseVidPrefer != 0) { -+ char tmp[ 64 ]; -+ Add(new cMenuEditIntItem(tr("Setup.Recording$Number of video directories"), &data.nVidPrefer, 1, DVLVIDPREFER_MAX)); -+ for (int zz = 0; zz < data.nVidPrefer; zz++) { -+ sprintf(tmp, tr("Setup.Recording$Video %d priority"), zz); -+ Add(new cMenuEditIntItem(tmp, &data.VidPreferPrio[ zz ], 0, 99)); -+ sprintf(tmp, tr("Setup.Recording$Video %d min. free MB"), zz); -+ Add(new cMenuEditIntItem(tmp, &data.VidPreferSize[ zz ], -1, 99999)); -+ } -+ } -+#endif /* DVLVIDPREFER */ - Add(new cMenuEditBoolItem(tr("Setup.Recording$Use episode name"), &data.UseSubtitle)); -+#ifdef USE_DVLFRIENDLYFNAMES -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Friendly filenames"), &data.UseFriendlyFNames)); -+#endif /* DVLFRIENDLYFNAMES */ - Add(new cMenuEditBoolItem(tr("Setup.Recording$Use VPS"), &data.UseVps)); - Add(new cMenuEditIntItem( tr("Setup.Recording$VPS margin (s)"), &data.VpsMargin, 0)); - Add(new cMenuEditBoolItem(tr("Setup.Recording$Mark instant recording"), &data.MarkInstantRecord)); - Add(new cMenuEditStrItem( tr("Setup.Recording$Name instant recording"), data.NameInstantRecord, sizeof(data.NameInstantRecord))); - Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 1, MAXINSTANTRECTIME)); - Add(new cMenuEditIntItem( tr("Setup.Recording$Max. video file size (MB)"), &data.MaxVideoFileSize, MINVIDEOFILESIZE, MAXVIDEOFILESIZE)); -+#ifdef USE_HARDLINKCUTTER -+ Add(new cMenuEditIntItem( tr("Setup.Recording$Max. recording size (GB)"), &data.MaxRecordingSize, MINRECORDINGSIZE, MAXRECORDINGSIZE)); -+#endif /* HARDLINKCUTTER */ - Add(new cMenuEditBoolItem(tr("Setup.Recording$Split edited files"), &data.SplitEditedFiles)); -+#ifdef USE_HARDLINKCUTTER -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Hard Link Cutter"), &data.HardLinkCutter)); -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ Add(new cMenuEditStraItem(tr("Setup.Recording$Delete timeshift recording"), &data.DelTimeshiftRec, 3, DelTimeshiftRecValues)); -+#endif /* DELTIMESHIFTREC */ -+#ifdef USE_LIEMIEXT -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Show date"), &data.ShowRecDate)); -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Show time"), &data.ShowRecTime)); -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Show length"), &data.ShowRecLength)); -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Show end of timer"), &data.ShowTimerStop)); -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ Add(new cMenuEditStraItem(tr("Setup.Recording$Sort recordings by"), &data.RecordingsSortMode, MAXSORTMODES, RecordingsSortModeTexts)); -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Sort directories before recordings"), &data.RecordingsSortDirsFirst)); -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Cutter auto delete"), &data.CutterAutoDelete)); -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Cutter adjust starttime"), &data.CutTime)); -+#endif /* CUTTIME */ - } - - // --- cMenuSetupReplay ------------------------------------------------------ -@@ -2715,6 +3752,31 @@ cMenuSetupReplay::cMenuSetupReplay(void) - Add(new cMenuEditBoolItem(tr("Setup.Replay$Multi speed mode"), &data.MultiSpeedMode)); - Add(new cMenuEditBoolItem(tr("Setup.Replay$Show replay mode"), &data.ShowReplayMode)); - Add(new cMenuEditIntItem(tr("Setup.Replay$Resume ID"), &data.ResumeID, 0, 99)); -+#ifdef USE_JUMPPLAY -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$Jump&Play"), &data.JumpPlay)); -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$Play&Jump"), &data.PlayJump)); -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$Pause at last mark"), &data.PauseLastMark)); -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$Reload marks"), &data.ReloadMarks)); -+#endif /* JUMPPLAY */ -+#ifdef USE_LIEMIEXT -+ Add(new cMenuEditIntItem(tr("Setup.Replay$Skip Seconds"), &data.JumpSeconds)); -+ Add(new cMenuEditIntItem(tr("Setup.Replay$Skip Seconds Slow"), &data.JumpSecondsSlow)); -+#endif /* LIEMIEXT */ -+#ifdef USE_DVDARCHIVE -+ static const char *dvddisplaymode[3]; -+ dvddisplaymode[0]=tr("Setup.Replay$Length"); -+ dvddisplaymode[1]=tr("Setup.Replay$Length / Number"); -+ dvddisplaymode[2]=tr("Setup.Replay$Number"); -+ Add(new cMenuEditStraItem(tr("Setup.Replay$DVD display mode"), &data.DvdDisplayMode,3,dvddisplaymode)); -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$DVD display leading zeros"), &data.DvdDisplayZeros)); -+ static const char *dvdtraymode[4]; -+ dvdtraymode[0]=tr("Setup.Replay$never"); -+ dvdtraymode[1]=tr("Setup.Replay$on begin"); -+ dvdtraymode[2]=tr("Setup.Replay$on end"); -+ dvdtraymode[3]=tr("Setup.Replay$on begin and end"); -+ Add(new cMenuEditStraItem(tr("Setup.Replay$Tray open"), &data.DvdTrayMode,4,dvdtraymode)); -+ Add(new cMenuEditIntItem( tr("Setup.Replay$Limit DVD to speed"), &data.DvdSpeedLimit, 0, 50)); -+#endif /* DVDARCHIVE */ - } - - void cMenuSetupReplay::Store(void) -@@ -2727,13 +3789,48 @@ void cMenuSetupReplay::Store(void) - // --- cMenuSetupMisc -------------------------------------------------------- - - class cMenuSetupMisc : public cMenuSetupBase { -+#ifdef USE_VOLCTRL -+private: -+ const char *lrChannelGroupsTexts[3]; -+ const char *lrForwardRewindTexts[3]; -+ void Setup(void); -+#endif /* VOLCTRL */ - public: - cMenuSetupMisc(void); -+#ifdef USE_VOLCTRL -+ virtual eOSState ProcessKey(eKeys Key); -+#endif /* VOLCTRL */ - }; - - cMenuSetupMisc::cMenuSetupMisc(void) - { -+#ifdef USE_VOLCTRL -+ lrChannelGroupsTexts[0] = tr("no"); -+ lrChannelGroupsTexts[1] = tr("Setup.Miscellaneous$only in channelinfo"); -+ lrChannelGroupsTexts[2] = tr("yes"); -+ lrForwardRewindTexts[0] = tr("no"); -+ lrForwardRewindTexts[1] = tr("Setup.Miscellaneous$only in progress display"); -+ lrForwardRewindTexts[2] = tr("yes"); -+#endif /* VOLCTRL */ - SetSection(tr("Miscellaneous")); -+#ifdef USE_VOLCTRL -+ Setup(); -+} -+ -+eOSState cMenuSetupMisc::ProcessKey(eKeys Key) -+{ -+ int newLRVolumeControl = data.LRVolumeControl; -+ eOSState state = cMenuSetupBase::ProcessKey(Key); -+ if (Key != kNone && data.LRVolumeControl != newLRVolumeControl) -+ Setup(); -+ return state; -+} -+ -+void cMenuSetupMisc::Setup(void) -+{ -+ int current = Current(); -+ Clear(); -+#endif /* VOLCTRL */ - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. event timeout (min)"), &data.MinEventTimeout)); - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. user inactivity (min)"), &data.MinUserInactivity)); - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"), &data.SVDRPTimeout)); -@@ -2741,9 +3838,77 @@ cMenuSetupMisc::cMenuSetupMisc(void) - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Channel entry timeout (ms)"), &data.ChannelEntryTimeout, 0)); - Add(new cMenuEditChanItem(tr("Setup.Miscellaneous$Initial channel"), &data.InitialChannel, tr("Setup.Miscellaneous$as before"))); - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Initial volume"), &data.InitialVolume, -1, 255, tr("Setup.Miscellaneous$as before"))); -+#ifdef USE_VOLCTRL -+ Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Volume ctrl with left/right"), &data.LRVolumeControl)); -+ if (data.LRVolumeControl) { -+ Add(new cMenuEditStraItem(tr("Setup.Miscellaneous$Channelgroups with left/right"), &data.LRChannelGroups, 3, lrChannelGroupsTexts)); -+ Add(new cMenuEditStraItem(tr("Setup.Miscellaneous$Search fwd/back with left/right"), &data.LRForwardRewind, 3, lrForwardRewindTexts)); -+ } -+ SetCurrent(Get(current)); -+ Display(); -+#endif /* VOLCTRL */ - Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Emergency exit"), &data.EmergencyExit)); -+#ifdef USE_LIRCSETTINGS -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat delay"), &data.LircRepeatDelay, 0, 1000)); -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat freq"), &data.LircRepeatFreq, 0, 1000)); -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat timeout"), &data.LircRepeatTimeout, 0, 5000)); -+#endif /* LIRCSETTINGS */ -+} -+ -+#ifdef USE_LIVEBUFFER -+// --- cMenuSetupLiveBuffer -------------------------------------------------- -+ -+class cMenuSetupLiveBuffer : public cMenuSetupBase { -+private: -+ void Setup(); -+public: -+ eOSState ProcessKey(eKeys Key); -+ cMenuSetupLiveBuffer(void); -+ }; -+ -+cMenuSetupLiveBuffer::cMenuSetupLiveBuffer(void) -+{ -+ SetSection("permanentes Timeshift"); -+ Setup(); - } - -+void cMenuSetupLiveBuffer::Setup(void) -+{ -+ int current=Current(); -+ Clear(); -+ Add(new cMenuEditBoolItem(tr("Permanent Timeshift"), &data.LiveBuffer)); -+ if (data.LiveBuffer) { -+ Add(new cMenuEditBoolItem(tr("Setup.LiveBuffer$Location"), &data.InRAM,tr("Setup.LiveBuffer$harddisk"),tr("Setup.LiveBuffer$memory"))); -+ if (data.InRAM) { -+ Add(new cMenuEditIntItem( tr("Setup.LiveBuffer$Buffer size in memory (MB)"), &data.MemBufSize, 5, 1000)); -+ Add(new cMenuEditBoolItem(tr("Setup.LiveBuffer$Extend to harddisk if necessary"), &data.ExtendBuffer)); -+ Add(new cMenuEditBoolItem(tr("Setup.LiveBuffer$Keep paused Buffer"), &data.KeepPaused)); -+ if (data.ExtendBuffer || data.KeepPaused) -+ Add(new cMenuEditIntItem(tr("Setup.LiveBuffer$Buffer size on harddisk (MB)"), &data.LiveBufferSize, 1, 100000)); -+ } -+ else { -+ Add(new cMenuEditIntItem( tr("Setup.LiveBuffer$Buffer size (MB)"), &data.LiveBufferSize, 1, 100000)); -+ Add(new cMenuEditBoolItem(tr("Setup.LiveBuffer$Keep paused Buffer"), &data.KeepPaused)); -+ } -+ } -+ SetCurrent(Get(current)); -+ Display(); -+} -+ -+eOSState cMenuSetupLiveBuffer::ProcessKey(eKeys Key) -+{ -+ int oldLiveBuffer = data.LiveBuffer; -+ int oldInRAM = data.InRAM; -+ int oldExtendBuffer = data.ExtendBuffer; -+ int oldKeepPaused = data.KeepPaused; -+ eOSState state = cMenuSetupBase::ProcessKey(Key); -+ -+ if (Key != kNone && (data.LiveBuffer != oldLiveBuffer || data.InRAM != oldInRAM || data.ExtendBuffer != oldExtendBuffer || data.KeepPaused != oldKeepPaused)) -+ Setup(); -+ return state; -+} -+ -+#endif /* LIVEBUFFER */ - // --- cMenuSetupPluginItem -------------------------------------------------- - - class cMenuSetupPluginItem : public cOsdItem { -@@ -2766,6 +3931,9 @@ class cMenuSetupPlugins : public cMenuSe - public: - cMenuSetupPlugins(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupPlugins"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupPlugins::cMenuSetupPlugins(void) -@@ -2815,6 +3983,9 @@ private: - public: - cMenuSetup(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetup"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetup::cMenuSetup(void) -@@ -2838,6 +4009,9 @@ void cMenuSetup::Set(void) - Add(new cOsdItem(hk(tr("Recording")), osUser6)); - Add(new cOsdItem(hk(tr("Replay")), osUser7)); - Add(new cOsdItem(hk(tr("Miscellaneous")), osUser8)); -+#ifdef USE_LIVEBUFFER -+ Add(new cOsdItem(hk(tr("Permanent Timeshift")),osLiveBuffer)); -+#endif /* LIVEBUFFER */ - if (cPluginManager::HasPlugins()) - Add(new cOsdItem(hk(tr("Plugins")), osUser9)); - Add(new cOsdItem(hk(tr("Restart")), osUser10)); -@@ -2868,6 +4042,9 @@ eOSState cMenuSetup::ProcessKey(eKeys Ke - case osUser8: return AddSubMenu(new cMenuSetupMisc); - case osUser9: return AddSubMenu(new cMenuSetupPlugins); - case osUser10: return Restart(); -+#ifdef USE_LIVEBUFFER -+ case osLiveBuffer: return AddSubMenu(new cMenuSetupLiveBuffer); -+#endif /* LIVEBUFFER */ - default: ; - } - if (I18nCurrentLanguage() != osdLanguage) { -@@ -2904,24 +4081,91 @@ cOsdObject *cMenuMain::pluginOsdObject = - cMenuMain::cMenuMain(eOSState State) - :cOsdMenu("") - { -+#ifdef USE_SETUP -+ // Load Menu Configuration -+ char *menuXML = NULL; -+ asprintf(&menuXML, "%s/setup/vdr-menu.%s.xml", cPlugin::ConfigDirectory(), Setup.OSDLanguage); -+ if (access(menuXML, 04) == -1) -+ asprintf(&menuXML, "%s/setup/vdr-menu.xml", cPlugin::ConfigDirectory()); -+ subMenu.LoadXml(menuXML); -+ free(menuXML); -+ nrDynamicMenuEntries=0; -+#endif /* SETUP */ - replaying = false; - stopReplayItem = NULL; - cancelEditingItem = NULL; - stopRecordingItem = NULL; - recordControlsState = 0; -+ -+#ifdef USE_MENUORG -+ MenuOrgPatch::EnterRootMenu(); -+#endif /* MENUORG */ -+ - Set(); - - // Initial submenus: - -+#ifdef USE_MAINMENUHOOKS -+ cOsdMenu *menu = NULL; -+#endif /* MAINMENUHOOKS */ - switch (State) { -+#ifdef USE_MAINMENUHOOKS -+ case osSchedule: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osSchedule", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osSchedule: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuSchedule; -+ } -+ break; -+ case osChannels: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osChannels", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osChannels: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuChannels; -+ } -+ break; -+ case osTimers: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osTimers", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osTimers: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuTimers; -+ } -+ break; -+ case osRecordings: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osRecordings", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osRecordings: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuRecordings(NULL, 0, true); -+ } -+ break; -+ case osSetup: menu = new cMenuSetup; break; -+ case osCommands: menu = new cMenuCommands(tr("Commands"), &Commands); break; -+#else - case osSchedule: AddSubMenu(new cMenuSchedule); break; - case osChannels: AddSubMenu(new cMenuChannels); break; - case osTimers: AddSubMenu(new cMenuTimers); break; - case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break; - case osSetup: AddSubMenu(new cMenuSetup); break; - case osCommands: AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); break; -+#endif /* MAINMENUHOOKS */ - default: break; - } -+#ifdef USE_MAINMENUHOOKS -+ if (menu) -+ AddSubMenu(menu); -+#endif /* MAINMENUHOOKS */ - } - - cOsdObject *cMenuMain::PluginOsdObject(void) -@@ -2931,38 +4175,155 @@ cOsdObject *cMenuMain::PluginOsdObject(v - return o; - } - -+#ifdef USE_SETUP -+void cMenuMain::Set(int current) -+#else - void cMenuMain::Set(void) -+#endif /* SETUP */ - { - Clear(); - SetTitle("VDR"); - SetHasHotkeys(); - -+#ifdef USE_MENUORG -+ if (MenuOrgPatch::IsCustomMenuAvailable()) { -+ MenuItemDefinitions* menuItems = MenuOrgPatch::MainMenuItems(); -+ for (MenuItemDefinitions::iterator i = menuItems->begin(); i != menuItems->end(); i++) { -+ cOsdItem* osdItem = NULL; -+ if ((*i)->IsCustomOsdItem()) { -+ osdItem = (*i)->CustomOsdItem(); -+ if (osdItem && !(*i)->IsSeparatorItem()) -+ osdItem->SetText(hk(osdItem->Text())); -+ } -+ else if ((*i)->IsPluginItem()) { -+ const char *item = (*i)->PluginMenuEntry(); -+ if (item) -+ osdItem = new cMenuPluginItem(hk(item), (*i)->PluginIndex()); -+ } -+ if (osdItem) { -+ Add(osdItem); -+ if ((*i)->IsSelected()) -+ SetCurrent(osdItem); -+ } -+ } -+ } -+ else { -+#endif /* MENUORG */ -+ -+#ifdef USE_SETUP -+ stopReplayItem = NULL; -+ cancelEditingItem = NULL; -+ stopRecordingItem = NULL; -+ -+ // remember initial dynamic MenuEntries added -+ nrDynamicMenuEntries = Count(); -+ for (cSubMenuNode *node = subMenu.GetMenuTree()->First(); node; node = subMenu.GetMenuTree()->Next(node)) { -+ cSubMenuNode::Type type = node->GetType(); -+ if (type==cSubMenuNode::PLUGIN) { -+ const char *item = node->GetPluginMainMenuEntry(); -+#ifdef USE_PINPLUGIN -+ if (item && !cStatus::MsgPluginProtected(cPluginManager::GetPlugin(node->GetPluginIndex()), true)) -+#else -+ if (item) -+#endif /* PINPLUGIN */ -+ Add(new cMenuPluginItem(hk(item), node->GetPluginIndex())); -+ } -+ else if (type==cSubMenuNode::MENU) { -+ cString item = cString::sprintf("%s%s", node->GetName(), subMenu.GetMenuSuffix()); -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected(item, true)) -+ Add(new cOsdItem(hk(item), osUnknown, node)); -+#else -+ Add(new cOsdItem(hk(item))); -+#endif /* PINPLUGIN */ -+ } -+ else if ((type==cSubMenuNode::COMMAND) || (type==cSubMenuNode::THREAD)) { -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected(node->GetName(), true)) -+ Add(new cOsdItem(hk(node->GetName()), osUnknown, node)); -+#else -+ Add(new cOsdItem(hk(node->GetName()))); -+#endif /* PINPLUGIN */ -+ } -+ else if (type==cSubMenuNode::SYSTEM) { -+ const char *item = node->GetName(); -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgMenuItemProtected(item, true)) -+ ; // nothing to do ;) -+ else -+#endif /* PINPLUGIN */ -+ if (strcmp(item, "Schedule") == 0) -+ Add(new cOsdItem(hk(tr("Schedule")), osSchedule)); -+ else if (strcmp(item, "Channels") == 0) -+ Add(new cOsdItem(hk(tr("Channels")), osChannels)); -+ else if (strcmp(item, "Timers") == 0) -+ Add(new cOsdItem(hk(tr("Timers")), osTimers)); -+ else if (strcmp(item, "Recordings") == 0) -+ Add(new cOsdItem(hk(tr("Recordings")), osRecordings)); -+ else if (strcmp(item, "Setup") == 0) -+ Add(new cOsdItem(hk(tr("Setup")), osSetup)); -+ else if (strcmp(item, "Commands") == 0 && Commands.Count()>0) -+ Add(new cOsdItem(hk(tr("Commands")), osCommands)); -+ } -+ } -+ if (current >=0 && current<Count()) { -+ SetCurrent(Get(current)); -+ } -+ -+#else /* NO SETUP */ -+ - // Basic menu items: - -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected("Schedule", true)) Add(new cOsdItem(hk(tr("Schedule")), osSchedule)); -+ if (!cStatus::MsgMenuItemProtected("Channels", true)) Add(new cOsdItem(hk(tr("Channels")), osChannels)); -+ if (!cStatus::MsgMenuItemProtected("Timers", true)) Add(new cOsdItem(hk(tr("Timers")), osTimers)); -+ if (!cStatus::MsgMenuItemProtected("Recordings", true)) Add(new cOsdItem(hk(tr("Recordings")), osRecordings)); -+#else - Add(new cOsdItem(hk(tr("Schedule")), osSchedule)); - Add(new cOsdItem(hk(tr("Channels")), osChannels)); - Add(new cOsdItem(hk(tr("Timers")), osTimers)); - Add(new cOsdItem(hk(tr("Recordings")), osRecordings)); -+#endif /* PINPLUGIN */ - - // Plugins: - - for (int i = 0; ; i++) { - cPlugin *p = cPluginManager::GetPlugin(i); - if (p) { -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgPluginProtected(p, true)) { -+#endif /* PINPLUGIN */ - const char *item = p->MainMenuEntry(); - if (item) - Add(new cMenuPluginItem(hk(item), i)); - } -+#ifdef USE_PINPLUGIN -+ } -+#endif /* PINPLUGIN */ - else - break; - } - - // More basic menu items: - -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected("Setup", true)) Add(new cOsdItem(hk(tr("Setup")), osSetup)); -+#else - Add(new cOsdItem(hk(tr("Setup")), osSetup)); -+#endif /* PINPLUGIN */ - if (Commands.Count()) -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected("Commands", true)) -+#endif /* PINPLUGIN */ - Add(new cOsdItem(hk(tr("Commands")), osCommands)); - -+#endif /* SETUP */ -+ -+#ifdef USE_MENUORG -+ } -+#endif /* MENUORG */ -+ - Update(true); - - Display(); -@@ -2971,13 +4332,40 @@ void cMenuMain::Set(void) - bool cMenuMain::Update(bool Force) - { - bool result = false; -- -+#ifdef USE_SETUP -+ cOsdItem *fMenu = NULL; -+ if (Force && subMenu.isTopMenu()) { -+ fMenu = First(); -+ nrDynamicMenuEntries = 0; -+ } -+ -+ if (subMenu.isTopMenu()) { -+#endif /* SETUP */ -+#ifdef USE_LIEMIEXT -+// this extension is not included in the original Liemikuutio -+ if (Setup.MainMenuTitle) { -+ if (Setup.MainMenuTitle == 1) -+ SetTitle(cString::sprintf("%s - %s", tr("VDR"), Setup.CustomMainMenuTitle)); -+ else if (Setup.MainMenuTitle == 2) -+ SetTitle(cString::sprintf("%s", Setup.CustomMainMenuTitle)); -+ else if (Setup.MainMenuTitle == 3) -+ SetTitle(cString::sprintf("%s %s", tr("VDR"), VDRVERSION)); -+ } -+ else -+#endif /* LIEMIEXT */ - // Title with disk usage: - if (FreeDiskSpace.HasChanged(Force)) { - //XXX -> skin function!!! - SetTitle(cString::sprintf("%s - %s", tr("VDR"), FreeDiskSpace.FreeDiskSpaceString())); - result = true; - } -+#ifdef USE_SETUP -+ } -+ else { -+ SetTitle(cString::sprintf("%s - %s", tr("VDR"), subMenu.GetParentMenuTitel())); -+ result = true; -+ } -+#endif /* SETUP */ - - bool NewReplaying = cControl::Control() != NULL; - if (Force || NewReplaying != replaying) { -@@ -2985,6 +4373,9 @@ bool cMenuMain::Update(bool Force) - // Replay control: - if (replaying && !stopReplayItem) - // TRANSLATORS: note the leading blank! -+#ifdef USE_LIEMIEXT -+ if (Setup.MenuCmdPosition) Ins(stopReplayItem = new cOsdItem(tr(" Stop replaying"), osStopReplay)); else -+#endif /* LIEMIEXT */ - Add(stopReplayItem = new cOsdItem(tr(" Stop replaying"), osStopReplay)); - else if (stopReplayItem && !replaying) { - Del(stopReplayItem->Index()); -@@ -2999,6 +4390,9 @@ bool cMenuMain::Update(bool Force) - bool CutterActive = cCutter::Active(); - if (CutterActive && !cancelEditingItem) { - // TRANSLATORS: note the leading blank! -+#ifdef USE_LIEMIEXT -+ if (Setup.MenuCmdPosition) Ins(cancelEditingItem = new cOsdItem(tr(" Cancel editing"), osCancelEdit)); else -+#endif /* LIEMIEXT */ - Add(cancelEditingItem = new cOsdItem(tr(" Cancel editing"), osCancelEdit)); - result = true; - } -@@ -3019,6 +4413,9 @@ bool cMenuMain::Update(bool Force) - while ((s = cRecordControls::GetInstantId(s)) != NULL) { - cOsdItem *item = new cOsdItem(osStopRecord); - item->SetText(cString::sprintf("%s%s", tr(STOP_RECORDING), s)); -+#ifdef USE_LIEMIEXT -+ if (Setup.MenuCmdPosition) Ins(item); else -+#endif /* LIEMIEXT */ - Add(item); - if (!stopRecordingItem) - stopRecordingItem = item; -@@ -3026,6 +4423,12 @@ bool cMenuMain::Update(bool Force) - result = true; - } - -+#ifdef USE_SETUP -+ // adjust nrDynamicMenuEntries -+ if (fMenu != NULL) -+ nrDynamicMenuEntries = fMenu->Index(); -+#endif /* SETUP */ -+ - return result; - } - -@@ -3036,13 +4439,69 @@ eOSState cMenuMain::ProcessKey(eKeys Key - eOSState state = cOsdMenu::ProcessKey(Key); - HadSubMenu |= HasSubMenu(); - -+#ifdef USE_PINPLUGIN -+ cOsdItem* item = Get(Current()); -+ -+ if (item && item->Text() && state != osBack && state != osContinue && Key != kNone) -+ if (cStatus::MsgMenuItemProtected(item->Text())) -+ return osContinue; -+#endif /* PINPLUGIN */ -+ -+#ifdef USE_MAINMENUHOOKS -+ cOsdMenu *menu = NULL; -+#endif /* MAINMENUHOOKS */ - switch (state) { -+#ifdef USE_MAINMENUHOOKS -+ case osSchedule: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osSchedule", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osSchedule: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuSchedule; -+ } -+ break; -+ case osChannels: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osChannels", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osChannels: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuChannels; -+ } -+ break; -+ case osTimers: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osTimers", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osTimers: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuTimers; -+ } -+ break; -+ case osRecordings: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osRecordings", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osRecordings: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuRecordings; -+ } -+ break; -+ case osSetup: menu = new cMenuSetup; break; -+ case osCommands: menu = new cMenuCommands(tr("Commands"), &Commands); break; -+#else - case osSchedule: return AddSubMenu(new cMenuSchedule); - case osChannels: return AddSubMenu(new cMenuChannels); - case osTimers: return AddSubMenu(new cMenuTimers); - case osRecordings: return AddSubMenu(new cMenuRecordings); - case osSetup: return AddSubMenu(new cMenuSetup); - case osCommands: return AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); -+#endif /* MAINMENUHOOKS */ - case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) { - cOsdItem *item = Get(Current()); - if (item) { -@@ -3061,6 +4520,9 @@ eOSState cMenuMain::ProcessKey(eKeys Key - if (item) { - cPlugin *p = cPluginManager::GetPlugin(item->PluginIndex()); - if (p) { -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgPluginProtected(p)) { -+#endif /* PINPLUGIN */ - cOsdObject *menu = p->MainMenuAction(); - if (menu) { - if (menu->IsMenu()) -@@ -3072,9 +4534,60 @@ eOSState cMenuMain::ProcessKey(eKeys Key - } - } - } -+#ifdef USE_PINPLUGIN -+ } -+#endif /* PINPLUGIN */ - state = osEnd; - } - break; -+#ifdef USE_SETUP -+ case osBack: { -+ int newCurrent = 0; -+ if (subMenu.Up(&newCurrent)) { -+ Set(newCurrent); -+ return osContinue; -+ } -+ else -+ return osEnd; -+ } -+ break; -+#endif /* SETUP */ -+#ifdef USE_MENUORG -+ case osBack: { -+ if (MenuOrgPatch::IsCustomMenuAvailable()) { -+ bool leavingMenuSucceeded = MenuOrgPatch::LeaveSubMenu(); -+ Set(); -+ stopReplayItem = NULL; -+ cancelEditingItem = NULL; -+ stopRecordingItem = NULL; -+ recordControlsState = 0; -+ Update(true); -+ Display(); -+ if (leavingMenuSucceeded) -+ return osContinue; -+ else -+ return osEnd; -+ } -+ } -+ break; -+ case osUser1: { -+ if (MenuOrgPatch::IsCustomMenuAvailable()) { -+ MenuOrgPatch::EnterSubMenu(Get(Current())); -+ Set(); -+ return osContinue; -+ } -+ } -+ break; -+ case osUser2: { -+ if (MenuOrgPatch::IsCustomMenuAvailable()) { -+ cOsdMenu* osdMenu = MenuOrgPatch::Execute(Get(Current())); -+ if (osdMenu) -+ return AddSubMenu(osdMenu); -+ return osEnd; -+ } -+ } -+ break; -+#endif /* MENUORG */ - default: switch (Key) { - case kRecord: - case kRed: if (!HadSubMenu) -@@ -3091,9 +4604,67 @@ eOSState cMenuMain::ProcessKey(eKeys Key - case kBlue: if (!HadSubMenu) - state = replaying ? osStopReplay : cReplayControl::LastReplayed() ? osReplay : osContinue; - break; -+#ifdef USE_SETUP -+ case kOk: if (state == osUnknown) { -+ cString buffer; -+#ifdef USE_PINPLUGIN -+ cSubMenuNode *node = Get(Current())->SubMenu(); -+#else -+ int index = Current()-nrDynamicMenuEntries; -+ cSubMenuNode *node = subMenu.GetNode(index); -+#endif /* PINPLUGIN */ -+ -+ if (node != NULL) { -+ if (node->GetType() == cSubMenuNode::MENU) { -+#ifdef USE_PINPLUGIN -+ subMenu.Down(node, Current()); -+#else -+ subMenu.Down(index); -+#endif /* PINPLUGIN */ -+ } -+ else if (node->GetType() == cSubMenuNode::COMMAND) { -+ bool confirmed = true; -+ if (node->CommandConfirm()) { -+ buffer = cString::sprintf("%s?", node->GetName()); -+ confirmed = Interface->Confirm(buffer); -+ } -+ if (confirmed) { -+ const char *Result = subMenu.ExecuteCommand(node->GetCommand()); -+ if (Result) -+ return AddSubMenu(new cMenuText(node->GetName(), Result, fontFix)); -+ return osEnd; -+ } -+ } -+ else if (node->GetType() == cSubMenuNode::THREAD) { -+ bool confirmed = true; -+ if (node->CommandConfirm()) { -+ buffer = cString::sprintf("%s?", node->GetName()); -+ confirmed = Interface->Confirm(buffer); -+ } -+ if (confirmed) { -+ buffer = cString::sprintf("%s", node->GetCommand()); -+ cExecCmdThread *execcmd = new cExecCmdThread(node->GetCommand()); -+ if (execcmd->Start()) -+ dsyslog("executing command '%s'", *buffer); -+ else -+ esyslog("ERROR: can't execute command '%s'", *buffer); -+ return osEnd; -+ } -+ } -+ } -+ -+ Set(); -+ return osContinue; -+ } -+ break; -+#endif /* SETUP */ - default: break; - } - } -+#ifdef USE_MAINMENUHOOKS -+ if (menu) -+ return AddSubMenu(menu); -+#endif /* MAINMENUHOOKS */ - if (!HasSubMenu() && Update(HadSubMenu)) - Display(); - if (Key != kNone) { -@@ -3237,7 +4808,14 @@ cChannel *cDisplayChannel::NextAvailable - if (Direction) { - while (Channel) { - Channel = Direction > 0 ? Channels.Next(Channel) : Channels.Prev(Channel); -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgChannelProtected(0, Channel) == false) -+#endif /* PINPLUGIN */ -+#ifdef USE_LNBSHARE -+ if (Channel && !Channel->GroupSep() && cDevice::GetDevice(Channel, 0, true) && cDevice::PrimaryDevice()->GetMaxBadPriority(Channel) < 0) -+#else - if (Channel && !Channel->GroupSep() && cDevice::GetDevice(Channel, 0, true)) -+#endif /* LNBSHARE */ - return Channel; - } - } -@@ -3295,6 +4873,13 @@ eOSState cDisplayChannel::ProcessKey(eKe - case kLeft: - case kRight|k_Repeat: - case kRight: -+#ifdef USE_VOLCTRL -+ if (Setup.LRVolumeControl && !Setup.LRChannelGroups) { -+ cRemote::Put(NORMALKEY(Key) == kLeft ? kVolDn : kVolUp, true); -+ break; -+ } -+ // else fall through -+#endif /* VOLCTRL */ - case kNext|k_Repeat: - case kNext: - case kPrev|k_Repeat: -@@ -3454,6 +5039,17 @@ void cDisplayVolume::Process(eKeys Key) - eOSState cDisplayVolume::ProcessKey(eKeys Key) - { - switch (Key) { -+#ifdef USE_VOLCTRL -+ case kLeft|k_Repeat: -+ case kLeft: -+ case kRight|k_Repeat: -+ case kRight: -+ if (Setup.LRVolumeControl) { -+ cRemote::Put(NORMALKEY(Key) == kLeft ? kVolDn : kVolUp, true); -+ break; -+ } -+ // else fall through -+#endif /* VOLCTRL */ - case kVolUp|k_Repeat: - case kVolUp: - case kVolDn|k_Repeat: -@@ -3703,6 +5299,10 @@ eOSState cDisplaySubtitleTracks::Process - - cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) - { -+#ifdef USE_DVLRECSCRIPTADDON -+ const cChannel *recChan = NULL; -+ char *chanName = NULL; -+#endif /* DVLRECSCRIPTADDON */ - // We're going to manipulate an event here, so we need to prevent - // others from modifying any EPG data: - cSchedulesLock SchedulesLock; -@@ -3747,12 +5347,57 @@ cRecordControl::cRecordControl(cDevice * - return; - } - -+#ifdef USE_DVLRECSCRIPTADDON -+ if (timer) -+ if ((recChan = timer->Channel()) != NULL) -+ chanName = strdup(recChan->Name()); -+ if (chanName != NULL) { -+ cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName, chanName); -+ free(chanName); -+ } -+ else -+#endif /* DVLRECSCRIPTADDON */ - cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName); - isyslog("record %s", fileName); - if (MakeDirs(fileName, true)) { - const cChannel *ch = timer->Channel(); -+#if defined (USE_LIVEBUFFER) || defined (USE_TTXTSUBS) -+#ifdef USE_LIVEBUFFER -+ int startFrame=-1; -+ int endFrame=0; -+ cLiveBuffer *liveBuffer = cLiveBufferManager::InLiveBuffer(timer, &startFrame, &endFrame); -+ if (liveBuffer) { -+ timer->SetFlags(tfhasLiveBuf); -+ liveBuffer->SetStartFrame(startFrame); -+ if (endFrame) { -+ liveBuffer->CreateIndexFile(fileName, 0, endFrame); -+ Timers.Del(timer); -+ Timers.SetModified(); -+ timer = NULL; -+ Recording.WriteInfo(); -+ Recordings.AddByName(fileName); -+ return; -+ } -+ } -+#endif /* LIVEBUFFER */ -+#ifdef USE_TTXTSUBS -+ cTtxtSubsRecorderBase *subsRecorder = cVDRTtxtsubsHookListener::Hook()->NewTtxtSubsRecorder(device, ch); -+#endif /* TTXTSUBS */ -+ recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids() -+#ifdef USE_TTXTSUBS -+ ,subsRecorder -+#endif /* TTXTSUBS */ -+#ifdef USE_LIVEBUFFER -+ ,liveBuffer -+#endif /* LIVEBUFFER */ -+ ); -+#else - recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids()); -+#endif /* LIVEBUFFER || TTXTSUBS */ - if (device->AttachReceiver(recorder)) { -+#ifdef USE_TTXTSUBS -+ if (subsRecorder) subsRecorder->DeviceAttach(); -+#endif /* TTXTSUBS */ - Recording.WriteInfo(); - cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true); - if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo() -@@ -3809,11 +5454,25 @@ bool cRecordControl::GetEvent(void) - void cRecordControl::Stop(void) - { - if (timer) { -+#ifdef USE_DVLRECSCRIPTADDON -+ char *chanName = NULL; -+ const cChannel *recChan = NULL; -+ -+ recChan = timer -> Channel(); -+ if (recChan != NULL) -+ chanName = strdup(recChan -> Name()); -+#endif /* DVLRECSCRIPTADDON */ - DELETENULL(recorder); - timer->SetRecording(false); - timer = NULL; - cStatus::MsgRecording(device, NULL, fileName, false); -+#ifdef USE_DVLRECSCRIPTADDON -+ cRecordingUserCommand::InvokeCommand(RUC_AFTERRECORDING, fileName, chanName); -+ if (chanName != NULL) -+ free(chanName); -+#else - cRecordingUserCommand::InvokeCommand(RUC_AFTERRECORDING, fileName); -+#endif /* DVLRECSCRIPTADDON */ - } - } - -@@ -3860,15 +5519,35 @@ bool cRecordControls::Start(cTimer *Time - int Priority = Timer ? Timer->Priority() : Pause ? Setup.PausePriority : Setup.DefaultPriority; - cDevice *device = cDevice::GetDevice(channel, Priority, false); - if (device) { -+#ifdef USE_LNBSHARE -+ cDevice *tmpDevice; -+ while ((tmpDevice = device->GetBadDevice(channel))) { -+ if (tmpDevice->Replaying() == false) { -+// Stop(tmpDevice); -+ if (tmpDevice->IsPrimaryDevice() ) -+ tmpDevice->SwitchChannelForced(channel, true); -+ else -+ tmpDevice->SwitchChannelForced(channel, false); -+ } else -+ tmpDevice->SwitchChannelForced(channel, false); -+ } -+#endif /* LNBSHARE */ - dsyslog("switching device %d to channel %d", device->DeviceNumber() + 1, channel->Number()); - if (!device->SwitchChannel(channel, false)) { - ShutdownHandler.RequestEmergencyExit(); - return false; - } -+#ifdef USE_LIVEBUFFER -+ if (!Timer || Timer->Matches() || cLiveBufferManager::InLiveBuffer(Timer)) { -+#else - if (!Timer || Timer->Matches()) { -+#endif /* LIVEBUFFER */ - for (int i = 0; i < MAXRECORDCONTROLS; i++) { - if (!RecordControls[i]) { - RecordControls[i] = new cRecordControl(device, Timer, Pause); -+#ifdef USE_PINPLUGIN -+ cStatus::MsgRecordingFile(RecordControls[i]->FileName()); -+#endif /* PINPLUGIN */ - return RecordControls[i]->Process(time(NULL)); - } - } -@@ -3999,12 +5678,22 @@ bool cRecordControls::StateChanged(int & - - // --- cReplayControl -------------------------------------------------------- - -+#ifdef USE_LIEMIEXT -+#define REPLAYCONTROLSKIPLIMIT 9 // s -+#define REPLAYCONTROLSKIPSECONDS 90 // s -+#define REPLAYCONTROLSKIPTIMEOUT 5000 // ms -+#endif /* LIEMIEXT */ -+ - cReplayControl *cReplayControl::currentReplayControl = NULL; - char *cReplayControl::fileName = NULL; - char *cReplayControl::title = NULL; - - cReplayControl::cReplayControl(void) -+#ifdef USE_JUMPPLAY -+:cDvbPlayerControl(fileName), marks(fileName) -+#else - :cDvbPlayerControl(fileName) -+#endif /* JUMPPLAY */ - { - currentReplayControl = this; - displayReplay = NULL; -@@ -4012,10 +5701,28 @@ cReplayControl::cReplayControl(void) - lastCurrent = lastTotal = -1; - lastPlay = lastForward = false; - lastSpeed = -2; // an invalid value -+#ifdef USE_LIEMIEXT -+ lastSkipKey = kNone; -+ lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; -+ lastSkipTimeout.Set(0); -+#endif /* LIEMIEXT */ - timeoutShow = 0; - timeSearchActive = false; -+#ifndef USE_JUMPPLAY - marks.Load(fileName); -+#endif /* JUMPPLAY */ - cRecording Recording(fileName); -+#ifdef USE_DVDARCHIVE -+ canJumpChapters = (Recording.GetDvdType() == DVD_VIDEO_ARCHIVE_TYPE); -+ dvdchapters = NULL; -+ if (canJumpChapters) { -+ const char *ret = Recording.GetDvdChapters(); -+ if (ret) -+ dvdchapters = strdup(ret); -+ else -+ canJumpChapters=false; -+ } -+#endif /* DVDARCHIVE */ - cStatus::MsgReplaying(this, Recording.Name(), Recording.FileName(), true); - SetTrackDescriptions(false); - } -@@ -4023,12 +5730,67 @@ cReplayControl::cReplayControl(void) - cReplayControl::~cReplayControl() - { - Hide(); -+#ifdef USE_DVDARCHIVE -+ free(dvdchapters); -+#endif /* DVDARCHIVE */ - cStatus::MsgReplaying(this, NULL, fileName, false); - Stop(); - if (currentReplayControl == this) - currentReplayControl = NULL; - } - -+#ifdef USE_DELTIMESHIFTREC -+void cReplayControl::Stop(void) -+{ -+ int dummy; -+ bool playing = GetIndex(dummy, dummy, false); -+ cRecordControl* rc = cRecordControls::GetRecordControl(fileName); -+ -+ if (playing && rc && rc->InstantId()) { -+ isyslog("found Timeshiftrecording"); -+ -+ if ((Setup.DelTimeshiftRec != 0 ) || (Interface->Confirm(tr("Delete recording?")))) { -+ cRecordControl *rc = cRecordControls::GetRecordControl(fileName); -+ if (rc) { -+ cTimer *timer = rc->Timer(); -+ if (timer) { -+ const char* reccmd_backup = cRecordingUserCommand::GetCommand(); -+ cRecordingUserCommand::SetCommand(NULL); -+ -+ timer->Skip(); -+ cRecordControls::Process(time(NULL)); -+ if (timer->IsSingleEvent()) { -+ isyslog("deleting timer %s", *timer->ToDescr()); -+ Timers.Del(timer); -+ } -+ Timers.SetModified(); -+ -+ // restore reccmd -+ cRecordingUserCommand::SetCommand(reccmd_backup); -+ } -+ } -+ isyslog("stop replaying %s", fileName); -+ cDvbPlayerControl::Stop(); -+ -+ if (Setup.DelTimeshiftRec != 1) { -+ cRecording *recording = Recordings.GetByName(fileName);; -+ if (recording) { -+ if (recording->Delete()) { -+ Recordings.DelByName(fileName); -+ ClearLastReplayed(fileName); -+ return; -+ } -+ else -+ Skins.Message(mtError, tr("Error while deleting recording!")); -+ } -+ } -+ } -+ else -+ cDvbPlayerControl::Stop(); -+ } -+} -+#endif /* DELTIMESHIFTREC */ -+ - void cReplayControl::SetRecording(const char *FileName, const char *Title) - { - free(fileName); -@@ -4123,6 +5885,9 @@ bool cReplayControl::ShowProgress(bool I - if (Initial) { - if (title) - displayReplay->SetTitle(title); -+#ifdef USE_OSDMAXITEMS -+ displayReplay->SetButtons(tr("Jump"), tr("Skip +60s"), tr("Skip -60s"), tr("Button$Stop")); -+#endif /* OSDMAXITEMS */ - lastCurrent = lastTotal = -1; - } - if (Total != lastTotal) { -@@ -4244,8 +6009,15 @@ void cReplayControl::MarkToggle(void) - ShowTimed(2); - bool Play, Forward; - int Speed; -+#ifdef USE_JUMPPLAY -+ if (GetReplayMode(Play, Forward, Speed) && !Play) { -+ Goto(Current, true); -+ displayFrames = true; -+ } -+#else - if (GetReplayMode(Play, Forward, Speed) && !Play) - Goto(Current, true); -+#endif /* JUMPPLAY */ - } - marks.Save(); - } -@@ -4258,8 +6030,22 @@ void cReplayControl::MarkJump(bool Forwa - if (GetIndex(Current, Total)) { - cMark *m = Forward ? marks.GetNext(Current) : marks.GetPrev(Current); - if (m) { -+#ifdef USE_JUMPPLAY -+ bool Play2, Forward2; -+ int Speed; -+ if (Setup.JumpPlay && GetReplayMode(Play2, Forward2, Speed) && -+ Play2 && Forward && m->position < Total - SecondsToFrames(3)) { -+ Goto(m->position); -+ Play(); -+ } -+ else { -+ Goto(m->position, true); -+ displayFrames = true; -+ } -+#else - Goto(m->position, true); - displayFrames = true; -+#endif /* JUMPPLAY */ - } - } - } -@@ -4288,11 +6074,43 @@ void cReplayControl::MarkMove(bool Forwa - } - } - -+#ifdef USE_DVDARCHIVE -+void cReplayControl::ChaptersJump(bool Forward) -+{ -+ int Current, Total; -+ if (GetIndex(Current, Total)) { -+ int position = -1; -+ char *buf, *pos; -+ cString old1("-1"); -+ cString old2("-1"); -+ buf = strdup(dvdchapters); -+ pos = strtok(buf, ","); -+ while (pos != NULL && position == -1) { -+ if (pos && atoi(pos) > Current) -+ position = Forward ? atoi(pos) : ((Current - atoi(old1)) <= (3*FRAMESPERSEC)) ? atoi(old2) : atoi(old1); -+ old2 = old1; -+ old1 = strdup(pos); -+ if(position == -1) pos = strtok(NULL, ","); -+ } -+ if (!pos && !Forward) -+ position = ((Current - atoi(old1)) <= (3*FRAMESPERSEC)) ? atoi(old2) : atoi(old1); -+ if (position >= 0) { -+ Goto(position); -+ Play(); -+ } -+ } -+} -+ -+#endif /* DVDARCHIVE */ - void cReplayControl::EditCut(void) - { - if (fileName) { - Hide(); -+#ifdef USE_CUTTERQUEUE -+ if (!cCutter::Active() || Interface->Confirm(tr("Cutter already running - Add to cutting queue?"))) { -+#else - if (!cCutter::Active()) { -+#endif /* CUTTERQUEUE */ - if (!marks.Count()) - Skins.Message(mtError, tr("No editing marks defined!")); - else if (!cCutter::Start(fileName)) -@@ -4314,7 +6132,11 @@ void cReplayControl::EditTest(void) - if (!m) - m = marks.GetNext(Current); - if (m) { -+#ifdef USE_JUMPPLAY -+ if ((m->Index() & 0x01) != 0 && !Setup.PlayJump) -+#else - if ((m->Index() & 0x01) != 0) -+#endif /* JUMPPLAY */ - m = marks.Next(m); - if (m) { - Goto(m->position - SecondsToFrames(3)); -@@ -4336,6 +6158,9 @@ eOSState cReplayControl::ProcessKey(eKey - { - if (!Active()) - return osEnd; -+#ifdef USE_JUMPPLAY -+ marks.Reload(); -+#endif /* JUMPPLAY */ - if (visible) { - if (timeoutShow && time(NULL) > timeoutShow) { - Hide(); -@@ -4353,7 +6178,32 @@ eOSState cReplayControl::ProcessKey(eKey - TimeSearchProcess(Key); - return osContinue; - } -+#ifdef USE_DVDARCHIVE -+ bool isOnMark = false; -+ if (canJumpChapters) { -+ int Current, Total; -+ GetIndex(Current, Total); -+ cMark *m = marks.Get(Current); -+ if (m && (m->position == Current)) isOnMark = true; -+ } -+#endif /* DVDARCHIVE */ - bool DoShowMode = true; -+#ifdef USE_VOLCTRL -+ if (Setup.LRVolumeControl && (!Setup.LRForwardRewind || (Setup.LRForwardRewind == 1 && !visible))) { -+ switch (Key) { -+ // Left/Right volume control -+ case kLeft|k_Repeat: -+ case kLeft: -+ case kRight|k_Repeat: -+ case kRight: -+ cRemote::Put(NORMALKEY(Key) == kLeft ? kVolDn : kVolUp, true); -+ return osContinue; -+ break; -+ default: -+ break; -+ } -+ } -+#endif /* VOLCTRL */ - switch (Key) { - // Positioning: - case kPlay: -@@ -4371,25 +6221,82 @@ eOSState cReplayControl::ProcessKey(eKey - case kFastFwd: - case kRight: Forward(); break; - case kRed: TimeSearch(); break; -+#ifdef USE_LIEMIEXT -+ case kGreen|k_Repeat: -+ case kGreen: SkipSeconds(-Setup.JumpSeconds); break; -+ case kYellow|k_Repeat: -+ case kYellow: SkipSeconds( Setup.JumpSeconds); break; -+ case k1|k_Repeat: -+ case k1: SkipSeconds(-Setup.JumpSecondsSlow); break; -+ case k3|k_Repeat: -+ case k3: SkipSeconds( Setup.JumpSecondsSlow); break; -+ case kPrev|k_Repeat: -+ case kPrev: if (lastSkipTimeout.TimedOut()) { -+ lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; -+ lastSkipKey = kPrev; -+ } -+ else if (RAWKEY(lastSkipKey) != kPrev && lastSkipSeconds > (2 * REPLAYCONTROLSKIPLIMIT)) { -+ lastSkipSeconds /= 2; -+ lastSkipKey = kNone; -+ } -+ lastSkipTimeout.Set(REPLAYCONTROLSKIPTIMEOUT); -+ SkipSeconds(-lastSkipSeconds); break; -+ case kNext|k_Repeat: -+ case kNext: if (lastSkipTimeout.TimedOut()) { -+ lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; -+ lastSkipKey = kNext; -+ } -+ else if (RAWKEY(lastSkipKey) != kNext && lastSkipSeconds > (2 * REPLAYCONTROLSKIPLIMIT)) { -+ lastSkipSeconds /= 2; -+ lastSkipKey = kNone; -+ } -+ lastSkipTimeout.Set(REPLAYCONTROLSKIPTIMEOUT); -+ SkipSeconds(lastSkipSeconds); break; -+#else - case kGreen|k_Repeat: - case kGreen: SkipSeconds(-60); break; - case kYellow|k_Repeat: - case kYellow: SkipSeconds( 60); break; -+#endif /* LIEMIEXT */ - case kStop: - case kBlue: Hide(); - Stop(); - return osEnd; -+#ifdef USE_DVDARCHIVE -+ case kDvdChapterJumpForward|k_Repeat: -+ case kDvdChapterJumpForward: if (canJumpChapters && !isOnMark) { -+ ChaptersJump(true); -+ } -+ else { -+ DoShowMode = false; -+ MarkMove(true); -+ } -+ break; -+ case kDvdChapterJumpBack|k_Repeat: -+ case kDvdChapterJumpBack: if (canJumpChapters && !isOnMark) { -+ ChaptersJump(false); -+ } -+ else { -+ DoShowMode = false; -+ MarkMove(false); -+ } -+ break; -+#endif /* DVDARCHIVE */ - default: { - DoShowMode = false; - switch (Key) { - // Editing: - case kMarkToggle: MarkToggle(); break; -+#ifndef USE_LIEMIEXT - case kPrev|k_Repeat: - case kPrev: -+#endif /* LIEMIEXT */ - case kMarkJumpBack|k_Repeat: - case kMarkJumpBack: MarkJump(false); break; -+#ifndef USE_LIEMIEXT - case kNext|k_Repeat: - case kNext: -+#endif /* LIEMIEXT */ - case kMarkJumpForward|k_Repeat: - case kMarkJumpForward: MarkJump(true); break; - case kMarkMoveBack|k_Repeat: -@@ -4409,7 +6316,16 @@ eOSState cReplayControl::ProcessKey(eKey - else - Show(); - break; -+#ifdef USE_DELTIMESHIFTREC -+ case kBack: { cRecordControl* rc = cRecordControls::GetRecordControl(fileName); -+ if (rc && rc->InstantId()) -+ return osEnd; -+ else -+ return osRecordings; -+ } -+#else - case kBack: return osRecordings; -+#endif /* DELTIMESHIFTREC */ - default: return osUnknown; - } - } -diff -ruNp vdr-1.7.0/menu.h vdr-1.7.0-extensions/menu.h ---- vdr-1.7.0/menu.h 2008-02-10 17:01:53.000000000 +0100 -+++ vdr-1.7.0-extensions/menu.h 2009-04-09 20:48:48.000000000 +0200 -@@ -18,6 +18,9 @@ - #include "menuitems.h" - #include "recorder.h" - #include "skins.h" -+#ifdef USE_SETUP -+#include "submenu.h" -+#endif /* SETUP */ - - class cMenuText : public cOsdMenu { - private: -@@ -29,12 +32,19 @@ public: - void SetText(const char *Text); - virtual void Display(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuText"; } -+#endif /* GRAPHTFT */ - }; - - class cMenuEditTimer : public cOsdMenu { - private: - cTimer *timer; - cTimer data; -+#ifdef USE_LIEMIEXT -+ char name[MaxFileName]; -+ char path[MaxFileName]; -+#endif /* LIEMIEXT */ - int channel; - bool addIfConfirmed; - cMenuEditDateItem *firstday; -@@ -43,6 +53,9 @@ public: - cMenuEditTimer(cTimer *Timer, bool New = false); - virtual ~cMenuEditTimer(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuTimerEdit"; } -+#endif /* GRAPHTFT */ - }; - - class cMenuEvent : public cOsdMenu { -@@ -52,22 +65,37 @@ public: - cMenuEvent(const cEvent *Event, bool CanSwitch = false, bool Buttons = false); - virtual void Display(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuEvent"; } -+#endif /* GRAPHTFT */ - }; - - class cMenuMain : public cOsdMenu { - private: -+#ifdef USE_SETUP -+ int nrDynamicMenuEntries; -+#endif /* SETUP */ - bool replaying; - cOsdItem *stopReplayItem; - cOsdItem *cancelEditingItem; - cOsdItem *stopRecordingItem; - int recordControlsState; - static cOsdObject *pluginOsdObject; -+#ifdef USE_SETUP -+ void Set(int current=0); -+ bool Update(bool Force = false); -+ cSubMenu subMenu; -+#else - void Set(void); - bool Update(bool Force = false); -+#endif /* SETUP */ - public: - cMenuMain(eOSState State = osUnknown); - virtual eOSState ProcessKey(eKeys Key); - static cOsdObject *PluginOsdObject(void); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuMain"; } -+#endif /* GRAPHTFT */ - }; - - class cDisplayChannel : public cOsdObject { -@@ -163,12 +191,18 @@ private: - eOSState Delete(void); - eOSState Info(void); - eOSState Commands(eKeys Key = kNone); -+#ifdef USE_LIEMIEXT -+ eOSState Rename(void); -+#endif /* LIEMIEXT */ - protected: - cRecording *GetRecording(cMenuRecordingItem *Item); - public: - cMenuRecordings(const char *Base = NULL, int Level = 0, bool OpenSubMenus = false); - ~cMenuRecordings(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuRecordings"; } -+#endif /* GRAPHTFT */ - }; - - class cRecordControl { -@@ -212,11 +246,21 @@ public: - class cReplayControl : public cDvbPlayerControl { - private: - cSkinDisplayReplay *displayReplay; -+#ifdef USE_JUMPPLAY -+ cMarksReload marks; -+#else - cMarks marks; -+#endif /* JUMPPLAY */ - bool visible, modeOnly, shown, displayFrames; - int lastCurrent, lastTotal; - bool lastPlay, lastForward; - int lastSpeed; -+#ifdef USE_LIEMIEXT -+ int lastSkipSeconds; -+ int lastSkipSecondsSlow; -+ eKeys lastSkipKey; -+ cTimeMs lastSkipTimeout; -+#endif /* LIEMIEXT */ - time_t timeoutShow; - bool timeSearchActive, timeSearchHide; - int timeSearchTime, timeSearchPos; -@@ -234,9 +278,17 @@ private: - void MarkMove(bool Forward); - void EditCut(void); - void EditTest(void); -+#ifdef USE_DVDARCHIVE -+ void ChaptersJump(bool Forward); -+ bool canJumpChapters; -+ char *dvdchapters; -+#endif /* DVDARCHIVE */ - public: - cReplayControl(void); - virtual ~cReplayControl(); -+#ifdef USE_DELTIMESHIFTREC -+ void Stop(void); -+#endif /* DELTIMESHIFTREC */ - virtual cOsdObject *GetInfo(void); - virtual eOSState ProcessKey(eKeys Key); - virtual void Show(void); -diff -ruNp vdr-1.7.0/menuitems.c vdr-1.7.0-extensions/menuitems.c ---- vdr-1.7.0/menuitems.c 2008-04-12 14:05:25.000000000 +0200 -+++ vdr-1.7.0-extensions/menuitems.c 2009-04-09 20:48:48.000000000 +0200 -@@ -32,9 +32,20 @@ cMenuEditItem::~cMenuEditItem() - free(name); - } - -+#ifdef USE_VALIDINPUT -+void cMenuEditItem::SetValue(const char *Value, bool HasPre, bool HasSucc) -+#else - void cMenuEditItem::SetValue(const char *Value) -+#endif /* VALIDINPUT */ - { - cString buffer = cString::sprintf("%s:\t%s", name, Value); -+#ifdef USE_VALIDINPUT -+ if (Setup.ShowValidInput) { -+ if (HasPre && HasSucc) buffer = cString::sprintf("%s:\t<%s>", name, Value); -+ else if (HasPre) buffer = cString::sprintf("%s:\t<%s", name, Value); -+ else if (HasSucc) buffer = cString::sprintf("%s:\t%s>", name, Value); -+ } -+#endif /* VALIDINPUT */ - SetText(buffer); - cStatus::MsgOsdCurrentItem(buffer); - } -@@ -126,7 +137,11 @@ void cMenuEditBoolItem::Set(void) - { - char buf[16]; - snprintf(buf, sizeof(buf), "%s", *value ? trueString : falseString); -+#ifdef USE_VALIDINPUT -+ SetValue(buf, *value, !*value); -+#else - SetValue(buf); -+#endif /* VALIDINPUT */ - } - - // --- cMenuEditBitItem ------------------------------------------------------ -@@ -619,6 +634,171 @@ eOSState cMenuEditStrItem::ProcessKey(eK - return osContinue; - } - -+#ifdef USE_LIEMIEXT -+// --- cMenuEditRecPathItem -------------------------------------------------- -+ -+cMenuEditRecPathItem::cMenuEditRecPathItem(const char* Name, char* Path, -+ int Length): cMenuEditStrItem(Name, Path, Length, tr(FileNameChars)) -+{ -+ SetBase(Path); -+} -+ -+cMenuEditRecPathItem::~cMenuEditRecPathItem() -+{ -+} -+ -+void cMenuEditRecPathItem::SetBase(const char* Path) -+{ -+ if (!Path) -+ base[0] = 0; -+ Utf8Strn0Cpy(base, Path, sizeof(base)); -+ char* p = strrchr(base, '~'); -+ if (p) -+ p[0] = 0; -+ else -+ base[0] = 0; -+} -+ -+void cMenuEditRecPathItem::FindNextLevel() -+{ -+ char item[MaxFileName]; -+ -+ for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) -+ { -+ char* p; -+ Utf8Strn0Cpy(item, recording->Name(), sizeof(item)); -+ stripspace(value); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ if (!lengthUtf8) -+ p = strchr(item, '~'); -+ else { -+ if (strstr(item, value) != item) -+ continue; -+ if (item[strlen(value)] != '~') -+ continue; -+ p = strchr(item + strlen(value) + 1, '~'); -+ } -+ if (!p) -+ continue; -+ p[0] = 0; -+ Utf8Strn0Cpy(base, value, length); -+ Utf8Strn0Cpy(value, item, length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ return; -+ } -+} -+ -+void cMenuEditRecPathItem::Find(bool Next) -+{ -+ char item[MaxFileName]; -+ char lastItem[MaxFileName] = ""; -+ -+ for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) -+ { -+ const char* recName = recording->Name(); -+ if (Utf8StrLen(base) && strstr(recName, base) != recName) -+ continue; -+ if (strlen(base) && recName[strlen(base)] != '~') -+ continue; -+ Utf8Strn0Cpy(item, recName, sizeof(item)); -+ char* p = strchr(item + strlen(base) + 1, '~'); -+ if (!p) -+ continue; -+ p[0] = 0; -+ if (!Next && (strcmp(item, value) == 0)) { -+ if (strlen(lastItem)) -+ Utf8Strn0Cpy(value, lastItem, length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ return; -+ } -+ if (strcmp(lastItem, item) != 0) { -+ if(Next && Utf8StrLen(lastItem) && strcmp(lastItem, value) == 0) { -+ Utf8Strn0Cpy(value, item, length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ return; -+ } -+ Utf8Strn0Cpy(lastItem, item, sizeof(lastItem)); -+ } -+ } -+} -+ -+void cMenuEditRecPathItem::SetHelpKeys(void) -+{ -+ cSkinDisplay::Current()->SetButtons(tr("Rename$Up"), tr("Rename$Down"), tr("Rename$Previous"), tr("Rename$Next")); -+} -+ -+eOSState cMenuEditRecPathItem::ProcessKey(eKeys Key) -+{ -+ switch (Key) { -+ case kLeft: -+ case kRed: // one level up -+ if (!InEditMode()) -+ return cMenuEditItem::ProcessKey(Key); -+ Utf8Strn0Cpy(value, base, lengthUtf8); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ SetBase(base); -+ pos = Utf8StrLen(base); -+ if (pos) -+ pos++; -+ if (!lengthUtf8) { -+ Utf8Strn0Cpy(value, " ", length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ } -+ break; -+ case kRight: -+ case kGreen: // one level down -+ if (InEditMode()) -+ FindNextLevel(); -+ else -+ EnterEditMode(); -+ -+ if (!lengthUtf8) { -+ Utf8Strn0Cpy(value, " ", length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ } -+ pos = Utf8StrLen(base); -+ if (pos) -+ pos++; -+ SetHelpKeys(); -+ break; -+ case kUp|k_Repeat: -+ case kUp: -+ case kYellow|k_Repeat: -+ case kYellow: // previous directory in list -+ if (!InEditMode()) -+ return cMenuEditItem::ProcessKey(Key); -+ Find(false); -+ pos = Utf8StrLen(base); -+ if (pos) -+ pos++; -+ break; -+ case kDown|k_Repeat: -+ case kDown: -+ case kBlue|k_Repeat: -+ case kBlue: // next directory in list -+ if (!InEditMode()) -+ return cMenuEditItem::ProcessKey(Key); -+ Find(true); -+ pos = Utf8StrLen(base); -+ if (pos) -+ pos++; -+ break; -+ case kOk: // done -+ if (!InEditMode()) -+ return cMenuEditItem::ProcessKey(Key); -+ stripspace(value); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ cSkinDisplay::Current()->SetButtons(NULL); -+ LeaveEditMode(Key == kOk); -+ break; -+ default: -+ return cMenuEditItem::ProcessKey(Key); -+ } -+ Set(); -+ return osContinue; -+} -+#endif /* LIEMIEXT */ -+ - // --- cMenuEditStraItem ----------------------------------------------------- - - cMenuEditStraItem::cMenuEditStraItem(const char *Name, int *Value, int NumStrings, const char * const *Strings) -@@ -630,7 +810,11 @@ cMenuEditStraItem::cMenuEditStraItem(con - - void cMenuEditStraItem::Set(void) - { -+#ifdef USE_VALIDINPUT -+ SetValue(strings[*value], (*value > min), (*value < max)); -+#else - SetValue(strings[*value]); -+#endif /* VALIDINPUT */ - } - - // --- cMenuEditChanItem ----------------------------------------------------- -diff -ruNp vdr-1.7.0/menuitems.h vdr-1.7.0-extensions/menuitems.h ---- vdr-1.7.0/menuitems.h 2008-04-12 14:03:59.000000000 +0200 -+++ vdr-1.7.0-extensions/menuitems.h 2009-04-09 20:48:48.000000000 +0200 -@@ -21,7 +21,11 @@ private: - public: - cMenuEditItem(const char *Name); - ~cMenuEditItem(); -+#ifdef USE_VALIDINPUT -+ void SetValue(const char *Value, bool HasPre=false, bool HasSucc=false); -+#else - void SetValue(const char *Value); -+#endif /* VALIDINPUT */ - }; - - class cMenuEditIntItem : public cMenuEditItem { -@@ -78,26 +82,46 @@ public: - - class cMenuEditStrItem : public cMenuEditItem { - private: -+#ifdef USE_LIEMIEXT -+ int offset; -+#else - char *value; - int length; - const char *allowed; - int pos, offset; -+#endif /* LIEMIEXT */ - bool insert, newchar, uppercase; -+#ifndef USE_LIEMIEXT - int lengthUtf8; - uint *valueUtf8; -+#endif /* LIEMIEXT */ - uint *allowedUtf8; - uint *charMapUtf8; - uint *currentCharUtf8; - eKeys lastKey; - cTimeMs autoAdvanceTimeout; -+#ifndef USE_LIEMIEXT - void SetHelpKeys(void); -+#endif /* LIEMIEXT */ - uint *IsAllowed(uint c); - void AdvancePos(void); -+#ifndef USE_LIEMIEXT - virtual void Set(void); -+#endif /* LIEMIEXT */ - uint Inc(uint c, bool Up); - void Insert(void); - void Delete(void); - protected: -+#ifdef USE_LIEMIEXT -+ char *value; -+ int length; -+ uint *valueUtf8; -+ int lengthUtf8; -+ const char *allowed; -+ int pos; -+ void SetHelpKeys(void); -+ virtual void Set(void); -+#endif /* LIEMIEXT */ - void EnterEditMode(void); - void LeaveEditMode(bool SaveValue = false); - bool InEditMode(void) { return valueUtf8 != NULL; } -@@ -107,6 +131,21 @@ public: - virtual eOSState ProcessKey(eKeys Key); - }; - -+#ifdef USE_LIEMIEXT -+class cMenuEditRecPathItem : public cMenuEditStrItem { -+protected: -+ char base[MaxFileName]; -+ virtual void SetHelpKeys(void); -+ void SetBase(const char* Path); -+ void FindNextLevel(); -+ void Find(bool Next); -+public: -+ cMenuEditRecPathItem(const char* Name, char* Path, int Length); -+ ~cMenuEditRecPathItem(); -+ virtual eOSState ProcessKey(eKeys Key); -+ }; -+#endif /* LIEMIEXT */ -+ - class cMenuEditStraItem : public cMenuEditIntItem { - private: - const char * const *strings; -@@ -185,6 +224,9 @@ public: - cMenuSetupPage(void); - virtual eOSState ProcessKey(eKeys Key); - void SetPlugin(cPlugin *Plugin); -+#ifdef USE_GRAPHTFT -+ const char* MenuKind() { return "MenuSetupPage"; } -+#endif /* GRAPHTFT */ - }; - - #endif //__MENUITEMS_H -diff -ruNp vdr-1.7.0/menuorgpatch.h vdr-1.7.0-extensions/menuorgpatch.h ---- vdr-1.7.0/menuorgpatch.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/menuorgpatch.h 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,102 @@ -+#ifdef USE_MENUORG -+/* -+ * vdr-menuorg - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2007 - 2008 Tobias Grimm <vdr@e-tobi.net> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ * $Id$ -+ * -+ */ -+ -+#ifndef __MENUORGPATCH_H -+#define __MENUORGPATCH_H -+ -+#include "mainmenuitemsprovider.h" -+ -+class MenuOrgPatch -+{ -+ private: -+ static IMainMenuItemsProvider* _mainMenuItemsProvider; -+ -+ private: -+ static IMainMenuItemsProvider* MainMenuItemsProvider() -+ { -+ if (!_mainMenuItemsProvider) -+ { -+ IMainMenuItemsProvider* mainMenuItemsProvider; -+ -+ if (cPluginManager::CallFirstService(MENU_ITEMS_PROVIDER_SERVICE_ID, &mainMenuItemsProvider)) -+ { -+ _mainMenuItemsProvider = mainMenuItemsProvider; -+ } -+ } -+ return _mainMenuItemsProvider; -+ } -+ -+ public: -+ static bool IsCustomMenuAvailable() -+ { -+ return (MainMenuItemsProvider() != NULL) && (MainMenuItemsProvider()->IsCustomMenuAvailable()); -+ } -+ -+ static void EnterRootMenu() -+ { -+ if (MainMenuItemsProvider()) -+ { -+ MainMenuItemsProvider()->EnterRootMenu(); -+ } -+ } -+ -+ static bool LeaveSubMenu() -+ { -+ if (MainMenuItemsProvider()) -+ { -+ return MainMenuItemsProvider()->LeaveSubMenu(); -+ } -+ return false; -+ } -+ -+ static void EnterSubMenu(cOsdItem* item) -+ { -+ if (MainMenuItemsProvider()) -+ { -+ MainMenuItemsProvider()->EnterSubMenu(item); -+ } -+ } -+ -+ static MenuItemDefinitions* MainMenuItems() -+ { -+ if (MainMenuItemsProvider()) -+ { -+ return MainMenuItemsProvider()->MainMenuItems(); -+ } -+ return NULL; -+ } -+ -+ static cOsdMenu* Execute(cOsdItem* item) -+ { -+ if (MainMenuItemsProvider()) -+ { -+ return MainMenuItemsProvider()->Execute(item); -+ } -+ return NULL; -+ } -+}; -+ -+IMainMenuItemsProvider* MenuOrgPatch::_mainMenuItemsProvider = NULL; -+ -+#endif //__MENUORGPATCH_H -+#endif /* MENUORG */ -diff -ruNp vdr-1.7.0/osdbase.c vdr-1.7.0-extensions/osdbase.c ---- vdr-1.7.0/osdbase.c 2008-02-17 12:33:04.000000000 +0100 -+++ vdr-1.7.0-extensions/osdbase.c 2009-04-09 20:48:48.000000000 +0200 -@@ -22,6 +22,9 @@ cOsdItem::cOsdItem(eOSState State) - state = State; - selectable = true; - fresh = true; -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ subMenu = 0; -+#endif /* SETUP & PINPLUGIN */ - } - - cOsdItem::cOsdItem(const char *Text, eOSState State, bool Selectable) -@@ -31,8 +34,23 @@ cOsdItem::cOsdItem(const char *Text, eOS - selectable = Selectable; - fresh = true; - SetText(Text); -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ subMenu = 0; -+#endif /* SETUP & PINPLUGIN */ - } - -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+cOsdItem::cOsdItem(const char *Text, eOSState State, cSubMenuNode* SubMenu) -+{ -+ text = NULL; -+ state = State; -+ selectable = true; -+ fresh = true; -+ SetText(Text); -+ subMenu = SubMenu; -+} -+#endif /* SETUP & PINPLUGIN */ -+ - cOsdItem::~cOsdItem() - { - free(text); -@@ -77,6 +95,9 @@ cOsdMenu::cOsdMenu(const char *Title, in - { - isMenu = true; - digit = 0; -+#ifdef USE_LIEMIEXT -+ key_nr = -1; -+#endif /* LIEMIEXT */ - hasHotkeys = false; - title = NULL; - SetTitle(Title); -@@ -97,6 +118,9 @@ cOsdMenu::~cOsdMenu() - free(status); - displayMenu->Clear(); - cStatus::MsgOsdClear(); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdMenuDestroy(); -+#endif /* GRAPHTFT */ - if (!--displayMenuCount) - DELETENULL(displayMenu); - } -@@ -119,7 +143,11 @@ const char *cOsdMenu::hk(const char *s) - digit = -1; // prevents automatic hotkeys - input already has them - if (digit >= 0) { - digit++; -+#ifdef USE_LIEMIEXT -+ buffer = cString::sprintf(" %2d%s %s", digit, (digit > 9) ? "" : " ", s); -+#else - buffer = cString::sprintf(" %c %s", (digit < 10) ? '0' + digit : ' ' , s); -+#endif /* LIEMIEXT */ - s = buffer; - } - } -@@ -199,9 +227,15 @@ void cOsdMenu::Display(void) - subMenu->Display(); - return; - } -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - displayMenu->SetMessage(mtStatus, NULL); - displayMenu->Clear(); - cStatus::MsgOsdClear(); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdMenuDisplay(MenuKind()); -+#endif /* GRAPHTFT */ - displayMenu->SetTabs(cols[0], cols[1], cols[2], cols[3], cols[4]);//XXX - displayMenu->SetTitle(title); - cStatus::MsgOsdTitle(title); -@@ -296,6 +330,9 @@ bool cOsdMenu::SelectableItem(int idx) - - void cOsdMenu::CursorUp(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int tmpCurrent = current; - int lastOnScreen = first + displayMenuItems - 1; - int last = Count() - 1; -@@ -334,6 +371,9 @@ void cOsdMenu::CursorUp(void) - - void cOsdMenu::CursorDown(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int tmpCurrent = current; - int lastOnScreen = first + displayMenuItems - 1; - int last = Count() - 1; -@@ -374,6 +414,9 @@ void cOsdMenu::CursorDown(void) - - void cOsdMenu::PageUp(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int oldCurrent = current; - int oldFirst = first; - current -= displayMenuItems; -@@ -408,6 +451,9 @@ void cOsdMenu::PageUp(void) - - void cOsdMenu::PageDown(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int oldCurrent = current; - int oldFirst = first; - current += displayMenuItems; -@@ -448,6 +494,64 @@ void cOsdMenu::Mark(void) - } - } - -+#ifdef USE_LIEMIEXT -+#define MENUKEY_TIMEOUT 1500 -+ -+eOSState cOsdMenu::HotKey(eKeys Key) -+{ -+ bool match = false; -+ bool highlight = false; -+ int item_nr; -+ int i; -+ -+ if (Key == kNone) { -+ if (lastActivity.TimedOut()) -+ Key = kOk; -+ else -+ return osContinue; -+ } -+ else { -+ lastActivity.Set(MENUKEY_TIMEOUT); -+ } -+ for (cOsdItem *item = Last(); item; item = Prev(item)) { -+ const char *s = item->Text(); -+ i = 0; -+ item_nr = 0; -+ if (s && (s = skipspace(s)) != '\0' && '0' <= s[i] && s[i] <= '9') { -+ do { -+ item_nr = item_nr * 10 + (s[i] - '0'); -+ } -+ while (!((s[++i] == '\t')||(s[i] == ' ')) && (s[i] != '\0') && ('0' <= s[i]) && (s[i] <= '9')); -+ if ((Key == kOk) && (item_nr == key_nr)) { -+ current = item->Index(); -+ RefreshCurrent(); -+ Display(); -+ cRemote::Put(kOk, true); -+ key_nr = -1; -+ break; -+ } -+ else if (Key != kOk) { -+ if (!highlight && (item_nr == (Key - k0))) { -+ highlight = true; -+ current = item->Index(); -+ } -+ if (!match && (key_nr == -1) && ((item_nr / 10) == (Key - k0))) { -+ match = true; -+ key_nr = (Key - k0); -+ } -+ else if (((key_nr == -1) && (item_nr == (Key - k0))) || (!match && (key_nr >= 0) && (item_nr == (10 * key_nr + Key - k0)))) { -+ current = item->Index(); -+ cRemote::Put(kOk, true); -+ key_nr = -1; -+ break; -+ } -+ } -+ } -+ } -+ if ((!match) && (Key != kNone)) { -+ key_nr = -1; -+ } -+#else - eOSState cOsdMenu::HotKey(eKeys Key) - { - for (cOsdItem *item = First(); item; item = Next(item)) { -@@ -462,6 +566,7 @@ eOSState cOsdMenu::HotKey(eKeys Key) - } - } - } -+#endif /* LIEMIEXT */ - return osContinue; - } - -@@ -500,8 +605,13 @@ eOSState cOsdMenu::ProcessKey(eKeys Key) - } - } - switch (Key) { -+#ifdef USE_LIEMIEXT -+ case kNone: -+ case k0...k9: return hasHotkeys ? HotKey(Key) : osUnknown; -+#else - case k0: return osUnknown; - case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown; -+#endif /* LIEMIEXT */ - case kUp|k_Repeat: - case kUp: CursorUp(); break; - case kDown|k_Repeat: -diff -ruNp vdr-1.7.0/osdbase.h vdr-1.7.0-extensions/osdbase.h ---- vdr-1.7.0/osdbase.h 2007-11-03 15:50:52.000000000 +0100 -+++ vdr-1.7.0-extensions/osdbase.h 2009-04-09 20:48:48.000000000 +0200 -@@ -15,6 +15,10 @@ - #include "skins.h" - #include "tools.h" - -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+#include "submenu.h" -+#endif /* SETUP & PINPLUGIN */ -+ - enum eOSState { osUnknown, - osContinue, - osSchedule, -@@ -44,6 +48,9 @@ enum eOSState { osUnknown, - osUser8, - osUser9, - osUser10, -+#ifdef USE_LIVEBUFFER -+ osLiveBuffer, -+#endif /* LIVEBUFFER */ - }; - - class cOsdItem : public cListObject { -@@ -51,16 +58,26 @@ private: - char *text; - eOSState state; - bool selectable; -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ cSubMenuNode* subMenu; -+#endif /* SETUP & PINPLUGIN */ - protected: - bool fresh; - public: - cOsdItem(eOSState State = osUnknown); - cOsdItem(const char *Text, eOSState State = osUnknown, bool Selectable = true); -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ cOsdItem(const char *Text, eOSState State, cSubMenuNode* SubMenu); -+#endif /* SETUP & PINPLUGIN */ - virtual ~cOsdItem(); - bool Selectable(void) const { return selectable; } - void SetText(const char *Text, bool Copy = true); - void SetSelectable(bool Selectable); - void SetFresh(bool Fresh); -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ void SetSubMenu(cSubMenuNode* SubMenu) { subMenu = SubMenu; } -+ cSubMenuNode* SubMenu() { return subMenu; } -+#endif /* SETUP & PINPLUGIN */ - const char *Text(void) const { return text; } - virtual void Set(void) {} - virtual eOSState ProcessKey(eKeys Key); -@@ -95,6 +112,10 @@ private: - char *status; - int digit; - bool hasHotkeys; -+#ifdef USE_LIEMIEXT -+ int key_nr; -+ cTimeMs lastActivity; -+#endif /* LIEMIEXT */ - protected: - void SetDisplayMenu(void); - cSkinDisplayMenu *DisplayMenu(void) { return displayMenu; } -@@ -129,6 +150,9 @@ public: - void Ins(cOsdItem *Item, bool Current = false, cOsdItem *Before = NULL); - virtual void Display(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuUnknown"; } -+#endif /* GRAPHTFT */ - }; - - #endif //__OSDBASE_H -diff -ruNp vdr-1.7.0/osd.c vdr-1.7.0-extensions/osd.c ---- vdr-1.7.0/osd.c 2007-10-12 14:38:36.000000000 +0200 -+++ vdr-1.7.0-extensions/osd.c 2009-04-09 20:48:48.000000000 +0200 -@@ -15,6 +15,9 @@ - #include <sys/stat.h> - #include <sys/unistd.h> - #include "tools.h" -+#ifdef USE_TTXTSUBS -+#include "vdrttxtsubshooks.h" -+#endif /* TTXTSUBS */ - - // --- cPalette -------------------------------------------------------------- - -@@ -720,6 +723,9 @@ int cOsd::osdTop = 0; - int cOsd::osdWidth = 0; - int cOsd::osdHeight = 0; - cVector<cOsd *> cOsd::Osds; -+#ifdef USE_PINPLUGIN -+bool cOsd::pinValid = false; -+#endif /* PINPLUGIN */ - - cOsd::cOsd(int Left, int Top, uint Level) - { -@@ -730,6 +736,9 @@ cOsd::cOsd(int Left, int Top, uint Level - width = height = 0; - level = Level; - active = false; -+#ifdef USE_YAEPG -+ vidWin.bpp = 0; -+#endif /* YAEPG */ - for (int i = 0; i < Osds.Size(); i++) { - if (Osds[i]->level > level) { - Osds.Insert(this, i); -diff -ruNp vdr-1.7.0/osd.h vdr-1.7.0-extensions/osd.h ---- vdr-1.7.0/osd.h 2007-10-12 16:28:44.000000000 +0200 -+++ vdr-1.7.0-extensions/osd.h 2009-04-09 20:48:48.000000000 +0200 -@@ -400,6 +400,12 @@ public: - ///< 7: vertical, falling, upper - virtual void Flush(void); - ///< Actually commits all data to the OSD hardware. -+#ifdef USE_PINPLUGIN -+ static bool pinValid; -+#endif /* PINPLUGIN */ -+#ifdef USE_YAEPG -+ tArea vidWin; -+#endif /* YAEPG */ - }; - - class cOsdProvider { -diff -ruNp vdr-1.7.0/player.c vdr-1.7.0-extensions/player.c ---- vdr-1.7.0/player.c 2007-07-20 17:25:24.000000000 +0200 -+++ vdr-1.7.0-extensions/player.c 2009-04-09 20:48:48.000000000 +0200 -@@ -60,10 +60,18 @@ cOsdObject *cControl::GetInfo(void) - return NULL; - } - -+#ifdef USE_LIVEBUFFER -+cControl *cControl::Control(bool Hidden) -+#else - cControl *cControl::Control(void) -+#endif /* LIVEBUFFER */ - { - cMutexLock MutexLock(&mutex); -+#ifdef USE_LIVEBUFFER -+ return (control && (!control->hidden || Hidden)) ? control : NULL; -+#else - return (control && !control->hidden) ? control : NULL; -+#endif /* LIVEBUFFER */ - } - - void cControl::Launch(cControl *Control) -diff -ruNp vdr-1.7.0/player.h vdr-1.7.0-extensions/player.h ---- vdr-1.7.0/player.h 2008-02-16 14:50:11.000000000 +0100 -+++ vdr-1.7.0-extensions/player.h 2009-04-09 20:48:48.000000000 +0200 -@@ -83,7 +83,11 @@ public: - static void Launch(cControl *Control); - static void Attach(void); - static void Shutdown(void); -+#ifdef USE_LIVEBUFFER -+ static cControl *Control(bool Hidden = false); -+#else - static cControl *Control(void); -+#endif /* LIVEBUFFER */ - }; - - #endif //__PLAYER_H -diff -ruNp vdr-1.7.0/plugin.c vdr-1.7.0-extensions/plugin.c ---- vdr-1.7.0/plugin.c 2008-02-17 14:32:12.000000000 +0100 -+++ vdr-1.7.0-extensions/plugin.c 2009-04-09 20:48:48.000000000 +0200 -@@ -316,6 +316,14 @@ void cPluginManager::AddPlugin(const cha - char *p = strchr(s, ' '); - if (p) - *p = 0; -+#ifdef USE_PLUGINMISSING -+ struct stat st; -+ if (stat (cString::sprintf("%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, APIVERSION), &st) && errno == ENOENT) { -+ esyslog("WARN: missing plugin '%s'", s); -+ fprintf(stderr, "vdr: missing plugin '%s'\n", s); -+ } -+ else -+#endif /* PLUGINMISSING */ - dlls.Add(new cDll(cString::sprintf("%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, APIVERSION), Args)); - free(s); - } -@@ -324,7 +332,11 @@ bool cPluginManager::LoadPlugins(bool Lo - { - for (cDll *dll = dlls.First(); dll; dll = dlls.Next(dll)) { - if (!dll->Load(Log)) -+#ifdef USE_PLUGINMISSING -+ ; -+#else - return false; -+#endif /* PLUGINMISSING */ - } - return true; - } -diff -ruNp vdr-1.7.0/po/ca_ES.po vdr-1.7.0-extensions/po/ca_ES.po ---- vdr-1.7.0/po/ca_ES.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/ca_ES.po 2009-04-09 20:48:48.000000000 +0200 -@@ -10,7 +10,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-03-02 19:02+0100\n" - "Last-Translator: Luca Olivetti <luca@ventoso.org>\n" - "Language-Team: Catalanian\n" -@@ -24,15 +24,12 @@ msgstr "off" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "auto" -+ - msgid "none" - msgstr "cap" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Canal incorrecte ***" - -@@ -321,12 +318,6 @@ msgstr "Protegir" - msgid "Hierarchy" - msgstr "Jerarquia" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioritat" -- - msgid "Rolloff" - msgstr "" - -@@ -375,6 +366,9 @@ msgstr "Fi" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioritat" -+ - msgid "Lifetime" - msgstr "Durada" - -@@ -909,9 +903,6 @@ msgstr "Sobrescriure" - msgid "Button$Insert" - msgstr "Inserir" - --msgid "auto" --msgstr "auto" -- - msgid "Plugin" - msgstr "Plugin" - -@@ -1019,3 +1010,270 @@ msgstr "Prem qualsevol tecla per cancel· - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR s'apagarà en %s minuts" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/cs_CZ.po vdr-1.7.0-extensions/po/cs_CZ.po ---- vdr-1.7.0/po/cs_CZ.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/cs_CZ.po 2009-04-09 20:48:48.000000000 +0200 -@@ -8,7 +8,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-02-28 15:00+0200\n" - "Last-Translator: Vladimír Bárta <vladimir.barta@k2atmitec.cz>, Jiøí Dobrý <jdobry@centrum.cz>\n" - "Language-Team: Czech\n" -@@ -22,15 +22,12 @@ msgstr "vyp." - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "auto" -+ - msgid "none" - msgstr "¾ádný" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Neplatný kanál ***" - -@@ -319,12 +316,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarchy" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Priorita" -- - msgid "Rolloff" - msgstr "" - -@@ -373,6 +364,9 @@ msgstr "Konec" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Priorita" -+ - msgid "Lifetime" - msgstr "®ivotnost" - -@@ -907,9 +901,6 @@ msgstr "Pøepsat" - msgid "Button$Insert" - msgstr "Vlo¾it" - --msgid "auto" --msgstr "auto" -- - msgid "Plugin" - msgstr "Modul" - -@@ -1017,3 +1008,270 @@ msgstr "Jakákoliv klávesa zru¹í restart" - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR se vypne za %s minut" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/da_DK.po vdr-1.7.0-extensions/po/da_DK.po ---- vdr-1.7.0/po/da_DK.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/da_DK.po 2009-04-09 20:48:48.000000000 +0200 -@@ -7,7 +7,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2007-08-12 14:17+0200\n" - "Last-Translator: Mogens Elneff <mogens@elneff.dk>\n" - "Language-Team: Danish\n" -@@ -21,15 +21,12 @@ msgstr "fra" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "automatisk" -+ - msgid "none" - msgstr "ingen" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Ugyldig kanal! ***" - -@@ -318,12 +315,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarki" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioritet" -- - msgid "Rolloff" - msgstr "" - -@@ -372,6 +363,9 @@ msgstr "Stop" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioritet" -+ - msgid "Lifetime" - msgstr "Levetid" - -@@ -906,9 +900,6 @@ msgstr "Overskriv" - msgid "Button$Insert" - msgstr "Indsæt" - --msgid "auto" --msgstr "automatisk" -- - msgid "Plugin" - msgstr "Plugin" - -@@ -1016,3 +1007,270 @@ msgstr "Tryk vilkårlig knap for at annul - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR slukker om %s minutter" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/de_DE.po vdr-1.7.0-extensions/po/de_DE.po ---- vdr-1.7.0/po/de_DE.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/de_DE.po 2009-04-09 20:48:48.000000000 +0200 -@@ -7,7 +7,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2007-11-25 15:19+0200\n" - "Last-Translator: Klaus Schmidinger <kls@cadsoft.de>\n" - "Language-Team: German\n" -@@ -21,15 +21,12 @@ msgstr "aus" - msgid "on" - msgstr "ein" - -+msgid "auto" -+msgstr "auto" -+ - msgid "none" - msgstr "keine" - --msgid "high" --msgstr "hoch" -- --msgid "low" --msgstr "niedrig" -- - msgid "*** Invalid Channel ***" - msgstr "*** Ungültiger Kanal ***" - -@@ -318,12 +315,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarchie" - --msgid "Alpha" --msgstr "Alpha" -- --msgid "Priority" --msgstr "Priorität" -- - msgid "Rolloff" - msgstr "Rolloff" - -@@ -372,6 +363,9 @@ msgstr "Ende" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Priorität" -+ - msgid "Lifetime" - msgstr "Lebensdauer" - -@@ -800,6 +794,30 @@ msgstr "Lautstärke beim Einschalten" - msgid "Setup.Miscellaneous$Emergency exit" - msgstr "Notausstieg" - -+msgid "Setup.Miscellaneous$Volume ctrl with left/right" -+msgstr "Lautstärke mit Rechts/Links regeln" -+ -+msgid "Setup.Miscellaneous$Channelgroups with left/right" -+msgstr "Kanalgruppen mit Rechts/Links" -+ -+msgid "Setup.Miscellaneous$only in channelinfo" -+msgstr "nur in Kanalinfo" -+ -+msgid "Setup.Miscellaneous$Search fwd/back with left/right" -+msgstr "Vor-/Rücklauf mit Rechts/Links" -+ -+msgid "Setup.Miscellaneous$only in progress display" -+msgstr "nur in Fortschrittsanzeige" -+ -+msgid "Setup.Miscellaneous$Lirc repeat delay" -+msgstr "Lirc Verzögerung" -+ -+msgid "Setup.Miscellaneous$Lirc repeat freq" -+msgstr "Lirc Frequenz" -+ -+msgid "Setup.Miscellaneous$Lirc repeat timeout" -+msgstr "Lirc Zeitbeschränkung" -+ - msgid "Plugins" - msgstr "Plugins" - -@@ -906,9 +924,6 @@ msgstr "Überschreiben" - msgid "Button$Insert" - msgstr "Einfügen" - --msgid "auto" --msgstr "auto" -- - msgid "Plugin" - msgstr "Plugin" - -@@ -1016,3 +1031,327 @@ msgstr "Taste drücken, um Neustart abzub - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR wird in %s Minuten ausschalten" -+ -+msgid "Parameters" -+msgstr "Parameter" -+ -+msgid "Channel locked by LNB!" -+msgstr "Kanal durch LNB gesperrt!" -+ -+msgid "Childlock" -+msgstr "Kindersicherung" -+ -+msgid "Path" -+msgstr "Pfad" -+ -+msgid "Timer commands" -+msgstr "Befehle für Aufzeichnungen" -+ -+msgid "Rename recording" -+msgstr "Aufzeichnung umbenennen" -+ -+msgid "Date" -+msgstr "Datum" -+ -+msgid "Length" -+msgstr "Länge" -+ -+msgid "Size" -+msgstr "Größe" -+ -+msgid "Delete marks information?" -+msgstr "Marks löschen?" -+ -+msgid "Delete resume information?" -+msgstr "Resume löschen?" -+ -+msgid "DVD plugin is not installed!" -+msgstr "Das DVD-Plugin ist nicht installiert!" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "Alphabet für Haupt-, flexibel für Unterverzeichnisse" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "Datum für Haupt-, flexibel für Unterverzeichnisse" -+ -+msgid "all alphabetically" -+msgstr "Alles alphabetisch" -+ -+msgid "all by date" -+msgstr "Alles nach Datum" -+ -+msgid "Sorting" -+msgstr "Sortierung" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "WarEagle icons verwenden" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "Hauptmenü Titel" -+ -+msgid "Setup.OSD$- Text" -+msgstr "- Text" -+ -+msgid "default" -+msgstr "Voreinstellung" -+ -+msgid "VDR - text" -+msgstr "VDR - Text" -+ -+msgid "text" -+msgstr "Text" -+ -+msgid "VDR - version" -+msgstr "VDR - Version" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Befehle Position im Hauptmenü" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "Zeige gültige Eingabe" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Zeitbalken anzeigen" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "Zeitspanne für dop. EPG-Suche (min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "Doppelten externen EPG-Eintrag" -+ -+msgid "Setup.EPG$Mode of noEPG-Patch" -+msgstr "Art des noEPG-Patches" -+ -+msgid "adjust" -+msgstr "anwenden" -+ -+msgid "delete" -+msgstr "löschen" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "Internes und externes EPG mischen" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "Erk. des lauf. VPS-Events abschalten" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "AC3-Transfer Fix benutzen" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "Sperre Kanäle" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "Kanal Sperren Filter" -+ -+msgid "qam256" -+msgstr "qam256" -+ -+msgid "dvb-c" -+msgstr "dvb-c" -+ -+msgid "dvb-s" -+msgstr "dvb-s" -+ -+msgid "all" -+msgstr "alle" -+ -+msgid "blacklist" -+msgstr "Blacklist" -+ -+msgid "whitelist" -+msgstr "Whitelist" -+ -+msgid "has decoder" -+msgstr "mit Decoder" -+ -+msgid "is primary" -+msgstr "ist primär" -+ -+msgid "has decoder + is primary" -+msgstr "mit Decoder und primär" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "Sync Early Patch benutzen" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "DVB-Empfänger %d nutzt LNB Nr." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "LNB-Nutzung protokollieren" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Dolby Digital Ton aufzeichnen" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "Videoverzeichnispolitik" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "Anzahl der Videoverzeichnisse" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "Video %d Priorität" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Video %d min. MB frei" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "Freundliche Dateinamen" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "Max. Aufnahmengröße (GB)" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "Hard Link Cutter" -+ -+msgid "Setup.Recording$Delete timeshift recording" -+msgstr "Zeitversetzte Aufnahme löschen" -+ -+msgid "request" -+msgstr "abfragen" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Aufnahmedatum anzeigen" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Aufnahmezeit anzeigen" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Länge der Aufnahme anzeigen" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "Ende für Timer anzeigen" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "Aufnahmen sortieren nach" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "Verzeichnisse vor Aufnahmen einsortieren" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "Aufnahmen nach dem Schneiden löschen" -+ -+msgid "Setup.Recording$Cutter adjust starttime" -+msgstr "Startzeit beim Schneiden anpassen" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "Wiedergabe nach Sprung" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Sprung bei Schnittmarke" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "Pause bei letzter Marke" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "Marken aktualisieren" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "Sprungweite in Sekunden" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "Sprungweite in Sekunden Langsam" -+ -+msgid "Setup.Replay$Length" -+msgstr "Länge" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "Länge / Nummer" -+ -+msgid "Setup.Replay$Number" -+msgstr "Nummer" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "DVD Anzeige" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "DVD führende Nullen anzeigen" -+ -+msgid "Setup.Replay$never" -+msgstr "nie" -+ -+msgid "Setup.Replay$on begin" -+msgstr "am Anfang" -+ -+msgid "Setup.Replay$on end" -+msgstr "am Ende" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "am Anfang und Ende" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "DVD-Schublade öffnen" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "DVD drosseln auf" -+ -+msgid "Jump" -+msgstr "Springen: " -+ -+msgid "Skip +60s" -+msgstr "Sprung +60s" -+ -+msgid "Skip -60s" -+msgstr "Sprung -60s" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "Schnitt bereits aktiv - zur Schnitt-Liste hinzufügen?" -+ -+msgid "Rename$Up" -+msgstr "Höher" -+ -+msgid "Rename$Down" -+msgstr "Tiefer" -+ -+msgid "Rename$Previous" -+msgstr "Vorheriger" -+ -+msgid "Rename$Next" -+msgstr "Nächster" -+ -+msgid "Please mount %s" -+msgstr "Bitte %s einlegen!" -+ -+msgid "Please mount DVD %04d" -+msgstr "Bitte DVD %04d einlegen!" -+ -+msgid "Please mount DVD %d" -+msgstr "Bitte DVD %d einlegen!" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "Bitte warten. Überprüfe DVD..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "Keine Index-Datei gefunden. Erstellung kann Minuten dauern. Erstellen?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "Bitte warten. Index-Datei wird erstellt..." -+ -+msgid "Wrong DVD!" -+msgstr "Falsche DVD!" -+ -+msgid "Permanent Timeshift" -+msgstr "Permanentes Timeshift" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Speicherort" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "Festplatte" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "Arbeitsspeicher" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Puffergröße im Arbeitsspeicher (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Auf Festplatte ausweiten wenn nötig" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Pausierten Puffer beibehalten" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Puffergröße auf Festplatte (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Puffergröße (MB)" -diff -ruNp vdr-1.7.0/po/el_GR.po vdr-1.7.0-extensions/po/el_GR.po ---- vdr-1.7.0/po/el_GR.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/el_GR.po 2009-04-09 20:48:48.000000000 +0200 -@@ -7,7 +7,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2007-08-12 14:17+0200\n" - "Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n" - "Language-Team: Greek\n" -@@ -21,15 +21,12 @@ msgstr "êëåéóôü" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "áõôüìáôï" -+ - msgid "none" - msgstr "êáíÝíá" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Áêõñï êáíÜëç ***" - -@@ -318,12 +315,6 @@ msgstr "Ðñïóôáóßá" - msgid "Hierarchy" - msgstr "Éåñáñ÷åßá" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Ðñïôåñáéüôçôá" -- - msgid "Rolloff" - msgstr "" - -@@ -372,6 +363,9 @@ msgstr "ÔÝëïò" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Ðñïôåñáéüôçôá" -+ - msgid "Lifetime" - msgstr "ÄéÝñêåéá ÐáñáìïíÞò" - -@@ -906,9 +900,6 @@ msgstr "ÁíôéêáôÜóôáóç" - msgid "Button$Insert" - msgstr "ÅéóáãùãÞ" - --msgid "auto" --msgstr "áõôüìáôï" -- - msgid "Plugin" - msgstr "ÅðÝêôáóç" - -@@ -1016,3 +1007,270 @@ msgstr "" - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/es_ES.po vdr-1.7.0-extensions/po/es_ES.po ---- vdr-1.7.0/po/es_ES.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/es_ES.po 2009-04-09 20:48:48.000000000 +0200 -@@ -8,7 +8,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-03-02 19:02+0100\n" - "Last-Translator: Luca Olivetti <luca@ventoso.org>\n" - "Language-Team: Spanish\n" -@@ -22,15 +22,12 @@ msgstr "off" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "auto" -+ - msgid "none" - msgstr "ninguno" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Canal no válido ***" - -@@ -319,12 +316,6 @@ msgstr "Int.Guarda" - msgid "Hierarchy" - msgstr "Jerarquía" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioridad" -- - msgid "Rolloff" - msgstr "" - -@@ -373,6 +364,9 @@ msgstr "Fin" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioridad" -+ - msgid "Lifetime" - msgstr "Duración" - -@@ -907,9 +901,6 @@ msgstr "Sobreescribir" - msgid "Button$Insert" - msgstr "Insertar" - --msgid "auto" --msgstr "auto" -- - msgid "Plugin" - msgstr "Plugin" - -@@ -1017,3 +1008,270 @@ msgstr "Pulse cualquier tecla para cance - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR se apagará en %s minutos" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/et_EE.po vdr-1.7.0-extensions/po/et_EE.po ---- vdr-1.7.0/po/et_EE.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/et_EE.po 2009-04-09 20:48:48.000000000 +0200 -@@ -7,7 +7,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2007-08-12 14:17+0200\n" - "Last-Translator: Arthur Konovalov <kasjas@hot.ee>\n" - "Language-Team: Estonian\n" -@@ -21,15 +21,12 @@ msgstr "väljas" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "automaatne" -+ - msgid "none" - msgstr "puudu" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Vigane kanal ***" - -@@ -318,12 +315,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarhia" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioriteet" -- - msgid "Rolloff" - msgstr "" - -@@ -372,6 +363,9 @@ msgstr "Stopp" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioriteet" -+ - msgid "Lifetime" - msgstr "Eluiga" - -@@ -906,9 +900,6 @@ msgstr "Asenda (OVR)" - msgid "Button$Insert" - msgstr "Lisa (INS)" - --msgid "auto" --msgstr "automaatne" -- - msgid "Plugin" - msgstr "Laiendusmoodul" - -@@ -1016,3 +1007,270 @@ msgstr "Restardi katkestamiseks vajuta s - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR lülitub välja %s minuti pärast" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "Ümbernimetamine" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Käsu asukoht peamenüüs" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Edenemisriba" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Salvestuse kuupäev" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Salvestuse kellaaeg" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Salvestuse pikkus" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "Üles" -+ -+msgid "Rename$Down" -+msgstr "Alla" -+ -+msgid "Rename$Previous" -+msgstr "Eelmine" -+ -+msgid "Rename$Next" -+msgstr "Järgmine" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/fi_FI.po vdr-1.7.0-extensions/po/fi_FI.po ---- vdr-1.7.0/po/fi_FI.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/fi_FI.po 2009-04-09 20:48:48.000000000 +0200 -@@ -10,7 +10,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2007-08-15 15:52+0200\n" - "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n" - "Language-Team: Finnish\n" -@@ -24,15 +24,12 @@ msgstr "poissa" - msgid "on" - msgstr "päällä" - -+msgid "auto" -+msgstr "auto" -+ - msgid "none" - msgstr "tyhjä" - --msgid "high" --msgstr "korkea" -- --msgid "low" --msgstr "matala" -- - msgid "*** Invalid Channel ***" - msgstr "*** Virheellinen kanavavalinta ***" - -@@ -45,6 +42,253 @@ msgstr "Siirtotilan aloitus epäonnistui! - msgid "Starting EPG scan" - msgstr "Ohjelmaoppaan päivitys aloitettu" - -+msgid "Content$Movie/Drama" -+msgstr "Elokuva/draama" -+ -+msgid "Content$Detective/Thriller" -+msgstr "Etsivä/trilleri" -+ -+msgid "Content$Adventure/Western/War" -+msgstr "Seikkailu/western/sota" -+ -+msgid "Content$Science Fiction/Fantasy/Horror" -+msgstr "Scifi/fantasia/kauhu" -+ -+msgid "Content$Comedy" -+msgstr "Komedia" -+ -+msgid "Content$Soap/Melodrama/Folkloric" -+msgstr "Saippua/melodraama/kansanperinne" -+ -+msgid "Content$Romance" -+msgstr "Romanssi" -+ -+msgid "Content$Serious/Classical/Religious/Historical Movie/Drama" -+msgstr "Vakava/klassinen/uskonnollinen/historiallinen elokuva/draama" -+ -+msgid "Content$Adult Movie/Drama" -+msgstr "Aikuiselokuva/draama" -+ -+msgid "Content$News/Current Affairs" -+msgstr "Uutiset/ajankohtaisohjelma" -+ -+msgid "Content$News/Weather Report" -+msgstr "Uutiset/säätiedot" -+ -+msgid "Content$News Magazine" -+msgstr "Uutismakasiini" -+ -+msgid "Content$Documentary" -+msgstr "Dokumentti" -+ -+msgid "Content$Discussion/Inverview/Debate" -+msgstr "Keskustelu/haastattelu/väittely" -+ -+msgid "Content$Show/Game Show" -+msgstr "Show/visailu" -+ -+msgid "Content$Game Show/Quiz/Contest" -+msgstr "Visailu/kilpailu" -+ -+msgid "Content$Variety Show" -+msgstr "Varietee" -+ -+msgid "Content$Talk Show" -+msgstr "Keskusteluohjelma" -+ -+msgid "Content$Sports" -+msgstr "Urheilua" -+ -+msgid "Content$Special Event" -+msgstr "Erikoistapahtuma" -+ -+msgid "Content$Sport Magazine" -+msgstr "Urheilumakasiini" -+ -+msgid "Content$Football" -+msgstr "Jalkapallo" -+ -+msgid "Content$Tennis/Squash" -+msgstr "Tennis/Squash" -+ -+msgid "Content$Team Sports" -+msgstr "Joukkueurheilua" -+ -+msgid "Content$Athletics" -+msgstr "Yleisurheilua" -+ -+msgid "Content$Motor Sport" -+msgstr "Moottoriurheilua" -+ -+msgid "Content$Water Sport" -+msgstr "Vesiurheilua" -+ -+msgid "Content$Winter Sports" -+msgstr "Talviurheilua" -+ -+msgid "Content$Equestrian" -+msgstr "Ratsastusta" -+ -+msgid "Content$Martial Sports" -+msgstr "Kamppailu-urheilua" -+ -+msgid "Content$Children's/Youth Programmes" -+msgstr "Lasten ja nuorten ohjelma" -+ -+msgid "Content$Pre-school Children's Programmes" -+msgstr "Alle kouluikäisten ohjelma" -+ -+msgid "Content$Entertainment Programmes for 6 to 14" -+msgstr "Viihdeohjelma 6-14 vuotiaille" -+ -+msgid "Content$Entertainment Programmes for 10 to 16" -+msgstr "Viihdeohjelma 10-16 vuotiaille" -+ -+msgid "Content$Informational/Educational/School Programme" -+msgstr "Opetus/kouluohjelma" -+ -+msgid "Content$Cartoons/Puppets" -+msgstr "Piirretty/nukke-esitys" -+ -+msgid "Content$Music/Ballet/Dance" -+msgstr "Musiikki/baletti/tanssi" -+ -+msgid "Content$Rock/Pop" -+msgstr "Rock/pop" -+ -+msgid "Content$Serious/Classical Music" -+msgstr "Vakava/klassinen musiikki" -+ -+msgid "Content$Folk/Tradional Music" -+msgstr "Folk/kansanmusiikki" -+ -+msgid "Content$Jazz" -+msgstr "Jazz" -+ -+msgid "Content$Musical/Opera" -+msgstr "Musikaali/ooppera" -+ -+msgid "Content$Ballet" -+msgstr "Baletti" -+ -+msgid "Content$Arts/Culture" -+msgstr "Taide/kulttuuri" -+ -+msgid "Content$Performing Arts" -+msgstr "Performanssitaide" -+ -+msgid "Content$Fine Arts" -+msgstr "Kuvataide" -+ -+msgid "Content$Religion" -+msgstr "Uskonto" -+ -+msgid "Content$Popular Culture/Traditional Arts" -+msgstr "Populaarikulttuuri/perinnetaiteet" -+ -+msgid "Content$Literature" -+msgstr "Kirjallisuus" -+ -+msgid "Content$Film/Cinema" -+msgstr "Elokuvataide" -+ -+msgid "Content$Experimental Film/Video" -+msgstr "Kokeellinen elokuva/video" -+ -+msgid "Content$Broadcasting/Press" -+msgstr "Televisio/radio/lehdistö" -+ -+msgid "Content$New Media" -+msgstr "Uusmedia" -+ -+msgid "Content$Arts/Culture Magazines" -+msgstr "Taide/kulttuurimakasiini" -+ -+msgid "Content$Fashion" -+msgstr "Muoti" -+ -+msgid "Content$Social/Political/Economics" -+msgstr "Yhteiskunta/politiikka/talous" -+ -+msgid "Content$Magazines/Reports/Documentary" -+msgstr "Makasiini/reportaasi/dokumentti" -+ -+msgid "Content$Economics/Social Advisory" -+msgstr "Talous/yhteiskunnallinen neuvonta" -+ -+msgid "Content$Remarkable People" -+msgstr "Merkittävät henkilöt" -+ -+msgid "Content$Education/Science/Factual" -+msgstr "Koulutus/tiede" -+ -+msgid "Content$Nature/Animals/Environment" -+msgstr "Luonto/eläimet/ympäristö" -+ -+msgid "Content$Technology/Natural Sciences" -+msgstr "Teknologia/luonnontiede" -+ -+msgid "Content$Medicine/Physiology/Psychology" -+msgstr "Lääketiede/fysiologia/psykologia" -+ -+msgid "Content$Foreign Countries/Expeditions" -+msgstr "Vieraat maat/tutkimusretket" -+ -+msgid "Content$Social/Spiritual Sciences" -+msgstr "Yhteiskunta/hengelliset tieteet" -+ -+msgid "Content$Further Education" -+msgstr "Jatkokoulutus" -+ -+msgid "Content$Languages" -+msgstr "Kielet" -+ -+msgid "Content$Leisure/Hobbies" -+msgstr "Vapaa-aika ja harrastukset" -+ -+msgid "Content$Tourism/Travel" -+msgstr "Turismi/matkustaminen" -+ -+msgid "Content$Handicraft" -+msgstr "Käsityöt" -+ -+msgid "Content$Motoring" -+msgstr "Autoilu" -+ -+msgid "Content$Fitness & Health" -+msgstr "Kuntoilu & terveys" -+ -+msgid "Content$Cooking" -+msgstr "Ruuanlaitto" -+ -+msgid "Content$Advertisement/Shopping" -+msgstr "Mainostaminen/ostaminen" -+ -+msgid "Content$Gardening" -+msgstr "Puutarhanhoito" -+ -+msgid "Content$Original Language" -+msgstr "Alkuperäiskieli" -+ -+msgid "Content$Black & White" -+msgstr "Mustavalkoinen" -+ -+msgid "Content$Unpublished" -+msgstr "Julkaisematon" -+ -+msgid "Content$Live Broadcast" -+msgstr "Suoralähetys" -+ -+msgid "Content$Special Characteristics" -+msgstr "Erikoisominaisuus" -+ -+msgid "Content$Drama" -+msgstr "Draama" -+ -+#, c-format -+msgid "Suitable for those aged %d and over" -+msgstr "Kielletty alle %d vuotiailta" -+ - msgid "No title" - msgstr "Ei esitystä" - -@@ -321,12 +565,6 @@ msgstr "Suojaväli" - msgid "Hierarchy" - msgstr "Hierarkia" - --msgid "Alpha" --msgstr "Alpha" -- --msgid "Priority" --msgstr "Prioriteetti" -- - msgid "Rolloff" - msgstr "Rolloff" - -@@ -375,6 +613,9 @@ msgstr "Lopetus" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioriteetti" -+ - msgid "Lifetime" - msgstr "Elinikä" - -@@ -909,9 +1150,6 @@ msgstr "Korvaa" - msgid "Button$Insert" - msgstr "Lisää" - --msgid "auto" --msgstr "auto" -- - msgid "Plugin" - msgstr "Laajennos" - -@@ -1019,3 +1257,273 @@ msgstr "Peru uudelleenkäynnistys painama - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR sammuu %s minuutin kuluttua" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "Polku" -+ -+msgid "Timer commands" -+msgstr "Ajastinkomennot" -+ -+msgid "Rename recording" -+msgstr "Nimeä tallenne" -+ -+msgid "Date" -+msgstr "Päiväys" -+ -+msgid "Length" -+msgstr "Pituus" -+ -+msgid "Size" -+msgstr "Koko" -+ -+msgid "Delete marks information?" -+msgstr "Poista tallenteen merkinnät" -+ -+msgid "Delete resume information?" -+msgstr "Poista tallenteen paluutiedot" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Komentojen sijainti päävalikossa" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Näytä aikajana" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Dolby Digital tallennus" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Näytä tallenteen päiväys" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Näytä tallenteen ajankohta" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Näytä tallenteen kesto" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "Ylemmäs" -+ -+msgid "Rename$Down" -+msgstr "Alemmas" -+ -+msgid "Rename$Previous" -+msgstr "Edellinen" -+ -+msgid "Rename$Next" -+msgstr "Seuraava" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Parameters" -+msgstr "Parametrit" -+ -+msgid "Permanent Timeshift" -+msgstr "Jatkuva ajansiirto" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Puskurin sijainti" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "kovalevyllä" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "muistissa" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Puffergröße im Arbeitsspeicher (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Käytä kovalevyä tarvittaessa" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Pidä pysäytetty puskuri" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Puffergröße auf Festplatte (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Puskurin koko (MB)" -diff -ruNp vdr-1.7.0/po/fr_FR.po vdr-1.7.0-extensions/po/fr_FR.po ---- vdr-1.7.0/po/fr_FR.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/fr_FR.po 2009-04-09 20:48:48.000000000 +0200 -@@ -8,12 +8,13 @@ - # Pierre Briec <pbriec@free.fr>, 2006 - # Bruno Roussel <bruno.roussel@free.fr>, 2007 - # Michael Nival <mnival@club-internet.fr>, 2007 -+# Patrice Staudt <patrice.staudt@laposte.net>, 2007, 2008 - # - msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-02-27 18:14+0100\n" - "Last-Translator: Jean-Claude Repetto <jc@repetto.org>\n" - "Language-Team: French\n" -@@ -27,15 +28,12 @@ msgstr "off" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "auto" -+ - msgid "none" - msgstr "aucun" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Chaîne invalide ! ***" - -@@ -324,12 +322,6 @@ msgstr "Intervalle de garde" - msgid "Hierarchy" - msgstr "Hiérarchie" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Priorité" -- - msgid "Rolloff" - msgstr "" - -@@ -378,6 +370,9 @@ msgstr "Fin" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Priorité" -+ - msgid "Lifetime" - msgstr "Durée de vie" - -@@ -912,9 +907,6 @@ msgstr "Ecraser" - msgid "Button$Insert" - msgstr "Insérer" - --msgid "auto" --msgstr "auto" -- - msgid "Plugin" - msgstr "Plugin" - -@@ -1022,3 +1014,270 @@ msgstr "Appuyer sur une touche pour annu - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR s'arrêtera dans %s minutes" -+ -+msgid "Channel locked by LNB!" -+msgstr "Chaîne interdite par la LNB" -+ -+msgid "Childlock" -+msgstr "Adulte" -+ -+msgid "Path" -+msgstr "Dossiers" -+ -+msgid "Timer commands" -+msgstr "Commandes de programmation" -+ -+msgid "Rename recording" -+msgstr "Renommer l'enregistrement" -+ -+msgid "Date" -+msgstr "Date" -+ -+msgid "Length" -+msgstr "Longeur" -+ -+msgid "Size" -+msgstr "Taille" -+ -+msgid "Delete marks information?" -+msgstr "Effacer marque d'information?" -+ -+msgid "Delete resume information?" -+msgstr "Effacer resume information?" -+ -+msgid "DVD plugin is not installed!" -+msgstr "Le plugin de DVD n'est pas installé!" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "Dir principal alphabétiquement, subdirs flexibles" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "Dir principal à la date, subdirs flexibles" -+ -+msgid "all alphabetically" -+msgstr "tous alphabétiquement" -+ -+msgid "all by date" -+msgstr "tous à la date" -+ -+msgid "Sorting" -+msgstr "Triage" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "Icônes WarEagle" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Position des commandes dans le menu" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "Afficher l'entrée valide" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Montrer la barre de progression" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "Intervalle de recherche EPG de double(min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "Double entrée EPG externe" -+ -+msgid "adjust" -+msgstr "ajuster" -+ -+msgid "delete" -+msgstr "effacer" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "Mélanger les EPG interne et externe" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "Arreter la reconnaissance des événements VPS" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "Utiliser le correctif AC3-Transfer" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "Utilisez Sync début patch" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "La carte DVB %d utilise la LNB No." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "Protocoller l'utilisation du LNB" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Enregistrer en Dolby Digital" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "Régles de répertoires vidéo" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "Nombre de répertoires vidéo" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "Video %d prioritaires" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Video %d min. librei Mo" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "Noms de fichiers facile" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "Taille max. de l'enregistrement (GB)" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "Découpe Hard links" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Montrer la date d'enregistrement" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Montrer l'heure d'enregistrement" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Monter la longueur de l'enregistrement" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "Montrer la fin du temporisateur" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "Ordonner les enregistrement suivant" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "Les dossiers devant les enregistrements" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "Effacer l'enregistrement après la découpe" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "Lecture après saut" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Saut sur les marques de découpes" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "Pause après la dernière marque" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "Actualiser les marques" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "Longueur de saut en secondes" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "Longueur de saut lent en secondes" -+ -+msgid "Setup.Replay$Length" -+msgstr "Longueur" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "Longueur / Numéro" -+ -+msgid "Setup.Replay$Number" -+msgstr "Numéro" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "Afficher le DVD" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "Afficher les zéros devant le numéro du DVD" -+ -+msgid "Setup.Replay$never" -+msgstr "jamais" -+ -+msgid "Setup.Replay$on begin" -+msgstr "au début" -+ -+msgid "Setup.Replay$on end" -+msgstr "à la fin" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "au début et à la fin" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "Ouvrir le tiroir du lecteur DVD" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "Ralentir la vitesse du DVD à" -+ -+msgid "Jump" -+msgstr "Saut" -+ -+msgid "Skip +60s" -+msgstr "Avance +60s" -+ -+msgid "Skip -60s" -+msgstr "Recule -60s" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "Découpe déjà active - l'ajouter à la liste de découpe?" -+ -+msgid "Rename$Up" -+msgstr "Haut" -+ -+msgid "Rename$Down" -+msgstr "Bas" -+ -+msgid "Rename$Previous" -+msgstr "Précédent" -+ -+msgid "Rename$Next" -+msgstr "Suivant" -+ -+msgid "Please mount %s" -+msgstr "Mettez %s dans le lecteur" -+ -+msgid "Please mount DVD %04d" -+msgstr "Mettez le DVD %04d dans le lecteur" -+ -+msgid "Please mount DVD %d" -+msgstr "Mettez le DVD %d dans le lecteur" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "Un moment SVP. Vérification du DVD..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "Pas trouvé de fichiers index. La création de ce ficher prends quelques minutes. Créer?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "Attendez, svp. Le fichier index est en cours de création..." -+ -+msgid "Wrong DVD!" -+msgstr "Mauvais DVD!" -+ -+msgid "Permanent Timeshift" -+msgstr "Timeshift permanent" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Localisation" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "disque dur" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "mémoire" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Taille de la mémoire tampon dans la mémoire (Mo)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Ètendre au disque dur, si nécessaire" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Gardez en veille la mémoire tampon" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Taille de la mémoire tampon sur le disque dur (Mo)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Taille de la mémoire tampon (Mo)" -diff -ruNp vdr-1.7.0/po/hr_HR.po vdr-1.7.0-extensions/po/hr_HR.po ---- vdr-1.7.0/po/hr_HR.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/hr_HR.po 2009-04-09 20:48:48.000000000 +0200 -@@ -9,7 +9,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-03-17 19:00+0100\n" - "Last-Translator: Adrian Caval <anrxc@sysphere.org>\n" - "Language-Team: Croatian\n" -@@ -23,15 +23,12 @@ msgstr "iskljuèi" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "automatski" -+ - msgid "none" - msgstr "ni¹ta" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Neispravan Program ***" - -@@ -320,12 +317,6 @@ msgstr "Za¹tita" - msgid "Hierarchy" - msgstr "Hijerarhija" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioritet" -- - msgid "Rolloff" - msgstr "" - -@@ -374,6 +365,9 @@ msgstr "Kraj" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioritet" -+ - msgid "Lifetime" - msgstr "Trajanje" - -@@ -908,9 +902,6 @@ msgstr "Prepi¹i" - msgid "Button$Insert" - msgstr "Umetni" - --msgid "auto" --msgstr "automatski" -- - msgid "Plugin" - msgstr "Dodatak" - -@@ -1018,3 +1009,270 @@ msgstr "Pritisnite jednu tipku za poni¹t - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR æe se iskljuèiti za %s minuta" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/hu_HU.po vdr-1.7.0-extensions/po/hu_HU.po ---- vdr-1.7.0/po/hu_HU.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/hu_HU.po 2009-04-09 20:48:48.000000000 +0200 -@@ -10,7 +10,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2007-12-01 21:42+0200\n" - "Last-Translator: István Füley <ifuley@tigercomp.ro>\n" - "Language-Team: Hungarian\n" -@@ -24,15 +24,12 @@ msgstr "ki" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "auto" -+ - msgid "none" - msgstr "semmi" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Érvénytelen csatorna ***" - -@@ -321,12 +318,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarhia" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioritás" -- - msgid "Rolloff" - msgstr "" - -@@ -375,6 +366,9 @@ msgstr "Vége" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioritás" -+ - msgid "Lifetime" - msgstr "Élettartam" - -@@ -909,9 +903,6 @@ msgstr "Átírni" - msgid "Button$Insert" - msgstr "Beilleszteni" - --msgid "auto" --msgstr "auto" -- - msgid "Plugin" - msgstr "Plugin" - -@@ -1019,3 +1010,270 @@ msgstr "Nyomj egy gombot az újraindítás - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "A VDR leáll %s perc múlva" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/it_IT.po vdr-1.7.0-extensions/po/it_IT.po ---- vdr-1.7.0/po/it_IT.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/it_IT.po 2009-04-09 20:48:48.000000000 +0200 -@@ -11,10 +11,10 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" --"PO-Revision-Date: 2008-03-08 21:06+0100\n" -+"POT-Creation-Date: 2008-10-05 05:55+0200\n" -+"PO-Revision-Date: 2008-10-05 05:57+0100\n" - "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" --"Language-Team: Italian\n" -+"Language-Team: Italian\n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=ISO-8859-15\n" - "Content-Transfer-Encoding: 8bit\n" -@@ -25,18 +25,18 @@ msgstr "off" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "automatico" -+ - msgid "none" - msgstr "nessuno" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Canale NON valido ***" - -+msgid "Channel locked by LNB!" -+msgstr "Canale bloccato dal LNB!" -+ - msgid "Channel not available!" - msgstr "Canale non disponibile!" - -@@ -46,6 +46,253 @@ msgstr "Impossibile avviare mod. trasfer - msgid "Starting EPG scan" - msgstr "Inizio scansione EPG" - -+msgid "Content$Movie/Drama" -+msgstr "Film/Dramma" -+ -+msgid "Content$Detective/Thriller" -+msgstr "Investigativo/Giallo" -+ -+msgid "Content$Adventure/Western/War" -+msgstr "Avventura/Western/Guerra" -+ -+msgid "Content$Science Fiction/Fantasy/Horror" -+msgstr "Finzione/Fantasia/Horror" -+ -+msgid "Content$Comedy" -+msgstr "Commedia" -+ -+msgid "Content$Soap/Melodrama/Folkloric" -+msgstr "Telenovella/Melodramma/Folcloristico" -+ -+msgid "Content$Romance" -+msgstr "Romanzo" -+ -+msgid "Content$Serious/Classical/Religious/Historical Movie/Drama" -+msgstr "Serio/Classico/Religioso/Film storico/Dramma" -+ -+msgid "Content$Adult Movie/Drama" -+msgstr "Film per adulti/Dramma" -+ -+msgid "Content$News/Current Affairs" -+msgstr "Notizie/Ultima ora" -+ -+msgid "Content$News/Weather Report" -+msgstr "Notizie/Previsioni meteo" -+ -+msgid "Content$News Magazine" -+msgstr "Rivista di notizie" -+ -+msgid "Content$Documentary" -+msgstr "Documentario" -+ -+msgid "Content$Discussion/Inverview/Debate" -+msgstr "Discussione/Intervista/Dibattito" -+ -+msgid "Content$Show/Game Show" -+msgstr "Spettacolo/Gioco a premi" -+ -+msgid "Content$Game Show/Quiz/Contest" -+msgstr "Gioco a premi/Quiz/Gara" -+ -+msgid "Content$Variety Show" -+msgstr "Spettacolo di varietà" -+ -+msgid "Content$Talk Show" -+msgstr "Talk Show" -+ -+msgid "Content$Sports" -+msgstr "Sport" -+ -+msgid "Content$Special Event" -+msgstr "Evento speciale" -+ -+msgid "Content$Sport Magazine" -+msgstr "Rivista di sport" -+ -+msgid "Content$Football" -+msgstr "Calcio" -+ -+msgid "Content$Tennis/Squash" -+msgstr "Tennis/Squash" -+ -+msgid "Content$Team Sports" -+msgstr "Sport di squadra" -+ -+msgid "Content$Athletics" -+msgstr "Atletica" -+ -+msgid "Content$Motor Sport" -+msgstr "Sport motoristici" -+ -+msgid "Content$Water Sport" -+msgstr "Sport acquatici" -+ -+msgid "Content$Winter Sports" -+msgstr "Sport invernali" -+ -+msgid "Content$Equestrian" -+msgstr "Equitazione" -+ -+msgid "Content$Martial Sports" -+msgstr "Arti marziali" -+ -+msgid "Content$Children's/Youth Programmes" -+msgstr "Programmi per ragazzi/giovani" -+ -+msgid "Content$Pre-school Children's Programmes" -+msgstr "Programmi per ragazzi prescolastici" -+ -+msgid "Content$Entertainment Programmes for 6 to 14" -+msgstr "Programmi di intrattenimento da 6 a 14" -+ -+msgid "Content$Entertainment Programmes for 10 to 16" -+msgstr "Programmi di intrattenimento da 10 a 16" -+ -+msgid "Content$Informational/Educational/School Programme" -+msgstr "Informativo/Educativo/Programma scolastico" -+ -+msgid "Content$Cartoons/Puppets" -+msgstr "Cartoni/Pupazzi" -+ -+msgid "Content$Music/Ballet/Dance" -+msgstr "Musica/Balletto/Danza" -+ -+msgid "Content$Rock/Pop" -+msgstr "Rock/Pop" -+ -+msgid "Content$Serious/Classical Music" -+msgstr "Serio/Musica classica" -+ -+msgid "Content$Folk/Tradional Music" -+msgstr "Folclore/Musica tradizionale" -+ -+msgid "Content$Jazz" -+msgstr "Jazz" -+ -+msgid "Content$Musical/Opera" -+msgstr "Musical/Opera" -+ -+msgid "Content$Ballet" -+msgstr "Balletto" -+ -+msgid "Content$Arts/Culture" -+msgstr "Arte/Cultura" -+ -+msgid "Content$Performing Arts" -+msgstr "Arti di rendimento" -+ -+msgid "Content$Fine Arts" -+msgstr "Arti fine" -+ -+msgid "Content$Religion" -+msgstr "Religione" -+ -+msgid "Content$Popular Culture/Traditional Arts" -+msgstr "Cultura popolare/Arti tradizionali" -+ -+msgid "Content$Literature" -+msgstr "Letteratura" -+ -+msgid "Content$Film/Cinema" -+msgstr "Film/Cinema" -+ -+msgid "Content$Experimental Film/Video" -+msgstr "Film esperimentale/Video" -+ -+msgid "Content$Broadcasting/Press" -+msgstr "Trasmissione/Stampa" -+ -+msgid "Content$New Media" -+msgstr "Nuovo programma" -+ -+msgid "Content$Arts/Culture Magazines" -+msgstr "Arte/Riviste di cultura" -+ -+msgid "Content$Fashion" -+msgstr "Moda" -+ -+msgid "Content$Social/Political/Economics" -+msgstr "Società/Politica/Economia" -+ -+msgid "Content$Magazines/Reports/Documentary" -+msgstr "Riviste/Reportage/Documentari" -+ -+msgid "Content$Economics/Social Advisory" -+msgstr "Economia/Consulenza sociale" -+ -+msgid "Content$Remarkable People" -+msgstr "Personaggi importanti" -+ -+msgid "Content$Education/Science/Factual" -+msgstr "Educazione/Scienza/Fatti" -+ -+msgid "Content$Nature/Animals/Environment" -+msgstr "Natura/Animali/Ambiente" -+ -+msgid "Content$Technology/Natural Sciences" -+msgstr "Tecnologia/Scienze naturali" -+ -+msgid "Content$Medicine/Physiology/Psychology" -+msgstr "Medicina/Filosofia/Psicologia" -+ -+msgid "Content$Foreign Countries/Expeditions" -+msgstr "Paesi esteri/Spedizioni" -+ -+msgid "Content$Social/Spiritual Sciences" -+msgstr "Società/Scienze spirituali" -+ -+msgid "Content$Further Education" -+msgstr "Altra educazione" -+ -+msgid "Content$Languages" -+msgstr "Lingua" -+ -+msgid "Content$Leisure/Hobbies" -+msgstr "Tempo libero/Hobby" -+ -+msgid "Content$Tourism/Travel" -+msgstr "Turismo/Viaggi" -+ -+msgid "Content$Handicraft" -+msgstr "Artigianato" -+ -+msgid "Content$Motoring" -+msgstr "Motori" -+ -+msgid "Content$Fitness & Health" -+msgstr "Culturismo & Salute" -+ -+msgid "Content$Cooking" -+msgstr "Cucina" -+ -+msgid "Content$Advertisement/Shopping" -+msgstr "Pubblicità/Acquisti" -+ -+msgid "Content$Gardening" -+msgstr "Giardinaggio" -+ -+msgid "Content$Original Language" -+msgstr "Lingua madre" -+ -+msgid "Content$Black & White" -+msgstr "Bianco & Nero" -+ -+msgid "Content$Unpublished" -+msgstr "Non pubblicato" -+ -+msgid "Content$Live Broadcast" -+msgstr "ys" -+ -+msgid "Content$Special Characteristics" -+msgstr "Caratteristiche speciali" -+ -+msgid "Content$Drama" -+msgstr "Dramma" -+ -+#, c-format -+msgid "Suitable for those aged %d and over" -+msgstr "Adatto per coloro con %d di età e oltre" -+ - msgid "No title" - msgstr "Senza titolo" - -@@ -232,11 +479,14 @@ msgstr "Utente8" - msgid "Key$User9" - msgstr "Utente9" - -+msgid "Recording started" -+msgstr "Registrazione avviata" -+ - msgid "Disk" - msgstr "Disco" - - msgid "free" --msgstr "liberi" -+msgstr "disponibili" - - msgid "Free To Air" - msgstr "in chiaro" -@@ -322,15 +572,12 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Gerarchia" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Priorità" -- - msgid "Rolloff" - msgstr "" - -+msgid "Parameters" -+msgstr "Parametri" -+ - msgid "Channel settings are not unique!" - msgstr "Parametri canale non univoci!" - -@@ -376,12 +623,27 @@ msgstr "Fine" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Priorità" -+ - msgid "Lifetime" --msgstr "Durata" -+msgstr "Scadenza" -+ -+msgid "Childlock" -+msgstr "Filtro fam." -+ -+msgid "yes" -+msgstr "sì" -+ -+msgid "no" -+msgstr "no" - - msgid "File" - msgstr "Nome" - -+msgid "Path" -+msgstr "Percorso" -+ - msgid "First day" - msgstr "1° giorno" - -@@ -400,6 +662,9 @@ msgstr "Eliminare il timer?" - msgid "Timer still recording - really delete?" - msgstr "Timer in registrazione - eliminare?" - -+msgid "Timer commands" -+msgstr "Comandi timer" -+ - msgid "Event" - msgstr "Evento" - -@@ -419,20 +684,20 @@ msgid "What's on next?" - msgstr "Prossimi programmi" - - msgid "Button$Next" --msgstr "Prossimo" -+msgstr "Prossimi" - - msgid "Button$Now" - msgstr "Adesso" - - msgid "Button$Schedule" --msgstr "Programma" -+msgstr "Programmi" - - msgid "Can't switch channel!" - msgstr "Impossibile cambiare canale!" - - #, c-format - msgid "Schedule - %s" --msgstr "Programma - %s" -+msgstr "Programmi - %s" - - #, c-format - msgid "This event - %s" -@@ -460,6 +725,27 @@ msgstr "Riproduci" - msgid "Button$Rewind" - msgstr "Riavvolgi" - -+msgid "Rename recording" -+msgstr "Rinomina registrazione" -+ -+msgid "Date" -+msgstr "Data" -+ -+msgid "Length" -+msgstr "Durata" -+ -+msgid "Size" -+msgstr "Dimensione" -+ -+msgid "Delete marks information?" -+msgstr "Eliminare informazione marcatori?" -+ -+msgid "Delete resume information?" -+msgstr "Eliminare informazione ripristino?" -+ -+msgid "Error while accessing recording!" -+msgstr "Errore accesso alla registrazione!" -+ - msgid "Recordings" - msgstr "Registrazioni" - -@@ -469,8 +755,8 @@ msgstr "Apri" - msgid "Commands" - msgstr "Comandi" - --msgid "Error while accessing recording!" --msgstr "Errore accesso alla registrazione!" -+msgid "DVD plugin is not installed!" -+msgstr "Il plugin DVD non è installato!" - - msgid "Delete recording?" - msgstr "Eliminare la registrazione?" -@@ -481,6 +767,21 @@ msgstr "Errore eliminazione registrazion - msgid "Recording commands" - msgstr "Comandi di registrazione" - -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "Dir. princ. in ordine alfabetico, sottodir. flessibili" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "Dir. princ. per data, sottodir. flessibili" -+ -+msgid "all alphabetically" -+msgstr "Tutte in ordine alfabetico" -+ -+msgid "all by date" -+msgstr "Tutte per data" -+ -+msgid "Sorting" -+msgstr "Ordinamento" -+ - msgid "never" - msgstr "mai" - -@@ -490,6 +791,18 @@ msgstr "in base allo stile interfaccia" - msgid "always" - msgstr "sempre" - -+msgid "default" -+msgstr "predefinito" -+ -+msgid "VDR - text" -+msgstr "VDR - Testo" -+ -+msgid "text" -+msgstr "Testo" -+ -+msgid "VDR - version" -+msgstr "VDR - Versione" -+ - msgid "OSD" - msgstr "OSD" - -@@ -502,6 +815,9 @@ msgstr "Stile interfaccia" - msgid "Setup.OSD$Theme" - msgstr "Tema colori" - -+msgid "Setup.OSD$WarEagle icons" -+msgstr "Icone WarEagle" -+ - msgid "Setup.OSD$Left" - msgstr "Sinistra" - -@@ -515,7 +831,7 @@ msgid "Setup.OSD$Height" - msgstr "Altezza OSD" - - msgid "Setup.OSD$Message time (s)" --msgstr "Tempo del messaggio (s)" -+msgstr "Durata del messaggio (s)" - - msgid "Setup.OSD$Use small font" - msgstr "Utilizza caratteri piccoli" -@@ -571,12 +887,30 @@ msgstr "Tasto Menu per chiudere" - msgid "Setup.OSD$Recording directories" - msgstr "Directory di registrazione" - -+msgid "Setup.OSD$Main menu title" -+msgstr "Titolo menu principale" -+ -+msgid "Setup.OSD$- Text" -+msgstr "- Testo" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Posizione comandi menu princ." -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "Mostra ingresso valido" -+ - msgid "EPG" - msgstr "Guida programmi EPG" - - msgid "Button$Scan" - msgstr "Scansione" - -+msgid "blacklist" -+msgstr "lista nera" -+ -+msgid "whitelist" -+msgstr "elenco autorizzati" -+ - msgid "Setup.EPG$EPG scan timeout (h)" - msgstr "Scadenza aggiorn. EPG (ore)" - -@@ -586,8 +920,11 @@ msgstr "Livello correzione EPG" - msgid "Setup.EPG$EPG linger time (min)" - msgstr "Mostra vecchi dati EPG (min)" - -+msgid "Setup.EPG$Show progress bar" -+msgstr "Mostra barra avanzamento" -+ - msgid "Setup.EPG$Set system time" --msgstr "Imposta orario automatico" -+msgstr "Imposta orario di sistema" - - msgid "Setup.EPG$Use time from transponder" - msgstr "Utilizza orario da transponder" -@@ -600,6 +937,27 @@ msgstr "Lingue preferite" - msgid "Setup.EPG$Preferred language" - msgstr "Lingua preferita" - -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "Tempo doppia ricerca EPG (min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "Doppio valore EPG esterno" -+ -+msgid "adjust" -+msgstr "regola" -+ -+msgid "delete" -+msgstr "elimina" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "Mescola EPG interno e esterno" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "Disabilita esec. evento VPS" -+ -+msgid "Setup.EPG$Mode of noEPG-Patch" -+msgstr "Modalità di noEPG-Patch" -+ - msgid "pan&scan" - msgstr "pan&scan" - -@@ -609,9 +967,6 @@ msgstr "letterbox" - msgid "center cut out" - msgstr "center cut out" - --msgid "no" --msgstr "no" -- - msgid "names only" - msgstr "solo nomi" - -@@ -630,6 +985,27 @@ msgstr "nuovi transponder" - msgid "DVB" - msgstr "Scheda DVB" - -+msgid "qam256" -+msgstr "qam256" -+ -+msgid "dvb-c" -+msgstr "dvb-c" -+ -+msgid "dvb-s" -+msgstr "dvb-s" -+ -+msgid "all" -+msgstr "tutti" -+ -+msgid "has decoder" -+msgstr "con decoder" -+ -+msgid "is primary" -+msgstr "primaria" -+ -+msgid "has decoder + is primary" -+msgstr "con decoder e primaria" -+ - msgid "Setup.DVB$Primary DVB interface" - msgstr "Scheda DVB primaria" - -@@ -637,13 +1013,13 @@ msgid "Setup.DVB$Video format" - msgstr "Formato video" - - msgid "Setup.DVB$Video display format" --msgstr "Formato di visualizz. video" -+msgstr "Formato visualizzazione video" - - msgid "Setup.DVB$Use Dolby Digital" - msgstr "Dolby Digital" - - msgid "Setup.DVB$Update channels" --msgstr "Aggiorna i canali" -+msgstr "Aggiornamento canali" - - msgid "Setup.DVB$Audio languages" - msgstr "Lingue audio" -@@ -669,9 +1045,28 @@ msgstr "Trasparenza sottotitoli" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Trasparenza sfondo sottotitoli" - -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "Utilizza correzione AC3-Transfer" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "Blocco canale" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "Modalità filtro blocco canale" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "Utilizza correzione Early Sync" -+ - msgid "LNB" - msgstr "LNB" - -+#, c-format -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "La scheda DVB %d utilizza LNB No." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "Registra utilizzo LNB" -+ - msgid "Setup.LNB$Use DiSEqC" - msgstr "Utilizza DiSEqC" - -@@ -714,6 +1109,9 @@ msgstr "La CAM è in uso - vuoi reimposta - msgid "Can't reset CAM!" - msgstr "Impossibile reimpostare il modulo CAM!" - -+msgid "request" -+msgstr "chiedi" -+ - msgid "Recording" - msgstr "Registrazione" - -@@ -730,17 +1128,37 @@ msgid "Setup.Recording$Default priority" - msgstr "Priorità predefinita" - - msgid "Setup.Recording$Default lifetime (d)" --msgstr "Durata predefinita (gg)" -+msgstr "Scadenza predefinita (gg)" - - msgid "Setup.Recording$Pause priority" - msgstr "Priorità di pausa" - - msgid "Setup.Recording$Pause lifetime (d)" --msgstr "Durata pausa (gg)" -+msgstr "Scadenza pausa (gg)" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Registra Dolby Digital" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "Regole directory video" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "Numero di directory video" -+ -+#, c-format -+msgid "Setup.Recording$Video %d priority" -+msgstr "Priorità video %d " -+ -+#, c-format -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Min. MB disponibili video %d " - - msgid "Setup.Recording$Use episode name" - msgstr "Utilizza nome episodio" - -+msgid "Setup.Recording$Friendly filenames" -+msgstr "Nomi file semplici" -+ - msgid "Setup.Recording$Use VPS" - msgstr "Utilizza VPS" - -@@ -754,14 +1172,44 @@ msgid "Setup.Recording$Name instant reco - msgstr "Nome reg. immediata" - - msgid "Setup.Recording$Instant rec. time (min)" --msgstr "Tempo reg. immediata (min)" -+msgstr "Durata reg. immediata (min)" - - msgid "Setup.Recording$Max. video file size (MB)" - msgstr "Dim. massima file video (MB)" - -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "Dim. massima reg. (GB)" -+ - msgid "Setup.Recording$Split edited files" - msgstr "Dividi i file modificati" - -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "Taglia collegamenti Hard" -+ -+msgid "Setup.Recording$Delete timeshift recording" -+msgstr "Elimina reg. timeshift" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Mostra data registrazione" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Mostra ora registrazione" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Mostra durata registrazione" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "Mostra fine del timer" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "Ordina registrazioni per" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "Ordina directory prima di reg." -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "Elimina taglio automatico" -+ - msgid "Replay" - msgstr "Riproduzione" - -@@ -774,6 +1222,63 @@ msgstr "Mostra modalità riproduzione" - msgid "Setup.Replay$Resume ID" - msgstr "ID di ripristino" - -+msgid "Setup.Replay$Jump&Play" -+msgstr "Vai a & Riproduci" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Riproduci & Vai a" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "Pausa all'ultimo marcatore" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "Ricarica marcatori" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "Salta secondi" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "Salta secondi lentamente" -+ -+msgid "Setup.Replay$Length" -+msgstr "Durata" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "Durata / Numero" -+ -+msgid "Setup.Replay$Number" -+msgstr "Numero" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "Mod. visualizzazione DVD" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "Mostra zeri davanti al DVD" -+ -+msgid "Setup.Replay$never" -+msgstr "mai" -+ -+msgid "Setup.Replay$on begin" -+msgstr "all'inizio" -+ -+msgid "Setup.Replay$on end" -+msgstr "alla fine" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "all'inizio e alla fine" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "Apri vassoio" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "Limita velocità DVD a" -+ -+msgid "Setup.Miscellaneous$only in channelinfo" -+msgstr "solo nelle info canale" -+ -+msgid "Setup.Miscellaneous$only in progress display" -+msgstr "solo nel canale in esec." -+ - msgid "Miscellaneous" - msgstr "Generici" - -@@ -801,9 +1306,54 @@ msgstr "come prima" - msgid "Setup.Miscellaneous$Initial volume" - msgstr "Volume iniziale" - -+msgid "Setup.Miscellaneous$Volume ctrl with left/right" -+msgstr "Controllo volume con Sinistra/Destra" -+ -+msgid "Setup.Miscellaneous$Channelgroups with left/right" -+msgstr "Gruppi canali con Sinistra/Destra" -+ -+msgid "Setup.Miscellaneous$Search fwd/back with left/right" -+msgstr "Cerca avanti/indietro con Sinistra/Destra" -+ - msgid "Setup.Miscellaneous$Emergency exit" - msgstr "Uscita di emergenza" - -+msgid "Setup.Miscellaneous$Lirc repeat delay" -+msgstr "Ritardo ripetizione LIRC" -+ -+msgid "Setup.Miscellaneous$Lirc repeat freq" -+msgstr "Frequenza ripetizione LIRC" -+ -+msgid "Setup.Miscellaneous$Lirc repeat timeout" -+msgstr "Scadenza ripetizione LIRC" -+ -+msgid "Permanent Timeshift" -+msgstr "Timeshift permanente" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Posizione" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "Disco fisso" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "Memoria" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Dim. buffer in memoria (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Utilizza disco fisso se necessario" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Mantieni buffer di pausa" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Dim. buffer nel disco fisso (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Dimensione buffer (MB)" -+ - msgid "Plugins" - msgstr "Plugins" - -@@ -829,7 +1379,6 @@ msgstr "Programmi" - msgid "VDR" - msgstr "VDR" - --#. TRANSLATORS: note the leading blank! - msgid " Stop replaying" - msgstr " Ferma riproduzione" - -@@ -845,7 +1394,6 @@ msgstr "Ferma" - msgid "Button$Resume" - msgstr "Riprendi" - --#. TRANSLATORS: note the leading blank! - msgid " Cancel editing" - msgstr " Annulla modifiche" - -@@ -876,10 +1424,22 @@ msgstr "Nessuna periferica DVB disponibi - msgid "Pausing live video..." - msgstr "Pausa del canale in visione..." - -+msgid "Jump" -+msgstr "Vai a" -+ -+msgid "Skip +60s" -+msgstr "Salta +60s" -+ -+msgid "Skip -60s" -+msgstr "Salta - 60s" -+ - #. TRANSLATORS: note the trailing blank! - msgid "Jump: " - msgstr "Vai a: " - -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "Taglio in esecuzione - Aggiungere alla coda tagli?" -+ - msgid "No editing marks defined!" - msgstr "Nessun marcatore di modifica definito!" - -@@ -895,9 +1455,6 @@ msgstr "Processo di modifica già attivo! - msgid "FileNameChars$ abcdefghijklmnopqrstuvwxyz0123456789-.,#~\\^$[]|()*+?{}/:%@&" - msgstr " aáàbcdeéèfghiìîjklmnoòpqrstuùvwxyz0123456789-.,#~\\^$[]|()*+?{}/:%@&°" - --msgid "yes" --msgstr "sì" -- - msgid "CharMap$ 0\t-.,1#~\\^$[]|()*+?{}/:%@&\tabc2\tdef3\tghi4\tjkl5\tmno6\tpqrs7\ttuv8\twxyz9" - msgstr " 0\t-.,1#~\\^$[]|()*+°?{}/:%@&\taàbc2\tdeèf3\tghiì4\tjkl5\tmnoò6\tpqrs7\ttuùv8\twxyz9" - -@@ -910,14 +1467,23 @@ msgstr "Sovrascrivi" - msgid "Button$Insert" - msgstr "Inserisci" - --msgid "auto" --msgstr "automatico" -+msgid "Rename$Up" -+msgstr "Su" -+ -+msgid "Rename$Down" -+msgstr "Giù" -+ -+msgid "Rename$Previous" -+msgstr "Precedente" -+ -+msgid "Rename$Next" -+msgstr "Successivo" - - msgid "Plugin" - msgstr "Plugin" - - msgid "Up/Dn for new location - OK to move" --msgstr "Su/Giù per nuova posizione - OK per muovere" -+msgstr "Su/Giù per nuova posizione - OK per spostare" - - msgid "Channel locked (recording)!" - msgstr "Canale bloccato (in registrazione)!" -@@ -925,6 +1491,30 @@ msgstr "Canale bloccato (in registrazion - msgid "Low disk space!" - msgstr "Poco spazio su disco!" - -+#, c-format -+msgid "Please mount %s" -+msgstr "Monta %s" -+ -+#, c-format -+msgid "Please mount DVD %04d" -+msgstr "Monta il DVD %04d" -+ -+#, c-format -+msgid "Please mount DVD %d" -+msgstr "Monta il DVD %d" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "Attendere prego. Verifica DVD..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "Nessun indice trovato. La creazione può impiegare alcuni minuti. Crearne uno?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "Attendere prego. Creazione indice..." -+ -+msgid "Wrong DVD!" -+msgstr "DVD errato!" -+ - msgid "Can't shutdown - option '-s' not given!" - msgstr "Impossibile spegnere - parametro '-s' non assegnato!" - -@@ -936,7 +1526,7 @@ msgstr "Registrazione in corso - spegner - - #, c-format - msgid "Recording in %ld minutes, shut down anyway?" --msgstr "Registrazione fra %ld minuti - spegnere comunque?" -+msgstr "Registrazione tra %ld minuti - spegnere comunque?" - - msgid "shut down anyway?" - msgstr "spegnere comunque?" -@@ -996,9 +1586,6 @@ msgstr "Domenica" - msgid "Upcoming recording!" - msgstr "Registrazione imminente!" - --msgid "Recording started" --msgstr "Registrazione avviata" -- - msgid "VDR will shut down later - press Power to force" - msgstr "VDR si spegnerà più tardi - premi Power per forzare" - -@@ -1020,3 +1607,4 @@ msgstr "Premi un tasto per annullare il - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR si spegnerà tra %s minuti" -+ -diff -ruNp vdr-1.7.0/po/nl_NL.po vdr-1.7.0-extensions/po/nl_NL.po ---- vdr-1.7.0/po/nl_NL.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/nl_NL.po 2009-04-09 20:48:48.000000000 +0200 -@@ -11,7 +11,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-02-26 17:20+0100\n" - "Last-Translator: Johan Schuring <johan.schuring@vetteblei.nl>\n" - "Language-Team: Dutch\n" -@@ -25,15 +25,12 @@ msgstr "uit" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "auto" -+ - msgid "none" - msgstr "geen" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Ongeldig kanaal ***" - -@@ -322,12 +319,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarchie" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioriteit" -- - msgid "Rolloff" - msgstr "" - -@@ -376,6 +367,9 @@ msgstr "Einde" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioriteit" -+ - msgid "Lifetime" - msgstr "Bewaarduur" - -@@ -910,9 +904,6 @@ msgstr "Overschrijven" - msgid "Button$Insert" - msgstr "Invoegen" - --msgid "auto" --msgstr "auto" -- - msgid "Plugin" - msgstr "Plugin" - -@@ -1020,3 +1011,270 @@ msgstr "Druk een willekeurige toets om h - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR zal na %s minuten uitschakelen" -+ -+msgid "Channel locked by LNB!" -+msgstr "Kanaal geblokkeerd door LNB" -+ -+msgid "Childlock" -+msgstr "Kinderslot" -+ -+msgid "Path" -+msgstr "Pad" -+ -+msgid "Timer commands" -+msgstr "Timer commando's" -+ -+msgid "Rename recording" -+msgstr "Hernoem opnamen" -+ -+msgid "Date" -+msgstr "Datum" -+ -+msgid "Length" -+msgstr "Lengte" -+ -+msgid "Size" -+msgstr "Grootte" -+ -+msgid "Delete marks information?" -+msgstr "Verwijder informatiemarkeringen?" -+ -+msgid "Delete resume information?" -+msgstr "Verwijder hervattingsmarkeringen?" -+ -+msgid "DVD plugin is not installed!" -+msgstr "DVd plugin is niet geÃnstalleerd!" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "hoofdmap alfabetisch, submappen flexibel" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "hoofdmap op datum, submappen flexibel" -+ -+msgid "all alphabetically" -+msgstr "alles alfabetisch" -+ -+msgid "all by date" -+msgstr "alles op datum" -+ -+msgid "Sorting" -+msgstr "Sortering" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "WarEagle symbolen" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Positie commandobalk in hoofdmenu" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "Toon geldige invoer" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Toon voortschreidingsbalk" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "Tijdsduur starten dubbele EPG zoekactie (min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "externe dubbele EPG invoer" -+ -+msgid "adjust" -+msgstr "afstellen" -+ -+msgid "delete" -+msgstr "verwijderen" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "Mix in- en externe EPG" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "Schakel aktieve VPS uitzending uit" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "Gebruik AC3-Transfer Fix" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "Gebruik 'Sync Early' Patch" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "LNB kaart %d gebruikt LNB Nr." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "Houd LNB gebruik bij" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Neem Dolby Digital spoor op" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "Omgang m.b.t. Videomappen" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "Aantal videomappen" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "Video %d prioriteit" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Video %d min. vrij MB" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "Handzame bestandsnamen" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "Max. opnamegrootte (GB)" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "'Hard link' bestandsbewerker" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Toon datum" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Toon tijd" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Toon lengte" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "Toon einde van timers" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "Sorteer opnames op" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "Sorteer mappen vÃÃr opnames" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "Bestandsbewerker automatisch wissen" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "Spring&Speel" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Speel&Spring" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "Pauzeer bij laatste markering" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "Herlaadt markeringen" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "Spring seconden" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "Spring seconden langzaam" -+ -+msgid "Setup.Replay$Length" -+msgstr "Lengte" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "Lengte / Nummer" -+ -+msgid "Setup.Replay$Number" -+msgstr "Nummer" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "DVD displayinstellingen" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "DVD toon voorloopnullen" -+ -+msgid "Setup.Replay$never" -+msgstr "nooit" -+ -+msgid "Setup.Replay$on begin" -+msgstr "aan het begin" -+ -+msgid "Setup.Replay$on end" -+msgstr "bij het einde" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "bij het begin en aan het einde" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "Open DVD lade" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "Beperk DVD omw. snelheid" -+ -+msgid "Jump" -+msgstr "Spring" -+ -+msgid "Skip +60s" -+msgstr "Spring +60s verder" -+ -+msgid "Skip -60s" -+msgstr "Spring -60s terug" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "Bestandsbewerker aktief - aan wachtrij toeveogen?" -+ -+msgid "Rename$Up" -+msgstr "Boven" -+ -+msgid "Rename$Down" -+msgstr "Onder" -+ -+msgid "Rename$Previous" -+msgstr "Vorige" -+ -+msgid "Rename$Next" -+msgstr "Volgende" -+ -+msgid "Please mount %s" -+msgstr "Koppel %s aan a.u.b." -+ -+msgid "Please mount DVD %04d" -+msgstr "Koppel DVD %04d aan a.u.b." -+ -+msgid "Please mount DVD %d" -+msgstr "Koppel DVD %d aan a.u.b." -+ -+msgid "Please wait. Checking DVD..." -+msgstr "Even wachten, DVD wordt gecontroleerd..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "Geen indexbestand gevonden. Aanmaken duurt even, doorgaan?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "Even wachten indexbestand wordt aangemaakt..." -+ -+msgid "Wrong DVD!" -+msgstr "Verkeerde DVD!" -+ -+msgid "Permanent Timeshift" -+msgstr "Permanente livebuffer" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Opslaglocatie" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "hardeschijf" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "geheugen" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Buffergrootte in geheugen (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Overlopen naar hardeschijf indien noodzakelijk" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Bewaar gepauzeerde buffer" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Buffergrootte op harddisk (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Buffergrootte (MB)" -diff -ruNp vdr-1.7.0/po/nn_NO.po vdr-1.7.0-extensions/po/nn_NO.po ---- vdr-1.7.0/po/nn_NO.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/nn_NO.po 2009-04-09 20:48:48.000000000 +0200 -@@ -8,7 +8,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2007-08-12 14:17+0200\n" - "Last-Translator: Truls Slevigen <truls@slevigen.no>\n" - "Language-Team: Norwegian\n" -@@ -22,13 +22,10 @@ msgstr "" - msgid "on" - msgstr "" - --msgid "none" --msgstr "" -- --msgid "high" -+msgid "auto" - msgstr "" - --msgid "low" -+msgid "none" - msgstr "" - - msgid "*** Invalid Channel ***" -@@ -319,12 +316,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarchy" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioritet" -- - msgid "Rolloff" - msgstr "" - -@@ -373,6 +364,9 @@ msgstr "Slutt" - msgid "VPS" - msgstr "" - -+msgid "Priority" -+msgstr "Prioritet" -+ - msgid "Lifetime" - msgstr "Levetid" - -@@ -907,9 +901,6 @@ msgstr "" - msgid "Button$Insert" - msgstr "" - --msgid "auto" --msgstr "" -- - msgid "Plugin" - msgstr "Plugin" - -@@ -1017,3 +1008,270 @@ msgstr "" - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/pl_PL.po vdr-1.7.0-extensions/po/pl_PL.po ---- vdr-1.7.0/po/pl_PL.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/pl_PL.po 2009-04-09 20:48:48.000000000 +0200 -@@ -8,7 +8,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-03-09 12:59+0100\n" - "Last-Translator: Michael Rakowski <mrak@gmx.de>\n" - "Language-Team: Polish\n" -@@ -22,15 +22,12 @@ msgstr "wy³±cz" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "auto" -+ - msgid "none" - msgstr "brak" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Niepoprawny kana³ ***" - -@@ -319,12 +316,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarchia" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Priorytet" -- - msgid "Rolloff" - msgstr "" - -@@ -373,6 +364,9 @@ msgstr "Koniec" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Priorytet" -+ - msgid "Lifetime" - msgstr "Czas ¿ycia" - -@@ -907,9 +901,6 @@ msgstr "Nadpisz" - msgid "Button$Insert" - msgstr "Wstaw" - --msgid "auto" --msgstr "auto" -- - msgid "Plugin" - msgstr "Wtyczka" - -@@ -1017,3 +1008,270 @@ msgstr "Naci¶nij dowolny klawisz aby nie - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR zostanie wy³±czony za %s minut" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/pt_PT.po vdr-1.7.0-extensions/po/pt_PT.po ---- vdr-1.7.0/po/pt_PT.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/pt_PT.po 2009-04-09 20:48:48.000000000 +0200 -@@ -7,7 +7,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-03-18 17:04+0100\n" - "Last-Translator: anonymous\n" - "Language-Team: Portuguese\n" -@@ -21,15 +21,12 @@ msgstr "off" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "Automático" -+ - msgid "none" - msgstr "nenhum" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Canal inválido ***" - -@@ -318,12 +315,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarquia" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioridade" -- - msgid "Rolloff" - msgstr "" - -@@ -372,6 +363,9 @@ msgstr "Fim" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioridade" -+ - msgid "Lifetime" - msgstr "Duração" - -@@ -906,9 +900,6 @@ msgstr "Substituir" - msgid "Button$Insert" - msgstr "Inserir" - --msgid "auto" --msgstr "Automático" -- - msgid "Plugin" - msgstr "Plugin" - -@@ -1016,3 +1007,270 @@ msgstr "Pressione qualquer tecla para nã - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR vai desligar em %s minutos" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/ro_RO.po vdr-1.7.0-extensions/po/ro_RO.po ---- vdr-1.7.0/po/ro_RO.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/ro_RO.po 2009-04-09 20:48:48.000000000 +0200 -@@ -8,7 +8,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-02-25 00:39+0100\n" - "Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n" - "Language-Team: Romanian\n" -@@ -24,15 +24,12 @@ msgstr "inactiv" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "automat" -+ - msgid "none" - msgstr "niciuna(ul)" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Canal invalid ***" - -@@ -321,12 +318,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Ierarhie" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioritate" -- - msgid "Rolloff" - msgstr "" - -@@ -375,6 +366,9 @@ msgstr "Sfârºit" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioritate" -+ - msgid "Lifetime" - msgstr "Timp de pãstrare" - -@@ -909,9 +903,6 @@ msgstr "Suprascrie" - msgid "Button$Insert" - msgstr "Insereazã" - --msgid "auto" --msgstr "automat" -- - msgid "Plugin" - msgstr "Plugin (modul adiþional)" - -@@ -1019,3 +1010,270 @@ msgstr "Apãsaþi orice tastã pentru a anu - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR se va închide în %s minute" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/ru_RU.po vdr-1.7.0-extensions/po/ru_RU.po ---- vdr-1.7.0/po/ru_RU.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/ru_RU.po 2009-04-09 20:48:48.000000000 +0200 -@@ -8,7 +8,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-02-15 16:37+0100\n" - "Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n" - "Language-Team: Russian\n" -@@ -22,15 +22,12 @@ msgstr "ÒëÚÛ" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "ÐÒâÞ" -+ - msgid "none" - msgstr "ÝØçÕÓÞ" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** ½ÕßàÐÒØÛìÝëÙ ÚÐÝÐÛ ***" - -@@ -319,12 +316,6 @@ msgstr "·ÐéØâÐ" - msgid "Hierarchy" - msgstr "¸ÕàÐàåØï" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "¿àØÞàØâÕâ" -- - msgid "Rolloff" - msgstr "" - -@@ -373,6 +364,9 @@ msgstr "ºÞÝÕæ" - msgid "VPS" - msgstr "VPS ßÞßàÐÒÚÐ" - -+msgid "Priority" -+msgstr "¿àØÞàØâÕâ" -+ - msgid "Lifetime" - msgstr "ÁàÞÚ åàÐÝÕÝØï" - -@@ -907,9 +901,6 @@ msgstr "·ÐÜÕÝÐ" - msgid "Button$Insert" - msgstr "²áâÐÒÚÐ" - --msgid "auto" --msgstr "ÐÒâÞ" -- - msgid "Plugin" - msgstr "¼ÞÔãÛì" - -@@ -1017,3 +1008,271 @@ msgstr "½ÐÖÜØâÕ ÛîÑãî ÚÝÞßÚã ÔÛï ÞâÜÕÝë - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR ÒëÚÛîçØâáï çÕàÕ× %s ÜØÝãâ" -+ -+msgid "Channel locked by LNB!" -+msgstr "ºÞÝÒÕàâÕà ÑÛÞÚØàãÕâ ÚÐÝÐÛ" -+ -+msgid "Childlock" -+msgstr "´ÕâáÚÐï ÑÛÞÚØàÞÒÚÐ" -+ -+msgid "Path" -+msgstr "¿ãâì" -+ -+msgid "Timer commands" -+msgstr "ºÞÜÜÐÝÔë âÐÙÜÕàÐ" -+ -+msgid "Rename recording" -+msgstr "¿ÕàÕØÜÕÝÞÒÐâì ×Ðߨáì" -+ -+msgid "Date" -+msgstr "´ÐâÐ" -+ -+msgid "Length" -+msgstr "´ÛØÝÐ" -+ -+msgid "Size" -+msgstr "ÀÐ×ÜÕà" -+ -+msgid "Delete marks information?" -+msgstr "ÃÔÐÛØâì ÜÕâÚØ?" -+ -+msgid "Delete resume information?" -+msgstr "²ÞááâÐÝÞÒØâì ÜÕâÚØ?" -+ -+msgid "DVD plugin is not installed!" -+msgstr "¼ÞÔãÛì DVD ÝÕ ãáâÐÝÞÒÛÕÝ!" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "ÓÛÐÒÝÐï ÔØàÕÚâÞàØï ßÞ ÐÛäÐÒØâã, ßÞÔÔØàÕÚâÞàØØ ÓØÑÚÞ" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "ÓÛÐÒÝÐï ÔØàÕÚâÞàØï ßÞ ÒàÕÜÕÝØ, ßÞÔÔØàÕÚâÞàØØ ÓØÑÚÞ" -+ -+msgid "all alphabetically" -+msgstr "ÒáÕ ßÞ ÐÛäÐÒØâã" -+ -+msgid "all by date" -+msgstr "ÒáÕ ßÞ ÒàÕÜÕÝØ" -+ -+msgid "Sorting" -+msgstr "ÁÞàâØàÞÒÚÐ" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "WarEagle ØÚÞÝÚØ" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "ÀÐ×ÜÕéÕÝØÕ ÚÞÜÐÝÔ Ò ÓÛÐÒÝÞÜ ÜÕÝî" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "¿ÞÚÐ× ßàÐÒØÛìÝÞÓÞ ÒÒÞÔÐ" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "¿ÞÚÐ× ÑÐÛÚØ ßàÞÓàÕááÐ" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "¿ÕàØÞÔ ÔÛï ßÞØáÚÐ ÔÒÞÙÝëå EPG(min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "²ÝÕèÝØÙ ØáâÞçÝØÚ ÔÒÞÙÝÞÓÞ EPG" -+ -+msgid "adjust" -+msgstr "ÝÐáâàÞØâì" -+ -+msgid "delete" -+msgstr "ãÔÐÛØâì" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "ÁÜÕèØÒÐÝØÕ ÒÝãâàÕÝÝÕÓÞ Ø ÒÝÕèÝÕÓÞ EPG" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "·ÐßàÕâ VPS áÞÑëâØï" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "¸áßÞÛì×ÞÒÐâì ÚÞààÕÚâØàÞÒÚã AC3-Transfer" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "¸áßÞÛì×ÞÒÐâì Sync Early " -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "DVB ãáâàÞÙáâÒÞ %d ØáßÞÛì×ãÕâ LNB No." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "»ÞÓØàÞÒÐÝØÕ ØáßÞÛì×ÞÒÐÝØï LNB" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "·Ðߨáì Dolby Digital" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "¿ÞàïÔÞÚ ÒØÔÕÞ ÔØàÕÚâÞàØØ" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "ºÞÛØçÕáâÒÞ ÒØÔÕÞ ÔØàÕÚâÞàØÙ" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "Video %d ßàØÞàØâÕâ" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Video %d ÜØÝ. áÒÞÑÞÔÝÞ MB" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "ÇØâÐÑÕÛìÝëÕ ØÜÕÝÐ äÐÙÛÞÒ" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "¼ÐÚá. àÐ×ÜÕà ×ÐßØáØ (GB)" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "¼ÞÝâÐÖ á hard link" -+ -+msgid "Setup.Recording$Show date" -+msgstr "¿ÞÚÐ×ëÒÐâì ÔÐâã" -+ -+msgid "Setup.Recording$Show time" -+msgstr "¿ÞÚÐ×ëÒÐâì ÒàÕÜï ×ÐߨáØ" -+ -+msgid "Setup.Recording$Show length" -+msgstr "¿ÞÚÐ×ëÒÐâì ßàÞÔÞÛÖØâÕÛìÝÞáâì ×ÐߨáØ" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "½Ð×ÒÐÝØÕ ÓÛÐÒÝÞÓÞ ÜÕÝî" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "¿ÞÚÐ× ÞÚÞÝçÐÝØï âÐÙÜÕàÐ" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "ÁÞàâØàÞÒÚÐ ×ÐߨáÕÙ ßÞ" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "ÁÞàâØàÞÒÚÐ ÔØàÕÚâÞàØÙ ÔÞ ×ÐߨáØ" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "°ÒâÞÜÐâØçÕáÚÞÕ ãÔÐÛÕÝØÕ ÜÞÝâÐÖÐ" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "Jump&Play" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Play&Jump" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "¿Ðã×Ð ÝÐ ßÞáÛÕÔÝÕÙ ÜÕâÚÕ" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "¿ÕàÕÓàãרâì ÜÕâÚØ" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "¿àÞßãáÚ áÕÚãÝÔ" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "¿àÞßãáÚ áÕÚãÝÔ ÜÕÔÛÕÝÝÞ" -+ -+msgid "Setup.Replay$Length" -+msgstr "´ÛØÝÐ" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "´ÛØÝÐ / ½ÞÜÕà" -+ -+msgid "Setup.Replay$Number" -+msgstr "½ÞÜÕà" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "ÀÕÖØÜ ßÞÚÐ×Ð DVD" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "ßÞÚÐ× ÒÕÔãéØå ÝãÛÕÙ" -+ -+msgid "Setup.Replay$never" -+msgstr "ÝØÚÞÓÔÐ" -+ -+msgid "Setup.Replay$on begin" -+msgstr "Ò ÝÐçÐÛÕ" -+ -+msgid "Setup.Replay$on end" -+msgstr "² ÚÞÝæÕ" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "Ò ÝÐçÐÛÕ Ø Ò ÚÞÝæÕ" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "¾âÚàëâì" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "¿àÕÔÕÛ áÚÞàÞáâØ DVD" -+ -+msgid "Jump" -+msgstr "¿àëÖÞÚ" -+ -+msgid "Skip +60s" -+msgstr "¿àÞßãáÚ +60s" -+ -+msgid "Skip -60s" -+msgstr "¿àÞßãáÚ -60s" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "¼ÞÝâÐÖÕà àÐÑÞâÐÕâ - ´ÞÑÐÒØâì Ò ÞçÕàÕÔì?" -+ -+msgid "Rename$Up" -+msgstr "²ÒÕàå" -+ -+msgid "Rename$Down" -+msgstr "²ÝØ×" -+ -+msgid "Rename$Previous" -+msgstr "¿àÕÔëÔãéØÙ" -+ -+msgid "Rename$Next" -+msgstr "ÁÛÕÔãîéØÙ" -+ -+msgid "Please mount %s" -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÜÞÝâØàãÙâÕ %s" -+ -+msgid "Please mount DVD %04d" -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÜÞÝâØàãÙâÕ DVD %04d" -+ -+msgid "Please mount DVD %d" -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÜÞÝâØàãÙâÕ DVD %d" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÞÖÔØâÕ. ¿àÞÒÕàÚÐ DVD..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "¸ÝÔÕÚá äÐÙÛ ÝÕ ÝÐÙÔÕÝ. ÁÞ×ÔÐÝØÕ âàÕÑãÕâ ÒàÕÜÕÝØ. ÁÞ×ÔÐâì?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÞÖÔØâÕ. ÁÞ×ÔÐÝØÕ ØÝÔÕÚá äÐÙÛÐ..." -+ -+msgid "Wrong DVD!" -+msgstr "¾èØÑÚÐ DVD!" -+ -+msgid "Permanent Timeshift" -+msgstr "¿ÞáâÞïÝÝëÙ âÐÙÜèØäâ" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "¼ÕáâÞÝÐåÞÖÔÕÝØï" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "ÖÕáâÚØÙ ÔØáÚ" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "ßÐÜïâì" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "ÀÐ×ÜÕà ÑãäÕàÐ Ò ßÐÜïâØ (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "´ÞÑÐÒÛïâì ÖÕáâÚØÙ ÔØáÚ ÕáÛØ ÝÕÞÑåÞÔØÜÞ" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "ÅàÐÝÕÝØÕ ÑãäÕàÐ ßÐã×ë" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "ÀÐ×ÜÕà ÑãäÕàÐ ÝÐ ÖÕáâÚÞÜ ÔØáÚÕ (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "ÀÐ×ÜÕà ÑãäÕàÐ (MB)" -+ -diff -ruNp vdr-1.7.0/po/sl_SI.po vdr-1.7.0-extensions/po/sl_SI.po ---- vdr-1.7.0/po/sl_SI.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/sl_SI.po 2009-04-09 20:48:48.000000000 +0200 -@@ -8,7 +8,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-02-28 19:44+0100\n" - "Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n" - "Language-Team: Slovenian\n" -@@ -22,15 +22,12 @@ msgstr "izklop" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "avtomatsko" -+ - msgid "none" - msgstr "nobeden" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Neznan kanal ***" - -@@ -319,12 +316,6 @@ msgstr "Za¹èita" - msgid "Hierarchy" - msgstr "Hierarhija" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioriteta" -- - msgid "Rolloff" - msgstr "" - -@@ -373,6 +364,9 @@ msgstr "Konec" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioriteta" -+ - msgid "Lifetime" - msgstr "Veljavnost" - -@@ -907,9 +901,6 @@ msgstr "Prepi¹i" - msgid "Button$Insert" - msgstr "Vstavi" - --msgid "auto" --msgstr "avtomatsko" -- - msgid "Plugin" - msgstr "Vstavek" - -@@ -1017,3 +1008,270 @@ msgstr "Pritisni katerokoli tipko za pre - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR se bo zaustavil v %s minutah" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/sv_SE.po vdr-1.7.0-extensions/po/sv_SE.po ---- vdr-1.7.0/po/sv_SE.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/sv_SE.po 2009-04-09 20:48:48.000000000 +0200 -@@ -10,7 +10,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-03-12 18:25+0100\n" - "Last-Translator: Magnus Andersson <svankan@bahnhof.se>\n" - "Language-Team: Swedish\n" -@@ -24,15 +24,12 @@ msgstr "av" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "automatisk" -+ - msgid "none" - msgstr "ingen" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Felaktig kanal ***" - -@@ -321,12 +318,6 @@ msgstr "Guard" - msgid "Hierarchy" - msgstr "Hierarchy" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Prioritet" -- - msgid "Rolloff" - msgstr "" - -@@ -375,6 +366,9 @@ msgstr "Slutar" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Prioritet" -+ - msgid "Lifetime" - msgstr "Livstid" - -@@ -909,9 +903,6 @@ msgstr "Skriv över" - msgid "Button$Insert" - msgstr "Infoga" - --msgid "auto" --msgstr "automatisk" -- - msgid "Plugin" - msgstr "Modul" - -@@ -1019,3 +1010,270 @@ msgstr "Tryck valfri knapp för att återk - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR kommer att stängas ned om %s minuter" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/tr_TR.po vdr-1.7.0-extensions/po/tr_TR.po ---- vdr-1.7.0/po/tr_TR.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/tr_TR.po 2009-04-09 20:48:48.000000000 +0200 -@@ -7,7 +7,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-02-28 00:33+0100\n" - "Last-Translator: Oktay Yolgeçen <oktay_73@yahoo.de>\n" - "Language-Team: Turkish\n" -@@ -21,15 +21,12 @@ msgstr "kapalý" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "otomatik" -+ - msgid "none" - msgstr "hiç" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** Geçersiz kanal ***" - -@@ -318,12 +315,6 @@ msgstr "Koruma" - msgid "Hierarchy" - msgstr "Hiyerarþi" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "Öncelik" -- - msgid "Rolloff" - msgstr "" - -@@ -372,6 +363,9 @@ msgstr "Bitiþ" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "Öncelik" -+ - msgid "Lifetime" - msgstr "Ömrü" - -@@ -906,9 +900,6 @@ msgstr "Üstüne yaz" - msgid "Button$Insert" - msgstr "Ekle" - --msgid "auto" --msgstr "otomatik" -- - msgid "Plugin" - msgstr "Eklenti" - -@@ -1016,3 +1007,270 @@ msgstr "Yeniden baþlatmayý iptal etmek i - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR %s dakikada kapanacak" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.0/po/uk_UA.po vdr-1.7.0-extensions/po/uk_UA.po ---- vdr-1.7.0/po/uk_UA.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/uk_UA.po 2009-04-09 20:48:48.000000000 +0200 -@@ -7,7 +7,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-03-07 14:17+0200\n" - "Last-Translator: Yarema Aka Knedlyk <yupadmin@gmail.com>\n" - "Language-Team: Ukrainian\n" -@@ -21,15 +21,12 @@ msgstr "ÒØÚÛ" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "ÐÒâÞ" -+ - msgid "none" - msgstr "ÝöçÞÓÞ" - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "*** ½ÕßàÐÒØÛìÝØÙ ÚÐÝÐÛ ***" - -@@ -318,12 +315,6 @@ msgstr "·ÐåØáâ" - msgid "Hierarchy" - msgstr "¦ôàÐàåöï" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "¿àöÞàØâÕâ" -- - msgid "Rolloff" - msgstr "" - -@@ -372,6 +363,9 @@ msgstr "ºöÝÕæì" - msgid "VPS" - msgstr "VPS ßÞßàÐÒÚÐ" - -+msgid "Priority" -+msgstr "¿àöÞàØâÕâ" -+ - msgid "Lifetime" - msgstr "ÁâàÞÚ ×ÑÕàöÓÐÝÝï" - -@@ -906,9 +900,6 @@ msgstr "·ÐÜöÝÐ" - msgid "Button$Insert" - msgstr "²áâÐÒÚÐ" - --msgid "auto" --msgstr "ÐÒâÞ" -- - msgid "Plugin" - msgstr "¼ÞÔãÛì" - -diff -ruNp vdr-1.7.0/po/zh_CN.po vdr-1.7.0-extensions/po/zh_CN.po ---- vdr-1.7.0/po/zh_CN.po 2008-04-13 16:16:58.000000000 +0200 -+++ vdr-1.7.0-extensions/po/zh_CN.po 2009-04-09 20:48:48.000000000 +0200 -@@ -7,7 +7,7 @@ msgid "" - msgstr "" - "Project-Id-Version: VDR 1.6.0\n" - "Report-Msgid-Bugs-To: <vdr-bugs@cadsoft.de>\n" --"POT-Creation-Date: 2008-04-12 14:19+0200\n" -+"POT-Creation-Date: 2008-12-14 16:10+0100\n" - "PO-Revision-Date: 2008-03-21 08:44+0800\n" - "Last-Translator: Nan Feng <nfgx@21cn.com>\n" - "Language-Team: Chinese\n" -@@ -24,15 +24,12 @@ msgstr "å…³" - msgid "on" - msgstr "" - -+msgid "auto" -+msgstr "自动" -+ - msgid "none" - msgstr "æ— " - --msgid "high" --msgstr "" -- --msgid "low" --msgstr "" -- - msgid "*** Invalid Channel ***" - msgstr "***æ— æ•ˆé¢‘é“ ***" - -@@ -321,12 +318,6 @@ msgstr "防护" - msgid "Hierarchy" - msgstr "层次" - --msgid "Alpha" --msgstr "" -- --msgid "Priority" --msgstr "优先" -- - msgid "Rolloff" - msgstr "" - -@@ -375,6 +366,9 @@ msgstr "åœæ¢" - msgid "VPS" - msgstr "VPS" - -+msgid "Priority" -+msgstr "优先" -+ - msgid "Lifetime" - msgstr "终生" - -@@ -909,9 +903,6 @@ msgstr "覆盖" - msgid "Button$Insert" - msgstr "æ’å…¥" - --msgid "auto" --msgstr "自动" -- - msgid "Plugin" - msgstr "æ’ä»¶" - -diff -ruNp vdr-1.7.0/README.cmdsubmenu vdr-1.7.0-extensions/README.cmdsubmenu ---- vdr-1.7.0/README.cmdsubmenu 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/README.cmdsubmenu 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,54 @@ -+CmdSubmenu patch for VDR -+------------------------ -+ -+With this patch the commands and recording commands menus can be organised -+hierarchically. To create a submenu entry, prefix the name by one ore more "-". -+ -+ -+Standard: -+ -+description_1 : cmd_1 -+description_2 : cmd_2 -+ -+ -+A submenu with two entries: -+ -+Submenu title ... : echo "submenu" -+-description_1 : cmd_1 -+-description_2 : cmd_2 -+ -+The dummy command in the title row is necessary. -+ -+ -+* History -+ -+ 2003-10-08: Version 0.1 - Albu at vdrportal.de -+ http://vdrportal.de/board/thread.php?threadid=6319 -+ -+ 2003-10-09: Version 0.2 - Tobias Grimm <tg@e-tobi.net> -+ - Added Define CMD_SUBMENUS in Makefile -+ -+ 2004-05-28: Version 0.3 - Thomas Günther <tom@toms-cafe.de> -+ - Fixed compilation with gcc-3.3.3 -+ - Added new virtual method AddConfig in cConfig -+ - Redefining of method Add in cListBase to virtual no longer necessary -+ - Improved code in menu.c -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.3.diff -+ -+ 2004-12-20: Version 0.4 - Thomas Günther <tom@toms-cafe.de> -+ - Solved conflict with jumpplay patch 0.6 -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.4.diff -+ -+ 2006-04-22: Version 0.5 - Thomas Günther <tom@toms-cafe.de> -+ - Added version define CMDSUBMENUVERSNUM -+ - Reformated to VDR style indentions -+ - Added description in README.cmdsubmenu -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.5-1.3.47.diff -+ -+ 2006-04-23: Version 0.6 - Thomas Günther <tom@toms-cafe.de> -+ - Fixed menus with more than one level -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.6-1.3.47.diff -+ -+ 2006-05-15: Version 0.7 - Thomas Günther <tom@toms-cafe.de> -+ - Fixed build with G++ 4.1 (extra qualification) -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.7-1.4.0.diff -diff -ruNp vdr-1.7.0/README-HLCUTTER vdr-1.7.0-extensions/README-HLCUTTER ---- vdr-1.7.0/README-HLCUTTER 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/README-HLCUTTER 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,117 @@ -+ -+ VDR-HLCUTTER README -+ -+ -+Written by: Udo Richter -+Available at: http://www.udo-richter.de/vdr/patches.html#hlcutter -+ http://www.udo-richter.de/vdr/patches.en.html#hlcutter -+Contact: udo_richter@gmx.de -+ -+ -+ -+About -+----- -+ -+The hard link cutter patch changes the recording editing algorithms of VDR to -+use filesystem hard links to 'copy' recording files whenever possible to speed -+up editing recordings noticeably. -+ -+The patch has matured to be quite stable, at least I'm using it without issues. -+Nevertheless the patch is still in development and should be used with caution. -+The patch is EXPERIMENTAL for multiple /videoxx folders. The safety checks -+should prevent data loss, but you should always carefully check the results. -+ -+While editing a recording, the patch searches for any 00x.vdr files that dont -+contain editing marks and would normally be copied 1:1 unmodified to the edited -+recording. In this case the current target 00x.vdr file will be aborted, and -+the cutter process attempts to duplicate the source file as a hard link, so -+that both files share the same disk space. If this succeeds, the editing -+process fast-forwards through the duplicated file and continues normally -+beginning with the next source file. If hard linking fails, the cutter process -+continues with plain old copying. (but does not take up the aborted last file.) -+ -+After editing, the un-edited recording can be deleted as usual, the hard linked -+copies will continue to exist as the only remaining copy. -+ -+To be effective, the default 'Max. video file size (MB)' should be lowered. -+The patch lowers the smallest possible file size to 1mb. Since VDR only -+supports up to 255 files, this would limit the recording size to 255Mb or -+10 minutes, in other words: This setting is insane! -+ -+To make sure that the 255 file limit will not be reached, the patch also -+introduces "Max. recording size (GB)" with a default of 100Gb (66 hours), and -+increases the file size to 2000Mb early enough, so that 100Gb-recordings will -+fit into the 255 files. -+ -+Picking the right parameters can be tricky. The smaller the file size, the -+faster the editing process works. However, with a small file size, long -+recordings will fall back to 2000Mb files soon, that are slow on editing again. -+ -+Here are some examples: -+ -+Max file size: 100Gb 100Gb 100Gb 100Gb 100Gb 100Gb 100Gb -+Max recording size: 1Mb 10Mb 20Mb 30Mb 40Mb 50Mb 100Mb -+ -+Small files: 1-203 1-204 1-205 1-206 1-207 1-209 1-214 -+ GBytes: 0.2 2.0 4.0 6.0 8.1 10.2 20.9 -+ Hours: 0.13 1.3 2.65 4 5.4 6.8 13.9 -+ -+Big (2000mb) files: 204-255 204-255 206-255 207-255 208-255 210-255 215-255 -+ GBytes: 101.5 99.6 97.7 95.7 93.8 89.8 80.1 -+ Hours: 67 66 65 63 62 60 53 -+ -+A recording limit of 100Gb keeps plenty of reserve without blocking too much -+file numbers. And with a file size of 30-40Mb, recordings of 4-5 hours fit into -+small files completely. (depends on bit rate of course) -+ -+ -+ -+The patch must be enabled in Setup-> Recordings-> Hard Link Cutter. When -+disabled, the cutter process behaves identical to VDR's default cutter. -+ -+There's a //#define HARDLINK_TEST_ONLY in the videodir.c file that enables a -+test-mode that hard-links 00x.vdr_ files only, and continues the classic -+editing. The resulting 00x.vdr and 00x.vdr_ files should be identical. If you -+delete the un-edited recording, dont forget to delete the *.vdr_ files too, -+they will now eat real disk space. -+ -+Note: 'du' displays the disk space of hard links only on first appearance, and -+usually you will see a noticeably smaller size on the edited recording. -+ -+ -+History -+------- -+Version 0.2.0 -+ -+ New: Support for multiple /videoXX recording folders, using advanced searching -+ for matching file systems where a hard link can be created. -+ Also supports deep mounted file systems. -+ Fix: Do not fail if last mark is a cut-in. (Again.) -+ -+Version 0.1.4 -+ New: Dynamic increase of file size before running out of xxx.vdr files -+ Fix: Last edit mark is not a cut-out -+ Fix: Write error if link-copied file is smaller than allowed file size -+ Fix: Broken index/marks if cut-in is at the start of a new file -+ Fix: Clear dangeling pointer to free'd cUnbufferedFile, -+ thx to Matthias Schwarzott -+ -+Version 0.1.0 -+ Initial release -+ -+ -+ -+ -+Future plans -+------------ -+ -+Since original and edited copy share disk space, free space is wrong if one of -+them is moved to *.del. Free space should only count files with hard link -+count = 1. This still goes wrong if all copies get deleted. -+ -+ -+For more safety, the hard-linked files may be made read-only, as modifications -+to one copy will affect the other copy too. (except deleting, of course) -+ -+ -+SetBrokenLink may get lost on rare cases, this needs some more thoughts.Index: vdr-1.5.9/README.jumpplay -diff -ruNp vdr-1.7.0/README.jumpplay vdr-1.7.0-extensions/README.jumpplay ---- vdr-1.7.0/README.jumpplay 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/README.jumpplay 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,92 @@ -+JumpPlay patch for VDR -+---------------------- -+ -+This patch changes the replay behaviour for recordings that contain editing -+marks. It allows to immediately continue the replay after jumping forward to -+the next mark, and to automatically jump over the commercial break to the next -+"start" mark, if an "end" mark is reached. -+ -+The features of this patch can be turned on or off with parameters in the replay -+setup. See MANUAL for description of this parameters: "Jump&Play", "Play&Jump", -+"Pause at last mark" and "Reload marks". -+ -+ -+* History -+ -+ 2003-07-04: jumpandrun.diff - the Noad <theNoad@SoftHome.net> -+ Jump&Play -+ -+ 2003-12-06: Version 0.0 - Torsten Kunkel <vdr@tkunkel.de> -+ Play&Jump (only if progressbar is visible) -+ Setup parameters Jump&Play and Play&Jump in the replay setup -+ -+ 2004-01-20: Version 0.1 - Thomas Günther <tom@toms-cafe.de> -+ Jump&Play: -+ - fixed speed after jump -+ - fixed removing of marks -+ Play&Jump: -+ - jump only on "end" marks -+ -+ 2004-01-27: Version 0.2 - Thomas Günther <tom@toms-cafe.de> -+ Jump&Play: -+ - fixed double jump -+ Play&Jump: -+ - fixed mark detection: fuzzy detection (until 3 seconds after mark) -+ - jump without progressbar -+ - mode "progressbar only" for old behaviour -+ -+ 2004-01-31: Version 0.3 - Thomas Günther <tom@toms-cafe.de> -+ Jump&Play: -+ - fixed display frames -+ Play&Jump: -+ - fixed end of playing at last mark -+ -+ 2004-07-11: Version 0.4 - Thomas Günther <tom@toms-cafe.de> -+ Jump&Play: -+ - don't play after jump to end -+ Play&Jump: -+ - don't prevent jumping after hide or show -+ Less conflicts with other patches (Elchi/AutoPID) -+ -+ 2004-08-21: Version 0.5 - Thomas Günther <tom@toms-cafe.de> -+ Play&Jump: -+ - exact jumps, replay like edited recording (no fuzzy mark detection) -+ - jump to first mark if replay starts at the beginning -+ - check jump marks with '8' key -+ - mode "progressbar only" removed -+ Description in README.jumpplay -+ -+ 2004-12-28: Version 0.6 - Thomas Günther <tom@toms-cafe.de> -+ Adapted noad extensions (from the Noad <theNoad@SoftHome.net>) to -+ jumpplay-0.5: -+ - cyclic reloading of marks found by noad online-scan -+ - don't stop after the last mark in case of live-recordings -+ New setup parameter "Load marks interval (s)" -+ Updated description in README.jumpplay -+ -+ 2006-04-14: Version 0.7 - Thomas Günther <tom@toms-cafe.de> -+ Fixed jump to first mark (crashed with plugin extrecmenu-0.9) -+ Added version define JUMPPLAYVERSNUM -+ Added placeholders for Czech language texts -+ Cleaned up i18n entries (support only VDR >= 1.3.29) -+ Improved description of i18n placeholders - hoping for real language texts -+ -+ 2006-05-12: Version 0.8 - Thomas Günther <tom@toms-cafe.de> -+ Fixed segfault in dvbplayer thread while the replaycontrol thread is -+ reloading the marks (thanks to horchi at vdrportal.de for reporting this - -+ see http://vdrportal.de/board/thread.php?postid=450463#post450463): -+ New class cMarksReload checks the timestamp of marks.vdr in 10 seconds -+ intervals, so the marks in the threads dvbplayer and replaycontrol can be -+ reloaded independently -+ Changed setup parameter "Load marks interval (s)" to "Reload marks" -+ Updated description in README.jumpplay -+ -+ 2006-05-28: Version 0.9 - Thomas Günther <tom@toms-cafe.de> -+ New setup parameter "Pause at last mark" -+ Updated description in README.jumpplay -+ Moved parameters description to MANUAL -+ -+ 2009-03-31: Version 1.0 - Thomas Günther <tom@toms-cafe.de> -+ Play&Jump: -+ - set resume position to 0 if replay stops at the first mark -+ Added French language texts (thanks to Michaël Nival) -diff -ruNp vdr-1.7.0/README.MainMenuHooks vdr-1.7.0-extensions/README.MainMenuHooks ---- vdr-1.7.0/README.MainMenuHooks 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/README.MainMenuHooks 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,55 @@ -+This is a "patch" for the Video Disk Recorder (VDR). -+ -+* Authors: -+Tobias Grimm <vdr at e-tobi dot net> -+Martin Prochnow <nordlicht at martins-kabuff dot de> -+Frank Schmirler <vdrdev at schmirler dot de> -+Christian Wieninger <cwieninger at gmx dot de> -+ -+* Description: -+This patch allows plugins to replace the VDR mainmenus "Schedule", -+"Channels", "Timers" and "Recordings" by a different implementation. -+ -+The patch is based on a suggestion of Christian Wieninger back in 2006 -+(http://www.linuxtv.org/pipermail/vdr/2006-March/008234.html). It is -+meant to be an interim solution for VDR 1.4 until (maybe) VDR 1.5 -+introduces an official API for this purpose. -+ -+* Installation -+Change into the VDR source directory, then issue -+ patch -p1 < path/to/MainMenuHooks-v1_0.patch -+and recompile. -+ -+* Notes for plugin authors -+The following code sample shows the required plugin code for replacing -+the original Schedule menu: -+ -+bool cMyPlugin::Service(const char *Id, void *Data) -+{ -+ cOsdMenu **menu = (cOsdMenu**) Data; -+ if (MySetup.replaceSchedule && -+ strcmp(Id, "MainMenuHooksPatch-v1.0::osSchedule") == 0) { -+ if (menu) -+ *menu = (cOsdMenu*) MainMenuAction(); -+ return true; -+ } -+ return false; -+} -+ -+A plugin can replace more than one menu at a time. Simply replace the -+call to MainMenuAction() in the sample above by appropriate code. -+ -+Note that a plugin *should* offer a setup option which allows the user -+to enable or disable the replacement. "Disabled" would be a reasonable -+default setting. By testing for define MAINMENUHOOKSVERSNUM, a plugin -+can leave the setup option out at compiletime. -+ -+In case there is an internal problem when trying to open the replacement -+menu, it is safe to return true even though Data is NULL. However an -+OSD message should indicate the problem to the user. -+ -+Feel free to ship this patch along with your plugin. However if you -+think you need to modify the patch, we'd encourage you to contact the -+authors first or at least use a service id which differs in more than -+just the version number. -+ -diff -ruNp vdr-1.7.0/README.sortrec vdr-1.7.0-extensions/README.sortrec ---- vdr-1.7.0/README.sortrec 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/README.sortrec 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,48 @@ -+Sort Recordings patch for VDR -+----------------------------- -+Copyright (C) 2005 Frank99 @vdr-portal.de -+Copyright (C) 2006-2008 Christoph Haubrich -+ -+Released under the same license as VDR itself, for details see vdr.c or -+http://firefly.vdr-developer.org/patches -+ -+This patch changes the sort behaviour of the recordings menu. It is based -+on the patch available here: http://www.vdr-portal.de/board/thread.php?threadid=36031 -+Required for this patch is the liemikuutio-patch for VDR which can be found here: -+http://www.saunalahti.fi/%7Erahrenbe/vdr/patches/ -+ -+There are four sorting modes available after this patch is applied: -+ -+mode behaviour for behaviour for -+ main directory sub directories -+-------------------------------------------------------------------------- -+ 0 alphabetically if special character(*) is found alphabetically, -+ else by date -+ 1 by date if special character(*) is found alphabetically, -+ else by date -+ 2 alphabetically alphabetically -+ 3 by date by date -+ -+(*) if the name of a subdirectory ends with one of ".-$" (dot, hyphen, dollar sign) -+ it is sorted alphabetically in sort mode 0 and 1 -+ -+Sort mode 0 with none of the special characters at the end of any subdir -+corresponds to the default sorting mode of the original VDR. -+ -+The sorting mode can be switched through in the recording menu with the '0' key -+(0->1->2->3->0->...), a default for startup can be set in the setup->recordings menu. -+ -+Additionally the sort order (ascending/descending) can be toggled by the '9' key -+(which is always set to ascending after a restart) -+ -+If you like the to see subdirectories before recordings you can select to put -+directories first in the setup->recordings menu. -+ -+If you would like the sorting to ignore a leading '%' (as normally displayed before -+cutted recordings) you can achive this by setting the environment variable LC_COLLATE -+properly (eg. LC_COLLATE=de_DE@euo in runvdr for germany). -+ -+History: -+2006-08-13 v3, sortrec release for VDR 1.4.1 and liemikuutio 1.8 -+2007-01-28 v3a, moved #ifdef from optimized-rename-patch to sortrec -+2008-03-29 v3b, removed ASCII-170 and ASCII-183 to make sortrec Utf8-ready -diff -ruNp vdr-1.7.0/README.timer-info vdr-1.7.0-extensions/README.timer-info ---- vdr-1.7.0/README.timer-info 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/README.timer-info 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,53 @@ -++------------------------------------------------------------------------------+ -+| Info about the timer-info-patch by Brougs78 | -+| brougs78@gmx.net / home.pages.at/brougs78 | -++------------------------------------------------------------------------------+ -+ -+ -+README timer-info: -+------------------ -+ -+Features: -+ - Shows info, if it is possible to record an event in the timer menu of vdr. -+ For calculations the free space incl. the deleted recordings is used, -+ considering an average consumtion of 25.75 MB/min (also used by vdr itself). -+ The first column in the timer-list shows: -+ ( + ) recording will be most probably possible (enough space) -+ (+/-) recording may be possible -+ ( - ) recording will most probably fail (to less space) -+ The calculations also consider repeating timers. -+ - It is possible to deactivate the patch in the OSD-menu of VDR. -+ -+ -+HISTORY timer-info: -+------------------- -+ -+25.11.2004: v0.1 -+ - Initial release -+ -+11.01.2005: v0.1b -+ - Bugfixes for vdr-1.3.18 -+ - In the menu the free recording-time no longer includes the space of the -+ deleted recordings, because this slowed the vdr down to much. -+ -+08.07.2005: v0.1c -+ - Made the patch configurable -+ -+29.01.2006: v0.2 - Thomas Günther <tom@toms-cafe.de> -+ - Rewritten great parts for vdr-1.3.38+ -+ http://toms-cafe.de/vdr/download/vdr-timer-info-0.2-1.3.38+.diff -+ -+05.02.2006: v0.3 - Thomas Günther <tom@toms-cafe.de> -+ - Fixed refresh of timer menu in cMenuTimers::OnOff -+ - Fixed check of repeating timers -+ - Syslog debug messages can be enabled with Define DEBUG_TIMER_INFO -+ http://toms-cafe.de/vdr/download/vdr-timer-info-0.3-1.3.38+.diff -+ -+03.03.2006: v0.4 - Thomas Günther <tom@toms-cafe.de> -+ - Adapted to vdr-1.3.44 -+ - Removed setup parameter "Show timer-info" -+ http://toms-cafe.de/vdr/download/vdr-timer-info-0.4-1.3.44.diff -+ -+03.03.2006: v0.5 - Tobias Grimm <tg@e-tobi.net> -+ - Adapted to vdr-1.3.45 -+ http://toms-cafe.de/vdr/download/vdr-timer-info-0.4-1.3.45.diff -diff -ruNp vdr-1.7.0/recorder.c vdr-1.7.0-extensions/recorder.c ---- vdr-1.7.0/recorder.c 2007-02-24 17:36:24.000000000 +0100 -+++ vdr-1.7.0-extensions/recorder.c 2009-04-09 20:48:48.000000000 +0200 -@@ -11,6 +11,9 @@ - #include <stdarg.h> - #include <stdio.h> - #include <unistd.h> -+#ifdef USE_TTXTSUBS -+#include <stdint.h> -+#endif /* TTXTSUBS */ - #include "shutdown.h" - - #define RECORDERBUFSIZE MEGABYTE(5) -@@ -26,6 +29,9 @@ - - class cFileWriter : public cThread { - private: -+#ifdef USE_TTXTSUBS -+ cTtxtSubsRecorderBase *ttxtSubsRecorder; -+#endif /* TTXTSUBS */ - cRemux *remux; - cFileName *fileName; - cIndexFile *index; -@@ -38,13 +44,24 @@ private: - protected: - virtual void Action(void); - public: -+#ifdef USE_TTXTSUBS -+ cFileWriter(const char *FileName, cRemux *Remux, cTtxtSubsRecorderBase *tsr); -+#else - cFileWriter(const char *FileName, cRemux *Remux); -+#endif /* TTXTSUBS */ - virtual ~cFileWriter(); - }; - -+#ifdef USE_TTXTSUBS -+cFileWriter::cFileWriter(const char *FileName, cRemux *Remux, cTtxtSubsRecorderBase *tsr) -+#else - cFileWriter::cFileWriter(const char *FileName, cRemux *Remux) -+#endif /* TTXTSUBS */ - :cThread("file writer") - { -+#ifdef USE_TTXTSUBS -+ ttxtSubsRecorder = tsr; -+#endif /* TTXTSUBS */ - fileName = NULL; - remux = Remux; - index = NULL; -@@ -67,6 +84,10 @@ cFileWriter::~cFileWriter() - Cancel(3); - delete index; - delete fileName; -+#ifdef USE_TTXTSUBS -+ if (ttxtSubsRecorder) -+ delete ttxtSubsRecorder; -+#endif /* TTXTSUBS */ - } - - bool cFileWriter::RunningLowOnDiskSpace(void) -@@ -85,7 +106,11 @@ bool cFileWriter::RunningLowOnDiskSpace( - bool cFileWriter::NextFile(void) - { - if (recordFile && pictureType == I_FRAME) { // every file shall start with an I_FRAME -+#ifndef USE_HARDLINKCUTTER - if (fileSize > MEGABYTE(Setup.MaxVideoFileSize) || RunningLowOnDiskSpace()) { -+#else -+ if (fileSize > fileName->MaxFileSize() || RunningLowOnDiskSpace()) { -+#endif /* HARDLINKCUTTER */ - recordFile = fileName->NextFile(); - fileSize = 0; - } -@@ -111,6 +136,18 @@ void cFileWriter::Action(void) - } - fileSize += Count; - remux->Del(Count); -+#ifdef USE_TTXTSUBS -+ // not sure if the pictureType test is needed, but it seems we can get -+ // incomplete pes packets from remux if we are not getting pictures? -+ if (ttxtSubsRecorder && pictureType != NO_PICTURE) { -+ uint8_t *subsp; -+ size_t len; -+ if (ttxtSubsRecorder->GetPacket(&subsp, &len)) { -+ recordFile->Write(subsp, len); -+ fileSize += len; -+ } -+ } -+#endif /* TTXTSUBS */ - } - else - break; -@@ -126,8 +163,23 @@ void cFileWriter::Action(void) - - // --- cRecorder ------------------------------------------------------------- - -+#if defined (USE_LIVEBUFFER) || defined (USE_TTXTSUBS) -+cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids -+#ifdef USE_TTXTSUBS -+ ,cTtxtSubsRecorderBase *tsr -+#endif /* TTXTSUBS */ -+#ifdef USE_LIVEBUFFER -+ ,cLiveBuffer *LiveBuffer -+#endif /* LIVEBUFFER */ -+ ) -+#else - cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids) -+#endif /* LIVEBUFFER || TTXTSUBS */ -+#ifdef USE_DOLBYINREC -+:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyInRecordings ? DPids : NULL, SPids) -+#else - :cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) -+#endif /* DOLBYINREC */ - ,cThread("recording") - { - // Make sure the disk is up and running: -@@ -136,8 +188,22 @@ cRecorder::cRecorder(const char *FileNam - - ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, TS_SIZE * 2, true, "Recorder"); - ringBuffer->SetTimeouts(0, 100); -+#ifdef USE_DOLBYINREC -+ remux = new cRemux(VPid, APids, Setup.UseDolbyInRecordings ? DPids : NULL, SPids, true); -+#else - remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, true); -+#endif /* DOLBYINREC */ -+#ifdef USE_LIVEBUFFER -+ fileName = strdup(FileName); -+ writer = NULL; -+ liveBuffer = LiveBuffer; -+ if (!LiveBuffer) -+#endif /* LIVEBUFFER */ -+#ifdef USE_TTXTSUBS -+ writer = new cFileWriter(FileName, remux, tsr); -+#else - writer = new cFileWriter(FileName, remux); -+#endif /* TTXTSUBS */ - } - - cRecorder::~cRecorder() -@@ -146,11 +212,17 @@ cRecorder::~cRecorder() - delete writer; - delete remux; - delete ringBuffer; -+#ifdef USE_LIVEBUFFER -+ free(fileName); -+#endif /* LIVEBUFFER */ - } - - void cRecorder::Activate(bool On) - { - if (On) { -+#ifdef USE_LIVEBUFFER -+ if (writer) -+#endif /* LIVEBUFFER */ - writer->Start(); - Start(); - } -@@ -174,6 +246,29 @@ void cRecorder::Action(void) - uchar *b = ringBuffer->Get(r); - if (b) { - int Count = remux->Put(b, r); -+#ifdef USE_LIVEBUFFER -+ if (!writer && liveBuffer) { -+ int c; -+ uchar pictureType; -+ uchar *p = remux->Get(c, &pictureType); -+ if (pictureType == I_FRAME && p && p[0]==0x00 && p[1]==0x00 && p[2]==0x01 && (p[7] & 0x80) && p[3]>=0xC0 && p[3]<=0xEF) { -+ int64_t pts = (int64_t) (p[ 9] & 0x0E) << 29 ; -+ pts |= (int64_t) p[ 10] << 22 ; -+ pts |= (int64_t) (p[ 11] & 0xFE) << 14 ; -+ pts |= (int64_t) p[ 12] << 7 ; -+ pts |= (int64_t) (p[ 13] & 0xFE) >> 1 ; -+ liveBuffer->CreateIndexFile(fileName,pts); -+#ifdef USE_TTXTSUBS -+ writer = new cFileWriter(fileName, remux, ttxtSubsRecorder); -+#else -+ writer = new cFileWriter(fileName, remux); -+#endif /* TTXTSUBS */ -+ writer->Start(); -+ } -+ else -+ remux->Del(c); -+ } -+#endif /* LIVEBUFFER */ - if (Count) - ringBuffer->Del(Count); - else -diff -ruNp vdr-1.7.0/recorder.h vdr-1.7.0-extensions/recorder.h ---- vdr-1.7.0/recorder.h 2007-01-05 11:44:05.000000000 +0100 -+++ vdr-1.7.0-extensions/recorder.h 2009-04-09 20:48:48.000000000 +0200 -@@ -10,11 +10,17 @@ - #ifndef __RECORDER_H - #define __RECORDER_H - -+#ifdef USE_LIVEBUFFER -+#include "livebuffer.h" -+#endif /* LIVEBUFFER */ - #include "receiver.h" - #include "recording.h" - #include "remux.h" - #include "ringbuffer.h" - #include "thread.h" -+#ifdef USE_TTXTSUBS -+#include "vdrttxtsubshooks.h" -+#endif /* TTXTSUBS */ - - class cFileWriter; - -@@ -23,12 +29,30 @@ private: - cRingBufferLinear *ringBuffer; - cRemux *remux; - cFileWriter *writer; -+#ifdef USE_LIVEBUFFER -+ char *fileName; -+ cLiveBuffer *liveBuffer; -+#ifdef USE_TTXTSUBS -+ cTtxtSubsRecorderBase *ttxtSubsRecorder; -+#endif /* TTXTSUBS */ -+#endif /* LIVEBUFFER */ - protected: - virtual void Activate(bool On); - virtual void Receive(uchar *Data, int Length); - virtual void Action(void); - public: -+#if defined (USE_LIVEBUFFER) || defined (USE_TTXTSUBS) -+ cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids -+#ifdef USE_TTXTSUBS -+ ,cTtxtSubsRecorderBase *tsr -+#endif /* TTXTSUBS */ -+#ifdef USE_LIVEBUFFER -+ ,cLiveBuffer *LiveBuffer = NULL -+#endif /* LIVEBUFFER */ -+ ); -+#else - cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids); -+#endif /* LIVEBUFFER || TTXTSUBS */ - // Creates a new recorder for the channel with the given ChannelID and - // the given Priority that will record the given PIDs into the file FileName. - virtual ~cRecorder(); -diff -ruNp vdr-1.7.0/recording.c vdr-1.7.0-extensions/recording.c ---- vdr-1.7.0/recording.c 2008-02-24 11:28:53.000000000 +0100 -+++ vdr-1.7.0-extensions/recording.c 2009-04-09 20:48:48.000000000 +0200 -@@ -8,6 +8,9 @@ - */ - - #include "recording.h" -+#ifdef USE_WAREAGLEICON -+#include "iconpatch.h" -+#endif /* WAREAGLEICON */ - #include <ctype.h> - #include <dirent.h> - #include <errno.h> -@@ -23,6 +26,17 @@ - #include "skins.h" - #include "tools.h" - #include "videodir.h" -+#ifdef USE_STREAMDEVEXT -+#include "status.h" -+#endif /* STREAMDEVEXT */ -+ -+#if defined (USE_DVDCHAPJUMP) && defined (USE_DVDARCHIVE) -+#include <assert.h> -+/* libdvdread stuff */ -+#include <dvdread/dvd_reader.h> -+#include <dvdread/ifo_types.h> -+#include <dvdread/ifo_read.h> -+#endif /* DVDCHAPJUMP & DVDARCHIVE */ - - #define SUMMARYFALLBACK - -@@ -46,6 +60,12 @@ - #endif - #define INFOFILESUFFIX "/info.vdr" - #define MARKSFILESUFFIX "/marks.vdr" -+#ifdef USE_LIEMIEXT -+#define INDEXFILESUFFIX "/index.vdr" -+#endif /* LIEMIEXT */ -+#ifdef USE_DVDARCHIVE -+#define DVDARCHIVEFILENAME "/dvd.vdr" -+#endif /* DVDARCHIVE */ - - #define MINDISKSPACE 1024 // MB - -@@ -62,6 +82,13 @@ - #define MAX_LINK_LEVEL 6 - - bool VfatFileSystem = false; -+#ifdef USE_LIEMIEXT -+bool DirOrderState = false; -+#endif /* LIEMIEXT */ -+ -+#ifdef USE_DVLFRIENDLYFNAMES -+char *MakeFriendlyFilename(char **buf); -+#endif /* DVLFRIENDLYFNAMES */ - - cRecordings DeletedRecordings(true); - -@@ -491,9 +518,24 @@ cRecording::cRecording(cTimer *Timer, co - { - resume = RESUME_NOT_INITIALIZED; - titleBuffer = NULL; -+#ifdef USE_SORTRECORDS -+ for (int i = 0; i < MAXSORTMODES; i++) { -+ sortBuffer[i] = NULL; -+ lastDirsFirst[i] = -1; -+ } -+#else - sortBuffer = NULL; -+#endif /* SORTRECORDS */ - fileName = NULL; - name = NULL; -+#ifdef USE_DVDARCHIVE -+ dvdname = NULL; -+ dvdtrack = NULL; -+ dvdchapters = NULL; -+ isArchived = false; -+ isOnlyOnDvd = false; -+ dvdtype = DVD_TYPE_UNKNOWN; -+#endif /* DVDARCHIVE */ - fileSizeMB = -1; // unknown - deleted = 0; - // set up the actual name: -@@ -524,6 +566,11 @@ cRecording::cRecording(cTimer *Timer, co - break; - } - if (Timer->IsSingleEvent()) { -+#ifdef USE_DVLFRIENDLYFNAMES -+ if (Setup.UseFriendlyFNames == 1) -+ Timer -> SetFile(MakeFriendlyFilename(&name)); -+ else -+#endif /* DVLFRIENDLYFNAMES */ - Timer->SetFile(name); // this was an instant recording, so let's set the actual data - Timers.SetModified(); - } -@@ -534,6 +581,10 @@ cRecording::cRecording(cTimer *Timer, co - name = strdup(cString::sprintf("%s~%s", Timer->File(), Subtitle)); - // substitute characters that would cause problems in file names: - strreplace(name, '\n', ' '); -+#ifdef USE_DVLFRIENDLYFNAMES -+ if (Setup.UseFriendlyFNames == 1) -+ MakeFriendlyFilename(&name); -+#endif /* DVLFRIENDLYFNAMES */ - start = Timer->StartTime(); - priority = Timer->Priority(); - lifetime = Timer->Lifetime(); -@@ -548,12 +599,27 @@ cRecording::cRecording(const char *FileN - fileSizeMB = -1; // unknown - deleted = 0; - titleBuffer = NULL; -+#ifdef USE_SORTRECORDS -+ for (int i = 0; i < MAXSORTMODES; i++) { -+ sortBuffer[i] = NULL; -+ lastDirsFirst[i] = -1; -+ } -+#else - sortBuffer = NULL; -+#endif /* SORTRECORDS */ - fileName = strdup(FileName); - FileName += strlen(VideoDirectory) + 1; - char *p = strrchr(FileName, '/'); - - name = NULL; -+#ifdef USE_DVDARCHIVE -+ dvdname = NULL; -+ dvdtrack = NULL; -+ dvdchapters = NULL; -+ isArchived = false; -+ isOnlyOnDvd = false; -+ dvdtype = DVD_TYPE_NOT_READ; -+#endif /* DVDARCHIVE */ - info = new cRecordingInfo; - if (p) { - time_t now = time(NULL); -@@ -633,15 +699,34 @@ cRecording::cRecording(const char *FileN - LOG_ERROR_STR(*SummaryFileName); - } - #endif -+#ifdef USE_DVDARCHIVE -+ if (CheckFileExistence("dvd.vdr")) { -+ GetDvdName(fileName); -+ isArchived = true; -+ if (!CheckFileExistence("001.vdr")) -+ isOnlyOnDvd = true; -+ } -+#endif /* DVDARCHIVE */ - } - } - - cRecording::~cRecording() - { - free(titleBuffer); -+#ifdef USE_SORTRECORDS -+ for (int i = 0; i < MAXSORTMODES; i++) { -+ free(sortBuffer[i]); -+ } -+#else - free(sortBuffer); -+#endif /* SORTRECORDS */ - free(fileName); - free(name); -+#ifdef USE_DVDARCHIVE -+ free(dvdname); -+ free(dvdtrack); -+ free(dvdchapters); -+#endif /* DVDARCHIVE */ - delete info; - } - -@@ -661,21 +746,46 @@ char *cRecording::StripEpisodeName(char - t++; - } - if (s1 && s2) -+#ifdef USE_SORTRECORDS -+ if (Setup.RecordingsSortDirsFirst) -+ *s1 = 'b'; -+ -+ if ((Setup.RecordingsSortMode <= 1 && s1 != s && !strchr(".-$ª·", *(s1 - 1))) || -+ (Setup.RecordingsSortMode == 1 && s1 == s) || -+ (Setup.RecordingsSortMode == 3)) -+#endif /* SORTRECORDS */ - memmove(s1 + 1, s2, t - s2 + 1); - return s; - } - - char *cRecording::SortName(void) const - { -+#ifdef USE_SORTRECORDS -+ if (!sortBuffer[Setup.RecordingsSortMode] || -+ lastDirsFirst[Setup.RecordingsSortMode] != Setup.RecordingsSortDirsFirst) { -+ free(sortBuffer[Setup.RecordingsSortMode]); -+ lastDirsFirst[Setup.RecordingsSortMode] = Setup.RecordingsSortDirsFirst; -+ char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory))); -+#else - if (!sortBuffer) { - char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory) + 1)); -+#endif /* SORTRECORDS */ - strreplace(s, '/', 'a'); // some locales ignore '/' when sorting - int l = strxfrm(NULL, s, 0) + 1; -+#ifdef USE_SORTRECORDS -+ sortBuffer[Setup.RecordingsSortMode] = MALLOC(char, l); -+ strxfrm(sortBuffer[Setup.RecordingsSortMode], s, l); -+#else - sortBuffer = MALLOC(char, l); - strxfrm(sortBuffer, s, l); -+#endif /* SORTRECORDS */ - free(s); - } -+#ifdef USE_SORTRECORDS -+ return sortBuffer[Setup.RecordingsSortMode]; -+#else - return sortBuffer; -+#endif /* SORTRECORDS */ - } - - int cRecording::GetResume(void) const -@@ -690,7 +800,15 @@ int cRecording::GetResume(void) const - int cRecording::Compare(const cListObject &ListObject) const - { - cRecording *r = (cRecording *)&ListObject; -+#ifdef USE_SORTRECORDS -+ return Recordings.GetSortOrder() * strcasecmp(SortName(), r->SortName()); -+#else -+#ifdef USE_LIEMIEXT -+ if (DirOrderState) -+ return strcasecmp(FileName(), r->FileName()); -+#endif /* LIEMIEXT */ - return strcasecmp(SortName(), r->SortName()); -+#endif /* USE_SORTRECORDS */ - } - - const char *cRecording::FileName(void) const -@@ -705,9 +823,359 @@ const char *cRecording::FileName(void) c - return fileName; - } - -+#ifdef USE_DVDARCHIVE -+bool cRecording::CheckFileExistence(const char* FileNameToTest, const bool useVideoDir) const -+{ -+ if (!useVideoDir || (useVideoDir && FileName())) { -+ cString filename = cString::sprintf("%s%s%s", useVideoDir ? FileName() : "", -+ useVideoDir ? "/" : "", -+ FileNameToTest); -+ struct stat statBuf; -+ if (lstat(filename, &statBuf) == -1) return false; -+ return S_ISREG(statBuf.st_mode) || S_ISLNK(statBuf.st_mode); -+ } -+ return false; -+} -+ -+bool cRecording::GetDvdName(const char* Directory) const -+{ -+ char* filename = (char*)alloca(strlen(Directory) + strlen(DVDARCHIVEFILENAME) + 1); -+ if (filename) { -+ strcpy(filename, Directory); -+ char *end = filename + strlen(filename); -+ strcpy(end, DVDARCHIVEFILENAME); -+ FILE* file; -+ if ((file = fopen(filename, "r"))) { -+ cReadLine ReadLine; -+ char* buffer = (char*)alloca(BUFSIZ); -+ if (buffer) { -+ buffer = ReadLine.Read(file); -+ if (buffer) -+ ((cRecording*)this)->dvdname = strdup(buffer); -+ else -+ ((cRecording*)this)->dvdname = NULL; -+ -+ buffer = ReadLine.Read(file); -+ if (buffer) { -+ ((cRecording*)this)->dvdtrack = strdup(buffer); -+ if (atoi(buffer) == 0) -+ ((cRecording*)this)->dvdtype = DVD_VIDEO_TYPE; -+ else -+ ((cRecording*)this)->dvdtype = DVD_VIDEO_ARCHIVE_TYPE; -+ } -+ else { -+ ((cRecording*)this)->dvdtrack = NULL; -+ ((cRecording*)this)->dvdtype = DVD_ARCHIVE_TYPE; -+ } -+ -+ fclose(file); -+ return true; -+ } -+ } -+ } -+ return false; -+} -+ -+bool cRecording::GetDvdChaptersFromDvd(int title) const -+{ -+#ifdef USE_DVDCHAPJUMP -+ cString buf; -+ -+ dvd_reader_t *dvd; -+ ifo_handle_t *ifo_file; -+ tt_srpt_t *tt_srpt; -+ ifo_handle_t *vts_file; -+ pgc_t *cur_pgc; -+ -+ dvd = DVDOpen(DVD_DEVICE); -+ if (!dvd) { -+ esyslog("DVD-ARCHIVE: Couldn't open DVD device %s!", DVD_DEVICE); -+ return false; -+ } -+ -+ /* open title manager */ -+ ifo_file = ifoOpen(dvd,0); -+ if (!ifo_file) { -+ esyslog("DVD-ARCHIVE: Can't open VMG info."); -+ DVDClose(dvd); -+ return false; -+ } -+ -+ /* read total_title */ -+ tt_srpt = ifo_file->tt_srpt; -+ -+ /* get total chapters */ -+ int title_set_nr = tt_srpt->title[title-1].title_set_nr; -+ int total_chap = tt_srpt->title[title-1].nr_of_ptts; -+ int local_title_id = tt_srpt->title[title-1].vts_ttn - 1; -+ -+ /* access title set file */ -+ vts_file = ifoOpen(dvd, title_set_nr); -+ if (!vts_file) { -+ esyslog("DVD-ARCHIVE: Can't open info file for title set %d!",title_set_nr); -+ DVDClose(dvd); -+ return false; -+ } -+ -+ /* find program chain and check programs -+ all chapters should be in the same prog chain and -+ should be numbered from 1 to <total_chap> -+ */ -+ { -+ vts_ptt_srpt_t *vts_ptt_srpt = vts_file->vts_ptt_srpt; -+ int pgc_nr = vts_ptt_srpt->title[local_title_id].ptt[0].pgcn; -+ int pg = vts_ptt_srpt->title[local_title_id].ptt[0].pgn; -+ int p; -+ -+ assert(pg==1); -+ for (p=1; p<total_chap; p++) { -+ int next_pg; -+ int this_pgc; -+ this_pgc = vts_ptt_srpt->title[local_title_id].ptt[p].pgcn; -+ assert(pgc_nr == this_pgc); -+ next_pg = vts_ptt_srpt->title[local_title_id].ptt[p].pgn; -+ assert(pg+1 == next_pg); -+ pg = next_pg; -+ } -+ -+ /* fetch program chain */ -+ cur_pgc = vts_file->vts_pgcit->pgci_srp[pgc_nr-1].pgc; -+ assert(cur_pgc->nr_of_programs == total_chap); -+ } -+ -+ /* --- main cell loop --- */ -+ { -+ pgc_program_map_t *chap_cell; -+ cell_playback_t *cell_pb; -+ int c; -+ int chap; -+ -+ /* total cells in chain */ -+ int total_cell = cur_pgc->nr_of_cells; -+ -+ /* get info */ -+ chap_cell = cur_pgc->program_map; -+ cell_pb = cur_pgc->cell_playback; -+ -+ /* loop through all cells */ -+ chap = -1; -+ int position = 0; -+ for (c=0; c<total_cell; c++) { -+ int cell_mode; -+ const char *mode; -+ -+ dvd_time_t *time = (dvd_time_t *)&cell_pb->playback_time; -+ -+ int framerate = time->frame_u>>6; -+ assert(framerate == 1 || framerate == 3); -+ int frames_per_sec = (framerate == 1) ? 25 : 30; -+ -+ /* upper 4 bits are first digit, down 4 bits are second digit */ -+ int hour = (time->hour>>4) * 10 + (time->hour&15); -+ int minute = (time->minute>>4) * 10 + (time->minute&15); -+ int second = (time->second>>4) * 10 + (time->second&15); -+ /* upper 4 bits are first digit, down 4 bits are second digit */ -+ int frame = (time->frame_u>>4&3) * 10 + (time->frame_u&15); -+ -+ int frames = ((hour * 3600) + (minute * 60) + second) * frames_per_sec + frame; -+ -+ /* this cell is the begin of a new chapter! */ -+ if (chap_cell[chap+1] == c+1) { -+ cString oldbuf = cString::sprintf("%s", *buf); -+ buf = cString::sprintf("%s%d%s", *oldbuf, position, ((chap+2) < total_chap) ? "," : ""); -+ chap++; -+ } -+ -+ /* cell_mode: 0=normal, 1=first of angle, 2=in angle, 3=last of angle */ -+ cell_mode = cell_pb->block_mode; -+ if ((cell_mode==0) || (cell_mode==1)) { -+ /* only account for normal or begin of angle cells */ -+ position += frames; -+ mode = "counted"; -+ } -+ else -+ mode = "skipped"; -+ -+ cell_pb++; -+ } -+ } -+ -+ ifoClose(ifo_file); -+ ifoClose(vts_file); -+ DVDClose(dvd); -+ -+ ((cRecording*)this)->dvdchapters = strdup(buf); -+ -+ return true; -+#else -+ return false; -+#endif /* DVDCHAPJUMP */ -+} -+ -+const char *cRecording::GetDvdChapters(void) const -+{ -+ // Read chapters from dvd -+ if (dvdtype == DVD_VIDEO_ARCHIVE_TYPE) { -+ if (dvdtrack) { -+ if (!GetDvdChaptersFromDvd(atoi(dvdtrack))) -+ ((cRecording*)this)->dvdchapters = NULL; -+ else -+ isyslog("DVD-ARCHIVE: Using following positions for chapter jumping: %s", dvdchapters); -+ return dvdchapters; -+ } -+ } -+ return NULL; -+} -+ -+int cRecording::MountDvd(void) const -+{ -+ cString cmd; -+ if (Setup.DvdSpeedLimit > 0) { -+ cmd = cString::sprintf("speedcontrol -x %d %s", Setup.DvdSpeedLimit, DVD_DEVICE); -+ SystemExec(cmd); -+ } -+ -+ cString msg; -+ if (atoi(dvdname) == 0) -+ msg = cString::sprintf(tr("Please mount %s"), dvdname); -+ else { -+ if (Setup.DvdDisplayZeros) -+ msg = cString::sprintf(tr("Please mount DVD %04d"), atoi(dvdname)); -+ else -+ msg = cString::sprintf(tr("Please mount DVD %d"), atoi(dvdname)); -+ } -+ -+ bool rep = true; -+ while (rep) { -+ if (Setup.DvdTrayMode==1 || Setup.DvdTrayMode==3) -+ cmd = cString::sprintf("umount %s; eject %s", DVD_DEVICE, DVD_DEVICE); -+ else -+ cmd = cString::sprintf("umount %s", DVD_DEVICE); -+ SystemExec(cmd); -+ -+ if (Interface->Confirm(msg, 300)) { -+ Skins.Message(mtStatus, tr("Please wait. Checking DVD...")); -+ Skins.Flush(); -+ cmd = cString::sprintf("eject -t %s; mkdir -p %s; mount -o ro -t %s %s %s", -+ DVD_DEVICE, DVD_MOUNT_PATH, -+ (dvdtrack ? "udf" : "iso9660"), -+ DVD_DEVICE, DVD_MOUNT_PATH); -+ SystemExec(cmd); -+ -+ bool correctDvd = true; -+ -+ char *olddvdname, *olddvdtrack; -+ int olddvdtype; -+ olddvdname = dvdname; -+ olddvdtrack = dvdtrack; -+ olddvdtype = dvdtype; -+ if (GetDvdName(DVD_MOUNT_PATH)) { -+ if (atoi(dvdname) != atoi(olddvdname)) correctDvd = false; -+ } -+ ((cRecording*)this)->dvdname = olddvdname; -+ ((cRecording*)this)->dvdtrack = olddvdtrack; -+ ((cRecording*)this)->dvdtype = olddvdtype; -+ -+ if (correctDvd) { -+ if (dvdtrack == NULL) { -+ // Archived DVD in VDR format -+ char fn[BUFSIZ]; -+ strcpy(fn, FileName()); -+ char *p = strrchr(fn, '/'); -+ cmd = cString::sprintf("find '%s' -name '%s'", DVD_MOUNT_PATH, p+1); -+ } -+ else { -+ // Either archived DVD in DVD-Video format or DVD-Video which -+ // should be played with the DVD plugin -+ cmd = cString::sprintf("find '%s' -iname 'VIDEO_TS'", DVD_MOUNT_PATH); -+ } -+ -+ cReadLine pipe; -+ FILE* file; -+ char *dirname = NULL; -+ if ((file = popen(cmd, "r")) != (FILE *)NULL) { -+ if ((dirname = pipe.Read(file)) != NULL) { -+ pclose(file); -+ if (dvdtrack != NULL && atoi(dvdtrack) == 0) { -+ // It is a valid Video-DVD and DVD plugin can be started -+ return MOUNT_DVD_LAUNCH_DVD_PLUGIN; -+ } -+ else { -+ // It is a valid Archive-DVD or an archived Video-DVD -+ // and the links can now be established -+ cString srcFn; -+ int n = 1; -+ -+ do { -+ if (dvdtrack == NULL) -+ srcFn = cString::sprintf("%s/%03d.vdr", dirname, n); -+ else -+ srcFn = cString::sprintf("%s/VTS_%02d_%d.VOB", dirname, atoi(dvdtrack), n); -+ -+ if (!access(srcFn, R_OK)) { -+ cmd = cString::sprintf("ln -sf '%s' '%s/%03d.vdr'", *srcFn, FileName(), n); -+ SystemExec(cmd); -+ isyslog("DVD-ARCHIVE: Linking %s/%03d.vdr -> %s", FileName(), n, *srcFn); -+ } -+ else -+ break; -+ } while ( ++n < 999); -+ -+ if (!CheckFileExistence("index.vdr")) { -+ if (dvdtrack == NULL) -+ srcFn = cString::sprintf("%s/index.vdr", dirname); -+ else -+ srcFn = cString::sprintf("%s/index_%02d.vdr", dirname, atoi(dvdtrack)); -+ -+ if (!CheckFileExistence(srcFn, false)) { -+ msg = cString::sprintf(tr("No index-file found. Creating may take minutes. Create one?")); -+ if (Interface->Confirm(msg, 300)) { -+ Skins.Message(mtStatus, tr("Please wait. Creating index-file...")); -+ cmd = cString::sprintf("speedcontrol -x 999 %s; cd %s && genindex &", DVD_DEVICE, FileName()); -+ SystemExec(cmd); -+ return MOUNT_DVD_ABORT; -+ } -+ } -+ else { -+ cmd = cString::sprintf("ln -sf '%s' '%s/index.vdr'", *srcFn, FileName()); -+ SystemExec(cmd); -+ isyslog("DVD-ARCHIVE: Linking %s/index.vdr -> %s", FileName(), *srcFn); -+ } -+ } -+ return MOUNT_DVD_REPLAY; -+ } -+ } -+ else { -+ Skins.Message(mtError, tr("Wrong DVD!"), 3); -+ Skins.Flush(); -+ } -+ } -+ pclose(file); -+ } -+ else { -+ Skins.Message(mtError, tr("Wrong DVD!"), 3); -+ Skins.Flush(); -+ } -+ } -+ else { -+ rep = false; -+ } -+ } -+ return MOUNT_DVD_ABORT; -+} -+ -+#endif /* DVDARCHIVE */ -+#ifdef USE_LIEMIEXT -+const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level, bool Original) const -+#else - const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) const -+#endif /* LIEMIEXT */ - { -+#ifdef USE_WAREAGLEICON -+ const char *New = NewIndicator && IsNew() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_NEW_UTF8 : ICON_NEW : "*" : " "; -+#else - char New = NewIndicator && IsNew() ? '*' : ' '; -+#endif /* WAREAGLEICON */ - free(titleBuffer); - titleBuffer = NULL; - if (Level < 0 || Level == HierarchyLevels()) { -@@ -718,7 +1186,14 @@ const char *cRecording::Title(char Delim - s++; - else - s = name; -+#ifdef USE_LIEMIEXT -+ if (Original) { -+#endif /* LIEMIEXT */ -+#ifdef USE_WAREAGLEICON -+ titleBuffer = strdup(cString::sprintf("%02d.%02d.%02d%c%02d:%02d%s%c%s", -+#else - titleBuffer = strdup(cString::sprintf("%02d.%02d.%02d%c%02d:%02d%c%c%s", -+#endif /* WAREAGLEICON */ - t->tm_mday, - t->tm_mon + 1, - t->tm_year % 100, -@@ -728,6 +1203,92 @@ const char *cRecording::Title(char Delim - New, - Delimiter, - s)); -+#ifdef USE_LIEMIEXT -+ } -+ else { -+ cString RecLength("---"); -+ if (Setup.ShowRecLength && FileName()) { -+ cString filename = cString::sprintf("%s%s", FileName(), INDEXFILESUFFIX); -+ if (*filename) { -+ if (access(filename, R_OK) == 0) { -+ struct stat buf; -+ if (stat(filename, &buf) == 0) { -+ struct tIndex { int offset; uchar type; uchar number; short reserved; }; -+ int delta = buf.st_size % sizeof(tIndex); -+ if (delta) { -+ delta = sizeof(tIndex) - delta; -+ esyslog("ERROR: invalid file size (%ld) in '%s'", buf.st_size, *filename); -+ } -+ RecLength = cString::sprintf("%ld'", (buf.st_size + delta) / sizeof(tIndex) / SecondsToFrames(60)); -+ } -+ } -+ } -+ } -+#endif /* LIEMIEXT */ -+#ifdef USE_DVDARCHIVE -+#ifdef USE_WAREAGLEICON -+ if (isArchived && !isOnlyOnDvd) New = Setup.WarEagleIcons ? IsLangUtf8() ? ICON_DVD_UTF8 : ICON_DVD : "~"; -+#else -+ if (isArchived && !isOnlyOnDvd) New = '~'; -+#endif /* WAREAGLEICON */ -+ -+ if (isOnlyOnDvd && Setup.DvdDisplayMode >= 1) { -+ char oldLength[21]; -+ -+ if (strrchr(RecLength, '\'')) -+ sprintf(oldLength,"%s", *RecLength); -+ else -+ oldLength[0] = 0; -+ -+ if (dvdname) { -+ if (atoi(dvdname) != 0) { -+ cString tmp; -+ if (Setup.DvdDisplayZeros) -+ tmp = cString::sprintf("%04d", atoi(dvdname)); -+ else { -+ int num = atoi(dvdname); -+ bool displaySpace = !(Setup.DvdDisplayMode == 1 && oldLength[0] != 0); -+ // ugly hack to have 2 spaces instead of one 0 for each place -+ tmp = cString::sprintf("%s%s%s%d", displaySpace && (num < 1000) ? " " : "", -+ displaySpace && (num < 100) ? " " : "", -+ displaySpace && (num < 10) ? " " : "", -+ num); -+ } -+ ((cRecording*)this)->dvdname = strdup(tmp); -+ } -+ } -+ -+ RecLength = strdup(cString::sprintf("%s%s%s%s", (Setup.ShowRecLength && (Setup.DvdDisplayMode == 1) && (oldLength[0] != 0)) ? oldLength : "", -+ (dvdname && isArchived && isOnlyOnDvd && Setup.ShowRecLength && (Setup.DvdDisplayMode == 1) && (oldLength[0] != 0)) ? " / " : "", -+ (dvdname && isArchived && isOnlyOnDvd) ? dvdname : "", -+ (dvdname && isArchived && isOnlyOnDvd) ? " " : "" -+ )); -+ } -+#endif /* DVDARCHIVE */ -+#ifdef USE_LIEMIEXT -+ cString RecDate = cString::sprintf("%02d.%02d.%02d", t->tm_mday, t->tm_mon + 1, t->tm_year % 100); -+ cString RecTime = cString::sprintf("%02d:%02d", t->tm_hour, t->tm_min); -+ cString RecDelimiter = cString::sprintf("%c", Delimiter); -+#ifdef USE_WAREAGLEICON -+ titleBuffer = strdup(cString::sprintf("%s%s%s%s%s%s%s%s", -+#else -+ titleBuffer = strdup(cString::sprintf("%s%s%s%c%s%s%s%s", -+#endif /* WAREAGLEICON */ -+ (Setup.ShowRecDate ? *RecDate : ""), -+ (Setup.ShowRecDate && Setup.ShowRecTime ? *RecDelimiter : ""), -+ (Setup.ShowRecTime ? *RecTime : ""), -+ New, -+ (Setup.ShowRecTime || Setup.ShowRecDate ? *RecDelimiter : ""), -+#ifdef USE_DVDARCHIVE -+ (((Setup.ShowRecLength + Setup.DvdDisplayMode) > 0) ? *RecLength : ""), -+ (((Setup.ShowRecLength + Setup.DvdDisplayMode) > 0) ? *RecDelimiter : ""), -+#else -+ (Setup.ShowRecLength ? *RecLength : ""), -+ (Setup.ShowRecLength ? *RecDelimiter : ""), -+#endif /* DVDARCHIVE */ -+ s)); -+ } -+#endif /* LIEMIEXT */ - // let's not display a trailing '~': - if (!NewIndicator) - stripspace(titleBuffer); -@@ -756,6 +1317,17 @@ const char *cRecording::Title(char Delim - return titleBuffer; - } - -+#ifdef USE_CUTTIME -+void cRecording::SetStartTime(time_t Start) -+{ -+ start=Start; -+ if (fileName) { -+ free(fileName); -+ fileName = NULL; -+ } -+} -+#endif /* CUTTIME */ -+ - const char *cRecording::PrefixFileName(char Prefix) - { - cString p = PrefixVideoFileName(FileName(), Prefix); -@@ -809,10 +1381,20 @@ bool cRecording::Delete(void) - // the new name already exists, so let's remove that one first: - isyslog("removing recording '%s'", NewName); - RemoveVideoFile(NewName); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgRecordingChange(this, scDel); -+#endif /* STREAMDEVEXT */ - } - isyslog("deleting recording '%s'", FileName()); -+#ifdef USE_STREAMDEVEXT -+ if (access(FileName(), F_OK) == 0) { -+ result = RenameVideoFile(FileName(), NewName); -+ cStatus::MsgRecordingChange(this, scDel); -+ } -+#else - if (access(FileName(), F_OK) == 0) - result = RenameVideoFile(FileName(), NewName); -+#endif /* STREAMDEVEXT */ - else { - isyslog("recording '%s' vanished", FileName()); - result = true; // well, we were going to delete it, anyway -@@ -830,7 +1412,13 @@ bool cRecording::Remove(void) - return false; - } - isyslog("removing recording %s", FileName()); -+#ifdef USE_STREAMDEVEXT -+ bool ret = RemoveVideoFile(FileName()); -+ cStatus::MsgRecordingChange(this, scDel); -+ return ret; -+#else - return RemoveVideoFile(FileName()); -+#endif /* STREAMDEVEXT */ - } - - bool cRecording::Undelete(void) -@@ -847,8 +1435,15 @@ bool cRecording::Undelete(void) - } - else { - isyslog("undeleting recording '%s'", FileName()); -+#ifdef USE_STREAMDEVEXT -+ if (access(FileName(), F_OK) == 0) { -+ result = RenameVideoFile(FileName(), NewName); -+ cStatus::MsgRecordingChange(this, scAdd); -+ } -+#else - if (access(FileName(), F_OK) == 0) - result = RenameVideoFile(FileName(), NewName); -+#endif /* STREAMDEVEXT */ - else { - isyslog("deleted recording '%s' vanished", FileName()); - result = false; -@@ -864,6 +1459,53 @@ void cRecording::ResetResume(void) const - resume = RESUME_NOT_INITIALIZED; - } - -+#ifdef USE_LIEMIEXT -+bool cRecording::Rename(const char *newName, int *newPriority, int *newLifetime) -+{ -+ bool result = false; -+ struct tm tm_r; -+ struct tm *t = localtime_r(&start, &tm_r); -+ char *localNewName = ExchangeChars(strdup(newName), true); -+ char *newFileName = strdup(cString::sprintf(NAMEFORMAT, VideoDirectory, localNewName, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, *newPriority, *newLifetime)); -+ free(localNewName); -+ if (strcmp(FileName(), newFileName)) { -+ if (access(newFileName, F_OK) == 0) { -+ isyslog("recording %s already exists", newFileName); -+ } -+ else { -+ isyslog("renaming recording %s to %s", FileName(), newFileName); -+ result = MakeDirs(newFileName, true); -+ if (result) -+ result = RenameVideoFile(FileName(), newFileName); -+ if (result) { -+ priority = *newPriority; -+ lifetime = *newLifetime; -+ free(fileName); -+ fileName = strdup(newFileName); -+ free(name); -+ name = strdup(newName); -+#ifdef USE_SORTRECORDS -+ for (int i = 0; i < MAXSORTMODES; i++) { -+ free(sortBuffer[i]); -+ sortBuffer[i] = NULL; -+ } -+#else -+ free(sortBuffer); -+ sortBuffer = NULL; -+#endif /* SORTRECORDS */ -+ free(titleBuffer); -+ titleBuffer = NULL; -+ } -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgRecordingChange(this, scMod); -+#endif /* STREAMDEVEXT */ -+ } -+ } -+ free(newFileName); -+ return result; -+} -+#endif /* LIEMIEXT */ -+ - // --- cRecordings ----------------------------------------------------------- - - cRecordings Recordings; -@@ -876,6 +1518,9 @@ cRecordings::cRecordings(bool Deleted) - deleted = Deleted; - lastUpdate = 0; - state = 0; -+#ifdef USE_SORTRECORDS -+ SortOrder = 1; -+#endif /* SORTRECORDS */ - } - - cRecordings::~cRecordings() -@@ -1154,14 +1799,70 @@ cMark *cMarks::GetNext(int Position) - return NULL; - } - -+#ifdef USE_JUMPPLAY -+// --- cMarksReload ---------------------------------------------------------- -+ -+#define MARKS_RELOAD_MS 10000 -+ -+time_t cMarksReload::lastsavetime = 0; -+ -+cMarksReload::cMarksReload(const char *RecordingFileName) -+:recDir(RecordingFileName) -+{ -+ struct stat sbuf; -+ if (Load(recDir) && stat(FileName(), &sbuf) == 0) -+ lastmodtime = sbuf.st_mtime; -+ else -+ lastmodtime = 0; -+ nextreload.Set(MARKS_RELOAD_MS - cTimeMs::Now() % MARKS_RELOAD_MS); -+} -+ -+bool cMarksReload::Reload(void) -+{ -+ // Check the timestamp of marks.vdr in 10 seconds intervals -+ // Independent but synchronized reloading of marks in two threads -+ if ((Setup.ReloadMarks && nextreload.TimedOut()) || lastsavetime > lastmodtime) { -+ nextreload.Set(MARKS_RELOAD_MS - cTimeMs::Now() % MARKS_RELOAD_MS); -+ struct stat sbuf; -+ if (stat(FileName(), &sbuf) == 0 && sbuf.st_mtime != lastmodtime) { -+ lastmodtime = sbuf.st_mtime; -+ if (Load(recDir)) -+ return true; -+ } -+ } -+ return false; -+} -+ -+bool cMarksReload::Save(void) -+{ -+ bool ok = cMarks::Save(); -+ struct stat sbuf; -+ if (ok && stat(FileName(), &sbuf) == 0) -+ lastsavetime = lastmodtime = sbuf.st_mtime; -+ return ok; -+} -+#endif /* JUMPPLAY */ -+ - // --- cRecordingUserCommand ------------------------------------------------- - - const char *cRecordingUserCommand::command = NULL; - -+#ifdef USE_DVLRECSCRIPTADDON -+void cRecordingUserCommand::InvokeCommand(const char *State, const char *RecordingFileName, char *chanName) -+#else - void cRecordingUserCommand::InvokeCommand(const char *State, const char *RecordingFileName) -+#endif /* DVLRECSCRIPTADDON */ - { - if (command) { -+#ifdef USE_DVLRECSCRIPTADDON -+ cString cmd; -+ if (chanName != NULL) -+ cmd = cString::sprintf("%s %s \"%s\" \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$"), chanName); -+ else -+ cmd = cString::sprintf("%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$")); -+#else - cString cmd = cString::sprintf("%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$")); -+#endif /* DVLRECSCRIPTADDON */ - isyslog("executing '%s'", *cmd); - SystemExec(cmd); - } -@@ -1172,7 +1873,9 @@ void cRecordingUserCommand::InvokeComman - //XXX+ somewhere else??? - // --- cIndexFile ------------------------------------------------------------ - -+#ifndef USE_LIEMIEXT - #define INDEXFILESUFFIX "/index.vdr" -+#endif /* LIEMIEXT */ - - // The number of frames to stay off the end in case of time shift: - #define INDEXSAFETYLIMIT 150 // frames -@@ -1431,6 +2134,48 @@ cFileName::cFileName(const char *FileNam - cFileName::~cFileName() - { - Close(); -+#ifdef USE_DVDARCHIVE -+ -+ char fn[BUFSIZ]; -+ strcpy(fn, fileName); -+ -+ char *p; -+ if((p = strrchr(fn, '/'))) { -+ p[0] = 0; -+ } -+ -+ cString cmd = cString::sprintf("find \"%s\" -type l -lname \"%s/*\"", fn, DVD_MOUNT_PATH); -+ -+ bool isOnDvd = false; -+ -+ cReadLine pipe; -+ FILE* file; -+ char* filename; -+ if ((file = popen(cmd, "r")) != (FILE *)NULL) { -+ while ((filename = pipe.Read(file)) != NULL) { -+ isOnDvd = true; -+ unlink(filename); -+ isyslog("DVD-ARCHIVE: Deleting %s", filename); -+ } -+ pclose(file); -+ } -+ -+ if (isOnDvd) { -+ if (Setup.DvdTrayMode==2 || Setup.DvdTrayMode==3) -+ cmd = cString::sprintf("umount %s; eject %s", DVD_DEVICE, DVD_DEVICE); -+ else -+ cmd = cString::sprintf("umount %s", DVD_DEVICE); -+ -+ SystemExec(cmd); -+ -+ if (Setup.DvdSpeedLimit > 0) { -+ cmd = cString::sprintf("speedcontrol -x 999 %s", DVD_DEVICE); -+ SystemExec(cmd); -+ } -+ } -+ -+#endif /* DVDARCHIVE */ -+ - free(fileName); - } - -@@ -1508,6 +2253,18 @@ cUnbufferedFile *cFileName::SetOffset(in - return NULL; - } - -+#ifdef USE_HARDLINKCUTTER -+int cFileName::MaxFileSize() { -+ const int smallFiles = (255 * MAXVIDEOFILESIZE - 1024 * Setup.MaxRecordingSize) -+ / max(MAXVIDEOFILESIZE - Setup.MaxVideoFileSize, 1); -+ -+ if (fileNumber <= smallFiles) -+ return MEGABYTE(Setup.MaxVideoFileSize); -+ -+ return MEGABYTE(MAXVIDEOFILESIZE); -+} -+#endif /* HARDLINKCUTTER */ -+ - cUnbufferedFile *cFileName::NextFile(void) - { - return SetOffset(fileNumber + 1); -@@ -1555,3 +2312,113 @@ int ReadFrame(cUnbufferedFile *f, uchar - LOG_ERROR; - return r; - } -+ -+#ifdef USE_DVLFRIENDLYFNAMES -+char *MakeFriendlyFilename(char **buf) -+{ -+ char *b, *x, *y; -+ -+ if (buf == NULL || *buf == NULL) -+ return(NULL); -+ -+ b = (char *)malloc(strlen(*buf) * 2); -+ x = *buf; -+ y = b; -+ -+ while (*x != 0) { -+ switch (*x) { -+ case 'Ä': -+ *y = 'A'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'ä': -+ *y = 'a'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'Ö': -+ *y = 'O'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'ö': -+ *y = 'o'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'Ü': -+ *y = 'U'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'ü': -+ *y = 'u'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'ß': -+ *y = 's'; -+ y++; -+ *y = 's'; -+ y++; x++; -+ break; -+ -+ // chars to replace -+ case ':': -+ case ';': -+ case '?': -+ case ' ': -+ case '\t': -+ *y = '_'; -+ y++; x++; -+ break; -+ -+ // chars to simply strip -+ case '\"': -+ case '*': -+ case '{': -+ case '}': -+ case '[': -+ case ']': -+ case '=': -+ case '<': -+ case '>': -+ case '#': -+ case '`': -+ case '|': -+ case '\\': -+ case '\n': -+ case '\r': -+ x++; -+ break; -+ -+ default: -+ *y = *x; -+ y++; x++; -+ break; -+ } -+ } -+ *y = 0; -+ -+ x = strdup(b); -+ free(b); -+ -+ free(*buf); -+ *buf = x; -+ -+ return(*buf); -+} -+#endif /* DVLFRIENDLYFNAMES */ -diff -ruNp vdr-1.7.0/recording.h vdr-1.7.0-extensions/recording.h ---- vdr-1.7.0/recording.h 2007-10-14 12:11:34.000000000 +0200 -+++ vdr-1.7.0-extensions/recording.h 2009-04-09 20:48:48.000000000 +0200 -@@ -19,6 +19,9 @@ - #include "tools.h" - - extern bool VfatFileSystem; -+#ifdef USE_LIEMIEXT -+extern bool DirOrderState; -+#endif /* LIEMIEXT */ - - void RemoveDeletedRecordings(void); - void AssertFreeDiskSpace(int Priority = 0, bool Force = false); -@@ -52,9 +55,15 @@ private: - public: - ~cRecordingInfo(); - tChannelID ChannelID(void) const { return channelID; } -+#ifdef USE_STREAMDEVEXT -+ const cEvent *GetEvent(void) const { return event; } -+#endif /* STREAMDEVEXT */ - const char *ChannelName(void) const { return channelName; } - const char *Title(void) const { return event->Title(); } - const char *ShortText(void) const { return event->ShortText(); } -+#ifdef USE_GRAPHTFT -+ tEventID EventID(void) const { return event->EventID(); } -+#endif /* GRAPHTFT */ - const char *Description(void) const { return event->Description(); } - const cComponents *Components(void) const { return event->Components(); } - const char *Aux(void) const { return aux; } -@@ -62,16 +71,50 @@ public: - bool Write(FILE *f, const char *Prefix = "") const; - }; - -+#ifdef USE_SORTRECORDS -+#define SORTRECORDINGSVERSNUM 3 -+#define MAXSORTMODES 4 -+#endif /* SORTRECORDS */ -+ -+#ifdef USE_DVDARCHIVE -+#define MOUNT_DVD_ABORT 0 -+#define MOUNT_DVD_REPLAY 1 -+#define MOUNT_DVD_LAUNCH_DVD_PLUGIN 2 -+#define DVD_DEVICE "/dev/cdrom" -+#define DVD_MOUNT_PATH "/tmp/vdr.dvd" -+ -+#define DVD_TYPE_UNKNOWN -1 -+#define DVD_TYPE_NOT_READ 0 -+#define DVD_VIDEO_TYPE 1 -+#define DVD_ARCHIVE_TYPE 2 -+#define DVD_VIDEO_ARCHIVE_TYPE 3 -+#endif /* DVDARCHIVE */ -+ - class cRecording : public cListObject { - friend class cRecordings; - private: - mutable int resume; - mutable char *titleBuffer; -+ -+#ifdef USE_SORTRECORDS -+ mutable char *sortBuffer[MAXSORTMODES]; -+ mutable char lastDirsFirst[MAXSORTMODES]; -+#else - mutable char *sortBuffer; -+#endif /* SORTRECORDS */ - mutable char *fileName; - mutable char *name; - mutable int fileSizeMB; - cRecordingInfo *info; -+#ifdef USE_DVDARCHIVE -+ char *dvdname; -+ char *dvdtrack; -+ char *dvdchapters; -+ bool isArchived; -+ bool isOnlyOnDvd; -+ int dvdtype; -+ bool GetDvdChaptersFromDvd(int title) const; -+#endif /* DVDARCHIVE */ - cRecording(const cRecording&); // can't copy cRecording - cRecording &operator=(const cRecording &); // can't assign cRecording - static char *StripEpisodeName(char *s); -@@ -88,8 +131,23 @@ public: - virtual int Compare(const cListObject &ListObject) const; - const char *Name(void) const { return name; } - const char *FileName(void) const; -+#ifdef USE_DVDARCHIVE -+ bool CheckFileExistence(const char* FileNameToTest, const bool useVideoDir = true) const; -+ bool GetDvdName(const char* Directory) const; -+ bool IsOnlyOnDvd(void) const { return isOnlyOnDvd; } -+ int MountDvd(void) const; -+ int GetDvdType(void) const { return dvdtype; } -+ const char *GetDvdChapters(void) const ; -+#endif /* DVDARCHIVE */ -+#ifdef USE_LIEMIEXT -+ const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1, bool Original = true) const; -+#else - const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1) const; -+#endif /* LIEMIEXT */ - const cRecordingInfo *Info(void) const { return info; } -+#ifdef USE_CUTTIME -+ void SetStartTime(time_t Start); -+#endif /* CUTTIME */ - const char *PrefixFileName(char Prefix); - int HierarchyLevels(void) const; - void ResetResume(void) const; -@@ -106,6 +164,11 @@ public: - // Changes the file name so that it will be visible in the "Recordings" menu again and - // not processed by cRemoveDeletedRecordingsThread. - // Returns false in case of error -+#ifdef USE_LIEMIEXT -+ bool Rename(const char *newName, int *newPriority, int *newLifetime); -+ // Changes the file name -+ // Returns false in case of error -+#endif /* LIEMIEXT */ - }; - - class cRecordings : public cList<cRecording>, public cThread { -@@ -114,6 +177,9 @@ private: - bool deleted; - time_t lastUpdate; - int state; -+#ifdef USE_SORTRECORDS -+ int SortOrder; -+#endif /* SORTRECORDS */ - const char *UpdateFileName(void); - void Refresh(bool Foreground = false); - void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0); -@@ -144,6 +210,10 @@ public: - void AddByName(const char *FileName, bool TriggerUpdate = true); - void DelByName(const char *FileName); - int TotalFileSizeMB(void); ///< Only for deleted recordings! -+#ifdef USE_SORTRECORDS -+ void ToggleSortOrder(void) { SortOrder *= -1; } -+ const int GetSortOrder(void) { return SortOrder; } -+#endif /* SORTRECORDS */ - }; - - extern cRecordings Recordings; -@@ -170,6 +240,20 @@ public: - cMark *GetNext(int Position); - }; - -+#ifdef USE_JUMPPLAY -+class cMarksReload : public cMarks { -+private: -+ cString recDir; -+ cTimeMs nextreload; -+ time_t lastmodtime; -+ static time_t lastsavetime; -+public: -+ cMarksReload(const char *RecordingFileName); -+ bool Reload(void); -+ bool Save(void); -+ }; -+#endif /* JUMPPLAY */ -+ - #define RUC_BEFORERECORDING "before" - #define RUC_AFTERRECORDING "after" - #define RUC_EDITEDRECORDING "edited" -@@ -178,8 +262,15 @@ class cRecordingUserCommand { - private: - static const char *command; - public: -+#ifdef USE_DELTIMESHIFTREC -+ static const char *GetCommand(void) { return command; } -+#endif /* DELTIMESHIFTREC */ - static void SetCommand(const char *Command) { command = Command; } -+#ifdef USE_DVLRECSCRIPTADDON -+ static void InvokeCommand(const char *State, const char *RecordingFileName, char *chanName = NULL); -+#else - static void InvokeCommand(const char *State, const char *RecordingFileName); -+#endif /* DVLRECSCRIPTADDON */ - }; - - //XXX+ -@@ -195,7 +286,19 @@ public: - // may be slightly higher because we stop recording only before the next - // 'I' frame, to have a complete Group Of Pictures): - #define MAXVIDEOFILESIZE 2000 // MB -+#ifndef USE_HARDLINKCUTTER - #define MINVIDEOFILESIZE 100 // MB -+#else -+#define MINVIDEOFILESIZE 1 // MB -+ -+#define MINRECORDINGSIZE 25 // GB -+#define MAXRECORDINGSIZE 500 // GB -+#define DEFAULTRECORDINGSIZE 100 // GB -+// Dynamic recording size: -+// Keep recording file size at Setup.MaxVideoFileSize for as long as possible, -+// but switch to MAXVIDEOFILESIZE early enough, so that Setup.MaxRecordingSize -+// will be reached, before recording to file 255.vdr -+#endif /* HARDLINKCUTTER */ - - class cIndexFile { - private: -@@ -207,6 +310,9 @@ private: - cResumeFile resumeFile; - cMutex mutex; - bool CatchUp(int Index = -1); -+#ifdef USE_DVDARCHIVE -+ bool isOnDVD; -+#endif /* DVDARCHIVE */ - public: - cIndexFile(const char *FileName, bool Record); - ~cIndexFile(); -@@ -236,6 +342,10 @@ public: - cUnbufferedFile *Open(void); - void Close(void); - cUnbufferedFile *SetOffset(int Number, int Offset = 0); -+#ifdef USE_HARDLINKCUTTER -+ int MaxFileSize(); -+ // Dynamic file size for this file -+#endif /* HARDLINKCUTTER */ - cUnbufferedFile *NextFile(void); - }; - -diff -ruNp vdr-1.7.0/remux.c vdr-1.7.0-extensions/remux.c ---- vdr-1.7.0/remux.c 2007-11-25 14:56:03.000000000 +0100 -+++ vdr-1.7.0-extensions/remux.c 2009-04-09 20:48:48.000000000 +0200 -@@ -1829,8 +1829,15 @@ void cTS2PES::ts_to_pes(const uint8_t *B - if (Buf[1] & TS_ERROR) - tsErrors++; - -+#ifdef USE_DVBSETUP -+ if (!(Buf[3] & (ADAPT_FIELD | PAY_LOAD))) { -+ dsyslog("TS packet discarded due to invalid adaption_field_control"); -+ return; -+ } -+#else - if (!(Buf[3] & (ADAPT_FIELD | PAY_LOAD))) - return; // discard TS packet with adaption_field_control set to '00'. -+#endif /* DVBSETUP */ - - if ((Buf[3] & PAY_LOAD) && ((Buf[3] ^ ccCounter) & CONT_CNT_MASK)) { - // This should check duplicates and packets which do not increase the counter. -@@ -1842,6 +1849,9 @@ void cTS2PES::ts_to_pes(const uint8_t *B - // These are the errors I used to get with Nova-T when antenna - // was not positioned correcly (not transport errors). //tvr - //dsyslog("TS continuity error (%d)", ccCounter); -+#ifdef USE_DVBSETUP -+ dsyslog("TS continuity error (%d)", ccCounter); -+#endif /* DVBSETUP */ - } - ccCounter = Buf[3] & CONT_CNT_MASK; - } -@@ -1867,6 +1877,10 @@ void cTS2PES::ts_to_pes(const uint8_t *B - - if (Buf[3] & PAY_LOAD) - instant_repack(Buf + 4 + off, TS_SIZE - 4 - off); -+#ifdef USE_DVBSETUP -+ else if (off + 4 < 188) -+ dsyslog("adaption_field zu short or PAY_LOAD not set"); -+#endif /* DVBSETUP */ - } - - // --- cRingBufferLinearPes -------------------------------------------------- -@@ -1896,12 +1910,19 @@ int cRingBufferLinearPes::DataReady(cons - - #define RESULTBUFFERSIZE KILOBYTE(256) - -+#ifdef USE_SYNCEARLY -+cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure, bool SyncEarly) -+#else - cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure) -+#endif /* SYNCEARLY */ - { - exitOnFailure = ExitOnFailure; - noVideo = VPid == 0 || VPid == 1 || VPid == 0x1FFF; - numUPTerrors = 0; - synced = false; -+#ifdef USE_SYNCEARLY -+ syncEarly = SyncEarly; -+#endif /* SYNCEARLY */ - skipped = 0; - numTracks = 0; - resultSkipped = 0; -@@ -2105,12 +2126,26 @@ uchar *cRemux::Get(int &Count, uchar *Pi - } - } - else if (!synced) { -+#ifdef USE_SYNCEARLY -+ if (pt == I_FRAME || syncEarly) { -+#else - if (pt == I_FRAME) { -+#endif /* SYNCEARLY */ - if (PictureType) - *PictureType = pt; - resultSkipped = i; // will drop everything before this position -+#ifdef USE_SYNCEARLY -+ if (!syncEarly) -+#endif /* SYNCEARLY */ - SetBrokenLink(data + i, l); - synced = true; -+#ifdef USE_SYNCEARLY -+ if (syncEarly) { -+ if (pt == I_FRAME) // syncEarly: it's ok but there is no need to call SetBrokenLink() -+ SetBrokenLink(data + i, l); -+ else fprintf(stderr, "video: synced early\n"); -+ } -+#endif /* SYNCEARLY */ - } - } - else if (Count) -@@ -2123,12 +2158,21 @@ uchar *cRemux::Get(int &Count, uchar *Pi - l = GetPacketLength(data, resultCount, i); - if (l < 0) - return resultData; -+#ifdef USE_SYNCEARLY -+ if (noVideo || !synced && syncEarly) { -+ if (!synced) { -+ if (PictureType && noVideo) -+#else - if (noVideo) { - if (!synced) { - if (PictureType) -+#endif /* SYNCEARLY */ - *PictureType = I_FRAME; - resultSkipped = i; // will drop everything before this position - synced = true; -+#ifdef USE_SYNCEARLY -+ if (!noVideo && syncEarly) fprintf(stderr, "audio: synced early\n"); -+#endif /* SYNCEARLY */ - } - else if (Count) - return resultData; -diff -ruNp vdr-1.7.0/remux.h vdr-1.7.0-extensions/remux.h ---- vdr-1.7.0/remux.h 2007-09-02 12:19:06.000000000 +0200 -+++ vdr-1.7.0-extensions/remux.h 2009-04-09 20:48:48.000000000 +0200 -@@ -40,6 +40,9 @@ private: - bool noVideo; - int numUPTerrors; - bool synced; -+#ifdef USE_SYNCEARLY -+ bool syncEarly; -+#endif /* SYNCEARLY */ - int skipped; - cTS2PES *ts2pes[MAXTRACKS]; - int numTracks; -@@ -47,12 +50,18 @@ private: - int resultSkipped; - int GetPid(const uchar *Data); - public: -+#ifdef USE_SYNCEARLY -+ cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false, bool SyncEarly = false); -+#else - cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false); -+#endif /* SYNCEARLY */ - ///< Creates a new remuxer for the given PIDs. VPid is the video PID, while - ///< APids, DPids and SPids are pointers to zero terminated lists of audio, - ///< dolby and subtitle PIDs (the pointers may be NULL if there is no such - ///< PID). If ExitOnFailure is true, the remuxer will initiate an "emergency - ///< exit" in case of problems with the data stream. -+ ///< If USE_SYNCEARLY is activated: SyncEarly causes cRemux to sync as soon -+ ///< as a video or audio frame is seen. - ~cRemux(); - void SetTimeouts(int PutTimeout, int GetTimeout) { resultBuffer->SetTimeouts(PutTimeout, GetTimeout); } - ///< By default cRemux assumes that Put() and Get() are called from different -diff -ruNp vdr-1.7.0/skinclassic.c vdr-1.7.0-extensions/skinclassic.c ---- vdr-1.7.0/skinclassic.c 2008-02-23 11:31:58.000000000 +0100 -+++ vdr-1.7.0-extensions/skinclassic.c 2009-04-09 20:48:48.000000000 +0200 -@@ -314,8 +314,52 @@ void cSkinClassicDisplayMenu::SetItem(co - for (int i = 0; i < MaxTabs; i++) { - const char *s = GetTabbedText(Text, i); - if (s) { -+#ifdef USE_LIEMIEXT -+ bool isprogressbar = false; -+ int now = 0, total = 0; -+ // check if progress bar: "[||||||| ]" -+ if ((strlen(s) > 5 && s[0] == '[' && s[strlen(s) - 1] == ']')) { -+ const char *p = s + 1; -+ // update status -+ isprogressbar = true; -+ for (; *p != ']'; ++p) { -+ // check if progressbar characters -+ if (*p == ' ' || *p == '|') { -+ // update counters -+ ++total; -+ if (*p == '|') -+ ++now; -+ } -+ else { -+ // wrong character detected; not a progressbar -+ isprogressbar = false; -+ break; -+ } -+ } -+ } -+ int xt = x0 + Tab(i); -+ if (Setup.ShowProgressBar && isprogressbar) { -+ // define x coordinates of progressbar -+ int px0 = xt; -+ int px1 = (Tab(i + 1)?Tab(i+1):x1) - 5; -+ int px = px0 + max((int)((float) now * (float) (px1 - px0) / (float) total), 1); -+ // define y coordinates of progressbar -+ int py0 = y + 4; -+ int py1 = y + lineHeight - 4; -+ // draw background -+ osd->DrawRectangle(px0, y, (Tab(i + 1)?Tab(i+1):x1) - 1, y + lineHeight - 1, ColorBg); -+ // draw progressbar -+ osd->DrawRectangle(px0, py0, px, py1, ColorFg); -+ osd->DrawRectangle(px + 1, py0, px1, py0 + 1, ColorFg); -+ osd->DrawRectangle(px + 1, py1 - 1, px1, py1, ColorFg); -+ osd->DrawRectangle(px1 - 1, py0, px1, py1, ColorFg); -+ } -+ else -+ osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x2 - xt); -+#else - int xt = x0 + Tab(i); - osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x2 - xt); -+#endif /* LIEMIEXT */ - } - if (!Tab(i + 1)) - break; -diff -ruNp vdr-1.7.0/skinsttng.c vdr-1.7.0-extensions/skinsttng.c ---- vdr-1.7.0/skinsttng.c 2008-02-23 11:23:44.000000000 +0100 -+++ vdr-1.7.0-extensions/skinsttng.c 2009-04-09 20:48:48.000000000 +0200 -@@ -558,8 +558,52 @@ void cSkinSTTNGDisplayMenu::SetItem(cons - for (int i = 0; i < MaxTabs; i++) { - const char *s = GetTabbedText(Text, i); - if (s) { -+#ifdef USE_LIEMIEXT -+ bool isprogressbar = false; -+ int now = 0, total = 0; -+ // check if progress bar: "[||||||| ]" -+ if ((strlen(s) > 5 && s[0] == '[' && s[strlen(s) - 1] == ']')) { -+ const char *p = s + 1; -+ // update status -+ isprogressbar = true; -+ for (; *p != ']'; ++p) { -+ // check if progressbar characters -+ if (*p == ' ' || *p == '|') { -+ // update counters -+ ++total; -+ if (*p == '|') -+ ++now; -+ } -+ else { -+ // wrong character detected; not a progressbar -+ isprogressbar = false; -+ break; -+ } -+ } -+ } -+ int xt = x3 + 5 + Tab(i); -+ if (Setup.ShowProgressBar && isprogressbar) { -+ // define x coordinates of progressbar -+ int px0 = xt; -+ int px1 = x3 + (Tab(i + 1)?Tab(i + 1):x4-x3-5) - 1; -+ int px = px0 + max((int)((float) now * (float) (px1 - px0) / (float) total), 1); -+ // define y coordinates of progressbar -+ int py0 = y + 4; -+ int py1 = y + lineHeight - 4; -+ // draw background -+ osd->DrawRectangle(px0, y, (Tab(i + 1)?Tab(i + 1):x4-x3-5) - 1, y + lineHeight - 1, ColorBg); -+ // draw progressbar -+ osd->DrawRectangle(px0, py0, px, py1, ColorFg); -+ osd->DrawRectangle(px + 1, py0, px1, py0 + 1, ColorFg); -+ osd->DrawRectangle(px + 1, py1 - 1, px1, py1, ColorFg); -+ osd->DrawRectangle(px1 - 1, py0, px1, py1, ColorFg); -+ } -+ else -+ osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x4 - xt); -+#else - int xt = x3 + 5 + Tab(i); - osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x4 - xt); -+#endif /* LIEMIEXT */ - } - if (!Tab(i + 1)) - break; -@@ -602,6 +646,21 @@ void cSkinSTTNGDisplayMenu::SetEvent(con - y += ts.Height(); - } - y += font->Height(); -+#ifdef USE_PARENTALRATING -+ if (!isempty(Event->GetParentalRatingString())) { -+ const cFont *font = cFont::GetFont(fontSml); -+ ts.Set(osd, xl, y, x4 - xl, y4 - y, Event->GetParentalRatingString(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground)); -+ y += ts.Height(); -+ } -+ int i = 0; -+ while (Event->Contents(i++)) { -+ if (!isempty(Event->GetContentsString())) { -+ const cFont *font = cFont::GetFont(fontSml); -+ ts.Set(osd, xl, y, x4 - xl, y4 - y, Event->GetContentsString(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground)); -+ y += ts.Height(); -+ } -+ } -+#endif /* PARENTALRATING */ - if (!isempty(Event->Description())) { - int yt = y; - int yb = y4 - Roundness; -diff -ruNp vdr-1.7.0/sources.c vdr-1.7.0-extensions/sources.c ---- vdr-1.7.0/sources.c 2008-02-10 15:07:26.000000000 +0100 -+++ vdr-1.7.0-extensions/sources.c 2009-04-09 20:48:48.000000000 +0200 -@@ -37,6 +37,9 @@ cString cSource::ToString(int Code) - char buffer[16]; - char *q = buffer; - switch (Code & st_Mask) { -+#ifdef USE_PLUGINPARAM -+ case stPlug: *q++ = 'P'; break; -+#endif /* PLUGINPARAM */ - case stCable: *q++ = 'C'; break; - case stSat: *q++ = 'S'; - { -@@ -56,6 +59,9 @@ int cSource::FromString(const char *s) - { - int type = stNone; - switch (toupper(*s)) { -+#ifdef USE_PLUGINPARAM -+ case 'P': type = stPlug; break; -+#endif /* PLUGINPARAM */ - case 'C': type = stCable; break; - case 'S': type = stSat; break; - case 'T': type = stTerr; break; -@@ -68,7 +74,11 @@ int cSource::FromString(const char *s) - int pos = 0; - bool dot = false; - bool neg = false; -+#ifdef USE_SOURCECAPS -+ while (*++s && !isblank(*s)) { -+#else - while (*++s) { -+#endif /* SOURCECAPS */ - switch (toupper(*s)) { - case '0' ... '9': pos *= 10; - pos += *s - '0'; -diff -ruNp vdr-1.7.0/sources.conf vdr-1.7.0-extensions/sources.conf ---- vdr-1.7.0/sources.conf 2007-02-17 17:15:13.000000000 +0100 -+++ vdr-1.7.0-extensions/sources.conf 2009-04-09 20:48:48.000000000 +0200 -@@ -188,3 +188,7 @@ C Cable - # Terrestrial - - T Terrestrial -+ -+# Plugin PLUGINPARAM -+ -+#P Plugin -diff -ruNp vdr-1.7.0/sources.h vdr-1.7.0-extensions/sources.h ---- vdr-1.7.0/sources.h 2005-05-14 11:30:41.000000000 +0200 -+++ vdr-1.7.0-extensions/sources.h 2009-04-09 20:48:48.000000000 +0200 -@@ -16,10 +16,17 @@ class cSource : public cListObject { - public: - enum eSourceType { - stNone = 0x0000, -+#ifdef USE_PLUGINPARAM -+ stPlug = 0x2000, -+#endif /* PLUGINPARAM */ - stCable = 0x4000, - stSat = 0x8000, - stTerr = 0xC000, -+#ifdef USE_PLUGINPARAM -+ st_Mask = 0xE000, -+#else - st_Mask = 0xC000, -+#endif /* PLUGINPARAM */ - st_Neg = 0x0800, - st_Pos = 0x07FF, - }; -@@ -35,6 +42,9 @@ public: - static cString ToString(int Code); - static int FromString(const char *s); - static int FromData(eSourceType SourceType, int Position = 0, bool East = false); -+#ifdef USE_PLUGINPARAM -+ static bool IsPlug(int Code) { return (Code & st_Mask) == stPlug; } -+#endif /* PLUGINPARAM */ - static bool IsCable(int Code) { return (Code & st_Mask) == stCable; } - static bool IsSat(int Code) { return (Code & st_Mask) == stSat; } - static bool IsTerr(int Code) { return (Code & st_Mask) == stTerr; } -diff -ruNp vdr-1.7.0/status.c vdr-1.7.0-extensions/status.c ---- vdr-1.7.0/status.c 2008-02-16 15:46:31.000000000 +0100 -+++ vdr-1.7.0-extensions/status.c 2009-04-09 20:48:48.000000000 +0200 -@@ -29,6 +29,20 @@ void cStatus::MsgTimerChange(const cTime - sm->TimerChange(Timer, Change); - } - -+#ifdef USE_STREAMDEVEXT -+void cStatus::MsgRecordingChange(const cRecording *Recording, eStatusChange Change) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->RecordingChange(Recording, Change); -+} -+ -+void cStatus::MsgChannelChange(const cChannel *Channel, eStatusChange Change) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->ChannelChange(Channel, Change); -+} -+#endif /* STREAMDEVEXT */ -+ - void cStatus::MsgChannelSwitch(const cDevice *Device, int ChannelNumber) - { - for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -@@ -124,3 +138,88 @@ void cStatus::MsgOsdProgramme(time_t Pre - for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) - sm->OsdProgramme(PresentTime, PresentTitle, PresentSubtitle, FollowingTime, FollowingTitle, FollowingSubtitle); - } -+ -+#ifdef USE_PINPLUGIN -+bool cStatus::MsgChannelProtected(const cDevice* Device, const cChannel* Channel) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ if (sm->ChannelProtected(Device, Channel) == true) -+ return true; -+ return false; -+} -+ -+bool cStatus::MsgReplayProtected(const cRecording* Recording, const char* Name, const char* Base, bool isDirectory, int menuView) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ if (sm->ReplayProtected(Recording, Name, Base, isDirectory, menuView) == true) -+ return true; -+ return false; -+} -+ -+void cStatus::MsgRecordingFile(const char* FileName) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->RecordingFile(FileName); -+} -+ -+void cStatus::MsgTimerCreation(cTimer* Timer, const cEvent *Event) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->TimerCreation(Timer, Event); -+} -+ -+bool cStatus::MsgPluginProtected(cPlugin* Plugin, int menuView) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ if (sm->PluginProtected(Plugin, menuView) == true) -+ return true; -+ return false; -+} -+ -+void cStatus::MsgUserAction(const eKeys key, const cOsdObject* Interact) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->UserAction(key, Interact); -+} -+ -+bool cStatus::MsgMenuItemProtected(const char* Name, int menuView) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ if (sm->MenuItemProtected(Name, menuView) == true) -+ return true; -+ return false; -+} -+#endif /* PINPLUGIN */ -+ -+#ifdef USE_GRAPHTFT -+void cStatus::MsgOsdSetEvent(const cEvent* event) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdSetEvent(event); -+} -+ -+void cStatus::MsgOsdSetRecording(const cRecording* recording) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdSetRecording(recording); -+} -+ -+void cStatus::MsgOsdMenuDisplay(const char* kind) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdMenuDisplay(kind); -+} -+ -+void cStatus::MsgOsdMenuDestroy() -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdMenuDestroy(); -+} -+ -+void cStatus::MsgOsdEventItem(const cEvent* Event, const char *Text, int Index, int Count) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdEventItem(Event, Text, Index, Count); -+} -+#endif /* GRAPHTFT */ -+ -diff -ruNp vdr-1.7.0/status.h vdr-1.7.0-extensions/status.h ---- vdr-1.7.0/status.h 2008-02-16 16:00:33.000000000 +0100 -+++ vdr-1.7.0-extensions/status.h 2009-04-09 20:48:48.000000000 +0200 -@@ -14,8 +14,14 @@ - #include "device.h" - #include "player.h" - #include "tools.h" -+#ifdef USE_PINPLUGIN -+#include "plugin.h" -+#endif /* PINPLUGIN */ - - enum eTimerChange { tcMod, tcAdd, tcDel }; -+#ifdef USE_STREAMDEVEXT -+enum eStatusChange { scMod, scAdd, scDel }; -+#endif /* STREAMDEVEXT */ - - class cTimer; - -@@ -30,6 +36,16 @@ protected: - // been added or will be deleted, respectively. In case of tcMod, - // Timer is NULL; this indicates that some timer has been changed. - // Note that tcAdd and tcDel are always also followed by a tcMod. -+#ifdef USE_STREAMDEVEXT -+ virtual void RecordingChange(const cRecording *Recording, eStatusChange Change) {} -+ // Indicates a change in the recordings settings. -+ // If Change is scAdd or scDel, Recording points to the recording that has -+ // been added or will be deleted, respectively. In case of scMod, -+ // Timer is NULL; this indicates that some timer has been changed. -+ // Note that scAdd and scDel are always also followed by a scMod. -+ virtual void ChannelChange(const cChannel *Channel, eStatusChange Change) {} -+ // Indicates a change in the channel list. -+#endif /* STREAMDEVEXT */ - virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber) {} - // Indicates a channel switch on the given DVB device. - // If ChannelNumber is 0, this is before the channel is being switched, -@@ -80,11 +96,46 @@ protected: - // The OSD displays the single line Text with the current channel information. - virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle) {} - // The OSD displays the given programme information. -+#ifdef USE_PINPLUGIN -+ virtual bool ChannelProtected(const cDevice *Device, const cChannel* Channel) { return false; } -+ // Checks if a channel is protected. -+ virtual bool ReplayProtected(const cRecording* Recording, const char* Name, const char* Base, bool isDirectory, int menuView = false) { return false; } -+ // Checks if a recording is protected. -+ virtual void RecordingFile(const char* FileName) {} -+ // The given DVB device has started recording to FileName. FileName is the name of the -+ // recording directory -+ virtual void TimerCreation(cTimer* Timer, const cEvent *Event) {} -+ // The given timer is created -+ virtual bool PluginProtected(cPlugin* Plugin, int menuView = false) { return false; } -+ // Checks if a plugin is protected. -+ virtual void UserAction(const eKeys key, const cOsdObject* Interact) {} -+ // report user action -+ virtual bool MenuItemProtected(const char* Name, int menuView = false) { return false; } -+ // Checks if a menu entry is protected. -+#endif /* PINPLUGIN */ -+#ifdef USE_GRAPHTFT -+ virtual void OsdSetRecording(const cRecording* recording) {} -+ // The OSD displays the recording information. -+ virtual void OsdSetEvent(const cEvent* event) {} -+ // The OSD displays the event information. -+ virtual void OsdMenuDisplay(const char* kind) {} -+ // report menu creation -+ virtual void OsdMenuDestroy() {} -+ // report menu destruvtion -+ virtual void OsdEventItem(const cEvent* Event, const char *Text, int Index, int Count) {} -+ // The OSD displays the given single line Event as menu item at Index. -+ -+#endif /* GRAPHTFT */ -+ - public: - cStatus(void); - virtual ~cStatus(); - // These functions are called whenever the related status information changes: - static void MsgTimerChange(const cTimer *Timer, eTimerChange Change); -+#ifdef USE_STREAMDEVEXT -+ static void MsgRecordingChange(const cRecording *Recording, eStatusChange Change); -+ static void MsgChannelChange(const cChannel *Channel, eStatusChange Change); -+#endif /* STREAMDEVEXT */ - static void MsgChannelSwitch(const cDevice *Device, int ChannelNumber); - static void MsgRecording(const cDevice *Device, const char *Name, const char *FileName, bool On); - static void MsgReplaying(const cControl *Control, const char *Name, const char *FileName, bool On); -@@ -101,6 +152,22 @@ public: - static void MsgOsdTextItem(const char *Text, bool Scroll = false); - static void MsgOsdChannel(const char *Text); - static void MsgOsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle); -+#ifdef USE_PINPLUGIN -+ static bool MsgChannelProtected(const cDevice* Device, const cChannel* Channel); -+ static bool MsgReplayProtected(const cRecording* Recording, const char* Name, const char* Base, bool isDirectory, int menuView = false); -+ static void MsgRecordingFile(const char* FileName); -+ static void MsgTimerCreation(cTimer* Timer, const cEvent *Event); -+ static bool MsgPluginProtected(cPlugin* Plugin, int menuView = false); -+ static void MsgUserAction(const eKeys key, const cOsdObject* Interact); -+ static bool MsgMenuItemProtected(const char* Name, int menuView = false); -+#endif /* PINPLUGIN */ -+#ifdef USE_GRAPHTFT -+ static void MsgOsdSetEvent(const cEvent* event); -+ static void MsgOsdSetRecording(const cRecording* recording); -+ static void MsgOsdMenuDisplay(const char* kind); -+ static void MsgOsdMenuDestroy(); -+ static void MsgOsdEventItem(const cEvent* Event, const char *Text, int Index, int Count); -+#endif /* GRAPHTFT */ - }; - - #endif //__STATUS_H -diff -ruNp vdr-1.7.0/submenu.c vdr-1.7.0-extensions/submenu.c ---- vdr-1.7.0/submenu.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/submenu.c 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,952 @@ -+#ifdef USE_SETUP -+/**************************************************************************** -+ * DESCRIPTION: -+ * Submenu -+ * -+ * $Id: vdr-1.3.44-Setup-0.3.0.diff,v 1.1 2006/03/04 09:58:47 ralf Exp $ -+ * -+ * Contact: ranga@teddycats.de -+ * -+ * Copyright (C) 2004, 2005 by Ralf Dotzert -+ * -+ * modified for the VDR Extensions Patch by zulu @vdr-portal -+ ****************************************************************************/ -+ -+#ifndef SUBMENU_H -+#include "submenu.h" -+#include "plugin.h" -+ -+static const char* TAG_SYSTEM = "system"; -+static const char* TAG_PLUGIN = "plugin"; -+static const char* TAG_COMMAND = "command"; -+static const char* TAG_THREAD = "thread"; -+static const char* TAG_MENU = "menu"; -+static const char* TAG_UNDEFINED = "undefined"; -+static const char* TRUE_STR = "yes"; -+ -+ -+//################################################################################ -+//# SubMenuNode -+//################################################################################ -+ -+cSubMenuNode::cSubMenuNode(TiXmlElement * xml, int level, cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu) -+{ -+ init(); -+ _parentMenu = parentMenu; -+ _currentMenu = currentMenu; -+ _level = level; -+ -+ if (xml != NULL && xml->Type() == TiXmlNode::ELEMENT) { -+ const char *tag = xml->Value(); -+ -+ if (cSubMenuNode::IsType(tag) != cSubMenuNode::UNDEFINED) { -+ SetType(tag); -+ SetName(xml->Attribute("name")); -+ if ((_type == COMMAND) || (_type == THREAD)) { -+ SetCommand(xml->Attribute("execute")); -+ const char * confirmStr = xml->Attribute("confirm"); -+ if (confirmStr != NULL && strcmp(confirmStr, TRUE_STR) == 0) -+ _commandConfirm = true; -+ } -+ else if (_type == PLUGIN) { // Add Plugin Index -+ SetCustomTitle(xml->Attribute("title")); -+ SetPlugin(); -+ } -+ else if (_type == MENU && xml->NoChildren() == false) { -+ xml = xml->FirstChildElement(); -+ do { -+ cSubMenuNode *node = new cSubMenuNode(xml, level+1, &_subMenus, currentMenu); -+ _subMenus.Add(node); -+ } while ((xml=xml->NextSiblingElement()) != NULL); -+ } -+ } -+ } -+ else -+ throw "Invalid XML Node"; -+} -+ -+/** -+ * Construct new Node empty Node -+ * -+ * -+ */ -+cSubMenuNode::cSubMenuNode(cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu) -+{ -+ init(); -+ _parentMenu = parentMenu; -+ _currentMenu = currentMenu; -+ -+} -+ -+ -+/** -+ * -+ */ -+void cSubMenuNode::init() -+{ -+ _name = NULL; -+ _command = NULL; -+ _title = NULL; -+ _pluginMainMenuEntry = NULL; -+ _type = UNDEFINED; -+ _level = 0; -+ _parentMenu = NULL; -+ _currentMenu = NULL; -+ _pluginIndex = 0; -+ _commandConfirm = false; -+} -+ -+ -+cSubMenuNode::~ cSubMenuNode() -+{ -+ if (_name != NULL) -+ free((void*)_name); -+ if (_command != NULL) -+ free((void*)_command); -+ if (_title != NULL) -+ free((void*)_title); -+ if (_pluginMainMenuEntry != NULL) -+ free((void*)_pluginMainMenuEntry); -+} -+ -+/** -+ * -+ */ -+void cSubMenuNode::SetPlugin() -+{ -+ bool found = false; -+ for (int i = 0; ; i++) { -+ cPlugin *p = cPluginManager::GetPlugin(i); -+ if (p) { -+ if (strcmp(_name, p->Name()) == 0 && p->MainMenuEntry() != NULL) { -+ SetPluginMainMenuEntry(p->MainMenuEntry()); -+ _pluginIndex = i; -+ found = true; -+ break; -+ } -+ } -+ else -+ break; -+ } -+ -+ if (!found) -+ _type = UNDEFINED; -+} -+ -+ -+bool cSubMenuNode::SaveXml(TiXmlElement * root) -+{ -+ bool ok = true; -+ -+ if (root!=NULL) { -+ TiXmlElement *e = NULL; -+ switch(_type) { -+ case SYSTEM: -+ e = new TiXmlElement(TAG_SYSTEM); -+ e->SetAttribute("name", GetName()); -+ break; -+ case COMMAND: -+ e = new TiXmlElement(TAG_COMMAND); -+ e->SetAttribute("name", GetName()); -+ e->SetAttribute("execute", GetCommand()); -+ if (_commandConfirm) -+ e->SetAttribute("confirm", TRUE_STR); -+ break; -+ case THREAD: -+ e = new TiXmlElement(TAG_THREAD); -+ e->SetAttribute("name", GetName()); -+ e->SetAttribute("execute", GetCommand()); -+ if (_commandConfirm) -+ e->SetAttribute("confirm", TRUE_STR); -+ break; -+ case PLUGIN: -+ e = new TiXmlElement(TAG_PLUGIN); -+ e->SetAttribute("name", GetName()); -+ if (GetCustomTitle() != NULL && strcmp(GetCustomTitle(), "") != 0) -+ e->SetAttribute("title", GetCustomTitle()); -+ break; -+ case MENU: -+ e = new TiXmlElement(TAG_MENU); -+ e->SetAttribute("name", GetName()); -+ break; -+ case UNDEFINED: -+ default: -+ ok = false; -+ break; -+ } -+ if (ok) { -+ root->LinkEndChild(e); -+ if (HasSubMenus()) -+ for (cSubMenuNode *node = _subMenus.First(); node; node = _subMenus.Next(node)) -+ node->SaveXml(e); -+ } -+ } -+ -+ return(ok); -+} -+ -+ -+cSubMenuNode::Type cSubMenuNode::IsType(const char *name) -+{ -+ Type type = UNDEFINED; -+ -+ if (strcmp(name ,TAG_SYSTEM) == 0) -+ type = cSubMenuNode::SYSTEM; -+ else if (strcmp(name ,TAG_PLUGIN) == 0) -+ type = cSubMenuNode::PLUGIN; -+ else if (strcmp(name ,TAG_COMMAND) == 0) -+ type = cSubMenuNode::COMMAND; -+ else if (strcmp(name ,TAG_THREAD) == 0) -+ type = cSubMenuNode::THREAD; -+ else if (strcmp(name ,TAG_MENU) == 0) -+ type = cSubMenuNode::MENU; -+ -+ return(type); -+} -+ -+void cSubMenuNode::SetType(const char * name) -+{ -+ _type = IsType(name); -+} -+ -+void cSubMenuNode::SetType(enum Type type) -+{ -+ _type = type; -+} -+ -+ -+cSubMenuNode::Type cSubMenuNode::GetType() -+{ -+ return(_type); -+} -+ -+const char * cSubMenuNode::GetTypeAsString() -+{ -+ const char *str=NULL; -+ switch(_type) { -+ case SYSTEM: -+ str = TAG_SYSTEM; -+ break; -+ case COMMAND: -+ str = TAG_COMMAND; -+ break; -+ case THREAD: -+ str = TAG_THREAD; -+ break; -+ case PLUGIN: -+ str = TAG_PLUGIN; -+ break; -+ case MENU: -+ str = TAG_MENU; -+ break; -+ case UNDEFINED: -+ str = TAG_UNDEFINED; -+ default: -+ break; -+ } -+ -+ return(str); -+} -+ -+void cSubMenuNode::SetCommand(const char * command) -+{ -+ if (_command != NULL) -+ free((void*)_command); -+ -+ if (command != NULL) -+ _command = strdup(command); -+ else -+ _command = NULL; -+} -+ -+const char * cSubMenuNode::GetCommand() -+{ -+ return(_command); -+} -+ -+bool cSubMenuNode::CommandConfirm() -+{ -+ return(_commandConfirm); -+} -+ -+void cSubMenuNode::SetCommandConfirm(int val) -+{ -+ if (val == 1) -+ _commandConfirm = true; -+ else -+ _commandConfirm = false; -+} -+ -+void cSubMenuNode::SetCustomTitle(const char * title) -+{ -+ if (_title != NULL) -+ free((void*)_title); -+ -+ if (title != NULL) -+ _title = strdup(title); -+ else -+ _title = NULL; -+} -+ -+const char * cSubMenuNode::GetCustomTitle() -+{ -+ return(_title); -+} -+ -+void cSubMenuNode::SetName(const char * name) -+{ -+ if (_name) -+ free ((void*)_name); -+ -+ if (name != NULL) -+ _name = strdup(name); -+ else -+ _name = NULL; -+} -+ -+const char * cSubMenuNode::GetName() -+{ -+ return(_name); -+} -+ -+int cSubMenuNode::GetLevel() -+{ -+ return(_level); -+} -+ -+void cSubMenuNode::SetLevel(int level) -+{ -+ _level = level; -+ if (HasSubMenus()) { //Adjust Levels of Subnodes -+ for (cSubMenuNode *node = _subMenus.First(); node; node = _subMenus.Next(node)) -+ node->SetLevel(level+1); -+ } -+} -+ -+int cSubMenuNode::GetPluginIndex() -+{ -+ return(_pluginIndex); -+} -+ -+void cSubMenuNode::SetPluginIndex(int index) -+{ -+ _pluginIndex = index; -+} -+ -+void cSubMenuNode::SetPluginMainMenuEntry(const char * mainMenuEntry) -+{ -+ if (_pluginMainMenuEntry != NULL) -+ free((void*)_pluginMainMenuEntry); -+ -+ if (_title != NULL && strcmp(_title, "") != 0) -+ _pluginMainMenuEntry = strdup(_title); -+ else if (mainMenuEntry != NULL) -+ _pluginMainMenuEntry = strdup(mainMenuEntry); -+ else -+ _pluginMainMenuEntry = NULL; -+} -+ -+const char * cSubMenuNode::GetPluginMainMenuEntry() -+{ -+ return(_pluginMainMenuEntry); -+} -+ -+ -+ -+cSubMenuNodes * cSubMenuNode::GetParentMenu() -+{ -+ return(_parentMenu); -+} -+ -+void cSubMenuNode::SetParentMenu(cSubMenuNodes * parent) -+{ -+ _parentMenu = parent; -+} -+ -+cSubMenuNodes * cSubMenuNode::GetCurrentMenu() -+{ -+ return(_currentMenu); -+} -+ -+void cSubMenuNode::SetCurrentMenu(cSubMenuNodes * current) -+{ -+ _currentMenu = current; -+} -+ -+ -+cSubMenuNodes * cSubMenuNode::GetSubMenus() -+{ -+ return(&_subMenus); -+} -+ -+bool cSubMenuNode::HasSubMenus() -+{ -+ if (_subMenus.Count() > 0) -+ return(true); -+ else -+ return(false); -+} -+ -+ -+void cSubMenuNode::Print(int index) -+{ -+ for (int i = 0; i < index; i++) -+ printf(" "); -+ -+ printf("Name=%s Type=%s Level=%d", _name, GetTypeAsString(), _level); -+ if (_type == COMMAND || _type == THREAD) -+ printf(" Command=%s", _command); -+ else if (_type == PLUGIN && _title != NULL) -+ printf(" Title=%s", _title); -+ printf("\n"); -+ -+ for (cSubMenuNode *node = _subMenus.First(); node; node = _subMenus.Next(node)) -+ node->Print(index+4); -+} -+ -+ -+//################################################################################ -+//# -+//################################################################################ -+cSubMenu::cSubMenu() -+{ -+ _menuSuffix = NULL; -+ _fname = NULL; -+ _commandResult = NULL; -+ _currentMenuTree = &_menuTree; -+ _currentParentMenuTree = NULL; -+#ifdef USE_PINPLUGIN -+ _currentParentIndex = -1; -+#endif /* PINPLUGIN */ -+ _nodeArray = NULL; -+ _nrNodes = 0; -+} -+ -+ -+cSubMenu::~cSubMenu() -+{ -+ if (_menuSuffix) -+ free(_menuSuffix); -+ if (_fname) -+ free(_fname); -+ if (_commandResult) -+ free(_commandResult); -+ if (_nodeArray) -+ free(_nodeArray); -+ _nrNodes = 0; -+} -+ -+ -+bool cSubMenu::LoadXml(char *fname) -+{ -+ TiXmlDocument xmlDoc = TiXmlDocument(fname); -+ TiXmlElement *root = NULL; -+ cSubMenuNode *node = NULL; -+ -+ bool ok = true; -+ //Clear previously loaded Menu -+ if (_fname != NULL) -+ free(_fname); -+ _menuTree.Clear(); -+ _fname = strdup(fname); -+ -+ if ((ok = xmlDoc.LoadFile())) { -+ if ((root = xmlDoc.FirstChildElement("menus")) != NULL) { -+ char *tmp = NULL; -+ if ((tmp = (char*)root->Attribute("suffix")) == NULL) -+ asprintf(&_menuSuffix, " "); // set default menuSuffix // asprintf(&_menuSuffix, " ..."); -+ else -+ asprintf(&_menuSuffix, tmp); -+ -+ if ((root = root->FirstChildElement()) != NULL) { -+ do { -+ try { -+ node = new cSubMenuNode(root, 0, &_menuTree, NULL); -+ _menuTree.Add(node); -+ } -+ catch (char *message) { -+ esyslog("ERROR: while decoding XML Node"); -+ ok = false; -+ } -+ } while (ok == true && (root = root->NextSiblingElement()) != NULL); -+ addMissingPlugins(); -+ removeUndefinedNodes(); -+ } -+ } -+ else { -+ esyslog("ERROR: in %s, missing Tag <menus>\n", fname); -+ ok = false; -+ } -+ } -+ else { -+ esyslog("ERROR: in %s : %s Col=%d Row=%d\n", -+ fname, -+ xmlDoc.ErrorDesc(), -+ xmlDoc.ErrorCol(), -+ xmlDoc.ErrorRow()); -+ ok = false; -+ } -+ -+ return(ok); -+} -+ -+ -+bool cSubMenu::SaveXml() -+{ -+ return(SaveXml(_fname)); -+} -+ -+ -+bool cSubMenu::SaveXml(char *fname) -+{ -+ bool ok = true; -+ -+ if (_fname != NULL) { -+ TiXmlDocument xml = TiXmlDocument(fname); -+ TiXmlComment comment; -+ comment.SetValue("\n\ -+- VDR Menu-Configuration File\n\ -+-\n\ -+-\n\ -+- Example:\n\ -+-\n\ -+ <menus>\n\ -+ <system name=\"Schedule\" />\n\ -+ <system name=\"Channels\" />\n\ -+ <system name=\"Timers\" />\n\ -+ <system name=\"Recordings\" />\n\ -+ <menu name=\"System\">\n\ -+ <system name=\"Setup\" />\n\ -+ <system name=\"Commands\" />\n\ -+ <plugin name=\"setup\" title=\"My Setup\" />\n\ -+ <command name=\"myCommand1\" execute=\"/usr/bin/mycommand1\" />\n\ -+ <command name=\"myCommand2\" execute=\"/usr/bin/mycommand2\" confirm=\"yes\" />\n\ -+ <thread name=\"myCommand3\" execute=\"/usr/bin/mycommand3\" confirm=\"yes\" />\n\ -+ <plugin name=\"epgsearch\" title=\"myProgram\" />\n\ -+ <menu name=\"mySubSubMenu\">\n\ -+ ...\n\ -+ </menu>\n\ -+ </menu>\n\ -+ <menu name=\"Suche\">\n\ -+ <plugin name=\"epgsearch\" />\n\ -+ ...\n\ -+ </menu>\n\ -+ </menus>\n\ -+"); -+ -+ TiXmlElement root("menus"); -+ root.SetAttribute("suffix", _menuSuffix); -+ for (cSubMenuNode *node = _menuTree.First(); node; node = _menuTree.Next(node)) -+ node->SaveXml(&root); -+ -+ if (xml.InsertEndChild(comment) != NULL && xml.InsertEndChild(root) != NULL) -+ ok = xml.SaveFile(fname); -+ } -+ else -+ ok = false; -+ -+ return(ok); -+} -+ -+ -+ -+cSubMenuNodes * cSubMenu::GetMenuTree() -+{ -+ return(_currentMenuTree); -+} -+ -+ -+void cSubMenu::PrintMenuTree() -+{ -+ for (cSubMenuNode *node = _menuTree.First(); node; node = _menuTree.Next(node)) -+ node->Print(); -+} -+ -+ -+int cSubMenu::GetNrOfNodes() -+{ -+ if (_nrNodes == 0) { -+ if ((_nrNodes = countNodes(&_menuTree)) > 0) { -+ _nodeArray = (cSubMenuNode**) malloc(sizeof(cSubMenuNode*)*_nrNodes); -+ int index = 0; -+ tree2Array(&_menuTree, index); -+ } -+ } -+ -+ return(_nrNodes); -+} -+ -+ -+/** -+ * returns the specified node within the current menu -+ * @param index position in the current menu -+ * @return node or null if not found -+ */ -+cSubMenuNode * cSubMenu::GetNode(int index) -+{ -+ cSubMenuNode *node = NULL; -+ if (_currentMenuTree == NULL || (node=_currentMenuTree->Get(index)) == NULL) -+ esyslog("ERROR: illegal call of cSubMenu::GetNode(%d)", index); -+ -+ return(node); -+} -+ -+ -+/** -+ * Get the specified Node -+ * @param index specfies the absolut indes in the list of all nodes -+ * @return node or NULL if not found -+ */ -+cSubMenuNode * cSubMenu::GetAbsNode(int index) -+{ -+ cSubMenuNode *node = NULL; -+ GetNrOfNodes(); -+ if (_nrNodes > 0 && index >= 0 && index < _nrNodes) -+ node = _nodeArray[index]; -+ -+ return(node); -+} -+ -+ -+#ifdef USE_PINPLUGIN -+bool cSubMenu::Down(cSubMenuNode *node, int currentIndex) -+#else -+bool cSubMenu::Down(int index) -+#endif /* PINPLUGIN */ -+{ -+ bool ok = true; -+#ifdef USE_PINPLUGIN -+ if (_currentMenuTree != NULL && node && node->GetType() == cSubMenuNode::MENU) { -+#else -+ cSubMenuNode *node = NULL; -+ -+ if (_currentMenuTree != NULL && (node=_currentMenuTree->Get(index)) != NULL && node->GetType() == cSubMenuNode::MENU) { -+#endif /* PINPLUGIN */ -+ _currentParentMenuTree = _currentMenuTree; -+#ifdef USE_PINPLUGIN -+ _currentParentIndex = currentIndex; -+#endif /* PINPLUGIN */ -+ _currentMenuTree = node->GetSubMenus(); -+ } -+ else { -+ ok = false; -+#ifdef USE_PINPLUGIN -+ esyslog("ERROR: illegal call of cSubMenu::Down"); -+#else -+ esyslog("ERROR: illegal call of cSubMenu::Down(%d)", index); -+#endif /* PINPLUGIN */ -+ } -+ -+ return(ok); -+} -+ -+bool cSubMenu::Up(int *parentIndex) -+{ -+ bool ok = true; -+ -+ if (_currentMenuTree != NULL && parentIndex != NULL) { -+#ifndef USE_PINPLUGIN -+ cSubMenuNode *node = NULL; -+#endif /* PINPLUGIN */ -+ *parentIndex = 0; -+#ifdef USE_PINPLUGIN -+ if (_currentParentIndex >= 0) -+ *parentIndex = _currentParentIndex; -+#else -+ if (_currentParentMenuTree != NULL) -+ for (int i = 0; (node = _currentParentMenuTree->Get(i)) != NULL; i++) { -+ if (_currentMenuTree == node->GetSubMenus()) { -+ *parentIndex = i; -+ break; -+ } -+ } -+#endif /* PINPLUGIN */ -+ -+ _currentMenuTree = _currentParentMenuTree; -+ if (_currentMenuTree != NULL) -+ _currentParentMenuTree = _currentMenuTree->Get(0)->GetParentMenu(); -+ else -+ ok = false; -+ } -+ else { -+ ok = false; -+ esyslog("ERROR: illegal call of cSubMenu::Up()"); -+ } -+ -+ return(ok); -+} -+ -+const char * cSubMenu::ExecuteCommand(const char * cmd) -+{ -+ free(_commandResult); -+ _commandResult = NULL; -+ -+ dsyslog("executing command '%s'", cmd); -+ FILE *p = popen(cmd, "r"); -+ if (p) { -+ int l = 0; -+ int c; -+ while ((c = fgetc(p)) != EOF) { -+ if (l % 20 == 0) -+ _commandResult = (char *)realloc(_commandResult, l + 21); -+ _commandResult[l++] = c; -+ } -+ if (_commandResult) -+ _commandResult[l] = 0; -+ pclose(p); -+ } -+ else -+ esyslog("ERROR: can't open pipe for command '%s'", cmd); -+ -+ return _commandResult; -+} -+ -+/** -+ * Move Menu Entry to new Position -+ * @param index index of menu entry to move -+ * @param toIndex index of destination -+ * @param where After ore before the destination index -+ */ -+void cSubMenu::MoveMenu(int index, int toIndex, enum Where where) -+{ -+ if (index < 0 || index > _nrNodes || // invalid index is ignored -+ toIndex < 0 || toIndex > _nrNodes || index == toIndex) -+ return; -+ -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ cSubMenuNode *destNode = GetAbsNode(toIndex); -+ -+ if (where == cSubMenu::INTO && destNode->GetType() != cSubMenuNode::MENU) -+ return; -+ -+ if (where == cSubMenu::INTO) { -+ if (destNode->GetType() == cSubMenuNode::MENU) { -+ srcNode->GetCurrentMenu()->Del(srcNode, false); -+ srcNode->SetLevel(destNode->GetLevel()+1); -+ srcNode->SetParentMenu(destNode->GetCurrentMenu()); -+ srcNode->SetCurrentMenu(destNode->GetSubMenus()); -+ -+ destNode->GetSubMenus()->Add(srcNode); -+ reloadNodeArray(); -+ } -+ } -+ else { -+ srcNode->GetCurrentMenu()->Del(srcNode, false); -+ srcNode->SetLevel(destNode->GetLevel()); -+ srcNode->SetParentMenu(destNode->GetParentMenu()); -+ srcNode->SetCurrentMenu(destNode->GetCurrentMenu()); -+ -+ if (where == cSubMenu::BEHIND) { -+ destNode->GetCurrentMenu()->Add(srcNode, GetAbsNode(toIndex)); -+ reloadNodeArray(); -+ } -+ else { -+ destNode->GetCurrentMenu()->Ins(srcNode, GetAbsNode(toIndex)); -+ reloadNodeArray(); -+ } -+ } -+} -+ -+/** -+ * Create a new Menu Entry -+ * @param index index of destination -+ * @param menuTitle Titel of new Menu entry -+ */ -+void cSubMenu::CreateMenu(int index, const char * menuTitle) -+{ -+ if (index >= 0 && index < _nrNodes) { -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ if (srcNode != NULL) { -+ cSubMenuNode *newNode = new cSubMenuNode(srcNode->GetParentMenu(), srcNode->GetCurrentMenu()); -+ newNode->SetLevel(srcNode->GetLevel()); -+ newNode->SetName(menuTitle); -+ newNode->SetType(cSubMenuNode::MENU); -+ newNode->SetParentMenu(srcNode->GetParentMenu()); -+ newNode->SetCurrentMenu(srcNode->GetCurrentMenu()); -+ -+ srcNode->GetCurrentMenu()->Add(newNode, GetAbsNode(index)); -+ reloadNodeArray(); -+ } -+ } -+} -+ -+/** -+ * delete the specified entry, or subtree if the specified entry is a menu -+ * @param index destion index -+ */ -+void cSubMenu::DeleteMenu(int index) -+{ -+ if (index >= 0 && index < _nrNodes) { -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ srcNode->GetCurrentMenu()->Del(srcNode, true); -+ reloadNodeArray(); -+ } -+} -+ -+ -+// Private Methods -+ -+int cSubMenu::countNodes(cSubMenuNodes * tree) -+{ -+ int count = 0; -+ if (tree != NULL) { -+ for (cSubMenuNode *node = tree->First(); node; node = tree->Next(node)) { -+ count++; -+ if (node->HasSubMenus()) -+ count += countNodes(node->GetSubMenus()); -+ } -+ } -+ return(count); -+} -+ -+ -+void cSubMenu::tree2Array(cSubMenuNodes * tree, int &index) -+{ -+ if (tree != NULL) { -+ for (cSubMenuNode *node = tree->First(); node; node = tree->Next(node)) { -+ _nodeArray[index++]=node; -+ if (node->HasSubMenus()) -+ tree2Array(node->GetSubMenus(), index); -+ } -+ } -+ -+} -+ -+bool cSubMenu::IsPluginInMenu(const char * name) -+{ -+ bool found = false; -+ for (int i = 0; i < _nrNodes && found == false; i++) { -+ cSubMenuNode *node = GetAbsNode(i); -+ if (node != NULL && node->GetType() == cSubMenuNode::PLUGIN && strcmp(name, node->GetName()) == 0) -+ found = true; -+ } -+ return(found); -+} -+ -+/** -+ * Adds the given plugin to the Menu-Tree if not allready in List -+ * @param name specifies the name of the plugin -+ */ -+void cSubMenu::AddPlugin(const char * name) -+{ -+ if (! IsPluginInMenu(name)) { -+ cSubMenuNode *node = new cSubMenuNode(&_menuTree, NULL); -+ node->SetName(name); -+ node->SetType("plugin"); -+ node->SetPlugin(); -+ _menuTree.Add(node); -+ } -+} -+ -+void cSubMenu::addMissingPlugins() -+{ -+ _nrNodes = GetNrOfNodes(); -+ for (int i = 0; ; i++) { -+ cPlugin *p = cPluginManager::GetPlugin(i); -+ if (p) -+ AddPlugin(p->Name()); -+ else -+ break; -+ } -+ reloadNodeArray(); -+} -+ -+/** -+ * Adds the given command to the Menu-Tree -+ * @param name specifies the name of the command -+ */ -+void cSubMenu::CreateCommand(int index, const char * name, const char * execute, int confirm) -+{ -+ if (index >= 0 && index < _nrNodes) { -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ if (srcNode != NULL) { -+ cSubMenuNode *newNode = new cSubMenuNode(srcNode->GetParentMenu(), srcNode->GetCurrentMenu()); -+ newNode->SetLevel(srcNode->GetLevel()); -+ newNode->SetName(name); -+ newNode->SetType("command"); -+ newNode->SetCommand(execute); -+ newNode->SetCommandConfirm(confirm); -+ newNode->SetParentMenu(srcNode->GetParentMenu()); -+ newNode->SetCurrentMenu(srcNode->GetCurrentMenu()); -+ -+ srcNode->GetCurrentMenu()->Add(newNode, GetAbsNode(index)); -+ reloadNodeArray(); -+ } -+ } -+} -+ -+void cSubMenu::CreateThread(int index, const char * name, const char * execute, int confirm) -+{ -+ if (index >= 0 && index < _nrNodes) { -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ if (srcNode != NULL) { -+ cSubMenuNode *newNode = new cSubMenuNode(srcNode->GetParentMenu(), srcNode->GetCurrentMenu()); -+ newNode->SetLevel(srcNode->GetLevel()); -+ newNode->SetName(name); -+ newNode->SetType("thread"); -+ newNode->SetCommand(execute); -+ newNode->SetCommandConfirm(confirm); -+ newNode->SetParentMenu(srcNode->GetParentMenu()); -+ newNode->SetCurrentMenu(srcNode->GetCurrentMenu()); -+ -+ srcNode->GetCurrentMenu()->Add(newNode, GetAbsNode(index)); -+ reloadNodeArray(); -+ } -+ } -+} -+ -+/** -+ * reloads the internal Array of Nodes -+ */ -+void cSubMenu::reloadNodeArray() -+{ -+ if (_nrNodes > 0) -+ free(_nodeArray); -+ _nodeArray = NULL; -+ _nrNodes = 0; -+ _nrNodes = GetNrOfNodes(); -+} -+ -+/** -+ * remove Undefined Nodes -+ */ -+void cSubMenu::removeUndefinedNodes() -+{ -+ bool remove = false; -+ -+ reloadNodeArray(); -+ for (int i = 0; i < _nrNodes; i++) { -+ cSubMenuNode *node = GetAbsNode(i); -+ if (node != NULL && node->GetType() == cSubMenuNode::UNDEFINED) { -+ cSubMenuNodes *pMenu = node->GetCurrentMenu(); -+ pMenu->Del(node, true); -+ remove = true; -+ } -+ } -+ if (remove) -+ reloadNodeArray(); -+} -+ -+ -+/** -+* Retrieves the Menutitel of the parent Menu -+*/ -+const char *cSubMenu::GetParentMenuTitel() -+{ -+ const char * result = ""; -+ -+ if (_currentMenuTree != NULL && _currentParentMenuTree != NULL) { -+ cSubMenuNode *node = NULL; -+ for (int i = 0; (node = _currentParentMenuTree->Get(i)) != NULL; i++) { -+ if (_currentMenuTree == node->GetSubMenus()) { -+ result = node->GetName(); -+ break; -+ } -+ } -+ } -+ -+ return(result); -+} -+ -+#endif -+#endif /* SETUP */ -diff -ruNp vdr-1.7.0/submenu.h vdr-1.7.0-extensions/submenu.h ---- vdr-1.7.0/submenu.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/submenu.h 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,160 @@ -+#ifdef USE_SETUP -+/**************************************************************************** -+ * DESCRIPTION: -+ * Submenu -+ * -+ * $Id: vdr-1.3.44-Setup-0.3.0.diff,v 1.1 2006/03/04 09:58:47 ralf Exp $ -+ * -+ * Contact: ranga@teddycats.de -+ * -+ * Copyright (C) 2004, 2005 by Ralf Dotzert -+ * -+ * modified for the VDR Extensions Patch by zulu @vdr-portal -+ ****************************************************************************/ -+ -+#ifndef SUBMENU_H -+#define SUBMENU_H -+ -+#include "thread.h" -+#include "tools.h" -+#include "tinystr.h" -+ -+class cSubMenuNode; -+class cSubMenuNodes; -+class cSubMenu; -+ -+ -+class cSubMenuNodes : public cList<cSubMenuNode> {}; -+ -+// execute cmd thread -+class cExecCmdThread : public cThread { -+private: -+ char *ExecCmd; -+protected: -+ virtual void Action(void) { -+ if (system(ExecCmd) == 0) -+ esyslog("%s - finished", ExecCmd); -+ delete(this); -+ }; -+public: -+ cExecCmdThread(char *cmd) { -+ asprintf(&ExecCmd, "%s", cmd); -+ } -+ cExecCmdThread(const char *cmd) { -+ asprintf(&ExecCmd, "%s", cmd); -+ } -+ ~cExecCmdThread() { -+ free(ExecCmd); -+ }; -+ }; -+ -+//################################################################################ -+//# SubMenuNode -+//################################################################################ -+class cSubMenuNode : public cListObject { -+public: -+ enum Type { UNDEFINED, SYSTEM, COMMAND, THREAD, PLUGIN, MENU }; -+ cSubMenuNode(TiXmlElement * xml, int level, cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu); -+ cSubMenuNode(cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu); -+ ~cSubMenuNode(); -+ bool SaveXml(TiXmlElement * root); -+ static cSubMenuNode::Type IsType(const char *name); -+ void SetType(const char *name); -+ void SetType(enum Type type); -+ void SetPlugin(); -+ cSubMenuNode::Type GetType(); -+ const char *GetTypeAsString(); -+ void SetCommand(const char *command); -+ bool CommandConfirm(); -+ void SetCommandConfirm(int val); -+ const char *GetCommand(); -+ void SetCustomTitle(const char *title); -+ const char *GetCustomTitle(); -+ void SetName(const char *name); -+ const char*GetName(); -+ int GetLevel(); -+ void SetLevel(int level); -+ int GetPluginIndex(); -+ void SetPluginIndex(int index); -+ void SetPluginMainMenuEntry(const char *mainMenuEntry); -+ const char *GetPluginMainMenuEntry(); -+ cSubMenuNodes *GetParentMenu(); -+ void SetParentMenu(cSubMenuNodes *parent); -+ cSubMenuNodes *GetCurrentMenu(); -+ void SetCurrentMenu(cSubMenuNodes *current); -+ cSubMenuNodes *GetSubMenus(); -+ bool HasSubMenus(); -+ void Print(int index = 0); -+private: -+ Type _type; -+ int _level; -+ // Plugin Variables -+ int _pluginIndex; -+ const char *_pluginMainMenuEntry; -+ // common -+ const char *_name; -+ const char *_command; -+ bool _commandConfirm; -+ const char *_title; -+ cSubMenuNodes _subMenus; -+ cSubMenuNodes *_parentMenu; -+ cSubMenuNodes *_currentMenu; -+ void init(); -+ }; -+ -+ -+//################################################################################ -+//# SubMenu Class -+//################################################################################ -+class cSubMenu { -+public: -+ cSubMenu(); -+ ~cSubMenu(); -+ enum Where { BEFORE, BEHIND, INTO}; -+ bool LoadXml(char *fname); -+ bool SaveXml(char *fname); -+ bool SaveXml(); -+ cSubMenuNodes *GetMenuTree(); -+ bool Up(int *ParentIndex); -+#ifdef USE_PINPLUGIN -+ bool Down(cSubMenuNode* node, int currentIndex); -+#else -+ bool Down(int index); -+#endif /* PINPLUGIN */ -+ int GetNrOfNodes(); -+ cSubMenuNode* GetAbsNode(int index); -+ cSubMenuNode* GetNode(int index); -+ void PrintMenuTree(); -+ bool IsPluginInMenu(const char *name); -+ void AddPlugin(const char *name); -+ void CreateCommand(int index, const char *name, const char *execute, int confirm); -+ void CreateThread(int index, const char *name, const char *execute, int confirm); -+ const char *ExecuteCommand(const char *command); -+ void MoveMenu(int index, int toindex, enum Where); -+ void CreateMenu(int index, const char *menuTitle); -+ void DeleteMenu(int index); -+ char *GetMenuSuffix() { return _menuSuffix; } -+ void SetMenuSuffix(char *suffix) { if (_menuSuffix) free(_menuSuffix); asprintf(&_menuSuffix, suffix); } -+ bool isTopMenu() { return (_currentParentMenuTree == NULL); } -+ const char *GetParentMenuTitel(); -+private: -+ cSubMenuNodes _menuTree; -+ cSubMenuNodes *_currentMenuTree; -+ cSubMenuNodes *_currentParentMenuTree; -+#ifdef USE_PINPLUGIN -+ int _currentParentIndex; -+#endif /* PINPLUGIN */ -+ char *_fname; -+ char *_commandResult; -+ int _nrNodes; -+ cSubMenuNode **_nodeArray; -+ char *_menuSuffix; -+ int countNodes(cSubMenuNodes *tree); -+ void tree2Array(cSubMenuNodes *tree, int &index); -+ void addMissingPlugins(); -+ void reloadNodeArray(); -+ void removeUndefinedNodes(); -+ }; -+ -+#endif //__SUBMENU_H -+#endif /* SETUP */ -diff -ruNp vdr-1.7.0/svdrp.c vdr-1.7.0-extensions/svdrp.c ---- vdr-1.7.0/svdrp.c 2008-02-17 14:36:01.000000000 +0100 -+++ vdr-1.7.0-extensions/svdrp.c 2009-04-09 20:48:48.000000000 +0200 -@@ -39,6 +39,9 @@ - #include "timers.h" - #include "tools.h" - #include "videodir.h" -+#ifdef USE_STREAMDEVEXT -+#include "status.h" -+#endif /* STREAMDEVEXT */ - - // --- cSocket --------------------------------------------------------------- - -@@ -296,6 +299,10 @@ const char *HelpPages[] = { - "REMO [ on | off ]\n" - " Turns the remote control on or off. Without a parameter, the current\n" - " status of the remote control is reported.", -+#ifdef USE_LIEMIEXT -+ "RENR <number> <new name>\n" -+ " Rename recording. Number must be the Number as returned by LSTR command.", -+#endif /* LIEMIEXT */ - "SCAN\n" - " Forces an EPG scan. If this is a single DVB device system, the scan\n" - " will be done on the primary device unless it is currently recording.", -@@ -616,6 +623,9 @@ void cSVDRP::CmdDELC(const char *Option) - Channels.ReNumber(); - Channels.SetModified(true); - isyslog("channel %s deleted", Option); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(NULL, scDel); -+#endif /* STREAMDEVEXT */ - if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { - if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) - Channels.SwitchTo(CurrentChannel->Number()); -@@ -1135,6 +1145,9 @@ void cSVDRP::CmdMODC(const char *Option) - Channels.ReNumber(); - Channels.SetModified(true); - isyslog("modifed channel %d %s", channel->Number(), *channel->ToText()); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(channel, scMod); -+#endif /* STREAMDEVEXT */ - Reply(250, "%d %s", channel->Number(), *channel->ToText()); - } - else -@@ -1221,6 +1234,9 @@ void cSVDRP::CmdMOVC(const char *Option) - else - cDevice::SetCurrentChannel(CurrentChannel); - } -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(ToChannel, scMod); -+#endif /* STREAMDEVEXT */ - isyslog("channel %d moved to %d", FromNumber, ToNumber); - Reply(250,"Channel \"%d\" moved to \"%d\"", From, To); - } -@@ -1264,6 +1280,9 @@ void cSVDRP::CmdNEWC(const char *Option) - Channels.ReNumber(); - Channels.SetModified(true); - isyslog("new channel %d %s", channel->Number(), *channel->ToText()); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(channel, scAdd); -+#endif /* STREAMDEVEXT */ - Reply(250, "%d %s", channel->Number(), *channel->ToText()); - } - else -@@ -1472,6 +1491,40 @@ void cSVDRP::CmdSCAN(const char *Option) - Reply(250, "EPG scan triggered"); - } - -+#ifdef USE_LIEMIEXT -+void cSVDRP::CmdRENR(const char *Option) -+{ -+ bool recordings = Recordings.Update(true); -+ if (recordings) { -+ if (*Option) { -+ char *tail; -+ int n = strtol(Option, &tail, 10); -+ cRecording *recording = Recordings.Get(n - 1); -+ if (recording && tail && tail != Option) { -+ int priority = recording->priority; -+ int lifetime = recording->lifetime; -+ char *oldName = strdup(recording->Name()); -+ tail = skipspace(tail); -+ if (recording->Rename(tail, &priority, &lifetime)) { -+ Reply(250, "Renamed \"%s\" to \"%s\"", oldName, recording->Name()); -+ Recordings.ChangeState(); -+ Recordings.TouchUpdate(); -+ } -+ else -+ Reply(501, "Renaming \"%s\" to \"%s\" failed", oldName, tail); -+ free(oldName); -+ } -+ else -+ Reply(501, "Recording not found or wrong syntax"); -+ } -+ else -+ Reply(501, "Missing Input settings"); -+ } -+ else -+ Reply(550, "No recordings available"); -+} -+#endif /* LIEMIEXT */ -+ - void cSVDRP::CmdSTAT(const char *Option) - { - if (*Option) { -@@ -1587,6 +1640,9 @@ void cSVDRP::Execute(char *Cmd) - else if (CMD("PLUG")) CmdPLUG(s); - else if (CMD("PUTE")) CmdPUTE(s); - else if (CMD("REMO")) CmdREMO(s); -+#ifdef USE_LIEMIEXT -+ else if (CMD("RENR")) CmdRENR(s); -+#endif /* LIEMIEXT */ - else if (CMD("SCAN")) CmdSCAN(s); - else if (CMD("STAT")) CmdSTAT(s); - else if (CMD("UPDT")) CmdUPDT(s); -diff -ruNp vdr-1.7.0/svdrp.h vdr-1.7.0-extensions/svdrp.h ---- vdr-1.7.0/svdrp.h 2007-04-30 14:28:28.000000000 +0200 -+++ vdr-1.7.0-extensions/svdrp.h 2009-04-09 20:48:48.000000000 +0200 -@@ -79,6 +79,9 @@ private: - void CmdPLUG(const char *Option); - void CmdPUTE(const char *Option); - void CmdREMO(const char *Option); -+#ifdef USE_LIEMIEXT -+ void CmdRENR(const char *Option); -+#endif /* LIEMIEXT */ - void CmdSCAN(const char *Option); - void CmdSTAT(const char *Option); - void CmdUPDT(const char *Option); -diff -ruNp vdr-1.7.0/timers.c vdr-1.7.0-extensions/timers.c ---- vdr-1.7.0/timers.c 2008-04-13 14:41:41.000000000 +0200 -+++ vdr-1.7.0-extensions/timers.c 2009-04-09 20:48:48.000000000 +0200 -@@ -13,6 +13,9 @@ - #include "device.h" - #include "i18n.h" - #include "libsi/si.h" -+#ifdef USE_LIVEBUFFER -+#include "livebuffer.h" -+#endif /* LIVEBUFFER */ - #include "recording.h" - #include "remote.h" - #include "status.h" -@@ -46,6 +49,9 @@ cTimer::cTimer(bool Instant, bool Pause, - stop -= 2400; - priority = Pause ? Setup.PausePriority : Setup.DefaultPriority; - lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime; -+#ifdef USE_PINPLUGIN -+ fskProtection = 0; -+#endif /* PINPLUGIN */ - *file = 0; - aux = NULL; - event = NULL; -@@ -79,12 +85,18 @@ cTimer::cTimer(const cEvent *Event) - stop -= 2400; - priority = Setup.DefaultPriority; - lifetime = Setup.DefaultLifetime; -+#ifdef USE_PINPLUGIN -+ fskProtection = 0; -+#endif /* PINPLUGIN */ - *file = 0; - const char *Title = Event->Title(); - if (!isempty(Title)) - Utf8Strn0Cpy(file, Event->Title(), sizeof(file)); - aux = NULL; - event = NULL; // let SetEvent() be called to get a log message -+#ifdef USE_PINPLUGIN -+ cStatus::MsgTimerCreation(this, Event); -+#endif /* PINPLUGIN */ - } - - cTimer::cTimer(const cTimer &Timer) -@@ -119,6 +131,9 @@ cTimer& cTimer::operator= (const cTimer - stop = Timer.stop; - priority = Timer.priority; - lifetime = Timer.lifetime; -+#ifdef USE_PINPLUGIN -+ fskProtection = Timer.fskProtection; -+#endif /* PINPLUGIN */ - strncpy(file, Timer.file, sizeof(file)); - free(aux); - aux = Timer.aux ? strdup(Timer.aux) : NULL; -@@ -313,6 +328,9 @@ bool cTimer::Parse(const char *s) - result = false; - } - } -+#ifdef USE_PINPLUGIN -+ fskProtection = aux && strstr(aux, "<pin-plugin><protected>yes</protected></pin-plugin>"); -+#endif /* PINPLUGIN */ - free(channelbuffer); - free(daybuffer); - free(filebuffer); -@@ -559,6 +577,9 @@ void cTimer::SetRecording(bool Recording - SetFlags(tfRecording); - else - ClrFlags(tfRecording); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgRecordingChange(NULL, scAdd); -+#endif /* STREAMDEVEXT */ - isyslog("timer %s %s", *ToDescr(), recording ? "start" : "stop"); - } - -@@ -622,6 +643,35 @@ void cTimer::OnOff(void) - Matches(); // refresh start and end time - } - -+#ifdef USE_PINPLUGIN -+void cTimer::SetFskProtection(int aFlag) -+{ -+ char* p; -+ char* tmp = 0; -+ -+ fskProtection = aFlag; -+ -+ if (fskProtection && (!aux || !strstr(aux, "<pin-plugin><protected>yes</protected></pin-plugin>"))) -+ { -+ // add protection info to aux -+ -+ if (aux) { tmp = strdup(aux); free(aux); } -+ asprintf(&aux,"%s<pin-plugin><protected>yes</protected></pin-plugin>", tmp ? tmp : ""); -+ } -+ else if (!fskProtection && aux && (p = strstr(aux, "<pin-plugin><protected>yes</protected></pin-plugin>"))) -+ { -+ // remove protection info to aux -+ -+ asprintf(&tmp, "%.*s%s", p-aux, aux, p+strlen("<pin-plugin><protected>yes</protected></pin-plugin>")); -+ free(aux); -+ aux = strdup(tmp); -+ } -+ -+ if (tmp) -+ free(tmp); -+} -+#endif /* PINPLUGIN */ -+ - // --- cTimers --------------------------------------------------------------- - - cTimers Timers; -@@ -651,7 +701,11 @@ cTimer *cTimers::GetMatch(time_t t) - static int LastPending = -1; - cTimer *t0 = NULL; - for (cTimer *ti = First(); ti; ti = Next(ti)) { -+#ifdef USE_LIVEBUFFER -+ if (!ti->Recording() && (ti->Matches(t) || cLiveBufferManager::InLiveBuffer(ti))) { -+#else - if (!ti->Recording() && ti->Matches(t)) { -+#endif /* LIVEBUFFER */ - if (ti->Pending()) { - if (ti->Index() > LastPending) - LastPending = ti->Index(); -@@ -752,7 +806,11 @@ void cTimers::DeleteExpired(void) - cTimer *ti = First(); - while (ti) { - cTimer *next = Next(ti); -+#ifdef USE_LIVEBUFFER -+ if (ti->Expired() && (!cLiveBufferManager::InLiveBuffer(ti) || !ti->HasFlags(tfActive))) { -+#else - if (ti->Expired()) { -+#endif /* LIVEBUFFER */ - isyslog("deleting timer %s", *ti->ToDescr()); - Del(ti); - SetModified(); -diff -ruNp vdr-1.7.0/timers.h vdr-1.7.0-extensions/timers.h ---- vdr-1.7.0/timers.h 2008-02-16 15:33:23.000000000 +0100 -+++ vdr-1.7.0-extensions/timers.h 2009-04-09 20:48:48.000000000 +0200 -@@ -20,12 +20,18 @@ enum eTimerFlags { tfNone = 0x0000, - tfInstant = 0x0002, - tfVps = 0x0004, - tfRecording = 0x0008, -+#ifdef USE_LIVEBUFFER -+ tfhasLiveBuf= 0x0010, -+#endif /* LIVEBUFFER */ - tfAll = 0xFFFF, - }; - enum eTimerMatch { tmNone, tmPartial, tmFull }; - - class cTimer : public cListObject { - friend class cMenuEditTimer; -+#ifdef USE_LIVEBUFFER -+ friend class cLiveBufferControl; -+#endif /* LIVEBUFFER */ - private: - mutable time_t startTime, stopTime; - time_t lastSetEvent; -@@ -37,6 +43,9 @@ private: - int start; - int stop; - int priority; -+#ifdef USE_PINPLUGIN -+ int fskProtection; -+#endif /* PINPLUGIN */ - int lifetime; - mutable char file[MaxFileName]; - char *aux; -@@ -58,6 +67,9 @@ public: - int Start(void) const { return start; } - int Stop(void) const { return stop; } - int Priority(void) const { return priority; } -+#ifdef USE_PINPLUGIN -+ int FskProtection(void) const { return fskProtection; } -+#endif /* PINPLUGIN */ - int Lifetime(void) const { return lifetime; } - const char *File(void) const { return file; } - time_t FirstDay(void) const { return weekdays ? day : 0; } -@@ -86,6 +98,9 @@ public: - void SetInVpsMargin(bool InVpsMargin); - void SetPriority(int Priority); - void SetFlags(uint Flags); -+#ifdef USE_PINPLUGIN -+ void SetFskProtection(int aFlag); -+#endif /* PINPLUGIN */ - void ClrFlags(uint Flags); - void InvFlags(uint Flags); - bool HasFlags(uint Flags) const; -diff -ruNp vdr-1.7.0/tinystr.c vdr-1.7.0-extensions/tinystr.c ---- vdr-1.7.0/tinystr.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/tinystr.c 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,301 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original file by Yves Berquin. -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include "tinyxml.h" -+ -+#ifndef TIXML_USE_STL -+ -+ -+#include <stdlib.h> -+#include <string.h> -+#include <ctype.h> -+ -+#include "tinystr.h" -+ -+// TiXmlString constructor, based on a C string -+TiXmlString::TiXmlString (const char* instring) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ if (!instring) -+ { -+ allocated = 0; -+ cstring = NULL; -+ current_length = 0; -+ return; -+ } -+ newlen = strlen (instring) + 1; -+ newstring = new char [newlen]; -+ memcpy (newstring, instring, newlen); -+ // strcpy (newstring, instring); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+// TiXmlString copy constructor -+TiXmlString::TiXmlString (const TiXmlString& copy) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ // Prevent copy to self! -+ if ( © == this ) -+ return; -+ -+ if (! copy . allocated) -+ { -+ allocated = 0; -+ cstring = NULL; -+ current_length = 0; -+ return; -+ } -+ newlen = copy . length () + 1; -+ newstring = new char [newlen]; -+ // strcpy (newstring, copy . cstring); -+ memcpy (newstring, copy . cstring, newlen); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+// TiXmlString = operator. Safe when assign own content -+void TiXmlString ::operator = (const char * content) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ if (! content) -+ { -+ empty_it (); -+ return; -+ } -+ newlen = strlen (content) + 1; -+ newstring = new char [newlen]; -+ // strcpy (newstring, content); -+ memcpy (newstring, content, newlen); -+ empty_it (); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+// = operator. Safe when assign own content -+void TiXmlString ::operator = (const TiXmlString & copy) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ if (! copy . length ()) -+ { -+ empty_it (); -+ return; -+ } -+ newlen = copy . length () + 1; -+ newstring = new char [newlen]; -+ // strcpy (newstring, copy . c_str ()); -+ memcpy (newstring, copy . c_str (), newlen); -+ empty_it (); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+ -+// append a const char * to an existing TiXmlString -+void TiXmlString::append( const char* str, int len ) -+{ -+ char * new_string; -+ unsigned new_alloc, new_size, size_suffix; -+ -+ // don't use strlen - it can overrun the len passed in! -+ const char* p = str; -+ size_suffix = 0; -+ -+ while ( *p && size_suffix < (unsigned)len ) -+ { -+ ++p; -+ ++size_suffix; -+ } -+ if ( !size_suffix) -+ return; -+ -+ new_size = length () + size_suffix + 1; -+ // check if we need to expand -+ if (new_size > allocated) -+ { -+ // compute new size -+ new_alloc = assign_new_size (new_size); -+ -+ // allocate new buffer -+ new_string = new char [new_alloc]; -+ new_string [0] = 0; -+ -+ // copy the previous allocated buffer into this one -+ if (allocated && cstring) -+ // strcpy (new_string, cstring); -+ memcpy (new_string, cstring, length ()); -+ -+ // append the suffix. It does exist, otherwize we wouldn't be expanding -+ // strncat (new_string, str, len); -+ memcpy (new_string + length (), -+ str, -+ size_suffix); -+ -+ // return previsously allocated buffer if any -+ if (allocated && cstring) -+ delete [] cstring; -+ -+ // update member variables -+ cstring = new_string; -+ allocated = new_alloc; -+ } -+ else -+ { -+ // we know we can safely append the new string -+ // strncat (cstring, str, len); -+ memcpy (cstring + length (), -+ str, -+ size_suffix); -+ } -+ current_length = new_size - 1; -+ cstring [current_length] = 0; -+} -+ -+ -+// append a const char * to an existing TiXmlString -+void TiXmlString::append( const char * suffix ) -+{ -+ char * new_string; -+ unsigned new_alloc, new_size; -+ -+ new_size = length () + strlen (suffix) + 1; -+ // check if we need to expand -+ if (new_size > allocated) -+ { -+ // compute new size -+ new_alloc = assign_new_size (new_size); -+ -+ // allocate new buffer -+ new_string = new char [new_alloc]; -+ new_string [0] = 0; -+ -+ // copy the previous allocated buffer into this one -+ if (allocated && cstring) -+ memcpy (new_string, cstring, 1 + length ()); -+ // strcpy (new_string, cstring); -+ -+ // append the suffix. It does exist, otherwize we wouldn't be expanding -+ // strcat (new_string, suffix); -+ memcpy (new_string + length (), -+ suffix, -+ strlen (suffix) + 1); -+ -+ // return previsously allocated buffer if any -+ if (allocated && cstring) -+ delete [] cstring; -+ -+ // update member variables -+ cstring = new_string; -+ allocated = new_alloc; -+ } -+ else -+ { -+ // we know we can safely append the new string -+ // strcat (cstring, suffix); -+ memcpy (cstring + length (), -+ suffix, -+ strlen (suffix) + 1); -+ } -+ current_length = new_size - 1; -+} -+ -+// Check for TiXmlString equuivalence -+//bool TiXmlString::operator == (const TiXmlString & compare) const -+//{ -+// return (! strcmp (c_str (), compare . c_str ())); -+//} -+ -+//unsigned TiXmlString::length () const -+//{ -+// if (allocated) -+// // return strlen (cstring); -+// return current_length; -+// return 0; -+//} -+ -+ -+unsigned TiXmlString::find (char tofind, unsigned offset) const -+{ -+ char * lookup; -+ -+ if (offset >= length ()) -+ return (unsigned) notfound; -+ for (lookup = cstring + offset; * lookup; lookup++) -+ if (* lookup == tofind) -+ return lookup - cstring; -+ return (unsigned) notfound; -+} -+ -+ -+bool TiXmlString::operator == (const TiXmlString & compare) const -+{ -+ if ( allocated && compare.allocated ) -+ { -+ assert( cstring ); -+ assert( compare.cstring ); -+ return ( strcmp( cstring, compare.cstring ) == 0 ); -+ } -+ return false; -+} -+ -+ -+bool TiXmlString::operator < (const TiXmlString & compare) const -+{ -+ if ( allocated && compare.allocated ) -+ { -+ assert( cstring ); -+ assert( compare.cstring ); -+ return ( strcmp( cstring, compare.cstring ) > 0 ); -+ } -+ return false; -+} -+ -+ -+bool TiXmlString::operator > (const TiXmlString & compare) const -+{ -+ if ( allocated && compare.allocated ) -+ { -+ assert( cstring ); -+ assert( compare.cstring ); -+ return ( strcmp( cstring, compare.cstring ) < 0 ); -+ } -+ return false; -+} -+ -+ -+#endif // TIXML_USE_STL -+#endif /* SETUP */ -diff -ruNp vdr-1.7.0/tinystr.h vdr-1.7.0-extensions/tinystr.h ---- vdr-1.7.0/tinystr.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/tinystr.h 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,244 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original file by Yves Berquin. -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include "tinyxml.h" -+ -+ -+#ifndef TIXML_USE_STL -+ -+#ifndef TIXML_STRING_INCLUDED -+#define TIXML_STRING_INCLUDED -+ -+#ifdef _MSC_VER -+#pragma warning( disable : 4786 ) // Debugger truncating names. -+#endif -+ -+#include <assert.h> -+ -+/* -+ TiXmlString is an emulation of the std::string template. -+ Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. -+ Only the member functions relevant to the TinyXML project have been implemented. -+ The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase -+ a string and there's no more room, we allocate a buffer twice as big as we need. -+*/ -+class TiXmlString -+{ -+ public : -+ // TiXmlString constructor, based on a string -+ TiXmlString (const char * instring); -+ -+ // TiXmlString empty constructor -+ TiXmlString () -+ { -+ allocated = 0; -+ cstring = NULL; -+ current_length = 0; -+ } -+ -+ // TiXmlString copy constructor -+ TiXmlString (const TiXmlString& copy); -+ -+ // TiXmlString destructor -+ ~ TiXmlString () -+ { -+ empty_it (); -+ } -+ -+ // Convert a TiXmlString into a classical char * -+ const char * c_str () const -+ { -+ if (allocated) -+ return cstring; -+ return ""; -+ } -+ -+ // Return the length of a TiXmlString -+ unsigned length () const -+ { -+ return ( allocated ) ? current_length : 0; -+ } -+ -+ // TiXmlString = operator -+ void operator = (const char * content); -+ -+ // = operator -+ void operator = (const TiXmlString & copy); -+ -+ // += operator. Maps to append -+ TiXmlString& operator += (const char * suffix) -+ { -+ append (suffix); -+ return *this; -+ } -+ -+ // += operator. Maps to append -+ TiXmlString& operator += (char single) -+ { -+ append (single); -+ return *this; -+ } -+ -+ // += operator. Maps to append -+ TiXmlString& operator += (TiXmlString & suffix) -+ { -+ append (suffix); -+ return *this; -+ } -+ bool operator == (const TiXmlString & compare) const; -+ bool operator < (const TiXmlString & compare) const; -+ bool operator > (const TiXmlString & compare) const; -+ -+ // Checks if a TiXmlString is empty -+ bool empty () const -+ { -+ return length () ? false : true; -+ } -+ -+ // single char extraction -+ const char& at (unsigned index) const -+ { -+ assert( index < length ()); -+ return cstring [index]; -+ } -+ -+ // find a char in a string. Return TiXmlString::notfound if not found -+ unsigned find (char lookup) const -+ { -+ return find (lookup, 0); -+ } -+ -+ // find a char in a string from an offset. Return TiXmlString::notfound if not found -+ unsigned find (char tofind, unsigned offset) const; -+ -+ /* Function to reserve a big amount of data when we know we'll need it. Be aware that this -+ function clears the content of the TiXmlString if any exists. -+ */ -+ void reserve (unsigned size) -+ { -+ empty_it (); -+ if (size) -+ { -+ allocated = size; -+ cstring = new char [size]; -+ cstring [0] = 0; -+ current_length = 0; -+ } -+ } -+ -+ // [] operator -+ char& operator [] (unsigned index) const -+ { -+ assert( index < length ()); -+ return cstring [index]; -+ } -+ -+ // Error value for find primitive -+ enum { notfound = 0xffffffff, -+ npos = notfound }; -+ -+ void append (const char *str, int len ); -+ -+ protected : -+ -+ // The base string -+ char * cstring; -+ // Number of chars allocated -+ unsigned allocated; -+ // Current string size -+ unsigned current_length; -+ -+ // New size computation. It is simplistic right now : it returns twice the amount -+ // we need -+ unsigned assign_new_size (unsigned minimum_to_allocate) -+ { -+ return minimum_to_allocate * 2; -+ } -+ -+ // Internal function that clears the content of a TiXmlString -+ void empty_it () -+ { -+ if (cstring) -+ delete [] cstring; -+ cstring = NULL; -+ allocated = 0; -+ current_length = 0; -+ } -+ -+ void append (const char *suffix ); -+ -+ // append function for another TiXmlString -+ void append (const TiXmlString & suffix) -+ { -+ append (suffix . c_str ()); -+ } -+ -+ // append for a single char. -+ void append (char single) -+ { -+ if ( cstring && current_length < (allocated-1) ) -+ { -+ cstring[ current_length ] = single; -+ ++current_length; -+ cstring[ current_length ] = 0; -+ } -+ else -+ { -+ char smallstr [2]; -+ smallstr [0] = single; -+ smallstr [1] = 0; -+ append (smallstr); -+ } -+ } -+ -+} ; -+ -+/* -+ TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. -+ Only the operators that we need for TinyXML have been developped. -+*/ -+class TiXmlOutStream : public TiXmlString -+{ -+public : -+ TiXmlOutStream () : TiXmlString () {} -+ -+ // TiXmlOutStream << operator. Maps to TiXmlString::append -+ TiXmlOutStream & operator << (const char * in) -+ { -+ append (in); -+ return (* this); -+ } -+ -+ // TiXmlOutStream << operator. Maps to TiXmlString::append -+ TiXmlOutStream & operator << (const TiXmlString & in) -+ { -+ append (in . c_str ()); -+ return (* this); -+ } -+} ; -+ -+#endif // TIXML_STRING_INCLUDED -+#endif // TIXML_USE_STL -+#endif /* SETUP */ -diff -ruNp vdr-1.7.0/tinyxml.c vdr-1.7.0-extensions/tinyxml.c ---- vdr-1.7.0/tinyxml.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/tinyxml.c 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,1429 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include <ctype.h> -+#include "tinyxml.h" -+ -+#ifdef TIXML_USE_STL -+#include <sstream> -+#endif -+ -+ -+bool TiXmlBase::condenseWhiteSpace = true; -+ -+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream ) -+{ -+ TIXML_STRING buffer; -+ PutString( str, &buffer ); -+ (*stream) << buffer; -+} -+ -+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString ) -+{ -+ int i=0; -+ -+ while( i<(int)str.length() ) -+ { -+ unsigned char c = (unsigned char) str[i]; -+ -+ if ( c == '&' -+ && i < ( (int)str.length() - 2 ) -+ && str[i+1] == '#' -+ && str[i+2] == 'x' ) -+ { -+ // Hexadecimal character reference. -+ // Pass through unchanged. -+ // © -- copyright symbol, for example. -+ // -+ // The -1 is a bug fix from Rob Laveaux. It keeps -+ // an overflow from happening if there is no ';'. -+ // There are actually 2 ways to exit this loop - -+ // while fails (error case) and break (semicolon found). -+ // However, there is no mechanism (currently) for -+ // this function to return an error. -+ while ( i<(int)str.length()-1 ) -+ { -+ outString->append( str.c_str() + i, 1 ); -+ ++i; -+ if ( str[i] == ';' ) -+ break; -+ } -+ } -+ else if ( c == '&' ) -+ { -+ outString->append( entity[0].str, entity[0].strLength ); -+ ++i; -+ } -+ else if ( c == '<' ) -+ { -+ outString->append( entity[1].str, entity[1].strLength ); -+ ++i; -+ } -+ else if ( c == '>' ) -+ { -+ outString->append( entity[2].str, entity[2].strLength ); -+ ++i; -+ } -+ else if ( c == '\"' ) -+ { -+ outString->append( entity[3].str, entity[3].strLength ); -+ ++i; -+ } -+ else if ( c == '\'' ) -+ { -+ outString->append( entity[4].str, entity[4].strLength ); -+ ++i; -+ } -+ else if ( c < 32 ) -+ { -+ // Easy pass at non-alpha/numeric/symbol -+ // Below 32 is symbolic. -+ char buf[ 32 ]; -+ sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); -+ outString->append( buf, strlen( buf ) ); -+ ++i; -+ } -+ else -+ { -+ //char realc = (char) c; -+ //outString->append( &realc, 1 ); -+ *outString += (char) c; // somewhat more efficient function call. -+ ++i; -+ } -+ } -+} -+ -+ -+// <-- Strange class for a bug fix. Search for STL_STRING_BUG -+TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str ) -+{ -+ buffer = new char[ str.length()+1 ]; -+ if ( buffer ) -+ { -+ strcpy( buffer, str.c_str() ); -+ } -+} -+ -+ -+TiXmlBase::StringToBuffer::~StringToBuffer() -+{ -+ delete [] buffer; -+} -+// End strange bug fix. --> -+ -+ -+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() -+{ -+ parent = 0; -+ type = _type; -+ firstChild = 0; -+ lastChild = 0; -+ prev = 0; -+ next = 0; -+} -+ -+ -+TiXmlNode::~TiXmlNode() -+{ -+ TiXmlNode* node = firstChild; -+ TiXmlNode* temp = 0; -+ -+ while ( node ) -+ { -+ temp = node; -+ node = node->next; -+ delete temp; -+ } -+} -+ -+ -+void TiXmlNode::CopyTo( TiXmlNode* target ) const -+{ -+ target->SetValue (value.c_str() ); -+ target->userData = userData; -+} -+ -+ -+void TiXmlNode::Clear() -+{ -+ TiXmlNode* node = firstChild; -+ TiXmlNode* temp = 0; -+ -+ while ( node ) -+ { -+ temp = node; -+ node = node->next; -+ delete temp; -+ } -+ -+ firstChild = 0; -+ lastChild = 0; -+} -+ -+ -+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) -+{ -+ node->parent = this; -+ -+ node->prev = lastChild; -+ node->next = 0; -+ -+ if ( lastChild ) -+ lastChild->next = node; -+ else -+ firstChild = node; // it was an empty list. -+ -+ lastChild = node; -+ return node; -+} -+ -+ -+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) -+{ -+ TiXmlNode* node = addThis.Clone(); -+ if ( !node ) -+ return 0; -+ -+ return LinkEndChild( node ); -+} -+ -+ -+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) -+{ -+ if ( !beforeThis || beforeThis->parent != this ) -+ return 0; -+ -+ TiXmlNode* node = addThis.Clone(); -+ if ( !node ) -+ return 0; -+ node->parent = this; -+ -+ node->next = beforeThis; -+ node->prev = beforeThis->prev; -+ if ( beforeThis->prev ) -+ { -+ beforeThis->prev->next = node; -+ } -+ else -+ { -+ assert( firstChild == beforeThis ); -+ firstChild = node; -+ } -+ beforeThis->prev = node; -+ return node; -+} -+ -+ -+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) -+{ -+ if ( !afterThis || afterThis->parent != this ) -+ return 0; -+ -+ TiXmlNode* node = addThis.Clone(); -+ if ( !node ) -+ return 0; -+ node->parent = this; -+ -+ node->prev = afterThis; -+ node->next = afterThis->next; -+ if ( afterThis->next ) -+ { -+ afterThis->next->prev = node; -+ } -+ else -+ { -+ assert( lastChild == afterThis ); -+ lastChild = node; -+ } -+ afterThis->next = node; -+ return node; -+} -+ -+ -+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) -+{ -+ if ( replaceThis->parent != this ) -+ return 0; -+ -+ TiXmlNode* node = withThis.Clone(); -+ if ( !node ) -+ return 0; -+ -+ node->next = replaceThis->next; -+ node->prev = replaceThis->prev; -+ -+ if ( replaceThis->next ) -+ replaceThis->next->prev = node; -+ else -+ lastChild = node; -+ -+ if ( replaceThis->prev ) -+ replaceThis->prev->next = node; -+ else -+ firstChild = node; -+ -+ delete replaceThis; -+ node->parent = this; -+ return node; -+} -+ -+ -+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) -+{ -+ if ( removeThis->parent != this ) -+ { -+ assert( 0 ); -+ return false; -+ } -+ -+ if ( removeThis->next ) -+ removeThis->next->prev = removeThis->prev; -+ else -+ lastChild = removeThis->prev; -+ -+ if ( removeThis->prev ) -+ removeThis->prev->next = removeThis->next; -+ else -+ firstChild = removeThis->next; -+ -+ delete removeThis; -+ return true; -+} -+ -+TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = firstChild; node; node = node->next ) -+ { -+ if ( node->SValue() == TIXML_STRING( _value )) -+ return node; -+ } -+ return 0; -+} -+ -+TiXmlNode* TiXmlNode::LastChild( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = lastChild; node; node = node->prev ) -+ { -+ if ( node->SValue() == TIXML_STRING (_value)) -+ return node; -+ } -+ return 0; -+} -+ -+TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) const -+{ -+ if ( !previous ) -+ { -+ return FirstChild(); -+ } -+ else -+ { -+ assert( previous->parent == this ); -+ return previous->NextSibling(); -+ } -+} -+ -+TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous ) const -+{ -+ if ( !previous ) -+ { -+ return FirstChild( val ); -+ } -+ else -+ { -+ assert( previous->parent == this ); -+ return previous->NextSibling( val ); -+ } -+} -+ -+TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = next; node; node = node->next ) -+ { -+ if ( node->SValue() == TIXML_STRING (_value)) -+ return node; -+ } -+ return 0; -+} -+ -+ -+TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = prev; node; node = node->prev ) -+ { -+ if ( node->SValue() == TIXML_STRING (_value)) -+ return node; -+ } -+ return 0; -+} -+ -+void TiXmlElement::RemoveAttribute( const char * name ) -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( node ) -+ { -+ attributeSet.Remove( node ); -+ delete node; -+ } -+} -+ -+TiXmlElement* TiXmlNode::FirstChildElement() const -+{ -+ TiXmlNode* node; -+ -+ for ( node = FirstChild(); -+ node; -+ node = node->NextSibling() ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const -+{ -+ TiXmlNode* node; -+ -+ for ( node = FirstChild( _value ); -+ node; -+ node = node->NextSibling( _value ) ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+ -+TiXmlElement* TiXmlNode::NextSiblingElement() const -+{ -+ TiXmlNode* node; -+ -+ for ( node = NextSibling(); -+ node; -+ node = node->NextSibling() ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const -+{ -+ TiXmlNode* node; -+ -+ for ( node = NextSibling( _value ); -+ node; -+ node = node->NextSibling( _value ) ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+ -+ -+TiXmlDocument* TiXmlNode::GetDocument() const -+{ -+ const TiXmlNode* node; -+ -+ for( node = this; node; node = node->parent ) -+ { -+ if ( node->ToDocument() ) -+ return node->ToDocument(); -+ } -+ return 0; -+} -+ -+ -+TiXmlElement::TiXmlElement (const char * _value) -+ : TiXmlNode( TiXmlNode::ELEMENT ) -+{ -+ firstChild = lastChild = 0; -+ value = _value; -+} -+ -+ -+#ifdef TIXML_USE_STL -+TiXmlElement::TiXmlElement( const std::string& _value ) -+ : TiXmlNode( TiXmlNode::ELEMENT ) -+{ -+ firstChild = lastChild = 0; -+ value = _value; -+} -+#endif -+ -+ -+TiXmlElement::TiXmlElement( const TiXmlElement& copy) -+ : TiXmlNode( TiXmlNode::ELEMENT ) -+{ -+ firstChild = lastChild = 0; -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlElement::operator=( const TiXmlElement& base ) -+{ -+ ClearThis(); -+ base.CopyTo( this ); -+} -+ -+ -+TiXmlElement::~TiXmlElement() -+{ -+ ClearThis(); -+} -+ -+ -+void TiXmlElement::ClearThis() -+{ -+ Clear(); -+ while( attributeSet.First() ) -+ { -+ TiXmlAttribute* node = attributeSet.First(); -+ attributeSet.Remove( node ); -+ delete node; -+ } -+} -+ -+ -+const char * TiXmlElement::Attribute( const char * name ) const -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ -+ if ( node ) -+ return node->Value(); -+ -+ return 0; -+} -+ -+ -+const char * TiXmlElement::Attribute( const char * name, int* i ) const -+{ -+ const char * s = Attribute( name ); -+ if ( i ) -+ { -+ if ( s ) -+ *i = atoi( s ); -+ else -+ *i = 0; -+ } -+ return s; -+} -+ -+ -+const char * TiXmlElement::Attribute( const char * name, double* d ) const -+{ -+ const char * s = Attribute( name ); -+ if ( d ) -+ { -+ if ( s ) -+ *d = atof( s ); -+ else -+ *d = 0; -+ } -+ return s; -+} -+ -+ -+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( !node ) -+ return TIXML_NO_ATTRIBUTE; -+ -+ return node->QueryIntValue( ival ); -+} -+ -+ -+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( !node ) -+ return TIXML_NO_ATTRIBUTE; -+ -+ return node->QueryDoubleValue( dval ); -+} -+ -+ -+void TiXmlElement::SetAttribute( const char * name, int val ) -+{ -+ char buf[64]; -+ sprintf( buf, "%d", val ); -+ SetAttribute( name, buf ); -+} -+ -+ -+void TiXmlElement::SetDoubleAttribute( const char * name, double val ) -+{ -+ char buf[128]; -+ sprintf( buf, "%f", val ); -+ SetAttribute( name, buf ); -+} -+ -+ -+void TiXmlElement::SetAttribute( const char * name, const char * _value ) -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( node ) -+ { -+ node->SetValue( _value ); -+ return; -+ } -+ -+ TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); -+ if ( attrib ) -+ { -+ attributeSet.Add( attrib ); -+ } -+ else -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ } -+} -+ -+void TiXmlElement::Print( FILE* cfile, int depth ) const -+{ -+ int i; -+ for ( i=0; i<depth; i++ ) -+ { -+ fprintf( cfile, " " ); -+ } -+ -+ fprintf( cfile, "<%s", value.c_str() ); -+ -+ TiXmlAttribute* attrib; -+ for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) -+ { -+ fprintf( cfile, " " ); -+ attrib->Print( cfile, depth ); -+ } -+ -+ // There are 3 different formatting approaches: -+ // 1) An element without children is printed as a <foo /> node -+ // 2) An element with only a text child is printed as <foo> text </foo> -+ // 3) An element with children is printed on multiple lines. -+ TiXmlNode* node; -+ if ( !firstChild ) -+ { -+ fprintf( cfile, " />" ); -+ } -+ else if ( firstChild == lastChild && firstChild->ToText() ) -+ { -+ fprintf( cfile, ">" ); -+ firstChild->Print( cfile, depth + 1 ); -+ fprintf( cfile, "</%s>", value.c_str() ); -+ } -+ else -+ { -+ fprintf( cfile, ">" ); -+ -+ for ( node = firstChild; node; node=node->NextSibling() ) -+ { -+ if ( !node->ToText() ) -+ { -+ fprintf( cfile, "\n" ); -+ } -+ node->Print( cfile, depth+1 ); -+ } -+ fprintf( cfile, "\n" ); -+ for( i=0; i<depth; ++i ) -+ fprintf( cfile, " " ); -+ fprintf( cfile, "</%s>", value.c_str() ); -+ } -+} -+ -+void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*stream) << "<" << value; -+ -+ TiXmlAttribute* attrib; -+ for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) -+ { -+ (*stream) << " "; -+ attrib->StreamOut( stream ); -+ } -+ -+ // If this node has children, give it a closing tag. Else -+ // make it an empty tag. -+ TiXmlNode* node; -+ if ( firstChild ) -+ { -+ (*stream) << ">"; -+ -+ for ( node = firstChild; node; node=node->NextSibling() ) -+ { -+ node->StreamOut( stream ); -+ } -+ (*stream) << "</" << value << ">"; -+ } -+ else -+ { -+ (*stream) << " />"; -+ } -+} -+ -+ -+void TiXmlElement::CopyTo( TiXmlElement* target ) const -+{ -+ // superclass: -+ TiXmlNode::CopyTo( target ); -+ -+ // Element class: -+ // Clone the attributes, then clone the children. -+ TiXmlAttribute* attribute = 0; -+ for( attribute = attributeSet.First(); -+ attribute; -+ attribute = attribute->Next() ) -+ { -+ target->SetAttribute( attribute->Name(), attribute->Value() ); -+ } -+ -+ TiXmlNode* node = 0; -+ for ( node = firstChild; node; node = node->NextSibling() ) -+ { -+ target->LinkEndChild( node->Clone() ); -+ } -+} -+ -+ -+TiXmlNode* TiXmlElement::Clone() const -+{ -+ TiXmlElement* clone = new TiXmlElement( Value() ); -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) -+{ -+ tabsize = 4; -+ ClearError(); -+} -+ -+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) -+{ -+ tabsize = 4; -+ value = documentName; -+ ClearError(); -+} -+ -+ -+#ifdef TIXML_USE_STL -+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) -+{ -+ tabsize = 4; -+ value = documentName; -+ ClearError(); -+} -+#endif -+ -+ -+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) -+{ -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlDocument::operator=( const TiXmlDocument& copy ) -+{ -+ Clear(); -+ copy.CopyTo( this ); -+} -+ -+ -+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) -+{ -+ // See STL_STRING_BUG below. -+ StringToBuffer buf( value ); -+ -+ if ( buf.buffer && LoadFile( buf.buffer, encoding ) ) -+ return true; -+ -+ return false; -+} -+ -+ -+bool TiXmlDocument::SaveFile() const -+{ -+ // See STL_STRING_BUG below. -+ StringToBuffer buf( value ); -+ -+ if ( buf.buffer && SaveFile( buf.buffer ) ) -+ return true; -+ -+ return false; -+} -+ -+bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding ) -+{ -+ // Delete the existing data: -+ Clear(); -+ location.Clear(); -+ -+ // There was a really terrifying little bug here. The code: -+ // value = filename -+ // in the STL case, cause the assignment method of the std::string to -+ // be called. What is strange, is that the std::string had the same -+ // address as it's c_str() method, and so bad things happen. Looks -+ // like a bug in the Microsoft STL implementation. -+ // See STL_STRING_BUG above. -+ // Fixed with the StringToBuffer class. -+ value = filename; -+ -+ FILE* file = fopen( value.c_str (), "r" ); -+ -+ if ( file ) -+ { -+ // Get the file size, so we can pre-allocate the string. HUGE speed impact. -+ long length = 0; -+ fseek( file, 0, SEEK_END ); -+ length = ftell( file ); -+ fseek( file, 0, SEEK_SET ); -+ -+ // Strange case, but good to handle up front. -+ if ( length == 0 ) -+ { -+ fclose( file ); -+ return false; -+ } -+ -+ // If we have a file, assume it is all one big XML file, and read it in. -+ // The document parser may decide the document ends sooner than the entire file, however. -+ TIXML_STRING data; -+ data.reserve( length ); -+ -+ const int BUF_SIZE = 2048; -+ char buf[BUF_SIZE]; -+ -+ while( fgets( buf, BUF_SIZE, file ) ) -+ { -+ data += buf; -+ } -+ fclose( file ); -+ -+ Parse( data.c_str(), 0, encoding ); -+ -+ if ( Error() ) -+ return false; -+ else -+ return true; -+ } -+ SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return false; -+} -+ -+bool TiXmlDocument::SaveFile( const char * filename ) const -+{ -+ // The old c stuff lives on... -+ FILE* fp = fopen( filename, "w" ); -+ if ( fp ) -+ { -+ Print( fp, 0 ); -+ fclose( fp ); -+ return true; -+ } -+ return false; -+} -+ -+ -+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+ -+ target->error = error; -+ target->errorDesc = errorDesc.c_str (); -+ -+ TiXmlNode* node = 0; -+ for ( node = firstChild; node; node = node->NextSibling() ) -+ { -+ target->LinkEndChild( node->Clone() ); -+ } -+} -+ -+ -+TiXmlNode* TiXmlDocument::Clone() const -+{ -+ TiXmlDocument* clone = new TiXmlDocument(); -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+void TiXmlDocument::Print( FILE* cfile, int depth ) const -+{ -+ TiXmlNode* node; -+ for ( node=FirstChild(); node; node=node->NextSibling() ) -+ { -+ node->Print( cfile, depth ); -+ fprintf( cfile, "\n" ); -+ } -+} -+ -+void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const -+{ -+ TiXmlNode* node; -+ for ( node=FirstChild(); node; node=node->NextSibling() ) -+ { -+ node->StreamOut( out ); -+ -+ // Special rule for streams: stop after the root element. -+ // The stream in code will only read one element, so don't -+ // write more than one. -+ if ( node->ToElement() ) -+ break; -+ } -+} -+ -+ -+TiXmlAttribute* TiXmlAttribute::Next() const -+{ -+ // We are using knowledge of the sentinel. The sentinel -+ // have a value or name. -+ if ( next->value.empty() && next->name.empty() ) -+ return 0; -+ return next; -+} -+ -+ -+TiXmlAttribute* TiXmlAttribute::Previous() const -+{ -+ // We are using knowledge of the sentinel. The sentinel -+ // have a value or name. -+ if ( prev->value.empty() && prev->name.empty() ) -+ return 0; -+ return prev; -+} -+ -+ -+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const -+{ -+ TIXML_STRING n, v; -+ -+ PutString( name, &n ); -+ PutString( value, &v ); -+ -+ if (value.find ('\"') == TIXML_STRING::npos) -+ fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); -+ else -+ fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); -+} -+ -+ -+void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ if (value.find( '\"' ) != TIXML_STRING::npos) -+ { -+ PutString( name, stream ); -+ (*stream) << "=" << "'"; -+ PutString( value, stream ); -+ (*stream) << "'"; -+ } -+ else -+ { -+ PutString( name, stream ); -+ (*stream) << "=" << "\""; -+ PutString( value, stream ); -+ (*stream) << "\""; -+ } -+} -+ -+int TiXmlAttribute::QueryIntValue( int* ival ) const -+{ -+ if ( sscanf( value.c_str(), "%d", ival ) == 1 ) -+ return TIXML_SUCCESS; -+ return TIXML_WRONG_TYPE; -+} -+ -+int TiXmlAttribute::QueryDoubleValue( double* dval ) const -+{ -+ if ( sscanf( value.c_str(), "%lf", dval ) == 1 ) -+ return TIXML_SUCCESS; -+ return TIXML_WRONG_TYPE; -+} -+ -+void TiXmlAttribute::SetIntValue( int _value ) -+{ -+ char buf [64]; -+ sprintf (buf, "%d", _value); -+ SetValue (buf); -+} -+ -+void TiXmlAttribute::SetDoubleValue( double _value ) -+{ -+ char buf [64]; -+ sprintf (buf, "%lf", _value); -+ SetValue (buf); -+} -+ -+const int TiXmlAttribute::IntValue() const -+{ -+ return atoi (value.c_str ()); -+} -+ -+const double TiXmlAttribute::DoubleValue() const -+{ -+ return atof (value.c_str ()); -+} -+ -+ -+TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) -+{ -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlComment::operator=( const TiXmlComment& base ) -+{ -+ Clear(); -+ base.CopyTo( this ); -+} -+ -+ -+void TiXmlComment::Print( FILE* cfile, int depth ) const -+{ -+ for ( int i=0; i<depth; i++ ) -+ { -+ fputs( " ", cfile ); -+ } -+ fprintf( cfile, "<!--%s-->", value.c_str() ); -+} -+ -+void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*stream) << "<!--"; -+ //PutString( value, stream ); -+ (*stream) << value; -+ (*stream) << "-->"; -+} -+ -+ -+void TiXmlComment::CopyTo( TiXmlComment* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+} -+ -+ -+TiXmlNode* TiXmlComment::Clone() const -+{ -+ TiXmlComment* clone = new TiXmlComment(); -+ -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const -+{ -+ TIXML_STRING buffer; -+ PutString( value, &buffer ); -+ fprintf( cfile, "%s", buffer.c_str() ); -+} -+ -+ -+void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ PutString( value, stream ); -+} -+ -+ -+void TiXmlText::CopyTo( TiXmlText* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+} -+ -+ -+TiXmlNode* TiXmlText::Clone() const -+{ -+ TiXmlText* clone = 0; -+ clone = new TiXmlText( "" ); -+ -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+TiXmlDeclaration::TiXmlDeclaration( const char * _version, -+ const char * _encoding, -+ const char * _standalone ) -+ : TiXmlNode( TiXmlNode::DECLARATION ) -+{ -+ version = _version; -+ encoding = _encoding; -+ standalone = _standalone; -+} -+ -+ -+#ifdef TIXML_USE_STL -+TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, -+ const std::string& _encoding, -+ const std::string& _standalone ) -+ : TiXmlNode( TiXmlNode::DECLARATION ) -+{ -+ version = _version; -+ encoding = _encoding; -+ standalone = _standalone; -+} -+#endif -+ -+ -+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) -+ : TiXmlNode( TiXmlNode::DECLARATION ) -+{ -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) -+{ -+ Clear(); -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const -+{ -+ fprintf (cfile, "<?xml "); -+ -+ if ( !version.empty() ) -+ fprintf (cfile, "version=\"%s\" ", version.c_str ()); -+ if ( !encoding.empty() ) -+ fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ()); -+ if ( !standalone.empty() ) -+ fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ()); -+ fprintf (cfile, "?>"); -+} -+ -+void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*stream) << "<?xml "; -+ -+ if ( !version.empty() ) -+ { -+ (*stream) << "version=\""; -+ PutString( version, stream ); -+ (*stream) << "\" "; -+ } -+ if ( !encoding.empty() ) -+ { -+ (*stream) << "encoding=\""; -+ PutString( encoding, stream ); -+ (*stream ) << "\" "; -+ } -+ if ( !standalone.empty() ) -+ { -+ (*stream) << "standalone=\""; -+ PutString( standalone, stream ); -+ (*stream) << "\" "; -+ } -+ (*stream) << "?>"; -+} -+ -+ -+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+ -+ target->version = version; -+ target->encoding = encoding; -+ target->standalone = standalone; -+} -+ -+ -+TiXmlNode* TiXmlDeclaration::Clone() const -+{ -+ TiXmlDeclaration* clone = new TiXmlDeclaration(); -+ -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+void TiXmlUnknown::Print( FILE* cfile, int depth ) const -+{ -+ for ( int i=0; i<depth; i++ ) -+ fprintf( cfile, " " ); -+ fprintf( cfile, "<%s>", value.c_str() ); -+} -+ -+ -+void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown. -+} -+ -+ -+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+} -+ -+ -+TiXmlNode* TiXmlUnknown::Clone() const -+{ -+ TiXmlUnknown* clone = new TiXmlUnknown(); -+ -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+TiXmlAttributeSet::TiXmlAttributeSet() -+{ -+ sentinel.next = &sentinel; -+ sentinel.prev = &sentinel; -+} -+ -+ -+TiXmlAttributeSet::~TiXmlAttributeSet() -+{ -+ assert( sentinel.next == &sentinel ); -+ assert( sentinel.prev == &sentinel ); -+} -+ -+ -+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) -+{ -+ assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. -+ -+ addMe->next = &sentinel; -+ addMe->prev = sentinel.prev; -+ -+ sentinel.prev->next = addMe; -+ sentinel.prev = addMe; -+} -+ -+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) -+{ -+ TiXmlAttribute* node; -+ -+ for( node = sentinel.next; node != &sentinel; node = node->next ) -+ { -+ if ( node == removeMe ) -+ { -+ node->prev->next = node->next; -+ node->next->prev = node->prev; -+ node->next = 0; -+ node->prev = 0; -+ return; -+ } -+ } -+ assert( 0 ); // we tried to remove a non-linked attribute. -+} -+ -+TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const -+{ -+ TiXmlAttribute* node; -+ -+ for( node = sentinel.next; node != &sentinel; node = node->next ) -+ { -+ if ( node->name == name ) -+ return node; -+ } -+ return 0; -+} -+ -+ -+#ifdef TIXML_USE_STL -+TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base) -+{ -+ TIXML_STRING tag; -+ tag.reserve( 8 * 1000 ); -+ base.StreamIn( &in, &tag ); -+ -+ base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); -+ return in; -+} -+#endif -+ -+ -+TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base) -+{ -+ base.StreamOut (& out); -+ return out; -+} -+ -+ -+#ifdef TIXML_USE_STL -+std::string & operator<< (std::string& out, const TiXmlNode& base ) -+{ -+ std::ostringstream os_stream( std::ostringstream::out ); -+ base.StreamOut( &os_stream ); -+ -+ out.append( os_stream.str() ); -+ return out; -+} -+#endif -+ -+ -+TiXmlHandle TiXmlHandle::FirstChild() const -+{ -+ if ( node ) -+ { -+ TiXmlNode* child = node->FirstChild(); -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const -+{ -+ if ( node ) -+ { -+ TiXmlNode* child = node->FirstChild( value ); -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::FirstChildElement() const -+{ -+ if ( node ) -+ { -+ TiXmlElement* child = node->FirstChildElement(); -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const -+{ -+ if ( node ) -+ { -+ TiXmlElement* child = node->FirstChildElement( value ); -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::Child( int count ) const -+{ -+ if ( node ) -+ { -+ int i; -+ TiXmlNode* child = node->FirstChild(); -+ for ( i=0; -+ child && i<count; -+ child = child->NextSibling(), ++i ) -+ { -+ // nothing -+ } -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const -+{ -+ if ( node ) -+ { -+ int i; -+ TiXmlNode* child = node->FirstChild( value ); -+ for ( i=0; -+ child && i<count; -+ child = child->NextSibling( value ), ++i ) -+ { -+ // nothing -+ } -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::ChildElement( int count ) const -+{ -+ if ( node ) -+ { -+ int i; -+ TiXmlElement* child = node->FirstChildElement(); -+ for ( i=0; -+ child && i<count; -+ child = child->NextSiblingElement(), ++i ) -+ { -+ // nothing -+ } -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const -+{ -+ if ( node ) -+ { -+ int i; -+ TiXmlElement* child = node->FirstChildElement( value ); -+ for ( i=0; -+ child && i<count; -+ child = child->NextSiblingElement( value ), ++i ) -+ { -+ // nothing -+ } -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+#endif /* SETUP */ -diff -ruNp vdr-1.7.0/tinyxmlerror.c vdr-1.7.0-extensions/tinyxmlerror.c ---- vdr-1.7.0/tinyxmlerror.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/tinyxmlerror.c 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,53 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include "tinyxml.h" -+ -+// The goal of the seperate error file is to make the first -+// step towards localization. tinyxml (currently) only supports -+// latin-1, but at least the error messages could now be translated. -+// -+// It also cleans up the code a bit. -+// -+ -+const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = -+{ -+ "No error", -+ "Error", -+ "Failed to open file", -+ "Memory allocation failed.", -+ "Error parsing Element.", -+ "Failed to read Element name", -+ "Error reading Element value.", -+ "Error reading Attributes.", -+ "Error: empty tag.", -+ "Error reading end tag.", -+ "Error parsing Unknown.", -+ "Error parsing Comment.", -+ "Error parsing Declaration.", -+ "Error document empty.", -+ "Error null (0) or unexpected EOF found in input stream.", -+}; -+#endif /* SETUP */ -diff -ruNp vdr-1.7.0/tinyxml.h vdr-1.7.0-extensions/tinyxml.h ---- vdr-1.7.0/tinyxml.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/tinyxml.h 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,1372 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+ -+#ifndef TINYXML_INCLUDED -+#define TINYXML_INCLUDED -+ -+#ifdef _MSC_VER -+#pragma warning( disable : 4530 ) -+#pragma warning( disable : 4786 ) -+#endif -+ -+#include <ctype.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+#include <assert.h> -+ -+// Help out windows: -+#if defined( _DEBUG ) && !defined( DEBUG ) -+#define DEBUG -+#endif -+ -+#if defined( DEBUG ) && defined( _MSC_VER ) -+#include <windows.h> -+#define TIXML_LOG OutputDebugString -+#else -+#define TIXML_LOG printf -+#endif -+ -+#ifdef TIXML_USE_STL -+ #include <string> -+ #include <iostream> -+ #define TIXML_STRING std::string -+ #define TIXML_ISTREAM std::istream -+ #define TIXML_OSTREAM std::ostream -+#else -+ #include "tinystr.h" -+ #define TIXML_STRING TiXmlString -+ #define TIXML_OSTREAM TiXmlOutStream -+#endif -+ -+class TiXmlDocument; -+class TiXmlElement; -+class TiXmlComment; -+class TiXmlUnknown; -+class TiXmlAttribute; -+class TiXmlText; -+class TiXmlDeclaration; -+class TiXmlParsingData; -+ -+const int TIXML_MAJOR_VERSION = 2; -+const int TIXML_MINOR_VERSION = 3; -+const int TIXML_PATCH_VERSION = 2; -+ -+/* Internal structure for tracking location of items -+ in the XML file. -+*/ -+struct TiXmlCursor -+{ -+ TiXmlCursor() { Clear(); } -+ void Clear() { row = col = -1; } -+ -+ int row; // 0 based. -+ int col; // 0 based. -+}; -+ -+ -+// Only used by Attribute::Query functions -+enum -+{ -+ TIXML_SUCCESS, -+ TIXML_NO_ATTRIBUTE, -+ TIXML_WRONG_TYPE -+}; -+ -+ -+// Used by the parsing routines. -+enum TiXmlEncoding -+{ -+ TIXML_ENCODING_UNKNOWN, -+ TIXML_ENCODING_UTF8, -+ TIXML_ENCODING_LEGACY -+}; -+ -+const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; -+ -+/** TiXmlBase is a base class for every class in TinyXml. -+ It does little except to establish that TinyXml classes -+ can be printed and provide some utility functions. -+ -+ In XML, the document and elements can contain -+ other elements and other types of nodes. -+ -+ @verbatim -+ A Document can contain: Element (container or leaf) -+ Comment (leaf) -+ Unknown (leaf) -+ Declaration( leaf ) -+ -+ An Element can contain: Element (container or leaf) -+ Text (leaf) -+ Attributes (not on tree) -+ Comment (leaf) -+ Unknown (leaf) -+ -+ A Decleration contains: Attributes (not on tree) -+ @endverbatim -+*/ -+class TiXmlBase -+{ -+ friend class TiXmlNode; -+ friend class TiXmlElement; -+ friend class TiXmlDocument; -+ -+public: -+ TiXmlBase() : userData(0) {} -+ virtual ~TiXmlBase() {} -+ -+ /** All TinyXml classes can print themselves to a filestream. -+ This is a formatted print, and will insert tabs and newlines. -+ -+ (For an unformatted stream, use the << operator.) -+ */ -+ virtual void Print( FILE* cfile, int depth ) const = 0; -+ -+ /** The world does not agree on whether white space should be kept or -+ not. In order to make everyone happy, these global, static functions -+ are provided to set whether or not TinyXml will condense all white space -+ into a single space or not. The default is to condense. Note changing this -+ values is not thread safe. -+ */ -+ static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } -+ -+ /// Return the current white space setting. -+ static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } -+ -+ /** Return the position, in the original source file, of this node or attribute. -+ The row and column are 1-based. (That is the first row and first column is -+ 1,1). If the returns values are 0 or less, then the parser does not have -+ a row and column value. -+ -+ Generally, the row and column value will be set when the TiXmlDocument::Load(), -+ TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set -+ when the DOM was created from operator>>. -+ -+ The values reflect the initial load. Once the DOM is modified programmatically -+ (by adding or changing nodes and attributes) the new values will NOT update to -+ reflect changes in the document. -+ -+ There is a minor performance cost to computing the row and column. Computation -+ can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. -+ -+ @sa TiXmlDocument::SetTabSize() -+ */ -+ int Row() const { return location.row + 1; } -+ int Column() const { return location.col + 1; } ///< See Row() -+ -+ void SetUserData( void* user ) { userData = user; } -+ void* GetUserData() { return userData; } -+ -+ // Table that returs, for a given lead byte, the total number of bytes -+ // in the UTF-8 sequence. -+ static const int utf8ByteTable[256]; -+ -+ virtual const char* Parse( const char* p, -+ TiXmlParsingData* data, -+ TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; -+ -+protected: -+ -+ // See STL_STRING_BUG -+ // Utility class to overcome a bug. -+ class StringToBuffer -+ { -+ public: -+ StringToBuffer( const TIXML_STRING& str ); -+ ~StringToBuffer(); -+ char* buffer; -+ }; -+ -+ static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); -+ inline static bool IsWhiteSpace( char c ) -+ { -+ return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); -+ } -+ -+ virtual void StreamOut (TIXML_OSTREAM *) const = 0; -+ -+ #ifdef TIXML_USE_STL -+ static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ); -+ #endif -+ -+ /* Reads an XML name into the string provided. Returns -+ a pointer just past the last character of the name, -+ or 0 if the function has an error. -+ */ -+ static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); -+ -+ /* Reads text. Returns a pointer past the given end tag. -+ Wickedly complex options, but it keeps the (sensitive) code in one place. -+ */ -+ static const char* ReadText( const char* in, // where to start -+ TIXML_STRING* text, // the string read -+ bool ignoreWhiteSpace, // whether to keep the white space -+ const char* endTag, // what ends this text -+ bool ignoreCase, // whether to ignore case in the end tag -+ TiXmlEncoding encoding ); // the current encoding -+ -+ // If an entity has been found, transform it into a character. -+ static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); -+ -+ // Get a character, while interpreting entities. -+ // The length can be from 0 to 4 bytes. -+ inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) -+ { -+ assert( p ); -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ *length = utf8ByteTable[ *((unsigned char*)p) ]; -+ assert( *length >= 0 && *length < 5 ); -+ } -+ else -+ { -+ *length = 1; -+ } -+ -+ if ( *length == 1 ) -+ { -+ if ( *p == '&' ) -+ return GetEntity( p, _value, length, encoding ); -+ *_value = *p; -+ return p+1; -+ } -+ else if ( *length ) -+ { -+ strncpy( _value, p, *length ); -+ return p + (*length); -+ } -+ else -+ { -+ // Not valid text. -+ return 0; -+ } -+ } -+ -+ // Puts a string to a stream, expanding entities as it goes. -+ // Note this should not contian the '<', '>', etc, or they will be transformed into entities! -+ static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out ); -+ -+ static void PutString( const TIXML_STRING& str, TIXML_STRING* out ); -+ -+ // Return true if the next characters in the stream are any of the endTag sequences. -+ // Ignore case only works for english, and should only be relied on when comparing -+ // to Engilish words: StringEqual( p, "version", true ) is fine. -+ static bool StringEqual( const char* p, -+ const char* endTag, -+ bool ignoreCase, -+ TiXmlEncoding encoding ); -+ -+ -+ enum -+ { -+ TIXML_NO_ERROR = 0, -+ TIXML_ERROR, -+ TIXML_ERROR_OPENING_FILE, -+ TIXML_ERROR_OUT_OF_MEMORY, -+ TIXML_ERROR_PARSING_ELEMENT, -+ TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, -+ TIXML_ERROR_READING_ELEMENT_VALUE, -+ TIXML_ERROR_READING_ATTRIBUTES, -+ TIXML_ERROR_PARSING_EMPTY, -+ TIXML_ERROR_READING_END_TAG, -+ TIXML_ERROR_PARSING_UNKNOWN, -+ TIXML_ERROR_PARSING_COMMENT, -+ TIXML_ERROR_PARSING_DECLARATION, -+ TIXML_ERROR_DOCUMENT_EMPTY, -+ TIXML_ERROR_EMBEDDED_NULL, -+ -+ TIXML_ERROR_STRING_COUNT -+ }; -+ static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; -+ -+ TiXmlCursor location; -+ -+ /// Field containing a generic user pointer -+ void* userData; -+ -+ // None of these methods are reliable for any language except English. -+ // Good for approximation, not great for accuracy. -+ static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); -+ static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); -+ inline static int ToLower( int v, TiXmlEncoding encoding ) -+ { -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ if ( v < 128 ) return tolower( v ); -+ return v; -+ } -+ else -+ { -+ return tolower( v ); -+ } -+ } -+ static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); -+ -+private: -+ TiXmlBase( const TiXmlBase& ); // not implemented. -+ void operator=( const TiXmlBase& base ); // not allowed. -+ -+ struct Entity -+ { -+ const char* str; -+ unsigned int strLength; -+ char chr; -+ }; -+ enum -+ { -+ NUM_ENTITY = 5, -+ MAX_ENTITY_LENGTH = 6 -+ -+ }; -+ static Entity entity[ NUM_ENTITY ]; -+ static bool condenseWhiteSpace; -+}; -+ -+ -+/** The parent class for everything in the Document Object Model. -+ (Except for attributes). -+ Nodes have siblings, a parent, and children. A node can be -+ in a document, or stand on its own. The type of a TiXmlNode -+ can be queried, and it can be cast to its more defined type. -+*/ -+class TiXmlNode : public TiXmlBase -+{ -+ friend class TiXmlDocument; -+ friend class TiXmlElement; -+ -+public: -+ #ifdef TIXML_USE_STL -+ -+ /** An input stream operator, for every class. Tolerant of newlines and -+ formatting, but doesn't expect them. -+ */ -+ friend std::istream& operator >> (std::istream& in, TiXmlNode& base); -+ -+ /** An output stream operator, for every class. Note that this outputs -+ without any newlines or formatting, as opposed to Print(), which -+ includes tabs and new lines. -+ -+ The operator<< and operator>> are not completely symmetric. Writing -+ a node to a stream is very well defined. You'll get a nice stream -+ of output, without any extra whitespace or newlines. -+ -+ But reading is not as well defined. (As it always is.) If you create -+ a TiXmlElement (for example) and read that from an input stream, -+ the text needs to define an element or junk will result. This is -+ true of all input streams, but it's worth keeping in mind. -+ -+ A TiXmlDocument will read nodes until it reads a root element, and -+ all the children of that root element. -+ */ -+ friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); -+ -+ /// Appends the XML node or attribute to a std::string. -+ friend std::string& operator<< (std::string& out, const TiXmlNode& base ); -+ -+ #else -+ // Used internally, not part of the public API. -+ friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base); -+ #endif -+ -+ /** The types of XML nodes supported by TinyXml. (All the -+ unsupported types are picked up by UNKNOWN.) -+ */ -+ enum NodeType -+ { -+ DOCUMENT, -+ ELEMENT, -+ COMMENT, -+ UNKNOWN, -+ TEXT, -+ DECLARATION, -+ TYPECOUNT -+ }; -+ -+ virtual ~TiXmlNode(); -+ -+ /** The meaning of 'value' changes for the specific type of -+ TiXmlNode. -+ @verbatim -+ Document: filename of the xml file -+ Element: name of the element -+ Comment: the comment text -+ Unknown: the tag contents -+ Text: the text string -+ @endverbatim -+ -+ The subclasses will wrap this function. -+ */ -+ const char * Value() const { return value.c_str (); } -+ -+ /** Changes the value of the node. Defined as: -+ @verbatim -+ Document: filename of the xml file -+ Element: name of the element -+ Comment: the comment text -+ Unknown: the tag contents -+ Text: the text string -+ @endverbatim -+ */ -+ void SetValue(const char * _value) { value = _value;} -+ -+ #ifdef TIXML_USE_STL -+ /// STL std::string form. -+ void SetValue( const std::string& _value ) -+ { -+ StringToBuffer buf( _value ); -+ SetValue( buf.buffer ? buf.buffer : "" ); -+ } -+ #endif -+ -+ /// Delete all the children of this node. Does not affect 'this'. -+ void Clear(); -+ -+ /// One step up the DOM. -+ TiXmlNode* Parent() const { return parent; } -+ -+ TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. -+ TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. -+ -+ TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. -+ TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. -+ -+ #ifdef TIXML_USE_STL -+ TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. -+ TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ /** An alternate way to walk the children of a node. -+ One way to iterate over nodes is: -+ @verbatim -+ for( child = parent->FirstChild(); child; child = child->NextSibling() ) -+ @endverbatim -+ -+ IterateChildren does the same thing with the syntax: -+ @verbatim -+ child = 0; -+ while( child = parent->IterateChildren( child ) ) -+ @endverbatim -+ -+ IterateChildren takes the previous child as input and finds -+ the next one. If the previous child is null, it returns the -+ first. IterateChildren will return null when done. -+ */ -+ TiXmlNode* IterateChildren( TiXmlNode* previous ) const; -+ -+ /// This flavor of IterateChildren searches for children with a particular 'value' -+ TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. -+ #endif -+ -+ /** Add a new node related to this. Adds a child past the LastChild. -+ Returns a pointer to the new object or NULL if an error occured. -+ */ -+ TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); -+ -+ -+ /** Add a new node related to this. Adds a child past the LastChild. -+ -+ NOTE: the node to be added is passed by pointer, and will be -+ henceforth owned (and deleted) by tinyXml. This method is efficient -+ and avoids an extra copy, but should be used with care as it -+ uses a different memory model than the other insert functions. -+ -+ @sa InsertEndChild -+ */ -+ TiXmlNode* LinkEndChild( TiXmlNode* addThis ); -+ -+ /** Add a new node related to this. Adds a child before the specified child. -+ Returns a pointer to the new object or NULL if an error occured. -+ */ -+ TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); -+ -+ /** Add a new node related to this. Adds a child after the specified child. -+ Returns a pointer to the new object or NULL if an error occured. -+ */ -+ TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); -+ -+ /** Replace a child of this node. -+ Returns a pointer to the new object or NULL if an error occured. -+ */ -+ TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); -+ -+ /// Delete a child of this node. -+ bool RemoveChild( TiXmlNode* removeThis ); -+ -+ /// Navigate to a sibling node. -+ TiXmlNode* PreviousSibling() const { return prev; } -+ -+ /// Navigate to a sibling node. -+ TiXmlNode* PreviousSibling( const char * ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. -+ TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ /// Navigate to a sibling node. -+ TiXmlNode* NextSibling() const { return next; } -+ -+ /// Navigate to a sibling node with the given 'value'. -+ TiXmlNode* NextSibling( const char * ) const; -+ -+ /** Convenience function to get through elements. -+ Calls NextSibling and ToElement. Will skip all non-Element -+ nodes. Returns 0 if there is not another element. -+ */ -+ TiXmlElement* NextSiblingElement() const; -+ -+ /** Convenience function to get through elements. -+ Calls NextSibling and ToElement. Will skip all non-Element -+ nodes. Returns 0 if there is not another element. -+ */ -+ TiXmlElement* NextSiblingElement( const char * ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ /// Convenience function to get through elements. -+ TiXmlElement* FirstChildElement() const; -+ -+ /// Convenience function to get through elements. -+ TiXmlElement* FirstChildElement( const char * value ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ /** Query the type (as an enumerated value, above) of this node. -+ The possible types are: DOCUMENT, ELEMENT, COMMENT, -+ UNKNOWN, TEXT, and DECLARATION. -+ */ -+ virtual int Type() const { return type; } -+ -+ /** Return a pointer to the Document this node lives in. -+ Returns null if not in a document. -+ */ -+ TiXmlDocument* GetDocument() const; -+ -+ /// Returns true if this node has no children. -+ bool NoChildren() const { return !firstChild; } -+ -+ TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlText* ToText() const { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ -+ /** Create an exact duplicate of this node and return it. The memory must be deleted -+ by the caller. -+ */ -+ virtual TiXmlNode* Clone() const = 0; -+ -+protected: -+ TiXmlNode( NodeType _type ); -+ -+ // Copy to the allocated object. Shared functionality between Clone, Copy constructor, -+ // and the assignment operator. -+ void CopyTo( TiXmlNode* target ) const; -+ -+ #ifdef TIXML_USE_STL -+ // The real work of the input operator. -+ virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0; -+ #endif -+ -+ // Figure out what is at *p, and parse it. Returns null if it is not an xml node. -+ TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); -+ -+ // Internal Value function returning a TIXML_STRING -+ const TIXML_STRING& SValue() const { return value ; } -+ -+ TiXmlNode* parent; -+ NodeType type; -+ -+ TiXmlNode* firstChild; -+ TiXmlNode* lastChild; -+ -+ TIXML_STRING value; -+ -+ TiXmlNode* prev; -+ TiXmlNode* next; -+ -+private: -+ TiXmlNode( const TiXmlNode& ); // not implemented. -+ void operator=( const TiXmlNode& base ); // not allowed. -+}; -+ -+ -+/** An attribute is a name-value pair. Elements have an arbitrary -+ number of attributes, each with a unique name. -+ -+ @note The attributes are not TiXmlNodes, since they are not -+ part of the tinyXML document object model. There are other -+ suggested ways to look at this problem. -+*/ -+class TiXmlAttribute : public TiXmlBase -+{ -+ friend class TiXmlAttributeSet; -+ -+public: -+ /// Construct an empty attribute. -+ TiXmlAttribute() : TiXmlBase() -+ { -+ document = 0; -+ prev = next = 0; -+ } -+ -+ #ifdef TIXML_USE_STL -+ /// std::string constructor. -+ TiXmlAttribute( const std::string& _name, const std::string& _value ) -+ { -+ name = _name; -+ value = _value; -+ document = 0; -+ prev = next = 0; -+ } -+ #endif -+ -+ /// Construct an attribute with a name and value. -+ TiXmlAttribute( const char * _name, const char * _value ) -+ { -+ name = _name; -+ value = _value; -+ document = 0; -+ prev = next = 0; -+ } -+ -+ const char* Name() const { return name.c_str (); } ///< Return the name of this attribute. -+ const char* Value() const { return value.c_str (); } ///< Return the value of this attribute. -+ const int IntValue() const; ///< Return the value of this attribute, converted to an integer. -+ const double DoubleValue() const; ///< Return the value of this attribute, converted to a double. -+ -+ /** QueryIntValue examines the value string. It is an alternative to the -+ IntValue() method with richer error checking. -+ If the value is an integer, it is stored in 'value' and -+ the call returns TIXML_SUCCESS. If it is not -+ an integer, it returns TIXML_WRONG_TYPE. -+ -+ A specialized but useful call. Note that for success it returns 0, -+ which is the opposite of almost all other TinyXml calls. -+ */ -+ int QueryIntValue( int* value ) const; -+ /// QueryDoubleValue examines the value string. See QueryIntValue(). -+ int QueryDoubleValue( double* value ) const; -+ -+ void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. -+ void SetValue( const char* _value ) { value = _value; } ///< Set the value. -+ -+ void SetIntValue( int value ); ///< Set the value from an integer. -+ void SetDoubleValue( double value ); ///< Set the value from a double. -+ -+ #ifdef TIXML_USE_STL -+ /// STL std::string form. -+ void SetName( const std::string& _name ) -+ { -+ StringToBuffer buf( _name ); -+ SetName ( buf.buffer ? buf.buffer : "error" ); -+ } -+ /// STL std::string form. -+ void SetValue( const std::string& _value ) -+ { -+ StringToBuffer buf( _value ); -+ SetValue( buf.buffer ? buf.buffer : "error" ); -+ } -+ #endif -+ -+ /// Get the next sibling attribute in the DOM. Returns null at end. -+ TiXmlAttribute* Next() const; -+ /// Get the previous sibling attribute in the DOM. Returns null at beginning. -+ TiXmlAttribute* Previous() const; -+ -+ bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } -+ bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } -+ bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } -+ -+ /* Attribute parsing starts: first letter of the name -+ returns: the next char after the value end quote -+ */ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+ // Prints this Attribute to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ virtual void StreamOut( TIXML_OSTREAM * out ) const; -+ // [internal use] -+ // Set the document pointer so the attribute can report errors. -+ void SetDocument( TiXmlDocument* doc ) { document = doc; } -+ -+private: -+ TiXmlAttribute( const TiXmlAttribute& ); // not implemented. -+ void operator=( const TiXmlAttribute& base ); // not allowed. -+ -+ TiXmlDocument* document; // A pointer back to a document, for error reporting. -+ TIXML_STRING name; -+ TIXML_STRING value; -+ TiXmlAttribute* prev; -+ TiXmlAttribute* next; -+}; -+ -+ -+/* A class used to manage a group of attributes. -+ It is only used internally, both by the ELEMENT and the DECLARATION. -+ -+ The set can be changed transparent to the Element and Declaration -+ classes that use it, but NOT transparent to the Attribute -+ which has to implement a next() and previous() method. Which makes -+ it a bit problematic and prevents the use of STL. -+ -+ This version is implemented with circular lists because: -+ - I like circular lists -+ - it demonstrates some independence from the (typical) doubly linked list. -+*/ -+class TiXmlAttributeSet -+{ -+public: -+ TiXmlAttributeSet(); -+ ~TiXmlAttributeSet(); -+ -+ void Add( TiXmlAttribute* attribute ); -+ void Remove( TiXmlAttribute* attribute ); -+ -+ TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } -+ TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } -+ TiXmlAttribute* Find( const char * name ) const; -+ -+private: -+ TiXmlAttribute sentinel; -+}; -+ -+ -+/** The element is a container class. It has a value, the element name, -+ and can contain other elements, text, comments, and unknowns. -+ Elements also contain an arbitrary number of attributes. -+*/ -+class TiXmlElement : public TiXmlNode -+{ -+public: -+ /// Construct an element. -+ TiXmlElement (const char * in_value); -+ -+ #ifdef TIXML_USE_STL -+ /// std::string constructor. -+ TiXmlElement( const std::string& _value ); -+ #endif -+ -+ TiXmlElement( const TiXmlElement& ); -+ -+ void operator=( const TiXmlElement& base ); -+ -+ virtual ~TiXmlElement(); -+ -+ /** Given an attribute name, Attribute() returns the value -+ for the attribute of that name, or null if none exists. -+ */ -+ const char* Attribute( const char* name ) const; -+ -+ /** Given an attribute name, Attribute() returns the value -+ for the attribute of that name, or null if none exists. -+ If the attribute exists and can be converted to an integer, -+ the integer value will be put in the return 'i', if 'i' -+ is non-null. -+ */ -+ const char* Attribute( const char* name, int* i ) const; -+ -+ /** Given an attribute name, Attribute() returns the value -+ for the attribute of that name, or null if none exists. -+ If the attribute exists and can be converted to an double, -+ the double value will be put in the return 'd', if 'd' -+ is non-null. -+ */ -+ const char* Attribute( const char* name, double* d ) const; -+ -+ /** QueryIntAttribute examines the attribute - it is an alternative to the -+ Attribute() method with richer error checking. -+ If the attribute is an integer, it is stored in 'value' and -+ the call returns TIXML_SUCCESS. If it is not -+ an integer, it returns TIXML_WRONG_TYPE. If the attribute -+ does not exist, then TIXML_NO_ATTRIBUTE is returned. -+ */ -+ int QueryIntAttribute( const char* name, int* value ) const; -+ /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). -+ int QueryDoubleAttribute( const char* name, double* value ) const; -+ -+ /** Sets an attribute of name to a given value. The attribute -+ will be created if it does not exist, or changed if it does. -+ */ -+ void SetAttribute( const char* name, const char * value ); -+ -+ #ifdef TIXML_USE_STL -+ const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); } -+ const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); } -+ const char* Attribute( const std::string& name, double* d ) const { return Attribute( name.c_str(), d ); } -+ int QueryIntAttribute( const std::string& name, int* value ) const { return QueryIntAttribute( name.c_str(), value ); } -+ int QueryDoubleAttribute( const std::string& name, double* value ) const { return QueryDoubleAttribute( name.c_str(), value ); } -+ -+ /// STL std::string form. -+ void SetAttribute( const std::string& name, const std::string& _value ) -+ { -+ StringToBuffer n( name ); -+ StringToBuffer v( _value ); -+ if ( n.buffer && v.buffer ) -+ SetAttribute (n.buffer, v.buffer ); -+ } -+ ///< STL std::string form. -+ void SetAttribute( const std::string& name, int _value ) -+ { -+ StringToBuffer n( name ); -+ if ( n.buffer ) -+ SetAttribute (n.buffer, _value); -+ } -+ #endif -+ -+ /** Sets an attribute of name to a given value. The attribute -+ will be created if it does not exist, or changed if it does. -+ */ -+ void SetAttribute( const char * name, int value ); -+ -+ /** Sets an attribute of name to a given value. The attribute -+ will be created if it does not exist, or changed if it does. -+ */ -+ void SetDoubleAttribute( const char * name, double value ); -+ -+ /** Deletes an attribute with the given name. -+ */ -+ void RemoveAttribute( const char * name ); -+ #ifdef TIXML_USE_STL -+ void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. -+ TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. -+ -+ /// Creates a new Element and returns it - the returned element is a copy. -+ virtual TiXmlNode* Clone() const; -+ // Print the Element to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ /* Attribtue parsing starts: next char past '<' -+ returns: next char past '>' -+ */ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected: -+ -+ void CopyTo( TiXmlElement* target ) const; -+ void ClearThis(); // like clear, but initializes 'this' object as well -+ -+ // Used to be public [internal use] -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ virtual void StreamOut( TIXML_OSTREAM * out ) const; -+ -+ /* [internal use] -+ Reads the "value" of the element -- another element, or text. -+ This should terminate with the current end tag. -+ */ -+ const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); -+ -+private: -+ -+ TiXmlAttributeSet attributeSet; -+}; -+ -+ -+/** An XML comment. -+*/ -+class TiXmlComment : public TiXmlNode -+{ -+public: -+ /// Constructs an empty comment. -+ TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} -+ TiXmlComment( const TiXmlComment& ); -+ void operator=( const TiXmlComment& base ); -+ -+ virtual ~TiXmlComment() {} -+ -+ /// Returns a copy of this Comment. -+ virtual TiXmlNode* Clone() const; -+ /// Write this Comment to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ /* Attribtue parsing starts: at the ! of the !-- -+ returns: next char past '>' -+ */ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected: -+ void CopyTo( TiXmlComment* target ) const; -+ -+ // used to be public -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ virtual void StreamOut( TIXML_OSTREAM * out ) const; -+ -+private: -+ -+}; -+ -+ -+/** XML text. Contained in an element. -+*/ -+class TiXmlText : public TiXmlNode -+{ -+ friend class TiXmlElement; -+public: -+ /// Constructor. -+ TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT) -+ { -+ SetValue( initValue ); -+ } -+ virtual ~TiXmlText() {} -+ -+ #ifdef TIXML_USE_STL -+ /// Constructor. -+ TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) -+ { -+ SetValue( initValue ); -+ } -+ #endif -+ -+ TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } -+ void operator=( const TiXmlText& base ) { base.CopyTo( this ); } -+ -+ /// Write this text object to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected : -+ /// [internal use] Creates a new Element and returns it. -+ virtual TiXmlNode* Clone() const; -+ void CopyTo( TiXmlText* target ) const; -+ -+ virtual void StreamOut ( TIXML_OSTREAM * out ) const; -+ bool Blank() const; // returns true if all white space and new lines -+ // [internal use] -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ -+private: -+}; -+ -+ -+/** In correct XML the declaration is the first entry in the file. -+ @verbatim -+ <?xml version="1.0" standalone="yes"?> -+ @endverbatim -+ -+ TinyXml will happily read or write files without a declaration, -+ however. There are 3 possible attributes to the declaration: -+ version, encoding, and standalone. -+ -+ Note: In this version of the code, the attributes are -+ handled as special cases, not generic attributes, simply -+ because there can only be at most 3 and they are always the same. -+*/ -+class TiXmlDeclaration : public TiXmlNode -+{ -+public: -+ /// Construct an empty declaration. -+ TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} -+ -+#ifdef TIXML_USE_STL -+ /// Constructor. -+ TiXmlDeclaration( const std::string& _version, -+ const std::string& _encoding, -+ const std::string& _standalone ); -+#endif -+ -+ /// Construct. -+ TiXmlDeclaration( const char* _version, -+ const char* _encoding, -+ const char* _standalone ); -+ -+ TiXmlDeclaration( const TiXmlDeclaration& copy ); -+ void operator=( const TiXmlDeclaration& copy ); -+ -+ virtual ~TiXmlDeclaration() {} -+ -+ /// Version. Will return an empty string if none was found. -+ const char *Version() const { return version.c_str (); } -+ /// Encoding. Will return an empty string if none was found. -+ const char *Encoding() const { return encoding.c_str (); } -+ /// Is this a standalone document? -+ const char *Standalone() const { return standalone.c_str (); } -+ -+ /// Creates a copy of this Declaration and returns it. -+ virtual TiXmlNode* Clone() const; -+ /// Print this declaration to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected: -+ void CopyTo( TiXmlDeclaration* target ) const; -+ // used to be public -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ virtual void StreamOut ( TIXML_OSTREAM * out) const; -+ -+private: -+ -+ TIXML_STRING version; -+ TIXML_STRING encoding; -+ TIXML_STRING standalone; -+}; -+ -+ -+/** Any tag that tinyXml doesn't recognize is saved as an -+ unknown. It is a tag of text, but should not be modified. -+ It will be written back to the XML, unchanged, when the file -+ is saved. -+ -+ DTD tags get thrown into TiXmlUnknowns. -+*/ -+class TiXmlUnknown : public TiXmlNode -+{ -+public: -+ TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} -+ virtual ~TiXmlUnknown() {} -+ -+ TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } -+ void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } -+ -+ /// Creates a copy of this Unknown and returns it. -+ virtual TiXmlNode* Clone() const; -+ /// Print this Unknown to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected: -+ void CopyTo( TiXmlUnknown* target ) const; -+ -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ virtual void StreamOut ( TIXML_OSTREAM * out ) const; -+ -+private: -+ -+}; -+ -+ -+/** Always the top level node. A document binds together all the -+ XML pieces. It can be saved, loaded, and printed to the screen. -+ The 'value' of a document node is the xml file name. -+*/ -+class TiXmlDocument : public TiXmlNode -+{ -+public: -+ /// Create an empty document, that has no name. -+ TiXmlDocument(); -+ /// Create a document with a name. The name of the document is also the filename of the xml. -+ TiXmlDocument( const char * documentName ); -+ -+ #ifdef TIXML_USE_STL -+ /// Constructor. -+ TiXmlDocument( const std::string& documentName ); -+ #endif -+ -+ TiXmlDocument( const TiXmlDocument& copy ); -+ void operator=( const TiXmlDocument& copy ); -+ -+ virtual ~TiXmlDocument() {} -+ -+ /** Load a file using the current document value. -+ Returns true if successful. Will delete any existing -+ document data before loading. -+ */ -+ bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); -+ /// Save a file using the current document value. Returns true if successful. -+ bool SaveFile() const; -+ /// Load a file using the given filename. Returns true if successful. -+ bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); -+ /// Save a file using the given filename. Returns true if successful. -+ bool SaveFile( const char * filename ) const; -+ -+ #ifdef TIXML_USE_STL -+ bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. -+ { -+ StringToBuffer f( filename ); -+ return ( f.buffer && LoadFile( f.buffer, encoding )); -+ } -+ bool SaveFile( const std::string& filename ) const ///< STL std::string version. -+ { -+ StringToBuffer f( filename ); -+ return ( f.buffer && SaveFile( f.buffer )); -+ } -+ #endif -+ -+ /** Parse the given null terminated block of xml data. Passing in an encoding to this -+ method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml -+ to use that encoding, regardless of what TinyXml might otherwise try to detect. -+ */ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); -+ -+ /** Get the root element -- the only top level element -- of the document. -+ In well formed XML, there should only be one. TinyXml is tolerant of -+ multiple elements at the document level. -+ */ -+ TiXmlElement* RootElement() const { return FirstChildElement(); } -+ -+ /** If an error occurs, Error will be set to true. Also, -+ - The ErrorId() will contain the integer identifier of the error (not generally useful) -+ - The ErrorDesc() method will return the name of the error. (very useful) -+ - The ErrorRow() and ErrorCol() will return the location of the error (if known) -+ */ -+ bool Error() const { return error; } -+ -+ /// Contains a textual (english) description of the error if one occurs. -+ const char * ErrorDesc() const { return errorDesc.c_str (); } -+ -+ /** Generally, you probably want the error string ( ErrorDesc() ). But if you -+ prefer the ErrorId, this function will fetch it. -+ */ -+ const int ErrorId() const { return errorId; } -+ -+ /** Returns the location (if known) of the error. The first column is column 1, -+ and the first row is row 1. A value of 0 means the row and column wasn't applicable -+ (memory errors, for example, have no row/column) or the parser lost the error. (An -+ error in the error reporting, in that case.) -+ -+ @sa SetTabSize, Row, Column -+ */ -+ int ErrorRow() { return errorLocation.row+1; } -+ int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() -+ -+ /** By calling this method, with a tab size -+ greater than 0, the row and column of each node and attribute is stored -+ when the file is loaded. Very useful for tracking the DOM back in to -+ the source file. -+ -+ The tab size is required for calculating the location of nodes. If not -+ set, the default of 4 is used. The tabsize is set per document. Setting -+ the tabsize to 0 disables row/column tracking. -+ -+ Note that row and column tracking is not supported when using operator>>. -+ -+ The tab size needs to be enabled before the parse or load. Correct usage: -+ @verbatim -+ TiXmlDocument doc; -+ doc.SetTabSize( 8 ); -+ doc.Load( "myfile.xml" ); -+ @endverbatim -+ -+ @sa Row, Column -+ */ -+ void SetTabSize( int _tabsize ) { tabsize = _tabsize; } -+ -+ int TabSize() const { return tabsize; } -+ -+ /** If you have handled the error, it can be reset with this call. The error -+ state is automatically cleared if you Parse a new XML block. -+ */ -+ void ClearError() { error = false; -+ errorId = 0; -+ errorDesc = ""; -+ errorLocation.row = errorLocation.col = 0; -+ //errorLocation.last = 0; -+ } -+ -+ /** Dump the document to standard out. */ -+ void Print() const { Print( stdout, 0 ); } -+ -+ /// Print this Document to a FILE stream. -+ virtual void Print( FILE* cfile, int depth = 0 ) const; -+ // [internal use] -+ void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); -+ -+protected : -+ virtual void StreamOut ( TIXML_OSTREAM * out) const; -+ // [internal use] -+ virtual TiXmlNode* Clone() const; -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ -+private: -+ void CopyTo( TiXmlDocument* target ) const; -+ -+ bool error; -+ int errorId; -+ TIXML_STRING errorDesc; -+ int tabsize; -+ TiXmlCursor errorLocation; -+}; -+ -+ -+/** -+ A TiXmlHandle is a class that wraps a node pointer with null checks; this is -+ an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml -+ DOM structure. It is a separate utility class. -+ -+ Take an example: -+ @verbatim -+ <Document> -+ <Element attributeA = "valueA"> -+ <Child attributeB = "value1" /> -+ <Child attributeB = "value2" /> -+ </Element> -+ <Document> -+ @endverbatim -+ -+ Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very -+ easy to write a *lot* of code that looks like: -+ -+ @verbatim -+ TiXmlElement* root = document.FirstChildElement( "Document" ); -+ if ( root ) -+ { -+ TiXmlElement* element = root->FirstChildElement( "Element" ); -+ if ( element ) -+ { -+ TiXmlElement* child = element->FirstChildElement( "Child" ); -+ if ( child ) -+ { -+ TiXmlElement* child2 = child->NextSiblingElement( "Child" ); -+ if ( child2 ) -+ { -+ // Finally do something useful. -+ @endverbatim -+ -+ And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity -+ of such code. A TiXmlHandle checks for null pointers so it is perfectly safe -+ and correct to use: -+ -+ @verbatim -+ TiXmlHandle docHandle( &document ); -+ TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element(); -+ if ( child2 ) -+ { -+ // do something useful -+ @endverbatim -+ -+ Which is MUCH more concise and useful. -+ -+ It is also safe to copy handles - internally they are nothing more than node pointers. -+ @verbatim -+ TiXmlHandle handleCopy = handle; -+ @endverbatim -+ -+ What they should not be used for is iteration: -+ -+ @verbatim -+ int i=0; -+ while ( true ) -+ { -+ TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element(); -+ if ( !child ) -+ break; -+ // do something -+ ++i; -+ } -+ @endverbatim -+ -+ It seems reasonable, but it is in fact two embedded while loops. The Child method is -+ a linear walk to find the element, so this code would iterate much more than it needs -+ to. Instead, prefer: -+ -+ @verbatim -+ TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element(); -+ -+ for( child; child; child=child->NextSiblingElement() ) -+ { -+ // do something -+ } -+ @endverbatim -+*/ -+class TiXmlHandle -+{ -+public: -+ /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. -+ TiXmlHandle( TiXmlNode* node ) { this->node = node; } -+ /// Copy constructor -+ TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } -+ TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } -+ -+ /// Return a handle to the first child node. -+ TiXmlHandle FirstChild() const; -+ /// Return a handle to the first child node with the given name. -+ TiXmlHandle FirstChild( const char * value ) const; -+ /// Return a handle to the first child element. -+ TiXmlHandle FirstChildElement() const; -+ /// Return a handle to the first child element with the given name. -+ TiXmlHandle FirstChildElement( const char * value ) const; -+ -+ /** Return a handle to the "index" child with the given name. -+ The first child is 0, the second 1, etc. -+ */ -+ TiXmlHandle Child( const char* value, int index ) const; -+ /** Return a handle to the "index" child. -+ The first child is 0, the second 1, etc. -+ */ -+ TiXmlHandle Child( int index ) const; -+ /** Return a handle to the "index" child element with the given name. -+ The first child element is 0, the second 1, etc. Note that only TiXmlElements -+ are indexed: other types are not counted. -+ */ -+ TiXmlHandle ChildElement( const char* value, int index ) const; -+ /** Return a handle to the "index" child element. -+ The first child element is 0, the second 1, etc. Note that only TiXmlElements -+ are indexed: other types are not counted. -+ */ -+ TiXmlHandle ChildElement( int index ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } -+ TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } -+ -+ TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } -+ TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } -+ #endif -+ -+ /// Return the handle as a TiXmlNode. This may return null. -+ TiXmlNode* Node() const { return node; } -+ /// Return the handle as a TiXmlElement. This may return null. -+ TiXmlElement* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } -+ /// Return the handle as a TiXmlText. This may return null. -+ TiXmlText* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } -+ /// Return the handle as a TiXmlUnknown. This may return null; -+ TiXmlUnknown* Unknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } -+ -+private: -+ TiXmlNode* node; -+}; -+ -+ -+#endif -+#endif /* SETUP */ -diff -ruNp vdr-1.7.0/tinyxmlparser.c vdr-1.7.0-extensions/tinyxmlparser.c ---- vdr-1.7.0/tinyxmlparser.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/tinyxmlparser.c 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,1494 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include "tinyxml.h" -+#include <ctype.h> -+ -+//#define DEBUG_PARSER -+ -+// Note tha "PutString" hardcodes the same list. This -+// is less flexible than it appears. Changing the entries -+// or order will break putstring. -+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = -+{ -+ { "&", 5, '&' }, -+ { "<", 4, '<' }, -+ { ">", 4, '>' }, -+ { """, 6, '\"' }, -+ { "'", 6, '\'' } -+}; -+ -+// Bunch of unicode info at: -+// http://www.unicode.org/faq/utf_bom.html -+// Including the basic of this table, which determines the #bytes in the -+// sequence from the lead byte. 1 placed for invalid sequences -- -+// although the result will be junk, pass it through as much as possible. -+// Beware of the non-characters in UTF-8: -+// ef bb bf (Microsoft "lead bytes") -+// ef bf be -+// ef bf bf -+ -+ -+ -+const int TiXmlBase::utf8ByteTable[256] = -+{ -+ // 0 1 2 3 4 5 6 7 8 9 a b c d e f -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 -+ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 -+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte -+ 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid -+}; -+ -+ -+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -+{ -+ const unsigned long BYTE_MASK = 0xBF; -+ const unsigned long BYTE_MARK = 0x80; -+ const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; -+ -+ if (input < 0x80) -+ *length = 1; -+ else if ( input < 0x800 ) -+ *length = 2; -+ else if ( input < 0x10000 ) -+ *length = 3; -+ else if ( input < 0x200000 ) -+ *length = 4; -+ else -+ { *length = 0; return; } // This code won't covert this correctly anyway. -+ -+ output += *length; -+ -+ // Scary scary fall throughs. -+ switch (*length) -+ { -+ case 4: -+ --output; -+ *output = (char)((input | BYTE_MARK) & BYTE_MASK); -+ input >>= 6; -+ case 3: -+ --output; -+ *output = (char)((input | BYTE_MARK) & BYTE_MASK); -+ input >>= 6; -+ case 2: -+ --output; -+ *output = (char)((input | BYTE_MARK) & BYTE_MASK); -+ input >>= 6; -+ case 1: -+ --output; -+ *output = (char)(input | FIRST_BYTE_MARK[*length]); -+ } -+} -+ -+ -+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ) -+{ -+ // This will only work for low-ascii, everything else is assumed to be a valid -+ // letter. I'm not sure this is the best approach, but it is quite tricky trying -+ // to figure out alhabetical vs. not across encoding. So take a very -+ // conservative approach. -+ -+// if ( encoding == TIXML_ENCODING_UTF8 ) -+// { -+ if ( anyByte < 127 ) -+ return isalpha( anyByte ); -+ else -+ return 1; // What else to do? The unicode set is huge...get the english ones right. -+// } -+// else -+// { -+// return isalpha( anyByte ); -+// } -+} -+ -+ -+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ) -+{ -+ // This will only work for low-ascii, everything else is assumed to be a valid -+ // letter. I'm not sure this is the best approach, but it is quite tricky trying -+ // to figure out alhabetical vs. not across encoding. So take a very -+ // conservative approach. -+ -+// if ( encoding == TIXML_ENCODING_UTF8 ) -+// { -+ if ( anyByte < 127 ) -+ return isalnum( anyByte ); -+ else -+ return 1; // What else to do? The unicode set is huge...get the english ones right. -+// } -+// else -+// { -+// return isalnum( anyByte ); -+// } -+} -+ -+ -+class TiXmlParsingData -+{ -+ friend class TiXmlDocument; -+ public: -+ void Stamp( const char* now, TiXmlEncoding encoding ); -+ -+ const TiXmlCursor& Cursor() { return cursor; } -+ -+ private: -+ // Only used by the document! -+ TiXmlParsingData( const char* start, int _tabsize, int row, int col ) -+ { -+ assert( start ); -+ stamp = start; -+ tabsize = _tabsize; -+ cursor.row = row; -+ cursor.col = col; -+ } -+ -+ TiXmlCursor cursor; -+ const char* stamp; -+ int tabsize; -+}; -+ -+ -+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) -+{ -+ assert( now ); -+ -+ // Do nothing if the tabsize is 0. -+ if ( tabsize < 1 ) -+ { -+ return; -+ } -+ -+ // Get the current row, column. -+ int row = cursor.row; -+ int col = cursor.col; -+ const char* p = stamp; -+ assert( p ); -+ -+ while ( p < now ) -+ { -+ // Code contributed by Fletcher Dunn: (modified by lee) -+ switch (*p) { -+ case 0: -+ // We *should* never get here, but in case we do, don't -+ // advance past the terminating null character, ever -+ return; -+ -+ case '\r': -+ // bump down to the next line -+ ++row; -+ col = 0; -+ // Eat the character -+ ++p; -+ -+ // Check for \r\n sequence, and treat this as a single character -+ if (*p == '\n') { -+ ++p; -+ } -+ break; -+ -+ case '\n': -+ // bump down to the next line -+ ++row; -+ col = 0; -+ -+ // Eat the character -+ ++p; -+ -+ // Check for \n\r sequence, and treat this as a single -+ // character. (Yes, this bizarre thing does occur still -+ // on some arcane platforms...) -+ if (*p == '\r') { -+ ++p; -+ } -+ break; -+ -+ case '\t': -+ // Eat the character -+ ++p; -+ -+ // Skip to next tab stop -+ col = (col / tabsize + 1) * tabsize; -+ break; -+ -+ case (char)(0xef): -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ if ( *(p+1) && *(p+2) ) -+ { -+ // In these cases, don't advance the column. These are -+ // 0-width spaces. -+ if ( *(p+1)==(char)(0xbb) && *(p+2)==(char)(0xbf) ) -+ p += 3; -+ else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbe) ) -+ p += 3; -+ else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbf) ) -+ p += 3; -+ else -+ { p +=3; ++col; } // A normal character. -+ } -+ } -+ else -+ { -+ ++p; -+ ++col; -+ } -+ break; -+ -+ default: -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ // Eat the 1 to 4 byte utf8 character. -+ int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)]; -+ if ( step == 0 ) -+ step = 1; // Error case from bad encoding, but handle gracefully. -+ p += step; -+ -+ // Just advance one column, of course. -+ ++col; -+ } -+ else -+ { -+ ++p; -+ ++col; -+ } -+ break; -+ } -+ } -+ cursor.row = row; -+ cursor.col = col; -+ assert( cursor.row >= -1 ); -+ assert( cursor.col >= -1 ); -+ stamp = p; -+ assert( stamp ); -+} -+ -+ -+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) -+{ -+ if ( !p || !*p ) -+ { -+ return 0; -+ } -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ while ( *p ) -+ { -+ // Skip the stupid Microsoft UTF-8 Byte order marks -+ if ( *(p+0)==(char) 0xef -+ && *(p+1)==(char) 0xbb -+ && *(p+2)==(char) 0xbf ) -+ { -+ p += 3; -+ continue; -+ } -+ else if(*(p+0)==(char) 0xef -+ && *(p+1)==(char) 0xbf -+ && *(p+2)==(char) 0xbe ) -+ { -+ p += 3; -+ continue; -+ } -+ else if(*(p+0)==(char) 0xef -+ && *(p+1)==(char) 0xbf -+ && *(p+2)==(char) 0xbf ) -+ { -+ p += 3; -+ continue; -+ } -+ -+ if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. -+ ++p; -+ else -+ break; -+ } -+ } -+ else -+ { -+ while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) -+ ++p; -+ } -+ -+ return p; -+} -+ -+#ifdef TIXML_USE_STL -+/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ for( ;; ) -+ { -+ if ( !in->good() ) return false; -+ -+ int c = in->peek(); -+ // At this scope, we can't get to a document. So fail silently. -+ if ( !IsWhiteSpace( c ) || c <= 0 ) -+ return true; -+ -+ *tag += (char) in->get(); -+ } -+} -+ -+/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ) -+{ -+ //assert( character > 0 && character < 128 ); // else it won't work in utf-8 -+ while ( in->good() ) -+ { -+ int c = in->peek(); -+ if ( c == character ) -+ return true; -+ if ( c <= 0 ) // Silent failure: can't get document at this scope -+ return false; -+ -+ in->get(); -+ *tag += (char) c; -+ } -+ return false; -+} -+#endif -+ -+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) -+{ -+ *name = ""; -+ assert( p ); -+ -+ // Names start with letters or underscores. -+ // Of course, in unicode, tinyxml has no idea what a letter *is*. The -+ // algorithm is generous. -+ // -+ // After that, they can be letters, underscores, numbers, -+ // hyphens, or colons. (Colons are valid ony for namespaces, -+ // but tinyxml can't tell namespaces from names.) -+ if ( p && *p -+ && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) -+ { -+ while( p && *p -+ && ( IsAlphaNum( (unsigned char ) *p, encoding ) -+ || *p == '_' -+ || *p == '-' -+ || *p == '.' -+ || *p == ':' ) ) -+ { -+ (*name) += *p; -+ ++p; -+ } -+ return p; -+ } -+ return 0; -+} -+ -+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) -+{ -+ // Presume an entity, and pull it out. -+ TIXML_STRING ent; -+ int i; -+ *length = 0; -+ -+ if ( *(p+1) && *(p+1) == '#' && *(p+2) ) -+ { -+ unsigned long ucs = 0; -+ unsigned delta = 0; -+ unsigned mult = 1; -+ -+ if ( *(p+2) == 'x' ) -+ { -+ // Hexadecimal. -+ if ( !*(p+3) ) return 0; -+ -+ const char* q = p+3; -+ q = strchr( q, ';' ); -+ -+ if ( !q || !*q ) return 0; -+ -+ delta = q-p; -+ --q; -+ -+ while ( *q != 'x' ) -+ { -+ if ( *q >= '0' && *q <= '9' ) -+ ucs += mult * (*q - '0'); -+ else if ( *q >= 'a' && *q <= 'f' ) -+ ucs += mult * (*q - 'a' + 10); -+ else if ( *q >= 'A' && *q <= 'F' ) -+ ucs += mult * (*q - 'A' + 10 ); -+ else -+ return 0; -+ mult *= 16; -+ --q; -+ } -+ } -+ else -+ { -+ // Decimal. -+ if ( !*(p+2) ) return 0; -+ -+ const char* q = p+2; -+ q = strchr( q, ';' ); -+ -+ if ( !q || !*q ) return 0; -+ -+ delta = q-p; -+ --q; -+ -+ while ( *q != '#' ) -+ { -+ if ( *q >= '0' && *q <= '9' ) -+ ucs += mult * (*q - '0'); -+ else -+ return 0; -+ mult *= 10; -+ --q; -+ } -+ } -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ // convert the UCS to UTF-8 -+ ConvertUTF32ToUTF8( ucs, value, length ); -+ } -+ else -+ { -+ *value = (char)ucs; -+ *length = 1; -+ } -+ return p + delta + 1; -+ } -+ -+ // Now try to match it. -+ for( i=0; i<NUM_ENTITY; ++i ) -+ { -+ if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 ) -+ { -+ assert( strlen( entity[i].str ) == entity[i].strLength ); -+ *value = entity[i].chr; -+ *length = 1; -+ return ( p + entity[i].strLength ); -+ } -+ } -+ -+ // So it wasn't an entity, its unrecognized, or something like that. -+ *value = *p; // Don't put back the last one, since we return it! -+ return p+1; -+} -+ -+ -+bool TiXmlBase::StringEqual( const char* p, -+ const char* tag, -+ bool ignoreCase, -+ TiXmlEncoding encoding ) -+{ -+ assert( p ); -+ assert( tag ); -+ if ( !p || !*p ) -+ { -+ assert( 0 ); -+ return false; -+ } -+ -+ const char* q = p; -+ -+ if ( ignoreCase ) -+ { -+ while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) ) -+ { -+ ++q; -+ ++tag; -+ } -+ -+ if ( *tag == 0 ) -+ return true; -+ } -+ else -+ { -+ while ( *q && *tag && *q == *tag ) -+ { -+ ++q; -+ ++tag; -+ } -+ -+ if ( *tag == 0 ) // Have we found the end of the tag, and everything equal? -+ return true; -+ } -+ return false; -+} -+ -+const char* TiXmlBase::ReadText( const char* p, -+ TIXML_STRING * text, -+ bool trimWhiteSpace, -+ const char* endTag, -+ bool caseInsensitive, -+ TiXmlEncoding encoding ) -+{ -+ *text = ""; -+ if ( !trimWhiteSpace // certain tags always keep whitespace -+ || !condenseWhiteSpace ) // if true, whitespace is always kept -+ { -+ // Keep all the white space. -+ while ( p && *p -+ && !StringEqual( p, endTag, caseInsensitive, encoding ) -+ ) -+ { -+ int len; -+ char cArr[4] = { 0, 0, 0, 0 }; -+ p = GetChar( p, cArr, &len, encoding ); -+ text->append( cArr, len ); -+ } -+ } -+ else -+ { -+ bool whitespace = false; -+ -+ // Remove leading white space: -+ p = SkipWhiteSpace( p, encoding ); -+ while ( p && *p -+ && !StringEqual( p, endTag, caseInsensitive, encoding ) ) -+ { -+ if ( *p == '\r' || *p == '\n' ) -+ { -+ whitespace = true; -+ ++p; -+ } -+ else if ( IsWhiteSpace( *p ) ) -+ { -+ whitespace = true; -+ ++p; -+ } -+ else -+ { -+ // If we've found whitespace, add it before the -+ // new character. Any whitespace just becomes a space. -+ if ( whitespace ) -+ { -+ (*text) += ' '; -+ whitespace = false; -+ } -+ int len; -+ char cArr[4] = { 0, 0, 0, 0 }; -+ p = GetChar( p, cArr, &len, encoding ); -+ if ( len == 1 ) -+ (*text) += cArr[0]; // more efficient -+ else -+ text->append( cArr, len ); -+ } -+ } -+ } -+ return p + strlen( endTag ); -+} -+ -+#ifdef TIXML_USE_STL -+ -+void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ // The basic issue with a document is that we don't know what we're -+ // streaming. Read something presumed to be a tag (and hope), then -+ // identify it, and call the appropriate stream method on the tag. -+ // -+ // This "pre-streaming" will never read the closing ">" so the -+ // sub-tag can orient itself. -+ -+ if ( !StreamTo( in, '<', tag ) ) -+ { -+ SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ -+ while ( in->good() ) -+ { -+ int tagIndex = (int) tag->length(); -+ while ( in->good() && in->peek() != '>' ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ break; -+ } -+ (*tag) += (char) c; -+ } -+ -+ if ( in->good() ) -+ { -+ // We now have something we presume to be a node of -+ // some sort. Identify it, and call the node to -+ // continue streaming. -+ TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); -+ -+ if ( node ) -+ { -+ node->StreamIn( in, tag ); -+ bool isElement = node->ToElement() != 0; -+ delete node; -+ node = 0; -+ -+ // If this is the root element, we're done. Parsing will be -+ // done by the >> operator. -+ if ( isElement ) -+ { -+ return; -+ } -+ } -+ else -+ { -+ SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ } -+ } -+ // We should have returned sooner. -+ SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); -+} -+ -+#endif -+ -+const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) -+{ -+ ClearError(); -+ -+ // Parse away, at the document level. Since a document -+ // contains nothing but other tags, most of what happens -+ // here is skipping white space. -+ if ( !p || !*p ) -+ { -+ SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return 0; -+ } -+ -+ // Note that, for a document, this needs to come -+ // before the while space skip, so that parsing -+ // starts from the pointer we are given. -+ location.Clear(); -+ if ( prevData ) -+ { -+ location.row = prevData->cursor.row; -+ location.col = prevData->cursor.col; -+ } -+ else -+ { -+ location.row = 0; -+ location.col = 0; -+ } -+ TiXmlParsingData data( p, TabSize(), location.row, location.col ); -+ location = data.Cursor(); -+ -+ if ( encoding == TIXML_ENCODING_UNKNOWN ) -+ { -+ // Check for the Microsoft UTF-8 lead bytes. -+ if ( *(p+0) && *(p+0) == (char)(0xef) -+ && *(p+1) && *(p+1) == (char)(0xbb) -+ && *(p+2) && *(p+2) == (char)(0xbf) ) -+ { -+ encoding = TIXML_ENCODING_UTF8; -+ } -+ } -+ -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p ) -+ { -+ SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return 0; -+ } -+ -+ while ( p && *p ) -+ { -+ TiXmlNode* node = Identify( p, encoding ); -+ if ( node ) -+ { -+ p = node->Parse( p, &data, encoding ); -+ LinkEndChild( node ); -+ } -+ else -+ { -+ break; -+ } -+ -+ // Did we get encoding info? -+ if ( encoding == TIXML_ENCODING_UNKNOWN -+ && node->ToDeclaration() ) -+ { -+ TiXmlDeclaration* dec = node->ToDeclaration(); -+ const char* enc = dec->Encoding(); -+ assert( enc ); -+ -+ if ( *enc == 0 ) -+ encoding = TIXML_ENCODING_UTF8; -+ else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) -+ encoding = TIXML_ENCODING_UTF8; -+ else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) -+ encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice -+ else -+ encoding = TIXML_ENCODING_LEGACY; -+ } -+ -+ p = SkipWhiteSpace( p, encoding ); -+ } -+ -+ // All is well. -+ return p; -+} -+ -+void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ // The first error in a chain is more accurate - don't set again! -+ if ( error ) -+ return; -+ -+ assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); -+ error = true; -+ errorId = err; -+ errorDesc = errorString[ errorId ]; -+ -+ errorLocation.Clear(); -+ if ( pError && data ) -+ { -+ //TiXmlParsingData data( pError, prevData ); -+ data->Stamp( pError, encoding ); -+ errorLocation = data->Cursor(); -+ } -+} -+ -+ -+TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) -+{ -+ TiXmlNode* returnNode = 0; -+ -+ p = SkipWhiteSpace( p, encoding ); -+ if( !p || !*p || *p != '<' ) -+ { -+ return 0; -+ } -+ -+ TiXmlDocument* doc = GetDocument(); -+ p = SkipWhiteSpace( p, encoding ); -+ -+ if ( !p || !*p ) -+ { -+ return 0; -+ } -+ -+ // What is this thing? -+ // - Elements start with a letter or underscore, but xml is reserved. -+ // - Comments: <!-- -+ // - Decleration: <?xml -+ // - Everthing else is unknown to tinyxml. -+ // -+ -+ const char* xmlHeader = { "<?xml" }; -+ const char* commentHeader = { "<!--" }; -+ const char* dtdHeader = { "<!" }; -+ -+ if ( StringEqual( p, xmlHeader, true, encoding ) ) -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Declaration\n" ); -+ #endif -+ returnNode = new TiXmlDeclaration(); -+ } -+ else if ( StringEqual( p, commentHeader, false, encoding ) ) -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Comment\n" ); -+ #endif -+ returnNode = new TiXmlComment(); -+ } -+ else if ( StringEqual( p, dtdHeader, false, encoding ) ) -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Unknown(1)\n" ); -+ #endif -+ returnNode = new TiXmlUnknown(); -+ } -+ else if ( IsAlpha( *(p+1), encoding ) -+ || *(p+1) == '_' ) -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Element\n" ); -+ #endif -+ returnNode = new TiXmlElement( "" ); -+ } -+ else -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Unknown(2)\n" ); -+ #endif -+ returnNode = new TiXmlUnknown(); -+ } -+ -+ if ( returnNode ) -+ { -+ // Set the parent, so it can report errors -+ returnNode->parent = this; -+ } -+ else -+ { -+ if ( doc ) -+ doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ } -+ return returnNode; -+} -+ -+#ifdef TIXML_USE_STL -+ -+void TiXmlElement::StreamIn (TIXML_ISTREAM * in, TIXML_STRING * tag) -+{ -+ // We're called with some amount of pre-parsing. That is, some of "this" -+ // element is in "tag". Go ahead and stream to the closing ">" -+ while( in->good() ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ (*tag) += (char) c ; -+ -+ if ( c == '>' ) -+ break; -+ } -+ -+ if ( tag->length() < 3 ) return; -+ -+ // Okay...if we are a "/>" tag, then we're done. We've read a complete tag. -+ // If not, identify and stream. -+ -+ if ( tag->at( tag->length() - 1 ) == '>' -+ && tag->at( tag->length() - 2 ) == '/' ) -+ { -+ // All good! -+ return; -+ } -+ else if ( tag->at( tag->length() - 1 ) == '>' ) -+ { -+ // There is more. Could be: -+ // text -+ // closing tag -+ // another node. -+ for ( ;; ) -+ { -+ StreamWhiteSpace( in, tag ); -+ -+ // Do we have text? -+ if ( in->good() && in->peek() != '<' ) -+ { -+ // Yep, text. -+ TiXmlText text( "" ); -+ text.StreamIn( in, tag ); -+ -+ // What follows text is a closing tag or another node. -+ // Go around again and figure it out. -+ continue; -+ } -+ -+ // We now have either a closing tag...or another node. -+ // We should be at a "<", regardless. -+ if ( !in->good() ) return; -+ assert( in->peek() == '<' ); -+ int tagIndex = tag->length(); -+ -+ bool closingTag = false; -+ bool firstCharFound = false; -+ -+ for( ;; ) -+ { -+ if ( !in->good() ) -+ return; -+ -+ int c = in->peek(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ -+ if ( c == '>' ) -+ break; -+ -+ *tag += (char) c; -+ in->get(); -+ -+ if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) ) -+ { -+ firstCharFound = true; -+ if ( c == '/' ) -+ closingTag = true; -+ } -+ } -+ // If it was a closing tag, then read in the closing '>' to clean up the input stream. -+ // If it was not, the streaming will be done by the tag. -+ if ( closingTag ) -+ { -+ if ( !in->good() ) -+ return; -+ -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ assert( c == '>' ); -+ *tag += (char) c; -+ -+ // We are done, once we've found our closing tag. -+ return; -+ } -+ else -+ { -+ // If not a closing tag, id it, and stream. -+ const char* tagloc = tag->c_str() + tagIndex; -+ TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING ); -+ if ( !node ) -+ return; -+ node->StreamIn( in, tag ); -+ delete node; -+ node = 0; -+ -+ // No return: go around from the beginning: text, closing tag, or node. -+ } -+ } -+ } -+} -+#endif -+ -+const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ p = SkipWhiteSpace( p, encoding ); -+ TiXmlDocument* document = GetDocument(); -+ -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding ); -+ return 0; -+ } -+ -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ -+ if ( *p != '<' ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding ); -+ return 0; -+ } -+ -+ p = SkipWhiteSpace( p+1, encoding ); -+ -+ // Read the name. -+ const char* pErr = p; -+ -+ p = ReadName( p, &value, encoding ); -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding ); -+ return 0; -+ } -+ -+ TIXML_STRING endTag ("</"); -+ endTag += value; -+ endTag += ">"; -+ -+ // Check for and read attributes. Also look for an empty -+ // tag or an end tag. -+ while ( p && *p ) -+ { -+ pErr = p; -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); -+ return 0; -+ } -+ if ( *p == '/' ) -+ { -+ ++p; -+ // Empty tag. -+ if ( *p != '>' ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding ); -+ return 0; -+ } -+ return (p+1); -+ } -+ else if ( *p == '>' ) -+ { -+ // Done with attributes (if there were any.) -+ // Read the value -- which can include other -+ // elements -- read the end tag, and return. -+ ++p; -+ p = ReadValue( p, data, encoding ); // Note this is an Element method, and will set the error if one happens. -+ if ( !p || !*p ) -+ return 0; -+ -+ // We should find the end tag now -+ if ( StringEqual( p, endTag.c_str(), false, encoding ) ) -+ { -+ p += endTag.length(); -+ return p; -+ } -+ else -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding ); -+ return 0; -+ } -+ } -+ else -+ { -+ // Try to read an attribute: -+ TiXmlAttribute* attrib = new TiXmlAttribute(); -+ if ( !attrib ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding ); -+ return 0; -+ } -+ -+ attrib->SetDocument( document ); -+ const char* pErr = p; -+ p = attrib->Parse( p, data, encoding ); -+ -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding ); -+ delete attrib; -+ return 0; -+ } -+ -+ // Handle the strange case of double attributes: -+ TiXmlAttribute* node = attributeSet.Find( attrib->Name() ); -+ if ( node ) -+ { -+ node->SetValue( attrib->Value() ); -+ delete attrib; -+ return 0; -+ } -+ -+ attributeSet.Add( attrib ); -+ } -+ } -+ return p; -+} -+ -+ -+const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ TiXmlDocument* document = GetDocument(); -+ -+ const char* pWithWhiteSpace = p; -+ // Read in text and elements in any order. -+ p = SkipWhiteSpace( p, encoding ); -+ while ( p && *p ) -+ { -+ if ( *p != '<' ) -+ { -+ // Take what we have, make a text element. -+ TiXmlText* textNode = new TiXmlText( "" ); -+ -+ if ( !textNode ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding ); -+ return 0; -+ } -+ -+ if ( TiXmlBase::IsWhiteSpaceCondensed() ) -+ { -+ p = textNode->Parse( p, data, encoding ); -+ } -+ else -+ { -+ // Special case: we want to keep the white space -+ // so that leading spaces aren't removed. -+ p = textNode->Parse( pWithWhiteSpace, data, encoding ); -+ } -+ -+ if ( !textNode->Blank() ) -+ LinkEndChild( textNode ); -+ else -+ delete textNode; -+ } -+ else -+ { -+ // We hit a '<' -+ // Have we hit a new element or an end tag? -+ if ( StringEqual( p, "</", false, encoding ) ) -+ { -+ return p; -+ } -+ else -+ { -+ TiXmlNode* node = Identify( p, encoding ); -+ if ( node ) -+ { -+ p = node->Parse( p, data, encoding ); -+ LinkEndChild( node ); -+ } -+ else -+ { -+ return 0; -+ } -+ } -+ } -+ p = SkipWhiteSpace( p, encoding ); -+ } -+ -+ if ( !p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding ); -+ } -+ return p; -+} -+ -+ -+#ifdef TIXML_USE_STL -+void TiXmlUnknown::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ while ( in->good() ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ (*tag) += (char) c; -+ -+ if ( c == '>' ) -+ { -+ // All is well. -+ return; -+ } -+ } -+} -+#endif -+ -+ -+const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ TiXmlDocument* document = GetDocument(); -+ p = SkipWhiteSpace( p, encoding ); -+ -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ if ( !p || !*p || *p != '<' ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding ); -+ return 0; -+ } -+ ++p; -+ value = ""; -+ -+ while ( p && *p && *p != '>' ) -+ { -+ value += *p; -+ ++p; -+ } -+ -+ if ( !p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding ); -+ } -+ if ( *p == '>' ) -+ return p+1; -+ return p; -+} -+ -+#ifdef TIXML_USE_STL -+void TiXmlComment::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ while ( in->good() ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ -+ (*tag) += (char) c; -+ -+ if ( c == '>' -+ && tag->at( tag->length() - 2 ) == '-' -+ && tag->at( tag->length() - 3 ) == '-' ) -+ { -+ // All is well. -+ return; -+ } -+ } -+} -+#endif -+ -+ -+const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ TiXmlDocument* document = GetDocument(); -+ value = ""; -+ -+ p = SkipWhiteSpace( p, encoding ); -+ -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ const char* startTag = "<!--"; -+ const char* endTag = "-->"; -+ -+ if ( !StringEqual( p, startTag, false, encoding ) ) -+ { -+ document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); -+ return 0; -+ } -+ p += strlen( startTag ); -+ p = ReadText( p, &value, false, endTag, false, encoding ); -+ return p; -+} -+ -+ -+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p || !*p ) return 0; -+ -+ int tabsize = 4; -+ if ( document ) -+ tabsize = document->TabSize(); -+ -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ // Read the name, the '=' and the value. -+ const char* pErr = p; -+ p = ReadName( p, &name, encoding ); -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); -+ return 0; -+ } -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p || !*p || *p != '=' ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); -+ return 0; -+ } -+ -+ ++p; // skip '=' -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); -+ return 0; -+ } -+ -+ const char* end; -+ -+ if ( *p == '\'' ) -+ { -+ ++p; -+ end = "\'"; -+ p = ReadText( p, &value, false, end, false, encoding ); -+ } -+ else if ( *p == '"' ) -+ { -+ ++p; -+ end = "\""; -+ p = ReadText( p, &value, false, end, false, encoding ); -+ } -+ else -+ { -+ // All attribute values should be in single or double quotes. -+ // But this is such a common error that the parser will try -+ // its best, even without them. -+ value = ""; -+ while ( p && *p // existence -+ && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace -+ && *p != '/' && *p != '>' ) // tag end -+ { -+ value += *p; -+ ++p; -+ } -+ } -+ return p; -+} -+ -+#ifdef TIXML_USE_STL -+void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ while ( in->good() ) -+ { -+ int c = in->peek(); -+ if ( c == '<' ) -+ return; -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ -+ (*tag) += (char) c; -+ in->get(); -+ } -+} -+#endif -+ -+const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ value = ""; -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ bool ignoreWhite = true; -+ -+ const char* end = "<"; -+ p = ReadText( p, &value, ignoreWhite, end, false, encoding ); -+ if ( p ) -+ return p-1; // don't truncate the '<' -+ return 0; -+} -+ -+#ifdef TIXML_USE_STL -+void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ while ( in->good() ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ (*tag) += (char) c; -+ -+ if ( c == '>' ) -+ { -+ // All is well. -+ return; -+ } -+ } -+} -+#endif -+ -+const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) -+{ -+ p = SkipWhiteSpace( p, _encoding ); -+ // Find the beginning, find the end, and look for -+ // the stuff in-between. -+ TiXmlDocument* document = GetDocument(); -+ if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); -+ return 0; -+ } -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, _encoding ); -+ location = data->Cursor(); -+ } -+ p += 5; -+ -+ version = ""; -+ encoding = ""; -+ standalone = ""; -+ -+ while ( p && *p ) -+ { -+ if ( *p == '>' ) -+ { -+ ++p; -+ return p; -+ } -+ -+ p = SkipWhiteSpace( p, _encoding ); -+ if ( StringEqual( p, "version", true, _encoding ) ) -+ { -+ TiXmlAttribute attrib; -+ p = attrib.Parse( p, data, _encoding ); -+ version = attrib.Value(); -+ } -+ else if ( StringEqual( p, "encoding", true, _encoding ) ) -+ { -+ TiXmlAttribute attrib; -+ p = attrib.Parse( p, data, _encoding ); -+ encoding = attrib.Value(); -+ } -+ else if ( StringEqual( p, "standalone", true, _encoding ) ) -+ { -+ TiXmlAttribute attrib; -+ p = attrib.Parse( p, data, _encoding ); -+ standalone = attrib.Value(); -+ } -+ else -+ { -+ // Read over whatever it is. -+ while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) -+ ++p; -+ } -+ } -+ return 0; -+} -+ -+bool TiXmlText::Blank() const -+{ -+ for ( unsigned i=0; i<value.length(); i++ ) -+ if ( !IsWhiteSpace( value[i] ) ) -+ return false; -+ return true; -+} -+#endif /* SETUP */ -diff -ruNp vdr-1.7.0/transfer.c vdr-1.7.0-extensions/transfer.c ---- vdr-1.7.0/transfer.c 2007-01-05 11:45:28.000000000 +0100 -+++ vdr-1.7.0-extensions/transfer.c 2009-04-09 20:48:48.000000000 +0200 -@@ -19,7 +19,11 @@ cTransfer::cTransfer(tChannelID ChannelI - ,cThread("transfer") - { - ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer"); -+#ifdef USE_SYNCEARLY -+ remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, false, Setup.UseSyncEarlyPatch); -+#else - remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids); -+#endif /* SYNCEARLY */ - } - - cTransfer::~cTransfer() -diff -ruNp vdr-1.7.0/transfer.h vdr-1.7.0-extensions/transfer.h ---- vdr-1.7.0/transfer.h 2007-01-05 11:45:45.000000000 +0100 -+++ vdr-1.7.0-extensions/transfer.h 2009-04-09 20:48:48.000000000 +0200 -@@ -30,6 +30,10 @@ public: - }; - - class cTransferControl : public cControl { -+#ifdef USE_LIVEBUFFER -+friend class cLiveBufferControl; -+friend class cLiveBufferManager; -+#endif /* LIVEBUFFER */ - private: - cTransfer *transfer; - static cDevice *receiverDevice; -diff -ruNp vdr-1.7.0/vdr.c vdr-1.7.0-extensions/vdr.c ---- vdr-1.7.0/vdr.c 2008-03-14 14:22:39.000000000 +0100 -+++ vdr-1.7.0-extensions/vdr.c 2009-04-09 20:48:48.000000000 +0200 -@@ -50,6 +50,9 @@ - #include "keys.h" - #include "libsi/si.h" - #include "lirc.h" -+#ifdef USE_LIVEBUFFER -+#include "livebuffer.h" -+#endif /* LIVEBUFFER */ - #include "menu.h" - #include "osdbase.h" - #include "plugin.h" -@@ -139,11 +142,18 @@ static bool SetKeepCaps(bool On) - return true; - } - -+#ifdef USE_SETTIME -+char *SetTime=NULL; -+#endif /* SETTIME */ -+ - static void SignalHandler(int signum) - { - isyslog("caught signal %d", signum); - switch (signum) { - case SIGPIPE: -+#ifdef USE_EM84XX -+ case SIGINT: -+#endif /* EM84XX */ - break; - case SIGHUP: - LastSignal = signum; -@@ -164,6 +174,10 @@ static void Watchdog(int signum) - exit(1); - } - -+#ifdef USE_CMDRECCMDI18N -+const char *ConfigDirectory = NULL; -+#endif /* CMDRECCMDI18N */ -+ - int main(int argc, char *argv[]) - { - // Save terminal settings: -@@ -188,8 +202,11 @@ int main(int argc, char *argv[]) - bool UserDump = false; - int SVDRPport = DEFAULTSVDRPPORT; - const char *AudioCommand = NULL; -+#ifndef USE_CMDRECCMDI18N - const char *ConfigDirectory = NULL; -+#endif /* CMDRECCMDI18N */ - const char *EpgDataFileName = DEFAULTEPGDATAFILENAME; -+ bool DisplayExtensions = false; - bool DisplayHelp = false; - bool DisplayVersion = false; - bool DaemonMode = false; -@@ -221,10 +238,14 @@ int main(int argc, char *argv[]) - - static struct option long_options[] = { - { "audio", required_argument, NULL, 'a' }, -+#ifdef USE_LIVEBUFFER -+ { "buffer", required_argument, NULL, 'b' }, -+#endif /* LIVEBUFFER */ - { "config", required_argument, NULL, 'c' }, - { "daemon", no_argument, NULL, 'd' }, - { "device", required_argument, NULL, 'D' }, - { "epgfile", required_argument, NULL, 'E' }, -+ { "extensions",no_argument, NULL, 'e' | 0x100 }, - { "grab", required_argument, NULL, 'g' }, - { "help", no_argument, NULL, 'h' }, - { "lib", required_argument, NULL, 'L' }, -@@ -239,6 +260,9 @@ int main(int argc, char *argv[]) - { "record", required_argument, NULL, 'r' }, - { "shutdown", required_argument, NULL, 's' }, - { "terminal", required_argument, NULL, 't' }, -+#ifdef USE_SETTIME -+ { "timeset", required_argument, NULL, 'T' }, -+#endif /* SETTIME */ - { "user", required_argument, NULL, 'u' }, - { "userdump", no_argument, NULL, 'u' | 0x100 }, - { "version", no_argument, NULL, 'V' }, -@@ -249,10 +273,28 @@ int main(int argc, char *argv[]) - }; - - int c; -+#ifdef USE_SETTIME -+#ifdef USE_LIVEBUFFER -+ while ((c = getopt_long(argc, argv, "a::b:c:dD:E:g:hl:L:mp:P:r:s:t:T:u:v:Vw:", long_options, NULL)) != -1) { -+#else -+ while ((c = getopt_long(argc, argv, "a:c:dD:E:g:hl:L:mp:P:r:s:t:T:u:v:Vw:", long_options, NULL)) != -1) { -+#endif /* LIVEBUFFER */ -+#else -+#ifdef USE_LIVEBUFFER -+ while ((c = getopt_long(argc, argv, "a::b:c:dD:E:g:hl:L:mp:P:r:s:t:u:v:Vw:", long_options, NULL)) != -1) { -+#else - while ((c = getopt_long(argc, argv, "a:c:dD:E:g:hl:L:mp:P:r:s:t:u:v:Vw:", long_options, NULL)) != -1) { -+#endif /* LIVEBUFFER */ -+#endif /* SETTIME */ - switch (c) { - case 'a': AudioCommand = optarg; - break; -+#ifdef USE_LIVEBUFFER -+ case 'b': BufferDirectory = optarg; -+ while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/') -+ optarg[strlen(optarg) - 1] = 0; -+ break; -+#endif /* LIVEBUFFER */ - case 'c': ConfigDirectory = optarg; - break; - case 'd': DaemonMode = true; break; -@@ -266,6 +308,9 @@ int main(int argc, char *argv[]) - fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg); - return 2; - break; -+ case 'e' | 0x100: -+ DisplayExtensions = true; -+ break; - case 'E': EpgDataFileName = (*optarg != '-' ? optarg : NULL); - break; - case 'g': cSVDRP::SetGrabImageDir(*optarg != '-' ? optarg : NULL); -@@ -337,6 +382,10 @@ int main(int argc, char *argv[]) - break; - case 's': ShutdownHandler.SetShutdownCommand(optarg); - break; -+#ifdef USE_SETTIME -+ case 'T': SetTime = strdup(optarg); -+ break; -+#endif /* SETTIME */ - case 't': Terminal = optarg; - if (access(Terminal, R_OK | W_OK) < 0) { - fprintf(stderr, "vdr: can't access terminal: %s\n", Terminal); -@@ -397,11 +446,16 @@ int main(int argc, char *argv[]) - if (DisplayHelp) { - printf("Usage: vdr [OPTIONS]\n\n" // for easier orientation, this is column 80| - " -a CMD, --audio=CMD send Dolby Digital audio to stdin of command CMD\n" -+#ifdef USE_LIVEBUFFER -+ " -b DIR, --buffer=DIR use DIR as LiveBuffer directory (default is to write\n" -+ " it to the video directory)\n" -+#endif /* LIVEBUFFER */ - " -c DIR, --config=DIR read config files from DIR (default: %s)\n" - " -d, --daemon run in daemon mode\n" - " -D NUM, --device=NUM use only the given DVB device (NUM = 0, 1, 2...)\n" - " there may be several -D options (default: all DVB\n" - " devices will be used)\n" -+ " --extensions print patchlevel and exit\n" - " -E FILE, --epgfile=FILE write the EPG data into the given FILE (default is\n" - " '%s' in the video directory)\n" - " '-E-' disables this\n" -@@ -432,6 +486,9 @@ int main(int argc, char *argv[]) - " -r CMD, --record=CMD call CMD before and after a recording\n" - " -s CMD, --shutdown=CMD call CMD to shutdown the computer\n" - " -t TTY, --terminal=TTY controlling tty\n" -+#ifdef USE_SETTIME -+ " -T CMD, --timeset=CMD call CMD to set the system time\n" -+#endif /* SETTIME */ - " -u USER, --user=USER run as user USER; only applicable if started as\n" - " root\n" - " --userdump allow coredumps if -u is given (debugging)\n" -@@ -475,6 +532,213 @@ int main(int argc, char *argv[]) - return 0; - } - -+ if (DisplayExtensions) { -+ printf("VDR %s\n", VDRVERSION); -+ printf("VDREXTENSIONS %d\n", VDREXTENSIONS); -+ -+#ifdef USE_ANALOGTV -+ printf(" ANALOGTV\n"); -+#endif /* ANALOGTV */ -+ -+#ifdef USE_ATSC -+ printf(" ATSC\n"); -+#endif /* ATSC */ -+ -+#ifdef USE_CHANNELSCAN -+ printf(" CHANNELSCAN\n"); -+#endif /* CHANNELSCAN */ -+ -+#ifdef USE_CMDRECCMDI18N -+ printf(" CMDRECCMDI18N\n"); -+#endif /* CMDRECCMDI18N */ -+ -+#ifdef USE_CMDSUBMENU -+ printf(" CMDSUBMENU %d\n", CMDSUBMENUVERSNUM); -+#endif /* CMDSUBMENU */ -+ -+#ifdef USE_CUTTERLIMIT -+ printf(" CUTTERLIMIT\n"); -+#endif /* CUTTERLIMIT */ -+ -+#ifdef USE_CUTTERQUEUE -+ printf(" CUTTERQUEUE\n"); -+#endif /* CUTTERQUEUE */ -+ -+#ifdef USE_CUTTIME -+ printf(" CUTTIME\n"); -+#endif /* CUTTIME */ -+ -+#ifdef USE_DDEPGENTRY -+ printf(" DDEPGENTRY\n"); -+#endif /* DDEPGENTRY */ -+ -+#ifdef USE_DELTIMESHIFTREC -+ printf(" DELTIMESHIFTREC\n"); -+#endif /* DELTIMESHIFTREC */ -+ -+#ifdef USE_DOLBYINREC -+ printf(" DOLBYINREC\n"); -+#endif /* DOLBYINREC */ -+ -+#ifdef USE_DVBPLAYER -+ printf(" DVBPLAYER\n"); -+#endif /* DVBPLAYER */ -+ -+#ifdef USE_DVBSETUP -+ printf(" DVBSETUP\n"); -+#endif /* DVBSETUP */ -+ -+#ifdef USE_DVDARCHIVE -+ printf(" DVDARCHIVE\n"); -+#endif /* DVDARCHIVE */ -+ -+#ifdef USE_DVDCHAPJUMP -+ printf(" DVDCHAPJUMP\n"); -+#endif /* DVDCHAPJUMP */ -+ -+#ifdef USE_DVLRECSCRIPTADDON -+ printf(" DVLRECSCRIPTADDON\n"); -+#endif /* DVLRECSCRIPTADDON */ -+ -+#ifdef USE_DVLVIDPREFER -+ printf(" DVLVIDPREFER\n"); -+#endif /* DVLVIDPREFER */ -+ -+#ifdef USE_DVLFRIENDLYFNAMES -+ printf(" DVLFRIENDLYFNAMES\n"); -+#endif /* DVLFRIENDLYFNAMES */ -+ -+#ifdef USE_EM84XX -+ printf(" EM84XX\n"); -+#endif /* EM84XX */ -+ -+#ifdef USE_GRAPHTFT -+ printf(" GRAPHTFT\n"); -+#endif /* GRAPHTFT */ -+ -+#ifdef USE_HARDLINKCUTTER -+ printf(" HARDLINKCUTTER\n"); -+#endif /* HARDLINKCUTTER */ -+ -+#ifdef USE_JUMPPLAY -+ printf(" JUMPPLAY %d\n", JUMPPLAYVERSNUM); -+#endif /* JUMPPLAY */ -+ -+#ifdef USE_LIEMIEXT -+ printf(" LIEMIEXT %d\n", LIEMIKUUTIO); -+#endif /* LIEMIEXT */ -+ -+#ifdef USE_LIRCSETTINGS -+ printf(" LIRCSETTINGS\n"); -+#endif /* LIRCSETTINGS */ -+ -+#ifdef USE_LIVEBUFFER -+ printf(" LIVEBUFFER\n"); -+#endif /* LIVEBUFFER */ -+ -+#ifdef USE_LNBSHARE -+ printf(" LNBSHARE\n"); -+#endif /* LNBSHARE */ -+ -+#ifdef USE_MAINMENUHOOKS -+ printf(" MAINMENUHOOKS %3.1f\n", MAINMENUHOOKSVERSNUM); -+#endif /* MAINMENUHOOKS */ -+ -+#ifdef USE_MENUORG -+ printf(" MENUORG\n"); -+#endif /* MENUORG */ -+ -+#ifdef USE_NOEPG -+ printf(" NOEPG\n"); -+#endif /* NOEPG */ -+ -+#ifdef USE_OSDMAXITEMS -+ printf(" OSDMAXITEMS\n"); -+#endif /* OSDMAXITEMS */ -+ -+#ifdef USE_PARENTALRATING -+ printf(" PARENTALRATING\n"); -+#endif /* PARENTALRATING */ -+ -+#ifdef USE_PINPLUGIN -+ printf(" PINPLUGIN %d\n", PIN_PLUGIN_PATCH); -+#endif /* PINPLUGIN */ -+ -+#ifdef USE_PLUGINAPI -+ printf(" PLUGINAPI\n"); -+#endif /* PLUGINAPI */ -+ -+#ifdef USE_PLUGINMISSING -+ printf(" PLUGINMISSING\n"); -+#endif /* PLUGINMISSING */ -+ -+#ifdef USE_PLUGINPARAM -+ printf(" PLUGINPARAM %d\n", PLUGINPARAMPATCHVERSNUM); -+#endif /* PLUGINPARAM */ -+ -+#ifdef USE_ROTOR -+ printf(" ROTOR\n"); -+#endif /* ROTOR */ -+ -+#ifdef USE_SETTIME -+ printf(" SETTIME\n"); -+#endif /* SETTIME */ -+ -+#ifdef USE_SETUP -+ printf(" SETUP\n"); -+#endif /* SETUP */ -+ -+#ifdef USE_SOFTOSD -+ printf(" SOFTOSD\n"); -+#endif /* SOFTOSD */ -+ -+#ifdef USE_SOURCECAPS -+ printf(" SOURCECAPS\n"); -+#endif /* SOURCECAPS */ -+ -+#ifdef USE_SORTRECORDS -+ printf(" SORTRECORDS\n"); -+#endif /* SORTRECORDS */ -+ -+#ifdef USE_STREAMDEVEXT -+ printf(" STREAMDEVEXT\n"); -+#endif /* STREAMDEVEXT */ -+ -+#ifdef USE_SYNCEARLY -+ printf(" SYNCEARLY\n"); -+#endif /* SYNCEARLY */ -+ -+#ifdef USE_TIMERCMD -+ printf(" TIMERCMD\n"); -+#endif /* TIMERCMD */ -+ -+#ifdef USE_TIMERINFO -+ printf(" TIMERINFO\n"); -+#endif /* TIMERINFO */ -+ -+#ifdef USE_TTXTSUBS -+ printf(" TTXTSUBS\n"); -+#endif /* TTXTSUBS*/ -+ -+#ifdef USE_VALIDINPUT -+ printf(" VALIDINPUT\n"); -+#endif /* VALIDINPUT */ -+ -+#ifdef USE_VOLCTRL -+ printf(" VOLCTRL\n"); -+#endif /* VOLCTRL */ -+ -+#ifdef USE_WAREAGLEICON -+ printf(" WAREAGLEICON\n"); -+#endif /* WAREAGLEICON */ -+ -+#ifdef USE_YAEPG -+ printf(" YAEPG\n"); -+#endif /* YAEPG */ -+ -+ return 0; -+ } -+ - // Log file: - - if (SysLogLevel > 0) -@@ -554,6 +818,11 @@ int main(int argc, char *argv[]) - if (!PluginManager.LoadPlugins(true)) - EXIT(2); - -+#ifdef USE_LIVEBUFFER -+ if (!BufferDirectory) -+ BufferDirectory = VideoDirectory; -+#endif /* LIVEBUFFER */ -+ - // Configuration data: - - if (!ConfigDirectory) -@@ -567,8 +836,20 @@ int main(int argc, char *argv[]) - Diseqcs.Load(AddDirectory(ConfigDirectory, "diseqc.conf"), true, Setup.DiSEqC) && - Channels.Load(AddDirectory(ConfigDirectory, "channels.conf"), false, true) && - Timers.Load(AddDirectory(ConfigDirectory, "timers.conf")) && -+#ifdef USE_CMDRECCMDI18N -+ LoadCommandsI18n(Commands,AddDirectory(ConfigDirectory, "commands.conf"), true) && -+ LoadCommandsI18n(RecordingCommands, AddDirectory(ConfigDirectory, "reccmds.conf"), true) && -+#else - Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"), true) && - RecordingCommands.Load(AddDirectory(ConfigDirectory, "reccmds.conf"), true) && -+#endif /* CMDRECCMDI18N */ -+#ifdef USE_TIMERCMD -+#ifdef USE_CMDRECCMDI18N -+ LoadCommandsI18n(TimerCommands, AddDirectory(ConfigDirectory, "timercmds.conf"), true) && -+#else -+ TimerCommands.Load(AddDirectory(ConfigDirectory, "timercmds.conf"), true) && -+#endif /* CMDRECCMDI18N */ -+#endif /* TIMERCMD */ - SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true) && - Keys.Load(AddDirectory(ConfigDirectory, "remote.conf")) && - KeyMacros.Load(AddDirectory(ConfigDirectory, "keymacros.conf"), true) -@@ -731,7 +1012,11 @@ int main(int argc, char *argv[]) - // Make sure we have a visible programme in case device usage has changed: - if (!EITScanner.Active() && cDevice::PrimaryDevice()->HasDecoder() && !cDevice::PrimaryDevice()->HasProgramme()) { - static time_t lastTime = 0; -+#ifdef USE_CHANNELSCAN -+ if (!scanning_on_receiving_device && (!Menu || CheckHasProgramme) && Now - lastTime > MINCHANNELWAIT) { -+#else - if ((!Menu || CheckHasProgramme) && Now - lastTime > MINCHANNELWAIT) { // !Menu to avoid interfering with the CAM if a CAM menu is open -+#endif /* CHANNELSCAN */ - cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel()); - if (Channel && (Channel->Vpid() || Channel->Apid(0))) { - if (!Channels.SwitchTo(cDevice::CurrentChannel()) // try to switch to the original channel... -@@ -787,8 +1072,17 @@ int main(int argc, char *argv[]) - } - // Channel display: - if (!EITScanner.Active() && cDevice::CurrentChannel() != LastChannel) { -+#ifdef USE_LIVEBUFFER -+ if (!Menu) { -+ if (cControl::Control(true)) -+ cControl::Control(true)->Hide(); -+#else - if (!Menu) -+#endif /* LIVEBUFFER */ - Menu = new cDisplayChannel(cDevice::CurrentChannel(), LastChannel >= 0); -+#ifdef USE_LIVEBUFFER -+ } -+#endif /* LIVEBUFFER */ - LastChannel = cDevice::CurrentChannel(); - LastChannelChanged = Now; - } -@@ -903,9 +1197,19 @@ int main(int argc, char *argv[]) - if (!Skins.IsOpen()) - Skins.ProcessQueuedMessages(); - // User Input: -+#ifdef USE_LIVEBUFFER -+ cOsdObject *Interact = Menu ? Menu : cControl::Control(true); -+#else - cOsdObject *Interact = Menu ? Menu : cControl::Control(); -+#endif /* LIVEBUFFER */ - eKeys key = Interface->GetKey(!Interact || !Interact->NeedsFastResponse()); -+#ifdef USE_LIVEBUFFER -+ Interact = Menu ? Menu : cControl::Control(); -+#endif /* LIVEBUFFER */ - if (ISREALKEY(key)) { -+#ifdef USE_PINPLUGIN -+ cStatus::MsgUserAction(key, Interact); -+#endif /* PINPLUGIN */ - EITScanner.Activity(); - // Cancel shutdown countdown: - if (ShutdownHandler.countdown) -@@ -922,9 +1226,17 @@ int main(int argc, char *argv[]) - bool WasMenu = Interact && Interact->IsMenu(); - if (Menu) - DELETE_MENU; -+#ifdef USE_LIVEBUFFER -+ else if (cControl::Control(true)) { -+#else - else if (cControl::Control()) { -+#endif /* LIVEBUFFER */ - if (cOsd::IsOpen()) -+#ifdef USE_LIVEBUFFER -+ cControl::Control(true)->Hide(); -+#else - cControl::Control()->Hide(); -+#endif /* LIVEBUFFER */ - else - WasOpen = false; - } -@@ -957,12 +1269,21 @@ int main(int argc, char *argv[]) - } - break; - // Direct main menu functions: -+#ifdef USE_LIVEBUFFER -+ #define DirectMainFunction(function)\ -+ DELETE_MENU;\ -+ if (cControl::Control(true))\ -+ cControl::Control(true)->Hide();\ -+ Menu = new cMenuMain(function);\ -+ key = kNone; // nobody else needs to see this key -+#else - #define DirectMainFunction(function)\ - DELETE_MENU;\ - if (cControl::Control())\ - cControl::Control()->Hide();\ - Menu = new cMenuMain(function);\ - key = kNone; // nobody else needs to see this key -+#endif /* LIVEBUFFER */ - case kSchedule: DirectMainFunction(osSchedule); break; - case kChannels: DirectMainFunction(osChannels); break; - case kTimers: DirectMainFunction(osTimers); break; -@@ -974,14 +1295,25 @@ int main(int argc, char *argv[]) - const char *PluginName = cRemote::GetPlugin(); - if (PluginName) { - DELETE_MENU; -+#ifdef USE_LIVEBUFFER -+ if (cControl::Control(true)) -+ cControl::Control(true)->Hide(); -+#else - if (cControl::Control()) - cControl::Control()->Hide(); -+#endif /* LIVEBUFFER */ - cPlugin *plugin = cPluginManager::GetPlugin(PluginName); - if (plugin) { -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgPluginProtected(plugin)) { -+#endif /* PINPLUGIN */ - Menu = plugin->MainMenuAction(); - if (Menu) - Menu->Show(); - } -+#ifdef USE_PINPLUGIN -+ } -+#endif /* PINPLUGIN */ - else - esyslog("ERROR: unknown plugin '%s'", PluginName); - } -@@ -993,8 +1325,17 @@ int main(int argc, char *argv[]) - case kChanUp: - case kChanDn|k_Repeat: - case kChanDn: -+#ifdef USE_LIVEBUFFER -+ if (!Interact) { -+ if (cControl::Control(true)) -+ cControl::Control(true)->Hide(); -+#else - if (!Interact) -+#endif /* LIVEBUFFER */ - Menu = new cDisplayChannel(NORMALKEY(key)); -+#ifdef USE_LIVEBUFFER -+ } -+#endif /* LIVEBUFFER */ - else if (cDisplayChannel::IsOpen() || cControl::Control()) { - Interact->ProcessKey(key); - continue; -@@ -1024,8 +1365,13 @@ int main(int argc, char *argv[]) - break; - // Audio track control: - case kAudio: -+#ifdef USE_LIVEBUFFER -+ if (cControl::Control(true)) -+ cControl::Control(true)->Hide(); -+#else - if (cControl::Control()) - cControl::Control()->Hide(); -+#endif /* LIVEBUFFER */ - if (!cDisplayTracks::IsOpen()) { - DELETE_MENU; - Menu = cDisplayTracks::Create(); -@@ -1048,7 +1394,11 @@ int main(int argc, char *argv[]) - break; - // Pausing live video: - case kPause: -+#ifdef USE_LIVEBUFFER -+ if (!cControl::Control() && !cLiveBufferManager::GetLiveBufferControl()) { -+#else - if (!cControl::Control()) { -+#endif /* LIVEBUFFER */ - DELETE_MENU; - if (!cRecordControls::PauseLiveVideo()) - Skins.Message(mtError, tr("No free DVB device to record!")); -@@ -1057,9 +1407,20 @@ int main(int argc, char *argv[]) - break; - // Instant recording: - case kRecord: -+#ifdef USE_LIVEBUFFER -+ if (!cControl::Control() && !cLiveBufferManager::GetLiveBufferControl()) { -+#else - if (!cControl::Control()) { -+#endif /* LIVEBUFFER */ -+#ifdef USE_STREAMDEVEXT -+ if (cRecordControls::Start()) { -+ Skins.Message(mtInfo, tr("Recording started")); -+ cStatus::MsgRecordingChange(NULL, scAdd); -+ } -+#else - if (cRecordControls::Start()) - Skins.Message(mtInfo, tr("Recording started")); -+#endif /* STREAMDEVEXT */ - key = kNone; // nobody else needs to see this key - } - break; -@@ -1109,14 +1470,42 @@ int main(int argc, char *argv[]) - state = osEnd; - } - switch (state) { -+#ifdef USE_LIVEBUFFER -+ case osPause: if (cLiveBufferManager::GetLiveBufferControl()) { -+ DELETE_MENU; -+ if (cControl::Control(true)) { -+ cControl::Control(true)->ProcessKey(kPlay); -+ cControl::Control(true)->ProcessKey(kPause); -+ } -+ break; -+ } -+ DELETE_MENU; -+#else - case osPause: DELETE_MENU; -+#endif /* LIVEBUFFER */ - cControl::Shutdown(); // just in case - if (!cRecordControls::PauseLiveVideo()) - Skins.Message(mtError, tr("No free DVB device to record!")); - break; -+#ifdef USE_LIVEBUFFER -+ case osRecord: if (cLiveBufferManager::GetLiveBufferControl()) { -+ if (cControl::Control(true)) -+ cControl::Control(true)->ProcessKey(kRecord); -+ break; -+ } -+ DELETE_MENU; -+#else - case osRecord: DELETE_MENU; -+#endif /* LIVEBUFFER */ -+#ifdef USE_STREAMDEVEXT -+ if (cRecordControls::Start()) { -+ Skins.Message(mtInfo, tr("Recording started")); -+ cStatus::MsgRecordingChange(NULL, scAdd); -+ } -+#else - if (cRecordControls::Start()) - Skins.Message(mtInfo, tr("Recording started")); -+#endif /* STREAMDEVEXT */ - break; - case osRecordings: - DELETE_MENU; -@@ -1153,6 +1542,12 @@ int main(int argc, char *argv[]) - } - } - else { -+#ifdef USE_LIVEBUFFER -+ eOSState state = osUnknown; -+ if (cLiveBufferManager::GetLiveBufferControl()) -+ state = cLiveBufferManager::GetLiveBufferControl()->ProcessKey(key); -+ if (state == osUnknown) { -+#endif /* LIVEBUFFER */ - // Key functions in "normal" viewing mode: - if (key != kNone && KeyMacros.Get(key)) { - cRemote::PutMacro(key); -@@ -1167,13 +1562,26 @@ int main(int argc, char *argv[]) - Channels.SwitchTo(PreviousChannel[PreviousChannelIndex ^= 1]); - break; - } -+#ifdef USE_VOLCTRL -+ // Left/Right volume control -+#else - // Direct Channel Select: - case k1 ... k9: - // Left/Right rotates through channel groups: -+#endif /* VOLCTRL */ - case kLeft|k_Repeat: - case kLeft: - case kRight|k_Repeat: - case kRight: -+#ifdef USE_VOLCTRL -+ if (Setup.LRVolumeControl && Setup.LRChannelGroups < 2) { -+ cRemote::Put(NORMALKEY(key) == kLeft ? kVolDn : kVolUp, true); -+ break; -+ } -+ // else fall through -+ // Direct Channel Select: -+ case k1 ... k9: -+#endif /* VOLCTRL */ - // Previous/Next rotates through channel groups: - case kPrev|k_Repeat: - case kPrev: -@@ -1184,6 +1592,10 @@ int main(int argc, char *argv[]) - case kUp: - case kDown|k_Repeat: - case kDown: -+#ifdef USE_LIVEBUFFER -+ if (cControl::Control(true)) -+ cControl::Control(true)->Hide(); -+#endif /* LIVEBUFFER */ - Menu = new cDisplayChannel(NORMALKEY(key)); - break; - // Viewing Control: -@@ -1191,13 +1603,22 @@ int main(int argc, char *argv[]) - // Instant resume of the last viewed recording: - case kPlay: - if (cReplayControl::LastReplayed()) { -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgReplayProtected(0, cReplayControl::LastReplayed(), 0, false) == false) { -+#endif /* PINPLUGIN */ - cControl::Shutdown(); - cControl::Launch(new cReplayControl); - } -+#ifdef USE_PINPLUGIN -+ } -+#endif /* PINPLUGIN */ - break; - default: break; - } - } -+#ifdef USE_LIVEBUFFER -+ } -+#endif /* LIVEBUFFER */ - if (!Menu) { - if (!InhibitEpgScan) - EITScanner.Process(); -@@ -1267,6 +1688,9 @@ Exit: - signal(SIGPIPE, SIG_DFL); - signal(SIGALRM, SIG_DFL); - -+#ifdef USE_LIVEBUFFER -+ cLiveBufferManager::Shutdown(); -+#endif /* LIVEBUFFER */ - PluginManager.StopPlugins(); - cRecordControls::Shutdown(); - cCutter::Stop(); -diff -ruNp vdr-1.7.0/vdrttxtsubshooks.c vdr-1.7.0-extensions/vdrttxtsubshooks.c ---- vdr-1.7.0/vdrttxtsubshooks.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/vdrttxtsubshooks.c 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,46 @@ -+#ifdef USE_TTXTSUBS -+ -+#include <stdlib.h> -+#include <stdio.h> -+#include <stdint.h> -+ -+#include "vdrttxtsubshooks.h" -+ -+// XXX Really should be a list... -+static cVDRTtxtsubsHookListener *gListener; -+ -+// ------ class cVDRTtxtsubsHookProxy ------ -+ -+class cVDRTtxtsubsHookProxy : public cVDRTtxtsubsHookListener -+{ -+ public: -+ virtual void HideOSD(void) { if(gListener) gListener->HideOSD(); }; -+ virtual void ShowOSD(void) { if(gListener) gListener->ShowOSD(); }; -+ virtual void PlayerTeletextData(uint8_t *p, int length) -+ { if(gListener) gListener->PlayerTeletextData(p, length); }; -+ virtual cTtxtSubsRecorderBase *NewTtxtSubsRecorder(cDevice *dev, const cChannel *ch) -+ { if(gListener) return gListener->NewTtxtSubsRecorder(dev, ch); else return NULL; }; -+}; -+ -+ -+// ------ class cVDRTtxtsubsHookListener ------ -+ -+cVDRTtxtsubsHookListener::~cVDRTtxtsubsHookListener() -+{ -+ gListener = 0; -+} -+ -+void cVDRTtxtsubsHookListener::HookAttach(void) -+{ -+ gListener = this; -+ //printf("cVDRTtxtsubsHookListener::HookAttach\n"); -+} -+ -+static cVDRTtxtsubsHookProxy gProxy; -+ -+cVDRTtxtsubsHookListener *cVDRTtxtsubsHookListener::Hook(void) -+{ -+ return &gProxy; -+} -+ -+#endif /* TTXTSUBS */ -diff -ruNp vdr-1.7.0/vdrttxtsubshooks.h vdr-1.7.0-extensions/vdrttxtsubshooks.h ---- vdr-1.7.0/vdrttxtsubshooks.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.0-extensions/vdrttxtsubshooks.h 2009-04-09 20:48:48.000000000 +0200 -@@ -0,0 +1,38 @@ -+#ifdef USE_TTXTSUBS -+ -+#ifndef __VDRTTXTSUBSHOOKS_H -+#define __VDRTTXTSUBSHOOKS_H -+ -+class cDevice; -+class cChannel; -+ -+#define VDRTTXTSUBSHOOKS -+ -+class cTtxtSubsRecorderBase { -+ public: -+ virtual ~cTtxtSubsRecorderBase() {}; -+ -+ // returns a PES packet if there is data to add to the recording -+ virtual uint8_t *GetPacket(uint8_t **buf, size_t *len) { return NULL; }; -+ virtual void DeviceAttach(void) {}; -+}; -+ -+class cVDRTtxtsubsHookListener { -+ public: -+ cVDRTtxtsubsHookListener(void) {}; -+ virtual ~cVDRTtxtsubsHookListener(); -+ -+ void HookAttach(void); -+ -+ virtual void HideOSD(void) {}; -+ virtual void ShowOSD(void) {}; -+ virtual void PlayerTeletextData(uint8_t *p, int length) {}; -+ virtual cTtxtSubsRecorderBase *NewTtxtSubsRecorder(cDevice *dev, const cChannel *ch) -+ { return NULL; }; -+ -+ // used by VDR to call hook listeners -+ static cVDRTtxtsubsHookListener *Hook(void); -+}; -+ -+#endif /* __VDRTTXTSUBSHOOKS_H */ -+#endif /* TTXTSUBS */ -diff -ruNp vdr-1.7.0/videodir.c vdr-1.7.0-extensions/videodir.c ---- vdr-1.7.0/videodir.c 2008-02-16 14:00:03.000000000 +0100 -+++ vdr-1.7.0-extensions/videodir.c 2009-04-09 20:48:48.000000000 +0200 -@@ -19,7 +19,17 @@ - #include "recording.h" - #include "tools.h" - -+#ifdef USE_HARDLINKCUTTER -+//#define HARDLINK_TEST_ONLY -+#ifdef USE_STREAMDEVEXT -+#include "status.h" -+#endif /* STREAMDEVEXT */ -+#endif /* HARDLINKCUTTER */ -+ - const char *VideoDirectory = VIDEODIR; -+#ifdef USE_LIVEBUFFER -+const char *BufferDirectory = NULL; -+#endif /* LIVEBUFFER */ - - class cVideoDirectory { - private: -@@ -36,6 +46,11 @@ public: - bool Next(void); - void Store(void); - const char *Adjust(const char *FileName); -+#ifdef USE_DVLVIDPREFER -+ char *GetVidPath(int nVid); -+ bool GetPreferedVideoDir(void); -+ bool IsVidDirOK(int nVid, int *freeMB = NULL); -+#endif /* DVLVIDPREFER */ - }; - - cVideoDirectory::cVideoDirectory(void) -@@ -117,6 +132,9 @@ cUnbufferedFile *OpenVideoFile(const cha - if ((Flags & O_CREAT) != 0) { - cVideoDirectory Dir; - if (Dir.IsDistributed()) { -+#ifdef USE_DVLVIDPREFER -+ if (Setup.UseVidPrefer == 0) { -+#endif /* DVLVIDPREFER */ - // Find the directory with the most free space: - int MaxFree = Dir.FreeMB(); - while (Dir.Next()) { -@@ -126,14 +144,24 @@ cUnbufferedFile *OpenVideoFile(const cha - MaxFree = Free; - } - } -+#ifdef USE_DVLVIDPREFER -+ } -+ else Dir.GetPreferedVideoDir(); -+#endif /* DVLVIDPREFER */ - if (Dir.Stored()) { - ActualFileName = Dir.Adjust(FileName); - if (!MakeDirs(ActualFileName, false)) - return NULL; // errno has been set by MakeDirs() -+#ifdef USE_DVLVIDPREFER -+ if (strcmp(ActualFileName, FileName) != 0) { -+#endif /* DVLVIDPREFER */ - if (symlink(ActualFileName, FileName) < 0) { - LOG_ERROR_STR(FileName); - return NULL; - } -+#ifdef USE_DVLVIDPREFER -+ } -+#endif /* DVLVIDPREFER */ - ActualFileName = strdup(ActualFileName); // must survive Dir! - } - } -@@ -168,6 +196,125 @@ bool RemoveVideoFile(const char *FileNam - return RemoveFileOrDir(FileName, true); - } - -+#ifdef USE_HARDLINKCUTTER -+static bool StatNearestDir(const char *FileName, struct stat *Stat) -+{ -+ cString Name(FileName); -+ char *p; -+ while ((p = strrchr((const char*)Name + 1, '/')) != NULL) { -+ *p = 0; // truncate at last '/' -+ if (stat(Name, Stat) == 0) { -+ isyslog("StatNearestDir: Stating %s", (const char*)Name); -+ return true; -+ } -+ } -+ return false; -+} -+ -+bool HardLinkVideoFile(const char *OldName, const char *NewName) -+{ -+ // Incoming name must be in base video directory: -+ if (strstr(OldName, VideoDirectory) != OldName) { -+ esyslog("ERROR: %s not in %s", OldName, VideoDirectory); -+ return false; -+ } -+ if (strstr(NewName, VideoDirectory) != NewName) { -+ esyslog("ERROR: %s not in %s", NewName, VideoDirectory); -+ return false; -+ } -+ -+ const char *ActualNewName = NewName; -+ cString ActualOldName(ReadLink(OldName), true); -+ -+ // Some safety checks: -+ struct stat StatOldName; -+ if (lstat(ActualOldName, &StatOldName) == 0) { -+ if (S_ISLNK(StatOldName.st_mode)) { -+ esyslog("HardLinkVideoFile: Failed to resolve symbolic link %s", (const char*)ActualOldName); -+ return false; -+ } -+ } -+ else { -+ esyslog("HardLinkVideoFile: lstat failed on %s", (const char*)ActualOldName); -+ return false; -+ } -+ isyslog("HardLinkVideoFile: %s is on %i", (const char*)ActualOldName, (int)StatOldName.st_dev); -+ -+ // Find the video directory where ActualOldName is located -+ -+ cVideoDirectory Dir; -+ struct stat StatDir; -+ if (!StatNearestDir(NewName, &StatDir)) { -+ esyslog("HardLinkVideoFile: stat failed on %s", NewName); -+ return false; -+ } -+ -+ isyslog("HardLinkVideoFile: %s is on %i", NewName, (int)StatDir.st_dev); -+ if (StatDir.st_dev != StatOldName.st_dev) { -+ // Not yet found. -+ -+ if (!Dir.IsDistributed()) { -+ esyslog("HardLinkVideoFile: No matching video folder to hard link %s", (const char*)ActualOldName); -+ return false; -+ } -+ -+ // Search in video01 and upwards -+ bool found = false; -+ while (Dir.Next()) { -+ Dir.Store(); -+ const char *TmpNewName = Dir.Adjust(NewName); -+ if (StatNearestDir(TmpNewName, &StatDir) && StatDir.st_dev == StatOldName.st_dev) { -+ isyslog("HardLinkVideoFile: %s is on %i (match)", TmpNewName, (int)StatDir.st_dev); -+ ActualNewName = TmpNewName; -+ found = true; -+ break; -+ } -+ isyslog("HardLinkVideoFile: %s is on %i", TmpNewName, (int)StatDir.st_dev); -+ } -+ if (ActualNewName == NewName) { -+ esyslog("HardLinkVideoFile: No matching video folder to hard link %s", (const char*)ActualOldName); -+ return false; -+ } -+ -+ // Looking good, we have a match. Create necessary folders. -+ if (!MakeDirs(ActualNewName, false)) -+ return false; -+ // There's no guarantee that the directory of ActualNewName -+ // is on the same device as the dir that StatNearestDir found. -+ // But worst case is that the link fails. -+ } -+ -+#ifdef HARDLINK_TEST_ONLY -+ // Do the hard link to *.vdr_ for testing only -+ char *name = NULL; -+ asprintf(&name, "%s_", ActualNewName); -+ link(ActualOldName, name); -+ free(name); -+ return false; -+#endif // HARDLINK_TEST_ONLY -+ -+ // Try creating the hard link -+ if (link(ActualOldName, ActualNewName) != 0) { -+ // Failed to hard link. Maybe not allowed on file system. -+ LOG_ERROR_STR(ActualNewName); -+ isyslog("HardLinkVideoFile: failed to hard link from %s to %s", (const char*)ActualOldName, ActualNewName); -+ return false; -+ } -+ -+ if (ActualNewName != NewName) { -+ // video01 and up. Do the remaining symlink -+ if (symlink(ActualNewName, NewName) < 0) { -+ LOG_ERROR_STR(NewName); -+ return false; -+ } -+ } -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgRecordingChange(Recordings.GetByName(NewName), scMod); -+#endif /* STREAMDEVEXT */ -+ return true; -+} -+#endif /* HARDLINKCUTTER */ -+ - bool VideoFileSpaceAvailable(int SizeMB) - { - cVideoDirectory Dir; -@@ -232,6 +379,129 @@ void RemoveEmptyVideoDirectories(void) - } while (Dir.Next()); - } - -+#ifdef USE_DVLVIDPREFER -+// returns path to nVid'th video directory or NULL if not existing -+char *cVideoDirectory::GetVidPath(int nVid) -+{ -+ char *b = strdup(VideoDirectory); -+ int l = strlen(b), di, n; -+ -+ while (l-- > 0 && isdigit(b[ l ])); -+ -+ l++; -+ di = strlen(b) - l; -+ -+ // di == number of digits -+ n = atoi(&b[ l ]); -+ if (n != 0) -+ return NULL; -+ -+ // add requested number to dir name -+ sprintf(&b[ l ], "%0*d", di, nVid); -+ -+ if (DirectoryOk(b) == true) -+ return b; -+ -+ free(b); -+ return NULL; -+} -+ -+// checks if a video dir is 'valid' -+bool cVideoDirectory::IsVidDirOK(int nVid, int *freeMB) -+{ -+ char *dn; -+ int fMB; -+ -+ if (nVid >= Setup.nVidPrefer) -+ return false; -+ -+ if (Setup.VidPreferSize[ nVid ] == -1) -+ return false; -+ -+ dn = GetVidPath(nVid); -+ if (dn == NULL) -+ return false; -+ -+ fMB = FreeDiskSpaceMB(dn, NULL); -+ if (freeMB != NULL) -+ *freeMB = fMB; -+ -+ free(dn); -+ -+ if (Setup.VidPreferSize[ nVid ] >= fMB) -+ return false; -+ return true; -+} -+ -+ -+// calculates which video dir to use -+bool cVideoDirectory::GetPreferedVideoDir(void) -+{ -+ cVideoDirectory d; -+ int nDirs = 1, -+ vidUse = Setup.nVidPrefer; -+ int i, top, topFree, x; -+ -+ if (name == NULL) -+ return(false); -+ -+ // count available video dirs -+ while (d.Next() == true) -+ nDirs++; -+ -+ if (vidUse > nDirs) -+ vidUse = nDirs; -+ -+ // check for prefered video dir -+ for (i = 0, top = -1, topFree = 0; i < vidUse; i++) { -+ if (IsVidDirOK(i, &x) == true) { -+ if (top == -1) { -+ // nothing set yet, use first 'ok' dir -+ top = i; -+ topFree = x; -+ } -+ else { -+ // check if we got a higher priority -+ if (Setup.VidPreferPrio[ i ] >= Setup.VidPreferPrio[ top ]) { -+ top = i; -+ topFree = x; -+ } -+ // check if we got same priority but more space -+ else if (Setup.VidPreferPrio[ i ] == Setup.VidPreferPrio[ top ] && x >= topFree) { -+ top = i; -+ topFree = x; -+ } -+ } -+ } -+ } -+ -+ if (top == -1) { -+ isyslog("VidPrefer: no prefered video directory could be determined!"); -+ -+ // something went wrong here... -+ // let VDR determine the video directory -+ int MaxFree = FreeMB(); -+ -+ while (Next()) { -+ int Free = FreeDiskSpaceMB(Name()); -+ -+ if (Free > MaxFree) { -+ Store(); -+ MaxFree = Free; -+ } -+ } -+ } -+ else { -+ isyslog("VidPrefer: prefered video directory '%d' set.", top); -+ if (stored != NULL) -+ free(stored); -+ stored = GetVidPath(top); -+ } -+ -+ return true; -+} -+#endif /* DVLVIDPREFER */ -+ - bool IsOnVideoDirectoryFileSystem(const char *FileName) - { - cVideoDirectory Dir; -diff -ruNp vdr-1.7.0/videodir.h vdr-1.7.0-extensions/videodir.h ---- vdr-1.7.0/videodir.h 2008-02-16 13:53:11.000000000 +0100 -+++ vdr-1.7.0-extensions/videodir.h 2009-04-09 20:48:48.000000000 +0200 -@@ -14,11 +14,17 @@ - #include "tools.h" - - extern const char *VideoDirectory; -+#ifdef USE_LIVEBUFFER -+extern const char *BufferDirectory; -+#endif /* LIVEBUFFER */ - - cUnbufferedFile *OpenVideoFile(const char *FileName, int Flags); - int CloseVideoFile(cUnbufferedFile *File); - bool RenameVideoFile(const char *OldName, const char *NewName); - bool RemoveVideoFile(const char *FileName); -+#ifdef USE_HARDLINKCUTTER -+bool HardLinkVideoFile(const char *OldName, const char *NewName); -+#endif /* HARDLINKCUTTER */ - bool VideoFileSpaceAvailable(int SizeMB); - int VideoDiskSpace(int *FreeMB = NULL, int *UsedMB = NULL); // returns the used disk space in percent - cString PrefixVideoFileName(const char *FileName, char Prefix); diff --git a/vdr/extensions/vdr-1.7.5_extensions.diff b/vdr/extensions/vdr-1.7.5_extensions.diff deleted file mode 100644 index 76341a9..0000000 --- a/vdr/extensions/vdr-1.7.5_extensions.diff +++ /dev/null @@ -1,23830 +0,0 @@ -diff -ruNp vdr-1.7.5/channels.c vdr-1.7.5-extensions/channels.c ---- vdr-1.7.5/channels.c 2009-04-10 13:29:55.000000000 +0200 -+++ vdr-1.7.5-extensions/channels.c 2009-04-12 13:37:59.000000000 +0200 -@@ -13,6 +13,9 @@ - #include "device.h" - #include "epg.h" - #include "timers.h" -+#ifdef USE_STREAMDEVEXT -+#include "status.h" -+#endif /* STREAMDEVEXT */ - - // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d' - // format characters in order to allow any number of blanks after a numeric -@@ -188,6 +191,9 @@ cChannel::cChannel(void) - shortName = strdup(""); - provider = strdup(""); - portalName = strdup(""); -+#ifdef USE_PLUGINPARAM -+ pluginParam = strdup(""); -+#endif /* PLUGINPARAM */ - memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__); - inversion = INVERSION_AUTO; - bandwidth = 8000000; -@@ -211,6 +217,9 @@ cChannel::cChannel(const cChannel &Chann - shortName = NULL; - provider = NULL; - portalName = NULL; -+#ifdef USE_PLUGINPARAM -+ pluginParam = NULL; -+#endif /* PLUGINPARAM */ - schedule = NULL; - linkChannels = NULL; - refChannel = NULL; -@@ -239,6 +248,9 @@ cChannel::~cChannel() - free(shortName); - free(provider); - free(portalName); -+#ifdef USE_PLUGINPARAM -+ free(pluginParam); -+#endif /* PLUGINPARAM */ - } - - cChannel& cChannel::operator= (const cChannel &Channel) -@@ -247,6 +259,9 @@ cChannel& cChannel::operator= (const cCh - shortName = strcpyrealloc(shortName, Channel.shortName); - provider = strcpyrealloc(provider, Channel.provider); - portalName = strcpyrealloc(portalName, Channel.portalName); -+#ifdef USE_PLUGINPARAM -+ pluginParam = strcpyrealloc(pluginParam, Channel.pluginParam); -+#endif /* PLUGINPARAM */ - memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__); - return *this; - } -@@ -306,6 +321,9 @@ void cChannel::CopyTransponderData(const - guard = Channel->guard; - hierarchy = Channel->hierarchy; - rollOff = Channel->rollOff; -+#ifdef USE_PLUGINPARAM -+ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, Channel->pluginParam); -+#endif /* PLUGINPARAM */ - } - } - -@@ -343,6 +361,24 @@ bool cChannel::SetSatTransponderData(int - return true; - } - -+#ifdef USE_PLUGINPARAM -+bool cChannel::SetPlugTransponderData(int Source, int Frequency, const char *PluginParam) -+{ -+ if (source != Source || frequency != Frequency || (strcmp(pluginParam, PluginParam) != 0)) { -+ if (Number()) { -+ dsyslog("changing transponder data of channel %d from %s:%d:%s to %s:%d:%s", Number(), *cSource::ToString(source), frequency, pluginParam, *cSource::ToString(Source), Frequency, PluginParam); -+ modification |= CHANNELMOD_TRANSP; -+ Channels.SetModified(); -+ } -+ source = Source; -+ frequency = Frequency; -+ pluginParam = strcpyrealloc(pluginParam, PluginParam); -+ schedule = NULL; -+ } -+ return true; -+} -+#endif /* PLUGINPARAM */ -+ - bool cChannel::SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH) - { - if (source != Source || frequency != Frequency || modulation != Modulation || srate != Srate || coderateH != CoderateH) { -@@ -413,6 +449,9 @@ void cChannel::SetName(const char *Name, - if (nn || ns || np) { - if (Number()) { - dsyslog("changing name of channel %d from '%s,%s;%s' to '%s,%s;%s'", Number(), name, shortName, provider, Name, ShortName, Provider); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(this, scMod); -+#endif /* STREAMDEVEXT */ - modification |= CHANNELMOD_NAME; - Channels.SetModified(); - } -@@ -438,6 +477,20 @@ void cChannel::SetPortalName(const char - } - } - -+#ifdef USE_PLUGINPARAM -+void cChannel::SetPluginParam(const char *PluginParam) -+{ -+ if (!isempty(PluginParam) && strcmp(pluginParam, PluginParam) != 0) { -+ if (Number()) { -+ dsyslog("changing plugin parameters of channel %d from '%s' to '%s'", Number(), pluginParam, PluginParam); -+ modification |= CHANNELMOD_TRANSP; -+ Channels.SetModified(); -+ } -+ pluginParam = strcpyrealloc(pluginParam, PluginParam); -+ } -+} -+#endif /* PLUGINPARAM */ -+ - #define STRDIFF 0x01 - #define VALDIFF 0x02 - -@@ -632,7 +685,11 @@ cString cChannel::ParametersToString(voi - if (isdigit(type)) - type = 'S'; - #define ST(s) if (strchr(s, type)) -+#ifdef USE_PLUGINPARAM -+ char buffer[256]; -+#else - char buffer[64]; -+#endif /* PLUGINPARAM */ - char *q = buffer; - *q = 0; - ST(" S ") q += sprintf(q, "%c", polarization); -@@ -646,6 +703,9 @@ cString cChannel::ParametersToString(voi - ST(" S ") q += PrintParameter(q, 'S', MapToUser(system, SystemValues)); - ST(" T") q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues)); - ST(" T") q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues)); -+#ifdef USE_PLUGINPARAM -+ ST("P ") snprintf(buffer, sizeof(buffer), "%s", pluginParam); -+#endif /* PLUGINPARAM */ - return buffer; - } - -@@ -674,7 +734,11 @@ static const char *SkipDigits(const char - - bool cChannel::StringToParameters(const char *s) - { -+#ifdef USE_PLUGINPARAM -+ while (s && *s && !IsPlug()) { -+#else - while (s && *s) { -+#endif /* PLUGINPARAM */ - switch (toupper(*s)) { - case 'A': s = SkipDigits(s); break; // for compatibility with the "multiproto" approach - may be removed in future versions - case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break; -@@ -792,7 +856,11 @@ bool cChannel::Parse(const char *s) - dpids[0] = 0; - ok = false; - if (parambuf && sourcebuf && vpidbuf && apidbuf) { -+#ifdef USE_PLUGINPARAM -+ ok = ((source = cSource::FromString(sourcebuf)) >= 0) && StringToParameters(parambuf); -+#else - ok = StringToParameters(parambuf) && (source = cSource::FromString(sourcebuf)) >= 0; -+#endif /* PLUGINPARAM */ - - char *p; - if ((p = strchr(vpidbuf, '=')) != NULL) { -@@ -887,6 +955,9 @@ bool cChannel::Parse(const char *s) - shortName = strcpyrealloc(shortName, p); - } - name = strcpyrealloc(name, namebuf); -+#ifdef USE_PLUGINPARAM -+ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, parambuf); -+#endif /* PLUGINPARAM */ - - free(parambuf); - free(sourcebuf); -@@ -1132,6 +1203,9 @@ cChannel *cChannels::NewChannel(const cC - NewChannel->SetName(Name, ShortName, Provider); - Add(NewChannel); - ReNumber(); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(NewChannel, scAdd); -+#endif /* STREAMDEVEXT */ - return NewChannel; - } - return NULL; -diff -ruNp vdr-1.7.5/channels.h vdr-1.7.5-extensions/channels.h ---- vdr-1.7.5/channels.h 2008-11-22 14:35:52.000000000 +0100 -+++ vdr-1.7.5-extensions/channels.h 2009-04-12 13:37:59.000000000 +0200 -@@ -116,6 +116,9 @@ private: - char *shortName; - char *provider; - char *portalName; -+#ifdef USE_PLUGINPARAM -+ char *pluginParam; -+#endif /* PLUGINPARAM */ - int __BeginData__; - int frequency; // MHz - int source; -@@ -171,6 +174,9 @@ public: - int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf' - int Transponder(void) const; ///< Returns the transponder frequency in MHz, plus the polarization in case of sat - static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization -+#ifdef USE_PLUGINPARAM -+ const char *PluginParam(void) const { return pluginParam; } -+#endif /* PLUGINPARAM */ - int Source(void) const { return source; } - int Srate(void) const { return srate; } - int Vpid(void) const { return vpid; } -@@ -208,6 +214,9 @@ public: - int RollOff(void) const { return rollOff; } - const cLinkChannels* LinkChannels(void) const { return linkChannels; } - const cChannel *RefChannel(void) const { return refChannel; } -+#ifdef USE_PLUGINPARAM -+ bool IsPlug(void) const { return cSource::IsPlug(source); } -+#endif /* PLUGINPARAM */ - bool IsCable(void) const { return cSource::IsCable(source); } - bool IsSat(void) const { return cSource::IsSat(source); } - bool IsTerr(void) const { return cSource::IsTerr(source); } -@@ -215,12 +224,18 @@ public: - bool HasTimer(void) const; - int Modification(int Mask = CHANNELMOD_ALL); - void CopyTransponderData(const cChannel *Channel); -+#ifdef USE_PLUGINPARAM -+ bool SetPlugTransponderData(int Source, int Frequency, const char *PluginParam); -+#endif /* PLUGINPARAM */ - bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation, int System, int RollOff); - bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH); - bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission); - void SetId(int Nid, int Tid, int Sid, int Rid = 0); - void SetName(const char *Name, const char *ShortName, const char *Provider); - void SetPortalName(const char *PortalName); -+#ifdef USE_PLUGINPARAM -+ void SetPluginParam(const char *PluginParam); -+#endif /* PLUGINPARAM */ - void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); - void SetCaIds(const int *CaIds); // list must be zero-terminated - void SetCaDescriptors(int Level); -diff -ruNp vdr-1.7.5/config.c vdr-1.7.5-extensions/config.c ---- vdr-1.7.5/config.c 2009-01-24 16:05:32.000000000 +0100 -+++ vdr-1.7.5-extensions/config.c 2009-04-12 13:37:59.000000000 +0200 -@@ -15,6 +15,9 @@ - #include "interface.h" - #include "plugin.h" - #include "recording.h" -+#ifdef USE_SOURCECAPS -+#include "sources.h" -+#endif /* SOURCECAPS */ - - // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d' - // format characters in order to allow any number of blanks after a numeric -@@ -28,18 +31,32 @@ cCommand::cCommand(void) - { - title = command = NULL; - confirm = false; -+#ifdef USE_CMDSUBMENU -+ nIndent = 0; -+ childs = NULL; -+#endif /* CMDSUBMENU */ - } - - cCommand::~cCommand() - { - free(title); - free(command); -+#ifdef USE_CMDSUBMENU -+ delete childs; -+#endif /* CMDSUBMENU */ - } - - bool cCommand::Parse(const char *s) - { - const char *p = strchr(s, ':'); - if (p) { -+#ifdef USE_CMDSUBMENU -+ nIndent = 0; -+ while (*s == '-') { -+ nIndent++; -+ s++; -+ } -+#endif /* CMDSUBMENU */ - int l = p - s; - if (l > 0) { - title = MALLOC(char, l + 1); -@@ -85,6 +102,20 @@ const char *cCommand::Execute(const char - return result; - } - -+#ifdef USE_CMDSUBMENU -+int cCommand::getChildCount(void) -+{ -+ return childs ? childs->Count() : 0; -+} -+ -+void cCommand::addChild(cCommand *newChild) -+{ -+ if (!childs) -+ childs = new cCommands(); -+ childs->AddConfig(newChild); -+} -+#endif /* CMDSUBMENU */ -+ - // --- cSVDRPhost ------------------------------------------------------------ - - cSVDRPhost::cSVDRPhost(void) -@@ -125,6 +156,26 @@ bool cSVDRPhost::Accepts(in_addr_t Addre - - cCommands Commands; - cCommands RecordingCommands; -+#ifdef USE_TIMERCMD -+cCommands TimerCommands; -+#endif /* TIMERCMD */ -+ -+#ifdef USE_CMDSUBMENU -+void cCommands::AddConfig(cCommand *Object) -+{ -+ if (!Object) -+ return; -+ //isyslog ("Indent %d %s\n", Object->getIndent(), Object->Title()); -+ for (int index = Count() - 1; index >= 0; index--) { -+ cCommand *parent = Get(index); -+ if (parent->getIndent() < Object->getIndent()) { -+ parent->addChild(Object); -+ return; -+ } -+ } -+ cConfig<cCommand>::Add(Object); -+} -+#endif /* CMDSUBMENU */ - - // --- cSVDRPhosts ----------------------------------------------------------- - -@@ -216,6 +267,12 @@ cSetup::cSetup(void) - strcpy(OSDLanguage, ""); // default is taken from environment - strcpy(OSDSkin, "sttng"); - strcpy(OSDTheme, "default"); -+#ifdef USE_WAREAGLEICON -+ WarEagleIcons = 1; -+#endif /* WAREAGLEICON */ -+#ifdef USE_VALIDINPUT -+ ShowValidInput = 0; -+#endif /* VALIDINPUT */ - PrimaryDVB = 1; - ShowInfoOnChSwitch = 1; - TimeoutRequChInfo = 1; -@@ -260,6 +317,15 @@ cSetup::cSetup(void) - VideoFormat = 0; - UpdateChannels = 5; - UseDolbyDigital = 1; -+#ifdef USE_DOLBYINREC -+ UseDolbyInRecordings = 1; -+#endif /* DOLBYINREC */ -+#ifdef USE_DVBSETUP -+ DolbyTransferFix = 1; -+ ChannelBlocker = 0; -+ ChannelBlockerMode = 0; -+ ChannelBlockerList = strdup(""); -+#endif /* DVBSETUP */ - ChannelInfoPos = 0; - ChannelInfoTime = 5; - OSDLeft = 54; -@@ -276,24 +342,135 @@ cSetup::cSetup(void) - FontSmlSize = 18; - FontFixSize = 20; - MaxVideoFileSize = MAXVIDEOFILESIZEDEFAULT; -+#ifdef USE_HARDLINKCUTTER -+ MaxRecordingSize = DEFAULTRECORDINGSIZE; -+#endif /* HARDLINKCUTTER */ - SplitEditedFiles = 0; -+#ifdef USE_HARDLINKCUTTER -+ HardLinkCutter = 0; -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ DelTimeshiftRec = 0; -+#endif /* DELTIMESHIFTREC */ - MinEventTimeout = 30; - MinUserInactivity = 300; - NextWakeupTime = 0; - MultiSpeedMode = 0; - ShowReplayMode = 0; -+#ifdef USE_DDEPGENTRY -+ DoubleEpgTimeDelta = 15; -+ DoubleEpgAction = 0; -+ MixEpgAction = 0; -+ DisableVPS = 0; -+#endif /* DDEPGENTRY */ - ResumeID = 0; -+#ifdef USE_JUMPPLAY -+ JumpPlay = 0; -+ PlayJump = 0; -+ PauseLastMark = 0; -+ ReloadMarks = 0; -+#endif /* JUMPPLAY */ -+#ifdef USE_SOURCECAPS -+ memset(SourceCaps, 0, sizeof SourceCaps); -+ SourceCapsSet = false; -+#endif /* SOURCECAPS */ - CurrentChannel = -1; - CurrentVolume = MAXVOLUME; - CurrentDolby = 0; - InitialChannel = 0; - InitialVolume = -1; -+#ifdef USE_VOLCTRL -+ LRVolumeControl = 0; -+ LRChannelGroups = 1; -+ LRForwardRewind = 1; -+#endif /* VOLCTRL */ - EmergencyExit = 1; -+#ifdef USE_NOEPG -+ noEPGMode = 0; -+ noEPGList = strdup(""); -+#endif /* NOEPG */ -+#ifdef USE_LIRCSETTINGS -+ LircRepeatDelay = 350; -+ LircRepeatFreq = 100; -+ LircRepeatTimeout = 500; -+#endif /* LIRCSETTINGS */ -+#ifdef USE_LIEMIEXT -+ ShowRecDate = 1; -+ ShowRecTime = 1; -+ ShowRecLength = 0; -+ ShowProgressBar = 0; -+ MenuCmdPosition = 0; -+ JumpSeconds = 60; -+ JumpSecondsSlow = 10; -+ ShowTimerStop = 1; -+ MainMenuTitle = 0; -+ strcpy(CustomMainMenuTitle, "Video Disk Recorder"); -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ RecordingsSortMode = 0; -+ RecordingsSortDirsFirst = 0; -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ CutterAutoDelete = 0; -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ CutTime = 1; -+#endif /* CUTTIME */ -+#ifdef USE_DVDARCHIVE -+ DvdDisplayMode = 1; -+ DvdDisplayZeros = 1; -+ DvdTrayMode = 0; -+ DvdSpeedLimit = 0; -+#endif /* DVDARCHIVE */ -+#ifdef USE_SOFTOSD -+ UseSoftOsd = 0; -+ SoftOsdRate = 50; -+ SoftOsdFadeinSteps = 6; -+ SoftOsdFadeoutSteps = 16; -+ SoftOsdPaletteOnly = 0; -+#endif /* SOFTOSD */ -+#ifdef USE_LNBSHARE -+ VerboseLNBlog = 0; -+ for (int i = 0; i < MAXDEVICES; i++) CardUsesLNBnr[i] = i + 1; -+#endif /* LNBSHARE */ -+#ifdef USE_DVLVIDPREFER -+ UseVidPrefer = 0; // default = disabled -+ nVidPrefer = 1; -+ for (int zz = 1; zz < DVLVIDPREFER_MAX; zz++) { -+ VidPreferPrio[ zz ] = 50; -+ VidPreferSize[ zz ] = 100; -+ } -+ VidPreferSize[ 0 ] = 800; -+ VidPreferPrio[ 0 ] = 50; -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLFRIENDLYFNAMES -+ UseFriendlyFNames = 0; // default = disabled -+#endif /* DVLFRIENDLYFNAMES */ -+} -+ -+#if defined (USE_DVBSETUP) || defined (USE_NOEPG) -+cSetup::~cSetup() -+{ -+#ifdef USE_DVBSETUP -+ free(ChannelBlockerList); -+#endif /* DVBSETUP */ -+#ifdef USE_NOEPG -+ free(noEPGList); -+#endif /* NOEPG */ - } -+#endif /* DVBSETUP + NOEPG */ - - cSetup& cSetup::operator= (const cSetup &s) - { - memcpy(&__BeginData__, &s.__BeginData__, (char *)&s.__EndData__ - (char *)&s.__BeginData__); -+#ifdef USE_DVBSETUP -+ free(ChannelBlockerList); -+ ChannelBlockerList = strdup(s.ChannelBlockerList); -+#endif /* DVBSETUP */ -+#ifdef USE_NOEPG -+ free(noEPGList); -+ noEPGList = strdup(s.noEPGList); -+#endif /* NOEPG */ - return *this; - } - -@@ -384,11 +561,62 @@ bool cSetup::ParseLanguages(const char * - return true; - } - -+#ifdef USE_SOURCECAPS -+void cSetup::StoreSourceCaps(const char *Name) -+{ -+ cSetupLine *l; -+ while ((l = Get(Name)) != NULL) -+ Del(l); -+ -+ for (int i = 0; i < MAXDEVICES; i++) { -+ char buffer[MAXSOURCECAPS*8]={0,}, *q = buffer; -+ int j = 0; -+ while (SourceCaps[i][j] && j < MAXSOURCECAPS) { -+ if (j==0) -+ q += snprintf(buffer, sizeof(buffer), "%i ", i+1); -+ q += snprintf(q, sizeof(buffer) - (q-buffer), "%s ", *cSource::ToString(SourceCaps[i][j++])); -+ } -+ if (*buffer) -+ Store(Name, buffer, NULL, true); -+ } -+} -+ -+bool cSetup::ParseSourceCaps(const char *Value) -+{ -+ char *p; -+ int d = strtol(Value, &p, 10)-1, i = 0; -+ while (p < Value+strlen(Value)) { -+ if (*p==0) return true; -+ if (isblank(*p)) ++p; -+ if (isalpha(*p)) { -+ int source = cSource::FromString(p); -+ if (source != cSource::stNone) { -+ SourceCaps[d][i++] = source; -+ SourceCapsSet = true; -+ } -+ else -+ return false; -+ while (!isblank(*p) && *p) -+ ++p; -+ if (i>MAXSOURCECAPS) -+ return false; -+ } -+ } -+ return true; -+} -+#endif /* SOURCECAPS */ -+ - bool cSetup::Parse(const char *Name, const char *Value) - { - if (!strcasecmp(Name, "OSDLanguage")) { strn0cpy(OSDLanguage, Value, sizeof(OSDLanguage)); I18nSetLocale(OSDLanguage); } - else if (!strcasecmp(Name, "OSDSkin")) Utf8Strn0Cpy(OSDSkin, Value, MaxSkinName); - else if (!strcasecmp(Name, "OSDTheme")) Utf8Strn0Cpy(OSDTheme, Value, MaxThemeName); -+#ifdef USE_WAREAGLEICON -+ else if (!strcasecmp(Name, "WarEagleIcons")) WarEagleIcons = atoi(Value); -+#endif /* WAREAGLEICON */ -+#ifdef USE_VALIDINPUT -+ else if (!strcasecmp(Name, "ShowValidInput")) ShowValidInput = atoi(Value); -+#endif /* VALIDINPUT */ - else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value); - else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value); - else if (!strcasecmp(Name, "TimeoutRequChInfo")) TimeoutRequChInfo = atoi(Value); -@@ -433,6 +661,18 @@ bool cSetup::Parse(const char *Name, con - else if (!strcasecmp(Name, "VideoFormat")) VideoFormat = atoi(Value); - else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value); - else if (!strcasecmp(Name, "UseDolbyDigital")) UseDolbyDigital = atoi(Value); -+#ifdef USE_DOLBYINREC -+ else if (!strcasecmp(Name, "UseDolbyInRecordings")) UseDolbyInRecordings = atoi(Value); -+#endif /* DOLBYINREC */ -+#ifdef USE_DVBSETUP -+ else if (!strcasecmp(Name, "DolbyTransferFix")) DolbyTransferFix = atoi(Value); -+ else if (!strcasecmp(Name, "ChannelBlocker")) ChannelBlocker = atoi(Value); -+ else if (!strcasecmp(Name, "ChannelBlockerMode")) ChannelBlockerMode = atoi(Value); -+ else if (!strcasecmp(Name, "ChannelBlockerList")) { -+ free(ChannelBlockerList); -+ ChannelBlockerList = strdup(Value ? Value : ""); -+ } -+#endif /* DVBSETUP */ - else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value); - else if (!strcasecmp(Name, "ChannelInfoTime")) ChannelInfoTime = atoi(Value); - else if (!strcasecmp(Name, "OSDLeft")) OSDLeft = atoi(Value); -@@ -449,21 +689,144 @@ bool cSetup::Parse(const char *Name, con - else if (!strcasecmp(Name, "FontSmlSize")) FontSmlSize = atoi(Value); - else if (!strcasecmp(Name, "FontFixSize")) FontFixSize = atoi(Value); - else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value); -+#ifdef USE_HARDLINKCUTTER -+ else if (!strcasecmp(Name, "MaxRecordingSize")) MaxRecordingSize = atoi(Value); -+#endif /* HARDLINKCUTTER */ - else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value); -+#ifdef USE_HARDLINKCUTTER -+ else if (!strcasecmp(Name, "HardLinkCutter")) HardLinkCutter = atoi(Value); -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ else if (!strcasecmp(Name, "DelTimeshiftRec")) DelTimeshiftRec = atoi(Value); -+#endif /* DELTIMESHIFTREC */ - else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value); - else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value); - else if (!strcasecmp(Name, "NextWakeupTime")) NextWakeupTime = atoi(Value); - else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value); - else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value); -+#ifdef USE_DDEPGENTRY -+ else if (!strcasecmp(Name, "DoubleEpgTimeDelta")) DoubleEpgTimeDelta = atoi(Value); -+ else if (!strcasecmp(Name, "DoubleEpgAction")) DoubleEpgAction = atoi(Value); -+ else if (!strcasecmp(Name, "MixEpgAction")) MixEpgAction = atoi(Value); -+ else if (!strcasecmp(Name, "DisableVPS")) DisableVPS = atoi(Value); -+#endif /* DDEPGENTRY */ - else if (!strcasecmp(Name, "ResumeID")) ResumeID = atoi(Value); -+#ifdef USE_JUMPPLAY -+ else if (!strcasecmp(Name, "JumpPlay")) JumpPlay = atoi(Value); -+ else if (!strcasecmp(Name, "PlayJump")) PlayJump = atoi(Value); -+ else if (!strcasecmp(Name, "PauseLastMark")) PauseLastMark = atoi(Value); -+ else if (!strcasecmp(Name, "ReloadMarks")) ReloadMarks = atoi(Value); -+#endif /* JUMPPLAY */ -+#ifdef USE_SOURCECAPS -+ else if (!strcasecmp(Name, "SourceCaps")) return ParseSourceCaps(Value); -+#endif /* SOURCECAPS */ - else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value); - else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value); - else if (!strcasecmp(Name, "CurrentDolby")) CurrentDolby = atoi(Value); - else if (!strcasecmp(Name, "InitialChannel")) InitialChannel = atoi(Value); - else if (!strcasecmp(Name, "InitialVolume")) InitialVolume = atoi(Value); -+#ifdef USE_VOLCTRL -+ else if (!strcasecmp(Name, "LRVolumeControl")) LRVolumeControl = atoi(Value); -+ else if (!strcasecmp(Name, "LRChannelGroups")) LRChannelGroups = atoi(Value); -+ else if (!strcasecmp(Name, "LRForwardRewind")) LRForwardRewind = atoi(Value); -+#endif /* VOLCTRL */ - else if (!strcasecmp(Name, "EmergencyExit")) EmergencyExit = atoi(Value); -+#ifdef USE_NOEPG -+ else if (!strcasecmp(Name, "noEPGMode")) noEPGMode = atoi(Value); -+ else if (!strcasecmp(Name, "noEPGList")) { -+ free(noEPGList); -+ noEPGList = strdup(Value ? Value : ""); -+ } -+#endif /* NOEPG */ -+#ifdef USE_LIRCSETTINGS -+ else if (!strcasecmp(Name, "LircRepeatDelay")) LircRepeatDelay = atoi(Value); -+ else if (!strcasecmp(Name, "LircRepeatFreq")) LircRepeatFreq = atoi(Value); -+ else if (!strcasecmp(Name, "LircRepeatTimeout")) LircRepeatTimeout = atoi(Value); -+#endif /* LIRCSETTINGS */ -+#ifdef USE_LIEMIEXT -+ else if (!strcasecmp(Name, "ShowRecDate")) ShowRecDate = atoi(Value); -+ else if (!strcasecmp(Name, "ShowRecTime")) ShowRecTime = atoi(Value); -+ else if (!strcasecmp(Name, "ShowRecLength")) ShowRecLength = atoi(Value); -+ else if (!strcasecmp(Name, "ShowProgressBar")) ShowProgressBar = atoi(Value); -+ else if (!strcasecmp(Name, "MenuCmdPosition")) MenuCmdPosition = atoi(Value); -+ else if (!strcasecmp(Name, "JumpSeconds")) JumpSeconds = atoi(Value); -+ else if (!strcasecmp(Name, "JumpSecondsSlow")) JumpSecondsSlow = atoi(Value); -+ else if (!strcasecmp(Name, "ShowTimerStop")) ShowTimerStop = atoi(Value); -+ else if (!strcasecmp(Name, "MainMenuTitle")) MainMenuTitle = atoi(Value); -+ else if (!strcasecmp(Name, "CustomMainMenuTitle")) Utf8Strn0Cpy(CustomMainMenuTitle, Value, MaxTitleName); -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ else if (!strcasecmp(Name, "RecordingsSortMode")) RecordingsSortMode = atoi(Value); -+ else if (!strcasecmp(Name, "RecordingsSortDirsFirst")) RecordingsSortDirsFirst = atoi(Value); -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ else if (!strcasecmp(Name, "CutterAutoDelete")) CutterAutoDelete = atoi(Value); -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ else if (!strcasecmp(Name, "CutTime")) CutTime = atoi(Value); -+#endif /* CUTTIME */ -+#ifdef USE_DVDARCHIVE -+ else if (!strcasecmp(Name, "DvdDisplayMode")) DvdDisplayMode = atoi(Value); -+ else if (!strcasecmp(Name, "DvdDisplayZeros")) DvdDisplayZeros = atoi(Value); -+ else if (!strcasecmp(Name, "DvdTrayMode")) DvdTrayMode = atoi(Value); -+ else if (!strcasecmp(Name, "DvdSpeedLimit")) DvdSpeedLimit = atoi(Value); -+#endif /* DVDARCHIVE */ -+#ifdef USE_SOFTOSD -+ else if (!strcasecmp(Name, "UseSoftOsd")) UseSoftOsd = atoi(Value); -+ else if (!strcasecmp(Name, "SoftOsdRate")) SoftOsdRate = atoi(Value); -+ else if (!strcasecmp(Name, "SoftOsdFadeinSteps")) SoftOsdFadeinSteps = atoi(Value); -+ else if (!strcasecmp(Name, "SoftOsdFadeoutSteps")) SoftOsdFadeoutSteps = atoi(Value); -+ else if (!strcasecmp(Name, "SoftOsdPaletteOnly")) SoftOsdPaletteOnly = atoi(Value); -+#endif /* SOFTOSD */ -+#ifdef USE_DVLVIDPREFER -+ else if (strcasecmp(Name, "UseVidPrefer") == 0) UseVidPrefer = atoi(Value); -+ else if (strcasecmp(Name, "nVidPrefer") == 0) nVidPrefer = atoi(Value); -+ else if (strstr(Name, "VidPrefer") == Name) { -+ char *x = (char *)&Name[ strlen(Name) - 1 ]; -+ int vN; -+ -+ if (isdigit(*x) != 0) { -+ while (isdigit(*x) != 0) -+ x--; -+ x++; -+ } -+ -+ vN = atoi(x); -+ if (vN < DVLVIDPREFER_MAX) { -+ if (strstr(Name, "VidPreferPrio") == Name) { -+ VidPreferPrio[ vN ] = atoi(Value); -+ if (VidPreferPrio[ vN ] > 99) -+ VidPreferPrio[ vN ] = 99; -+ } -+ else if (strstr(Name, "VidPreferSize") == Name) { -+ VidPreferSize[ vN ] = atoi(Value); -+ } -+ else -+ return false; -+ } -+ } -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLFRIENDLYFNAMES -+ else if (strcasecmp(Name, "UseFriendlyFNames") == 0) UseFriendlyFNames = atoi(Value); -+#endif /* DVLFRIENDLYFNAMES */ - else -+#ifdef USE_LNBSHARE -+ if (!strcasecmp(Name, "VerboseLNBlog")) VerboseLNBlog = atoi(Value); -+ else { -+ char tmp[20]; -+ bool result = false; -+ for (int i = 1; i <= MAXDEVICES; i++) { -+ sprintf(tmp, "Card%dusesLNBnr", i); -+ if (!strcasecmp(Name, tmp)) { -+ CardUsesLNBnr[i - 1] = atoi(Value); -+ result = true; -+ } -+ } -+ return result; -+ } -+#else - return false; -+#endif /* LNBSHARE */ - return true; - } - -@@ -472,6 +835,12 @@ bool cSetup::Save(void) - Store("OSDLanguage", OSDLanguage); - Store("OSDSkin", OSDSkin); - Store("OSDTheme", OSDTheme); -+#ifdef USE_WAREAGLEICON -+ Store("WarEagleIcons", WarEagleIcons); -+#endif /* WAREAGLEICON */ -+#ifdef USE_VALIDINPUT -+ Store("ShowValidInput", ShowValidInput); -+#endif /* VALIDINPUT */ - Store("PrimaryDVB", PrimaryDVB); - Store("ShowInfoOnChSwitch", ShowInfoOnChSwitch); - Store("TimeoutRequChInfo", TimeoutRequChInfo); -@@ -516,6 +885,15 @@ bool cSetup::Save(void) - Store("VideoFormat", VideoFormat); - Store("UpdateChannels", UpdateChannels); - Store("UseDolbyDigital", UseDolbyDigital); -+#ifdef USE_DOLBYINREC -+ Store("UseDolbyInRecordings", UseDolbyInRecordings); -+#endif /* DOLBYINREC */ -+#ifdef USE_DVBSETUP -+ Store("DolbyTransferFix", DolbyTransferFix); -+ Store("ChannelBlocker", ChannelBlocker); -+ Store("ChannelBlockerMode", ChannelBlockerMode); -+ Store("ChannelBlockerList", ChannelBlockerList); -+#endif /* DVBSETUP */ - Store("ChannelInfoPos", ChannelInfoPos); - Store("ChannelInfoTime", ChannelInfoTime); - Store("OSDLeft", OSDLeft); -@@ -532,25 +910,156 @@ bool cSetup::Save(void) - Store("FontSmlSize", FontSmlSize); - Store("FontFixSize", FontFixSize); - Store("MaxVideoFileSize", MaxVideoFileSize); -+#ifdef USE_HARDLINKCUTTER -+ Store("MaxRecordingSize", MaxRecordingSize); -+#endif /* HARDLINKCUTTER */ - Store("SplitEditedFiles", SplitEditedFiles); -+#ifdef USE_HARDLINKCUTTER -+ Store("HardLinkCutter", HardLinkCutter); -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ Store("DelTimeshiftRec", DelTimeshiftRec); -+#endif /* DELTIMESHIFTREC */ - Store("MinEventTimeout", MinEventTimeout); - Store("MinUserInactivity", MinUserInactivity); - Store("NextWakeupTime", NextWakeupTime); -+#ifdef USE_DDEPGENTRY -+ Store("DoubleEpgAction", DoubleEpgAction); -+ Store("MixEpgAction", MixEpgAction); -+ Store("DisableVPS", DisableVPS); -+ Store("DoubleEpgTimeDelta", DoubleEpgTimeDelta); -+#endif /* DDEPGENTRY */ - Store("MultiSpeedMode", MultiSpeedMode); - Store("ShowReplayMode", ShowReplayMode); - Store("ResumeID", ResumeID); -+#ifdef USE_JUMPPLAY -+ Store("JumpPlay", JumpPlay); -+ Store("PlayJump", PlayJump); -+ Store("PauseLastMark", PauseLastMark); -+ Store("ReloadMarks", ReloadMarks); -+#endif /* JUMPPLAY */ -+#ifdef USE_SOURCECAPS -+ if (SourceCapsSet) StoreSourceCaps("SourceCaps"); -+#endif /* SOURCECAPS */ - Store("CurrentChannel", CurrentChannel); - Store("CurrentVolume", CurrentVolume); - Store("CurrentDolby", CurrentDolby); - Store("InitialChannel", InitialChannel); - Store("InitialVolume", InitialVolume); -+#ifdef USE_VOLCTRL -+ Store("LRVolumeControl", LRVolumeControl); -+ Store("LRChannelGroups", LRChannelGroups); -+ Store("LRForwardRewind", LRForwardRewind); -+#endif /* VOLCTRL */ - Store("EmergencyExit", EmergencyExit); -+#ifdef USE_NOEPG -+ Store("noEPGMode", noEPGMode); -+ Store("noEPGList", noEPGList); -+#endif /* NOEPG */ -+#ifdef USE_LIRCSETTINGS -+ Store("LircRepeatDelay", LircRepeatDelay); -+ Store("LircRepeatFreq", LircRepeatFreq); -+ Store("LircRepeatTimeout", LircRepeatTimeout); -+#endif /* LIRCSETTINGS */ -+#ifdef USE_LIEMIEXT -+ Store("ShowRecDate", ShowRecDate); -+ Store("ShowRecTime", ShowRecTime); -+ Store("ShowRecLength", ShowRecLength); -+ Store("ShowProgressBar", ShowProgressBar); -+ Store("MenuCmdPosition", MenuCmdPosition); -+ Store("JumpSeconds", JumpSeconds); -+ Store("JumpSecondsSlow", JumpSecondsSlow); -+ Store("ShowTimerStop", ShowTimerStop); -+ Store("MainMenuTitle", MainMenuTitle); -+ Store("CustomMainMenuTitle",CustomMainMenuTitle); -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ Store("RecordingsSortMode", RecordingsSortMode); -+ Store("RecordingsSortDirsFirst", RecordingsSortDirsFirst); -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ Store("CutterAutoDelete", CutterAutoDelete); -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ Store("CutTime", CutTime); -+#endif /* CUTTIME */ -+#ifdef USE_DVDARCHIVE -+ Store("DvdDisplayMode", DvdDisplayMode); -+ Store("DvdDisplayZeros", DvdDisplayZeros); -+ Store("DvdTrayMode", DvdTrayMode); -+ Store("DvdSpeedLimit", DvdSpeedLimit); -+#endif /* DVDARCHIVE */ -+#ifdef USE_SOFTOSD -+ Store("UseSoftOsd", UseSoftOsd); -+ Store("SoftOsdRate", SoftOsdRate); -+ Store("SoftOsdFadeinSteps", SoftOsdFadeinSteps); -+ Store("SoftOsdFadeoutSteps", SoftOsdFadeoutSteps); -+ Store("SoftOsdPaletteOnly", SoftOsdPaletteOnly); -+#endif /* SOFTOSD */ -+#ifdef USE_LNBSHARE -+ Store("VerboseLNBlog", VerboseLNBlog); -+ char tmp[20]; -+ if (cDevice::NumDevices() > 1) { -+ for (int i = 1; i <= cDevice::NumDevices(); i++) { -+ sprintf(tmp, "Card%dusesLNBnr", i); -+ Store(tmp, CardUsesLNBnr[i - 1]); -+ } -+ } -+#endif /* LNBSHARE */ -+#ifdef USE_DVLVIDPREFER -+ Store ("UseVidPrefer", UseVidPrefer); -+ Store ("nVidPrefer", nVidPrefer); -+ -+ char vidBuf[32]; -+ for (int zz = 0; zz < nVidPrefer; zz++) { -+ sprintf(vidBuf, "VidPreferPrio%d", zz); -+ Store (vidBuf, VidPreferPrio[zz]); -+ sprintf(vidBuf, "VidPreferSize%d", zz); -+ Store (vidBuf, VidPreferSize[zz]); -+ } -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLFRIENDLYFNAMES -+ Store ("UseFriendlyFNames", UseFriendlyFNames); -+#endif /* DVLFRIENDLYFNAMES */ - - Sort(); - - if (cConfig<cSetupLine>::Save()) { - isyslog("saved setup to %s", FileName()); -+#ifdef USE_DVDARCHIVE -+ if (DvdDisplayMode >= 1) ::Recordings.Load(); -+#endif /* DVDARCHIVE */ - return true; - } - return false; - } -+ -+#ifdef USE_CMDRECCMDI18N -+bool LoadCommandsI18n(cCommands & cmds, const char *FileName, bool AllowComments, bool MustExist) -+{ -+ -+ bool bRet = true; -+ bool bLoadDefault = (bool)strcmp(Setup.OSDLanguage,"en_US"); -+ if (bLoadDefault) { -+ // attempt to load a translated file -+ char *FullPath = NULL; -+ asprintf(&FullPath, "%s.%s", FileName, Setup.OSDLanguage); -+ if (!cmds.Load((FullPath), AllowComments, true)) { -+ // require to exist, just to be able to log -+ // fallback -+ bLoadDefault = false; -+ esyslog("Failed to load translated '%s' for language (%s)", FullPath, Setup.OSDLanguage); -+ esyslog("Falling back to default '%s' (if any)", FileName); -+ } -+ free(FullPath); -+ } -+ if (!bLoadDefault) { -+ // let's do it the normal way -+ bRet = cmds.Load(FileName, AllowComments, MustExist); -+ } -+ // return status only for the default commands file -+ return bRet; -+} -+ -+#endif /* CMDRECCMDI18N */ -+ -diff -ruNp vdr-1.7.5/config.h vdr-1.7.5-extensions/config.h ---- vdr-1.7.5/config.h 2009-01-30 17:05:34.000000000 +0100 -+++ vdr-1.7.5-extensions/config.h 2009-04-12 13:37:59.000000000 +0200 -@@ -36,23 +36,74 @@ - // plugins to work with newer versions of the core VDR as long as no - // VDR header files have changed. - -+#define VDREXTENSIONS 70 -+ -+#ifdef USE_JUMPPLAY -+#define JUMPPLAYVERSNUM 100 -+#endif /* JUMPPLAY */ -+ -+#ifdef USE_LIEMIEXT -+#define LIEMIKUUTIO 123 -+#define MAXMAINMENUTITLE 4 -+#define MaxTitleName 64 -+#endif /* LIEMIEXT */ -+ -+#ifdef USE_CMDSUBMENU -+#define CMDSUBMENUVERSNUM 7 -+#endif /* CMDSUBMENU */ -+ -+#ifdef USE_MAINMENUHOOKS -+#define MAINMENUHOOKSVERSNUM 1.0 -+#endif /* MAINMENUHOOKS */ -+ -+#ifdef USE_PINPLUGIN -+#define PIN_PLUGIN_PATCH 120 -+#endif /* PINPLUGIN */ -+ -+#ifdef USE_PLUGINPARAM -+#define PLUGINPARAMPATCHVERSNUM 1 -+#endif /* PLUGINPARAM */ -+ - #define MAXPRIORITY 99 - #define MAXLIFETIME 99 - -+#ifdef USE_DVLVIDPREFER -+#define DVLVIDPREFER_MAX 12 -+#endif /* DVLVIDPREFER */ -+ - #define MINOSDWIDTH 480 - #define MAXOSDWIDTH 672 - #define MINOSDHEIGHT 324 - #define MAXOSDHEIGHT 567 - -+#ifdef USE_SOURCECAPS -+#define MAXDEVICES 16 // the maximum number of devices in the system -+#define MAXSOURCECAPS 128 // the maximum number of different sources per device -+#endif /* SOURCECAPS */ -+ -+#ifdef USE_LNBSHARE -+#ifndef MAXDEVICES -+#define MAXDEVICES 16 // the maximum number of devices in the system -+#endif -+#endif /* LNBSHARE */ -+ - #define MaxFileName 256 - #define MaxSkinName 16 - #define MaxThemeName 16 - -+#ifdef USE_CMDSUBMENU -+class cCommands; -+#endif /* CMDSUBMENU */ -+ - class cCommand : public cListObject { - private: - char *title; - char *command; - bool confirm; -+#ifdef USE_CMDSUBMENU -+ int nIndent; -+ cCommands *childs; -+#endif /* CMDSUBMENU */ - static char *result; - public: - cCommand(void); -@@ -61,6 +112,14 @@ public: - const char *Title(void) { return title; } - bool Confirm(void) { return confirm; } - const char *Execute(const char *Parameters = NULL); -+#ifdef USE_CMDSUBMENU -+ int getIndent(void) { return nIndent; } -+ void setIndent(int nNewIndent) { nIndent = nNewIndent; } -+ cCommands *getChilds(void) { return childs; } -+ int getChildCount(void); -+ bool hasChilds(void) { return getChildCount() > 0; } -+ void addChild(cCommand *newChild); -+#endif /* CMDSUBMENU */ - }; - - typedef uint32_t in_addr_t; //XXX from /usr/include/netinet/in.h (apparently this is not defined on systems with glibc < 2.2) -@@ -88,6 +147,9 @@ private: - public: - cConfig(void) { fileName = NULL; } - virtual ~cConfig() { free(fileName); } -+#ifdef USE_CMDSUBMENU -+ virtual void AddConfig(T *Object) { cList<T>::Add(Object); } -+#endif /* CMDSUBMENU */ - const char *FileName(void) { return fileName; } - bool Load(const char *FileName = NULL, bool AllowComments = false, bool MustExist = false) - { -@@ -117,7 +179,11 @@ public: - if (!isempty(s)) { - T *l = new T; - if (l->Parse(s)) -+#ifdef USE_CMDSUBMENU -+ AddConfig(l); -+#else - Add(l); -+#endif /* CMDSUBMENU */ - else { - esyslog("ERROR: error in %s, line %d", fileName, line); - delete l; -@@ -158,7 +224,14 @@ public: - } - }; - -+#ifdef USE_CMDSUBMENU -+class cCommands : public cConfig<cCommand> { -+public: -+ virtual void AddConfig(cCommand *Object); -+ }; -+#else - class cCommands : public cConfig<cCommand> {}; -+#endif /* CMDSUBMENU */ - - class cSVDRPhosts : public cConfig<cSVDRPhost> { - public: -@@ -167,6 +240,9 @@ public: - - extern cCommands Commands; - extern cCommands RecordingCommands; -+#ifdef USE_TIMERCMD -+extern cCommands TimerCommands; -+#endif /* TIMERCMD */ - extern cSVDRPhosts SVDRPhosts; - - class cSetupLine : public cListObject { -@@ -192,6 +268,10 @@ private: - void StoreLanguages(const char *Name, int *Values); - bool ParseLanguages(const char *Value, int *Values); - bool Parse(const char *Name, const char *Value); -+#ifdef USE_SOURCECAPS -+ void StoreSourceCaps(const char *Name); -+ bool ParseSourceCaps(const char *Value); -+#endif /* SOURCECAPS */ - cSetupLine *Get(const char *Name, const char *Plugin = NULL); - void Store(const char *Name, const char *Value, const char *Plugin = NULL, bool AllowMultiple = false); - void Store(const char *Name, int Value, const char *Plugin = NULL); -@@ -201,6 +281,12 @@ public: - char OSDLanguage[I18N_MAX_LOCALE_LEN]; - char OSDSkin[MaxSkinName]; - char OSDTheme[MaxThemeName]; -+#ifdef USE_WAREAGLEICON -+ int WarEagleIcons; -+#endif /* WAREAGLEICON */ -+#ifdef USE_VALIDINPUT -+ int ShowValidInput; -+#endif /* VALIDINPUT */ - int PrimaryDVB; - int ShowInfoOnChSwitch; - int TimeoutRequChInfo; -@@ -241,6 +327,14 @@ public: - int VideoFormat; - int UpdateChannels; - int UseDolbyDigital; -+#ifdef USE_DOLBYINREC -+ int UseDolbyInRecordings; -+#endif /* DOLBYINREC */ -+#ifdef USE_DVBSETUP -+ int DolbyTransferFix; -+ int ChannelBlocker; -+ int ChannelBlockerMode; -+#endif /* DVBSETUP */ - int ChannelInfoPos; - int ChannelInfoTime; - int OSDLeft, OSDTop, OSDWidth, OSDHeight; -@@ -254,20 +348,111 @@ public: - int FontSmlSize; - int FontFixSize; - int MaxVideoFileSize; -+#ifdef USE_HARDLINKCUTTER -+ int MaxRecordingSize; -+#endif /* HARDLINKCUTTER */ - int SplitEditedFiles; -+#ifdef USE_HARDLINKCUTTER -+ int HardLinkCutter; -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ int DelTimeshiftRec; -+#endif /* DELTIMESHIFTREC */ - int MinEventTimeout, MinUserInactivity; - time_t NextWakeupTime; - int MultiSpeedMode; - int ShowReplayMode; -+#ifdef USE_DDEPGENTRY -+ int DoubleEpgTimeDelta; -+ int DoubleEpgAction; -+ int MixEpgAction; -+ int DisableVPS; -+#endif /* DDEPGENTRY */ - int ResumeID; -+#ifdef USE_JUMPPLAY -+ int JumpPlay; -+ int PlayJump; -+ int PauseLastMark; -+ int ReloadMarks; -+#endif /* JUMPPLAY */ -+#ifdef USE_SOURCECAPS -+ int SourceCaps[MAXDEVICES][MAXSOURCECAPS]; -+ bool SourceCapsSet; -+#endif /* SOURCECAPS */ - int CurrentChannel; - int CurrentVolume; - int CurrentDolby; - int InitialChannel; - int InitialVolume; -+#ifdef USE_VOLCTRL -+ int LRVolumeControl; -+ int LRChannelGroups; -+ int LRForwardRewind; -+#endif /* VOLCTRL */ - int EmergencyExit; -+#ifdef USE_NOEPG -+ int noEPGMode; -+#endif /* NOEPG */ -+#ifdef USE_LIRCSETTINGS -+ int LircRepeatDelay; -+ int LircRepeatFreq; -+ int LircRepeatTimeout; -+#endif /* LIRCSETTINGS */ -+#ifdef USE_LIEMIEXT -+ int ShowRecDate, ShowRecTime, ShowRecLength, ShowProgressBar, MenuCmdPosition; -+ int JumpSeconds; -+ int JumpSecondsSlow; -+ int ShowTimerStop; -+ int MainMenuTitle; -+ char CustomMainMenuTitle[MaxTitleName]; -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ int RecordingsSortMode; -+ int RecordingsSortDirsFirst; -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ int CutterAutoDelete; -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ int CutTime; -+#endif /* CUTTIME */ -+#ifdef USE_DVDARCHIVE -+ int DvdDisplayMode; -+ int DvdDisplayZeros; -+ int DvdTrayMode; -+ int DvdSpeedLimit; -+#endif /* DVDARCHIVE */ -+#ifdef USE_SOFTOSD -+ int UseSoftOsd; -+ int SoftOsdRate; -+ int SoftOsdFadeinSteps; -+ int SoftOsdFadeoutSteps; -+ int SoftOsdPaletteOnly; -+#endif /* SOFTOSD */ -+#ifdef USE_LNBSHARE -+ int VerboseLNBlog; -+ int CardUsesLNBnr[MAXDEVICES]; -+#endif /* LNBSHARE */ -+#ifdef USE_DVLVIDPREFER -+ int UseVidPrefer; // 0 = VDR's default, 1 = use -+ int nVidPrefer; -+ int VidPreferPrio[DVLVIDPREFER_MAX]; -+ int VidPreferSize[DVLVIDPREFER_MAX]; -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLFRIENDLYFNAMES -+ int UseFriendlyFNames; -+#endif /* DVLFRIENDLYFNAMES */ - int __EndData__; -+#ifdef USE_DVBSETUP -+ char *ChannelBlockerList; -+#endif /* DVBSETUP */ -+#ifdef USE_NOEPG -+ char *noEPGList; // pointer not to be flat-copied -+#endif /* NOEPG */ - cSetup(void); -+#if defined (USE_DVBSETUP) || defined (USE_NOEPG) -+ ~cSetup(); -+#endif /* DVBSETUP + NOEPG */ - cSetup& operator= (const cSetup &s); - bool Load(const char *FileName); - bool Save(void); -@@ -275,4 +460,8 @@ public: - - extern cSetup Setup; - -+#ifdef USE_CMDRECCMDI18N -+bool LoadCommandsI18n(cCommands & cmds, const char *FileName = NULL, bool AllowComments = false, bool MustExist = false); -+#endif /* CMDRECCMDI18N */ -+ - #endif //__CONFIG_H -diff -ruNp vdr-1.7.5/cutter.c vdr-1.7.5-extensions/cutter.c ---- vdr-1.7.5/cutter.c 2009-01-24 16:19:26.000000000 +0100 -+++ vdr-1.7.5-extensions/cutter.c 2009-04-12 13:37:59.000000000 +0200 -@@ -15,6 +15,19 @@ - - // --- cCuttingThread -------------------------------------------------------- - -+#ifdef USE_CUTTERLIMIT -+#ifndef CUTTER_MAX_BANDWIDTH -+# define CUTTER_MAX_BANDWIDTH MEGABYTE(10) // 10 MB/s -+#endif -+#ifndef CUTTER_REL_BANDWIDTH -+# define CUTTER_REL_BANDWIDTH 75 // % -+#endif -+#ifndef CUTTER_PRIORITY -+# define CUTTER_PRIORITY sched_get_priority_min(SCHED_OTHER) -+#endif -+#define CUTTER_TIMESLICE 100 // ms -+#endif /* CUTTERLIMIT */ -+ - class cCuttingThread : public cThread { - private: - const char *error; -@@ -66,6 +79,22 @@ cCuttingThread::~cCuttingThread() - - void cCuttingThread::Action(void) - { -+#ifdef USE_CUTTERLIMIT -+#ifdef USE_HARDLINKCUTTER -+ if (!Setup.HardLinkCutter) -+#endif /* HARDLINKCUTTER */ -+ { -+ sched_param tmp; -+ tmp.sched_priority = CUTTER_PRIORITY; -+ if (!pthread_setschedparam(pthread_self(), SCHED_OTHER, &tmp)) -+ printf("cCuttingThread::Action: cant set priority\n"); -+ } -+ -+ int bytes = 0; -+ int __attribute__((unused)) burst_size = CUTTER_MAX_BANDWIDTH * CUTTER_TIMESLICE / 1000; // max bytes/timeslice -+ cTimeMs __attribute__((unused)) t; -+#endif /* CUTTERLIMIT */ -+ - cMark *Mark = fromMarks.First(); - if (Mark) { - fromFile = fromFileName->Open(); -@@ -77,6 +106,9 @@ void cCuttingThread::Action(void) - Mark = fromMarks.Next(Mark); - off_t FileSize = 0; - int CurrentFileNumber = 0; -+#ifdef USE_HARDLINKCUTTER -+ bool SkipThisSourceFile = false; -+#endif /* HARDLINKCUTTER */ - int LastIFrame = 0; - toMarks.Add(0); - toMarks.Save(); -@@ -95,12 +127,101 @@ void cCuttingThread::Action(void) - - // Read one frame: - -+#ifndef USE_HARDLINKCUTTER - if (fromIndex->Get(Index++, &FileNumber, &FileOffset, &Independent, &Length)) { - if (FileNumber != CurrentFileNumber) { - fromFile = fromFileName->SetOffset(FileNumber, FileOffset); - fromFile->SetReadAhead(MEGABYTE(20)); - CurrentFileNumber = FileNumber; - } -+#else -+ if (!fromIndex->Get(Index++, &FileNumber, &FileOffset, &Independent, &Length)) { -+ // Error, unless we're past last cut-in and there's no cut-out -+ if (Mark || LastMark) -+ error = "index"; -+ break; -+ } -+ -+ if (FileNumber != CurrentFileNumber) { -+ fromFile = fromFileName->SetOffset(FileNumber, FileOffset); -+ fromFile->SetReadAhead(MEGABYTE(20)); -+ CurrentFileNumber = FileNumber; -+ if (SkipThisSourceFile) { -+ // At end of fast forward: Always skip to next file -+ toFile = toFileName->NextFile(); -+ if (!toFile) { -+ error = "toFile 4"; -+ break; -+ } -+ FileSize = 0; -+ SkipThisSourceFile = false; -+ } -+ -+ -+ if (Setup.HardLinkCutter && FileOffset == 0) { -+ // We are at the beginning of a new source file. -+ // Do we need to copy the whole file? -+ -+ // if !Mark && LastMark, then we're past the last cut-out and continue to next I-frame -+ // if !Mark && !LastMark, then there's just a cut-in, but no cut-out -+ // if Mark, then we're between a cut-in and a cut-out -+ -+ uint16_t MarkFileNumber; -+ off_t MarkFileOffset; -+ // Get file number of next cut mark -+ if (!Mark && !LastMark -+ || Mark -+ && fromIndex->Get(Mark->position, &MarkFileNumber, &MarkFileOffset) -+ && (MarkFileNumber != CurrentFileNumber)) { -+ // The current source file will be copied completely. -+ // Start new output file unless we did that already -+ if (FileSize != 0) { -+ toFile = toFileName->NextFile(); -+ if (!toFile) { -+ error = "toFile 3"; -+ break; -+ } -+ FileSize = 0; -+ } -+ -+ // Safety check that file has zero size -+ struct stat buf; -+ if (stat(toFileName->Name(), &buf) == 0) { -+ if (buf.st_size != 0) { -+ esyslog("cCuttingThread: File %s exists and has nonzero size", toFileName->Name()); -+ error = "nonzero file exist"; -+ break; -+ } -+ } -+ else if (errno != ENOENT) { -+ esyslog("cCuttingThread: stat failed on %s", toFileName->Name()); -+ error = "stat"; -+ break; -+ } -+ -+ // Clean the existing 0-byte file -+ toFileName->Close(); -+ cString ActualToFileName(ReadLink(toFileName->Name()), true); -+ unlink(ActualToFileName); -+ unlink(toFileName->Name()); -+ -+ // Try to create a hard link -+ if (HardLinkVideoFile(fromFileName->Name(), toFileName->Name())) { -+ // Success. Skip all data transfer for this file -+ SkipThisSourceFile = true; -+ cutIn = false; -+ toFile = NULL; // was deleted by toFileName->Close() -+ } -+ else { -+ // Fallback: Re-open the file if necessary -+ toFile = toFileName->Open(); -+ } -+ } -+ } -+ } -+ -+ if (!SkipThisSourceFile) { -+#endif /* HARDLINKCUTTER */ - if (fromFile) { - int len = ReadFrame(fromFile, buffer, Length, sizeof(buffer)); - if (len < 0) { -@@ -117,6 +238,7 @@ void cCuttingThread::Action(void) - break; - } - } -+#ifndef USE_HARDLINKCUTTER - else { - // Error, unless we're past the last cut-in and there's no cut-out - if (Mark || LastMark) -@@ -124,12 +246,17 @@ void cCuttingThread::Action(void) - break; - } - -+#endif /* HARDLINKCUTTER */ - // Write one frame: - - if (Independent) { // every file shall start with an independent frame - if (LastMark) // edited version shall end before next I-frame - break; -+#ifndef USE_HARDLINKCUTTER - if (FileSize > maxVideoFileSize) { -+#else -+ if (!SkipThisSourceFile && FileSize > toFileName->MaxFileSize()) { -+#endif /* HARDLINKCUTTER */ - toFile = toFileName->NextFile(); - if (!toFile) { - error = "toFile 1"; -@@ -139,12 +266,20 @@ void cCuttingThread::Action(void) - } - LastIFrame = 0; - -+#ifndef USE_HARDLINKCUTTER - if (cutIn) { -+#else -+ if (!SkipThisSourceFile && cutIn) { -+#endif /* HARDLINKCUTTER */ - cRemux::SetBrokenLink(buffer, Length); - cutIn = false; - } - } -+#ifndef USE_HARDLINKCUTTER - if (toFile->Write(buffer, Length) < 0) { -+#else -+ if (!SkipThisSourceFile && toFile->Write(buffer, Length) < 0) { -+#endif /* HARDLINKCUTTER */ - error = "safe_write"; - break; - } -@@ -179,8 +314,44 @@ void cCuttingThread::Action(void) - } - } - else -+#ifndef USE_HARDLINKCUTTER - LastMark = true; -+#else -+ LastMark = true; // After last cut-out: Write on until next I-frame, then exit -+#endif /* HARDLINKCUTTER */ - } -+#ifdef USE_CUTTERLIMIT -+#ifdef USE_HARDLINKCUTTER -+ if (!Setup.HardLinkCutter) { -+#endif /* HARDLINKCUTTER */ -+ bytes += Length; -+ if (bytes >= burst_size) { -+ int elapsed = t.Elapsed(); -+ int sleep = 0; -+ -+#if CUTTER_REL_BANDWIDTH > 0 && CUTTER_REL_BANDWIDTH < 100 -+ // stay under max. relative bandwidth -+ -+ sleep = (elapsed * 100 / CUTTER_REL_BANDWIDTH) - elapsed; -+ //if (sleep<=0 && elapsed<=2) sleep = 1; -+ //if (sleep) esyslog("cutter: relative bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE); -+#endif -+ // stay under max. absolute bandwidth -+ if (elapsed < CUTTER_TIMESLICE) { -+ sleep = max(CUTTER_TIMESLICE - elapsed, sleep); -+ //if (sleep) esyslog("cutter: absolute bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE); -+ } -+ -+ if (sleep>0) -+ cCondWait::SleepMs(sleep); -+ t.Set(); -+ bytes = 0; -+ } -+#ifdef USE_HARDLINKCUTTER -+ } -+#endif /* HARDLINKCUTTER */ -+#endif /* CUTTERLIMIT */ -+ - } - Recordings.TouchUpdate(); - } -@@ -190,18 +361,74 @@ void cCuttingThread::Action(void) - - // --- cCutter --------------------------------------------------------------- - -+#ifdef USE_CUTTERQUEUE -+#define WAIT_BEFORE_NEXT_CUT (10*1000) // 10 seconds -+ -+class cStringListObject : public cListObject { -+ public: -+ cStringListObject(const char *s) { str = strdup(s); } -+ ~cStringListObject() { free(str); } -+ -+ const char *Value() { return str; } -+ operator const char * () { return str; } -+ -+ private: -+ char *str; -+}; -+#endif /* CUTTERQUEUE */ -+ - char *cCutter::editedVersionName = NULL; - cCuttingThread *cCutter::cuttingThread = NULL; - bool cCutter::error = false; - bool cCutter::ended = false; -+#ifdef USE_CUTTERQUEUE -+cMutex *cCutter::cutterLock = new cMutex(); -+static uint64_t /*cCutter::*/lastCuttingEndTime = 0; -+static cList<cStringListObject> /**cCutter::*/cutterQueue /*= new cList<cStringListObject>*/; -+#endif /* CUTTERQUEUE */ - - bool cCutter::Start(const char *FileName) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+ if (FileName) { -+ /* Add file to queue. -+ * If cutter is still active, next cutting will be started -+ * when vdr.c:main calls cCutter::Active and previous cutting has -+ * been stopped > 10 s before -+ */ -+ cutterQueue.Add(new cStringListObject(FileName)); -+ } -+ if (cuttingThread) -+ return true; -+ /* cut next file from queue */ -+ if (!(cutterQueue.First())) -+ return false; -+ FileName = cutterQueue.First()->Value(); -+#endif /* CUTTERQUEUE */ - if (!cuttingThread) { - error = false; - ended = false; - cRecording Recording(FileName); -+#ifdef USE_CUTTIME -+ if (Setup.CutTime) { -+ cMarks FromMarks; -+ FromMarks.Load(FileName); -+ cMark *First = FromMarks.First(); -+ if (First) Recording.SetStartTime(Recording.start + (int(First->position / Recording.FramesPerSecond() +30) / 60) * 60); -+ } -+#endif /* CUTTIME */ - const char *evn = Recording.PrefixFileName('%'); -+#ifdef USE_CUTTERQUEUE -+ if (!(Recordings.GetByName(FileName))) { -+ // Should _not_ remove any cutted recordings -+ // (original recording already deleted ?) -+ // so, just pop item from queue and return. -+ esyslog("can't cut non-existing recording %s", FileName); -+ cutterQueue.Del(cutterQueue.First()); -+ return true; // might be already queued recording -+ } -+#endif /* CUTTERQUEUE */ - if (evn && RemoveVideoFile(evn) && MakeDirs(evn, true)) { - // XXX this can be removed once RenameVideoFile() follows symlinks (see videodir.c) - // remove a possible deleted recording with the same name to avoid symlink mixups: -@@ -227,6 +454,9 @@ bool cCutter::Start(const char *FileName - - void cCutter::Stop(void) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+#endif /* CUTTERQUEUE */ - bool Interrupted = cuttingThread && cuttingThread->Active(); - const char *Error = cuttingThread ? cuttingThread->Error() : NULL; - delete cuttingThread; -@@ -238,11 +468,20 @@ void cCutter::Stop(void) - esyslog("ERROR: '%s' during editing process", Error); - RemoveVideoFile(editedVersionName); //XXX what if this file is currently being replayed? - Recordings.DelByName(editedVersionName); -+#ifdef USE_CUTTERQUEUE -+ cutterQueue.Del(cutterQueue.First()); -+#endif /* CUTTERQUEUE */ - } -+#ifdef USE_CUTTERQUEUE -+ lastCuttingEndTime = cTimeMs::Now(); -+#endif /* CUTTERQUEUE */ - } - - bool cCutter::Active(void) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+#endif /* CUTTERQUEUE */ - if (cuttingThread) { - if (cuttingThread->Active()) - return true; -@@ -253,12 +492,40 @@ bool cCutter::Active(void) - free(editedVersionName); - editedVersionName = NULL; - ended = true; -+#ifdef USE_CUTTERQUEUE -+ if (Setup.CutterAutoDelete) { -+ /* Remove original (if cutting was successful) */ -+ if (!error) { -+ cRecording *recording = Recordings.GetByName(*cutterQueue.First()); -+ if (!recording) -+ esyslog("ERROR: Can't found '%s' after editing process", cutterQueue.First()->Value()); -+ else { -+ if (recording->Delete()) -+ Recordings.DelByName(recording->FileName()); -+ else -+ esyslog("ERROR: Can't delete '%s' after editing process", cutterQueue.First()->Value()); -+ } -+ } -+ lastCuttingEndTime = cTimeMs::Now(); -+ } -+ cutterQueue.Del(cutterQueue.First()); -+#endif /* CUTTERQUEUE */ -+ } -+#ifdef USE_CUTTERQUEUE -+ if (!cuttingThread && cutterQueue.First()) { -+ /* start next cutting from queue*/ -+ if (cTimeMs::Now() > lastCuttingEndTime + WAIT_BEFORE_NEXT_CUT) -+ Start(NULL); - } -+#endif /* CUTTERQUEUE */ - return false; - } - - bool cCutter::Error(void) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+#endif /* CUTTERQUEUE */ - bool result = error; - error = false; - return result; -@@ -266,6 +533,9 @@ bool cCutter::Error(void) - - bool cCutter::Ended(void) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+#endif /* CUTTERQUEUE */ - bool result = ended; - ended = false; - return result; -diff -ruNp vdr-1.7.5/cutter.h vdr-1.7.5-extensions/cutter.h ---- vdr-1.7.5/cutter.h 2002-06-22 12:03:15.000000000 +0200 -+++ vdr-1.7.5-extensions/cutter.h 2009-04-12 13:37:59.000000000 +0200 -@@ -11,6 +11,9 @@ - #define __CUTTER_H - - class cCuttingThread; -+#ifdef USE_CUTTERQUEUE -+class cMutex; -+#endif /* CUTTERQUEUE */ - - class cCutter { - private: -@@ -18,6 +21,9 @@ private: - static cCuttingThread *cuttingThread; - static bool error; - static bool ended; -+#ifdef USE_CUTTERQUEUE -+ static cMutex *cutterLock; -+#endif /* CUTTERQUEUE */ - public: - static bool Start(const char *FileName); - static void Stop(void); -diff -ruNp vdr-1.7.5/device.c vdr-1.7.5-extensions/device.c ---- vdr-1.7.5/device.c 2009-04-05 14:15:41.000000000 +0200 -+++ vdr-1.7.5-extensions/device.c 2009-04-12 13:37:59.000000000 +0200 -@@ -19,6 +19,14 @@ - #include "status.h" - #include "transfer.h" - -+#ifdef USE_LNBSHARE -+#include "diseqc.h" -+#endif /* LNBSHARE */ -+ -+#ifdef USE_CHANNELSCAN -+bool scanning_on_receiving_device = false; -+#endif /* CHANNELSCAN */ -+ - // --- cLiveSubtitle --------------------------------------------------------- - - class cLiveSubtitle : public cReceiver { -@@ -68,6 +76,12 @@ cDevice::cDevice(void) - - SetVideoFormat(Setup.VideoFormat); - -+#ifdef USE_LNBSHARE -+ LNBstate = -1; -+ LNBnr = Setup.CardUsesLNBnr[cardIndex]; -+ LNBsource = NULL; -+#endif /* LNBSHARE */ -+ - mute = false; - volume = Setup.CurrentVolume; - -@@ -93,8 +107,15 @@ cDevice::cDevice(void) - for (int i = 0; i < MAXRECEIVERS; i++) - receiver[i] = NULL; - -+#ifdef USE_SOURCECAPS -+ if (numDevices < MAXDEVICES) { -+ device[numDevices++] = this; -+ SetSourceCaps(cardIndex); -+ } -+#else - if (numDevices < MAXDEVICES) - device[numDevices++] = this; -+#endif /* SOURCECAPS */ - else - esyslog("ERROR: too many devices!"); - } -@@ -129,6 +150,16 @@ void cDevice::SetUseDevice(int n) - useDevice |= (1 << n); - } - -+#ifdef USE_LNBSHARE -+void cDevice::SetLNBnr(void) -+{ -+ for (int i = 0; i < numDevices; i++) { -+ device[i]->LNBnr = Setup.CardUsesLNBnr[i]; -+ isyslog("LNB-sharing: setting device %d to use LNB %d", i, device[i]->LNBnr); -+ } -+} -+#endif /* LNBSHARE */ -+ - int cDevice::NextCardIndex(int n) - { - if (n > 0) { -@@ -189,6 +220,98 @@ cDevice *cDevice::ActualDevice(void) - return d; - } - -+#ifdef USE_LNBSHARE -+cDevice *cDevice::GetBadDevice(const cChannel *Channel) -+{ -+ if (!cSource::IsSat(Channel->Source())) -+ return NULL; -+ if (Setup.DiSEqC) { -+ cDiseqc *diseqc; -+ diseqc = Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); -+ -+ for (int i = 0; i < numDevices; i++) { -+ if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBsource() != (int*) diseqc) { -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Device check for channel %d on device %d. LNB or DiSEq conflict with device %d", LNBnr, Channel->Number(), this->DeviceNumber(), i); -+ return device[i]; -+ } -+ } -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Device check for for channel %d on device %d. OK", LNBnr, Channel->Number(), this->DeviceNumber()); -+ } -+ else { -+ char requiredState; -+ -+ if (Channel->Frequency() >= Setup.LnbSLOF) -+ requiredState = 1 ; -+ else -+ requiredState = 0; -+ -+ if (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') -+ requiredState += 2; -+ -+ for (int i = 0; i < numDevices; i++) { -+ if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBconf() != requiredState) { -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Device check for channel %d, LNBstate %d on device %d, current LNBstate %d. Conflict with device %d, LNBstate %d", LNBnr, Channel->Number(), requiredState, this->DeviceNumber(), LNBstate, i, device[i]->GetLNBconf()); -+ return device[i]; -+ } -+ } -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Device check for channel %d, LNBstate %d on device %d, current LNBstate %d. No other devices affected", LNBnr, Channel->Number(), requiredState, this->DeviceNumber(), LNBstate); -+ } -+ return NULL; -+} -+ -+int cDevice::GetMaxBadPriority(const cChannel *Channel) -+{ -+ if (!cSource::IsSat(Channel->Source())) return -2; -+ bool PrimaryIsBad = false; -+ int maxBadPriority = -2; -+ -+ if (Setup.DiSEqC) { -+ cDiseqc *diseqc; -+ diseqc = Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); -+ -+ for (int i = 0; i < numDevices; i++) { -+ if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBsource() != (int*) diseqc) { -+ if (device[i]->Receiving() && device[i]->Priority() > maxBadPriority) -+ maxBadPriority = device[i]->Priority(); -+ if (i == ActualDevice()->CardIndex()) -+ PrimaryIsBad = true; -+ } -+ } -+ } -+ else { -+ char requiredState; -+ if (Channel->Frequency() >= Setup.LnbSLOF) -+ requiredState = 1 ; -+ else -+ requiredState = 0; -+ -+ if (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') -+ requiredState += 2; -+ -+ for (int i = 0; i < numDevices; i++) { -+ if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBconf() != requiredState) { -+ if (device[i]->Receiving() && device[i]->Priority() > maxBadPriority) -+ maxBadPriority = device[i]->Priority(); -+ if (i == ActualDevice()->CardIndex()) -+ PrimaryIsBad = true; -+ } -+ } -+ } -+ -+ if (PrimaryIsBad && maxBadPriority == -2) -+ maxBadPriority = -1; -+ -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Request for channel %d on device %d. MaxBadPriority is %d", LNBnr, Channel->Number(), this->DeviceNumber(), maxBadPriority); -+ -+ return maxBadPriority; -+} -+#endif /* LNBSHARE */ -+ - cDevice *cDevice::GetDevice(int Index) - { - return (0 <= Index && Index < numDevices) ? device[Index] : NULL; -@@ -238,6 +361,10 @@ cDevice *cDevice::GetDevice(const cChann - cCamSlot *s = NULL; - - uint32_t Impact = 0xFFFFFFFF; // we're looking for a device with the least impact -+#ifdef USE_LNBSHARE -+ int badPriority; -+ uint imp2; -+#endif /* LNBSHARE */ - for (int j = 0; j < NumCamSlots || !NumUsableSlots; j++) { - if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) - continue; // there is no CAM available in this slot -@@ -271,7 +398,31 @@ cDevice *cDevice::GetDevice(const cChann - imp <<= 1; imp |= NumUsableSlots ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels - imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards - imp <<= 1; imp |= NumUsableSlots ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel -+#ifdef USE_LNBSHARE -+ badPriority = device[i]->GetMaxBadPriority(Channel); -+ if (badPriority >= Priority || (badPriority == -1 && Priority < Setup.PrimaryLimit)) { -+ // channel is not available for the requested prioity -+ imp = 0xFFFFFFFF; -+ } -+ else { -+ switch (badPriority) { -+ case -2: // not affected by LNB-sharing -+ imp2 = 0; -+ break; -+ case -1: // the primary device would need a channel switch -+ imp += 1 << 17; -+ imp2 = 0xFFFFFFFF | 1 << 17; -+ break; -+ default: // a device receiving with lower priority would need to be stopped -+ imp += badPriority << 8; -+ imp2 = 0xFFFFFFFF | badPriority << 8; -+ break; -+ } -+ } -+ if (imp < Impact && imp2 < Impact) { -+#else - if (imp < Impact) { -+#endif /* LNBSHARE */ - // This device has less impact than any previous one, so we take it. - Impact = imp; - d = device[i]; -@@ -312,6 +463,18 @@ void cDevice::SetCamSlot(cCamSlot *CamSl - camSlot = CamSlot; - } - -+#ifdef USE_SOURCECAPS -+void cDevice::SetSourceCaps(int Index) -+{ -+ for (int d = 0; d < numDevices; d++) { -+ if (Index < 0 || Index == device[d]->CardIndex()) { -+ for (int i = 0; i < MAXSOURCECAPS; i++) -+ device[d]->sourceCaps[i] = Setup.SourceCaps[device[d]->CardIndex()][i]; -+ } -+ } -+} -+#endif /* SOURCECAPS */ -+ - void cDevice::Shutdown(void) - { - primaryDevice = NULL; -@@ -556,7 +719,11 @@ bool cDevice::ProvidesTransponder(const - bool cDevice::ProvidesTransponderExclusively(const cChannel *Channel) const - { - for (int i = 0; i < numDevices; i++) { -+#ifdef USE_LNBSHARE -+ if (device[i] && device[i] != this && device[i]->ProvidesTransponder(Channel) && device[i]->GetLNBnr() != LNBnr) -+#else - if (device[i] && device[i] != this && device[i]->ProvidesTransponder(Channel)) -+#endif /* LNBSHARE */ - return false; - } - return true; -@@ -584,6 +751,24 @@ bool cDevice::MaySwitchTransponder(void) - - bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView) - { -+#ifdef USE_LNBSHARE -+ cDevice *tmpDevice; -+ if (this->GetMaxBadPriority(Channel) >= 0) { -+ Skins.Message(mtInfo, tr("Channel locked by LNB!")); -+ return false; -+ } -+ while ((tmpDevice = GetBadDevice(Channel)) != NULL) { -+ if (tmpDevice->IsPrimaryDevice() && LiveView) -+ tmpDevice->SwitchChannelForced(Channel, true); -+ else -+ tmpDevice->SwitchChannelForced(Channel, false); -+ } -+ return SwitchChannelForced(Channel, LiveView); -+} -+ -+bool cDevice::SwitchChannelForced(const cChannel *Channel, bool LiveView) -+{ -+#endif /* LNBSHARE */ - if (LiveView) { - isyslog("switching to channel %d", Channel->Number()); - cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer -@@ -613,7 +798,14 @@ bool cDevice::SwitchChannel(int Directio - cChannel *channel; - while ((channel = Channels.GetByNumber(n, Direction)) != NULL) { - // try only channels which are currently available -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgChannelProtected(0, channel) == false) -+#endif /* PINPLUGIN */ -+#ifdef USE_LNBSHARE -+ if (PrimaryDevice()->GetMaxBadPriority(channel) < 0 && (GetDevice(channel, 0, true))) -+#else - if (GetDevice(channel, 0, true)) -+#endif /* LNBSHARE */ - break; - n = channel->Number() + Direction; - } -@@ -634,6 +826,13 @@ bool cDevice::SwitchChannel(int Directio - - eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) - { -+#ifdef USE_PINPLUGIN -+ // I hope 'LiveView = false' indicates a channel switch for recording, -+ // I really don't know, but it works ... -+ if (LiveView && cStatus::MsgChannelProtected(this, Channel) == true) -+ return scrNotAvailable; -+#endif /* PINPLUGIN */ -+ - if (LiveView) { - StopReplay(); - DELETENULL(liveSubtitle); -@@ -646,11 +845,37 @@ eSetChannelResult cDevice::SetChannel(co - - eSetChannelResult Result = scrOk; - -+#ifdef USE_LNBSHARE -+ char requiredState; -+ if (Channel->Frequency() >= Setup.LnbSLOF) -+ requiredState = 1; -+ else -+ requiredState = 0; -+ -+ if (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') -+ requiredState += 2; -+ -+ if (Setup.VerboseLNBlog) -+ isyslog("LNB %d: Switching device %d to channel %d", LNBnr, this->DeviceNumber(), Channel->Number()); -+#endif /* LNBSHARE */ -+ - // If this DVB card can't receive this channel, let's see if we can - // use the card that actually can receive it and transfer data from there: - - if (NeedsTransferMode) { - if (Device && CanReplay()) { -+#ifdef USE_LNBSHARE -+ if (Device->GetLNBnr() == LNBnr) { -+ if (LNBstate != requiredState || (Setup.DiSEqC && LNBsource != (int*) Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization())) ) { -+ if (IsPrimaryDevice()) -+ SetChannelDevice(Channel, true); -+ else -+ SetChannelDevice(Channel, false); -+ LNBstate = requiredState; -+ LNBsource = (int*) Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); -+ } -+ } -+#endif /* LNBSHARE */ - cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel - if (Device->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()! - cControl::Launch(new cTransferControl(Device, Channel->GetChannelID(), Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids())); -@@ -668,6 +893,10 @@ eSetChannelResult cDevice::SetChannel(co - sectionHandler->SetStatus(false); - sectionHandler->SetChannel(NULL); - } -+#ifdef USE_LNBSHARE -+ LNBstate = requiredState; -+ LNBsource = (int*) Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); -+#endif /* LNBSHARE */ - // Tell the camSlot about the channel switch and add all PIDs of this - // channel to it, for possible later decryption: - if (camSlot) -@@ -960,7 +1189,12 @@ void cDevice::EnsureSubtitleTrack(void) - int LanguagePreference = INT_MAX; // higher than the maximum possible value - for (int i = ttSubtitleFirst; i <= ttSubtitleLast; i++) { - const tTrackId *TrackId = GetTrack(eTrackType(i)); -+#ifdef USE_LIEMIEXT -+ if (TrackId && TrackId->id && (I18nIsPreferredLanguage(Setup.SubtitleLanguages, TrackId->language, LanguagePreference) || -+ ((i == ttSubtitleFirst + 8) && !(*TrackId->language) && (LanguagePreference == INT_MAX)))) -+#else - if (TrackId && TrackId->id && I18nIsPreferredLanguage(Setup.SubtitleLanguages, TrackId->language, LanguagePreference)) -+#endif /* LIEMIEXT */ - PreferredTrack = eTrackType(i); - } - // Make sure we're set to an available subtitle track: -@@ -1192,7 +1426,11 @@ pre_1_3_19_PrivateStreamDetected: - w = PlaySubtitle(Start, d); - break; - case 0x80: // AC3 & DTS -+#ifdef USE_DOLBYINREC -+ if (Setup.UseDolbyInRecordings) { -+#else - if (Setup.UseDolbyDigital) { -+#endif /* DOLBYINREC */ - SetAvailableTrack(ttDolby, SubStreamIndex, SubStreamId); - if ((!VideoOnly || HasIBPTrickSpeed()) && SubStreamId == availableTracks[currentAudioTrack].id) { - w = PlayAudio(Start, d, SubStreamId); -diff -ruNp vdr-1.7.5/device.h vdr-1.7.5-extensions/device.h ---- vdr-1.7.5/device.h 2009-04-05 14:12:44.000000000 +0200 -+++ vdr-1.7.5-extensions/device.h 2009-04-12 13:37:59.000000000 +0200 -@@ -24,13 +24,22 @@ - #include "spu.h" - #include "thread.h" - #include "tools.h" -+#ifdef USE_ROTOR -+#include <linux/dvb/frontend.h> -+#endif /* ROTOR */ - -+#ifndef USE_SOURCECAPS - #define MAXDEVICES 16 // the maximum number of devices in the system -+#endif /* SOURCECAPS */ - #define MAXPIDHANDLES 64 // the maximum number of different PIDs per device - #define MAXRECEIVERS 16 // the maximum number of receivers per device - #define MAXVOLUME 255 - #define VOLUMEDELTA 5 // used to increase/decrease the volume - -+#ifdef USE_CHANNELSCAN -+extern bool scanning_on_receiving_device; -+#endif /* CHANNELSCAN */ -+ - enum eSetChannelResult { scrOk, scrNotAvailable, scrNoTransfer, scrFailed }; - - enum ePlayMode { pmNone, // audio/video from decoder -@@ -142,6 +151,35 @@ public: - ///< this device/CAM combination will be skipped in the next call to - ///< GetDevice(). - ///< See also ProvidesChannel(). -+#ifdef USE_SOURCECAPS -+ static void SetSourceCaps(int Index = -1); -+ ///< Sets the SourceCaps of the given device according to the Setup data. -+#endif /* SOURCECAPS */ -+#ifdef USE_LNBSHARE -+private: -+ char LNBstate; // Current frequency band and polarization of the DVB-tuner -+// cDiseqc *LNBsource; // can not #include "diseqc.h". A workaround follows: -+ int *LNBsource; // [DiSEqC] DiSEqC-Source -+ int LNBnr; // Number of LNB used -+public: -+ char GetLNBconf(void) { return LNBstate; } -+ int *GetLNBsource(void) { return LNBsource; } -+ int GetLNBnr(void) { return LNBnr; } -+ static void SetLNBnr(void); -+ cDevice *GetBadDevice(const cChannel *Channel); -+ ///< Returns NULL if there is no device which uses the same LNB or if -+ ///< all of those devices are tuned to the same frequency band and -+ ///< polarization as of the requested channel. -+ ///< Otherwise returns the first device found. -+ int GetMaxBadPriority(const cChannel *Channel); -+ ///< Returns the highest priority of all receiving devices which use -+ ///< the same LNB and are tuned to a different frequency band or -+ ///< polarization as of the requested channel. -+ ///< Returns -1 if there are no such devices, but the primary device -+ ///< would be affected by switching to the requested channel. -+ ///< Returns -2 if there are no such devices and the primary device -+ ///< would not be affected by switching to the requested channel. -+#endif /* LNBSHARE */ - static void SetAvoidDevice(cDevice *Device) { avoidDevice = Device; } - ///< Sets the given Device to be temporarily avoided in the next call to - ///< GetDevice(const cChannel, int, bool). -@@ -152,6 +190,9 @@ private: - static int nextCardIndex; - int cardIndex; - protected: -+#ifdef USE_SOURCECAPS -+ int sourceCaps[MAXSOURCECAPS]; -+#endif /* SOURCECAPS */ - cDevice(void); - virtual ~cDevice(); - virtual bool Ready(void); -@@ -239,17 +280,30 @@ public: - bool SwitchChannel(const cChannel *Channel, bool LiveView); - ///< Switches the device to the given Channel, initiating transfer mode - ///< if necessary. -+ -+#ifdef USE_LNBSHARE -+ bool SwitchChannelForced(const cChannel *Channel, bool LiveView); -+ ///< Switches the device to the given channel, initiating transfer mode -+ ///< if necessary. Forces the switch without taking care of the LNB configuration. -+#endif /* LNBSHARE */ -+ - static bool SwitchChannel(int Direction); - ///< Switches the primary device to the next available channel in the given - ///< Direction (only the sign of Direction is evaluated, positive values - ///< switch to higher channel numbers). - private: -+#ifndef USE_YAEPG - eSetChannelResult SetChannel(const cChannel *Channel, bool LiveView); - ///< Sets the device to the given channel (general setup). -+#endif /* YAEPG */ - protected: - virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); - ///< Sets the device to the given channel (actual physical setup). - public: -+#ifdef USE_YAEPG -+ eSetChannelResult SetChannel(const cChannel *Channel, bool LiveView); -+ ///< Sets the device to the given channel (general setup). -+#endif /* YAEPG */ - static int CurrentChannel(void) { return primaryDevice ? currentChannel : 0; } - ///< Returns the number of the current channel on the primary device. - static void SetCurrentChannel(const cChannel *Channel) { currentChannel = Channel ? Channel->Number() : 0; } -@@ -267,6 +321,9 @@ public: - virtual bool HasProgramme(void); - ///< Returns true if the device is currently showing any programme to - ///< the user, either through replaying or live. -+#ifdef USE_ROTOR -+ virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd) { return false; } -+#endif /* ROTOR */ - - // PID handle facilities - -diff -ruNp vdr-1.7.5/dvbdevice.c vdr-1.7.5-extensions/dvbdevice.c ---- vdr-1.7.5/dvbdevice.c 2009-04-10 11:54:24.000000000 +0200 -+++ vdr-1.7.5-extensions/dvbdevice.c 2009-04-12 13:37:59.000000000 +0200 -@@ -71,6 +71,9 @@ static int DvbOpen(const char *Name, int - class cDvbTuner : public cThread { - private: - enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked }; -+#ifdef USE_ROTOR -+ bool SendDiseqc; -+#endif /* ROTOR */ - int fd_frontend; - int cardIndex; - int tuneTimeout; -@@ -83,6 +86,9 @@ private: - cMutex mutex; - cCondVar locked; - cCondVar newSet; -+#ifdef USE_ROTOR -+ dvb_diseqc_master_cmd diseqc_cmd; -+#endif /* ROTOR */ - bool GetFrontendStatus(fe_status_t &Status, int TimeoutMs = 0); - bool SetFrontend(void); - virtual void Action(void); -@@ -91,12 +97,18 @@ public: - virtual ~cDvbTuner(); - bool IsTunedTo(const cChannel *Channel) const; - void Set(const cChannel *Channel, bool Tune); -+#ifdef USE_ROTOR -+ bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd); -+#endif /* ROTOR */ - bool Locked(int TimeoutMs = 0); - }; - - cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_delivery_system FrontendType) - { - fd_frontend = Fd_Frontend; -+#ifdef USE_ROTOR -+ SendDiseqc = false; -+#endif /* ROTOR */ - cardIndex = CardIndex; - frontendType = FrontendType; - tuneTimeout = 0; -@@ -163,6 +175,19 @@ bool cDvbTuner::Locked(int TimeoutMs) - return tunerStatus >= tsLocked; - } - -+#ifdef USE_ROTOR -+bool cDvbTuner::SendDiseqcCmd(dvb_diseqc_master_cmd cmd) -+{ -+ cMutexLock MutexLock(&mutex); -+ if ((!SYS_DVBS & !SYS_DVBS2) || SendDiseqc) -+ return false; -+ diseqc_cmd = cmd; -+ SendDiseqc = true; -+ newSet.Broadcast(); -+ return true; -+} -+#endif /* ROTOR */ -+ - bool cDvbTuner::GetFrontendStatus(fe_status_t &Status, int TimeoutMs) - { - if (TimeoutMs) { -@@ -241,6 +266,9 @@ bool cDvbTuner::SetFrontend(void) - } - } - diseqcCommands = diseqc->Commands(); -+#ifdef USE_DVBSETUP -+ isyslog("Sent DISEQC command: %s", diseqcCommands); -+#endif /* DVBSETUP */ - } - frequency -= diseqc->Lof(); - } -@@ -303,6 +331,18 @@ bool cDvbTuner::SetFrontend(void) - tuneTimeout = DVBC_TUNE_TIMEOUT; - lockTimeout = DVBC_LOCK_TIMEOUT; - } -+#ifdef USE_ATSC -+ else if (frontendType == SYS_ATSC) { -+ // ATSC -+ SETCMD(DTV_DELIVERY_SYSTEM, frontendType); -+ SETCMD(DTV_FREQUENCY, FrequencyToHz(channel.Frequency())); -+ SETCMD(DTV_INVERSION, channel.Inversion()); -+ SETCMD(DTV_MODULATION, channel.Modulation()); -+ -+ tuneTimeout = DVBT_TUNE_TIMEOUT; -+ lockTimeout = DVBT_LOCK_TIMEOUT; -+ } -+#endif /* ATSC */ - else if (frontendType == SYS_DVBT) { - // DVB-T - SETCMD(DTV_DELIVERY_SYSTEM, frontendType); -@@ -341,6 +381,12 @@ void cDvbTuner::Action(void) - if (GetFrontendStatus(NewStatus, 10)) - Status = NewStatus; - cMutexLock MutexLock(&mutex); -+#ifdef USE_ROTOR -+ if (SendDiseqc) { -+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &diseqc_cmd)); -+ SendDiseqc = false; -+ } -+#endif /* ROTOR */ - switch (tunerStatus) { - case tsIdle: - break; -@@ -483,6 +529,11 @@ cDvbDevice::cDvbDevice(int n) - - if (fd_frontend >= 0) { - if (ioctl(fd_frontend, FE_GET_INFO, &frontendInfo) >= 0) { -+#ifdef USE_DVBSETUP -+ if (Setup.ChannelBlockerMode == 4) -+ frontendType = (n == Setup.PrimaryDVB - 1) ? SYS_UNDEFINED : frontendType; -+ else -+#endif /* DVBSETUP */ - switch (frontendInfo.type) { - case FE_QPSK: frontendType = (frontendInfo.caps & FE_CAN_2G_MODULATION) ? SYS_DVBS2 : SYS_DVBS; break; - case FE_OFDM: frontendType = SYS_DVBT; break; -@@ -748,6 +799,13 @@ eVideoSystem cDvbDevice::GetVideoSystem( - - bool cDvbDevice::SetAudioBypass(bool On) - { -+#ifdef USE_DVBSETUP -+ if (Setup.DolbyTransferFix && On) { -+ cChannel *c=Channels.GetByNumber(cDevice::CurrentChannel()); -+ if (c->Ca(0) != 0) -+ return false; -+ } -+#endif /* DVBSETUP */ - if (setTransferModeForDolbyDigital != 1) - return false; - return ioctl(fd_audio, AUDIO_SET_BYPASS_MODE, On) == 0; -@@ -853,14 +911,43 @@ void cDvbDevice::TurnOffLiveMode(bool Li - bool cDvbDevice::ProvidesSource(int Source) const - { - int type = Source & cSource::st_Mask; -+#ifdef USE_SOURCECAPS -+ if (Setup.SourceCapsSet && type == cSource::stSat && (frontendType == SYS_DVBS || frontendType == SYS_DVBS2)) { -+ for (int i = 0; i < MAXSOURCECAPS; i++) -+ if (sourceCaps[i] == Source) -+ return true; -+ return false; -+ } -+ else -+#endif /* SOURCECAPS */ - return type == cSource::stNone - || type == cSource::stCable && (frontendType == SYS_DVBC_ANNEX_AC || frontendType == SYS_DVBC_ANNEX_B) - || type == cSource::stSat && (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) -+#ifdef USE_ATSC -+ || type == cSource::stTerr && (frontendType == SYS_DVBT || frontendType == SYS_ATSC); -+#else - || type == cSource::stTerr && (frontendType == SYS_DVBT); -+#endif /* ATSC */ - } - - bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const - { -+#ifdef USE_DVBSETUP -+ if (Setup.ChannelBlocker != 0) { -+ if ((Setup.ChannelBlockerMode == 0) || -+ (Setup.ChannelBlockerMode == 1 && HasDecoder()) || -+ (Setup.ChannelBlockerMode == 2 && IsPrimaryDevice()) || -+ (Setup.ChannelBlockerMode == 3 && IsPrimaryDevice() && HasDecoder())) { -+ if ((Setup.ChannelBlocker == 1 && cSource::IsCable(Channel->Source()) && Channel->Modulation() == QAM_256) || -+ (Setup.ChannelBlocker == 2 && cSource::IsCable(Channel->Source())) || -+ (Setup.ChannelBlocker == 3 && cSource::IsSat(Channel->Source())) || -+ (Setup.ChannelBlocker == 4 && strstr(::Setup.ChannelBlockerList, Channel->GetChannelID().ToString()) != NULL) || // blacklist -+ (Setup.ChannelBlocker == 5 && strstr(::Setup.ChannelBlockerList, Channel->GetChannelID().ToString()) == NULL) || // whitelist -+ (Setup.ChannelBlocker == 6)) -+ return false; -+ } -+ } -+#endif /* DVBSETUP */ - if (!ProvidesSource(Channel->Source())) - return false; // doesn't provide source - if (!cSource::IsSat(Channel->Source())) -@@ -872,10 +959,31 @@ bool cDvbDevice::ProvidesTransponder(con - - bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const - { -+#ifdef USE_DVBSETUP -+ if (Setup.ChannelBlocker != 0) { -+ if ((Setup.ChannelBlockerMode == 0) || -+ (Setup.ChannelBlockerMode == 1 && HasDecoder()) || -+ (Setup.ChannelBlockerMode == 2 && IsPrimaryDevice()) || -+ (Setup.ChannelBlockerMode == 3 && IsPrimaryDevice() && HasDecoder())) { -+ if ((Setup.ChannelBlocker == 1 && cSource::IsCable(Channel->Source()) && Channel->Modulation() == QAM_256) || -+ (Setup.ChannelBlocker == 2 && cSource::IsCable(Channel->Source())) || -+ (Setup.ChannelBlocker == 3 && cSource::IsSat(Channel->Source())) || -+ (Setup.ChannelBlocker == 4 && strstr(::Setup.ChannelBlockerList, Channel->GetChannelID().ToString()) != NULL) || // blacklist -+ (Setup.ChannelBlocker == 5 && strstr(::Setup.ChannelBlockerList, Channel->GetChannelID().ToString()) == NULL) || // whitelist -+ (Setup.ChannelBlocker == 6)) -+ return false; -+ } -+ } -+#endif /* DVBSETUP */ - bool result = false; - bool hasPriority = Priority < 0 || Priority > this->Priority(); - bool needsDetachReceivers = false; - -+#ifdef USE_ANALOGTV -+ if ((Channel->Ca(0) == 0xA0) || (Channel->Ca(0) == 0xA1) || (Channel->Ca(0) == 0xA2)) -+ return false; -+#endif /* ANALOGTV */ -+ - if (ProvidesTransponder(Channel)) { - result = hasPriority; - if (Priority >= 0 && Receiving(true)) { -@@ -992,6 +1100,13 @@ bool cDvbDevice::HasLock(int TimeoutMs) - return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false; - } - -+#ifdef USE_ROTOR -+bool cDvbDevice::SendDiseqcCmd(dvb_diseqc_master_cmd cmd) -+{ -+ return dvbTuner->SendDiseqcCmd(cmd); -+} -+#endif /* ROTOR */ -+ - int cDvbDevice::GetAudioChannelDevice(void) - { - if (HasDecoder()) { -diff -ruNp vdr-1.7.5/dvbdevice.h vdr-1.7.5-extensions/dvbdevice.h ---- vdr-1.7.5/dvbdevice.h 2008-12-06 14:31:12.000000000 +0100 -+++ vdr-1.7.5-extensions/dvbdevice.h 2009-04-12 13:37:59.000000000 +0200 -@@ -74,6 +74,9 @@ protected: - virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); - public: - virtual bool HasLock(int TimeoutMs = 0); -+#ifdef USE_ROTOR -+ virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd); -+#endif /* ROTOR */ - - // PID handle facilities - -diff -ruNp vdr-1.7.5/dvbosd.c vdr-1.7.5-extensions/dvbosd.c ---- vdr-1.7.5/dvbosd.c 2007-09-16 10:55:54.000000000 +0200 -+++ vdr-1.7.5-extensions/dvbosd.c 2009-04-12 13:37:59.000000000 +0200 -@@ -20,12 +20,26 @@ - #define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 - #define MAXOSDMEMORY 92000 // number of bytes available to the OSD (for unmodified DVB cards) - -+#ifdef USE_SOFTOSD -+ #define SOFTOSD_MAXSIZE (720*576) -+ #define SOFTOSD_MINSIZE (720*64) -+#endif -+ - class cDvbOsd : public cOsd { - private: - int osdDev; - int osdMem; - bool shown; - void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL); -+#ifdef USE_SOFTOSD -+ int GetOsdSize() { -+ int OsdSize = 0; -+ cBitmap *Bitmap; -+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) -+ OsdSize += Bitmap->Width() * Bitmap->Height(); -+ return OsdSize; -+ } -+#endif - protected: - virtual void SetActive(bool On); - public: -@@ -76,6 +90,44 @@ void cDvbOsd::SetActive(bool On) - } - else if (shown) { - cBitmap *Bitmap; -+#ifdef USE_SOFTOSD -+ if (Setup.UseSoftOsd) { -+ if (SOFTOSD_MAXSIZE > GetOsdSize() && SOFTOSD_MINSIZE < GetOsdSize()) { -+ for (int fade = Setup.SoftOsdFadeoutSteps - 1; fade > 0; fade--) { -+ int64_t flush_start = cTimeMs::Now(); -+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { -+ Cmd(OSD_SetWindow, 0, i + 1); -+ int NumColors; -+ const tColor *Colors = Bitmap->Colors(NumColors); -+ if (Colors) { -+ tColor colors[NumColors]; -+ for (int i = 0; i < NumColors; i++) { -+ // convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way): -+ int alpha = (Colors[i] >> 24) & 0x000000FF; -+ alpha = (alpha * fade) / Setup.SoftOsdFadeoutSteps; -+ colors[i] = (alpha << 24) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); -+ } -+ Colors = colors; -+ Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors); -+ if (!Setup.SoftOsdPaletteOnly) { -+ //Cmd(OSD_SetBlock, Bitmap->Width(), 0, 0, Bitmap->Width() - 1, Bitmap->Height() - 1, Bitmap->Data(0, 0)); -+ Cmd(OSD_SetBlock, Bitmap->Width(), 0, 0, 0, 0, Bitmap->Data(0, 0)); -+ } -+ } -+ } -+ int flush_time = cTimeMs::Now() - flush_start; -+ dsyslog("SOFTOSD: FadeOut Step %d from %d FlushTime = %d ms", -+ Setup.SoftOsdFadeoutSteps - fade, Setup.SoftOsdFadeoutSteps - 1, flush_time); -+ int wait_time = 1000 / Setup.SoftOsdRate; -+ while (flush_time > wait_time && fade > 2) { -+ fade--; -+ flush_time -= wait_time; -+ } -+ cCondWait::SleepMs(wait_time-flush_time); -+ } -+ } -+ } -+#endif /* SOFTOSD */ - for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { - Cmd(OSD_SetWindow, 0, i + 1); - Cmd(OSD_Close); -@@ -83,6 +135,12 @@ void cDvbOsd::SetActive(bool On) - shown = false; - } - } -+#ifdef USE_YAEPG -+ if (vidWin.bpp != 0) { -+ Cmd(OSD_SetWindow, 0, 5); -+ Cmd(OSD_Close); -+ } -+#endif /* YAEPG */ - } - - eOsdError cDvbOsd::CanHandleAreas(const tArea *Areas, int NumAreas) -@@ -182,6 +240,12 @@ void cDvbOsd::Flush(void) - for (int i = 0; i < NumColors; i++) { - // convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way): - colors[i] = (Colors[i] & 0xFF000000) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); -+#ifdef USE_SOFTOSD -+ if (Setup.UseSoftOsd && !shown) { -+ if (SOFTOSD_MAXSIZE > GetOsdSize() && SOFTOSD_MINSIZE < GetOsdSize()) -+ colors[i] = 0; -+ } -+#endif /* SOFTOSD */ - } - Colors = colors; - //TODO end of stuff that should be fixed in the driver -@@ -198,6 +262,51 @@ void cDvbOsd::Flush(void) - Cmd(OSD_SetWindow, 0, i + 1); - Cmd(OSD_MoveWindow, 0, Left() + Bitmap->X0(), Top() + Bitmap->Y0()); - } -+#ifdef USE_YAEPG -+ if (vidWin.bpp != 0) { -+ Cmd(OSD_SetWindow, 0, 5); -+ Cmd(OSD_OpenRaw, vidWin.bpp, vidWin.x1, vidWin.y1, vidWin.x2, vidWin.y2, (void *)0); -+ } -+#endif /* YAEPG */ -+#ifdef USE_SOFTOSD -+ if (Setup.UseSoftOsd) { -+ if (SOFTOSD_MAXSIZE > GetOsdSize() && SOFTOSD_MINSIZE < GetOsdSize()) { -+ for (int fade = 1; fade <= Setup.SoftOsdFadeinSteps; fade++) { -+ int64_t flush_start = cTimeMs::Now(); -+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { -+ Cmd(OSD_SetWindow, 0, i + 1); -+ int NumColors; -+ const tColor *Colors = Bitmap->Colors(NumColors); -+ if (Colors) { -+ tColor colors[NumColors]; -+ for (int i = 0; i < NumColors; i++) { -+ // convert AARRGGBB to AABBGGRR: -+ int alpha = (Colors[i]>>24) & 0x000000FF; -+ alpha = (alpha * fade) / Setup.SoftOsdFadeinSteps; -+ colors[i] = (alpha << 24) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); -+ } -+ Colors = colors; -+ Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors); -+ if (!Setup.SoftOsdPaletteOnly) { -+ //Cmd(OSD_SetBlock, Bitmap->Width(), 0, 0, Bitmap->Width() - 1, Bitmap->Height() - 1, Bitmap->Data(0, 0)); -+ Cmd(OSD_SetBlock, Bitmap->Width(), 0, 0, 0, 0, Bitmap->Data(0, 0)); -+ } -+ } -+ } -+ int flush_time = cTimeMs::Now() - flush_start; -+ dsyslog("SOFTOSD: FadeIn Step %d from %d FlushTime = %d ms", fade, Setup.SoftOsdFadeinSteps, flush_time); -+ int wait_time = 1000 / Setup.SoftOsdRate; -+ while (flush_time > wait_time && fade < Setup.SoftOsdFadeinSteps - 1) { -+ fade++; -+ flush_time -= wait_time; -+ } -+ if (fade == Setup.SoftOsdFadeinSteps) /* last step, don't wait */ -+ break; -+ cCondWait::SleepMs(wait_time - flush_time); -+ } -+ } -+ } -+#endif /* SOFTOSD */ - shown = true; - } - } -diff -ruNp vdr-1.7.5/dvbplayer.c vdr-1.7.5-extensions/dvbplayer.c ---- vdr-1.7.5/dvbplayer.c 2009-04-05 15:04:33.000000000 +0200 -+++ vdr-1.7.5-extensions/dvbplayer.c 2009-04-12 13:37:59.000000000 +0200 -@@ -204,6 +204,9 @@ private: - cNonBlockingFileReader *nonBlockingFileReader; - cRingBufferFrame *ringBuffer; - cPtsIndex ptsIndex; -+#ifdef USE_JUMPPLAY -+ cMarksReload marks; -+#endif /* JUMPPLAY */ - cFileName *fileName; - cIndexFile *index; - cUnbufferedFile *replayFile; -@@ -249,7 +252,11 @@ public: - int cDvbPlayer::Speeds[] = { 0, -2, -4, -8, 1, 2, 4, 12, 0 }; - - cDvbPlayer::cDvbPlayer(const char *FileName) -+#ifdef USE_JUMPPLAY -+:cThread("dvbplayer"), marks(FileName) -+#else - :cThread("dvbplayer") -+#endif /* JUMPPLAY */ - { - nonBlockingFileReader = NULL; - ringBuffer = NULL; -@@ -357,6 +364,11 @@ bool cDvbPlayer::Save(void) - if (index) { - int Index = ptsIndex.FindIndex(DeviceGetSTC()); - if (Index >= 0) { -+#ifdef USE_JUMPPLAY -+ // set resume position to 0 if replay stops at the first mark -+ if (Setup.PlayJump && marks.First() && abs(Index - marks.First()->position) <= RESUMEBACKUP) -+ Index = 0; -+#endif /* JUMPPLAY */ - Index -= int(round(RESUMEBACKUP * framesPerSecond)); - if (Index > 0) - Index = index->GetNextIFrame(Index, false); -@@ -384,11 +396,29 @@ void cDvbPlayer::Action(void) - uchar *b = NULL; - uchar *p = NULL; - int pc = 0; -+#ifdef USE_JUMPPLAY -+ bool cutIn = false; -+ int total = -1; -+#endif /* JUMPPLAY */ - - readIndex = Resume(); - if (readIndex >= 0) - isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true, framesPerSecond)); - -+#ifdef USE_JUMPPLAY -+ if (Setup.PlayJump && readIndex <= 0 && marks.First() && index) { -+ int Index = marks.First()->position; -+ uint16_t FileNumber; -+ off_t FileOffset; -+ if (index->Get(Index, &FileNumber, &FileOffset) && NextFile(FileNumber, FileOffset)) { -+ isyslog("PlayJump: start replay at first mark %d (%s)", Index, *IndexToHMSF(Index, true)); -+ readIndex = Index; -+ } -+ } -+ -+ bool LastMarkPause = false; -+#endif /* JUMPPLAY */ -+ - nonBlockingFileReader = new cNonBlockingFileReader; - int Length = 0; - bool Sleep = false; -@@ -413,7 +443,11 @@ void cDvbPlayer::Action(void) - - // Read the next frame from the file: - -+#ifdef USE_JUMPPLAY -+ if (playMode != pmStill && playMode != pmPause && !LastMarkPause) { -+#else - if (playMode != pmStill && playMode != pmPause) { -+#endif /* JUMPPLAY */ - if (!readFrame && (replayFile || readIndex >= 0)) { - if (!nonBlockingFileReader->Reading()) { - if (!SwitchToPlayFrame && (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward))) { -@@ -454,6 +488,42 @@ void cDvbPlayer::Action(void) - readIndex++; - else - eof = true; -+#ifdef USE_JUMPPLAY -+ if (Setup.PlayJump || Setup.PauseLastMark) { -+ // check for end mark - jump to next mark or pause -+ marks.Reload(); -+ cMark *m = marks.Get(readIndex); -+ if (m && (m->Index() & 0x01) != 0) { -+ m = marks.Next(m); -+ int Index; -+ if (m) -+ Index = m->position; -+ else if (Setup.PauseLastMark) { -+ // pause at last mark -+ isyslog("PauseLastMark: pause at position %d (%s)", readIndex, *IndexToHMSF(readIndex, true)); -+ LastMarkPause = true; -+ Index = -1; -+ } -+ else if (total == index->Last()) -+ // at last mark jump to end of recording -+ Index = index->Last() - 1; -+ else -+ // jump but stay off end of live-recordings -+ Index = index->GetNextIFrame(index->Last() - 150, true); -+ -+ // don't jump in edited recordings -+ if (Setup.PlayJump && Index > readIndex && Index > index->GetNextIFrame(readIndex, true)) { -+ isyslog("PlayJump: %d frames to %d (%s)", Index - readIndex, Index, *IndexToHMSF(Index, true)); -+ readIndex = Index; -+ cutIn = true; -+ } -+ } -+ } -+ // for detecting growing length of live-recordings -+ bool Independent; -+ if (index->Get(readIndex, &FileNumber, &FileOffset, &Independent) && Independent) -+ total = index->Last(); -+#endif /* JUMPPLAY */ - } - else // allows replay even if the index file is missing - Length = MAXFRAMESIZE / TS_SIZE * TS_SIZE;// FIXME: use a linear ringbuffer in this case, and fix cDevice::PlayPes() -@@ -491,6 +561,12 @@ void cDvbPlayer::Action(void) - // Store the frame in the buffer: - - if (readFrame) { -+#ifdef USE_JUMPPLAY -+ if (cutIn) { -+ cRemux::SetBrokenLink(readFrame->Data(), readFrame->Count()); -+ cutIn = false; -+ } -+#endif /* JUMPPLAY */ - if (ringBuffer->Put(readFrame)) - readFrame = NULL; - } -@@ -546,8 +622,19 @@ void cDvbPlayer::Action(void) - p = NULL; - } - } -+#ifdef USE_JUMPPLAY -+ else { -+ if (LastMarkPause) { -+ LastMarkPause = false; -+ playMode = pmPause; -+// writeIndex = readIndex; -+ } -+ Sleep = true; -+ } -+#else - else - Sleep = true; -+#endif /* JUMPPLAY */ - - // Handle hitting begin/end of recording: - -diff -ruNp vdr-1.7.5/eit.c vdr-1.7.5-extensions/eit.c ---- vdr-1.7.5/eit.c 2009-04-11 12:03:24.000000000 +0200 -+++ vdr-1.7.5-extensions/eit.c 2009-04-12 13:37:59.000000000 +0200 -@@ -17,13 +17,40 @@ - #include "libsi/section.h" - #include "libsi/descriptor.h" - -+#ifdef USE_SETTIME -+extern char *SetTime; -+#endif /* SETTIME */ -+ - // --- cEIT ------------------------------------------------------------------ - - class cEIT : public SI::EIT { - public: - cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bool OnlyRunningStatus = false); -+#ifdef USE_NOEPG -+private: -+ bool allowedEPG(tChannelID kanalID); -+#endif /* NOEPG */ - }; - -+#ifdef USE_NOEPG -+bool cEIT::allowedEPG(tChannelID kanalID) { -+ bool rc; -+ -+ if (Setup.noEPGMode == 1) { -+ rc = false; -+ if (strstr(::Setup.noEPGList, kanalID.ToString()) != NULL) -+ rc = true; -+ } -+ else { -+ rc = true; -+ if (strstr(::Setup.noEPGList, kanalID.ToString()) != NULL) -+ rc = false; -+ } -+ -+ return rc; -+} -+#endif /* NOEPG */ -+ - cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bool OnlyRunningStatus) - :SI::EIT(Data, false) - { -@@ -35,6 +62,14 @@ cEIT::cEIT(cSchedules *Schedules, int So - if (!channel) - return; // only collect data for known channels - -+#ifdef USE_NOEPG -+ // only use epg from channels not blocked by noEPG-patch -+ tChannelID kanalID; -+ kanalID = channel->GetChannelID(); -+ if (!allowedEPG(kanalID)) -+ return; -+#endif /* NOEPG */ -+ - cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channel, true); - - bool Empty = true; -@@ -77,8 +112,74 @@ cEIT::cEIT(cSchedules *Schedules, int So - // not be overwritten. - uchar TableID = pEvent->TableID(); - if (TableID == 0x00) { -+#ifdef USE_DDEPGENTRY -+ if (pEvent->Version() == getVersionNumber()) { -+ if (Setup.MixEpgAction == 0) -+ continue; -+ //printf("in"); -+ //printf("%s", pEvent->GetTimeString()); -+ // to use the info of the original epg, update the extern one, -+ // if it has less info -+ SI::Descriptor *d; -+ SI::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL; -+ //SI::ExtendedEventDescriptor *eed = NULL; -+ SI::ShortEventDescriptor *ShortEventDescriptor = NULL; -+ //SI::ShortEventDescriptor *sed = NULL; -+ //SI::TimeShiftedEventDescriptor *tsed = NULL; -+ //cLinkChannels *LinkChannels = NULL; -+ for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2));) { -+ if (d->getDescriptorTag() == SI::ShortEventDescriptorTag) { -+ int LanguagePreferenceShort = -1; -+ SI::ShortEventDescriptor *sed = (SI::ShortEventDescriptor *)d; -+ if (I18nIsPreferredLanguage(Setup.EPGLanguages, sed->languageCode, LanguagePreferenceShort) || !ShortEventDescriptor) { -+ delete ShortEventDescriptor; -+ ShortEventDescriptor = sed; -+ d = NULL; // so that it is not deleted -+ } -+ } -+ else if (d->getDescriptorTag() == SI::ExtendedEventDescriptorTag) { -+ int LanguagePreferenceExt = -1; -+ bool UseExtendedEventDescriptor = false; -+ SI::ExtendedEventDescriptor *eed = (SI::ExtendedEventDescriptor *)d; -+ if (I18nIsPreferredLanguage(Setup.EPGLanguages, eed->languageCode, LanguagePreferenceExt) || !ExtendedEventDescriptors) { -+ delete ExtendedEventDescriptors; -+ ExtendedEventDescriptors = new SI::ExtendedEventDescriptors; -+ UseExtendedEventDescriptor = true; -+ } -+ if (UseExtendedEventDescriptor) { -+ ExtendedEventDescriptors->Add(eed); -+ d = NULL; // so that it is not deleted -+ } -+ if (eed->getDescriptorNumber() == eed->getLastDescriptorNumber()) -+ UseExtendedEventDescriptor = false; -+ } -+ delete d; -+ } -+ if (pEvent) { -+ if (ShortEventDescriptor) { -+ char buffer[256]; -+ if (ShortEventDescriptor->text.getText(buffer, sizeof(buffer)) && pEvent->ShortText() && (strlen(ShortEventDescriptor->text.getText(buffer, sizeof(buffer))) > strlen(pEvent->ShortText()))) { -+ pEvent->SetShortText(ShortEventDescriptor->text.getText(buffer, sizeof(buffer))); -+ pEvent->FixEpgBugs(); -+ } -+ } -+ if (ExtendedEventDescriptors) { -+ char buffer[ExtendedEventDescriptors->getMaximumTextLength(": ") + 1]; -+ //pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ")); -+ if (ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ") && pEvent->Description() && (strlen(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ")) > strlen(pEvent->Description()))) { -+ pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": ")); -+ pEvent->FixEpgBugs(); -+ } -+ } -+ } -+ delete ExtendedEventDescriptors; -+ delete ShortEventDescriptor; -+ continue; -+ } -+#else - if (pEvent->Version() == getVersionNumber()) - continue; -+#endif /* DDEPGENTRY */ - HasExternalData = ExternalData = true; - } - // If the new event has a higher table ID, let's skip it. -@@ -103,7 +204,11 @@ cEIT::cEIT(cSchedules *Schedules, int So - if (newEvent) - pSchedule->AddEvent(newEvent); - if (Tid == 0x4E) { // we trust only the present/following info on the actual TS -+#ifdef USE_DDEPGENTRY -+ if (Setup.DisableVPS == 0 && SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning) -+#else - if (SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning) -+#endif /* DDEPGENTRY */ - pSchedule->SetRunningStatus(pEvent, SiEitEvent.getRunningStatus(), channel); - } - if (OnlyRunningStatus) -@@ -149,8 +254,46 @@ cEIT::cEIT(cSchedules *Schedules, int So - } - break; - case SI::ContentDescriptorTag: -+#ifdef USE_PARENTALRATING -+ { -+ int NumContents = 0; -+ uchar Contents[MAXEVCONTENTS + 1] = { 0 }; -+ SI::ContentDescriptor *cd = (SI::ContentDescriptor *)d; -+ SI::ContentDescriptor::Nibble Nibble; -+ for (SI::Loop::Iterator it3; cd->nibbleLoop.getNext(Nibble, it3); ) { -+ if (NumContents < MAXEVCONTENTS) { -+ Contents[NumContents] = ((Nibble.getContentNibbleLevel1() & 0xF) << 4) | (Nibble.getContentNibbleLevel2() & 0xF); -+ NumContents++; -+ } -+ } -+ pEvent->SetContents(Contents); -+ } -+#endif /* PARENTALRATING */ - break; - case SI::ParentalRatingDescriptorTag: -+#ifdef USE_PARENTALRATING -+ { -+ int LanguagePreferenceRating = -1; -+ SI::ParentalRatingDescriptor *prd = (SI::ParentalRatingDescriptor *)d; -+ SI::ParentalRatingDescriptor::Rating Rating; -+ for (SI::Loop::Iterator it3; prd->ratingLoop.getNext(Rating, it3); ) { -+ if (I18nIsPreferredLanguage(Setup.EPGLanguages, Rating.languageCode, LanguagePreferenceRating)) { -+ int rate = (Rating.getRating() & 0xFF); -+ switch (rate) { -+ case 0x01 ... 0x0F: // minimum age = rating + 3 years -+ rate += 3; -+ break; -+ case 0: // undefined -+ case 0x10 ... 0xFF: // defined by the broadcaster -+ default: -+ rate = 0; -+ break; -+ } -+ pEvent->SetParentalRating(rate); -+ } -+ } -+ } -+#endif /* PARENTALRATING */ - break; - case SI::PDCDescriptorTag: { - SI::PDCDescriptor *pd = (SI::PDCDescriptor *)d; -@@ -261,6 +404,62 @@ cEIT::cEIT(cSchedules *Schedules, int So - if (LinkChannels) - channel->SetLinkChannels(LinkChannels); - Modified = true; -+#ifdef USE_DDEPGENTRY -+ //to avoid double epg-entrys from ext and int epg sources :EW -+ if (pEvent && pEvent->TableID() != 0x00) { -+ cEvent *pPreviousEvent = (cEvent *)pSchedule->GetPreviousEvent(pEvent); -+ if (pPreviousEvent) { -+ if (Setup.DoubleEpgAction == 0) { -+ pPreviousEvent->SetStartTime(pEvent->StartTime()); -+ pPreviousEvent->SetDuration(pEvent->Duration()); -+ if (Setup.DisableVPS == 0) { -+ if (channel) -+ pPreviousEvent->SetRunningStatus(pEvent->RunningStatus(), channel); -+ else -+ pPreviousEvent->SetRunningStatus(pEvent->RunningStatus()); -+ } -+ // to use the info of the original epg, update the extern one, -+ // if it has less info -+ char buffer_short_intern[256]; -+ char buffer_short_extern[256]; -+ int len_short_intern = 0; -+ int len_short_extern = 0; -+ if (pEvent->ShortText()) -+ len_short_intern = snprintf (buffer_short_intern, sizeof(buffer_short_intern)-1, "%s", pEvent->ShortText()); -+ if (pPreviousEvent->ShortText()) -+ len_short_extern = snprintf (buffer_short_extern, sizeof(buffer_short_extern)-1, "%s", pPreviousEvent->ShortText()); -+ if (len_short_intern > 0) { -+ if (len_short_extern < 1) -+ pPreviousEvent->SetShortText(buffer_short_intern); -+ else if (len_short_intern > len_short_extern) -+ pPreviousEvent->SetShortText(buffer_short_intern); -+ } -+ if (pEvent->Description()) { -+ char buffer_title_intern[4096]; -+ char buffer_title_extern[4096]; -+ int len_title_intern = 0; -+ int len_title_extern = 0; -+ if (pEvent->Description()) -+ len_title_intern = snprintf (buffer_title_intern, sizeof(buffer_title_intern)-1, "%s", pEvent->Description()); -+ if (pPreviousEvent->Description()) -+ len_title_extern = snprintf (buffer_title_extern, sizeof(buffer_title_extern)-1, "%s", pPreviousEvent->Description()); -+ if (len_title_intern > 0) { -+ if (len_title_extern < 1) -+ pPreviousEvent->SetDescription(buffer_title_intern); -+ else if (len_title_intern > len_title_extern) -+ pPreviousEvent->SetDescription(buffer_title_intern); -+ } -+ } -+ if (pPreviousEvent->Vps() == 0 && pEvent->Vps() != 0) -+ pPreviousEvent->SetVps(pEvent->Vps()); -+ pSchedule->DelEvent(pEvent); -+ pPreviousEvent->FixEpgBugs(); -+ } -+ else -+ pSchedule->DelEvent(pPreviousEvent); -+ } -+ } -+#endif /* DDEPGENTRY */ - } - if (Tid == 0x4E) { - if (Empty && getSectionNumber() == 0) -@@ -299,10 +498,26 @@ cTDT::cTDT(const u_char *Data) - time_t sattim = getTime(); - time_t loctim = time(NULL); - -+#ifdef USE_SETTIME -+ char timestr[20]; -+ struct tm *ptm; -+ struct tm tm_r; -+ ptm = localtime_r(&sattim, &tm_r); -+#endif /* SETTIME */ -+ - int diff = abs(sattim - loctim); - if (diff > 2) { - mutex.Lock(); - if (abs(diff - lastDiff) < 3) { -+#ifdef USE_SETTIME -+ if (SetTime) { -+ strftime(timestr, 20, "%m%d%H%M%Y.%S", ptm); -+ cString cmd = cString::sprintf("%s %s %ld", SetTime, timestr, sattim); -+ dsyslog("Executing: %s", *cmd); -+ SystemExec(cmd); -+ } -+ else -+#endif /* SETTIME */ - if (stime(&sattim) == 0) - isyslog("system time changed from %s (%ld) to %s (%ld)", *TimeToString(loctim), loctim, *TimeToString(sattim), sattim); - else -diff -ruNp vdr-1.7.5/eitscan.c vdr-1.7.5-extensions/eitscan.c ---- vdr-1.7.5/eitscan.c 2006-01-07 15:10:17.000000000 +0100 -+++ vdr-1.7.5-extensions/eitscan.c 2009-04-12 13:37:59.000000000 +0200 -@@ -151,9 +151,17 @@ void cEITScanner::Process(void) - if (Device->ProvidesTransponder(Channel)) { - if (!Device->Receiving()) { - bool MaySwitchTransponder = Device->MaySwitchTransponder(); -+#ifdef USE_LNBSHARE -+ if (MaySwitchTransponder && Device->GetMaxBadPriority(Channel) == -2 || Device->ProvidesTransponderExclusively(Channel) && Device->GetMaxBadPriority(Channel) <= -1 && now - lastActivity > Setup.EPGScanTimeout * 3600) { -+#else - if (MaySwitchTransponder || Device->ProvidesTransponderExclusively(Channel) && now - lastActivity > Setup.EPGScanTimeout * 3600) { -+#endif /* LNBSHARE */ - if (!MaySwitchTransponder) { -+#ifdef USE_LNBSHARE -+ if ((Device == cDevice::ActualDevice() || Device->GetMaxBadPriority(Channel) == -1) && !currentChannel) { -+#else - if (Device == cDevice::ActualDevice() && !currentChannel) { -+#endif /* LNBSHARE */ - cDevice::PrimaryDevice()->StopReplay(); // stop transfer mode - currentChannel = Device->CurrentChannel(); - Skins.Message(mtInfo, tr("Starting EPG scan")); -diff -ruNp vdr-1.7.5/epg.c vdr-1.7.5-extensions/epg.c ---- vdr-1.7.5/epg.c 2008-05-01 16:53:55.000000000 +0200 -+++ vdr-1.7.5-extensions/epg.c 2009-04-12 13:37:59.000000000 +0200 -@@ -114,6 +114,11 @@ cEvent::cEvent(tEventID EventID) - components = NULL; - startTime = 0; - duration = 0; -+#ifdef USE_PARENTALRATING -+ for (int i = 0; i < MAXEVCONTENTS; i++) -+ contents[i] = 0; -+ parentalRating = 0; -+#endif /* PARENTALRATING */ - vps = 0; - SetSeen(); - } -@@ -202,6 +207,19 @@ void cEvent::SetDuration(int Duration) - duration = Duration; - } - -+#ifdef USE_PARENTALRATING -+void cEvent::SetContents(uchar *Contents) -+{ -+ for (int i = 0; i < MAXEVCONTENTS; i++) -+ contents[i] = Contents[i]; -+} -+ -+void cEvent::SetParentalRating(uchar ParentalRating) -+{ -+ parentalRating = ParentalRating; -+} -+#endif /* PARENTALRATING */ -+ - void cEvent::SetVps(time_t Vps) - { - vps = Vps; -@@ -257,6 +275,340 @@ cString cEvent::GetVpsString(void) const - return buf; - } - -+#ifdef USE_PARENTALRATING -+cString cEvent::GetContentsString(int i) const -+{ -+ cString str(""); -+ switch (contents[i] & 0xF0) { -+ case EVCONTENTMASK_MOVIEDRAMA: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Movie/Drama")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Detective/Thriller")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Adventure/Western/War")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Science Fiction/Fantasy/Horror")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Comedy")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Soap/Melodrama/Folkloric")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Romance")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Serious/Classical/Religious/Historical Movie/Drama")); -+ break; -+ case 0x08: -+ str = cString(tr("Content$Adult Movie/Drama")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_NEWSCURRENTAFFAIRS: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$News/Current Affairs")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$News/Weather Report")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$News Magazine")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Documentary")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Discussion/Inverview/Debate")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_SHOW: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Show/Game Show")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Game Show/Quiz/Contest")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Variety Show")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Talk Show")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_SPORTS: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Sports")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Special Event")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Sport Magazine")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Football")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Tennis/Squash")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Team Sports")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Athletics")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Motor Sport")); -+ break; -+ case 0x08: -+ str = cString(tr("Content$Water Sport")); -+ break; -+ case 0x09: -+ str = cString(tr("Content$Winter Sports")); -+ break; -+ case 0x0A: -+ str = cString(tr("Content$Equestrian")); -+ break; -+ case 0x0B: -+ str = cString(tr("Content$Martial Sports")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_CHILDRENYOUTH: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Children's/Youth Programmes")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Pre-school Children's Programmes")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Entertainment Programmes for 6 to 14")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Entertainment Programmes for 10 to 16")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Informational/Educational/School Programme")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Cartoons/Puppets")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_MUSICBALLETDANCE: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Music/Ballet/Dance")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Rock/Pop")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Serious/Classical Music")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Folk/Tradional Music")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Jazz")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Musical/Opera")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Ballet")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_ARTSCULTURE: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Arts/Culture")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Performing Arts")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Fine Arts")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Religion")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Popular Culture/Traditional Arts")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Literature")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Film/Cinema")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Experimental Film/Video")); -+ break; -+ case 0x08: -+ str = cString(tr("Content$Broadcasting/Press")); -+ break; -+ case 0x09: -+ str = cString(tr("Content$New Media")); -+ break; -+ case 0x0A: -+ str = cString(tr("Content$Arts/Culture Magazines")); -+ break; -+ case 0x0B: -+ str = cString(tr("Content$Fashion")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_SOCIALPOLITICALECONOMICS: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Social/Political/Economics")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Magazines/Reports/Documentary")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Economics/Social Advisory")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Remarkable People")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_EDUCATIONALSCIENCE: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Education/Science/Factual")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Nature/Animals/Environment")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Technology/Natural Sciences")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Medicine/Physiology/Psychology")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Foreign Countries/Expeditions")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Social/Spiritual Sciences")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Further Education")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Languages")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_LEISUREHOBBIES: -+ switch (contents[i] & 0x0F) { -+ default: -+ case 0x00: -+ str = cString(tr("Content$Leisure/Hobbies")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Tourism/Travel")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Handicraft")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Motoring")); -+ break; -+ case 0x04: -+ str = cString(tr("Content$Fitness & Health")); -+ break; -+ case 0x05: -+ str = cString(tr("Content$Cooking")); -+ break; -+ case 0x06: -+ str = cString(tr("Content$Advertisement/Shopping")); -+ break; -+ case 0x07: -+ str = cString(tr("Content$Gardening")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_SPECIAL: -+ switch (contents[i] & 0x0F) { -+ case 0x00: -+ str = cString(tr("Content$Original Language")); -+ break; -+ case 0x01: -+ str = cString(tr("Content$Black & White")); -+ break; -+ case 0x02: -+ str = cString(tr("Content$Unpublished")); -+ break; -+ case 0x03: -+ str = cString(tr("Content$Live Broadcast")); -+ break; -+ default: -+ str = cString(tr("Content$Special Characteristics")); -+ break; -+ } -+ break; -+ -+ case EVCONTENTMASK_USERDEFINED: -+ switch (contents[i] & 0x0F) { -+ case 0x00: -+ str = cString(tr("Content$Drama")); // UK Freeview -+ break; -+ default: -+ break; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ return str; -+} -+ -+cString cEvent::GetParentalRatingString(void) const -+{ -+ if (parentalRating > 0) -+ return cString::sprintf(tr("Suitable for those aged %d and over"), parentalRating); -+ return NULL; -+} -+#endif /* PARENTALRATING */ -+ - void cEvent::Dump(FILE *f, const char *Prefix, bool InfoOnly) const - { - if (InfoOnly || startTime + duration + Setup.EPGLinger * 60 >= time(NULL)) { -@@ -744,6 +1096,28 @@ const cEvent *cSchedule::GetEventAround( - return pe; - } - -+#ifdef USE_DDEPGENTRY -+const cEvent *cSchedule::GetPreviousEvent(cEvent *Event) const -+{ -+ if (!Event || Event->Duration() == 0 || Event->StartTime() == 0) -+ return NULL; -+ // Returns either the event info to the previous/following event to the given EventID or, if that one can't be found NULL :EW -+ cEvent *pt = NULL; -+ int epgTimeDelta = Setup.DoubleEpgTimeDelta * 60 + 1; -+ for (pt = events.First(); pt; pt = events.Next(pt)) -+ if (pt && pt->TableID() == 0x00) -+ if ((Event->StartTime() - pt->StartTime()) > - epgTimeDelta && (Event->StartTime() - pt->StartTime()) < epgTimeDelta) { -+ if ((pt->Duration() + (pt->Duration()/ 5) + 1) > Event->Duration() && (pt->Duration() - (pt->Duration()/ 5) - 1) < Event->Duration()) -+ return pt; -+ else if (pt->Title() && Event->Title() && (strcmp(pt->Title(), ".") != 0 && strcmp(Event->Title(), ".") != 0)) { -+ if (strstr(pt->Title(), Event->Title()) != NULL || strstr(Event->Title(), pt->Title()) != NULL) -+ return pt; -+ } -+ } -+ return NULL; -+} -+#endif /* DDEPGENTRY */ -+ - void cSchedule::SetRunningStatus(cEvent *Event, int RunningStatus, cChannel *Channel) - { - hasRunning = false; -diff -ruNp vdr-1.7.5/epg.h vdr-1.7.5-extensions/epg.h ---- vdr-1.7.5/epg.h 2006-10-07 15:47:19.000000000 +0200 -+++ vdr-1.7.5-extensions/epg.h 2009-04-12 13:37:59.000000000 +0200 -@@ -50,6 +50,22 @@ class cSchedule; - - typedef u_int32_t tEventID; - -+#ifdef USE_PARENTALRATING -+#define MAXEVCONTENTS 4 -+#define EVCONTENTMASK_MOVIEDRAMA 0x10 -+#define EVCONTENTMASK_NEWSCURRENTAFFAIRS 0x20 -+#define EVCONTENTMASK_SHOW 0x30 -+#define EVCONTENTMASK_SPORTS 0x40 -+#define EVCONTENTMASK_CHILDRENYOUTH 0x50 -+#define EVCONTENTMASK_MUSICBALLETDANCE 0x60 -+#define EVCONTENTMASK_ARTSCULTURE 0x70 -+#define EVCONTENTMASK_SOCIALPOLITICALECONOMICS 0x80 -+#define EVCONTENTMASK_EDUCATIONALSCIENCE 0x90 -+#define EVCONTENTMASK_LEISUREHOBBIES 0xA0 -+#define EVCONTENTMASK_SPECIAL 0xB0 -+#define EVCONTENTMASK_USERDEFINED 0xF0 -+#endif /* PARENTALRATING */ -+ - class cEvent : public cListObject { - friend class cSchedule; - private: -@@ -64,6 +80,10 @@ private: - cComponents *components; // The stream components of this event - time_t startTime; // Start time of this event - int duration; // Duration of this event in seconds -+#ifdef USE_PARENTALRATING -+ uchar contents[MAXEVCONTENTS + 1]; // Contents of this event; list is zero-terminated -+ uchar parentalRating; // Parental rating of this event -+#endif /* PARENTALRATING */ - time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL) - time_t seen; // When this event was last seen in the data stream - public: -@@ -83,6 +103,10 @@ public: - time_t StartTime(void) const { return startTime; } - time_t EndTime(void) const { return startTime + duration; } - int Duration(void) const { return duration; } -+#ifdef USE_PARENTALRATING -+ uchar Contents(int i = 0) const { return (0 <= i && i < MAXEVCONTENTS) ? contents[i] : 0; } -+ uchar ParentalRating(void) const { return parentalRating; } -+#endif /* PARENTALRATING */ - time_t Vps(void) const { return vps; } - time_t Seen(void) const { return seen; } - bool SeenWithin(int Seconds) const { return time(NULL) - seen < Seconds; } -@@ -92,6 +116,10 @@ public: - cString GetTimeString(void) const; - cString GetEndTimeString(void) const; - cString GetVpsString(void) const; -+#ifdef USE_PARENTALRATING -+ cString GetContentsString(int i = 0) const; -+ cString GetParentalRatingString(void) const; -+#endif /* PARENTALRATING */ - void SetEventID(tEventID EventID); - void SetTableID(uchar TableID); - void SetVersion(uchar Version); -@@ -102,6 +130,10 @@ public: - void SetComponents(cComponents *Components); // Will take ownership of Components! - void SetStartTime(time_t StartTime); - void SetDuration(int Duration); -+#ifdef USE_PARENTALRATING -+ void SetContents(uchar *Contents); -+ void SetParentalRating(uchar ParentalRating); -+#endif /* PARENTALRATING */ - void SetVps(time_t Vps); - void SetSeen(void); - cString ToDescr(void) const; -@@ -137,6 +169,9 @@ public: - void DropOutdated(time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version); - void Cleanup(time_t Time); - void Cleanup(void); -+#ifdef USE_DDEPGENTRY -+ const cEvent *GetPreviousEvent(cEvent *Event) const; //:EW -+#endif /* DDEPGENTRY */ - cEvent *AddEvent(cEvent *Event); - void DelEvent(cEvent *Event); - void HashEvent(cEvent *Event); -diff -ruNp vdr-1.7.5/HISTORY-liemikuutio vdr-1.7.5-extensions/HISTORY-liemikuutio ---- vdr-1.7.5/HISTORY-liemikuutio 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/HISTORY-liemikuutio 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,116 @@ -+----------------------------------- -+Liemikuutio for Video Disc Recorder -+ -+Maintainer: Rolf Ahrenberg -+----------------------------------- -+ -+2006-01-08: Version 1.0 -+ -+- Based on enAIO with these original patches: -+ Simple recordings sorting by Walter@VDRPortal -+ Alternate rename recordings by Ralf Müller -+ Menu selection by Peter Dittmann -+ Recording length by Tobias Faust -+ -+2006-01-15: Version 1.1 -+ -+- Removed patches already found in vdr-1.3.39. -+ -+2006-01-25: Version 1.2 -+ -+- Added "Main menu command position" feature. -+ -+2006-02-05: Version 1.3 -+ -+- Improved menu selection response. -+ -+2006-04-18: Version 1.4 -+ -+- Added Estonian translation (Thanks to Arthur Konovalov). -+ -+2006-04-30: Version 1.5 -+ -+- Added progress bar view into "What's on now?" menu. -+ -+2006-06-06: Version 1.6 -+ -+- Added French translation (Thanks to ECLiPSE). -+ -+2006-06-14: Version 1.7 -+ -+- Fixed RENR crash. -+ -+2006-07-14: Version 1.8 -+ -+- Fixed RENR/OSD bug. -+ -+2006-08-27: Version 1.9 -+ -+- Some modifications to the recording length and rename recordings -+ patches (Thanks to Firefly). -+- Added k1_k3_jumps_20s patch by Petri Hintukainen. -+ -+2006-08-29: Version 1.10 -+ -+- The cRecording:Title() method now defaults to original formatting. -+ -+2006-09-04: Version 1.11 -+ -+- Removed unused variable from cRecording::Title() method (Thanks to -+ C.Y.M.). -+- Some modifications to the rename recordings patch (Thanks to Firefly). -+ -+2006-09-13: Version 1.12 -+ -+- More modifications to the rename recordings patch (Thanks to Firefly). -+ -+2006-10-01: Version 1.13 -+ -+- Removed unnecessary syslog printing (Thanks to Firefly). -+ -+2007-08-14: Version 1.14 -+ -+- Updated for vdr-1.5.7. -+ -+2007-10-16: Version 1.15 -+ -+- Added recmenu play patch (Thanks to Ville Skyttä). -+- Updated French translation (Thanks to ECLiPSE). -+ -+2007-11-04: Version 1.16 -+ -+- Updated for vdr-1.5.11. -+ -+2007-12-08: Version 1.17 -+ -+- Added binary skip patch. -+- Removed k1_k3_jumps_20s patch. -+ -+2008-02-17: Version 1.18 -+ -+- Updated for vdr-1.5.15. -+ -+2008-03-02: Version 1.19 -+ -+- Modified binary skip to use kPrev and kNext keys and the skip is now -+ always shortened after a direction change (Thanks to Timo Eskola). -+- Readded k1_k3_jumps_20s patch. -+ -+2008-04-04: Version 1.20 -+ -+- Added bitrate information into rename menu. -+- Readded the path editing support of rename recordings patch (Thanks -+ to Firefly). -+ -+2008-05-08: Version 1.21 -+ -+- Fixed rename recordings (Thanks to Firefly). -+- Added a DVB subtitles hack for old recordings (Thanks to Anssi Hannula). -+ -+2009-01-08: Version 1.22 -+ -+- Updated for vdr-1.7.3. -+ -+2009-01-25: Version 1.23 -+ -+- Updated for vdr-1.7.4. -diff -ruNp vdr-1.7.5/iconpatch.c vdr-1.7.5-extensions/iconpatch.c ---- vdr-1.7.5/iconpatch.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/iconpatch.c 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,31 @@ -+#ifdef USE_WAREAGLEICON -+ -+#include "iconpatch.h" -+ -+#include <langinfo.h> -+#include <locale.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+ -+bool IsLangUtf8(void) -+{ -+ char *CodeSet = NULL; -+ if (setlocale(LC_CTYPE, "")) -+ CodeSet = nl_langinfo(CODESET); -+ else { -+ char *LangEnv = getenv("LANG"); // last resort in case locale stuff isn't installed -+ if (LangEnv) { -+ CodeSet = strchr(LangEnv, '.'); -+ if (CodeSet) -+ CodeSet++; // skip the dot -+ } -+ } -+ -+ if (CodeSet && strcasestr(CodeSet, "UTF-8") != 0) -+ return true; -+ -+ return false; -+} -+ -+#endif /* WAREAGLEICON */ -diff -ruNp vdr-1.7.5/iconpatch.h vdr-1.7.5-extensions/iconpatch.h ---- vdr-1.7.5/iconpatch.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/iconpatch.h 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,73 @@ -+#ifdef USE_WAREAGLEICON -+/* -+ * iconpatch.h: Information of iconpatch -+ * -+ * Diese Datei ist die Übersichtsdatei für den Iconpatch. -+ * Hier werden kleine Infos abgelegt. -+ * Der Iconpatch ändert die Dateien: -+ * iconpatch.h -+ * menu.c -+ * recording.c -+ * fontosd.c -+ * -+ */ -+ -+// Iconpatch-Variablen - Anfang -+#define ICON_NUMBERSIGN "\x23" -+#define ICON_ASTERISK "\x2A" -+#define ICON_GREATER "\x3E" -+#define ICON_EXCLAM "\x21" -+#define ICON_PLUSMINUS "\xB1" -+ -+#define ICON_RESUME "\x80" -+#define ICON_DVD "\x81" -+#define ICON_FOLDER "\x82" -+#define ICON_BLANK "\x83" -+#define ICON_CUTTING "\x84" -+#define ICON_MOVE_FILE "\x85" -+#define ICON_MOVE_FOLDER "\x86" -+#define ICON_BAR_START "\x87" -+#define ICON_BAR_FILLED "\x88" -+#define ICON_BAR_CLEAR "\x89" -+#define ICON_BAR_END "\x8A" -+#define ICON_REC "\x8B" -+#define ICON_CLOCK "\x8C" -+#define ICON_TV_CRYPTED "\x8D" -+#define ICON_RADIO "\x8E" -+#define ICON_TV "\x8F" -+#define ICON_NEW "\x90" -+#define ICON_ARROW "\x91" -+#define ICON_RUNNING "\x92" -+#define ICON_VPS "\x93" -+#define ICON_CLOCK_UH "\x94" -+#define ICON_CLOCK_LH "\x95" -+ -+// UTF-8 Icons -+#define ICON_RESUME_UTF8 "\uE000" -+#define ICON_DVD_UTF8 "\uE001" -+#define ICON_FOLDER_UTF8 "\uE002" -+#define ICON_BLANK_UTF8 "\uE003" -+#define ICON_CUTTING_UTF8 "\uE004" -+#define ICON_MOVE_FILE_UTF8 "\uE005" -+#define ICON_MOVE_FOLDER_UTF8 "\uE006" -+#define ICON_BAR_START_UTF8 "\uE007" -+#define ICON_BAR_FILLED_UTF8 "\uE008" -+#define ICON_BAR_EMPTY_UTF8 "\uE009" -+#define ICON_BAR_CLOSE_UTF8 "\uE00A" -+#define ICON_REC_UTF8 "\uE00B" -+#define ICON_CLOCK_UTF8 "\uE00C" -+#define ICON_TV_CRYPTED_UTF8 "\uE00D" -+#define ICON_RADIO_UTF8 "\uE00E" -+#define ICON_TV_UTF8 "\uE00F" -+#define ICON_NEW_UTF8 "\uE010" -+#define ICON_ARROW_UTF8 "\uE011" -+#define ICON_RUNNING_UTF8 "\uE012" -+#define ICON_VPS_UTF8 "\uE013" -+#define ICON_CLOCK_UH_UTF8 "\uE014" -+#define ICON_CLOCK_LH_UTF8 "\uE015" -+ -+// Iconpatch-Variablen - Ende -+ -+bool IsLangUtf8(void); -+ -+#endif /* WAREAGLEICON */ -diff -ruNp vdr-1.7.5/keys.h vdr-1.7.5-extensions/keys.h ---- vdr-1.7.5/keys.h 2007-08-26 14:34:50.000000000 +0200 -+++ vdr-1.7.5-extensions/keys.h 2009-04-12 13:37:59.000000000 +0200 -@@ -71,6 +71,10 @@ enum eKeys { // "Up" and "Down" must be - #define kEditCut k2 - #define kEditTest k8 - -+#ifdef USE_DVDARCHIVE -+#define kDvdChapterJumpForward k6 -+#define kDvdChapterJumpBack k4 -+#endif /* DVDARCHIVE */ - #define RAWKEY(k) (eKeys((k) & ~k_Flags)) - #define ISRAWKEY(k) ((k) != kNone && ((k) & k_Flags) == 0) - #define NORMALKEY(k) (eKeys((k) & ~k_Repeat)) -diff -ruNp vdr-1.7.5/lirc.c vdr-1.7.5-extensions/lirc.c ---- vdr-1.7.5/lirc.c 2006-05-28 10:48:13.000000000 +0200 -+++ vdr-1.7.5-extensions/lirc.c 2009-04-12 13:37:59.000000000 +0200 -@@ -12,6 +12,9 @@ - #include "lirc.h" - #include <netinet/in.h> - #include <sys/socket.h> -+#ifdef USE_LIRCSETTINGS -+#include "config.h" -+#endif /* LIRCSETTINGS */ - - #define REPEATDELAY 350 // ms - #define REPEATFREQ 100 // ms -@@ -94,7 +97,11 @@ void cLircRemote::Action(void) - continue; - } - if (count == 0) { -+#ifdef USE_LIRCSETTINGS -+ if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < (unsigned int)Setup.LircRepeatDelay) -+#else - if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < REPEATDELAY) -+#endif /* LIRCSETTINGS */ - continue; // skip keys coming in too fast - if (repeat) - Put(LastKeyName, false, true); -@@ -104,18 +111,34 @@ void cLircRemote::Action(void) - timeout = -1; - } - else { -+#ifdef USE_LIRCSETTINGS -+ if (LastTime.Elapsed() < (unsigned int)Setup.LircRepeatFreq) -+#else - if (LastTime.Elapsed() < REPEATFREQ) -+#endif /* LIRCSETTINGS */ - continue; // repeat function kicks in after a short delay (after last key instead of first key) -+#ifdef USE_LIRCSETTINGS -+ if (FirstTime.Elapsed() < (unsigned int)Setup.LircRepeatDelay) -+#else - if (FirstTime.Elapsed() < REPEATDELAY) -+#endif /* LIRCSETTINGS */ - continue; // skip keys coming in too fast (for count != 0 as well) - repeat = true; -+#ifdef USE_LIRCSETTINGS -+ timeout = Setup.LircRepeatDelay; -+#else - timeout = REPEATDELAY; -+#endif /* LIRCSETTINGS */ - } - LastTime.Set(); - Put(KeyName, repeat); - } - else if (repeat) { // the last one was a repeat, so let's generate a release -+#ifdef USE_LIRCSETTINGS -+ if (LastTime.Elapsed() >= (unsigned int)Setup.LircRepeatTimeout) { -+#else - if (LastTime.Elapsed() >= REPEATTIMEOUT) { -+#endif /* LIRCSETTINGS */ - Put(LastKeyName, false, true); - repeat = false; - *LastKeyName = 0; -diff -ruNp vdr-1.7.5/mainmenuitemsprovider.h vdr-1.7.5-extensions/mainmenuitemsprovider.h ---- vdr-1.7.5/mainmenuitemsprovider.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/mainmenuitemsprovider.h 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,62 @@ -+#ifdef USE_MENUORG -+/* -+ * vdr-menuorg - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2007 - 2008 Tobias Grimm <vdr@e-tobi.net> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ * $Id$ -+ * -+ */ -+ -+#ifndef __MAINMENUITEMSPROVIDER_H -+#define __MAINMENUITEMSPROVIDER_H -+ -+#include <vector> -+ -+class cOsdItem; -+class cOsdMenu; -+ -+class IMenuItemDefinition -+{ -+ public: -+ virtual ~IMenuItemDefinition() {}; -+ virtual bool IsCustomOsdItem() = 0; -+ virtual bool IsPluginItem() = 0; -+ virtual bool IsSeparatorItem() = 0; -+ virtual cOsdItem* CustomOsdItem() = 0; -+ virtual const char* PluginMenuEntry() = 0; -+ virtual bool IsSelected() = 0; -+ virtual int PluginIndex() = 0; -+}; -+ -+typedef std::vector<IMenuItemDefinition*> MenuItemDefinitions; -+ -+#define MENU_ITEMS_PROVIDER_SERVICE_ID "MenuOrgPatch-v0.4.2::MainMenuItemsProvider" -+ -+class IMainMenuItemsProvider -+{ -+ public: -+ virtual ~IMainMenuItemsProvider() {}; -+ virtual bool IsCustomMenuAvailable() = 0; -+ virtual MenuItemDefinitions* MainMenuItems() = 0; -+ virtual void EnterRootMenu() = 0; -+ virtual void EnterSubMenu(cOsdItem* item) = 0; -+ virtual bool LeaveSubMenu() = 0; -+ virtual cOsdMenu* Execute(cOsdItem* item) = 0; -+}; -+ -+#endif //__MAINMENUITEMSPROVIDER_H -+#endif /* MENUORG */ -diff -ruNp vdr-1.7.5/Make.config.template vdr-1.7.5-extensions/Make.config.template ---- vdr-1.7.5/Make.config.template 2009-01-18 11:46:13.000000000 +0100 -+++ vdr-1.7.5-extensions/Make.config.template 2009-04-12 13:37:59.000000000 +0200 -@@ -42,8 +42,242 @@ RCU_DEVICE = /dev/ttyS1 - ## Define if you want vdr to not run as root - #VDR_USER = vdr - -+### VDR-Extensions: -+# Comment the patches you don't need -+# DVDCHAPJUMP needs DVDARCHIVE enabled -+# DVDARCHIVE needs LIEMIEXT enabled -+# SORTRECORDS needs LIEMIEXT enabled -+# you can only enable MENUORG or SETUP -+ -+#ANALOGTV = 1 -+#ATSC = 1 -+#CHANNELSCAN = 1 -+CMDRECCMDI18N = 1 -+CMDSUBMENU = 1 -+#CUTTERLIMIT = 1 -+#CUTTERQUEUE = 1 -+CUTTIME = 1 -+DDEPGENTRY = 1 -+#DELTIMESHIFTREC = 1 -+DOLBYINREC = 1 -+#DVBSETUP = 1 -+#DVDARCHIVE = 1 -+#DVDCHAPJUMP = 1 -+#DVLFRIENDLYFNAMES = 1 -+#DVLRECSCRIPTADDON = 1 -+#DVLVIDPREFER = 1 -+#EM84XX = 1 -+#GRAPHTFT = 1 -+#HARDLINKCUTTER = 1 -+#JUMPPLAY = 1 -+LIEMIEXT = 1 -+#LIRCSETTINGS = 1 -+#LNBSHARE = 1 -+#MAINMENUHOOKS = 1 -+#MENUORG = 1 -+#NOEPG = 1 -+#OSDMAXITEMS = 1 -+#PARENTALRATING = 1 -+#PINPLUGIN = 1 -+PLUGINAPI = 1 -+PLUGINMISSING = 1 -+#PLUGINPARAM = 1 -+#ROTOR = 1 -+SETTIME = 1 -+#SETUP = 1 -+#SOFTOSD = 1 -+#SOURCECAPS = 1 -+#SORTRECORDS = 1 -+STREAMDEVEXT = 1 -+#TIMERCMD = 1 -+#TIMERINFO = 1 -+#VALIDINPUT = 1 -+#VOLCTRL = 1 -+WAREAGLEICON = 1 -+#YAEPG = 1 -+ - ### You don't need to touch the following: - - ifdef DVBDIR - INCLUDES += -I$(DVBDIR)/include - endif -+ -+ifdef ANALOGTV -+DEFINES += -DUSE_ANALOGTV -+endif -+ -+ifdef ATSC -+DEFINES += -DUSE_ATSC -+endif -+ -+ifdef CHANNELSCAN -+DEFINES += -DUSE_CHANNELSCAN -+endif -+ -+ifdef CMDRECCMDI18N -+DEFINES += -DUSE_CMDRECCMDI18N -+endif -+ -+ifdef CMDSUBMENU -+DEFINES += -DUSE_CMDSUBMENU -+endif -+ -+ifdef CUTTERLIMIT -+DEFINES += -DUSE_CUTTERLIMIT -+endif -+ -+ifdef CUTTERQUEUE -+DEFINES += -DUSE_CUTTERQUEUE -+endif -+ -+ifdef CUTTIME -+DEFINES += -DUSE_CUTTIME -+endif -+ -+ifdef DDEPGENTRY -+DEFINES += -DUSE_DDEPGENTRY -+endif -+ -+ifdef DELTIMESHIFTREC -+DEFINES += -DUSE_DELTIMESHIFTREC -+endif -+ -+ifdef DOLBYINREC -+DEFINES += -DUSE_DOLBYINREC -+endif -+ -+ifdef DVBSETUP -+DEFINES += -DUSE_DVBSETUP -+endif -+ -+ifdef DVDARCHIVE -+ifdef LIEMIEXT -+DEFINES += -DUSE_DVDARCHIVE -+endif -+endif -+ -+ifdef DVLRECSCRIPTADDON -+DEFINES += -DUSE_DVLRECSCRIPTADDON -+endif -+ -+ifdef DVLVIDPREFER -+DEFINES += -DUSE_DVLVIDPREFER -+endif -+ -+ifdef DVLFRIENDLYFNAMES -+DEFINES += -DUSE_DVLFRIENDLYFNAMES -+endif -+ -+ifdef EM84XX -+DEFINES += -DUSE_EM84XX -+endif -+ -+ifdef GRAPHTFT -+DEFINES += -DUSE_GRAPHTFT -+endif -+ -+ifdef HARDLINKCUTTER -+DEFINES += -DUSE_HARDLINKCUTTER -+endif -+ -+ifdef JUMPPLAY -+DEFINES += -DUSE_JUMPPLAY -+endif -+ -+ifdef LIEMIEXT -+DEFINES += -DUSE_LIEMIEXT -+endif -+ -+ifdef LIRCSETTINGS -+DEFINES += -DUSE_LIRCSETTINGS -+endif -+ -+ifdef LNBSHARE -+DEFINES += -DUSE_LNBSHARE -+endif -+ -+ifdef MAINMENUHOOKS -+DEFINES += -DUSE_MAINMENUHOOKS -+endif -+ -+ifdef MENUORG -+DEFINES += -DUSE_MENUORG -+else -+ifdef SETUP -+DEFINES += -DUSE_SETUP -+endif -+endif -+ -+ifdef NOEPG -+DEFINES += -DUSE_NOEPG -+endif -+ -+ifdef OSDMAXITEMS -+DEFINES += -DUSE_OSDMAXITEMS -+endif -+ -+ifdef PARENTALRATING -+DEFINES += -DUSE_PARENTALRATING -+endif -+ -+ifdef PINPLUGIN -+DEFINES += -DUSE_PINPLUGIN -+endif -+ -+ifdef PLUGINMISSING -+DEFINES += -DUSE_PLUGINMISSING -+endif -+ -+ifdef PLUGINPARAM -+DEFINES += -DUSE_PLUGINPARAM -+endif -+ -+ifdef ROTOR -+DEFINES += -DUSE_ROTOR -+endif -+ -+ifdef SETTIME -+DEFINES += -DUSE_SETTIME -+endif -+ -+ifdef SOFTOSD -+DEFINES += -DUSE_SOFTOSD -+endif -+ -+ifdef SOURCECAPS -+DEFINES += -DUSE_SOURCECAPS -+endif -+ -+ifdef SORTRECORDS -+ifdef LIEMIEXT -+DEFINES += -DUSE_SORTRECORDS -+endif -+endif -+ -+ifdef STREAMDEVEXT -+DEFINES += -DUSE_STREAMDEVEXT -+endif -+ -+ifdef TIMERCMD -+DEFINES += -DUSE_TIMERCMD -+endif -+ -+ifdef TIMERINFO -+DEFINES += -DUSE_TIMERINFO -+endif -+ -+ifdef VALIDINPUT -+DEFINES += -DUSE_VALIDINPUT -+endif -+ -+ifdef VOLCTRL -+DEFINES += -DUSE_VOLCTRL -+endif -+ -+ifdef WAREAGLEICON -+DEFINES += -DUSE_WAREAGLEICON -+endif -+ -+ifdef YAEPG -+DEFINES += -DUSE_YAEPG -+endif -diff -ruNp vdr-1.7.5/Makefile vdr-1.7.5-extensions/Makefile ---- vdr-1.7.5/Makefile 2008-12-24 16:21:09.000000000 +0100 -+++ vdr-1.7.5-extensions/Makefile 2009-04-12 13:37:59.000000000 +0200 -@@ -43,6 +43,14 @@ OBJS = audio.o channels.o ci.o config.o - skinclassic.o skins.o skinsttng.o sources.o spu.o status.o svdrp.o themes.o thread.o\ - timers.o tools.o transfer.o vdr.o videodir.o - -+ifdef WAREAGLEICON -+OBJS += iconpatch.o -+endif -+ -+ifdef SETUP -+OBJS += tinystr.o tinyxml.o tinyxmlerror.o tinyxmlparser.o submenu.o -+endif -+ - ifndef NO_KBD - DEFINES += -DREMOTE_KBD - endif -@@ -72,6 +80,14 @@ DEFINES += -DLOCDIR=\"$(LOCDIR)\" - VDRVERSION = $(shell sed -ne '/define VDRVERSION/s/^.*"\(.*\)".*$$/\1/p' config.h) - APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' config.h) - -+ifdef DVDARCHIVE -+ifdef DVDCHAPJUMP -+LIBS += -ldvdread -+INCLUDES += -I/usr/include/dvdread -+DEFINES += -DUSE_DVDCHAPJUMP -+endif -+endif -+ - all: vdr i18n - - # Implicit rules: -@@ -137,6 +153,26 @@ include-dir: - - # Plugins: - -+ifdef PLUGINAPI -+DEFINES += -DUSE_PLUGINAPI -+plugins: include-dir -+ @failed="";\ -+ noapiv="";\ -+ for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do\ -+ echo "Plugin $$i:";\ -+ if ! grep -q "\$$(LIBDIR)/.*\$$(APIVERSION)" "$(PLUGINDIR)/src/$$i/Makefile" ; then\ -+ sed -i -e s/VDRVERSION/APIVERSION/g $(PLUGINDIR)/src/$$i/Makefile;\ -+ if ! grep -q "\$$(LIBDIR)/.*\$$(APIVERSION)" "$(PLUGINDIR)/src/$$i/Makefile" ; then\ -+ echo "ERROR: plugin $$i doesn't honor APIVERSION - not compiled!";\ -+ noapiv="$$noapiv $$i";\ -+ continue;\ -+ fi;\ -+ fi;\ -+ $(MAKE) -C "$(PLUGINDIR)/src/$$i" all || failed="$$failed $$i";\ -+ done;\ -+ if [ -n "$$noapiv" ] ; then echo; echo "*** plugins without APIVERSION:$$noapiv"; echo; fi;\ -+ if [ -n "$$failed" ] ; then echo; echo "*** failed plugins:$$failed"; echo; fi -+else - plugins: include-dir - @failed="";\ - noapiv="";\ -@@ -151,6 +187,7 @@ plugins: include-dir - done;\ - if [ -n "$$noapiv" ] ; then echo; echo "*** plugins without APIVERSION:$$noapiv"; echo; fi;\ - if [ -n "$$failed" ] ; then echo; echo "*** failed plugins:$$failed"; echo; exit 1; fi -+endif - - clean-plugins: - @for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do $(MAKE) -C "$(PLUGINDIR)/src/$$i" clean; done -diff -ruNp vdr-1.7.5/MANUAL vdr-1.7.5-extensions/MANUAL ---- vdr-1.7.5/MANUAL 2008-02-24 11:09:17.000000000 +0100 -+++ vdr-1.7.5-extensions/MANUAL 2009-04-12 13:37:59.000000000 +0200 -@@ -813,6 +813,30 @@ Version 1.6 - 0 resulting in a file named 'resume.vdr', and any other - value resulting in 'resume.n.vdr'. - -+ Jump&Play = no Turns playing on or off after jumping forward to the -+ next editing mark with the '9' key. -+ -+ Play&Jump = no Turns automatic jumping over commercial breaks on or -+ off. This includes jumping to the first mark, if the -+ replay starts at the beginning of a recording - and -+ stopping the replay at the last mark. -+ With this setting enabled, the behaviour of the '8' -+ key during replay is changed too. It moves the actual -+ replay position not only three seconds before the -+ next "start" mark, but also before the next "end" -+ mark. This can be used to test, if the editing marks -+ are correctly positioned for a "smooth" jump over a -+ commercial break. -+ -+ Pause at last mark = no -+ Turns pausing of replay at the last editing mark on or -+ off. -+ -+ Reload marks = no Turns reloading of editing marks on or off. This can -+ be used if an external programme adjusts the editing -+ marks, e.g. noad in online mode. The marks are reloaded -+ in 10 seconds intervals. -+ - Miscellaneous: - - Min. event timeout = 30 -diff -ruNp vdr-1.7.5/menu.c vdr-1.7.5-extensions/menu.c ---- vdr-1.7.5/menu.c 2009-01-24 16:05:43.000000000 +0100 -+++ vdr-1.7.5-extensions/menu.c 2009-04-12 13:37:59.000000000 +0200 -@@ -8,12 +8,18 @@ - */ - - #include "menu.h" -+#ifdef USE_WAREAGLEICON -+#include "iconpatch.h" -+#endif /* WAREAGLEICON */ - #include <ctype.h> - #include <limits.h> - #include <math.h> - #include <stdio.h> - #include <stdlib.h> - #include <string.h> -+#ifdef USE_LIEMIEXT -+#include <math.h> -+#endif /* LIEMIEXT */ - #include "channels.h" - #include "config.h" - #include "cutter.h" -@@ -30,6 +36,13 @@ - #include "timers.h" - #include "transfer.h" - #include "videodir.h" -+#ifdef USE_MENUORG -+#include "menuorgpatch.h" -+#endif /* MENUORG */ -+ -+#ifdef USE_CMDRECCMDI18N -+extern const char *ConfigDirectory; -+#endif /* CMDRECCMDI18N */ - - #define MAXWAIT4EPGINFO 3 // seconds - #define MODETIMEOUT 3 // seconds -@@ -190,10 +203,16 @@ private: - cChannel *channel; - cChannel data; - char name[256]; -+#ifdef USE_PLUGINPARAM -+ char pluginParam[256]; -+#endif /* PLUGINPARAM */ - void Setup(void); - public: - cMenuEditChannel(cChannel *Channel, bool New = false); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuEditChannel"; } -+#endif /* GRAPHTFT */ - }; - - cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New) -@@ -222,6 +241,9 @@ void cMenuEditChannel::Setup(void) - - // Parameters for all types of sources: - strn0cpy(name, data.name, sizeof(name)); -+#ifdef USE_PLUGINPARAM -+ strn0cpy(pluginParam, data.pluginParam, sizeof(pluginParam)); -+#endif /* PLUGINPARAM */ - Add(new cMenuEditStrItem( tr("Name"), name, sizeof(name))); - Add(new cMenuEditSrcItem( tr("Source"), &data.source)); - Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency)); -@@ -254,6 +276,9 @@ void cMenuEditChannel::Setup(void) - ST(" T") Add(new cMenuEditMapItem( tr("Guard"), &data.guard, GuardValues)); - ST(" T") Add(new cMenuEditMapItem( tr("Hierarchy"), &data.hierarchy, HierarchyValues)); - ST(" S ") Add(new cMenuEditMapItem( tr("Rolloff"), &data.rollOff, RollOffValues)); -+#ifdef USE_PLUGINPARAM -+ ST("P ") Add(new cMenuEditStrItem( tr("Parameters"), pluginParam, sizeof(pluginParam), tr(FileNameChars))); -+#endif /* PLUGINPARAM */ - - SetCurrent(Get(current)); - Display(); -@@ -268,9 +293,15 @@ eOSState cMenuEditChannel::ProcessKey(eK - if (Key == kOk) { - if (Channels.HasUniqueChannelID(&data, channel)) { - data.name = strcpyrealloc(data.name, name); -+#ifdef USE_PLUGINPARAM -+ data.pluginParam = strcpyrealloc(data.pluginParam, pluginParam); -+#endif /* PLUGINPARAM */ - if (channel) { - *channel = data; - isyslog("edited channel %d %s", channel->Number(), *data.ToText()); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(channel, scMod); -+#endif /* STREAMDEVEXT */ - state = osBack; - } - else { -@@ -279,6 +310,9 @@ eOSState cMenuEditChannel::ProcessKey(eK - Channels.Add(channel); - Channels.ReNumber(); - isyslog("added channel %d %s", channel->Number(), *data.ToText()); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(channel, scAdd); -+#endif /* STREAMDEVEXT */ - state = osUser1; - } - Channels.SetModified(true); -@@ -341,6 +375,16 @@ void cMenuChannelItem::Set(void) - if (!channel->GroupSep()) { - if (sortMode == csmProvider) - buffer = cString::sprintf("%d\t%s - %s", channel->Number(), channel->Provider(), channel->Name()); -+#ifdef USE_WAREAGLEICON -+ else if (Setup.WarEagleIcons) { -+ if (channel->Vpid() == 1 || channel->Vpid() == 0) -+ buffer = cString::sprintf("%d\t%s %-30s", channel->Number(), IsLangUtf8() ? ICON_RADIO_UTF8 : ICON_RADIO, channel->Name()); -+ else if (channel->Ca() == 0) -+ buffer = cString::sprintf("%d\t%s %-30s", channel->Number(), IsLangUtf8() ? ICON_TV_UTF8 : ICON_TV, channel->Name()); -+ else -+ buffer = cString::sprintf("%d\t%s %-30s", channel->Number(), IsLangUtf8() ? ICON_TV_CRYPTED_UTF8 : ICON_TV_CRYPTED, channel->Name()); -+ } -+#endif /* WAREAGLEICON */ - else - buffer = cString::sprintf("%d\t%s", channel->Number(), channel->Name()); - } -@@ -371,6 +415,9 @@ public: - cMenuChannels(void); - ~cMenuChannels(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuChannels"; } -+#endif /* GRAPHTFT */ - }; - - cMenuChannels::cMenuChannels(void) -@@ -500,6 +547,9 @@ eOSState cMenuChannels::Delete(void) - Propagate(); - Channels.SetModified(true); - isyslog("channel %d deleted", DeletedChannel); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(NULL, scDel); -+#endif /* STREAMDEVEXT */ - if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { - if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) - Channels.SwitchTo(CurrentChannel->Number()); -@@ -525,6 +575,9 @@ void cMenuChannels::Move(int From, int T - Propagate(); - Channels.SetModified(true); - isyslog("channel %d moved to %d", FromNumber, ToNumber); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(ToChannel, scMod); -+#endif /* STREAMDEVEXT */ - if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { - if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) - Channels.SwitchTo(CurrentChannel->Number()); -@@ -637,14 +690,47 @@ cMenuEditTimer::cMenuEditTimer(cTimer *T - data.SetFlags(tfActive); - channel = data.Channel()->Number(); - Add(new cMenuEditBitItem( tr("Active"), &data.flags, tfActive)); -+#ifdef USE_PINPLUGIN -+ if (cOsd::pinValid) Add(new cMenuEditChanItem(tr("Channel"), &channel)); -+ else { -+ cString buf = cString::sprintf("%s\t%s", tr("Channel"), Channels.GetByNumber(channel)->Name()); -+ Add(new cOsdItem(buf)); -+ } -+#else - Add(new cMenuEditChanItem(tr("Channel"), &channel)); -+#endif /* PINPLUGIN */ - Add(new cMenuEditDateItem(tr("Day"), &data.day, &data.weekdays)); - Add(new cMenuEditTimeItem(tr("Start"), &data.start)); - Add(new cMenuEditTimeItem(tr("Stop"), &data.stop)); - Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps)); - Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY)); - Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME)); -+#ifdef USE_PINPLUGIN -+ if (cOsd::pinValid || !data.fskProtection) Add(new cMenuEditBoolItem(tr("Childlock"),&data.fskProtection)); -+ else { -+ cString buf = cString::sprintf("%s\t%s", tr("Childlock"), data.fskProtection ? tr("yes") : tr("no")); -+ Add(new cOsdItem(buf)); -+ } -+#endif /* PINPLUGIN */ -+#ifdef USE_LIEMIEXT -+ char* p = strrchr(data.file, '~'); -+ if (p) { -+ p++; -+ Utf8Strn0Cpy(name, p, sizeof(name)); -+ Utf8Strn0Cpy(path, data.file, sizeof(path)); -+ p = strrchr(path, '~'); -+ if (p) -+ p[0] = 0; -+ } -+ else { -+ Utf8Strn0Cpy(name, data.file, sizeof(name)); -+ Utf8Strn0Cpy(path, "", sizeof(path)); -+ } -+ Add(new cMenuEditStrItem(tr("File"), name, sizeof(name), tr(FileNameChars))); -+ Add(new cMenuEditRecPathItem(tr("Path"), path, sizeof(path))); -+#else - Add(new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file))); -+#endif /* LIEMIEXT */ - SetFirstDayItem(); - } - Timers.IncBeingEdited(); -@@ -684,6 +770,12 @@ eOSState cMenuEditTimer::ProcessKey(eKey - Skins.Message(mtError, tr("*** Invalid Channel ***")); - break; - } -+#ifdef USE_LIEMIEXT -+ if (strlen(path)) -+ snprintf(data.file, sizeof(data.file), "%s~%s", path, name); -+ else -+ snprintf(data.file, sizeof(data.file), "%s", name); -+#endif /* LIEMIEXT */ - if (!*data.file) - strcpy(data.file, data.Channel()->ShortName(true)); - if (timer) { -@@ -711,13 +803,37 @@ eOSState cMenuEditTimer::ProcessKey(eKey - return state; - } - -+#ifdef USE_TIMERCMD -+// --- cMenuCommands --------------------------------------------------------- -+// declaration shifted so it can be used in cMenuTimers -+class cMenuCommands : public cOsdMenu { -+private: -+ cCommands *commands; -+ char *parameters; -+ eOSState Execute(void); -+public: -+ cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters = NULL); -+ virtual ~cMenuCommands(); -+ virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuCommands"; } -+#endif /* GRAPHTFT - passt das so? */ -+ }; -+#endif /* TIMERCMD */ -+ - // --- cMenuTimerItem -------------------------------------------------------- - - class cMenuTimerItem : public cOsdItem { - private: - cTimer *timer; -+#ifdef USE_TIMERINFO -+ char diskStatus; -+#endif /* TIMERINFO */ - public: - cMenuTimerItem(cTimer *Timer); -+#ifdef USE_TIMERINFO -+ void SetDiskStatus(char DiskStatus); -+#endif /* TIMERINFO */ - virtual int Compare(const cListObject &ListObject) const; - virtual void Set(void); - cTimer *Timer(void) { return timer; } -@@ -726,6 +842,9 @@ public: - cMenuTimerItem::cMenuTimerItem(cTimer *Timer) - { - timer = Timer; -+#ifdef USE_TIMERINFO -+ diskStatus = ' '; -+#endif /* TIMERINFO */ - Set(); - } - -@@ -751,8 +870,56 @@ void cMenuTimerItem::Set(void) - strftime(buffer, sizeof(buffer), "%Y%m%d", &tm_r); - day = buffer; - } -+#ifdef USE_LIEMIEXT -+ if (!Setup.ShowTimerStop) { -+#ifdef USE_TIMERINFO -+#ifdef USE_WAREAGLEICON -+ SetText(cString::sprintf("%c%s\t%d\t%s%s%s\t%02d:%02d\t%s", -+#else -+ SetText(cString::sprintf("%c%c\t%d\t%s%s%s\t%02d:%02d\t%s", -+#endif /* WAREAGLEICON */ -+ diskStatus, -+#else -+#ifdef USE_WAREAGLEICON -+ SetText(cString::sprintf("%s\t%d\t%s%s%s\t%02d:%02d\t%s", -+#else -+ SetText(cString::sprintf("%c\t%d\t%s%s%s\t%02d:%02d\t%s", -+#endif /* WAREAGLEICON */ -+#endif /* TIMERINFO */ -+#ifdef USE_WAREAGLEICON -+ !(timer->HasFlags(tfActive)) ? " " : timer->FirstDay() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_ARROW_UTF8 : ICON_ARROW : "!" : timer->Recording() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_REC_UTF8 : ICON_REC : "#" : Setup.WarEagleIcons ? IsLangUtf8() ? ICON_CLOCK_UTF8 : ICON_CLOCK : ">", -+#else -+ !(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>', -+#endif /* WAREAGLEICON */ -+ timer->Channel()->Number(), -+ *name, -+ *name && **name ? " " : "", -+ *day, -+ timer->Start() / 100, -+ timer->Start() % 100, -+ timer->File())); -+ } -+ else { -+#endif /* LIEMIEXT */ -+#ifdef USE_TIMERINFO -+#ifdef USE_WAREAGLEICON -+ SetText(cString::sprintf("%c%s\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", -+#else -+ SetText(cString::sprintf("%c%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", -+#endif /* WAREAGLEICON */ -+ diskStatus, -+#else -+#ifdef USE_WAREAGLEICON -+ SetText(cString::sprintf("%s\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", -+#else - SetText(cString::sprintf("%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s", -+#endif /* WAREAGLEICON */ -+#endif /* TIMERINFO */ -+#ifdef USE_WAREAGLEICON -+ !(timer->HasFlags(tfActive)) ? " " : timer->FirstDay() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_ARROW_UTF8 : ICON_ARROW : "!" : timer->Recording() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_REC_UTF8 : ICON_REC : "#" : Setup.WarEagleIcons ? IsLangUtf8() ? ICON_CLOCK_UTF8 : ICON_CLOCK : ">", -+#else - !(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>', -+#endif /* WAREAGLEICON */ - timer->Channel()->Number(), - *name, - *name && **name ? " " : "", -@@ -762,8 +929,64 @@ void cMenuTimerItem::Set(void) - timer->Stop() / 100, - timer->Stop() % 100, - timer->File())); -+#ifdef USE_LIEMIEXT -+ } -+#endif /* LIEMIEXT */ -+} -+ -+#ifdef USE_TIMERINFO -+void cMenuTimerItem::SetDiskStatus(char DiskStatus) -+{ -+ diskStatus = DiskStatus; -+ Set(); -+} -+ -+// --- cTimerEntry ----------------------------------------------------------- -+ -+class cTimerEntry : public cListObject { -+private: -+ cMenuTimerItem *item; -+ const cTimer *timer; -+ time_t start; -+public: -+ cTimerEntry(cMenuTimerItem *item) : item(item), timer(item->Timer()), start(timer->StartTime()) {} -+ cTimerEntry(const cTimer *timer, time_t start) : item(NULL), timer(timer), start(start) {} -+ virtual int Compare(const cListObject &ListObject) const; -+ bool active(void) const { return timer->HasFlags(tfActive); } -+ time_t startTime(void) const { return start; } -+ int priority(void) const { return timer->Priority(); } -+ int duration(void) const; -+ bool repTimer(void) const { return !timer->IsSingleEvent(); } -+ bool isDummy(void) const { return item == NULL; } -+ const cTimer *Timer(void) const { return timer; } -+ void SetDiskStatus(char DiskStatus); -+ }; -+ -+int cTimerEntry::Compare(const cListObject &ListObject) const -+{ -+ cTimerEntry *entry = (cTimerEntry *)&ListObject; -+ int r = startTime() - entry->startTime(); -+ if (r == 0) -+ r = entry->priority() - priority(); -+ return r; -+} -+ -+int cTimerEntry::duration(void) const -+{ -+ int dur = (timer->Stop() / 100 * 60 + timer->Stop() % 100) - -+ (timer->Start() / 100 * 60 + timer->Start() % 100); -+ if (dur < 0) -+ dur += 24 * 60; -+ return dur; - } - -+void cTimerEntry::SetDiskStatus(char DiskStatus) -+{ -+ if (item) -+ item->SetDiskStatus(DiskStatus); -+} -+#endif /* TIMERINFO */ -+ - // --- cMenuTimers ----------------------------------------------------------- - - class cMenuTimers : public cOsdMenu { -@@ -776,14 +999,31 @@ private: - eOSState Info(void); - cTimer *CurrentTimer(void); - void SetHelpKeys(void); -+#ifdef USE_TIMERINFO -+ void ActualiseDiskStatus(void); -+ bool actualiseDiskStatus; -+#endif /* TIMERINFO */ -+#ifdef USE_TIMERCMD -+ eOSState Commands(eKeys Key = kNone); -+#endif /* TIMERCMD */ - public: - cMenuTimers(void); - virtual ~cMenuTimers(); -+#ifdef USE_TIMERINFO -+ virtual void Display(void); -+#endif /* TIMERINFO */ - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuTimers"; } -+#endif /* GRAPHTFT */ - }; - - cMenuTimers::cMenuTimers(void) -+#ifdef USE_TIMERINFO -+:cOsdMenu(tr("Timers"), 3, CHNUMWIDTH, 10, 6, 6) -+#else - :cOsdMenu(tr("Timers"), 2, CHNUMWIDTH, 10, 6, 6) -+#endif /* TIMERINFO */ - { - helpKeys = -1; - for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) { -@@ -794,6 +1034,9 @@ cMenuTimers::cMenuTimers(void) - SetCurrent(First()); - SetHelpKeys(); - Timers.IncBeingEdited(); -+#ifdef USE_TIMERINFO -+ actualiseDiskStatus = true; -+#endif /* TIMERINFO */ - } - - cMenuTimers::~cMenuTimers() -@@ -832,7 +1075,11 @@ eOSState cMenuTimers::OnOff(void) - timer->OnOff(); - timer->SetEventFromSchedule(); - RefreshCurrent(); -+#ifdef USE_TIMERINFO -+ Display(); -+#else - DisplayCurrent(true); -+#endif /* TIMERINFO */ - if (timer->FirstDay()) - isyslog("timer %s first day set to %s", *timer->ToDescr(), *timer->PrintFirstDay()); - else -@@ -891,6 +1138,117 @@ eOSState cMenuTimers::Info(void) - return osContinue; - } - -+#ifdef USE_TIMERCMD -+#define CHECK_2PTR_NULL(x_,y_) ((x_)? ((y_)? y_:""):"") -+ -+eOSState cMenuTimers::Commands(eKeys Key) -+{ -+ if (HasSubMenu() || Count() == 0) -+ return osContinue; -+ cTimer *ti = CurrentTimer(); -+ if (ti) { -+ const cEvent *pEvent = ti->Event(); -+ int iRecNumber=0; -+ -+ if (!pEvent) { -+ Timers.SetEvents(); -+ pEvent = ti->Event(); -+ } -+ if (pEvent) { -+ // create a dummy recording to get the real filename -+ cRecording *rc_dummy = new cRecording(ti, pEvent); -+ Recordings.Load(); -+ cRecording *rc = Recordings.GetByName(rc_dummy->FileName()); -+ -+ delete rc_dummy; -+ if (rc) -+ iRecNumber=rc->Index() + 1; -+ } -+ // TODO: Geht das so...? -+ // Parameter format TimerNumber 'ChannelId' Start Stop 'Titel' 'Subtitel' 'file' RecNumer -+ // 1 2 3 4 5 6 7 8 -+ cString parameter = cString::sprintf("%d '%s' %d %d '%s' '%s' '%s' %d", ti->Index(), -+ *ti->Channel()->GetChannelID().ToString(), -+ (int)ti->StartTime(), -+ (int)ti->StopTime(), -+ CHECK_2PTR_NULL(pEvent, pEvent->Title()), -+ CHECK_2PTR_NULL(pEvent, pEvent->ShortText()), -+ ti->File(), -+ iRecNumber); -+ isyslog("timercmd: %s", *parameter); -+ cMenuCommands *menu; -+ eOSState state = AddSubMenu(menu = new cMenuCommands(tr("Timer commands"), &TimerCommands, parameter)); -+ if (Key != kNone) -+ state = menu->ProcessKey(Key); -+ return state; -+ } -+ return osContinue; -+} -+#endif /* TIMERCMD */ -+ -+#ifdef USE_TIMERINFO -+void cMenuTimers::ActualiseDiskStatus(void) -+{ -+ if (!actualiseDiskStatus || !Count()) -+ return; -+ -+ // compute free disk space -+ int freeMB, freeMinutes, runshortMinutes; -+ VideoDiskSpace(&freeMB); -+ freeMinutes = int(double(freeMB) * 1.1 / MB_PER_MINUTE); // overestimate by 10 percent -+ runshortMinutes = freeMinutes / 5; // 20 Percent -+ -+ // fill entries list -+ cTimerEntry *entry; -+ cList<cTimerEntry> entries; -+ for (cOsdItem *item = First(); item; item = Next(item)) -+ entries.Add(new cTimerEntry((cMenuTimerItem *)item)); -+ -+ // search last start time -+ time_t last = 0; -+ for (entry = entries.First(); entry; entry = entries.Next(entry)) -+ last = max(entry->startTime(), last); -+ -+ // add entries for repeating timers -+ for (entry = entries.First(); entry; entry = entries.Next(entry)) -+ if (entry->repTimer() && !entry->isDummy()) -+ for (time_t start = cTimer::IncDay(entry->startTime(), 1); -+ start <= last; -+ start = cTimer::IncDay(start, 1)) -+ if (entry->Timer()->DayMatches(start)) -+ entries.Add(new cTimerEntry(entry->Timer(), start)); -+ -+ // set the disk-status -+ entries.Sort(); -+ for (entry = entries.First(); entry; entry = entries.Next(entry)) { -+ char status = ' '; -+ if (entry->active()) { -+ freeMinutes -= entry->duration(); -+ status = freeMinutes > runshortMinutes ? '+' : freeMinutes > 0 ? '~' /* ± 177 +/- */ : '-'; -+ } -+ entry->SetDiskStatus(status); -+#ifdef DEBUG_TIMER_INFO -+ dsyslog("timer-info: %c | %d | %s | %s | %3d | %+5d -> %+5d", -+ status, -+ entry->startTime(), -+ entry->active() ? "aktiv " : "n.akt.", -+ entry->repTimer() ? entry->isDummy() ? " dummy " : "mehrmalig" : "einmalig ", -+ entry->duration(), -+ entry->active() ? freeMinutes + entry->duration() : freeMinutes, -+ freeMinutes); -+#endif -+ } -+ -+ actualiseDiskStatus = false; -+} -+ -+void cMenuTimers::Display(void) -+{ -+ ActualiseDiskStatus(); -+ cOsdMenu::Display(); -+} -+#endif /* TIMERINFO */ -+ - eOSState cMenuTimers::ProcessKey(eKeys Key) - { - int TimerNumber = HasSubMenu() ? Count() : -1; -@@ -899,18 +1257,40 @@ eOSState cMenuTimers::ProcessKey(eKeys K - if (state == osUnknown) { - switch (Key) { - case kOk: return Edit(); -+#ifdef USE_TIMERINFO -+ case kRed: actualiseDiskStatus = true; -+ state = OnOff(); break; // must go through SetHelpKeys()! -+#else - case kRed: state = OnOff(); break; // must go through SetHelpKeys()! -+#endif /* TIMERINFO */ - case kGreen: return New(); -+#ifdef USE_TIMERINFO -+ case kYellow: actualiseDiskStatus = true; -+ state = Delete(); break; -+#else - case kYellow: state = Delete(); break; -+#endif /* TIMERINFO */ - case kInfo: - case kBlue: return Info(); - break; -+#ifdef USE_TIMERCMD -+ case k1...k9: return Commands(Key); -+ case k0: return (TimerCommands.Count()? Commands():osContinue); -+#endif /* TIMERCMD */ - default: break; - } - } -+#ifdef USE_TIMERINFO -+ if (TimerNumber >= 0 && !HasSubMenu()) { -+ if (Timers.Get(TimerNumber)) // a newly created timer was confirmed with Ok -+ Add(new cMenuTimerItem(Timers.Get(TimerNumber)), true); -+ Sort(); -+ actualiseDiskStatus = true; -+#else - if (TimerNumber >= 0 && !HasSubMenu() && Timers.Get(TimerNumber)) { - // a newly created timer was confirmed with Ok - Add(new cMenuTimerItem(Timers.Get(TimerNumber)), true); -+#endif /* TIMERINFO */ - Display(); - } - if (Key != kNone) -@@ -940,6 +1320,9 @@ void cMenuEvent::Display(void) - { - cOsdMenu::Display(); - DisplayMenu()->SetEvent(event); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdSetEvent(event); -+#endif /* GRAPHTFT */ - if (event->Description()) - cStatus::MsgOsdTextItem(event->Description()); - } -@@ -987,7 +1370,12 @@ public: - const cChannel *channel; - bool withDate; - int timerMatch; -+#ifdef USE_LIEMIEXT -+ bool withBar; -+ cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL, bool WithDate = false, bool WithBar = false); -+#else - cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL, bool WithDate = false); -+#endif /* LIEMIEXT */ - static void SetSortMode(eScheduleSortMode SortMode) { sortMode = SortMode; } - static void IncSortMode(void) { sortMode = eScheduleSortMode((sortMode == ssmAllAll) ? ssmAllThis : sortMode + 1); } - static eScheduleSortMode SortMode(void) { return sortMode; } -@@ -997,12 +1385,19 @@ public: - - cMenuScheduleItem::eScheduleSortMode cMenuScheduleItem::sortMode = ssmAllThis; - -+#ifdef USE_LIEMIEXT -+cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel, bool WithDate, bool WithBar) -+#else - cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel, bool WithDate) -+#endif /* LIEMIEXT */ - { - event = Event; - channel = Channel; - withDate = WithDate; - timerMatch = tmNone; -+#ifdef USE_LIEMIEXT -+ withBar = WithBar; -+#endif /* LIEMIEXT */ - Update(true); - } - -@@ -1017,7 +1412,29 @@ int cMenuScheduleItem::Compare(const cLi - return r; - } - -+#ifdef USE_LIEMIEXT -+static const char * const ProgressBar[7] = -+{ -+ "[ ]", -+ "[| ]", -+ "[|| ]", -+ "[||| ]", -+ "[|||| ]", -+ "[||||| ]", -+ "[||||||]" -+}; -+#endif /* LIEMIEXT */ -+ -+#ifdef USE_WAREAGLEICON -+static const char *TimerMatchChars[9] = -+{ -+ " ", "t", "T", -+ ICON_BLANK, ICON_CLOCK_UH, ICON_CLOCK, -+ ICON_BLANK_UTF8, ICON_CLOCK_UH_UTF8, ICON_CLOCK_UTF8 -+}; -+#else - static const char *TimerMatchChars = " tT"; -+#endif /* WAREAGLEICON */ - - bool cMenuScheduleItem::Update(bool Force) - { -@@ -1026,17 +1443,54 @@ bool cMenuScheduleItem::Update(bool Forc - Timers.GetMatch(event, &timerMatch); - if (Force || timerMatch != OldTimerMatch) { - cString buffer; -+#ifdef USE_WAREAGLEICON -+ const char *t = Setup.WarEagleIcons ? IsLangUtf8() ? TimerMatchChars[timerMatch+6] : TimerMatchChars[timerMatch+3] : TimerMatchChars[timerMatch]; -+ const char *v = event->Vps() && (event->Vps() - event->StartTime()) ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_VPS_UTF8 : ICON_VPS : "V" : " "; -+ const char *r = event->SeenWithin(30) && event->IsRunning() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_RUNNING_UTF8 : ICON_RUNNING : "*" : " "; -+#else - char t = TimerMatchChars[timerMatch]; - char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' '; - char r = event->SeenWithin(30) && event->IsRunning() ? '*' : ' '; -+#endif /* WAREAGLEICON */ - const char *csn = channel ? channel->ShortName(true) : NULL; - cString eds = event->GetDateString(); - if (channel && withDate) -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%d\t%.*s\t%.*s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); -+#else - buffer = cString::sprintf("%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ - else if (channel) -+#ifdef USE_LIEMIEXT -+ if (Setup.ShowProgressBar && withBar) { -+ int progress = (int)roundf( (float)(time(NULL) - event->StartTime()) / (float)(event->Duration()) * 6.0 ); -+ if (progress < 0) progress = 0; -+ else if (progress > 6) progress = 6; -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), ProgressBar[progress], t, v, r, event->Title()); -+#else -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), ProgressBar[progress], t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ -+ } -+ else -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); -+#else -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ -+#else -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%d\t%.*s\t%s\t%s%s%s\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); -+#else - buffer = cString::sprintf("%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ -+#endif /* LIEMIEXT */ - else -+#ifdef USE_WAREAGLEICON -+ buffer = cString::sprintf("%.*s\t%s\t%s%s%s\t%s", Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); -+#else - buffer = cString::sprintf("%.*s\t%s\t%c%c%c\t%s", Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); -+#endif /* WAREAGLEICON */ - SetText(buffer); - result = true; - } -@@ -1062,13 +1516,21 @@ public: - static void SetCurrentChannel(int ChannelNr) { currentChannel = ChannelNr; } - static const cEvent *ScheduleEvent(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return now ? "MenuWhatsOnNow" : "MenuWhatsOnNext"; } -+ virtual void Display(void); -+#endif /* GRAPHTFT */ - }; - - int cMenuWhatsOn::currentChannel = 0; - const cEvent *cMenuWhatsOn::scheduleEvent = NULL; - - cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr) -+#ifdef USE_LIEMIEXT -+:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6, 4, 4) -+#else - :cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6, 4) -+#endif /* LIEMIEXT */ - { - now = Now; - helpKeys = -1; -@@ -1080,7 +1542,11 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedu - if (Schedule) { - const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent(); - if (Event) -+#ifdef USE_LIEMIEXT -+ Add(new cMenuScheduleItem(Event, Channel, false, Now), Channel->Number() == CurrentChannelNr); -+#else - Add(new cMenuScheduleItem(Event, Channel), Channel->Number() == CurrentChannelNr); -+#endif /* LIEMIEXT */ - } - } - } -@@ -1089,6 +1555,19 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedu - SetHelpKeys(); - } - -+#ifdef USE_GRAPHTFT -+void cMenuWhatsOn::Display(void) -+{ -+ cOsdMenu::Display(); -+ -+ if (Count() > 0) { -+ int ni = 0; -+ for (cOsdItem *item = First(); item; item = Next(item)) -+ cStatus::MsgOsdEventItem(((cMenuScheduleItem*)item)->event, item->Text(), ni++, Count()); -+ } -+} -+#endif /* GRAPHTFT */ -+ - bool cMenuWhatsOn::Update(void) - { - bool result = false; -@@ -1229,6 +1708,10 @@ public: - cMenuSchedule(void); - virtual ~cMenuSchedule(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSchedule"; } -+ virtual void Display(void); -+#endif /* GRAPHTFT */ - }; - - cMenuSchedule::cMenuSchedule(void) -@@ -1254,6 +1737,19 @@ cMenuSchedule::~cMenuSchedule() - cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared - } - -+#ifdef USE_GRAPHTFT -+void cMenuSchedule::Display(void) -+{ -+ cOsdMenu::Display(); -+ -+ if (Count() > 0) { -+ int ni = 0; -+ for (cOsdItem *item = First(); item; item = Next(item)) -+ cStatus::MsgOsdEventItem(((cMenuScheduleItem*)item)->event, item->Text(), ni++, Count()); -+ } -+} -+#endif /* GRAPHTFT */ -+ - void cMenuSchedule::PrepareScheduleAllThis(const cEvent *Event, const cChannel *Channel) - { - Clear(); -@@ -1487,6 +1983,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys - - // --- cMenuCommands --------------------------------------------------------- - -+#ifndef USE_TIMERCMD - class cMenuCommands : public cOsdMenu { - private: - cCommands *commands; -@@ -1496,7 +1993,11 @@ public: - cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters = NULL); - virtual ~cMenuCommands(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuCommands"; } -+#endif /* GRAPHTFT */ - }; -+#endif /* TIMERCMD */ - - cMenuCommands::cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters) - :cOsdMenu(Title) -@@ -1518,6 +2019,12 @@ eOSState cMenuCommands::Execute(void) - cCommand *command = commands->Get(Current()); - if (command) { - bool confirmed = true; -+#ifdef USE_CMDSUBMENU -+ if (command->hasChilds()) { -+ AddSubMenu(new cMenuCommands(command->Title(), command->getChilds(), parameters)); -+ return osContinue; -+ } -+#endif /* CMDSUBMENU */ - if (command->Confirm()) - confirmed = Interface->Confirm(cString::sprintf("%s?", command->Title())); - if (confirmed) { -@@ -1568,6 +2075,9 @@ public: - cMenuCam(cCamSlot *CamSlot); - virtual ~cMenuCam(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuCam"; } -+#endif /* GRAPHTFT */ - }; - - cMenuCam::cMenuCam(cCamSlot *CamSlot) -@@ -1747,6 +2257,9 @@ public: - cMenuRecording(const cRecording *Recording, bool WithButtons = false); - virtual void Display(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuRecording"; } -+#endif /* GRAPHTFT */ - }; - - cMenuRecording::cMenuRecording(const cRecording *Recording, bool WithButtons) -@@ -1762,6 +2275,9 @@ void cMenuRecording::Display(void) - { - cOsdMenu::Display(); - DisplayMenu()->SetRecording(recording); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdSetRecording(recording); -+#endif /* GRAPHTFT */ - if (recording->Info()->Description()) - cStatus::MsgOsdTextItem(recording->Info()->Description()); - } -@@ -1822,7 +2338,11 @@ cMenuRecordingItem::cMenuRecordingItem(c - fileName = strdup(Recording->FileName()); - name = NULL; - totalEntries = newEntries = 0; -+#ifdef USE_LIEMIEXT -+ SetText(Recording->Title('\t', true, Level, false)); -+#else - SetText(Recording->Title('\t', true, Level)); -+#endif /* LIEMIEXT */ - if (*Text() == '\t') - name = strdup(Text() + 2); // 'Text() + 2' to skip the two '\t' - } -@@ -1838,13 +2358,198 @@ void cMenuRecordingItem::IncrementCounte - totalEntries++; - if (New) - newEntries++; -+#ifdef USE_LIEMIEXT -+#ifdef USE_WAREAGLEICON -+ switch (Setup.ShowRecTime + Setup.ShowRecDate + Setup.ShowRecLength) { -+ case 0: -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s %s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, name)); -+ else -+ SetText(cString::sprintf("%s", name)); -+ break; -+ case 1: -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s %d\t%s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, totalEntries, name)); -+ else -+ SetText(cString::sprintf("%d\t%s", totalEntries, name)); -+ break; -+ case 2: -+ default: -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s (%d/%d)\t%s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, totalEntries, newEntries, name)); -+ else -+ SetText(cString::sprintf("%d\t%d\t%s", totalEntries, newEntries, name)); -+ break; -+ case 3: -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s (%d/%d)\t\t%s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, totalEntries, newEntries, name)); -+ else -+ SetText(cString::sprintf("%d\t%d\t\t%s", totalEntries, newEntries, name)); -+ break; -+ } -+#else -+ switch (Setup.ShowRecTime + Setup.ShowRecDate + Setup.ShowRecLength) { -+ case 0: -+ SetText(cString::sprintf("%s", name)); -+ break; -+ case 1: -+ SetText(cString::sprintf("%d\t%s", totalEntries, name)); -+ break; -+ case 2: -+ default: -+ SetText(cString::sprintf("%d\t%d\t%s", totalEntries, newEntries, name)); -+ break; -+ case 3: -+ SetText(cString::sprintf("%d\t%d\t\t%s", totalEntries, newEntries, name)); -+ break; -+ } -+#endif /* WAREAGLEICON */ -+#else -+#ifdef USE_WAREAGLEICON -+ if (Setup.WarEagleIcons) -+ SetText(cString::sprintf("%s (%d/%d)\t%s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER, totalEntries, newEntries, name)); -+ else -+#endif /* WAREAGLEICON */ - SetText(cString::sprintf("%d\t%d\t%s", totalEntries, newEntries, name)); -+#endif /* LIEMIEXT */ -+} -+ -+#ifdef USE_LIEMIEXT -+// --- cMenuRenameRecording -------------------------------------------------- -+ -+class cMenuRenameRecording : public cOsdMenu { -+private: -+ char name[MaxFileName]; -+ char path[MaxFileName]; -+ cOsdItem *marksItem, *resumeItem; -+ bool isResume, isMarks; -+ cRecording *recording; -+public: -+ cMenuRenameRecording(cRecording *Recording); -+ virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuRenameRecording"; } -+#endif /* GRAPHTFT */ -+}; -+ -+cMenuRenameRecording::cMenuRenameRecording(cRecording *Recording) -+:cOsdMenu(tr("Rename recording"), 12) -+{ -+ cMarks marks; -+ -+ recording = Recording; -+ -+ char* p = strrchr(recording->Name(), '~'); -+ if (p) { -+ p++; -+ Utf8Strn0Cpy(name, p, sizeof(name)); -+ Utf8Strn0Cpy(path, recording->Name(), sizeof(path)); -+ p = strrchr(path, '~'); -+ if (p) -+ p[0] = 0; -+ } -+ else { -+ Utf8Strn0Cpy(name, recording->Name(), sizeof(name)); -+ Utf8Strn0Cpy(path, "", sizeof(path)); -+ } -+ Add(new cMenuEditStrItem(tr("Name"), name, sizeof(name), tr(FileNameChars))); -+ Add(new cMenuEditRecPathItem(tr("Path"), path, sizeof(path) )); -+ -+ Add(new cOsdItem("", osUnknown, false)); -+ -+ Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Date"), *DayDateTime(recording->start)), osUnknown, false)); -+ -+ cChannel *channel = Channels.GetByChannelID(((cRecordingInfo *)recording->Info())->ChannelID()); -+ if (channel) -+ Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Channel"), *ChannelString(channel, 0)), osUnknown, false)); -+ -+ cIndexFile *index = new cIndexFile(recording->FileName(), false); -+ int recLen = 0; -+ if (index) { -+ recLen = int(index->Last() / recording->FramesPerSecond()); -+ Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Length"), *IndexToHMSF(index->Last())), osUnknown, false)); -+ delete index; -+ } -+ -+ int dirSize = DirSizeMB(recording->FileName()); -+ cString bitRate = recLen ? cString::sprintf(" (%.2f MBit/s)", 8.0 * dirSize / recLen) : cString(""); -+ Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Format"), recording->IsPesRecording() ? tr("PES") : tr("TS")), osUnknown, false)); -+ Add(new cOsdItem((dirSize > 9999) ? cString::sprintf("%s:\t%.2f GB%s", tr("Size"), dirSize / 1024.0, *bitRate) : cString::sprintf("%s:\t%d MB%s", tr("Size"), dirSize, *bitRate), osUnknown, false)); -+ -+ Add(new cOsdItem("", osUnknown, false)); -+ -+ isMarks = marks.Load(recording->FileName()) && marks.Count(); -+ marksItem = new cOsdItem(tr("Delete marks information?"), osUser1, isMarks); -+ Add(marksItem); -+ -+ cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording()); -+ isResume = (ResumeFile.Read() != -1); -+ resumeItem = new cOsdItem(tr("Delete resume information?"), osUser2, isResume); -+ Add(resumeItem); -+} -+ -+eOSState cMenuRenameRecording::ProcessKey(eKeys Key) -+{ -+ eOSState state = cOsdMenu::ProcessKey(Key); -+ -+ if (state == osUnknown) { -+ if (Key == kOk) { -+ char buffer[MaxFileName]; -+ if (Utf8StrLen(path)) -+ snprintf(buffer, sizeof(buffer), "%s~%s", path, name); -+ else -+ snprintf(buffer, sizeof(buffer), "%s", name); -+ if (recording->Rename(buffer)) { -+ Recordings.ChangeState(); -+ Recordings.TouchUpdate(); -+ return osRecordings; -+ } -+ else -+ Skins.Message(mtError, tr("Error while accessing recording!")); -+ } -+ return osContinue; -+ } -+ else if (state == osUser1) { -+ if (isMarks && Interface->Confirm(tr("Delete marks information?"))) { -+ cMarks marks; -+ marks.Load(recording->FileName()); -+ cMark *mark = marks.First(); -+ while (mark) { -+ cMark *nextmark = marks.Next(mark); -+ marks.Del(mark); -+ mark = nextmark; -+ } -+ marks.Save(); -+ isMarks = false; -+ marksItem->SetSelectable(isMarks); -+ SetCurrent(First()); -+ Display(); -+ } -+ return osContinue; -+ } -+ else if (state == osUser2) { -+ if (isResume && Interface->Confirm(tr("Delete resume information?"))) { -+ cResumeFile ResumeFile(recording->FileName(), recording->IsPesRecording()); -+ ResumeFile.Delete(); -+ isResume = false; -+ resumeItem->SetSelectable(isResume); -+ SetCurrent(First()); -+ Display(); -+ } -+ return osContinue; -+ } -+ return state; - } -+#endif /* LIEMIEXT */ - - // --- cMenuRecordings ------------------------------------------------------- - - cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus) -+#ifdef USE_LIEMIEXT -+:cOsdMenu(Base ? Base : tr("Recordings"), 9, 7, 7) -+#else - :cOsdMenu(Base ? Base : tr("Recordings"), 9, 7) -+#endif /* LIEMIEXT */ - { - base = Base ? strdup(Base) : NULL; - level = Setup.RecordingDirs ? Level : -1; -@@ -1921,7 +2626,12 @@ void cMenuRecordings::Set(bool Refresh) - for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { - if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == '~')) { - cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level); -+#ifdef USE_PINPLUGIN -+ if ((*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) -+ && (!cStatus::MsgReplayProtected(GetRecording(Item), Item->Name(), base, Item->IsDirectory(), true))) { -+#else - if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) { -+#endif /* PINPLUGIN */ - Add(Item); - LastItem = Item; - free(LastItemText); -@@ -1971,13 +2681,43 @@ eOSState cMenuRecordings::Play(void) - { - cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); - if (ri) { -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgReplayProtected(GetRecording(ri), ri->Name(), base, ri->IsDirectory()) == true) -+ return osContinue; -+#endif /* PINPLUGIN */ - if (ri->IsDirectory()) - Open(); - else { - cRecording *recording = GetRecording(ri); - if (recording) { -+#ifdef USE_DVDARCHIVE -+ int mountRet = MOUNT_DVD_REPLAY; -+ if (recording->IsOnlyOnDvd()) { -+ mountRet = recording->MountDvd(); -+ } -+ if (mountRet == MOUNT_DVD_REPLAY) { -+ cReplayControl::SetRecording(recording->FileName(), recording->Title()); -+ return osReplay; -+ } -+ else if (mountRet == MOUNT_DVD_LAUNCH_DVD_PLUGIN) { -+ //launch DVD plugin here -+ cPlugin *p = cPluginManager::GetPlugin("dvd"); -+ cOsdObject *osd = NULL; -+ if (p) { -+ osd = p->MainMenuAction(); -+ delete osd; -+ osd = NULL; -+ return osEnd; -+ } -+ else { -+ Skins.Message(mtError, tr("DVD plugin is not installed!")); -+ Skins.Flush(); -+ } -+ } -+#else - cReplayControl::SetRecording(recording->FileName(), recording->Title()); - return osReplay; -+#endif /* DVDARCHIVE */ - } - } - } -@@ -2078,12 +2818,34 @@ eOSState cMenuRecordings::Commands(eKeys - return osContinue; - } - -+#ifdef USE_LIEMIEXT -+eOSState cMenuRecordings::Rename(void) -+{ -+ if (HasSubMenu() || Count() == 0) -+ return osContinue; -+ cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); -+ if (ri && !ri->IsDirectory()) { -+ cRecording *recording = GetRecording(ri); -+ if (recording) -+ return AddSubMenu(new cMenuRenameRecording(recording)); -+ } -+ return osContinue; -+} -+#endif /* LIEMIEXT */ -+ - eOSState cMenuRecordings::ProcessKey(eKeys Key) - { - bool HadSubMenu = HasSubMenu(); - eOSState state = cOsdMenu::ProcessKey(Key); - - if (state == osUnknown) { -+#ifdef USE_SORTRECORDS -+ const char *RecordingsSortModeTexts[MAXSORTMODES]; -+ RecordingsSortModeTexts[0] = tr("main dir alphabetically, subdirs flexible"); -+ RecordingsSortModeTexts[1] = tr("main dir by date, subdirs flexible"); -+ RecordingsSortModeTexts[2] = tr("all alphabetically"); -+ RecordingsSortModeTexts[3] = tr("all by date"); -+#endif /* SORTRECORDS */ - switch (Key) { - case kPlay: - case kOk: return Play(); -@@ -2092,7 +2854,26 @@ eOSState cMenuRecordings::ProcessKey(eKe - case kYellow: return Delete(); - case kInfo: - case kBlue: return Info(); -+#ifdef USE_SORTRECORDS -+ case k0: Setup.RecordingsSortMode = ++Setup.RecordingsSortMode % MAXSORTMODES; -+ Set(true); -+ Skins.Message(mtStatus, cString::sprintf("%s %d: %s", tr("Sorting"), Setup.RecordingsSortMode, RecordingsSortModeTexts[Setup.RecordingsSortMode])); -+ return osContinue; -+ case k1...k7: return Commands(Key); -+ case k8: return Rename(); -+ case k9: Recordings.ToggleSortOrder(); -+ Set(true); -+ return osContinue; -+#elif defined (USE_LIEMIEXT) -+ case k0: DirOrderState = !DirOrderState; -+ Set(true); -+ return osContinue; -+ case k8: return Rename(); -+ case k9: -+ case k1...k7: return Commands(Key); -+#else - case k1...k9: return Commands(Key); -+#endif /* LIEMIEXT & SORTRECORDS */ - case kNone: if (Recordings.StateChanged(recordingsState)) - Set(true); - break; -@@ -2141,6 +2922,9 @@ void cMenuSetupBase::Store(void) - class cMenuSetupOSD : public cMenuSetupBase { - private: - const char *useSmallFontTexts[3]; -+#ifdef USE_LIEMIEXT -+ const char *mainMenuTitle[MAXMAINMENUTITLE]; -+#endif /* LIEMIEXT */ - int osdLanguageIndex; - int numSkins; - int originalSkinIndex; -@@ -2156,6 +2940,9 @@ public: - cMenuSetupOSD(void); - virtual ~cMenuSetupOSD(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupOsd"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupOSD::cMenuSetupOSD(void) -@@ -2191,12 +2978,21 @@ void cMenuSetupOSD::Set(void) - useSmallFontTexts[0] = tr("never"); - useSmallFontTexts[1] = tr("skin dependent"); - useSmallFontTexts[2] = tr("always"); -+#ifdef USE_LIEMIEXT -+ mainMenuTitle[0]=tr("default"); -+ mainMenuTitle[1]=tr("VDR - text"); -+ mainMenuTitle[2]=tr("text"); -+ mainMenuTitle[3]=tr("VDR - version"); -+#endif /* LIEMIEXT */ - Clear(); - SetSection(tr("OSD")); - Add(new cMenuEditStraItem(tr("Setup.OSD$Language"), &osdLanguageIndex, I18nNumLanguagesWithLocale(), &I18nLanguages()->At(0))); - Add(new cMenuEditStraItem(tr("Setup.OSD$Skin"), &skinIndex, numSkins, skinDescriptions)); - if (themes.NumThemes()) - Add(new cMenuEditStraItem(tr("Setup.OSD$Theme"), &themeIndex, themes.NumThemes(), themes.Descriptions())); -+#ifdef USE_WAREAGLEICON -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$WarEagle icons"), &data.WarEagleIcons)); -+#endif /* WAREAGLEICON */ - Add(new cMenuEditIntItem( tr("Setup.OSD$Left"), &data.OSDLeft, 0, MAXOSDWIDTH)); - Add(new cMenuEditIntItem( tr("Setup.OSD$Top"), &data.OSDTop, 0, MAXOSDHEIGHT)); - Add(new cMenuEditIntItem( tr("Setup.OSD$Width"), &data.OSDWidth, MINOSDWIDTH, MAXOSDWIDTH)); -@@ -2218,6 +3014,24 @@ void cMenuSetupOSD::Set(void) - Add(new cMenuEditBoolItem(tr("Setup.OSD$Scroll wraps"), &data.MenuScrollWrap)); - Add(new cMenuEditBoolItem(tr("Setup.OSD$Menu key closes"), &data.MenuKeyCloses)); - Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs)); -+#ifdef USE_LIEMIEXT -+ Add(new cMenuEditStraItem(tr("Setup.OSD$Main menu title"), &data.MainMenuTitle, MAXMAINMENUTITLE, mainMenuTitle)); -+ if (data.MainMenuTitle == 1 || data.MainMenuTitle == 2) -+ Add(new cMenuEditStrItem(tr("Setup.OSD$- Text"), data.CustomMainMenuTitle, sizeof(data.CustomMainMenuTitle))); -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$Main menu command position"), &data.MenuCmdPosition, tr("bottom"), tr("top"))); -+#endif /* LIEMIEXT */ -+#ifdef USE_VALIDINPUT -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$Show valid input"), &data.ShowValidInput)); -+#endif /* VALIDINPUT */ -+#ifdef USE_SOFTOSD -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$Use SoftOSD"), &data.UseSoftOsd)); -+ if (data.UseSoftOsd) { -+ Add(new cMenuEditIntItem( tr("Setup.OSD$SoftOSD Rate"), &data.SoftOsdRate, 10, 100)); -+ Add(new cMenuEditIntItem( tr("Setup.OSD$SoftOSD FadeIn Steps"), &data.SoftOsdFadeinSteps, 1, 100)); -+ Add(new cMenuEditIntItem( tr("Setup.OSD$SoftOSD FadeOut Steps"), &data.SoftOsdFadeoutSteps, 1, 100)); -+ Add(new cMenuEditBoolItem(tr("Setup.OSD$SoftOSD Palette Only"), &data.SoftOsdPaletteOnly)); -+ } -+#endif /* SOFTOSD */ - SetCurrent(Get(current)); - Display(); - } -@@ -2266,6 +3080,12 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys - - int oldSkinIndex = skinIndex; - int oldOsdLanguageIndex = osdLanguageIndex; -+#ifdef USE_LIEMIEXT -+ int oldMainMenuTitle = data.MainMenuTitle; -+#endif /* LIEMIEXT */ -+#ifdef USE_SOFTOSD -+ bool newUseSoftOsd = data.UseSoftOsd; -+#endif /* SOFTOSD */ - eOSState state = cMenuSetupBase::ProcessKey(Key); - - if (ModifiedApperance) -@@ -2288,6 +3108,25 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys - Set(); - I18nSetLanguage(OriginalOSDLanguage); - } -+ -+#ifdef USE_LIEMIEXT -+ if (data.MainMenuTitle != oldMainMenuTitle) -+ Set(); -+#endif /* LIEMIEXT */ -+#ifdef USE_SOFTOSD -+ if (data.UseSoftOsd != newUseSoftOsd) -+ Set(); -+#endif /* SOFTOSD */ -+#ifdef USE_CMDRECCMDI18N -+ if (Key == kOk) { -+ // try to load translated command files if available, otherwise fallback to defaults -+ LoadCommandsI18n(Commands, AddDirectory(ConfigDirectory, "commands.conf"), true); -+ LoadCommandsI18n(RecordingCommands, AddDirectory(ConfigDirectory, "reccmds.conf"), true); -+#ifdef USE_TIMERCMD -+ LoadCommandsI18n(TimerCommands, AddDirectory(ConfigDirectory, "timercmds.conf"), true); -+#endif /* TIMERCMD */ -+ } -+#endif /* CMDRECCMDI18N */ - return state; - } - -@@ -2295,12 +3134,18 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys - - class cMenuSetupEPG : public cMenuSetupBase { - private: -+#ifdef USE_NOEPG -+ const char *noEPGModes[2]; -+#endif /* NOEPG */ - int originalNumLanguages; - int numLanguages; - void Setup(void); - public: - cMenuSetupEPG(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupEpg"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupEPG::cMenuSetupEPG(void) -@@ -2317,11 +3162,19 @@ void cMenuSetupEPG::Setup(void) - { - int current = Current(); - -+#ifdef USE_NOEPG -+ noEPGModes[0] = tr("blacklist"); -+ noEPGModes[1] = tr("whitelist"); -+#endif /* NOEPG */ -+ - Clear(); - - Add(new cMenuEditIntItem( tr("Setup.EPG$EPG scan timeout (h)"), &data.EPGScanTimeout)); - Add(new cMenuEditIntItem( tr("Setup.EPG$EPG bugfix level"), &data.EPGBugfixLevel, 0, MAXEPGBUGFIXLEVEL)); - Add(new cMenuEditIntItem( tr("Setup.EPG$EPG linger time (min)"), &data.EPGLinger, 0)); -+#ifdef USE_LIEMIEXT -+ Add(new cMenuEditBoolItem(tr("Setup.EPG$Show progress bar"), &data.ShowProgressBar)); -+#endif /* LIEMIEXT */ - Add(new cMenuEditBoolItem(tr("Setup.EPG$Set system time"), &data.SetSystemTime)); - if (data.SetSystemTime) - Add(new cMenuEditTranItem(tr("Setup.EPG$Use time from transponder"), &data.TimeTransponder, &data.TimeSource)); -@@ -2330,6 +3183,15 @@ void cMenuSetupEPG::Setup(void) - for (int i = 0; i < numLanguages; i++) - // TRANSLATORS: note the singular! - Add(new cMenuEditStraItem(tr("Setup.EPG$Preferred language"), &data.EPGLanguages[i], I18nLanguages()->Size(), &I18nLanguages()->At(0))); -+#ifdef USE_DDEPGENTRY -+ Add(new cMenuEditIntItem( tr("Setup.EPG$Period for double EPG search(min)"), &data.DoubleEpgTimeDelta)); -+ Add(new cMenuEditBoolItem(tr("Setup.EPG$Extern double Epg entry"), &data.DoubleEpgAction, tr("adjust"), tr("delete"))); -+ Add(new cMenuEditBoolItem(tr("Setup.EPG$Mix intern and extern EPG"), &data.MixEpgAction)); -+ Add(new cMenuEditBoolItem(tr("Setup.EPG$Disable running VPS event"), &data.DisableVPS)); -+#endif /* DDEPGENTRY */ -+#ifdef USE_NOEPG -+ Add(new cMenuEditStraItem(tr("Setup.EPG$Mode of noEPG-Patch"), &data.noEPGMode, 2, noEPGModes)); -+#endif /* NOEPG */ - - SetCurrent(Get(current)); - Display(); -@@ -2386,6 +3248,10 @@ eOSState cMenuSetupEPG::ProcessKey(eKeys - - class cMenuSetupDVB : public cMenuSetupBase { - private: -+#ifdef USE_DVBSETUP -+ const char *ChannelBlockers[7]; -+ const char *ChannelBlockerModes[4]; -+#endif /* DVBSETUP */ - int originalNumAudioLanguages; - int numAudioLanguages; - int originalNumSubtitleLanguages; -@@ -2396,6 +3262,9 @@ private: - public: - cMenuSetupDVB(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupDvb"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupDVB::cMenuSetupDVB(void) -@@ -2424,6 +3293,21 @@ void cMenuSetupDVB::Setup(void) - { - int current = Current(); - -+#ifdef USE_DVBSETUP -+ ChannelBlockers[0] = tr("none"); -+ ChannelBlockers[1] = tr("qam256"); -+ ChannelBlockers[2] = tr("dvb-c"); -+ ChannelBlockers[3] = tr("dvb-s"); -+ ChannelBlockers[4] = tr("blacklist"); -+ ChannelBlockers[5] = tr("whitelist"); -+ ChannelBlockers[6] = tr("all"); -+ -+ ChannelBlockerModes[0] = tr("none"); -+ ChannelBlockerModes[1] = tr("has decoder"); -+ ChannelBlockerModes[2] = tr("is primary"); -+ ChannelBlockerModes[3] = tr("has decoder + is primary"); -+#endif /* DVBSETUP */ -+ - Clear(); - - Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDevice::NumDevices())); -@@ -2444,6 +3328,11 @@ void cMenuSetupDVB::Setup(void) - Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9)); - Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10)); - } -+#ifdef USE_DVBSETUP -+ Add(new cMenuEditBoolItem(tr("Setup.DVB$Use AC3-Transfer Fix"), &data.DolbyTransferFix)); -+ Add(new cMenuEditStraItem(tr("Setup.DVB$Channel Blocker"), &data.ChannelBlocker, 7, ChannelBlockers)); -+ Add(new cMenuEditStraItem(tr("Setup.DVB$Channel Blocker Filter Mode"), &data.ChannelBlockerMode, 4, ChannelBlockerModes)); -+#endif /* DVBSETUP */ - - SetCurrent(Get(current)); - Display(); -@@ -2525,6 +3414,9 @@ private: - public: - cMenuSetupLNB(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupLnb"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupLNB::cMenuSetupLNB(void) -@@ -2539,6 +3431,23 @@ void cMenuSetupLNB::Setup(void) - - Clear(); - -+#ifdef USE_LNBSHARE -+ int numSatDevices = 0; -+ for (int i = 0; i < cDevice::NumDevices(); i++) { -+ if (cDevice::GetDevice(i)->ProvidesSource(cSource::stSat)) numSatDevices++; -+ } -+ if (numSatDevices > 1) { -+ char tmp[30]; -+ for (int i = 1; i <= cDevice::NumDevices(); i++) { -+ if (cDevice::GetDevice(i - 1)->ProvidesSource(cSource::stSat)) { -+ sprintf( tmp, tr("Setup.LNB$DVB device %d uses LNB No."), i); -+ Add(new cMenuEditIntItem( tmp, &data.CardUsesLNBnr[i - 1], 1, numSatDevices )); -+ } -+ } -+ } -+ Add(new cMenuEditBoolItem(tr("Setup.LNB$Log LNB usage"), &data.VerboseLNBlog)); -+#endif /* LNBSHARE */ -+ - Add(new cMenuEditBoolItem(tr("Setup.LNB$Use DiSEqC"), &data.DiSEqC)); - if (!data.DiSEqC) { - Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"), &data.LnbSLOF)); -@@ -2555,6 +3464,10 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys - int oldDiSEqC = data.DiSEqC; - eOSState state = cMenuSetupBase::ProcessKey(Key); - -+#ifdef USE_LNBSHARE -+ if (Key == kOk) cDevice::SetLNBnr(); -+#endif /* LNBSHARE */ -+ - if (Key != kNone && data.DiSEqC != oldDiSEqC) - Setup(); - return state; -@@ -2605,6 +3518,9 @@ private: - public: - cMenuSetupCAM(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupCam"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupCAM::cMenuSetupCAM(void) -@@ -2678,12 +3594,73 @@ eOSState cMenuSetupCAM::ProcessKey(eKeys - // --- cMenuSetupRecord ------------------------------------------------------ - - class cMenuSetupRecord : public cMenuSetupBase { -+#ifdef USE_SORTRECORDS -+private: -+ const char *RecordingsSortModeTexts[MAXSORTMODES]; -+#endif /* SORTRECORDS */ -+#ifdef USE_DELTIMESHIFTREC -+private: -+ const char *DelTimeshiftRecValues[3]; -+#endif /* DELTIMESHIFTREC */ - public: - cMenuSetupRecord(void); -+#ifdef USE_DVLVIDPREFER -+ eOSState ProcessKey(eKeys key); -+ -+private: -+ void Set(void); -+ -+ int tmpNVidPrefer, -+ tmpUseVidPrefer; -+#endif /* DVLVIDPREFER */ - }; - -+#ifdef USE_DVLVIDPREFER - cMenuSetupRecord::cMenuSetupRecord(void) - { -+ Set(); -+} -+ -+eOSState cMenuSetupRecord::ProcessKey(eKeys key) -+{ -+ eOSState s = cMenuSetupBase::ProcessKey(key);; -+ -+ if (key != kNone) { -+ if (tmpNVidPrefer != data.nVidPrefer || tmpUseVidPrefer != data.UseVidPrefer) { -+ int cur = Current(); -+ -+ tmpNVidPrefer = data.nVidPrefer; -+ tmpUseVidPrefer = data.UseVidPrefer; -+ -+ Clear(); -+ Set(); -+ SetCurrent(Get(cur)); -+ Display(); -+ cMenuSetupBase::ProcessKey(kNone); -+ return osContinue; -+ } -+ } -+ return s; -+} -+ -+#else -+cMenuSetupRecord::cMenuSetupRecord(void) -+#endif /* DVLVIDPREFER */ -+#ifdef USE_DVLVIDPREFER -+void cMenuSetupRecord::Set(void) -+#endif /* DVLVIDPREFER */ -+{ -+#ifdef USE_SORTRECORDS -+ RecordingsSortModeTexts[0] = tr("main dir alphabetically, subdirs flexible"); -+ RecordingsSortModeTexts[1] = tr("main dir by date, subdirs flexible"); -+ RecordingsSortModeTexts[2] = tr("all alphabetically"); -+ RecordingsSortModeTexts[3] = tr("all by date"); -+#endif /* SORTRECORDS */ -+#ifdef USE_DELTIMESHIFTREC -+ DelTimeshiftRecValues[0] = tr("request"); -+ DelTimeshiftRecValues[1] = tr("no"); -+ DelTimeshiftRecValues[2] = tr("yes"); -+#endif /* DELTIMESHIFTREC */ - SetSection(tr("Recording")); - Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at start (min)"), &data.MarginStart)); - Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at stop (min)"), &data.MarginStop)); -@@ -2692,14 +3669,61 @@ cMenuSetupRecord::cMenuSetupRecord(void) - Add(new cMenuEditIntItem( tr("Setup.Recording$Default lifetime (d)"), &data.DefaultLifetime, 0, MAXLIFETIME)); - Add(new cMenuEditIntItem( tr("Setup.Recording$Pause priority"), &data.PausePriority, 0, MAXPRIORITY)); - Add(new cMenuEditIntItem( tr("Setup.Recording$Pause lifetime (d)"), &data.PauseLifetime, 0, MAXLIFETIME)); -+#ifdef USE_DOLBYINREC -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Record Dolby Digital"), &data.UseDolbyInRecordings)); -+#endif /* DOLBYINREC */ -+#ifdef USE_DVLVIDPREFER -+ tmpNVidPrefer = data.nVidPrefer; -+ tmpUseVidPrefer = data.UseVidPrefer; -+ -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Video directory policy"), &data.UseVidPrefer)); -+ if (data.UseVidPrefer != 0) { -+ char tmp[ 64 ]; -+ Add(new cMenuEditIntItem(tr("Setup.Recording$Number of video directories"), &data.nVidPrefer, 1, DVLVIDPREFER_MAX)); -+ for (int zz = 0; zz < data.nVidPrefer; zz++) { -+ sprintf(tmp, tr("Setup.Recording$Video %d priority"), zz); -+ Add(new cMenuEditIntItem(tmp, &data.VidPreferPrio[ zz ], 0, 99)); -+ sprintf(tmp, tr("Setup.Recording$Video %d min. free MB"), zz); -+ Add(new cMenuEditIntItem(tmp, &data.VidPreferSize[ zz ], -1, 99999)); -+ } -+ } -+#endif /* DVLVIDPREFER */ - Add(new cMenuEditBoolItem(tr("Setup.Recording$Use episode name"), &data.UseSubtitle)); -+#ifdef USE_DVLFRIENDLYFNAMES -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Friendly filenames"), &data.UseFriendlyFNames)); -+#endif /* DVLFRIENDLYFNAMES */ - Add(new cMenuEditBoolItem(tr("Setup.Recording$Use VPS"), &data.UseVps)); - Add(new cMenuEditIntItem( tr("Setup.Recording$VPS margin (s)"), &data.VpsMargin, 0)); - Add(new cMenuEditBoolItem(tr("Setup.Recording$Mark instant recording"), &data.MarkInstantRecord)); - Add(new cMenuEditStrItem( tr("Setup.Recording$Name instant recording"), data.NameInstantRecord, sizeof(data.NameInstantRecord))); - Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 1, MAXINSTANTRECTIME)); - Add(new cMenuEditIntItem( tr("Setup.Recording$Max. video file size (MB)"), &data.MaxVideoFileSize, MINVIDEOFILESIZE, MAXVIDEOFILESIZETS)); -+#ifdef USE_HARDLINKCUTTER -+ Add(new cMenuEditIntItem( tr("Setup.Recording$Max. recording size (GB)"), &data.MaxRecordingSize, MINRECORDINGSIZE, MAXRECORDINGSIZE)); -+#endif /* HARDLINKCUTTER */ - Add(new cMenuEditBoolItem(tr("Setup.Recording$Split edited files"), &data.SplitEditedFiles)); -+#ifdef USE_HARDLINKCUTTER -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Hard Link Cutter"), &data.HardLinkCutter)); -+#endif /* HARDLINKCUTTER */ -+#ifdef USE_DELTIMESHIFTREC -+ Add(new cMenuEditStraItem(tr("Setup.Recording$Delete timeshift recording"), &data.DelTimeshiftRec, 3, DelTimeshiftRecValues)); -+#endif /* DELTIMESHIFTREC */ -+#ifdef USE_LIEMIEXT -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Show date"), &data.ShowRecDate)); -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Show time"), &data.ShowRecTime)); -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Show length"), &data.ShowRecLength)); -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Show end of timer"), &data.ShowTimerStop)); -+#endif /* LIEMIEXT */ -+#ifdef USE_SORTRECORDS -+ Add(new cMenuEditStraItem(tr("Setup.Recording$Sort recordings by"), &data.RecordingsSortMode, MAXSORTMODES, RecordingsSortModeTexts)); -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Sort directories before recordings"), &data.RecordingsSortDirsFirst)); -+#endif /* SORTRECORDS */ -+#ifdef USE_CUTTERQUEUE -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Cutter auto delete"), &data.CutterAutoDelete)); -+#endif /* CUTTERQUEUE */ -+#ifdef USE_CUTTIME -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Cutter adjust starttime"), &data.CutTime)); -+#endif /* CUTTIME */ - } - - // --- cMenuSetupReplay ------------------------------------------------------ -@@ -2717,6 +3741,31 @@ cMenuSetupReplay::cMenuSetupReplay(void) - Add(new cMenuEditBoolItem(tr("Setup.Replay$Multi speed mode"), &data.MultiSpeedMode)); - Add(new cMenuEditBoolItem(tr("Setup.Replay$Show replay mode"), &data.ShowReplayMode)); - Add(new cMenuEditIntItem(tr("Setup.Replay$Resume ID"), &data.ResumeID, 0, 99)); -+#ifdef USE_JUMPPLAY -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$Jump&Play"), &data.JumpPlay)); -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$Play&Jump"), &data.PlayJump)); -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$Pause at last mark"), &data.PauseLastMark)); -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$Reload marks"), &data.ReloadMarks)); -+#endif /* JUMPPLAY */ -+#ifdef USE_LIEMIEXT -+ Add(new cMenuEditIntItem(tr("Setup.Replay$Skip Seconds"), &data.JumpSeconds)); -+ Add(new cMenuEditIntItem(tr("Setup.Replay$Skip Seconds Slow"), &data.JumpSecondsSlow)); -+#endif /* LIEMIEXT */ -+#ifdef USE_DVDARCHIVE -+ static const char *dvddisplaymode[3]; -+ dvddisplaymode[0]=tr("Setup.Replay$Length"); -+ dvddisplaymode[1]=tr("Setup.Replay$Length / Number"); -+ dvddisplaymode[2]=tr("Setup.Replay$Number"); -+ Add(new cMenuEditStraItem(tr("Setup.Replay$DVD display mode"), &data.DvdDisplayMode,3,dvddisplaymode)); -+ Add(new cMenuEditBoolItem(tr("Setup.Replay$DVD display leading zeros"), &data.DvdDisplayZeros)); -+ static const char *dvdtraymode[4]; -+ dvdtraymode[0]=tr("Setup.Replay$never"); -+ dvdtraymode[1]=tr("Setup.Replay$on begin"); -+ dvdtraymode[2]=tr("Setup.Replay$on end"); -+ dvdtraymode[3]=tr("Setup.Replay$on begin and end"); -+ Add(new cMenuEditStraItem(tr("Setup.Replay$Tray open"), &data.DvdTrayMode,4,dvdtraymode)); -+ Add(new cMenuEditIntItem( tr("Setup.Replay$Limit DVD to speed"), &data.DvdSpeedLimit, 0, 50)); -+#endif /* DVDARCHIVE */ - } - - void cMenuSetupReplay::Store(void) -@@ -2729,13 +3778,48 @@ void cMenuSetupReplay::Store(void) - // --- cMenuSetupMisc -------------------------------------------------------- - - class cMenuSetupMisc : public cMenuSetupBase { -+#ifdef USE_VOLCTRL -+private: -+ const char *lrChannelGroupsTexts[3]; -+ const char *lrForwardRewindTexts[3]; -+ void Setup(void); -+#endif /* VOLCTRL */ - public: - cMenuSetupMisc(void); -+#ifdef USE_VOLCTRL -+ virtual eOSState ProcessKey(eKeys Key); -+#endif /* VOLCTRL */ - }; - - cMenuSetupMisc::cMenuSetupMisc(void) - { -+#ifdef USE_VOLCTRL -+ lrChannelGroupsTexts[0] = tr("no"); -+ lrChannelGroupsTexts[1] = tr("Setup.Miscellaneous$only in channelinfo"); -+ lrChannelGroupsTexts[2] = tr("yes"); -+ lrForwardRewindTexts[0] = tr("no"); -+ lrForwardRewindTexts[1] = tr("Setup.Miscellaneous$only in progress display"); -+ lrForwardRewindTexts[2] = tr("yes"); -+#endif /* VOLCTRL */ - SetSection(tr("Miscellaneous")); -+#ifdef USE_VOLCTRL -+ Setup(); -+} -+ -+eOSState cMenuSetupMisc::ProcessKey(eKeys Key) -+{ -+ int newLRVolumeControl = data.LRVolumeControl; -+ eOSState state = cMenuSetupBase::ProcessKey(Key); -+ if (Key != kNone && data.LRVolumeControl != newLRVolumeControl) -+ Setup(); -+ return state; -+} -+ -+void cMenuSetupMisc::Setup(void) -+{ -+ int current = Current(); -+ Clear(); -+#endif /* VOLCTRL */ - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. event timeout (min)"), &data.MinEventTimeout)); - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. user inactivity (min)"), &data.MinUserInactivity)); - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"), &data.SVDRPTimeout)); -@@ -2743,7 +3827,21 @@ cMenuSetupMisc::cMenuSetupMisc(void) - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Channel entry timeout (ms)"), &data.ChannelEntryTimeout, 0)); - Add(new cMenuEditChanItem(tr("Setup.Miscellaneous$Initial channel"), &data.InitialChannel, tr("Setup.Miscellaneous$as before"))); - Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Initial volume"), &data.InitialVolume, -1, 255, tr("Setup.Miscellaneous$as before"))); -+#ifdef USE_VOLCTRL -+ Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Volume ctrl with left/right"), &data.LRVolumeControl)); -+ if (data.LRVolumeControl) { -+ Add(new cMenuEditStraItem(tr("Setup.Miscellaneous$Channelgroups with left/right"), &data.LRChannelGroups, 3, lrChannelGroupsTexts)); -+ Add(new cMenuEditStraItem(tr("Setup.Miscellaneous$Search fwd/back with left/right"), &data.LRForwardRewind, 3, lrForwardRewindTexts)); -+ } -+ SetCurrent(Get(current)); -+ Display(); -+#endif /* VOLCTRL */ - Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Emergency exit"), &data.EmergencyExit)); -+#ifdef USE_LIRCSETTINGS -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat delay"), &data.LircRepeatDelay, 0, 1000)); -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat freq"), &data.LircRepeatFreq, 0, 1000)); -+ Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Lirc repeat timeout"), &data.LircRepeatTimeout, 0, 5000)); -+#endif /* LIRCSETTINGS */ - } - - // --- cMenuSetupPluginItem -------------------------------------------------- -@@ -2768,6 +3866,9 @@ class cMenuSetupPlugins : public cMenuSe - public: - cMenuSetupPlugins(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupPlugins"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupPlugins::cMenuSetupPlugins(void) -@@ -2817,6 +3918,9 @@ private: - public: - cMenuSetup(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetup"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetup::cMenuSetup(void) -@@ -2906,24 +4010,91 @@ cOsdObject *cMenuMain::pluginOsdObject = - cMenuMain::cMenuMain(eOSState State) - :cOsdMenu("") - { -+#ifdef USE_SETUP -+ // Load Menu Configuration -+ char *menuXML = NULL; -+ asprintf(&menuXML, "%s/setup/vdr-menu.%s.xml", cPlugin::ConfigDirectory(), Setup.OSDLanguage); -+ if (access(menuXML, 04) == -1) -+ asprintf(&menuXML, "%s/setup/vdr-menu.xml", cPlugin::ConfigDirectory()); -+ subMenu.LoadXml(menuXML); -+ free(menuXML); -+ nrDynamicMenuEntries=0; -+#endif /* SETUP */ - replaying = false; - stopReplayItem = NULL; - cancelEditingItem = NULL; - stopRecordingItem = NULL; - recordControlsState = 0; -+ -+#ifdef USE_MENUORG -+ MenuOrgPatch::EnterRootMenu(); -+#endif /* MENUORG */ -+ - Set(); - - // Initial submenus: - -+#ifdef USE_MAINMENUHOOKS -+ cOsdMenu *menu = NULL; -+#endif /* MAINMENUHOOKS */ - switch (State) { -+#ifdef USE_MAINMENUHOOKS -+ case osSchedule: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osSchedule", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osSchedule: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuSchedule; -+ } -+ break; -+ case osChannels: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osChannels", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osChannels: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuChannels; -+ } -+ break; -+ case osTimers: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osTimers", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osTimers: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuTimers; -+ } -+ break; -+ case osRecordings: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osRecordings", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osRecordings: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuRecordings(NULL, 0, true); -+ } -+ break; -+ case osSetup: menu = new cMenuSetup; break; -+ case osCommands: menu = new cMenuCommands(tr("Commands"), &Commands); break; -+#else - case osSchedule: AddSubMenu(new cMenuSchedule); break; - case osChannels: AddSubMenu(new cMenuChannels); break; - case osTimers: AddSubMenu(new cMenuTimers); break; - case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break; - case osSetup: AddSubMenu(new cMenuSetup); break; - case osCommands: AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); break; -+#endif /* MAINMENUHOOKS */ - default: break; - } -+#ifdef USE_MAINMENUHOOKS -+ if (menu) -+ AddSubMenu(menu); -+#endif /* MAINMENUHOOKS */ - } - - cOsdObject *cMenuMain::PluginOsdObject(void) -@@ -2933,38 +4104,155 @@ cOsdObject *cMenuMain::PluginOsdObject(v - return o; - } - -+#ifdef USE_SETUP -+void cMenuMain::Set(int current) -+#else - void cMenuMain::Set(void) -+#endif /* SETUP */ - { - Clear(); - SetTitle("VDR"); - SetHasHotkeys(); - -+#ifdef USE_MENUORG -+ if (MenuOrgPatch::IsCustomMenuAvailable()) { -+ MenuItemDefinitions* menuItems = MenuOrgPatch::MainMenuItems(); -+ for (MenuItemDefinitions::iterator i = menuItems->begin(); i != menuItems->end(); i++) { -+ cOsdItem* osdItem = NULL; -+ if ((*i)->IsCustomOsdItem()) { -+ osdItem = (*i)->CustomOsdItem(); -+ if (osdItem && !(*i)->IsSeparatorItem()) -+ osdItem->SetText(hk(osdItem->Text())); -+ } -+ else if ((*i)->IsPluginItem()) { -+ const char *item = (*i)->PluginMenuEntry(); -+ if (item) -+ osdItem = new cMenuPluginItem(hk(item), (*i)->PluginIndex()); -+ } -+ if (osdItem) { -+ Add(osdItem); -+ if ((*i)->IsSelected()) -+ SetCurrent(osdItem); -+ } -+ } -+ } -+ else { -+#endif /* MENUORG */ -+ -+#ifdef USE_SETUP -+ stopReplayItem = NULL; -+ cancelEditingItem = NULL; -+ stopRecordingItem = NULL; -+ -+ // remember initial dynamic MenuEntries added -+ nrDynamicMenuEntries = Count(); -+ for (cSubMenuNode *node = subMenu.GetMenuTree()->First(); node; node = subMenu.GetMenuTree()->Next(node)) { -+ cSubMenuNode::Type type = node->GetType(); -+ if (type==cSubMenuNode::PLUGIN) { -+ const char *item = node->GetPluginMainMenuEntry(); -+#ifdef USE_PINPLUGIN -+ if (item && !cStatus::MsgPluginProtected(cPluginManager::GetPlugin(node->GetPluginIndex()), true)) -+#else -+ if (item) -+#endif /* PINPLUGIN */ -+ Add(new cMenuPluginItem(hk(item), node->GetPluginIndex())); -+ } -+ else if (type==cSubMenuNode::MENU) { -+ cString item = cString::sprintf("%s%s", node->GetName(), subMenu.GetMenuSuffix()); -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected(item, true)) -+ Add(new cOsdItem(hk(item), osUnknown, node)); -+#else -+ Add(new cOsdItem(hk(item))); -+#endif /* PINPLUGIN */ -+ } -+ else if ((type==cSubMenuNode::COMMAND) || (type==cSubMenuNode::THREAD)) { -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected(node->GetName(), true)) -+ Add(new cOsdItem(hk(node->GetName()), osUnknown, node)); -+#else -+ Add(new cOsdItem(hk(node->GetName()))); -+#endif /* PINPLUGIN */ -+ } -+ else if (type==cSubMenuNode::SYSTEM) { -+ const char *item = node->GetName(); -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgMenuItemProtected(item, true)) -+ ; // nothing to do ;) -+ else -+#endif /* PINPLUGIN */ -+ if (strcmp(item, "Schedule") == 0) -+ Add(new cOsdItem(hk(tr("Schedule")), osSchedule)); -+ else if (strcmp(item, "Channels") == 0) -+ Add(new cOsdItem(hk(tr("Channels")), osChannels)); -+ else if (strcmp(item, "Timers") == 0) -+ Add(new cOsdItem(hk(tr("Timers")), osTimers)); -+ else if (strcmp(item, "Recordings") == 0) -+ Add(new cOsdItem(hk(tr("Recordings")), osRecordings)); -+ else if (strcmp(item, "Setup") == 0) -+ Add(new cOsdItem(hk(tr("Setup")), osSetup)); -+ else if (strcmp(item, "Commands") == 0 && Commands.Count()>0) -+ Add(new cOsdItem(hk(tr("Commands")), osCommands)); -+ } -+ } -+ if (current >=0 && current<Count()) { -+ SetCurrent(Get(current)); -+ } -+ -+#else /* NO SETUP */ -+ - // Basic menu items: - -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected("Schedule", true)) Add(new cOsdItem(hk(tr("Schedule")), osSchedule)); -+ if (!cStatus::MsgMenuItemProtected("Channels", true)) Add(new cOsdItem(hk(tr("Channels")), osChannels)); -+ if (!cStatus::MsgMenuItemProtected("Timers", true)) Add(new cOsdItem(hk(tr("Timers")), osTimers)); -+ if (!cStatus::MsgMenuItemProtected("Recordings", true)) Add(new cOsdItem(hk(tr("Recordings")), osRecordings)); -+#else - Add(new cOsdItem(hk(tr("Schedule")), osSchedule)); - Add(new cOsdItem(hk(tr("Channels")), osChannels)); - Add(new cOsdItem(hk(tr("Timers")), osTimers)); - Add(new cOsdItem(hk(tr("Recordings")), osRecordings)); -+#endif /* PINPLUGIN */ - - // Plugins: - - for (int i = 0; ; i++) { - cPlugin *p = cPluginManager::GetPlugin(i); - if (p) { -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgPluginProtected(p, true)) { -+#endif /* PINPLUGIN */ - const char *item = p->MainMenuEntry(); - if (item) - Add(new cMenuPluginItem(hk(item), i)); - } -+#ifdef USE_PINPLUGIN -+ } -+#endif /* PINPLUGIN */ - else - break; - } - - // More basic menu items: - -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected("Setup", true)) Add(new cOsdItem(hk(tr("Setup")), osSetup)); -+#else - Add(new cOsdItem(hk(tr("Setup")), osSetup)); -+#endif /* PINPLUGIN */ - if (Commands.Count()) -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgMenuItemProtected("Commands", true)) -+#endif /* PINPLUGIN */ - Add(new cOsdItem(hk(tr("Commands")), osCommands)); - -+#endif /* SETUP */ -+ -+#ifdef USE_MENUORG -+ } -+#endif /* MENUORG */ -+ - Update(true); - - Display(); -@@ -2973,13 +4261,40 @@ void cMenuMain::Set(void) - bool cMenuMain::Update(bool Force) - { - bool result = false; -- -+#ifdef USE_SETUP -+ cOsdItem *fMenu = NULL; -+ if (Force && subMenu.isTopMenu()) { -+ fMenu = First(); -+ nrDynamicMenuEntries = 0; -+ } -+ -+ if (subMenu.isTopMenu()) { -+#endif /* SETUP */ -+#ifdef USE_LIEMIEXT -+// this extension is not included in the original Liemikuutio -+ if (Setup.MainMenuTitle) { -+ if (Setup.MainMenuTitle == 1) -+ SetTitle(cString::sprintf("%s - %s", tr("VDR"), Setup.CustomMainMenuTitle)); -+ else if (Setup.MainMenuTitle == 2) -+ SetTitle(cString::sprintf("%s", Setup.CustomMainMenuTitle)); -+ else if (Setup.MainMenuTitle == 3) -+ SetTitle(cString::sprintf("%s %s", tr("VDR"), VDRVERSION)); -+ } -+ else -+#endif /* LIEMIEXT */ - // Title with disk usage: - if (FreeDiskSpace.HasChanged(Force)) { - //XXX -> skin function!!! - SetTitle(cString::sprintf("%s - %s", tr("VDR"), FreeDiskSpace.FreeDiskSpaceString())); - result = true; - } -+#ifdef USE_SETUP -+ } -+ else { -+ SetTitle(cString::sprintf("%s - %s", tr("VDR"), subMenu.GetParentMenuTitel())); -+ result = true; -+ } -+#endif /* SETUP */ - - bool NewReplaying = cControl::Control() != NULL; - if (Force || NewReplaying != replaying) { -@@ -2987,6 +4302,9 @@ bool cMenuMain::Update(bool Force) - // Replay control: - if (replaying && !stopReplayItem) - // TRANSLATORS: note the leading blank! -+#ifdef USE_LIEMIEXT -+ if (Setup.MenuCmdPosition) Ins(stopReplayItem = new cOsdItem(tr(" Stop replaying"), osStopReplay)); else -+#endif /* LIEMIEXT */ - Add(stopReplayItem = new cOsdItem(tr(" Stop replaying"), osStopReplay)); - else if (stopReplayItem && !replaying) { - Del(stopReplayItem->Index()); -@@ -3001,6 +4319,9 @@ bool cMenuMain::Update(bool Force) - bool CutterActive = cCutter::Active(); - if (CutterActive && !cancelEditingItem) { - // TRANSLATORS: note the leading blank! -+#ifdef USE_LIEMIEXT -+ if (Setup.MenuCmdPosition) Ins(cancelEditingItem = new cOsdItem(tr(" Cancel editing"), osCancelEdit)); else -+#endif /* LIEMIEXT */ - Add(cancelEditingItem = new cOsdItem(tr(" Cancel editing"), osCancelEdit)); - result = true; - } -@@ -3021,6 +4342,9 @@ bool cMenuMain::Update(bool Force) - while ((s = cRecordControls::GetInstantId(s)) != NULL) { - cOsdItem *item = new cOsdItem(osStopRecord); - item->SetText(cString::sprintf("%s%s", tr(STOP_RECORDING), s)); -+#ifdef USE_LIEMIEXT -+ if (Setup.MenuCmdPosition) Ins(item); else -+#endif /* LIEMIEXT */ - Add(item); - if (!stopRecordingItem) - stopRecordingItem = item; -@@ -3028,6 +4352,12 @@ bool cMenuMain::Update(bool Force) - result = true; - } - -+#ifdef USE_SETUP -+ // adjust nrDynamicMenuEntries -+ if (fMenu != NULL) -+ nrDynamicMenuEntries = fMenu->Index(); -+#endif /* SETUP */ -+ - return result; - } - -@@ -3038,13 +4368,69 @@ eOSState cMenuMain::ProcessKey(eKeys Key - eOSState state = cOsdMenu::ProcessKey(Key); - HadSubMenu |= HasSubMenu(); - -+#ifdef USE_PINPLUGIN -+ cOsdItem* item = Get(Current()); -+ -+ if (item && item->Text() && state != osBack && state != osContinue && Key != kNone) -+ if (cStatus::MsgMenuItemProtected(item->Text())) -+ return osContinue; -+#endif /* PINPLUGIN */ -+ -+#ifdef USE_MAINMENUHOOKS -+ cOsdMenu *menu = NULL; -+#endif /* MAINMENUHOOKS */ - switch (state) { -+#ifdef USE_MAINMENUHOOKS -+ case osSchedule: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osSchedule", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osSchedule: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuSchedule; -+ } -+ break; -+ case osChannels: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osChannels", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osChannels: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuChannels; -+ } -+ break; -+ case osTimers: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osTimers", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osTimers: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuTimers; -+ } -+ break; -+ case osRecordings: -+ { -+ cPlugin *p = cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osRecordings", &menu); -+ if (p && !menu) -+ isyslog("MainMenuHook::osRecordings: plugin %s claims to support service but didn't return menu", p->Name()); -+ -+ if (!menu) -+ menu = new cMenuRecordings; -+ } -+ break; -+ case osSetup: menu = new cMenuSetup; break; -+ case osCommands: menu = new cMenuCommands(tr("Commands"), &Commands); break; -+#else - case osSchedule: return AddSubMenu(new cMenuSchedule); - case osChannels: return AddSubMenu(new cMenuChannels); - case osTimers: return AddSubMenu(new cMenuTimers); - case osRecordings: return AddSubMenu(new cMenuRecordings); - case osSetup: return AddSubMenu(new cMenuSetup); - case osCommands: return AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); -+#endif /* MAINMENUHOOKS */ - case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) { - cOsdItem *item = Get(Current()); - if (item) { -@@ -3063,6 +4449,9 @@ eOSState cMenuMain::ProcessKey(eKeys Key - if (item) { - cPlugin *p = cPluginManager::GetPlugin(item->PluginIndex()); - if (p) { -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgPluginProtected(p)) { -+#endif /* PINPLUGIN */ - cOsdObject *menu = p->MainMenuAction(); - if (menu) { - if (menu->IsMenu()) -@@ -3074,9 +4463,60 @@ eOSState cMenuMain::ProcessKey(eKeys Key - } - } - } -+#ifdef USE_PINPLUGIN -+ } -+#endif /* PINPLUGIN */ - state = osEnd; - } - break; -+#ifdef USE_SETUP -+ case osBack: { -+ int newCurrent = 0; -+ if (subMenu.Up(&newCurrent)) { -+ Set(newCurrent); -+ return osContinue; -+ } -+ else -+ return osEnd; -+ } -+ break; -+#endif /* SETUP */ -+#ifdef USE_MENUORG -+ case osBack: { -+ if (MenuOrgPatch::IsCustomMenuAvailable()) { -+ bool leavingMenuSucceeded = MenuOrgPatch::LeaveSubMenu(); -+ Set(); -+ stopReplayItem = NULL; -+ cancelEditingItem = NULL; -+ stopRecordingItem = NULL; -+ recordControlsState = 0; -+ Update(true); -+ Display(); -+ if (leavingMenuSucceeded) -+ return osContinue; -+ else -+ return osEnd; -+ } -+ } -+ break; -+ case osUser1: { -+ if (MenuOrgPatch::IsCustomMenuAvailable()) { -+ MenuOrgPatch::EnterSubMenu(Get(Current())); -+ Set(); -+ return osContinue; -+ } -+ } -+ break; -+ case osUser2: { -+ if (MenuOrgPatch::IsCustomMenuAvailable()) { -+ cOsdMenu* osdMenu = MenuOrgPatch::Execute(Get(Current())); -+ if (osdMenu) -+ return AddSubMenu(osdMenu); -+ return osEnd; -+ } -+ } -+ break; -+#endif /* MENUORG */ - default: switch (Key) { - case kRecord: - case kRed: if (!HadSubMenu) -@@ -3093,9 +4533,67 @@ eOSState cMenuMain::ProcessKey(eKeys Key - case kBlue: if (!HadSubMenu) - state = replaying ? osStopReplay : cReplayControl::LastReplayed() ? osReplay : osContinue; - break; -+#ifdef USE_SETUP -+ case kOk: if (state == osUnknown) { -+ cString buffer; -+#ifdef USE_PINPLUGIN -+ cSubMenuNode *node = Get(Current())->SubMenu(); -+#else -+ int index = Current()-nrDynamicMenuEntries; -+ cSubMenuNode *node = subMenu.GetNode(index); -+#endif /* PINPLUGIN */ -+ -+ if (node != NULL) { -+ if (node->GetType() == cSubMenuNode::MENU) { -+#ifdef USE_PINPLUGIN -+ subMenu.Down(node, Current()); -+#else -+ subMenu.Down(index); -+#endif /* PINPLUGIN */ -+ } -+ else if (node->GetType() == cSubMenuNode::COMMAND) { -+ bool confirmed = true; -+ if (node->CommandConfirm()) { -+ buffer = cString::sprintf("%s?", node->GetName()); -+ confirmed = Interface->Confirm(buffer); -+ } -+ if (confirmed) { -+ const char *Result = subMenu.ExecuteCommand(node->GetCommand()); -+ if (Result) -+ return AddSubMenu(new cMenuText(node->GetName(), Result, fontFix)); -+ return osEnd; -+ } -+ } -+ else if (node->GetType() == cSubMenuNode::THREAD) { -+ bool confirmed = true; -+ if (node->CommandConfirm()) { -+ buffer = cString::sprintf("%s?", node->GetName()); -+ confirmed = Interface->Confirm(buffer); -+ } -+ if (confirmed) { -+ buffer = cString::sprintf("%s", node->GetCommand()); -+ cExecCmdThread *execcmd = new cExecCmdThread(node->GetCommand()); -+ if (execcmd->Start()) -+ dsyslog("executing command '%s'", *buffer); -+ else -+ esyslog("ERROR: can't execute command '%s'", *buffer); -+ return osEnd; -+ } -+ } -+ } -+ -+ Set(); -+ return osContinue; -+ } -+ break; -+#endif /* SETUP */ - default: break; - } - } -+#ifdef USE_MAINMENUHOOKS -+ if (menu) -+ return AddSubMenu(menu); -+#endif /* MAINMENUHOOKS */ - if (!HasSubMenu() && Update(HadSubMenu)) - Display(); - if (Key != kNone) { -@@ -3241,7 +4739,14 @@ cChannel *cDisplayChannel::NextAvailable - if (Direction) { - while (Channel) { - Channel = Direction > 0 ? Channels.Next(Channel) : Channels.Prev(Channel); -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgChannelProtected(0, Channel) == false) -+#endif /* PINPLUGIN */ -+#ifdef USE_LNBSHARE -+ if (Channel && !Channel->GroupSep() && cDevice::GetDevice(Channel, 0, true) && cDevice::PrimaryDevice()->GetMaxBadPriority(Channel) < 0) -+#else - if (Channel && !Channel->GroupSep() && cDevice::GetDevice(Channel, 0, true)) -+#endif /* LNBSHARE */ - return Channel; - } - } -@@ -3299,6 +4804,13 @@ eOSState cDisplayChannel::ProcessKey(eKe - case kLeft: - case kRight|k_Repeat: - case kRight: -+#ifdef USE_VOLCTRL -+ if (Setup.LRVolumeControl && !Setup.LRChannelGroups) { -+ cRemote::Put(NORMALKEY(Key) == kLeft ? kVolDn : kVolUp, true); -+ break; -+ } -+ // else fall through -+#endif /* VOLCTRL */ - case kNext|k_Repeat: - case kNext: - case kPrev|k_Repeat: -@@ -3458,6 +4970,17 @@ void cDisplayVolume::Process(eKeys Key) - eOSState cDisplayVolume::ProcessKey(eKeys Key) - { - switch (Key) { -+#ifdef USE_VOLCTRL -+ case kLeft|k_Repeat: -+ case kLeft: -+ case kRight|k_Repeat: -+ case kRight: -+ if (Setup.LRVolumeControl) { -+ cRemote::Put(NORMALKEY(Key) == kLeft ? kVolDn : kVolUp, true); -+ break; -+ } -+ // else fall through -+#endif /* VOLCTRL */ - case kVolUp|k_Repeat: - case kVolUp: - case kVolDn|k_Repeat: -@@ -3707,6 +5230,10 @@ eOSState cDisplaySubtitleTracks::Process - - cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) - { -+#ifdef USE_DVLRECSCRIPTADDON -+ const cChannel *recChan = NULL; -+ char *chanName = NULL; -+#endif /* DVLRECSCRIPTADDON */ - // We're going to manipulate an event here, so we need to prevent - // others from modifying any EPG data: - cSchedulesLock SchedulesLock; -@@ -3751,6 +5278,16 @@ cRecordControl::cRecordControl(cDevice * - return; - } - -+#ifdef USE_DVLRECSCRIPTADDON -+ if (timer) -+ if ((recChan = timer->Channel()) != NULL) -+ chanName = strdup(recChan->Name()); -+ if (chanName != NULL) { -+ cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName, chanName); -+ free(chanName); -+ } -+ else -+#endif /* DVLRECSCRIPTADDON */ - cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName); - isyslog("record %s", fileName); - if (MakeDirs(fileName, true)) { -@@ -3813,11 +5350,25 @@ bool cRecordControl::GetEvent(void) - void cRecordControl::Stop(void) - { - if (timer) { -+#ifdef USE_DVLRECSCRIPTADDON -+ char *chanName = NULL; -+ const cChannel *recChan = NULL; -+ -+ recChan = timer -> Channel(); -+ if (recChan != NULL) -+ chanName = strdup(recChan -> Name()); -+#endif /* DVLRECSCRIPTADDON */ - DELETENULL(recorder); - timer->SetRecording(false); - timer = NULL; - cStatus::MsgRecording(device, NULL, fileName, false); -+#ifdef USE_DVLRECSCRIPTADDON -+ cRecordingUserCommand::InvokeCommand(RUC_AFTERRECORDING, fileName, chanName); -+ if (chanName != NULL) -+ free(chanName); -+#else - cRecordingUserCommand::InvokeCommand(RUC_AFTERRECORDING, fileName); -+#endif /* DVLRECSCRIPTADDON */ - } - } - -@@ -3864,6 +5415,19 @@ bool cRecordControls::Start(cTimer *Time - int Priority = Timer ? Timer->Priority() : Pause ? Setup.PausePriority : Setup.DefaultPriority; - cDevice *device = cDevice::GetDevice(channel, Priority, false); - if (device) { -+#ifdef USE_LNBSHARE -+ cDevice *tmpDevice; -+ while ((tmpDevice = device->GetBadDevice(channel))) { -+ if (tmpDevice->Replaying() == false) { -+// Stop(tmpDevice); -+ if (tmpDevice->IsPrimaryDevice() ) -+ tmpDevice->SwitchChannelForced(channel, true); -+ else -+ tmpDevice->SwitchChannelForced(channel, false); -+ } else -+ tmpDevice->SwitchChannelForced(channel, false); -+ } -+#endif /* LNBSHARE */ - dsyslog("switching device %d to channel %d", device->DeviceNumber() + 1, channel->Number()); - if (!device->SwitchChannel(channel, false)) { - ShutdownHandler.RequestEmergencyExit(); -@@ -3873,6 +5437,9 @@ bool cRecordControls::Start(cTimer *Time - for (int i = 0; i < MAXRECORDCONTROLS; i++) { - if (!RecordControls[i]) { - RecordControls[i] = new cRecordControl(device, Timer, Pause); -+#ifdef USE_PINPLUGIN -+ cStatus::MsgRecordingFile(RecordControls[i]->FileName()); -+#endif /* PINPLUGIN */ - return RecordControls[i]->Process(time(NULL)); - } - } -@@ -4003,12 +5570,22 @@ bool cRecordControls::StateChanged(int & - - // --- cReplayControl -------------------------------------------------------- - -+#ifdef USE_LIEMIEXT -+#define REPLAYCONTROLSKIPLIMIT 9 // s -+#define REPLAYCONTROLSKIPSECONDS 90 // s -+#define REPLAYCONTROLSKIPTIMEOUT 5000 // ms -+#endif /* LIEMIEXT */ -+ - cReplayControl *cReplayControl::currentReplayControl = NULL; - char *cReplayControl::fileName = NULL; - char *cReplayControl::title = NULL; - - cReplayControl::cReplayControl(void) -+#ifdef USE_JUMPPLAY -+:cDvbPlayerControl(fileName), marks(fileName) -+#else - :cDvbPlayerControl(fileName) -+#endif /* JUMPPLAY */ - { - currentReplayControl = this; - displayReplay = NULL; -@@ -4016,23 +5593,96 @@ cReplayControl::cReplayControl(void) - lastCurrent = lastTotal = -1; - lastPlay = lastForward = false; - lastSpeed = -2; // an invalid value -+#ifdef USE_LIEMIEXT -+ lastSkipKey = kNone; -+ lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; -+ lastSkipTimeout.Set(0); -+#endif /* LIEMIEXT */ - timeoutShow = 0; - timeSearchActive = false; - cRecording Recording(fileName); -+#ifdef USE_DVDARCHIVE -+ canJumpChapters = (Recording.GetDvdType() == DVD_VIDEO_ARCHIVE_TYPE); -+ dvdchapters = NULL; -+ if (canJumpChapters) { -+ const char *ret = Recording.GetDvdChapters(); -+ if (ret) -+ dvdchapters = strdup(ret); -+ else -+ canJumpChapters=false; -+ } -+#endif /* DVDARCHIVE */ - cStatus::MsgReplaying(this, Recording.Name(), Recording.FileName(), true); -+#ifndef USE_JUMPPLAY - marks.Load(fileName, Recording.FramesPerSecond(), Recording.IsPesRecording()); -+#endif /* JUMPPLAY */ - SetTrackDescriptions(false); - } - - cReplayControl::~cReplayControl() - { - Hide(); -+#ifdef USE_DVDARCHIVE -+ free(dvdchapters); -+#endif /* DVDARCHIVE */ - cStatus::MsgReplaying(this, NULL, fileName, false); - Stop(); - if (currentReplayControl == this) - currentReplayControl = NULL; - } - -+#ifdef USE_DELTIMESHIFTREC -+void cReplayControl::Stop(void) -+{ -+ int dummy; -+ bool playing = GetIndex(dummy, dummy, false); -+ cRecordControl* rc = cRecordControls::GetRecordControl(fileName); -+ -+ if (playing && rc && rc->InstantId()) { -+ isyslog("found Timeshiftrecording"); -+ -+ if ((Setup.DelTimeshiftRec != 0 ) || (Interface->Confirm(tr("Delete recording?")))) { -+ cRecordControl *rc = cRecordControls::GetRecordControl(fileName); -+ if (rc) { -+ cTimer *timer = rc->Timer(); -+ if (timer) { -+ const char* reccmd_backup = cRecordingUserCommand::GetCommand(); -+ cRecordingUserCommand::SetCommand(NULL); -+ -+ timer->Skip(); -+ cRecordControls::Process(time(NULL)); -+ if (timer->IsSingleEvent()) { -+ isyslog("deleting timer %s", *timer->ToDescr()); -+ Timers.Del(timer); -+ } -+ Timers.SetModified(); -+ -+ // restore reccmd -+ cRecordingUserCommand::SetCommand(reccmd_backup); -+ } -+ } -+ isyslog("stop replaying %s", fileName); -+ cDvbPlayerControl::Stop(); -+ -+ if (Setup.DelTimeshiftRec != 1) { -+ cRecording *recording = Recordings.GetByName(fileName);; -+ if (recording) { -+ if (recording->Delete()) { -+ Recordings.DelByName(fileName); -+ ClearLastReplayed(fileName); -+ return; -+ } -+ else -+ Skins.Message(mtError, tr("Error while deleting recording!")); -+ } -+ } -+ } -+ else -+ cDvbPlayerControl::Stop(); -+ } -+} -+#endif /* DELTIMESHIFTREC */ -+ - void cReplayControl::SetRecording(const char *FileName, const char *Title) - { - free(fileName); -@@ -4127,6 +5777,9 @@ bool cReplayControl::ShowProgress(bool I - if (Initial) { - if (title) - displayReplay->SetTitle(title); -+#ifdef USE_OSDMAXITEMS -+ displayReplay->SetButtons(tr("Jump"), tr("Skip +60s"), tr("Skip -60s"), tr("Button$Stop")); -+#endif /* OSDMAXITEMS */ - lastCurrent = lastTotal = -1; - } - if (Total != lastTotal) { -@@ -4248,8 +5901,15 @@ void cReplayControl::MarkToggle(void) - ShowTimed(2); - bool Play, Forward; - int Speed; -+#ifdef USE_JUMPPLAY -+ if (GetReplayMode(Play, Forward, Speed) && !Play) { -+ Goto(Current, true); -+ displayFrames = true; -+ } -+#else - if (GetReplayMode(Play, Forward, Speed) && !Play) - Goto(Current, true); -+#endif /* JUMPPLAY */ - } - marks.Save(); - } -@@ -4262,8 +5922,22 @@ void cReplayControl::MarkJump(bool Forwa - if (GetIndex(Current, Total)) { - cMark *m = Forward ? marks.GetNext(Current) : marks.GetPrev(Current); - if (m) { -+#ifdef USE_JUMPPLAY -+ bool Play2, Forward2; -+ int Speed; -+ if (Setup.JumpPlay && GetReplayMode(Play2, Forward2, Speed) && -+ Play2 && Forward && m->position < Total - SecondsToFrames(3)) { -+ Goto(m->position); -+ Play(); -+ } -+ else { -+ Goto(m->position, true); -+ displayFrames = true; -+ } -+#else - Goto(m->position, true); - displayFrames = true; -+#endif /* JUMPPLAY */ - } - } - } -@@ -4292,11 +5966,43 @@ void cReplayControl::MarkMove(bool Forwa - } - } - -+#ifdef USE_DVDARCHIVE -+void cReplayControl::ChaptersJump(bool Forward) -+{ -+ int Current, Total; -+ if (GetIndex(Current, Total)) { -+ int position = -1; -+ char *buf, *pos; -+ cString old1("-1"); -+ cString old2("-1"); -+ buf = strdup(dvdchapters); -+ pos = strtok(buf, ","); -+ while (pos != NULL && position == -1) { -+ if (pos && atoi(pos) > Current) -+ position = Forward ? atoi(pos) : ((Current - atoi(old1)) <= (3 * FramesPerSecond())) ? atoi(old2) : atoi(old1); -+ old2 = old1; -+ old1 = strdup(pos); -+ if(position == -1) pos = strtok(NULL, ","); -+ } -+ if (!pos && !Forward) -+ position = ((Current - atoi(old1)) <= (3 * FramesPerSecond())) ? atoi(old2) : atoi(old1); -+ if (position >= 0) { -+ Goto(position); -+ Play(); -+ } -+ } -+} -+ -+#endif /* DVDARCHIVE */ - void cReplayControl::EditCut(void) - { - if (fileName) { - Hide(); -+#ifdef USE_CUTTERQUEUE -+ if (!cCutter::Active() || Interface->Confirm(tr("Cutter already running - Add to cutting queue?"))) { -+#else - if (!cCutter::Active()) { -+#endif /* CUTTERQUEUE */ - if (!marks.Count()) - Skins.Message(mtError, tr("No editing marks defined!")); - else if (!cCutter::Start(fileName)) -@@ -4318,7 +6024,11 @@ void cReplayControl::EditTest(void) - if (!m) - m = marks.GetNext(Current); - if (m) { -+#ifdef USE_JUMPPLAY -+ if ((m->Index() & 0x01) != 0 && !Setup.PlayJump) -+#else - if ((m->Index() & 0x01) != 0) -+#endif /* JUMPPLAY */ - m = marks.Next(m); - if (m) { - Goto(m->position - SecondsToFrames(3, FramesPerSecond())); -@@ -4340,6 +6050,9 @@ eOSState cReplayControl::ProcessKey(eKey - { - if (!Active()) - return osEnd; -+#ifdef USE_JUMPPLAY -+ marks.Reload(); -+#endif /* JUMPPLAY */ - if (visible) { - if (timeoutShow && time(NULL) > timeoutShow) { - Hide(); -@@ -4357,7 +6070,32 @@ eOSState cReplayControl::ProcessKey(eKey - TimeSearchProcess(Key); - return osContinue; - } -+#ifdef USE_DVDARCHIVE -+ bool isOnMark = false; -+ if (canJumpChapters) { -+ int Current, Total; -+ GetIndex(Current, Total); -+ cMark *m = marks.Get(Current); -+ if (m && (m->position == Current)) isOnMark = true; -+ } -+#endif /* DVDARCHIVE */ - bool DoShowMode = true; -+#ifdef USE_VOLCTRL -+ if (Setup.LRVolumeControl && (!Setup.LRForwardRewind || (Setup.LRForwardRewind == 1 && !visible))) { -+ switch (Key) { -+ // Left/Right volume control -+ case kLeft|k_Repeat: -+ case kLeft: -+ case kRight|k_Repeat: -+ case kRight: -+ cRemote::Put(NORMALKEY(Key) == kLeft ? kVolDn : kVolUp, true); -+ return osContinue; -+ break; -+ default: -+ break; -+ } -+ } -+#endif /* VOLCTRL */ - switch (Key) { - // Positioning: - case kPlay: -@@ -4375,25 +6113,82 @@ eOSState cReplayControl::ProcessKey(eKey - case kFastFwd: - case kRight: Forward(); break; - case kRed: TimeSearch(); break; -+#ifdef USE_LIEMIEXT -+ case kGreen|k_Repeat: -+ case kGreen: SkipSeconds(-Setup.JumpSeconds); break; -+ case kYellow|k_Repeat: -+ case kYellow: SkipSeconds( Setup.JumpSeconds); break; -+ case k1|k_Repeat: -+ case k1: SkipSeconds(-Setup.JumpSecondsSlow); break; -+ case k3|k_Repeat: -+ case k3: SkipSeconds( Setup.JumpSecondsSlow); break; -+ case kPrev|k_Repeat: -+ case kPrev: if (lastSkipTimeout.TimedOut()) { -+ lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; -+ lastSkipKey = kPrev; -+ } -+ else if (RAWKEY(lastSkipKey) != kPrev && lastSkipSeconds > (2 * REPLAYCONTROLSKIPLIMIT)) { -+ lastSkipSeconds /= 2; -+ lastSkipKey = kNone; -+ } -+ lastSkipTimeout.Set(REPLAYCONTROLSKIPTIMEOUT); -+ SkipSeconds(-lastSkipSeconds); break; -+ case kNext|k_Repeat: -+ case kNext: if (lastSkipTimeout.TimedOut()) { -+ lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; -+ lastSkipKey = kNext; -+ } -+ else if (RAWKEY(lastSkipKey) != kNext && lastSkipSeconds > (2 * REPLAYCONTROLSKIPLIMIT)) { -+ lastSkipSeconds /= 2; -+ lastSkipKey = kNone; -+ } -+ lastSkipTimeout.Set(REPLAYCONTROLSKIPTIMEOUT); -+ SkipSeconds(lastSkipSeconds); break; -+#else - case kGreen|k_Repeat: - case kGreen: SkipSeconds(-60); break; - case kYellow|k_Repeat: - case kYellow: SkipSeconds( 60); break; -+#endif /* LIEMIEXT */ - case kStop: - case kBlue: Hide(); - Stop(); - return osEnd; -+#ifdef USE_DVDARCHIVE -+ case kDvdChapterJumpForward|k_Repeat: -+ case kDvdChapterJumpForward: if (canJumpChapters && !isOnMark) { -+ ChaptersJump(true); -+ } -+ else { -+ DoShowMode = false; -+ MarkMove(true); -+ } -+ break; -+ case kDvdChapterJumpBack|k_Repeat: -+ case kDvdChapterJumpBack: if (canJumpChapters && !isOnMark) { -+ ChaptersJump(false); -+ } -+ else { -+ DoShowMode = false; -+ MarkMove(false); -+ } -+ break; -+#endif /* DVDARCHIVE */ - default: { - DoShowMode = false; - switch (Key) { - // Editing: - case kMarkToggle: MarkToggle(); break; -+#ifndef USE_LIEMIEXT - case kPrev|k_Repeat: - case kPrev: -+#endif /* LIEMIEXT */ - case kMarkJumpBack|k_Repeat: - case kMarkJumpBack: MarkJump(false); break; -+#ifndef USE_LIEMIEXT - case kNext|k_Repeat: - case kNext: -+#endif /* LIEMIEXT */ - case kMarkJumpForward|k_Repeat: - case kMarkJumpForward: MarkJump(true); break; - case kMarkMoveBack|k_Repeat: -@@ -4413,7 +6208,16 @@ eOSState cReplayControl::ProcessKey(eKey - else - Show(); - break; -+#ifdef USE_DELTIMESHIFTREC -+ case kBack: { cRecordControl* rc = cRecordControls::GetRecordControl(fileName); -+ if (rc && rc->InstantId()) -+ return osEnd; -+ else -+ return osRecordings; -+ } -+#else - case kBack: return osRecordings; -+#endif /* DELTIMESHIFTREC */ - default: return osUnknown; - } - } -diff -ruNp vdr-1.7.5/menu.h vdr-1.7.5-extensions/menu.h ---- vdr-1.7.5/menu.h 2008-02-10 17:01:53.000000000 +0100 -+++ vdr-1.7.5-extensions/menu.h 2009-04-12 13:37:59.000000000 +0200 -@@ -18,6 +18,9 @@ - #include "menuitems.h" - #include "recorder.h" - #include "skins.h" -+#ifdef USE_SETUP -+#include "submenu.h" -+#endif /* SETUP */ - - class cMenuText : public cOsdMenu { - private: -@@ -29,12 +32,19 @@ public: - void SetText(const char *Text); - virtual void Display(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuText"; } -+#endif /* GRAPHTFT */ - }; - - class cMenuEditTimer : public cOsdMenu { - private: - cTimer *timer; - cTimer data; -+#ifdef USE_LIEMIEXT -+ char name[MaxFileName]; -+ char path[MaxFileName]; -+#endif /* LIEMIEXT */ - int channel; - bool addIfConfirmed; - cMenuEditDateItem *firstday; -@@ -43,6 +53,9 @@ public: - cMenuEditTimer(cTimer *Timer, bool New = false); - virtual ~cMenuEditTimer(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuTimerEdit"; } -+#endif /* GRAPHTFT */ - }; - - class cMenuEvent : public cOsdMenu { -@@ -52,22 +65,37 @@ public: - cMenuEvent(const cEvent *Event, bool CanSwitch = false, bool Buttons = false); - virtual void Display(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuEvent"; } -+#endif /* GRAPHTFT */ - }; - - class cMenuMain : public cOsdMenu { - private: -+#ifdef USE_SETUP -+ int nrDynamicMenuEntries; -+#endif /* SETUP */ - bool replaying; - cOsdItem *stopReplayItem; - cOsdItem *cancelEditingItem; - cOsdItem *stopRecordingItem; - int recordControlsState; - static cOsdObject *pluginOsdObject; -+#ifdef USE_SETUP -+ void Set(int current=0); -+ bool Update(bool Force = false); -+ cSubMenu subMenu; -+#else - void Set(void); - bool Update(bool Force = false); -+#endif /* SETUP */ - public: - cMenuMain(eOSState State = osUnknown); - virtual eOSState ProcessKey(eKeys Key); - static cOsdObject *PluginOsdObject(void); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuMain"; } -+#endif /* GRAPHTFT */ - }; - - class cDisplayChannel : public cOsdObject { -@@ -163,12 +191,18 @@ private: - eOSState Delete(void); - eOSState Info(void); - eOSState Commands(eKeys Key = kNone); -+#ifdef USE_LIEMIEXT -+ eOSState Rename(void); -+#endif /* LIEMIEXT */ - protected: - cRecording *GetRecording(cMenuRecordingItem *Item); - public: - cMenuRecordings(const char *Base = NULL, int Level = 0, bool OpenSubMenus = false); - ~cMenuRecordings(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuRecordings"; } -+#endif /* GRAPHTFT */ - }; - - class cRecordControl { -@@ -212,11 +246,21 @@ public: - class cReplayControl : public cDvbPlayerControl { - private: - cSkinDisplayReplay *displayReplay; -+#ifdef USE_JUMPPLAY -+ cMarksReload marks; -+#else - cMarks marks; -+#endif /* JUMPPLAY */ - bool visible, modeOnly, shown, displayFrames; - int lastCurrent, lastTotal; - bool lastPlay, lastForward; - int lastSpeed; -+#ifdef USE_LIEMIEXT -+ int lastSkipSeconds; -+ int lastSkipSecondsSlow; -+ eKeys lastSkipKey; -+ cTimeMs lastSkipTimeout; -+#endif /* LIEMIEXT */ - time_t timeoutShow; - bool timeSearchActive, timeSearchHide; - int timeSearchTime, timeSearchPos; -@@ -234,9 +278,17 @@ private: - void MarkMove(bool Forward); - void EditCut(void); - void EditTest(void); -+#ifdef USE_DVDARCHIVE -+ void ChaptersJump(bool Forward); -+ bool canJumpChapters; -+ char *dvdchapters; -+#endif /* DVDARCHIVE */ - public: - cReplayControl(void); - virtual ~cReplayControl(); -+#ifdef USE_DELTIMESHIFTREC -+ void Stop(void); -+#endif /* DELTIMESHIFTREC */ - virtual cOsdObject *GetInfo(void); - virtual eOSState ProcessKey(eKeys Key); - virtual void Show(void); -diff -ruNp vdr-1.7.5/menuitems.c vdr-1.7.5-extensions/menuitems.c ---- vdr-1.7.5/menuitems.c 2009-04-05 12:15:12.000000000 +0200 -+++ vdr-1.7.5-extensions/menuitems.c 2009-04-12 13:37:59.000000000 +0200 -@@ -32,9 +32,20 @@ cMenuEditItem::~cMenuEditItem() - free(name); - } - -+#ifdef USE_VALIDINPUT -+void cMenuEditItem::SetValue(const char *Value, bool HasPre, bool HasSucc) -+#else - void cMenuEditItem::SetValue(const char *Value) -+#endif /* VALIDINPUT */ - { - cString buffer = cString::sprintf("%s:\t%s", name, Value); -+#ifdef USE_VALIDINPUT -+ if (Setup.ShowValidInput) { -+ if (HasPre && HasSucc) buffer = cString::sprintf("%s:\t<%s>", name, Value); -+ else if (HasPre) buffer = cString::sprintf("%s:\t<%s", name, Value); -+ else if (HasSucc) buffer = cString::sprintf("%s:\t%s>", name, Value); -+ } -+#endif /* VALIDINPUT */ - SetText(buffer); - cStatus::MsgOsdCurrentItem(buffer); - } -@@ -126,7 +137,11 @@ void cMenuEditBoolItem::Set(void) - { - char buf[16]; - snprintf(buf, sizeof(buf), "%s", *value ? trueString : falseString); -+#ifdef USE_VALIDINPUT -+ SetValue(buf, *value, !*value); -+#else - SetValue(buf); -+#endif /* VALIDINPUT */ - } - - // --- cMenuEditBitItem ------------------------------------------------------ -@@ -619,6 +634,171 @@ eOSState cMenuEditStrItem::ProcessKey(eK - return osContinue; - } - -+#ifdef USE_LIEMIEXT -+// --- cMenuEditRecPathItem -------------------------------------------------- -+ -+cMenuEditRecPathItem::cMenuEditRecPathItem(const char* Name, char* Path, -+ int Length): cMenuEditStrItem(Name, Path, Length, tr(FileNameChars)) -+{ -+ SetBase(Path); -+} -+ -+cMenuEditRecPathItem::~cMenuEditRecPathItem() -+{ -+} -+ -+void cMenuEditRecPathItem::SetBase(const char* Path) -+{ -+ if (!Path) -+ base[0] = 0; -+ Utf8Strn0Cpy(base, Path, sizeof(base)); -+ char* p = strrchr(base, '~'); -+ if (p) -+ p[0] = 0; -+ else -+ base[0] = 0; -+} -+ -+void cMenuEditRecPathItem::FindNextLevel() -+{ -+ char item[MaxFileName]; -+ -+ for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) -+ { -+ char* p; -+ Utf8Strn0Cpy(item, recording->Name(), sizeof(item)); -+ stripspace(value); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ if (!lengthUtf8) -+ p = strchr(item, '~'); -+ else { -+ if (strstr(item, value) != item) -+ continue; -+ if (item[strlen(value)] != '~') -+ continue; -+ p = strchr(item + strlen(value) + 1, '~'); -+ } -+ if (!p) -+ continue; -+ p[0] = 0; -+ Utf8Strn0Cpy(base, value, length); -+ Utf8Strn0Cpy(value, item, length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ return; -+ } -+} -+ -+void cMenuEditRecPathItem::Find(bool Next) -+{ -+ char item[MaxFileName]; -+ char lastItem[MaxFileName] = ""; -+ -+ for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) -+ { -+ const char* recName = recording->Name(); -+ if (Utf8StrLen(base) && strstr(recName, base) != recName) -+ continue; -+ if (strlen(base) && recName[strlen(base)] != '~') -+ continue; -+ Utf8Strn0Cpy(item, recName, sizeof(item)); -+ char* p = strchr(item + strlen(base) + 1, '~'); -+ if (!p) -+ continue; -+ p[0] = 0; -+ if (!Next && (strcmp(item, value) == 0)) { -+ if (strlen(lastItem)) -+ Utf8Strn0Cpy(value, lastItem, length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ return; -+ } -+ if (strcmp(lastItem, item) != 0) { -+ if(Next && Utf8StrLen(lastItem) && strcmp(lastItem, value) == 0) { -+ Utf8Strn0Cpy(value, item, length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ return; -+ } -+ Utf8Strn0Cpy(lastItem, item, sizeof(lastItem)); -+ } -+ } -+} -+ -+void cMenuEditRecPathItem::SetHelpKeys(void) -+{ -+ cSkinDisplay::Current()->SetButtons(tr("Rename$Up"), tr("Rename$Down"), tr("Rename$Previous"), tr("Rename$Next")); -+} -+ -+eOSState cMenuEditRecPathItem::ProcessKey(eKeys Key) -+{ -+ switch (Key) { -+ case kLeft: -+ case kRed: // one level up -+ if (!InEditMode()) -+ return cMenuEditItem::ProcessKey(Key); -+ Utf8Strn0Cpy(value, base, lengthUtf8); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ SetBase(base); -+ pos = Utf8StrLen(base); -+ if (pos) -+ pos++; -+ if (!lengthUtf8) { -+ Utf8Strn0Cpy(value, " ", length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ } -+ break; -+ case kRight: -+ case kGreen: // one level down -+ if (InEditMode()) -+ FindNextLevel(); -+ else -+ EnterEditMode(); -+ -+ if (!lengthUtf8) { -+ Utf8Strn0Cpy(value, " ", length); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ } -+ pos = Utf8StrLen(base); -+ if (pos) -+ pos++; -+ SetHelpKeys(); -+ break; -+ case kUp|k_Repeat: -+ case kUp: -+ case kYellow|k_Repeat: -+ case kYellow: // previous directory in list -+ if (!InEditMode()) -+ return cMenuEditItem::ProcessKey(Key); -+ Find(false); -+ pos = Utf8StrLen(base); -+ if (pos) -+ pos++; -+ break; -+ case kDown|k_Repeat: -+ case kDown: -+ case kBlue|k_Repeat: -+ case kBlue: // next directory in list -+ if (!InEditMode()) -+ return cMenuEditItem::ProcessKey(Key); -+ Find(true); -+ pos = Utf8StrLen(base); -+ if (pos) -+ pos++; -+ break; -+ case kOk: // done -+ if (!InEditMode()) -+ return cMenuEditItem::ProcessKey(Key); -+ stripspace(value); -+ lengthUtf8 = Utf8ToArray(value, valueUtf8, length); -+ cSkinDisplay::Current()->SetButtons(NULL); -+ LeaveEditMode(Key == kOk); -+ break; -+ default: -+ return cMenuEditItem::ProcessKey(Key); -+ } -+ Set(); -+ return osContinue; -+} -+#endif /* LIEMIEXT */ -+ - // --- cMenuEditStraItem ----------------------------------------------------- - - cMenuEditStraItem::cMenuEditStraItem(const char *Name, int *Value, int NumStrings, const char * const *Strings) -@@ -630,7 +810,11 @@ cMenuEditStraItem::cMenuEditStraItem(con - - void cMenuEditStraItem::Set(void) - { -+#ifdef USE_VALIDINPUT -+ SetValue(strings[*value], (*value > min), (*value < max)); -+#else - SetValue(strings[*value]); -+#endif /* VALIDINPUT */ - } - - // --- cMenuEditChanItem ----------------------------------------------------- -diff -ruNp vdr-1.7.5/menuitems.h vdr-1.7.5-extensions/menuitems.h ---- vdr-1.7.5/menuitems.h 2008-04-12 14:03:59.000000000 +0200 -+++ vdr-1.7.5-extensions/menuitems.h 2009-04-12 13:37:59.000000000 +0200 -@@ -21,7 +21,11 @@ private: - public: - cMenuEditItem(const char *Name); - ~cMenuEditItem(); -+#ifdef USE_VALIDINPUT -+ void SetValue(const char *Value, bool HasPre=false, bool HasSucc=false); -+#else - void SetValue(const char *Value); -+#endif /* VALIDINPUT */ - }; - - class cMenuEditIntItem : public cMenuEditItem { -@@ -78,26 +82,46 @@ public: - - class cMenuEditStrItem : public cMenuEditItem { - private: -+#ifdef USE_LIEMIEXT -+ int offset; -+#else - char *value; - int length; - const char *allowed; - int pos, offset; -+#endif /* LIEMIEXT */ - bool insert, newchar, uppercase; -+#ifndef USE_LIEMIEXT - int lengthUtf8; - uint *valueUtf8; -+#endif /* LIEMIEXT */ - uint *allowedUtf8; - uint *charMapUtf8; - uint *currentCharUtf8; - eKeys lastKey; - cTimeMs autoAdvanceTimeout; -+#ifndef USE_LIEMIEXT - void SetHelpKeys(void); -+#endif /* LIEMIEXT */ - uint *IsAllowed(uint c); - void AdvancePos(void); -+#ifndef USE_LIEMIEXT - virtual void Set(void); -+#endif /* LIEMIEXT */ - uint Inc(uint c, bool Up); - void Insert(void); - void Delete(void); - protected: -+#ifdef USE_LIEMIEXT -+ char *value; -+ int length; -+ uint *valueUtf8; -+ int lengthUtf8; -+ const char *allowed; -+ int pos; -+ void SetHelpKeys(void); -+ virtual void Set(void); -+#endif /* LIEMIEXT */ - void EnterEditMode(void); - void LeaveEditMode(bool SaveValue = false); - bool InEditMode(void) { return valueUtf8 != NULL; } -@@ -107,6 +131,21 @@ public: - virtual eOSState ProcessKey(eKeys Key); - }; - -+#ifdef USE_LIEMIEXT -+class cMenuEditRecPathItem : public cMenuEditStrItem { -+protected: -+ char base[MaxFileName]; -+ virtual void SetHelpKeys(void); -+ void SetBase(const char* Path); -+ void FindNextLevel(); -+ void Find(bool Next); -+public: -+ cMenuEditRecPathItem(const char* Name, char* Path, int Length); -+ ~cMenuEditRecPathItem(); -+ virtual eOSState ProcessKey(eKeys Key); -+ }; -+#endif /* LIEMIEXT */ -+ - class cMenuEditStraItem : public cMenuEditIntItem { - private: - const char * const *strings; -@@ -185,6 +224,9 @@ public: - cMenuSetupPage(void); - virtual eOSState ProcessKey(eKeys Key); - void SetPlugin(cPlugin *Plugin); -+#ifdef USE_GRAPHTFT -+ const char* MenuKind() { return "MenuSetupPage"; } -+#endif /* GRAPHTFT */ - }; - - #endif //__MENUITEMS_H -diff -ruNp vdr-1.7.5/menuorgpatch.h vdr-1.7.5-extensions/menuorgpatch.h ---- vdr-1.7.5/menuorgpatch.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/menuorgpatch.h 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,102 @@ -+#ifdef USE_MENUORG -+/* -+ * vdr-menuorg - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2007 - 2008 Tobias Grimm <vdr@e-tobi.net> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ * $Id$ -+ * -+ */ -+ -+#ifndef __MENUORGPATCH_H -+#define __MENUORGPATCH_H -+ -+#include "mainmenuitemsprovider.h" -+ -+class MenuOrgPatch -+{ -+ private: -+ static IMainMenuItemsProvider* _mainMenuItemsProvider; -+ -+ private: -+ static IMainMenuItemsProvider* MainMenuItemsProvider() -+ { -+ if (!_mainMenuItemsProvider) -+ { -+ IMainMenuItemsProvider* mainMenuItemsProvider; -+ -+ if (cPluginManager::CallFirstService(MENU_ITEMS_PROVIDER_SERVICE_ID, &mainMenuItemsProvider)) -+ { -+ _mainMenuItemsProvider = mainMenuItemsProvider; -+ } -+ } -+ return _mainMenuItemsProvider; -+ } -+ -+ public: -+ static bool IsCustomMenuAvailable() -+ { -+ return (MainMenuItemsProvider() != NULL) && (MainMenuItemsProvider()->IsCustomMenuAvailable()); -+ } -+ -+ static void EnterRootMenu() -+ { -+ if (MainMenuItemsProvider()) -+ { -+ MainMenuItemsProvider()->EnterRootMenu(); -+ } -+ } -+ -+ static bool LeaveSubMenu() -+ { -+ if (MainMenuItemsProvider()) -+ { -+ return MainMenuItemsProvider()->LeaveSubMenu(); -+ } -+ return false; -+ } -+ -+ static void EnterSubMenu(cOsdItem* item) -+ { -+ if (MainMenuItemsProvider()) -+ { -+ MainMenuItemsProvider()->EnterSubMenu(item); -+ } -+ } -+ -+ static MenuItemDefinitions* MainMenuItems() -+ { -+ if (MainMenuItemsProvider()) -+ { -+ return MainMenuItemsProvider()->MainMenuItems(); -+ } -+ return NULL; -+ } -+ -+ static cOsdMenu* Execute(cOsdItem* item) -+ { -+ if (MainMenuItemsProvider()) -+ { -+ return MainMenuItemsProvider()->Execute(item); -+ } -+ return NULL; -+ } -+}; -+ -+IMainMenuItemsProvider* MenuOrgPatch::_mainMenuItemsProvider = NULL; -+ -+#endif //__MENUORGPATCH_H -+#endif /* MENUORG */ -diff -ruNp vdr-1.7.5/osdbase.c vdr-1.7.5-extensions/osdbase.c ---- vdr-1.7.5/osdbase.c 2008-02-17 12:33:04.000000000 +0100 -+++ vdr-1.7.5-extensions/osdbase.c 2009-04-12 13:37:59.000000000 +0200 -@@ -22,6 +22,9 @@ cOsdItem::cOsdItem(eOSState State) - state = State; - selectable = true; - fresh = true; -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ subMenu = 0; -+#endif /* SETUP & PINPLUGIN */ - } - - cOsdItem::cOsdItem(const char *Text, eOSState State, bool Selectable) -@@ -31,8 +34,23 @@ cOsdItem::cOsdItem(const char *Text, eOS - selectable = Selectable; - fresh = true; - SetText(Text); -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ subMenu = 0; -+#endif /* SETUP & PINPLUGIN */ - } - -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+cOsdItem::cOsdItem(const char *Text, eOSState State, cSubMenuNode* SubMenu) -+{ -+ text = NULL; -+ state = State; -+ selectable = true; -+ fresh = true; -+ SetText(Text); -+ subMenu = SubMenu; -+} -+#endif /* SETUP & PINPLUGIN */ -+ - cOsdItem::~cOsdItem() - { - free(text); -@@ -77,6 +95,9 @@ cOsdMenu::cOsdMenu(const char *Title, in - { - isMenu = true; - digit = 0; -+#ifdef USE_LIEMIEXT -+ key_nr = -1; -+#endif /* LIEMIEXT */ - hasHotkeys = false; - title = NULL; - SetTitle(Title); -@@ -97,6 +118,9 @@ cOsdMenu::~cOsdMenu() - free(status); - displayMenu->Clear(); - cStatus::MsgOsdClear(); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdMenuDestroy(); -+#endif /* GRAPHTFT */ - if (!--displayMenuCount) - DELETENULL(displayMenu); - } -@@ -119,7 +143,11 @@ const char *cOsdMenu::hk(const char *s) - digit = -1; // prevents automatic hotkeys - input already has them - if (digit >= 0) { - digit++; -+#ifdef USE_LIEMIEXT -+ buffer = cString::sprintf(" %2d%s %s", digit, (digit > 9) ? "" : " ", s); -+#else - buffer = cString::sprintf(" %c %s", (digit < 10) ? '0' + digit : ' ' , s); -+#endif /* LIEMIEXT */ - s = buffer; - } - } -@@ -199,9 +227,15 @@ void cOsdMenu::Display(void) - subMenu->Display(); - return; - } -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - displayMenu->SetMessage(mtStatus, NULL); - displayMenu->Clear(); - cStatus::MsgOsdClear(); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdMenuDisplay(MenuKind()); -+#endif /* GRAPHTFT */ - displayMenu->SetTabs(cols[0], cols[1], cols[2], cols[3], cols[4]);//XXX - displayMenu->SetTitle(title); - cStatus::MsgOsdTitle(title); -@@ -296,6 +330,9 @@ bool cOsdMenu::SelectableItem(int idx) - - void cOsdMenu::CursorUp(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int tmpCurrent = current; - int lastOnScreen = first + displayMenuItems - 1; - int last = Count() - 1; -@@ -334,6 +371,9 @@ void cOsdMenu::CursorUp(void) - - void cOsdMenu::CursorDown(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int tmpCurrent = current; - int lastOnScreen = first + displayMenuItems - 1; - int last = Count() - 1; -@@ -374,6 +414,9 @@ void cOsdMenu::CursorDown(void) - - void cOsdMenu::PageUp(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int oldCurrent = current; - int oldFirst = first; - current -= displayMenuItems; -@@ -408,6 +451,9 @@ void cOsdMenu::PageUp(void) - - void cOsdMenu::PageDown(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int oldCurrent = current; - int oldFirst = first; - current += displayMenuItems; -@@ -448,6 +494,64 @@ void cOsdMenu::Mark(void) - } - } - -+#ifdef USE_LIEMIEXT -+#define MENUKEY_TIMEOUT 1500 -+ -+eOSState cOsdMenu::HotKey(eKeys Key) -+{ -+ bool match = false; -+ bool highlight = false; -+ int item_nr; -+ int i; -+ -+ if (Key == kNone) { -+ if (lastActivity.TimedOut()) -+ Key = kOk; -+ else -+ return osContinue; -+ } -+ else { -+ lastActivity.Set(MENUKEY_TIMEOUT); -+ } -+ for (cOsdItem *item = Last(); item; item = Prev(item)) { -+ const char *s = item->Text(); -+ i = 0; -+ item_nr = 0; -+ if (s && (s = skipspace(s)) != '\0' && '0' <= s[i] && s[i] <= '9') { -+ do { -+ item_nr = item_nr * 10 + (s[i] - '0'); -+ } -+ while (!((s[++i] == '\t')||(s[i] == ' ')) && (s[i] != '\0') && ('0' <= s[i]) && (s[i] <= '9')); -+ if ((Key == kOk) && (item_nr == key_nr)) { -+ current = item->Index(); -+ RefreshCurrent(); -+ Display(); -+ cRemote::Put(kOk, true); -+ key_nr = -1; -+ break; -+ } -+ else if (Key != kOk) { -+ if (!highlight && (item_nr == (Key - k0))) { -+ highlight = true; -+ current = item->Index(); -+ } -+ if (!match && (key_nr == -1) && ((item_nr / 10) == (Key - k0))) { -+ match = true; -+ key_nr = (Key - k0); -+ } -+ else if (((key_nr == -1) && (item_nr == (Key - k0))) || (!match && (key_nr >= 0) && (item_nr == (10 * key_nr + Key - k0)))) { -+ current = item->Index(); -+ cRemote::Put(kOk, true); -+ key_nr = -1; -+ break; -+ } -+ } -+ } -+ } -+ if ((!match) && (Key != kNone)) { -+ key_nr = -1; -+ } -+#else - eOSState cOsdMenu::HotKey(eKeys Key) - { - for (cOsdItem *item = First(); item; item = Next(item)) { -@@ -462,6 +566,7 @@ eOSState cOsdMenu::HotKey(eKeys Key) - } - } - } -+#endif /* LIEMIEXT */ - return osContinue; - } - -@@ -500,8 +605,13 @@ eOSState cOsdMenu::ProcessKey(eKeys Key) - } - } - switch (Key) { -+#ifdef USE_LIEMIEXT -+ case kNone: -+ case k0...k9: return hasHotkeys ? HotKey(Key) : osUnknown; -+#else - case k0: return osUnknown; - case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown; -+#endif /* LIEMIEXT */ - case kUp|k_Repeat: - case kUp: CursorUp(); break; - case kDown|k_Repeat: -diff -ruNp vdr-1.7.5/osdbase.h vdr-1.7.5-extensions/osdbase.h ---- vdr-1.7.5/osdbase.h 2007-11-03 15:50:52.000000000 +0100 -+++ vdr-1.7.5-extensions/osdbase.h 2009-04-12 13:37:59.000000000 +0200 -@@ -15,6 +15,10 @@ - #include "skins.h" - #include "tools.h" - -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+#include "submenu.h" -+#endif /* SETUP & PINPLUGIN */ -+ - enum eOSState { osUnknown, - osContinue, - osSchedule, -@@ -51,16 +55,26 @@ private: - char *text; - eOSState state; - bool selectable; -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ cSubMenuNode* subMenu; -+#endif /* SETUP & PINPLUGIN */ - protected: - bool fresh; - public: - cOsdItem(eOSState State = osUnknown); - cOsdItem(const char *Text, eOSState State = osUnknown, bool Selectable = true); -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ cOsdItem(const char *Text, eOSState State, cSubMenuNode* SubMenu); -+#endif /* SETUP & PINPLUGIN */ - virtual ~cOsdItem(); - bool Selectable(void) const { return selectable; } - void SetText(const char *Text, bool Copy = true); - void SetSelectable(bool Selectable); - void SetFresh(bool Fresh); -+#if defined (USE_SETUP) && defined (USE_PINPLUGIN) -+ void SetSubMenu(cSubMenuNode* SubMenu) { subMenu = SubMenu; } -+ cSubMenuNode* SubMenu() { return subMenu; } -+#endif /* SETUP & PINPLUGIN */ - const char *Text(void) const { return text; } - virtual void Set(void) {} - virtual eOSState ProcessKey(eKeys Key); -@@ -95,6 +109,10 @@ private: - char *status; - int digit; - bool hasHotkeys; -+#ifdef USE_LIEMIEXT -+ int key_nr; -+ cTimeMs lastActivity; -+#endif /* LIEMIEXT */ - protected: - void SetDisplayMenu(void); - cSkinDisplayMenu *DisplayMenu(void) { return displayMenu; } -@@ -129,6 +147,9 @@ public: - void Ins(cOsdItem *Item, bool Current = false, cOsdItem *Before = NULL); - virtual void Display(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuUnknown"; } -+#endif /* GRAPHTFT */ - }; - - #endif //__OSDBASE_H -diff -ruNp vdr-1.7.5/osd.c vdr-1.7.5-extensions/osd.c ---- vdr-1.7.5/osd.c 2009-04-05 12:17:25.000000000 +0200 -+++ vdr-1.7.5-extensions/osd.c 2009-04-12 13:37:59.000000000 +0200 -@@ -724,6 +724,9 @@ int cOsd::osdTop = 0; - int cOsd::osdWidth = 0; - int cOsd::osdHeight = 0; - cVector<cOsd *> cOsd::Osds; -+#ifdef USE_PINPLUGIN -+bool cOsd::pinValid = false; -+#endif /* PINPLUGIN */ - - cOsd::cOsd(int Left, int Top, uint Level) - { -@@ -734,6 +737,9 @@ cOsd::cOsd(int Left, int Top, uint Level - width = height = 0; - level = Level; - active = false; -+#ifdef USE_YAEPG -+ vidWin.bpp = 0; -+#endif /* YAEPG */ - for (int i = 0; i < Osds.Size(); i++) { - if (Osds[i]->level > level) { - Osds.Insert(this, i); -diff -ruNp vdr-1.7.5/osd.h vdr-1.7.5-extensions/osd.h ---- vdr-1.7.5/osd.h 2009-04-05 12:16:05.000000000 +0200 -+++ vdr-1.7.5-extensions/osd.h 2009-04-12 13:37:59.000000000 +0200 -@@ -401,6 +401,12 @@ public: - ///< 7: vertical, falling, upper - virtual void Flush(void); - ///< Actually commits all data to the OSD hardware. -+#ifdef USE_PINPLUGIN -+ static bool pinValid; -+#endif /* PINPLUGIN */ -+#ifdef USE_YAEPG -+ tArea vidWin; -+#endif /* YAEPG */ - }; - - class cOsdProvider { -diff -ruNp vdr-1.7.5/plugin.c vdr-1.7.5-extensions/plugin.c ---- vdr-1.7.5/plugin.c 2009-04-05 12:16:48.000000000 +0200 -+++ vdr-1.7.5-extensions/plugin.c 2009-04-12 13:37:59.000000000 +0200 -@@ -317,6 +317,14 @@ void cPluginManager::AddPlugin(const cha - char *p = strchr(s, ' '); - if (p) - *p = 0; -+#ifdef USE_PLUGINMISSING -+ struct stat st; -+ if (stat (cString::sprintf("%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, APIVERSION), &st) && errno == ENOENT) { -+ esyslog("WARN: missing plugin '%s'", s); -+ fprintf(stderr, "vdr: missing plugin '%s'\n", s); -+ } -+ else -+#endif /* PLUGINMISSING */ - dlls.Add(new cDll(cString::sprintf("%s/%s%s%s%s", directory, LIBVDR_PREFIX, s, SO_INDICATOR, APIVERSION), Args)); - free(s); - } -@@ -325,7 +333,11 @@ bool cPluginManager::LoadPlugins(bool Lo - { - for (cDll *dll = dlls.First(); dll; dll = dlls.Next(dll)) { - if (!dll->Load(Log)) -+#ifdef USE_PLUGINMISSING -+ ; -+#else - return false; -+#endif /* PLUGINMISSING */ - } - return true; - } -diff -ruNp vdr-1.7.5/po/ca_ES.po vdr-1.7.5-extensions/po/ca_ES.po ---- vdr-1.7.5/po/ca_ES.po 2009-04-12 11:08:04.000000000 +0200 -+++ vdr-1.7.5-extensions/po/ca_ES.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1010,3 +1010,270 @@ msgstr "Prem qualsevol tecla per cancel· - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR s'apagarà en %s minuts" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/cs_CZ.po vdr-1.7.5-extensions/po/cs_CZ.po ---- vdr-1.7.5/po/cs_CZ.po 2009-04-12 11:08:04.000000000 +0200 -+++ vdr-1.7.5-extensions/po/cs_CZ.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1008,3 +1008,270 @@ msgstr "Jakákoliv klávesa zru¹í restart" - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR se vypne za %s minut" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/da_DK.po vdr-1.7.5-extensions/po/da_DK.po ---- vdr-1.7.5/po/da_DK.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/da_DK.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1007,3 +1007,270 @@ msgstr "Tryk vilkårlig knap for at annul - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR slukker om %s minutter" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/de_DE.po vdr-1.7.5-extensions/po/de_DE.po ---- vdr-1.7.5/po/de_DE.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/de_DE.po 2009-04-12 13:37:59.000000000 +0200 -@@ -794,6 +794,30 @@ msgstr "Lautstärke beim Einschalten" - msgid "Setup.Miscellaneous$Emergency exit" - msgstr "Notausstieg" - -+msgid "Setup.Miscellaneous$Volume ctrl with left/right" -+msgstr "Lautstärke mit Rechts/Links regeln" -+ -+msgid "Setup.Miscellaneous$Channelgroups with left/right" -+msgstr "Kanalgruppen mit Rechts/Links" -+ -+msgid "Setup.Miscellaneous$only in channelinfo" -+msgstr "nur in Kanalinfo" -+ -+msgid "Setup.Miscellaneous$Search fwd/back with left/right" -+msgstr "Vor-/Rücklauf mit Rechts/Links" -+ -+msgid "Setup.Miscellaneous$only in progress display" -+msgstr "nur in Fortschrittsanzeige" -+ -+msgid "Setup.Miscellaneous$Lirc repeat delay" -+msgstr "Lirc Verzögerung" -+ -+msgid "Setup.Miscellaneous$Lirc repeat freq" -+msgstr "Lirc Frequenz" -+ -+msgid "Setup.Miscellaneous$Lirc repeat timeout" -+msgstr "Lirc Zeitbeschränkung" -+ - msgid "Plugins" - msgstr "Plugins" - -@@ -1007,3 +1031,336 @@ msgstr "Taste drücken, um Neustart abzub - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR wird in %s Minuten ausschalten" -+ -+msgid "Parameters" -+msgstr "Parameter" -+ -+msgid "Channel locked by LNB!" -+msgstr "Kanal durch LNB gesperrt!" -+ -+msgid "Childlock" -+msgstr "Kindersicherung" -+ -+msgid "Path" -+msgstr "Pfad" -+ -+msgid "Timer commands" -+msgstr "Befehle für Aufzeichnungen" -+ -+msgid "Rename recording" -+msgstr "Aufzeichnung umbenennen" -+ -+msgid "Date" -+msgstr "Datum" -+ -+msgid "Length" -+msgstr "Länge" -+ -+msgid "Size" -+msgstr "Größe" -+ -+msgid "Delete marks information?" -+msgstr "Marks löschen?" -+ -+msgid "Delete resume information?" -+msgstr "Resume löschen?" -+ -+msgid "DVD plugin is not installed!" -+msgstr "Das DVD-Plugin ist nicht installiert!" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "Alphabet für Haupt-, flexibel für Unterverzeichnisse" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "Datum für Haupt-, flexibel für Unterverzeichnisse" -+ -+msgid "all alphabetically" -+msgstr "Alles alphabetisch" -+ -+msgid "all by date" -+msgstr "Alles nach Datum" -+ -+msgid "Sorting" -+msgstr "Sortierung" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "WarEagle icons verwenden" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "Hauptmenü Titel" -+ -+msgid "Setup.OSD$- Text" -+msgstr "- Text" -+ -+msgid "default" -+msgstr "Voreinstellung" -+ -+msgid "VDR - text" -+msgstr "VDR - Text" -+ -+msgid "text" -+msgstr "Text" -+ -+msgid "VDR - version" -+msgstr "VDR - Version" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Befehle Position im Hauptmenü" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "Zeige gültige Eingabe" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Zeitbalken anzeigen" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "Zeitspanne für dop. EPG-Suche (min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "Doppelten externen EPG-Eintrag" -+ -+msgid "Setup.EPG$Mode of noEPG-Patch" -+msgstr "Art des noEPG-Patches" -+ -+msgid "adjust" -+msgstr "anwenden" -+ -+msgid "delete" -+msgstr "löschen" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "Internes und externes EPG mischen" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "Erk. des lauf. VPS-Events abschalten" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "AC3-Transfer Fix benutzen" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "Sperre Kanäle" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "Kanal Sperren Filter" -+ -+msgid "qam256" -+msgstr "qam256" -+ -+msgid "dvb-c" -+msgstr "dvb-c" -+ -+msgid "dvb-s" -+msgstr "dvb-s" -+ -+msgid "all" -+msgstr "alle" -+ -+msgid "blacklist" -+msgstr "Blacklist" -+ -+msgid "whitelist" -+msgstr "Whitelist" -+ -+msgid "has decoder" -+msgstr "mit Decoder" -+ -+msgid "is primary" -+msgstr "ist primär" -+ -+msgid "has decoder + is primary" -+msgstr "mit Decoder und primär" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "Sync Early Patch benutzen" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "DVB-Empfänger %d nutzt LNB Nr." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "LNB-Nutzung protokollieren" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Dolby Digital Ton aufzeichnen" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "Videoverzeichnispolitik" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "Anzahl der Videoverzeichnisse" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "Video %d Priorität" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Video %d min. MB frei" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "Freundliche Dateinamen" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "Max. Aufnahmengröße (GB)" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "Hard Link Cutter" -+ -+msgid "Setup.Recording$Delete timeshift recording" -+msgstr "Zeitversetzte Aufnahme löschen" -+ -+msgid "request" -+msgstr "abfragen" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Aufnahmedatum anzeigen" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Aufnahmezeit anzeigen" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Länge der Aufnahme anzeigen" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "Ende für Timer anzeigen" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "Aufnahmen sortieren nach" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "Verzeichnisse vor Aufnahmen einsortieren" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "Aufnahmen nach dem Schneiden löschen" -+ -+msgid "Setup.Recording$Cutter adjust starttime" -+msgstr "Startzeit beim Schneiden anpassen" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "Wiedergabe nach Sprung" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Sprung bei Schnittmarke" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "Pause bei letzter Marke" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "Marken aktualisieren" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "Sprungweite in Sekunden" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "Sprungweite in Sekunden Langsam" -+ -+msgid "Setup.Replay$Length" -+msgstr "Länge" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "Länge / Nummer" -+ -+msgid "Setup.Replay$Number" -+msgstr "Nummer" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "DVD Anzeige" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "DVD führende Nullen anzeigen" -+ -+msgid "Setup.Replay$never" -+msgstr "nie" -+ -+msgid "Setup.Replay$on begin" -+msgstr "am Anfang" -+ -+msgid "Setup.Replay$on end" -+msgstr "am Ende" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "am Anfang und Ende" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "DVD-Schublade öffnen" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "DVD drosseln auf" -+ -+msgid "Jump" -+msgstr "Springen: " -+ -+msgid "Skip +60s" -+msgstr "Sprung +60s" -+ -+msgid "Skip -60s" -+msgstr "Sprung -60s" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "Schnitt bereits aktiv - zur Schnitt-Liste hinzufügen?" -+ -+msgid "Format" -+msgstr "Format" -+ -+msgid "PES" -+msgstr "PES" -+ -+msgid "TS" -+msgstr "TS" -+ -+msgid "Rename$Up" -+msgstr "Höher" -+ -+msgid "Rename$Down" -+msgstr "Tiefer" -+ -+msgid "Rename$Previous" -+msgstr "Vorheriger" -+ -+msgid "Rename$Next" -+msgstr "Nächster" -+ -+msgid "Please mount %s" -+msgstr "Bitte %s einlegen!" -+ -+msgid "Please mount DVD %04d" -+msgstr "Bitte DVD %04d einlegen!" -+ -+msgid "Please mount DVD %d" -+msgstr "Bitte DVD %d einlegen!" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "Bitte warten. Überprüfe DVD..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "Keine Index-Datei gefunden. Erstellung kann Minuten dauern. Erstellen?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "Bitte warten. Index-Datei wird erstellt..." -+ -+msgid "Wrong DVD!" -+msgstr "Falsche DVD!" -+ -+msgid "Permanent Timeshift" -+msgstr "Permanentes Timeshift" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Speicherort" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "Festplatte" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "Arbeitsspeicher" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Puffergröße im Arbeitsspeicher (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Auf Festplatte ausweiten wenn nötig" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Pausierten Puffer beibehalten" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Puffergröße auf Festplatte (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Puffergröße (MB)" -diff -ruNp vdr-1.7.5/po/el_GR.po vdr-1.7.5-extensions/po/el_GR.po ---- vdr-1.7.5/po/el_GR.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/el_GR.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1007,3 +1007,270 @@ msgstr "" - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/es_ES.po vdr-1.7.5-extensions/po/es_ES.po ---- vdr-1.7.5/po/es_ES.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/es_ES.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1008,3 +1008,270 @@ msgstr "Pulse cualquier tecla para cance - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR se apagará en %s minutos" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/et_EE.po vdr-1.7.5-extensions/po/et_EE.po ---- vdr-1.7.5/po/et_EE.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/et_EE.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1007,3 +1007,279 @@ msgstr "Restardi katkestamiseks vajuta s - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR lülitub välja %s minuti pärast" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "Ümbernimetamine" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Käsu asukoht peamenüüs" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Edenemisriba" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Salvestuse kuupäev" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Salvestuse kellaaeg" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Salvestuse pikkus" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Format" -+msgstr "" -+ -+msgid "PES" -+msgstr "" -+ -+msgid "TS" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "Üles" -+ -+msgid "Rename$Down" -+msgstr "Alla" -+ -+msgid "Rename$Previous" -+msgstr "Eelmine" -+ -+msgid "Rename$Next" -+msgstr "Järgmine" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/fi_FI.po vdr-1.7.5-extensions/po/fi_FI.po ---- vdr-1.7.5/po/fi_FI.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/fi_FI.po 2009-04-12 13:37:59.000000000 +0200 -@@ -42,6 +42,253 @@ msgstr "Siirtotilan aloitus epäonnistui! - msgid "Starting EPG scan" - msgstr "Ohjelmaoppaan päivitys aloitettu" - -+msgid "Content$Movie/Drama" -+msgstr "Elokuva/draama" -+ -+msgid "Content$Detective/Thriller" -+msgstr "Etsivä/trilleri" -+ -+msgid "Content$Adventure/Western/War" -+msgstr "Seikkailu/western/sota" -+ -+msgid "Content$Science Fiction/Fantasy/Horror" -+msgstr "Scifi/fantasia/kauhu" -+ -+msgid "Content$Comedy" -+msgstr "Komedia" -+ -+msgid "Content$Soap/Melodrama/Folkloric" -+msgstr "Saippua/melodraama/kansanperinne" -+ -+msgid "Content$Romance" -+msgstr "Romanssi" -+ -+msgid "Content$Serious/Classical/Religious/Historical Movie/Drama" -+msgstr "Vakava/klassinen/uskonnollinen/historiallinen elokuva/draama" -+ -+msgid "Content$Adult Movie/Drama" -+msgstr "Aikuiselokuva/draama" -+ -+msgid "Content$News/Current Affairs" -+msgstr "Uutiset/ajankohtaisohjelma" -+ -+msgid "Content$News/Weather Report" -+msgstr "Uutiset/säätiedot" -+ -+msgid "Content$News Magazine" -+msgstr "Uutismakasiini" -+ -+msgid "Content$Documentary" -+msgstr "Dokumentti" -+ -+msgid "Content$Discussion/Inverview/Debate" -+msgstr "Keskustelu/haastattelu/väittely" -+ -+msgid "Content$Show/Game Show" -+msgstr "Show/visailu" -+ -+msgid "Content$Game Show/Quiz/Contest" -+msgstr "Visailu/kilpailu" -+ -+msgid "Content$Variety Show" -+msgstr "Varietee" -+ -+msgid "Content$Talk Show" -+msgstr "Keskusteluohjelma" -+ -+msgid "Content$Sports" -+msgstr "Urheilua" -+ -+msgid "Content$Special Event" -+msgstr "Erikoistapahtuma" -+ -+msgid "Content$Sport Magazine" -+msgstr "Urheilumakasiini" -+ -+msgid "Content$Football" -+msgstr "Jalkapallo" -+ -+msgid "Content$Tennis/Squash" -+msgstr "Tennis/Squash" -+ -+msgid "Content$Team Sports" -+msgstr "Joukkueurheilua" -+ -+msgid "Content$Athletics" -+msgstr "Yleisurheilua" -+ -+msgid "Content$Motor Sport" -+msgstr "Moottoriurheilua" -+ -+msgid "Content$Water Sport" -+msgstr "Vesiurheilua" -+ -+msgid "Content$Winter Sports" -+msgstr "Talviurheilua" -+ -+msgid "Content$Equestrian" -+msgstr "Ratsastusta" -+ -+msgid "Content$Martial Sports" -+msgstr "Kamppailu-urheilua" -+ -+msgid "Content$Children's/Youth Programmes" -+msgstr "Lasten ja nuorten ohjelma" -+ -+msgid "Content$Pre-school Children's Programmes" -+msgstr "Alle kouluikäisten ohjelma" -+ -+msgid "Content$Entertainment Programmes for 6 to 14" -+msgstr "Viihdeohjelma 6-14 vuotiaille" -+ -+msgid "Content$Entertainment Programmes for 10 to 16" -+msgstr "Viihdeohjelma 10-16 vuotiaille" -+ -+msgid "Content$Informational/Educational/School Programme" -+msgstr "Opetus/kouluohjelma" -+ -+msgid "Content$Cartoons/Puppets" -+msgstr "Piirretty/nukke-esitys" -+ -+msgid "Content$Music/Ballet/Dance" -+msgstr "Musiikki/baletti/tanssi" -+ -+msgid "Content$Rock/Pop" -+msgstr "Rock/pop" -+ -+msgid "Content$Serious/Classical Music" -+msgstr "Vakava/klassinen musiikki" -+ -+msgid "Content$Folk/Tradional Music" -+msgstr "Folk/kansanmusiikki" -+ -+msgid "Content$Jazz" -+msgstr "Jazz" -+ -+msgid "Content$Musical/Opera" -+msgstr "Musikaali/ooppera" -+ -+msgid "Content$Ballet" -+msgstr "Baletti" -+ -+msgid "Content$Arts/Culture" -+msgstr "Taide/kulttuuri" -+ -+msgid "Content$Performing Arts" -+msgstr "Performanssitaide" -+ -+msgid "Content$Fine Arts" -+msgstr "Kuvataide" -+ -+msgid "Content$Religion" -+msgstr "Uskonto" -+ -+msgid "Content$Popular Culture/Traditional Arts" -+msgstr "Populaarikulttuuri/perinnetaiteet" -+ -+msgid "Content$Literature" -+msgstr "Kirjallisuus" -+ -+msgid "Content$Film/Cinema" -+msgstr "Elokuvataide" -+ -+msgid "Content$Experimental Film/Video" -+msgstr "Kokeellinen elokuva/video" -+ -+msgid "Content$Broadcasting/Press" -+msgstr "Televisio/radio/lehdistö" -+ -+msgid "Content$New Media" -+msgstr "Uusmedia" -+ -+msgid "Content$Arts/Culture Magazines" -+msgstr "Taide/kulttuurimakasiini" -+ -+msgid "Content$Fashion" -+msgstr "Muoti" -+ -+msgid "Content$Social/Political/Economics" -+msgstr "Yhteiskunta/politiikka/talous" -+ -+msgid "Content$Magazines/Reports/Documentary" -+msgstr "Makasiini/reportaasi/dokumentti" -+ -+msgid "Content$Economics/Social Advisory" -+msgstr "Talous/yhteiskunnallinen neuvonta" -+ -+msgid "Content$Remarkable People" -+msgstr "Merkittävät henkilöt" -+ -+msgid "Content$Education/Science/Factual" -+msgstr "Koulutus/tiede" -+ -+msgid "Content$Nature/Animals/Environment" -+msgstr "Luonto/eläimet/ympäristö" -+ -+msgid "Content$Technology/Natural Sciences" -+msgstr "Teknologia/luonnontiede" -+ -+msgid "Content$Medicine/Physiology/Psychology" -+msgstr "Lääketiede/fysiologia/psykologia" -+ -+msgid "Content$Foreign Countries/Expeditions" -+msgstr "Vieraat maat/tutkimusretket" -+ -+msgid "Content$Social/Spiritual Sciences" -+msgstr "Yhteiskunta/hengelliset tieteet" -+ -+msgid "Content$Further Education" -+msgstr "Jatkokoulutus" -+ -+msgid "Content$Languages" -+msgstr "Kielet" -+ -+msgid "Content$Leisure/Hobbies" -+msgstr "Vapaa-aika ja harrastukset" -+ -+msgid "Content$Tourism/Travel" -+msgstr "Turismi/matkustaminen" -+ -+msgid "Content$Handicraft" -+msgstr "Käsityöt" -+ -+msgid "Content$Motoring" -+msgstr "Autoilu" -+ -+msgid "Content$Fitness & Health" -+msgstr "Kuntoilu & terveys" -+ -+msgid "Content$Cooking" -+msgstr "Ruuanlaitto" -+ -+msgid "Content$Advertisement/Shopping" -+msgstr "Mainostaminen/ostaminen" -+ -+msgid "Content$Gardening" -+msgstr "Puutarhanhoito" -+ -+msgid "Content$Original Language" -+msgstr "Alkuperäiskieli" -+ -+msgid "Content$Black & White" -+msgstr "Mustavalkoinen" -+ -+msgid "Content$Unpublished" -+msgstr "Julkaisematon" -+ -+msgid "Content$Live Broadcast" -+msgstr "Suoralähetys" -+ -+msgid "Content$Special Characteristics" -+msgstr "Erikoisominaisuus" -+ -+msgid "Content$Drama" -+msgstr "Draama" -+ -+#, c-format -+msgid "Suitable for those aged %d and over" -+msgstr "Kielletty alle %d vuotiailta" -+ - msgid "No title" - msgstr "Ei esitystä" - -@@ -1010,3 +1257,282 @@ msgstr "Peru uudelleenkäynnistys painama - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR sammuu %s minuutin kuluttua" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "Polku" -+ -+msgid "Timer commands" -+msgstr "Ajastinkomennot" -+ -+msgid "Rename recording" -+msgstr "Nimeä tallenne" -+ -+msgid "Date" -+msgstr "Päiväys" -+ -+msgid "Length" -+msgstr "Pituus" -+ -+msgid "Size" -+msgstr "Koko" -+ -+msgid "Delete marks information?" -+msgstr "Poista tallenteen merkinnät" -+ -+msgid "Delete resume information?" -+msgstr "Poista tallenteen paluutiedot" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Komentojen sijainti päävalikossa" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Näytä aikajana" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Dolby Digital tallennus" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Näytä tallenteen päiväys" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Näytä tallenteen ajankohta" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Näytä tallenteen kesto" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Format" -+msgstr "Tiedostomuoto" -+ -+msgid "PES" -+msgstr "PES" -+ -+msgid "TS" -+msgstr "TS" -+ -+msgid "Rename$Up" -+msgstr "Ylemmäs" -+ -+msgid "Rename$Down" -+msgstr "Alemmas" -+ -+msgid "Rename$Previous" -+msgstr "Edellinen" -+ -+msgid "Rename$Next" -+msgstr "Seuraava" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Parameters" -+msgstr "Parametrit" -+ -+msgid "Permanent Timeshift" -+msgstr "Jatkuva ajansiirto" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Puskurin sijainti" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "kovalevyllä" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "muistissa" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Puffergröße im Arbeitsspeicher (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Käytä kovalevyä tarvittaessa" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Pidä pysäytetty puskuri" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Puffergröße auf Festplatte (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Puskurin koko (MB)" -diff -ruNp vdr-1.7.5/po/fr_FR.po vdr-1.7.5-extensions/po/fr_FR.po ---- vdr-1.7.5/po/fr_FR.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/fr_FR.po 2009-04-12 13:37:59.000000000 +0200 -@@ -8,6 +8,7 @@ - # Pierre Briec <pbriec@free.fr>, 2006 - # Bruno Roussel <bruno.roussel@free.fr>, 2007 - # Michael Nival <mnival@club-internet.fr>, 2007 -+# Patrice Staudt <patrice.staudt@laposte.net>, 2007, 2008 - # - msgid "" - msgstr "" -@@ -1013,3 +1014,279 @@ msgstr "Appuyer sur une touche pour annu - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR s'arrêtera dans %s minutes" -+ -+msgid "Channel locked by LNB!" -+msgstr "Chaîne interdite par la LNB" -+ -+msgid "Childlock" -+msgstr "Adulte" -+ -+msgid "Path" -+msgstr "Dossiers" -+ -+msgid "Format" -+msgstr "Format" -+ -+msgid "PES" -+msgstr "PES" -+ -+msgid "TS" -+msgstr "TS" -+ -+msgid "Timer commands" -+msgstr "Commandes de programmation" -+ -+msgid "Rename recording" -+msgstr "Renommer l'enregistrement" -+ -+msgid "Date" -+msgstr "Date" -+ -+msgid "Length" -+msgstr "Longeur" -+ -+msgid "Size" -+msgstr "Taille" -+ -+msgid "Delete marks information?" -+msgstr "Effacer marque d'information?" -+ -+msgid "Delete resume information?" -+msgstr "Effacer resume information?" -+ -+msgid "DVD plugin is not installed!" -+msgstr "Le plugin de DVD n'est pas installé!" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "Dir principal alphabétiquement, subdirs flexibles" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "Dir principal à la date, subdirs flexibles" -+ -+msgid "all alphabetically" -+msgstr "tous alphabétiquement" -+ -+msgid "all by date" -+msgstr "tous à la date" -+ -+msgid "Sorting" -+msgstr "Triage" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "Icônes WarEagle" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Position des commandes dans le menu" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "Afficher l'entrée valide" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Montrer la barre de progression" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "Intervalle de recherche EPG de double(min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "Double entrée EPG externe" -+ -+msgid "adjust" -+msgstr "ajuster" -+ -+msgid "delete" -+msgstr "effacer" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "Mélanger les EPG interne et externe" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "Arreter la reconnaissance des événements VPS" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "Utiliser le correctif AC3-Transfer" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "Utilisez Sync début patch" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "La carte DVB %d utilise la LNB No." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "Protocoller l'utilisation du LNB" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Enregistrer en Dolby Digital" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "Régles de répertoires vidéo" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "Nombre de répertoires vidéo" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "Video %d prioritaires" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Video %d min. librei Mo" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "Noms de fichiers facile" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "Taille max. de l'enregistrement (GB)" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "Découpe Hard links" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Montrer la date d'enregistrement" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Montrer l'heure d'enregistrement" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Montrer la longueur de l'enregistrement" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "Montrer la fin du temporisateur" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "Ordonner les enregistrement suivant" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "Les dossiers devant les enregistrements" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "Effacer l'enregistrement après la découpe" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "Lecture après saut" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Saut sur les marques de découpes" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "Pause après la dernière marque" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "Actualiser les marques" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "Longueur de saut en secondes" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "Longueur de saut lent en secondes" -+ -+msgid "Setup.Replay$Length" -+msgstr "Longueur" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "Longueur / Numéro" -+ -+msgid "Setup.Replay$Number" -+msgstr "Numéro" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "Afficher le DVD" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "Afficher les zéros devant le numéro du DVD" -+ -+msgid "Setup.Replay$never" -+msgstr "jamais" -+ -+msgid "Setup.Replay$on begin" -+msgstr "au début" -+ -+msgid "Setup.Replay$on end" -+msgstr "à la fin" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "au début et à la fin" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "Ouvrir le tiroir du lecteur DVD" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "Ralentir la vitesse du DVD à" -+ -+msgid "Jump" -+msgstr "Saut" -+ -+msgid "Skip +60s" -+msgstr "Avance +60s" -+ -+msgid "Skip -60s" -+msgstr "Recule -60s" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "Découpe déjà active - l'ajouter à la liste de découpe?" -+ -+msgid "Rename$Up" -+msgstr "Haut" -+ -+msgid "Rename$Down" -+msgstr "Bas" -+ -+msgid "Rename$Previous" -+msgstr "Précédent" -+ -+msgid "Rename$Next" -+msgstr "Suivant" -+ -+msgid "Please mount %s" -+msgstr "Mettez %s dans le lecteur" -+ -+msgid "Please mount DVD %04d" -+msgstr "Mettez le DVD %04d dans le lecteur" -+ -+msgid "Please mount DVD %d" -+msgstr "Mettez le DVD %d dans le lecteur" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "Un moment SVP. Vérification du DVD..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "Pas trouvé de fichiers index. La création de ce ficher prends quelques minutes. Créer?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "Attendez, svp. Le fichier index est en cours de création..." -+ -+msgid "Wrong DVD!" -+msgstr "Mauvais DVD!" -+ -+msgid "Permanent Timeshift" -+msgstr "Timeshift permanent" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Localisation" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "disque dur" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "mémoire" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Taille de la mémoire tampon dans la mémoire (Mo)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Ètendre au disque dur, si nécessaire" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Gardez en veille la mémoire tampon" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Taille de la mémoire tampon sur le disque dur (Mo)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Taille de la mémoire tampon (Mo)" -diff -ruNp vdr-1.7.5/po/hr_HR.po vdr-1.7.5-extensions/po/hr_HR.po ---- vdr-1.7.5/po/hr_HR.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/hr_HR.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1009,3 +1009,270 @@ msgstr "Pritisnite jednu tipku za poni¹t - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR æe se iskljuèiti za %s minuta" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/hu_HU.po vdr-1.7.5-extensions/po/hu_HU.po ---- vdr-1.7.5/po/hu_HU.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/hu_HU.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1010,3 +1010,270 @@ msgstr "Nyomj egy gombot az újraindítás - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "A VDR leáll %s perc múlva" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/it_IT.po vdr-1.7.5-extensions/po/it_IT.po ---- vdr-1.7.5/po/it_IT.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/it_IT.po 2009-04-12 13:37:59.000000000 +0200 -@@ -37,6 +37,9 @@ msgstr "nessuno" - msgid "*** Invalid Channel ***" - msgstr "*** Canale NON valido ***" - -+msgid "Channel locked by LNB!" -+msgstr "Canale bloccato dal LNB!" -+ - msgid "Channel not available!" - msgstr "Canale non disponibile!" - -@@ -46,6 +49,253 @@ msgstr "Impossibile avviare mod. trasfer - msgid "Starting EPG scan" - msgstr "Inizio scansione EPG" - -+msgid "Content$Movie/Drama" -+msgstr "Film/Dramma" -+ -+msgid "Content$Detective/Thriller" -+msgstr "Investigativo/Giallo" -+ -+msgid "Content$Adventure/Western/War" -+msgstr "Avventura/Western/Guerra" -+ -+msgid "Content$Science Fiction/Fantasy/Horror" -+msgstr "Finzione/Fantasia/Horror" -+ -+msgid "Content$Comedy" -+msgstr "Commedia" -+ -+msgid "Content$Soap/Melodrama/Folkloric" -+msgstr "Telenovella/Melodramma/Folcloristico" -+ -+msgid "Content$Romance" -+msgstr "Romanzo" -+ -+msgid "Content$Serious/Classical/Religious/Historical Movie/Drama" -+msgstr "Serio/Classico/Religioso/Film storico/Dramma" -+ -+msgid "Content$Adult Movie/Drama" -+msgstr "Film per adulti/Dramma" -+ -+msgid "Content$News/Current Affairs" -+msgstr "Notizie/Ultima ora" -+ -+msgid "Content$News/Weather Report" -+msgstr "Notizie/Previsioni meteo" -+ -+msgid "Content$News Magazine" -+msgstr "Rivista di notizie" -+ -+msgid "Content$Documentary" -+msgstr "Documentario" -+ -+msgid "Content$Discussion/Inverview/Debate" -+msgstr "Discussione/Intervista/Dibattito" -+ -+msgid "Content$Show/Game Show" -+msgstr "Spettacolo/Gioco a premi" -+ -+msgid "Content$Game Show/Quiz/Contest" -+msgstr "Gioco a premi/Quiz/Gara" -+ -+msgid "Content$Variety Show" -+msgstr "Spettacolo di varietà" -+ -+msgid "Content$Talk Show" -+msgstr "Talk Show" -+ -+msgid "Content$Sports" -+msgstr "Sport" -+ -+msgid "Content$Special Event" -+msgstr "Evento speciale" -+ -+msgid "Content$Sport Magazine" -+msgstr "Rivista di sport" -+ -+msgid "Content$Football" -+msgstr "Calcio" -+ -+msgid "Content$Tennis/Squash" -+msgstr "Tennis/Squash" -+ -+msgid "Content$Team Sports" -+msgstr "Sport di squadra" -+ -+msgid "Content$Athletics" -+msgstr "Atletica" -+ -+msgid "Content$Motor Sport" -+msgstr "Sport motoristici" -+ -+msgid "Content$Water Sport" -+msgstr "Sport acquatici" -+ -+msgid "Content$Winter Sports" -+msgstr "Sport invernali" -+ -+msgid "Content$Equestrian" -+msgstr "Equitazione" -+ -+msgid "Content$Martial Sports" -+msgstr "Arti marziali" -+ -+msgid "Content$Children's/Youth Programmes" -+msgstr "Programmi per ragazzi/giovani" -+ -+msgid "Content$Pre-school Children's Programmes" -+msgstr "Programmi per ragazzi prescolastici" -+ -+msgid "Content$Entertainment Programmes for 6 to 14" -+msgstr "Programmi di intrattenimento da 6 a 14" -+ -+msgid "Content$Entertainment Programmes for 10 to 16" -+msgstr "Programmi di intrattenimento da 10 a 16" -+ -+msgid "Content$Informational/Educational/School Programme" -+msgstr "Informativo/Educativo/Programma scolastico" -+ -+msgid "Content$Cartoons/Puppets" -+msgstr "Cartoni/Pupazzi" -+ -+msgid "Content$Music/Ballet/Dance" -+msgstr "Musica/Balletto/Danza" -+ -+msgid "Content$Rock/Pop" -+msgstr "Rock/Pop" -+ -+msgid "Content$Serious/Classical Music" -+msgstr "Serio/Musica classica" -+ -+msgid "Content$Folk/Tradional Music" -+msgstr "Folclore/Musica tradizionale" -+ -+msgid "Content$Jazz" -+msgstr "Jazz" -+ -+msgid "Content$Musical/Opera" -+msgstr "Musical/Opera" -+ -+msgid "Content$Ballet" -+msgstr "Balletto" -+ -+msgid "Content$Arts/Culture" -+msgstr "Arte/Cultura" -+ -+msgid "Content$Performing Arts" -+msgstr "Arti di rendimento" -+ -+msgid "Content$Fine Arts" -+msgstr "Arti fine" -+ -+msgid "Content$Religion" -+msgstr "Religione" -+ -+msgid "Content$Popular Culture/Traditional Arts" -+msgstr "Cultura popolare/Arti tradizionali" -+ -+msgid "Content$Literature" -+msgstr "Letteratura" -+ -+msgid "Content$Film/Cinema" -+msgstr "Film/Cinema" -+ -+msgid "Content$Experimental Film/Video" -+msgstr "Film esperimentale/Video" -+ -+msgid "Content$Broadcasting/Press" -+msgstr "Trasmissione/Stampa" -+ -+msgid "Content$New Media" -+msgstr "Nuovo programma" -+ -+msgid "Content$Arts/Culture Magazines" -+msgstr "Arte/Riviste di cultura" -+ -+msgid "Content$Fashion" -+msgstr "Moda" -+ -+msgid "Content$Social/Political/Economics" -+msgstr "Società/Politica/Economia" -+ -+msgid "Content$Magazines/Reports/Documentary" -+msgstr "Riviste/Reportage/Documentari" -+ -+msgid "Content$Economics/Social Advisory" -+msgstr "Economia/Consulenza sociale" -+ -+msgid "Content$Remarkable People" -+msgstr "Personaggi importanti" -+ -+msgid "Content$Education/Science/Factual" -+msgstr "Educazione/Scienza/Fatti" -+ -+msgid "Content$Nature/Animals/Environment" -+msgstr "Natura/Animali/Ambiente" -+ -+msgid "Content$Technology/Natural Sciences" -+msgstr "Tecnologia/Scienze naturali" -+ -+msgid "Content$Medicine/Physiology/Psychology" -+msgstr "Medicina/Filosofia/Psicologia" -+ -+msgid "Content$Foreign Countries/Expeditions" -+msgstr "Paesi esteri/Spedizioni" -+ -+msgid "Content$Social/Spiritual Sciences" -+msgstr "Società/Scienze spirituali" -+ -+msgid "Content$Further Education" -+msgstr "Altra educazione" -+ -+msgid "Content$Languages" -+msgstr "Lingua" -+ -+msgid "Content$Leisure/Hobbies" -+msgstr "Tempo libero/Hobby" -+ -+msgid "Content$Tourism/Travel" -+msgstr "Turismo/Viaggi" -+ -+msgid "Content$Handicraft" -+msgstr "Artigianato" -+ -+msgid "Content$Motoring" -+msgstr "Motori" -+ -+msgid "Content$Fitness & Health" -+msgstr "Culturismo & Salute" -+ -+msgid "Content$Cooking" -+msgstr "Cucina" -+ -+msgid "Content$Advertisement/Shopping" -+msgstr "Pubblicità/Acquisti" -+ -+msgid "Content$Gardening" -+msgstr "Giardinaggio" -+ -+msgid "Content$Original Language" -+msgstr "Lingua madre" -+ -+msgid "Content$Black & White" -+msgstr "Bianco & Nero" -+ -+msgid "Content$Unpublished" -+msgstr "Non pubblicato" -+ -+msgid "Content$Live Broadcast" -+msgstr "ys" -+ -+msgid "Content$Special Characteristics" -+msgstr "Caratteristiche speciali" -+ -+msgid "Content$Drama" -+msgstr "Dramma" -+ -+#, c-format -+msgid "Suitable for those aged %d and over" -+msgstr "Adatto per coloro con %d di età e oltre" -+ - msgid "No title" - msgstr "Senza titolo" - -@@ -232,6 +482,9 @@ msgstr "Utente8" - msgid "Key$User9" - msgstr "Utente9" - -+msgid "Recording started" -+msgstr "Registrazione avviata" -+ - msgid "Disk" - msgstr "Disco" - -@@ -325,6 +578,9 @@ msgstr "Gerarchia" - msgid "Rolloff" - msgstr "Rolloff" - -+msgid "Parameters" -+msgstr "Parametri" -+ - msgid "Channel settings are not unique!" - msgstr "Parametri canale non univoci!" - -@@ -376,9 +632,15 @@ msgstr "Priorità " - msgid "Lifetime" - msgstr "Scadenza" - -+msgid "Childlock" -+msgstr "Filtro fam." -+ - msgid "File" - msgstr "Nome" - -+msgid "Path" -+msgstr "Percorso" -+ - msgid "First day" - msgstr "1° giorno" - -@@ -397,6 +659,9 @@ msgstr "Eliminare il timer?" - msgid "Timer still recording - really delete?" - msgstr "Timer in registrazione - eliminare?" - -+msgid "Timer commands" -+msgstr "Comandi timer" -+ - msgid "Event" - msgstr "Evento" - -@@ -457,6 +722,27 @@ msgstr "Riproduci" - msgid "Button$Rewind" - msgstr "Riavvolgi" - -+msgid "Rename recording" -+msgstr "Rinomina registrazione" -+ -+msgid "Date" -+msgstr "Data" -+ -+msgid "Length" -+msgstr "Durata" -+ -+msgid "Size" -+msgstr "Dimensione" -+ -+msgid "Delete marks information?" -+msgstr "Eliminare informazione marcatori?" -+ -+msgid "Delete resume information?" -+msgstr "Eliminare informazione ripristino?" -+ -+msgid "Error while accessing recording!" -+msgstr "Errore accesso alla registrazione!" -+ - msgid "Recordings" - msgstr "Registrazioni" - -@@ -466,8 +752,8 @@ msgstr "Apri" - msgid "Commands" - msgstr "Comandi" - --msgid "Error while accessing recording!" --msgstr "Errore accesso alla registrazione!" -+msgid "DVD plugin is not installed!" -+msgstr "Il plugin DVD non è installato!" - - msgid "Delete recording?" - msgstr "Eliminare la registrazione?" -@@ -478,6 +764,21 @@ msgstr "Errore eliminazione registrazion - msgid "Recording commands" - msgstr "Comandi di registrazione" - -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "Dir. princ. in ordine alfabetico, sottodir. flessibili" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "Dir. princ. per data, sottodir. flessibili" -+ -+msgid "all alphabetically" -+msgstr "Tutte in ordine alfabetico" -+ -+msgid "all by date" -+msgstr "Tutte per data" -+ -+msgid "Sorting" -+msgstr "Ordinamento" -+ - msgid "never" - msgstr "mai" - -@@ -487,6 +788,18 @@ msgstr "in base allo stile interfaccia" - msgid "always" - msgstr "sempre" - -+msgid "default" -+msgstr "predefinito" -+ -+msgid "VDR - text" -+msgstr "VDR - Testo" -+ -+msgid "text" -+msgstr "Testo" -+ -+msgid "VDR - version" -+msgstr "VDR - Versione" -+ - msgid "OSD" - msgstr "OSD" - -@@ -499,6 +812,9 @@ msgstr "Stile interfaccia" - msgid "Setup.OSD$Theme" - msgstr "Tema colori" - -+msgid "Setup.OSD$WarEagle icons" -+msgstr "Icone WarEagle" -+ - msgid "Setup.OSD$Left" - msgstr "Sinistra" - -@@ -568,12 +884,30 @@ msgstr "Tasto Menu per chiudere" - msgid "Setup.OSD$Recording directories" - msgstr "Directory di registrazione" - -+msgid "Setup.OSD$Main menu title" -+msgstr "Titolo menu principale" -+ -+msgid "Setup.OSD$- Text" -+msgstr "- Testo" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Posizione comandi menu princ." -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "Mostra ingresso valido" -+ - msgid "EPG" - msgstr "Guida programmi EPG" - - msgid "Button$Scan" - msgstr "Scansione" - -+msgid "blacklist" -+msgstr "lista nera" -+ -+msgid "whitelist" -+msgstr "elenco autorizzati" -+ - msgid "Setup.EPG$EPG scan timeout (h)" - msgstr "Scadenza aggiorn. EPG (ore)" - -@@ -583,6 +917,9 @@ msgstr "Livello correzione EPG" - msgid "Setup.EPG$EPG linger time (min)" - msgstr "Mostra vecchi dati EPG (min)" - -+msgid "Setup.EPG$Show progress bar" -+msgstr "Mostra barra avanzamento" -+ - msgid "Setup.EPG$Set system time" - msgstr "Imposta orario di sistema" - -@@ -597,6 +934,27 @@ msgstr "Lingue preferite" - msgid "Setup.EPG$Preferred language" - msgstr "Lingua preferita" - -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "Tempo doppia ricerca EPG (min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "Doppio valore EPG esterno" -+ -+msgid "adjust" -+msgstr "regola" -+ -+msgid "delete" -+msgstr "elimina" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "Mescola EPG interno e esterno" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "Disabilita esec. evento VPS" -+ -+msgid "Setup.EPG$Mode of noEPG-Patch" -+msgstr "Modalità di noEPG-Patch" -+ - msgid "pan&scan" - msgstr "pan&scan" - -@@ -627,6 +985,27 @@ msgstr "nuovi transponder" - msgid "DVB" - msgstr "Scheda DVB" - -+msgid "qam256" -+msgstr "qam256" -+ -+msgid "dvb-c" -+msgstr "dvb-c" -+ -+msgid "dvb-s" -+msgstr "dvb-s" -+ -+msgid "all" -+msgstr "tutti" -+ -+msgid "has decoder" -+msgstr "con decoder" -+ -+msgid "is primary" -+msgstr "primaria" -+ -+msgid "has decoder + is primary" -+msgstr "con decoder e primaria" -+ - msgid "Setup.DVB$Primary DVB interface" - msgstr "Scheda DVB primaria" - -@@ -666,9 +1045,28 @@ msgstr "Trasparenza sottotitoli" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Trasparenza sfondo sottotitoli" - -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "Utilizza correzione AC3-Transfer" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "Blocco canale" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "Modalità filtro blocco canale" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "Utilizza correzione Early Sync" -+ - msgid "LNB" - msgstr "LNB" - -+#, c-format -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "La scheda DVB %d utilizza LNB No." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "Registra utilizzo LNB" -+ - msgid "Setup.LNB$Use DiSEqC" - msgstr "Utilizza DiSEqC" - -@@ -711,6 +1109,9 @@ msgstr "La CAM è in uso - vuoi reimpost - msgid "Can't reset CAM!" - msgstr "Impossibile reimpostare il modulo CAM!" - -+msgid "request" -+msgstr "chiedi" -+ - msgid "Recording" - msgstr "Registrazione" - -@@ -735,9 +1136,29 @@ msgstr "Priorità di pausa" - msgid "Setup.Recording$Pause lifetime (d)" - msgstr "Scadenza pausa (gg)" - -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Registra Dolby Digital" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "Regole directory video" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "Numero di directory video" -+ -+#, c-format -+msgid "Setup.Recording$Video %d priority" -+msgstr "Priorità video %d " -+ -+#, c-format -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Min. MB disponibili video %d " -+ - msgid "Setup.Recording$Use episode name" - msgstr "Utilizza nome episodio" - -+msgid "Setup.Recording$Friendly filenames" -+msgstr "Nomi file semplici" -+ - msgid "Setup.Recording$Use VPS" - msgstr "Utilizza VPS" - -@@ -756,9 +1177,39 @@ msgstr "Durata reg. immediata (min)" - msgid "Setup.Recording$Max. video file size (MB)" - msgstr "Dim. massima file video (MB)" - -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "Dim. massima reg. (GB)" -+ - msgid "Setup.Recording$Split edited files" - msgstr "Dividi i file modificati" - -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "Taglia collegamenti Hard" -+ -+msgid "Setup.Recording$Delete timeshift recording" -+msgstr "Elimina reg. timeshift" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Mostra data registrazione" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Mostra ora registrazione" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Mostra durata registrazione" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "Mostra fine del timer" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "Ordina registrazioni per" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "Ordina directory prima di reg." -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "Elimina taglio automatico" -+ - msgid "Replay" - msgstr "Riproduzione" - -@@ -771,6 +1222,63 @@ msgstr "Mostra modalità riproduzione" - msgid "Setup.Replay$Resume ID" - msgstr "ID di ripristino" - -+msgid "Setup.Replay$Jump&Play" -+msgstr "Vai a & Riproduci" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Riproduci & Vai a" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "Pausa all'ultimo marcatore" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "Ricarica marcatori" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "Salta secondi" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "Salta secondi lentamente" -+ -+msgid "Setup.Replay$Length" -+msgstr "Durata" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "Durata / Numero" -+ -+msgid "Setup.Replay$Number" -+msgstr "Numero" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "Mod. visualizzazione DVD" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "Mostra zeri davanti al DVD" -+ -+msgid "Setup.Replay$never" -+msgstr "mai" -+ -+msgid "Setup.Replay$on begin" -+msgstr "all'inizio" -+ -+msgid "Setup.Replay$on end" -+msgstr "alla fine" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "all'inizio e alla fine" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "Apri vassoio" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "Limita velocità DVD a" -+ -+msgid "Setup.Miscellaneous$only in channelinfo" -+msgstr "solo nelle info canale" -+ -+msgid "Setup.Miscellaneous$only in progress display" -+msgstr "solo nel canale in esec." -+ - msgid "Miscellaneous" - msgstr "Generici" - -@@ -798,9 +1306,54 @@ msgstr "come prima" - msgid "Setup.Miscellaneous$Initial volume" - msgstr "Volume iniziale" - -+msgid "Setup.Miscellaneous$Volume ctrl with left/right" -+msgstr "Controllo volume con Sinistra/Destra" -+ -+msgid "Setup.Miscellaneous$Channelgroups with left/right" -+msgstr "Gruppi canali con Sinistra/Destra" -+ -+msgid "Setup.Miscellaneous$Search fwd/back with left/right" -+msgstr "Cerca avanti/indietro con Sinistra/Destra" -+ - msgid "Setup.Miscellaneous$Emergency exit" - msgstr "Uscita di emergenza" - -+msgid "Setup.Miscellaneous$Lirc repeat delay" -+msgstr "Ritardo ripetizione LIRC" -+ -+msgid "Setup.Miscellaneous$Lirc repeat freq" -+msgstr "Frequenza ripetizione LIRC" -+ -+msgid "Setup.Miscellaneous$Lirc repeat timeout" -+msgstr "Scadenza ripetizione LIRC" -+ -+msgid "Permanent Timeshift" -+msgstr "Timeshift permanente" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Posizione" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "Disco fisso" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "Memoria" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Dim. buffer in memoria (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Utilizza disco fisso se necessario" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Mantieni buffer di pausa" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Dim. buffer nel disco fisso (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Dimensione buffer (MB)" -+ - msgid "Plugins" - msgstr "Plugins" - -@@ -826,7 +1379,6 @@ msgstr "Programmi" - msgid "VDR" - msgstr "VDR" - --#. TRANSLATORS: note the leading blank! - msgid " Stop replaying" - msgstr " Ferma riproduzione" - -@@ -842,7 +1394,6 @@ msgstr "Ferma" - msgid "Button$Resume" - msgstr "Riprendi" - --#. TRANSLATORS: note the leading blank! - msgid " Cancel editing" - msgstr " Annulla modifiche" - -@@ -873,10 +1424,22 @@ msgstr "Nessuna periferica DVB disponibi - msgid "Pausing live video..." - msgstr "Pausa del canale in visione..." - -+msgid "Jump" -+msgstr "Vai a" -+ -+msgid "Skip +60s" -+msgstr "Salta +60s" -+ -+msgid "Skip -60s" -+msgstr "Salta - 60s" -+ - #. TRANSLATORS: note the trailing blank! - msgid "Jump: " - msgstr "Vai a: " - -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "Taglio in esecuzione - Aggiungere alla coda tagli?" -+ - msgid "No editing marks defined!" - msgstr "Nessun marcatore di modifica definito!" - -@@ -907,6 +1470,18 @@ msgstr "Sovrascrivi" - msgid "Button$Insert" - msgstr "Inserisci" - -+msgid "Rename$Up" -+msgstr "Su" -+ -+msgid "Rename$Down" -+msgstr "Giù" -+ -+msgid "Rename$Previous" -+msgstr "Precedente" -+ -+msgid "Rename$Next" -+msgstr "Successivo" -+ - msgid "Plugin" - msgstr "Plugin" - -@@ -919,6 +1494,30 @@ msgstr "Canale bloccato (in registrazion - msgid "Low disk space!" - msgstr "Poco spazio su disco!" - -+#, c-format -+msgid "Please mount %s" -+msgstr "Monta %s" -+ -+#, c-format -+msgid "Please mount DVD %04d" -+msgstr "Monta il DVD %04d" -+ -+#, c-format -+msgid "Please mount DVD %d" -+msgstr "Monta il DVD %d" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "Attendere prego. Verifica DVD..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "Nessun indice trovato. La creazione può impiegare alcuni minuti. Crearne uno?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "Attendere prego. Creazione indice..." -+ -+msgid "Wrong DVD!" -+msgstr "DVD errato!" -+ - msgid "Can't shutdown - option '-s' not given!" - msgstr "Impossibile spegnere - parametro '-s' non assegnato!" - -@@ -990,9 +1589,6 @@ msgstr "Domenica" - msgid "Upcoming recording!" - msgstr "Registrazione imminente!" - --msgid "Recording started" --msgstr "Registrazione avviata" -- - msgid "VDR will shut down later - press Power to force" - msgstr "VDR si spegnerà più tardi - premi Power per forzare" - -diff -ruNp vdr-1.7.5/po/nl_NL.po vdr-1.7.5-extensions/po/nl_NL.po ---- vdr-1.7.5/po/nl_NL.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/nl_NL.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1011,3 +1011,270 @@ msgstr "Druk een willekeurige toets om h - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR zal na %s minuten uitschakelen" -+ -+msgid "Channel locked by LNB!" -+msgstr "Kanaal geblokkeerd door LNB" -+ -+msgid "Childlock" -+msgstr "Kinderslot" -+ -+msgid "Path" -+msgstr "Pad" -+ -+msgid "Timer commands" -+msgstr "Timer commando's" -+ -+msgid "Rename recording" -+msgstr "Hernoem opnamen" -+ -+msgid "Date" -+msgstr "Datum" -+ -+msgid "Length" -+msgstr "Lengte" -+ -+msgid "Size" -+msgstr "Grootte" -+ -+msgid "Delete marks information?" -+msgstr "Verwijder informatiemarkeringen?" -+ -+msgid "Delete resume information?" -+msgstr "Verwijder hervattingsmarkeringen?" -+ -+msgid "DVD plugin is not installed!" -+msgstr "DVd plugin is niet geÃnstalleerd!" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "hoofdmap alfabetisch, submappen flexibel" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "hoofdmap op datum, submappen flexibel" -+ -+msgid "all alphabetically" -+msgstr "alles alfabetisch" -+ -+msgid "all by date" -+msgstr "alles op datum" -+ -+msgid "Sorting" -+msgstr "Sortering" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "WarEagle symbolen" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Positie commandobalk in hoofdmenu" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "Toon geldige invoer" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Toon voortschreidingsbalk" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "Tijdsduur starten dubbele EPG zoekactie (min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "externe dubbele EPG invoer" -+ -+msgid "adjust" -+msgstr "afstellen" -+ -+msgid "delete" -+msgstr "verwijderen" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "Mix in- en externe EPG" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "Schakel aktieve VPS uitzending uit" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "Gebruik AC3-Transfer Fix" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "Gebruik 'Sync Early' Patch" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "LNB kaart %d gebruikt LNB Nr." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "Houd LNB gebruik bij" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "Neem Dolby Digital spoor op" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "Omgang m.b.t. Videomappen" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "Aantal videomappen" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "Video %d prioriteit" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Video %d min. vrij MB" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "Handzame bestandsnamen" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "Max. opnamegrootte (GB)" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "'Hard link' bestandsbewerker" -+ -+msgid "Setup.Recording$Show date" -+msgstr "Toon datum" -+ -+msgid "Setup.Recording$Show time" -+msgstr "Toon tijd" -+ -+msgid "Setup.Recording$Show length" -+msgstr "Toon lengte" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "Toon einde van timers" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "Sorteer opnames op" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "Sorteer mappen vÃÃr opnames" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "Bestandsbewerker automatisch wissen" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "Spring&Speel" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Speel&Spring" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "Pauzeer bij laatste markering" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "Herlaadt markeringen" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "Spring seconden" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "Spring seconden langzaam" -+ -+msgid "Setup.Replay$Length" -+msgstr "Lengte" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "Lengte / Nummer" -+ -+msgid "Setup.Replay$Number" -+msgstr "Nummer" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "DVD displayinstellingen" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "DVD toon voorloopnullen" -+ -+msgid "Setup.Replay$never" -+msgstr "nooit" -+ -+msgid "Setup.Replay$on begin" -+msgstr "aan het begin" -+ -+msgid "Setup.Replay$on end" -+msgstr "bij het einde" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "bij het begin en aan het einde" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "Open DVD lade" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "Beperk DVD omw. snelheid" -+ -+msgid "Jump" -+msgstr "Spring" -+ -+msgid "Skip +60s" -+msgstr "Spring +60s verder" -+ -+msgid "Skip -60s" -+msgstr "Spring -60s terug" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "Bestandsbewerker aktief - aan wachtrij toeveogen?" -+ -+msgid "Rename$Up" -+msgstr "Boven" -+ -+msgid "Rename$Down" -+msgstr "Onder" -+ -+msgid "Rename$Previous" -+msgstr "Vorige" -+ -+msgid "Rename$Next" -+msgstr "Volgende" -+ -+msgid "Please mount %s" -+msgstr "Koppel %s aan a.u.b." -+ -+msgid "Please mount DVD %04d" -+msgstr "Koppel DVD %04d aan a.u.b." -+ -+msgid "Please mount DVD %d" -+msgstr "Koppel DVD %d aan a.u.b." -+ -+msgid "Please wait. Checking DVD..." -+msgstr "Even wachten, DVD wordt gecontroleerd..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "Geen indexbestand gevonden. Aanmaken duurt even, doorgaan?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "Even wachten indexbestand wordt aangemaakt..." -+ -+msgid "Wrong DVD!" -+msgstr "Verkeerde DVD!" -+ -+msgid "Permanent Timeshift" -+msgstr "Permanente livebuffer" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "Opslaglocatie" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "hardeschijf" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "geheugen" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "Buffergrootte in geheugen (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "Overlopen naar hardeschijf indien noodzakelijk" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "Bewaar gepauzeerde buffer" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "Buffergrootte op harddisk (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "Buffergrootte (MB)" -diff -ruNp vdr-1.7.5/po/nn_NO.po vdr-1.7.5-extensions/po/nn_NO.po ---- vdr-1.7.5/po/nn_NO.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/nn_NO.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1008,3 +1008,270 @@ msgstr "" - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/pl_PL.po vdr-1.7.5-extensions/po/pl_PL.po ---- vdr-1.7.5/po/pl_PL.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/pl_PL.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1008,3 +1008,270 @@ msgstr "Naci¶nij dowolny klawisz aby nie - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR zostanie wy³±czony za %s minut" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/pt_PT.po vdr-1.7.5-extensions/po/pt_PT.po ---- vdr-1.7.5/po/pt_PT.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/pt_PT.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1007,3 +1007,270 @@ msgstr "Pressione qualquer tecla para nã - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR vai desligar em %s minutos" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/ro_RO.po vdr-1.7.5-extensions/po/ro_RO.po ---- vdr-1.7.5/po/ro_RO.po 2009-04-12 11:08:05.000000000 +0200 -+++ vdr-1.7.5-extensions/po/ro_RO.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1010,3 +1010,270 @@ msgstr "Apãsaþi orice tastã pentru a anu - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR se va închide în %s minute" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/ru_RU.po vdr-1.7.5-extensions/po/ru_RU.po ---- vdr-1.7.5/po/ru_RU.po 2009-04-12 11:08:06.000000000 +0200 -+++ vdr-1.7.5-extensions/po/ru_RU.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1008,3 +1008,280 @@ msgstr "½ÐÖÜØâÕ ÛîÑãî ÚÝÞßÚã ÔÛï ÞâÜÕÝë - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR ÒëÚÛîçØâáï çÕàÕ× %s ÜØÝãâ" -+ -+msgid "Channel locked by LNB!" -+msgstr "ºÞÝÒÕàâÕà ÑÛÞÚØàãÕâ ÚÐÝÐÛ" -+ -+msgid "Childlock" -+msgstr "´ÕâáÚÐï ÑÛÞÚØàÞÒÚÐ" -+ -+msgid "Path" -+msgstr "¿ãâì" -+ -+msgid "Timer commands" -+msgstr "ºÞÜÜÐÝÔë âÐÙÜÕàÐ" -+ -+msgid "Rename recording" -+msgstr "¿ÕàÕØÜÕÝÞÒÐâì ×Ðߨáì" -+ -+msgid "Date" -+msgstr "´ÐâÐ" -+ -+msgid "Length" -+msgstr "´ÛØÝÐ" -+ -+msgid "Size" -+msgstr "ÀÐ×ÜÕà" -+ -+msgid "Format" -+msgstr "" -+ -+msgid "PES" -+msgstr "" -+ -+msgid "TS" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "ÃÔÐÛØâì ÜÕâÚØ?" -+ -+msgid "Delete resume information?" -+msgstr "²ÞááâÐÝÞÒØâì ÜÕâÚØ?" -+ -+msgid "DVD plugin is not installed!" -+msgstr "¼ÞÔãÛì DVD ÝÕ ãáâÐÝÞÒÛÕÝ!" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "ÓÛÐÒÝÐï ÔØàÕÚâÞàØï ßÞ ÐÛäÐÒØâã, ßÞÔÔØàÕÚâÞàØØ ÓØÑÚÞ" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "ÓÛÐÒÝÐï ÔØàÕÚâÞàØï ßÞ ÒàÕÜÕÝØ, ßÞÔÔØàÕÚâÞàØØ ÓØÑÚÞ" -+ -+msgid "all alphabetically" -+msgstr "ÒáÕ ßÞ ÐÛäÐÒØâã" -+ -+msgid "all by date" -+msgstr "ÒáÕ ßÞ ÒàÕÜÕÝØ" -+ -+msgid "Sorting" -+msgstr "ÁÞàâØàÞÒÚÐ" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "WarEagle ØÚÞÝÚØ" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "ÀÐ×ÜÕéÕÝØÕ ÚÞÜÐÝÔ Ò ÓÛÐÒÝÞÜ ÜÕÝî" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "¿ÞÚÐ× ßàÐÒØÛìÝÞÓÞ ÒÒÞÔÐ" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "¿ÞÚÐ× ÑÐÛÚØ ßàÞÓàÕááÐ" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "¿ÕàØÞÔ ÔÛï ßÞØáÚÐ ÔÒÞÙÝëå EPG(min)" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "²ÝÕèÝØÙ ØáâÞçÝØÚ ÔÒÞÙÝÞÓÞ EPG" -+ -+msgid "adjust" -+msgstr "ÝÐáâàÞØâì" -+ -+msgid "delete" -+msgstr "ãÔÐÛØâì" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "ÁÜÕèØÒÐÝØÕ ÒÝãâàÕÝÝÕÓÞ Ø ÒÝÕèÝÕÓÞ EPG" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "·ÐßàÕâ VPS áÞÑëâØï" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "¸áßÞÛì×ÞÒÐâì ÚÞààÕÚâØàÞÒÚã AC3-Transfer" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "¸áßÞÛì×ÞÒÐâì Sync Early " -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "DVB ãáâàÞÙáâÒÞ %d ØáßÞÛì×ãÕâ LNB No." -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "»ÞÓØàÞÒÐÝØÕ ØáßÞÛì×ÞÒÐÝØï LNB" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "·Ðߨáì Dolby Digital" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "¿ÞàïÔÞÚ ÒØÔÕÞ ÔØàÕÚâÞàØØ" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "ºÞÛØçÕáâÒÞ ÒØÔÕÞ ÔØàÕÚâÞàØÙ" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "Video %d ßàØÞàØâÕâ" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "Video %d ÜØÝ. áÒÞÑÞÔÝÞ MB" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "ÇØâÐÑÕÛìÝëÕ ØÜÕÝÐ äÐÙÛÞÒ" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "¼ÐÚá. àÐ×ÜÕà ×ÐßØáØ (GB)" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "¼ÞÝâÐÖ á hard link" -+ -+msgid "Setup.Recording$Show date" -+msgstr "¿ÞÚÐ×ëÒÐâì ÔÐâã" -+ -+msgid "Setup.Recording$Show time" -+msgstr "¿ÞÚÐ×ëÒÐâì ÒàÕÜï ×ÐߨáØ" -+ -+msgid "Setup.Recording$Show length" -+msgstr "¿ÞÚÐ×ëÒÐâì ßàÞÔÞÛÖØâÕÛìÝÞáâì ×ÐߨáØ" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "½Ð×ÒÐÝØÕ ÓÛÐÒÝÞÓÞ ÜÕÝî" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "¿ÞÚÐ× ÞÚÞÝçÐÝØï âÐÙÜÕàÐ" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "ÁÞàâØàÞÒÚÐ ×ÐߨáÕÙ ßÞ" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "ÁÞàâØàÞÒÚÐ ÔØàÕÚâÞàØÙ ÔÞ ×ÐߨáØ" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "°ÒâÞÜÐâØçÕáÚÞÕ ãÔÐÛÕÝØÕ ÜÞÝâÐÖÐ" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "Jump&Play" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "Play&Jump" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "¿Ðã×Ð ÝÐ ßÞáÛÕÔÝÕÙ ÜÕâÚÕ" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "¿ÕàÕÓàãרâì ÜÕâÚØ" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "¿àÞßãáÚ áÕÚãÝÔ" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "¿àÞßãáÚ áÕÚãÝÔ ÜÕÔÛÕÝÝÞ" -+ -+msgid "Setup.Replay$Length" -+msgstr "´ÛØÝÐ" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "´ÛØÝÐ / ½ÞÜÕà" -+ -+msgid "Setup.Replay$Number" -+msgstr "½ÞÜÕà" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "ÀÕÖØÜ ßÞÚÐ×Ð DVD" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "ßÞÚÐ× ÒÕÔãéØå ÝãÛÕÙ" -+ -+msgid "Setup.Replay$never" -+msgstr "ÝØÚÞÓÔÐ" -+ -+msgid "Setup.Replay$on begin" -+msgstr "Ò ÝÐçÐÛÕ" -+ -+msgid "Setup.Replay$on end" -+msgstr "² ÚÞÝæÕ" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "Ò ÝÐçÐÛÕ Ø Ò ÚÞÝæÕ" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "¾âÚàëâì" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "¿àÕÔÕÛ áÚÞàÞáâØ DVD" -+ -+msgid "Jump" -+msgstr "¿àëÖÞÚ" -+ -+msgid "Skip +60s" -+msgstr "¿àÞßãáÚ +60s" -+ -+msgid "Skip -60s" -+msgstr "¿àÞßãáÚ -60s" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "¼ÞÝâÐÖÕà àÐÑÞâÐÕâ - ´ÞÑÐÒØâì Ò ÞçÕàÕÔì?" -+ -+msgid "Rename$Up" -+msgstr "²ÒÕàå" -+ -+msgid "Rename$Down" -+msgstr "²ÝØ×" -+ -+msgid "Rename$Previous" -+msgstr "¿àÕÔëÔãéØÙ" -+ -+msgid "Rename$Next" -+msgstr "ÁÛÕÔãîéØÙ" -+ -+msgid "Please mount %s" -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÜÞÝâØàãÙâÕ %s" -+ -+msgid "Please mount DVD %04d" -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÜÞÝâØàãÙâÕ DVD %04d" -+ -+msgid "Please mount DVD %d" -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÜÞÝâØàãÙâÕ DVD %d" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÞÖÔØâÕ. ¿àÞÒÕàÚÐ DVD..." -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "¸ÝÔÕÚá äÐÙÛ ÝÕ ÝÐÙÔÕÝ. ÁÞ×ÔÐÝØÕ âàÕÑãÕâ ÒàÕÜÕÝØ. ÁÞ×ÔÐâì?" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "¿ÞÖÐÛãÙáâÐ ßÞÔÞÖÔØâÕ. ÁÞ×ÔÐÝØÕ ØÝÔÕÚá äÐÙÛÐ..." -+ -+msgid "Wrong DVD!" -+msgstr "¾èØÑÚÐ DVD!" -+ -+msgid "Permanent Timeshift" -+msgstr "¿ÞáâÞïÝÝëÙ âÐÙÜèØäâ" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "¼ÕáâÞÝÐåÞÖÔÕÝØï" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "ÖÕáâÚØÙ ÔØáÚ" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "ßÐÜïâì" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "ÀÐ×ÜÕà ÑãäÕàÐ Ò ßÐÜïâØ (MB)" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "´ÞÑÐÒÛïâì ÖÕáâÚØÙ ÔØáÚ ÕáÛØ ÝÕÞÑåÞÔØÜÞ" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "ÅàÐÝÕÝØÕ ÑãäÕàÐ ßÐã×ë" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "ÀÐ×ÜÕà ÑãäÕàÐ ÝÐ ÖÕáâÚÞÜ ÔØáÚÕ (MB)" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "ÀÐ×ÜÕà ÑãäÕàÐ (MB)" -+ -diff -ruNp vdr-1.7.5/po/sl_SI.po vdr-1.7.5-extensions/po/sl_SI.po ---- vdr-1.7.5/po/sl_SI.po 2009-04-12 11:08:06.000000000 +0200 -+++ vdr-1.7.5-extensions/po/sl_SI.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1008,3 +1008,270 @@ msgstr "Pritisni katerokoli tipko za pre - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR se bo zaustavil v %s minutah" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/sv_SE.po vdr-1.7.5-extensions/po/sv_SE.po ---- vdr-1.7.5/po/sv_SE.po 2009-04-12 11:08:06.000000000 +0200 -+++ vdr-1.7.5-extensions/po/sv_SE.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1010,3 +1010,270 @@ msgstr "Tryck valfri knapp för att återk - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR kommer att stängas ned om %s minuter" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/po/tr_TR.po vdr-1.7.5-extensions/po/tr_TR.po ---- vdr-1.7.5/po/tr_TR.po 2009-04-12 11:08:06.000000000 +0200 -+++ vdr-1.7.5-extensions/po/tr_TR.po 2009-04-12 13:37:59.000000000 +0200 -@@ -1007,3 +1007,270 @@ msgstr "Yeniden baþlatmayý iptal etmek i - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR %s dakikada kapanacak" -+ -+msgid "Channel locked by LNB!" -+msgstr "" -+ -+msgid "Childlock" -+msgstr "" -+ -+msgid "Path" -+msgstr "" -+ -+msgid "Timer commands" -+msgstr "" -+ -+msgid "Rename recording" -+msgstr "" -+ -+msgid "Date" -+msgstr "" -+ -+msgid "Length" -+msgstr "" -+ -+msgid "Size" -+msgstr "" -+ -+msgid "Delete marks information?" -+msgstr "" -+ -+msgid "Delete resume information?" -+msgstr "" -+ -+msgid "DVD plugin is not installed!" -+msgstr "" -+ -+msgid "main dir alphabetically, subdirs flexible" -+msgstr "" -+ -+msgid "main dir by date, subdirs flexible" -+msgstr "" -+ -+msgid "all alphabetically" -+msgstr "" -+ -+msgid "all by date" -+msgstr "" -+ -+msgid "Sorting" -+msgstr "" -+ -+msgid "Setup.OSD$WarEagle icons" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "" -+ -+msgid "Setup.OSD$Show valid input" -+msgstr "" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "" -+ -+msgid "Setup.EPG$Period for double EPG search(min)" -+msgstr "" -+ -+msgid "Setup.EPG$Extern double Epg entry" -+msgstr "" -+ -+msgid "adjust" -+msgstr "" -+ -+msgid "delete" -+msgstr "" -+ -+msgid "Setup.EPG$Mix intern and extern EPG" -+msgstr "" -+ -+msgid "Setup.EPG$Disable running VPS event" -+msgstr "" -+ -+msgid "Setup.DVB$Use AC3-Transfer Fix" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker" -+msgstr "" -+ -+msgid "Setup.DVB$Channel Blocker Filter Mode" -+msgstr "" -+ -+msgid "Setup.DVB$Use Sync Early Patch" -+msgstr "" -+ -+msgid "Setup.LNB$DVB device %d uses LNB No." -+msgstr "" -+ -+msgid "Setup.LNB$Log LNB usage" -+msgstr "" -+ -+msgid "Setup.Recording$Record Dolby Digital" -+msgstr "" -+ -+msgid "Setup.Recording$Video directory policy" -+msgstr "" -+ -+msgid "Setup.Recording$Number of video directories" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d priority" -+msgstr "" -+ -+msgid "Setup.Recording$Video %d min. free MB" -+msgstr "" -+ -+msgid "Setup.Recording$Friendly filenames" -+msgstr "" -+ -+msgid "Setup.Recording$Max. recording size (GB)" -+msgstr "" -+ -+msgid "Setup.Recording$Hard Link Cutter" -+msgstr "" -+ -+msgid "Setup.Recording$Show date" -+msgstr "" -+ -+msgid "Setup.Recording$Show time" -+msgstr "" -+ -+msgid "Setup.Recording$Show length" -+msgstr "" -+ -+msgid "Setup.OSD$Main menu title" -+msgstr "" -+ -+msgid "Setup.Recording$Show end of timer" -+msgstr "" -+ -+msgid "Setup.Recording$Sort recordings by" -+msgstr "" -+ -+msgid "Setup.Recording$Sort directories before recordings" -+msgstr "" -+ -+msgid "Setup.Recording$Cutter auto delete" -+msgstr "" -+ -+msgid "Setup.Replay$Jump&Play" -+msgstr "" -+ -+msgid "Setup.Replay$Play&Jump" -+msgstr "" -+ -+msgid "Setup.Replay$Pause at last mark" -+msgstr "" -+ -+msgid "Setup.Replay$Reload marks" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds" -+msgstr "" -+ -+msgid "Setup.Replay$Skip Seconds Slow" -+msgstr "" -+ -+msgid "Setup.Replay$Length" -+msgstr "" -+ -+msgid "Setup.Replay$Length / Number" -+msgstr "" -+ -+msgid "Setup.Replay$Number" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display mode" -+msgstr "" -+ -+msgid "Setup.Replay$DVD display leading zeros" -+msgstr "" -+ -+msgid "Setup.Replay$never" -+msgstr "" -+ -+msgid "Setup.Replay$on begin" -+msgstr "" -+ -+msgid "Setup.Replay$on end" -+msgstr "" -+ -+msgid "Setup.Replay$on begin and end" -+msgstr "" -+ -+msgid "Setup.Replay$Tray open" -+msgstr "" -+ -+msgid "Setup.Replay$Limit DVD to speed" -+msgstr "" -+ -+msgid "Jump" -+msgstr "" -+ -+msgid "Skip +60s" -+msgstr "" -+ -+msgid "Skip -60s" -+msgstr "" -+ -+msgid "Cutter already running - Add to cutting queue?" -+msgstr "" -+ -+msgid "Rename$Up" -+msgstr "" -+ -+msgid "Rename$Down" -+msgstr "" -+ -+msgid "Rename$Previous" -+msgstr "" -+ -+msgid "Rename$Next" -+msgstr "" -+ -+msgid "Please mount %s" -+msgstr "" -+ -+msgid "Please mount DVD %04d" -+msgstr "" -+ -+msgid "Please mount DVD %d" -+msgstr "" -+ -+msgid "Please wait. Checking DVD..." -+msgstr "" -+ -+msgid "No index-file found. Creating may take minutes. Create one?" -+msgstr "" -+ -+msgid "Please wait. Creating index-file..." -+msgstr "" -+ -+msgid "Wrong DVD!" -+msgstr "" -+ -+msgid "Permanent Timeshift" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Location" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$harddisk" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$memory" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size in memory (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Extend to harddisk if necessary" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Keep paused Buffer" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size on harddisk (MB)" -+msgstr "" -+ -+msgid "Setup.LiveBuffer$Buffer size (MB)" -+msgstr "" -diff -ruNp vdr-1.7.5/README.cmdsubmenu vdr-1.7.5-extensions/README.cmdsubmenu ---- vdr-1.7.5/README.cmdsubmenu 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/README.cmdsubmenu 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,54 @@ -+CmdSubmenu patch for VDR -+------------------------ -+ -+With this patch the commands and recording commands menus can be organised -+hierarchically. To create a submenu entry, prefix the name by one ore more "-". -+ -+ -+Standard: -+ -+description_1 : cmd_1 -+description_2 : cmd_2 -+ -+ -+A submenu with two entries: -+ -+Submenu title ... : echo "submenu" -+-description_1 : cmd_1 -+-description_2 : cmd_2 -+ -+The dummy command in the title row is necessary. -+ -+ -+* History -+ -+ 2003-10-08: Version 0.1 - Albu at vdrportal.de -+ http://vdrportal.de/board/thread.php?threadid=6319 -+ -+ 2003-10-09: Version 0.2 - Tobias Grimm <tg@e-tobi.net> -+ - Added Define CMD_SUBMENUS in Makefile -+ -+ 2004-05-28: Version 0.3 - Thomas Günther <tom@toms-cafe.de> -+ - Fixed compilation with gcc-3.3.3 -+ - Added new virtual method AddConfig in cConfig -+ - Redefining of method Add in cListBase to virtual no longer necessary -+ - Improved code in menu.c -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.3.diff -+ -+ 2004-12-20: Version 0.4 - Thomas Günther <tom@toms-cafe.de> -+ - Solved conflict with jumpplay patch 0.6 -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.4.diff -+ -+ 2006-04-22: Version 0.5 - Thomas Günther <tom@toms-cafe.de> -+ - Added version define CMDSUBMENUVERSNUM -+ - Reformated to VDR style indentions -+ - Added description in README.cmdsubmenu -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.5-1.3.47.diff -+ -+ 2006-04-23: Version 0.6 - Thomas Günther <tom@toms-cafe.de> -+ - Fixed menus with more than one level -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.6-1.3.47.diff -+ -+ 2006-05-15: Version 0.7 - Thomas Günther <tom@toms-cafe.de> -+ - Fixed build with G++ 4.1 (extra qualification) -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.7-1.4.0.diff -diff -ruNp vdr-1.7.5/README-HLCUTTER vdr-1.7.5-extensions/README-HLCUTTER ---- vdr-1.7.5/README-HLCUTTER 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/README-HLCUTTER 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,117 @@ -+ -+ VDR-HLCUTTER README -+ -+ -+Written by: Udo Richter -+Available at: http://www.udo-richter.de/vdr/patches.html#hlcutter -+ http://www.udo-richter.de/vdr/patches.en.html#hlcutter -+Contact: udo_richter@gmx.de -+ -+ -+ -+About -+----- -+ -+The hard link cutter patch changes the recording editing algorithms of VDR to -+use filesystem hard links to 'copy' recording files whenever possible to speed -+up editing recordings noticeably. -+ -+The patch has matured to be quite stable, at least I'm using it without issues. -+Nevertheless the patch is still in development and should be used with caution. -+The patch is EXPERIMENTAL for multiple /videoxx folders. The safety checks -+should prevent data loss, but you should always carefully check the results. -+ -+While editing a recording, the patch searches for any 00x.vdr files that dont -+contain editing marks and would normally be copied 1:1 unmodified to the edited -+recording. In this case the current target 00x.vdr file will be aborted, and -+the cutter process attempts to duplicate the source file as a hard link, so -+that both files share the same disk space. If this succeeds, the editing -+process fast-forwards through the duplicated file and continues normally -+beginning with the next source file. If hard linking fails, the cutter process -+continues with plain old copying. (but does not take up the aborted last file.) -+ -+After editing, the un-edited recording can be deleted as usual, the hard linked -+copies will continue to exist as the only remaining copy. -+ -+To be effective, the default 'Max. video file size (MB)' should be lowered. -+The patch lowers the smallest possible file size to 1mb. Since VDR only -+supports up to 255 files, this would limit the recording size to 255Mb or -+10 minutes, in other words: This setting is insane! -+ -+To make sure that the 255 file limit will not be reached, the patch also -+introduces "Max. recording size (GB)" with a default of 100Gb (66 hours), and -+increases the file size to 2000Mb early enough, so that 100Gb-recordings will -+fit into the 255 files. -+ -+Picking the right parameters can be tricky. The smaller the file size, the -+faster the editing process works. However, with a small file size, long -+recordings will fall back to 2000Mb files soon, that are slow on editing again. -+ -+Here are some examples: -+ -+Max file size: 100Gb 100Gb 100Gb 100Gb 100Gb 100Gb 100Gb -+Max recording size: 1Mb 10Mb 20Mb 30Mb 40Mb 50Mb 100Mb -+ -+Small files: 1-203 1-204 1-205 1-206 1-207 1-209 1-214 -+ GBytes: 0.2 2.0 4.0 6.0 8.1 10.2 20.9 -+ Hours: 0.13 1.3 2.65 4 5.4 6.8 13.9 -+ -+Big (2000mb) files: 204-255 204-255 206-255 207-255 208-255 210-255 215-255 -+ GBytes: 101.5 99.6 97.7 95.7 93.8 89.8 80.1 -+ Hours: 67 66 65 63 62 60 53 -+ -+A recording limit of 100Gb keeps plenty of reserve without blocking too much -+file numbers. And with a file size of 30-40Mb, recordings of 4-5 hours fit into -+small files completely. (depends on bit rate of course) -+ -+ -+ -+The patch must be enabled in Setup-> Recordings-> Hard Link Cutter. When -+disabled, the cutter process behaves identical to VDR's default cutter. -+ -+There's a //#define HARDLINK_TEST_ONLY in the videodir.c file that enables a -+test-mode that hard-links 00x.vdr_ files only, and continues the classic -+editing. The resulting 00x.vdr and 00x.vdr_ files should be identical. If you -+delete the un-edited recording, dont forget to delete the *.vdr_ files too, -+they will now eat real disk space. -+ -+Note: 'du' displays the disk space of hard links only on first appearance, and -+usually you will see a noticeably smaller size on the edited recording. -+ -+ -+History -+------- -+Version 0.2.0 -+ -+ New: Support for multiple /videoXX recording folders, using advanced searching -+ for matching file systems where a hard link can be created. -+ Also supports deep mounted file systems. -+ Fix: Do not fail if last mark is a cut-in. (Again.) -+ -+Version 0.1.4 -+ New: Dynamic increase of file size before running out of xxx.vdr files -+ Fix: Last edit mark is not a cut-out -+ Fix: Write error if link-copied file is smaller than allowed file size -+ Fix: Broken index/marks if cut-in is at the start of a new file -+ Fix: Clear dangeling pointer to free'd cUnbufferedFile, -+ thx to Matthias Schwarzott -+ -+Version 0.1.0 -+ Initial release -+ -+ -+ -+ -+Future plans -+------------ -+ -+Since original and edited copy share disk space, free space is wrong if one of -+them is moved to *.del. Free space should only count files with hard link -+count = 1. This still goes wrong if all copies get deleted. -+ -+ -+For more safety, the hard-linked files may be made read-only, as modifications -+to one copy will affect the other copy too. (except deleting, of course) -+ -+ -+SetBrokenLink may get lost on rare cases, this needs some more thoughts.Index: vdr-1.5.9/README.jumpplay -diff -ruNp vdr-1.7.5/README.jumpplay vdr-1.7.5-extensions/README.jumpplay ---- vdr-1.7.5/README.jumpplay 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/README.jumpplay 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,92 @@ -+JumpPlay patch for VDR -+---------------------- -+ -+This patch changes the replay behaviour for recordings that contain editing -+marks. It allows to immediately continue the replay after jumping forward to -+the next mark, and to automatically jump over the commercial break to the next -+"start" mark, if an "end" mark is reached. -+ -+The features of this patch can be turned on or off with parameters in the replay -+setup. See MANUAL for description of this parameters: "Jump&Play", "Play&Jump", -+"Pause at last mark" and "Reload marks". -+ -+ -+* History -+ -+ 2003-07-04: jumpandrun.diff - the Noad <theNoad@SoftHome.net> -+ Jump&Play -+ -+ 2003-12-06: Version 0.0 - Torsten Kunkel <vdr@tkunkel.de> -+ Play&Jump (only if progressbar is visible) -+ Setup parameters Jump&Play and Play&Jump in the replay setup -+ -+ 2004-01-20: Version 0.1 - Thomas Günther <tom@toms-cafe.de> -+ Jump&Play: -+ - fixed speed after jump -+ - fixed removing of marks -+ Play&Jump: -+ - jump only on "end" marks -+ -+ 2004-01-27: Version 0.2 - Thomas Günther <tom@toms-cafe.de> -+ Jump&Play: -+ - fixed double jump -+ Play&Jump: -+ - fixed mark detection: fuzzy detection (until 3 seconds after mark) -+ - jump without progressbar -+ - mode "progressbar only" for old behaviour -+ -+ 2004-01-31: Version 0.3 - Thomas Günther <tom@toms-cafe.de> -+ Jump&Play: -+ - fixed display frames -+ Play&Jump: -+ - fixed end of playing at last mark -+ -+ 2004-07-11: Version 0.4 - Thomas Günther <tom@toms-cafe.de> -+ Jump&Play: -+ - don't play after jump to end -+ Play&Jump: -+ - don't prevent jumping after hide or show -+ Less conflicts with other patches (Elchi/AutoPID) -+ -+ 2004-08-21: Version 0.5 - Thomas Günther <tom@toms-cafe.de> -+ Play&Jump: -+ - exact jumps, replay like edited recording (no fuzzy mark detection) -+ - jump to first mark if replay starts at the beginning -+ - check jump marks with '8' key -+ - mode "progressbar only" removed -+ Description in README.jumpplay -+ -+ 2004-12-28: Version 0.6 - Thomas Günther <tom@toms-cafe.de> -+ Adapted noad extensions (from the Noad <theNoad@SoftHome.net>) to -+ jumpplay-0.5: -+ - cyclic reloading of marks found by noad online-scan -+ - don't stop after the last mark in case of live-recordings -+ New setup parameter "Load marks interval (s)" -+ Updated description in README.jumpplay -+ -+ 2006-04-14: Version 0.7 - Thomas Günther <tom@toms-cafe.de> -+ Fixed jump to first mark (crashed with plugin extrecmenu-0.9) -+ Added version define JUMPPLAYVERSNUM -+ Added placeholders for Czech language texts -+ Cleaned up i18n entries (support only VDR >= 1.3.29) -+ Improved description of i18n placeholders - hoping for real language texts -+ -+ 2006-05-12: Version 0.8 - Thomas Günther <tom@toms-cafe.de> -+ Fixed segfault in dvbplayer thread while the replaycontrol thread is -+ reloading the marks (thanks to horchi at vdrportal.de for reporting this - -+ see http://vdrportal.de/board/thread.php?postid=450463#post450463): -+ New class cMarksReload checks the timestamp of marks.vdr in 10 seconds -+ intervals, so the marks in the threads dvbplayer and replaycontrol can be -+ reloaded independently -+ Changed setup parameter "Load marks interval (s)" to "Reload marks" -+ Updated description in README.jumpplay -+ -+ 2006-05-28: Version 0.9 - Thomas Günther <tom@toms-cafe.de> -+ New setup parameter "Pause at last mark" -+ Updated description in README.jumpplay -+ Moved parameters description to MANUAL -+ -+ 2009-03-31: Version 1.0 - Thomas Günther <tom@toms-cafe.de> -+ Play&Jump: -+ - set resume position to 0 if replay stops at the first mark -+ Added French language texts (thanks to Michaël Nival) -diff -ruNp vdr-1.7.5/README.MainMenuHooks vdr-1.7.5-extensions/README.MainMenuHooks ---- vdr-1.7.5/README.MainMenuHooks 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/README.MainMenuHooks 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,55 @@ -+This is a "patch" for the Video Disk Recorder (VDR). -+ -+* Authors: -+Tobias Grimm <vdr at e-tobi dot net> -+Martin Prochnow <nordlicht at martins-kabuff dot de> -+Frank Schmirler <vdrdev at schmirler dot de> -+Christian Wieninger <cwieninger at gmx dot de> -+ -+* Description: -+This patch allows plugins to replace the VDR mainmenus "Schedule", -+"Channels", "Timers" and "Recordings" by a different implementation. -+ -+The patch is based on a suggestion of Christian Wieninger back in 2006 -+(http://www.linuxtv.org/pipermail/vdr/2006-March/008234.html). It is -+meant to be an interim solution for VDR 1.4 until (maybe) VDR 1.5 -+introduces an official API for this purpose. -+ -+* Installation -+Change into the VDR source directory, then issue -+ patch -p1 < path/to/MainMenuHooks-v1_0.patch -+and recompile. -+ -+* Notes for plugin authors -+The following code sample shows the required plugin code for replacing -+the original Schedule menu: -+ -+bool cMyPlugin::Service(const char *Id, void *Data) -+{ -+ cOsdMenu **menu = (cOsdMenu**) Data; -+ if (MySetup.replaceSchedule && -+ strcmp(Id, "MainMenuHooksPatch-v1.0::osSchedule") == 0) { -+ if (menu) -+ *menu = (cOsdMenu*) MainMenuAction(); -+ return true; -+ } -+ return false; -+} -+ -+A plugin can replace more than one menu at a time. Simply replace the -+call to MainMenuAction() in the sample above by appropriate code. -+ -+Note that a plugin *should* offer a setup option which allows the user -+to enable or disable the replacement. "Disabled" would be a reasonable -+default setting. By testing for define MAINMENUHOOKSVERSNUM, a plugin -+can leave the setup option out at compiletime. -+ -+In case there is an internal problem when trying to open the replacement -+menu, it is safe to return true even though Data is NULL. However an -+OSD message should indicate the problem to the user. -+ -+Feel free to ship this patch along with your plugin. However if you -+think you need to modify the patch, we'd encourage you to contact the -+authors first or at least use a service id which differs in more than -+just the version number. -+ -diff -ruNp vdr-1.7.5/README.sortrec vdr-1.7.5-extensions/README.sortrec ---- vdr-1.7.5/README.sortrec 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/README.sortrec 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,48 @@ -+Sort Recordings patch for VDR -+----------------------------- -+Copyright (C) 2005 Frank99 @vdr-portal.de -+Copyright (C) 2006-2008 Christoph Haubrich -+ -+Released under the same license as VDR itself, for details see vdr.c or -+http://firefly.vdr-developer.org/patches -+ -+This patch changes the sort behaviour of the recordings menu. It is based -+on the patch available here: http://www.vdr-portal.de/board/thread.php?threadid=36031 -+Required for this patch is the liemikuutio-patch for VDR which can be found here: -+http://www.saunalahti.fi/%7Erahrenbe/vdr/patches/ -+ -+There are four sorting modes available after this patch is applied: -+ -+mode behaviour for behaviour for -+ main directory sub directories -+-------------------------------------------------------------------------- -+ 0 alphabetically if special character(*) is found alphabetically, -+ else by date -+ 1 by date if special character(*) is found alphabetically, -+ else by date -+ 2 alphabetically alphabetically -+ 3 by date by date -+ -+(*) if the name of a subdirectory ends with one of ".-$" (dot, hyphen, dollar sign) -+ it is sorted alphabetically in sort mode 0 and 1 -+ -+Sort mode 0 with none of the special characters at the end of any subdir -+corresponds to the default sorting mode of the original VDR. -+ -+The sorting mode can be switched through in the recording menu with the '0' key -+(0->1->2->3->0->...), a default for startup can be set in the setup->recordings menu. -+ -+Additionally the sort order (ascending/descending) can be toggled by the '9' key -+(which is always set to ascending after a restart) -+ -+If you like the to see subdirectories before recordings you can select to put -+directories first in the setup->recordings menu. -+ -+If you would like the sorting to ignore a leading '%' (as normally displayed before -+cutted recordings) you can achive this by setting the environment variable LC_COLLATE -+properly (eg. LC_COLLATE=de_DE@euo in runvdr for germany). -+ -+History: -+2006-08-13 v3, sortrec release for VDR 1.4.1 and liemikuutio 1.8 -+2007-01-28 v3a, moved #ifdef from optimized-rename-patch to sortrec -+2008-03-29 v3b, removed ASCII-170 and ASCII-183 to make sortrec Utf8-ready -diff -ruNp vdr-1.7.5/README.timer-info vdr-1.7.5-extensions/README.timer-info ---- vdr-1.7.5/README.timer-info 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/README.timer-info 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,53 @@ -++------------------------------------------------------------------------------+ -+| Info about the timer-info-patch by Brougs78 | -+| brougs78@gmx.net / home.pages.at/brougs78 | -++------------------------------------------------------------------------------+ -+ -+ -+README timer-info: -+------------------ -+ -+Features: -+ - Shows info, if it is possible to record an event in the timer menu of vdr. -+ For calculations the free space incl. the deleted recordings is used, -+ considering an average consumtion of 25.75 MB/min (also used by vdr itself). -+ The first column in the timer-list shows: -+ ( + ) recording will be most probably possible (enough space) -+ (+/-) recording may be possible -+ ( - ) recording will most probably fail (to less space) -+ The calculations also consider repeating timers. -+ - It is possible to deactivate the patch in the OSD-menu of VDR. -+ -+ -+HISTORY timer-info: -+------------------- -+ -+25.11.2004: v0.1 -+ - Initial release -+ -+11.01.2005: v0.1b -+ - Bugfixes for vdr-1.3.18 -+ - In the menu the free recording-time no longer includes the space of the -+ deleted recordings, because this slowed the vdr down to much. -+ -+08.07.2005: v0.1c -+ - Made the patch configurable -+ -+29.01.2006: v0.2 - Thomas Günther <tom@toms-cafe.de> -+ - Rewritten great parts for vdr-1.3.38+ -+ http://toms-cafe.de/vdr/download/vdr-timer-info-0.2-1.3.38+.diff -+ -+05.02.2006: v0.3 - Thomas Günther <tom@toms-cafe.de> -+ - Fixed refresh of timer menu in cMenuTimers::OnOff -+ - Fixed check of repeating timers -+ - Syslog debug messages can be enabled with Define DEBUG_TIMER_INFO -+ http://toms-cafe.de/vdr/download/vdr-timer-info-0.3-1.3.38+.diff -+ -+03.03.2006: v0.4 - Thomas Günther <tom@toms-cafe.de> -+ - Adapted to vdr-1.3.44 -+ - Removed setup parameter "Show timer-info" -+ http://toms-cafe.de/vdr/download/vdr-timer-info-0.4-1.3.44.diff -+ -+03.03.2006: v0.5 - Tobias Grimm <tg@e-tobi.net> -+ - Adapted to vdr-1.3.45 -+ http://toms-cafe.de/vdr/download/vdr-timer-info-0.4-1.3.45.diff -diff -ruNp vdr-1.7.5/recorder.c vdr-1.7.5-extensions/recorder.c ---- vdr-1.7.5/recorder.c 2009-03-20 16:49:02.000000000 +0100 -+++ vdr-1.7.5-extensions/recorder.c 2009-04-12 13:37:59.000000000 +0200 -@@ -22,7 +22,11 @@ - // --- cRecorder ------------------------------------------------------------- - - cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids) -+#ifdef USE_DOLBYINREC -+:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyInRecordings ? DPids : NULL, SPids) -+#else - :cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) -+#endif /* DOLBYINREC */ - ,cThread("recording") - ,recordingInfo(FileName) - { -@@ -85,7 +89,11 @@ bool cRecorder::RunningLowOnDiskSpace(vo - bool cRecorder::NextFile(void) - { - if (recordFile && frameDetector->IndependentFrame()) { // every file shall start with an independent frame -+#ifndef USE_HARDLINKCUTTER - if (fileSize > MEGABYTE(off_t(Setup.MaxVideoFileSize)) || RunningLowOnDiskSpace()) { -+#else -+ if (fileSize > fileName->MaxFileSize() || RunningLowOnDiskSpace()) { -+#endif /* HARDLINKCUTTER */ - recordFile = fileName->NextFile(); - fileSize = 0; - } -diff -ruNp vdr-1.7.5/recording.c vdr-1.7.5-extensions/recording.c ---- vdr-1.7.5/recording.c 2009-01-30 17:27:19.000000000 +0100 -+++ vdr-1.7.5-extensions/recording.c 2009-04-12 13:37:59.000000000 +0200 -@@ -8,6 +8,9 @@ - */ - - #include "recording.h" -+#ifdef USE_WAREAGLEICON -+#include "iconpatch.h" -+#endif /* WAREAGLEICON */ - #include <ctype.h> - #include <dirent.h> - #include <errno.h> -@@ -23,6 +26,17 @@ - #include "skins.h" - #include "tools.h" - #include "videodir.h" -+#ifdef USE_STREAMDEVEXT -+#include "status.h" -+#endif /* STREAMDEVEXT */ -+ -+#if defined (USE_DVDCHAPJUMP) && defined (USE_DVDARCHIVE) -+#include <assert.h> -+/* libdvdread stuff */ -+#include <dvdread/dvd_reader.h> -+#include <dvdread/ifo_types.h> -+#include <dvdread/ifo_read.h> -+#endif /* DVDCHAPJUMP & DVDARCHIVE */ - - #define SUMMARYFALLBACK - -@@ -48,6 +62,12 @@ - #endif - #define INFOFILESUFFIX "/info" - #define MARKSFILESUFFIX "/marks" -+#ifdef USE_LIEMIEXT -+#define INDEXFILESUFFIX "/index" -+#endif /* LIEMIEXT */ -+#ifdef USE_DVDARCHIVE /* ??? */ -+#define DVDARCHIVEFILENAME "/dvd.vdr" -+#endif /* DVDARCHIVE */ - - #define MINDISKSPACE 1024 // MB - -@@ -65,6 +85,13 @@ - - bool VfatFileSystem = false; - int InstanceId = 0; -+#ifdef USE_LIEMIEXT -+bool DirOrderState = false; -+#endif /* LIEMIEXT */ -+ -+#ifdef USE_DVLFRIENDLYFNAMES -+char *MakeFriendlyFilename(char **buf); -+#endif /* DVLFRIENDLYFNAMES */ - - cRecordings DeletedRecordings(true); - -@@ -599,9 +626,24 @@ cRecording::cRecording(cTimer *Timer, co - { - resume = RESUME_NOT_INITIALIZED; - titleBuffer = NULL; -+#ifdef USE_SORTRECORDS -+ for (int i = 0; i < MAXSORTMODES; i++) { -+ sortBuffer[i] = NULL; -+ lastDirsFirst[i] = -1; -+ } -+#else - sortBuffer = NULL; -+#endif /* SORTRECORDS */ - fileName = NULL; - name = NULL; -+#ifdef USE_DVDARCHIVE -+ dvdname = NULL; -+ dvdtrack = NULL; -+ dvdchapters = NULL; -+ isArchived = false; -+ isOnlyOnDvd = false; -+ dvdtype = DVD_TYPE_UNKNOWN; -+#endif /* DVDARCHIVE */ - fileSizeMB = -1; // unknown - channel = Timer->Channel()->Number(); - instanceId = InstanceId; -@@ -636,6 +678,11 @@ cRecording::cRecording(cTimer *Timer, co - break; - } - if (Timer->IsSingleEvent()) { -+#ifdef USE_DVLFRIENDLYFNAMES -+ if (Setup.UseFriendlyFNames == 1) -+ Timer -> SetFile(MakeFriendlyFilename(&name)); -+ else -+#endif /* DVLFRIENDLYFNAMES */ - Timer->SetFile(name); // this was an instant recording, so let's set the actual data - Timers.SetModified(); - } -@@ -646,6 +693,10 @@ cRecording::cRecording(cTimer *Timer, co - name = strdup(cString::sprintf("%s~%s", Timer->File(), Subtitle)); - // substitute characters that would cause problems in file names: - strreplace(name, '\n', ' '); -+#ifdef USE_DVLFRIENDLYFNAMES -+ if (Setup.UseFriendlyFNames == 1) -+ MakeFriendlyFilename(&name); -+#endif /* DVLFRIENDLYFNAMES */ - start = Timer->StartTime(); - priority = Timer->Priority(); - lifetime = Timer->Lifetime(); -@@ -668,12 +719,27 @@ cRecording::cRecording(const char *FileN - framesPerSecond = DEFAULTFRAMESPERSECOND; - deleted = 0; - titleBuffer = NULL; -+#ifdef USE_SORTRECORDS -+ for (int i = 0; i < MAXSORTMODES; i++) { -+ sortBuffer[i] = NULL; -+ lastDirsFirst[i] = -1; -+ } -+#else - sortBuffer = NULL; -+#endif /* SORTRECORDS */ - fileName = strdup(FileName); - FileName += strlen(VideoDirectory) + 1; - char *p = strrchr(FileName, '/'); - - name = NULL; -+#ifdef USE_DVDARCHIVE -+ dvdname = NULL; -+ dvdtrack = NULL; -+ dvdchapters = NULL; -+ isArchived = false; -+ isOnlyOnDvd = false; -+ dvdtype = DVD_TYPE_NOT_READ; -+#endif /* DVDARCHIVE */ - info = new cRecordingInfo; - if (p) { - time_t now = time(NULL); -@@ -762,15 +828,34 @@ cRecording::cRecording(const char *FileN - LOG_ERROR_STR(*SummaryFileName); - } - #endif -+#ifdef USE_DVDARCHIVE -+ if (CheckFileExistence("dvd.vdr")) { -+ GetDvdName(fileName); -+ isArchived = true; -+ if (!CheckFileExistence("001.vdr")) -+ isOnlyOnDvd = true; -+ } -+#endif /* DVDARCHIVE */ - } - } - - cRecording::~cRecording() - { - free(titleBuffer); -+#ifdef USE_SORTRECORDS -+ for (int i = 0; i < MAXSORTMODES; i++) { -+ free(sortBuffer[i]); -+ } -+#else - free(sortBuffer); -+#endif /* SORTRECORDS */ - free(fileName); - free(name); -+#ifdef USE_DVDARCHIVE -+ free(dvdname); -+ free(dvdtrack); -+ free(dvdchapters); -+#endif /* DVDARCHIVE */ - delete info; - } - -@@ -790,21 +875,46 @@ char *cRecording::StripEpisodeName(char - t++; - } - if (s1 && s2) -+#ifdef USE_SORTRECORDS -+ if (Setup.RecordingsSortDirsFirst) -+ *s1 = 'b'; -+ -+ if ((Setup.RecordingsSortMode <= 1 && s1 != s && !strchr(".-$ª·", *(s1 - 1))) || -+ (Setup.RecordingsSortMode == 1 && s1 == s) || -+ (Setup.RecordingsSortMode == 3)) -+#endif /* SORTRECORDS */ - memmove(s1 + 1, s2, t - s2 + 1); - return s; - } - - char *cRecording::SortName(void) const - { -+#ifdef USE_SORTRECORDS -+ if (!sortBuffer[Setup.RecordingsSortMode] || -+ lastDirsFirst[Setup.RecordingsSortMode] != Setup.RecordingsSortDirsFirst) { -+ free(sortBuffer[Setup.RecordingsSortMode]); -+ lastDirsFirst[Setup.RecordingsSortMode] = Setup.RecordingsSortDirsFirst; -+ char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory))); -+#else - if (!sortBuffer) { - char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory) + 1)); -+#endif /* SORTRECORDS */ - strreplace(s, '/', 'a'); // some locales ignore '/' when sorting - int l = strxfrm(NULL, s, 0) + 1; -+#ifdef USE_SORTRECORDS -+ sortBuffer[Setup.RecordingsSortMode] = MALLOC(char, l); -+ strxfrm(sortBuffer[Setup.RecordingsSortMode], s, l); -+#else - sortBuffer = MALLOC(char, l); - strxfrm(sortBuffer, s, l); -+#endif /* SORTRECORDS */ - free(s); - } -+#ifdef USE_SORTRECORDS -+ return sortBuffer[Setup.RecordingsSortMode]; -+#else - return sortBuffer; -+#endif /* SORTRECORDS */ - } - - int cRecording::GetResume(void) const -@@ -819,7 +929,15 @@ int cRecording::GetResume(void) const - int cRecording::Compare(const cListObject &ListObject) const - { - cRecording *r = (cRecording *)&ListObject; -+#ifdef USE_SORTRECORDS -+ return Recordings.GetSortOrder() * strcasecmp(SortName(), r->SortName()); -+#else -+#ifdef USE_LIEMIEXT -+ if (DirOrderState) -+ return strcasecmp(FileName(), r->FileName()); -+#endif /* LIEMIEXT */ - return strcasecmp(SortName(), r->SortName()); -+#endif /* USE_SORTRECORDS */ - } - - const char *cRecording::FileName(void) const -@@ -837,9 +955,359 @@ const char *cRecording::FileName(void) c - return fileName; - } - -+#ifdef USE_DVDARCHIVE -+bool cRecording::CheckFileExistence(const char* FileNameToTest, const bool useVideoDir) const -+{ -+ if (!useVideoDir || (useVideoDir && FileName())) { -+ cString filename = cString::sprintf("%s%s%s", useVideoDir ? FileName() : "", -+ useVideoDir ? "/" : "", -+ FileNameToTest); -+ struct stat statBuf; -+ if (lstat(filename, &statBuf) == -1) return false; -+ return S_ISREG(statBuf.st_mode) || S_ISLNK(statBuf.st_mode); -+ } -+ return false; -+} -+ -+bool cRecording::GetDvdName(const char* Directory) const -+{ -+ char* filename = (char*)alloca(strlen(Directory) + strlen(DVDARCHIVEFILENAME) + 1); -+ if (filename) { -+ strcpy(filename, Directory); -+ char *end = filename + strlen(filename); -+ strcpy(end, DVDARCHIVEFILENAME); -+ FILE* file; -+ if ((file = fopen(filename, "r"))) { -+ cReadLine ReadLine; -+ char* buffer = (char*)alloca(BUFSIZ); -+ if (buffer) { -+ buffer = ReadLine.Read(file); -+ if (buffer) -+ ((cRecording*)this)->dvdname = strdup(buffer); -+ else -+ ((cRecording*)this)->dvdname = NULL; -+ -+ buffer = ReadLine.Read(file); -+ if (buffer) { -+ ((cRecording*)this)->dvdtrack = strdup(buffer); -+ if (atoi(buffer) == 0) -+ ((cRecording*)this)->dvdtype = DVD_VIDEO_TYPE; -+ else -+ ((cRecording*)this)->dvdtype = DVD_VIDEO_ARCHIVE_TYPE; -+ } -+ else { -+ ((cRecording*)this)->dvdtrack = NULL; -+ ((cRecording*)this)->dvdtype = DVD_ARCHIVE_TYPE; -+ } -+ -+ fclose(file); -+ return true; -+ } -+ } -+ } -+ return false; -+} -+ -+bool cRecording::GetDvdChaptersFromDvd(int title) const -+{ -+#ifdef USE_DVDCHAPJUMP -+ cString buf; -+ -+ dvd_reader_t *dvd; -+ ifo_handle_t *ifo_file; -+ tt_srpt_t *tt_srpt; -+ ifo_handle_t *vts_file; -+ pgc_t *cur_pgc; -+ -+ dvd = DVDOpen(DVD_DEVICE); -+ if (!dvd) { -+ esyslog("DVD-ARCHIVE: Couldn't open DVD device %s!", DVD_DEVICE); -+ return false; -+ } -+ -+ /* open title manager */ -+ ifo_file = ifoOpen(dvd,0); -+ if (!ifo_file) { -+ esyslog("DVD-ARCHIVE: Can't open VMG info."); -+ DVDClose(dvd); -+ return false; -+ } -+ -+ /* read total_title */ -+ tt_srpt = ifo_file->tt_srpt; -+ -+ /* get total chapters */ -+ int title_set_nr = tt_srpt->title[title-1].title_set_nr; -+ int total_chap = tt_srpt->title[title-1].nr_of_ptts; -+ int local_title_id = tt_srpt->title[title-1].vts_ttn - 1; -+ -+ /* access title set file */ -+ vts_file = ifoOpen(dvd, title_set_nr); -+ if (!vts_file) { -+ esyslog("DVD-ARCHIVE: Can't open info file for title set %d!",title_set_nr); -+ DVDClose(dvd); -+ return false; -+ } -+ -+ /* find program chain and check programs -+ all chapters should be in the same prog chain and -+ should be numbered from 1 to <total_chap> -+ */ -+ { -+ vts_ptt_srpt_t *vts_ptt_srpt = vts_file->vts_ptt_srpt; -+ int pgc_nr = vts_ptt_srpt->title[local_title_id].ptt[0].pgcn; -+ int pg = vts_ptt_srpt->title[local_title_id].ptt[0].pgn; -+ int p; -+ -+ assert(pg==1); -+ for (p=1; p<total_chap; p++) { -+ int next_pg; -+ int this_pgc; -+ this_pgc = vts_ptt_srpt->title[local_title_id].ptt[p].pgcn; -+ assert(pgc_nr == this_pgc); -+ next_pg = vts_ptt_srpt->title[local_title_id].ptt[p].pgn; -+ assert(pg+1 == next_pg); -+ pg = next_pg; -+ } -+ -+ /* fetch program chain */ -+ cur_pgc = vts_file->vts_pgcit->pgci_srp[pgc_nr-1].pgc; -+ assert(cur_pgc->nr_of_programs == total_chap); -+ } -+ -+ /* --- main cell loop --- */ -+ { -+ pgc_program_map_t *chap_cell; -+ cell_playback_t *cell_pb; -+ int c; -+ int chap; -+ -+ /* total cells in chain */ -+ int total_cell = cur_pgc->nr_of_cells; -+ -+ /* get info */ -+ chap_cell = cur_pgc->program_map; -+ cell_pb = cur_pgc->cell_playback; -+ -+ /* loop through all cells */ -+ chap = -1; -+ int position = 0; -+ for (c=0; c<total_cell; c++) { -+ int cell_mode; -+ const char *mode; -+ -+ dvd_time_t *time = (dvd_time_t *)&cell_pb->playback_time; -+ -+ int framerate = time->frame_u>>6; -+ assert(framerate == 1 || framerate == 3); -+ int frames_per_sec = (framerate == 1) ? 25 : 30; -+ -+ /* upper 4 bits are first digit, down 4 bits are second digit */ -+ int hour = (time->hour>>4) * 10 + (time->hour&15); -+ int minute = (time->minute>>4) * 10 + (time->minute&15); -+ int second = (time->second>>4) * 10 + (time->second&15); -+ /* upper 4 bits are first digit, down 4 bits are second digit */ -+ int frame = (time->frame_u>>4&3) * 10 + (time->frame_u&15); -+ -+ int frames = ((hour * 3600) + (minute * 60) + second) * frames_per_sec + frame; -+ -+ /* this cell is the begin of a new chapter! */ -+ if (chap_cell[chap+1] == c+1) { -+ cString oldbuf = cString::sprintf("%s", *buf); -+ buf = cString::sprintf("%s%d%s", *oldbuf, position, ((chap+2) < total_chap) ? "," : ""); -+ chap++; -+ } -+ -+ /* cell_mode: 0=normal, 1=first of angle, 2=in angle, 3=last of angle */ -+ cell_mode = cell_pb->block_mode; -+ if ((cell_mode==0) || (cell_mode==1)) { -+ /* only account for normal or begin of angle cells */ -+ position += frames; -+ mode = "counted"; -+ } -+ else -+ mode = "skipped"; -+ -+ cell_pb++; -+ } -+ } -+ -+ ifoClose(ifo_file); -+ ifoClose(vts_file); -+ DVDClose(dvd); -+ -+ ((cRecording*)this)->dvdchapters = strdup(buf); -+ -+ return true; -+#else -+ return false; -+#endif /* DVDCHAPJUMP */ -+} -+ -+const char *cRecording::GetDvdChapters(void) const -+{ -+ // Read chapters from dvd -+ if (dvdtype == DVD_VIDEO_ARCHIVE_TYPE) { -+ if (dvdtrack) { -+ if (!GetDvdChaptersFromDvd(atoi(dvdtrack))) -+ ((cRecording*)this)->dvdchapters = NULL; -+ else -+ isyslog("DVD-ARCHIVE: Using following positions for chapter jumping: %s", dvdchapters); -+ return dvdchapters; -+ } -+ } -+ return NULL; -+} -+ -+int cRecording::MountDvd(void) const -+{ -+ cString cmd; -+ if (Setup.DvdSpeedLimit > 0) { -+ cmd = cString::sprintf("speedcontrol -x %d %s", Setup.DvdSpeedLimit, DVD_DEVICE); -+ SystemExec(cmd); -+ } -+ -+ cString msg; -+ if (atoi(dvdname) == 0) -+ msg = cString::sprintf(tr("Please mount %s"), dvdname); -+ else { -+ if (Setup.DvdDisplayZeros) -+ msg = cString::sprintf(tr("Please mount DVD %04d"), atoi(dvdname)); -+ else -+ msg = cString::sprintf(tr("Please mount DVD %d"), atoi(dvdname)); -+ } -+ -+ bool rep = true; -+ while (rep) { -+ if (Setup.DvdTrayMode==1 || Setup.DvdTrayMode==3) -+ cmd = cString::sprintf("umount %s; eject %s", DVD_DEVICE, DVD_DEVICE); -+ else -+ cmd = cString::sprintf("umount %s", DVD_DEVICE); -+ SystemExec(cmd); -+ -+ if (Interface->Confirm(msg, 300)) { -+ Skins.Message(mtStatus, tr("Please wait. Checking DVD...")); -+ Skins.Flush(); -+ cmd = cString::sprintf("eject -t %s; mkdir -p %s; mount -o ro -t %s %s %s", -+ DVD_DEVICE, DVD_MOUNT_PATH, -+ (dvdtrack ? "udf" : "iso9660"), -+ DVD_DEVICE, DVD_MOUNT_PATH); -+ SystemExec(cmd); -+ -+ bool correctDvd = true; -+ -+ char *olddvdname, *olddvdtrack; -+ int olddvdtype; -+ olddvdname = dvdname; -+ olddvdtrack = dvdtrack; -+ olddvdtype = dvdtype; -+ if (GetDvdName(DVD_MOUNT_PATH)) { -+ if (atoi(dvdname) != atoi(olddvdname)) correctDvd = false; -+ } -+ ((cRecording*)this)->dvdname = olddvdname; -+ ((cRecording*)this)->dvdtrack = olddvdtrack; -+ ((cRecording*)this)->dvdtype = olddvdtype; -+ -+ if (correctDvd) { -+ if (dvdtrack == NULL) { -+ // Archived DVD in VDR format -+ char fn[BUFSIZ]; -+ strcpy(fn, FileName()); -+ char *p = strrchr(fn, '/'); -+ cmd = cString::sprintf("find '%s' -name '%s'", DVD_MOUNT_PATH, p+1); -+ } -+ else { -+ // Either archived DVD in DVD-Video format or DVD-Video which -+ // should be played with the DVD plugin -+ cmd = cString::sprintf("find '%s' -iname 'VIDEO_TS'", DVD_MOUNT_PATH); -+ } -+ -+ cReadLine pipe; -+ FILE* file; -+ char *dirname = NULL; -+ if ((file = popen(cmd, "r")) != (FILE *)NULL) { -+ if ((dirname = pipe.Read(file)) != NULL) { -+ pclose(file); -+ if (dvdtrack != NULL && atoi(dvdtrack) == 0) { -+ // It is a valid Video-DVD and DVD plugin can be started -+ return MOUNT_DVD_LAUNCH_DVD_PLUGIN; -+ } -+ else { -+ // It is a valid Archive-DVD or an archived Video-DVD -+ // and the links can now be established -+ cString srcFn; -+ int n = 1; -+ -+ do { -+ if (dvdtrack == NULL) -+ srcFn = cString::sprintf("%s/%03d.vdr", dirname, n); -+ else -+ srcFn = cString::sprintf("%s/VTS_%02d_%d.VOB", dirname, atoi(dvdtrack), n); -+ -+ if (!access(srcFn, R_OK)) { -+ cmd = cString::sprintf("ln -sf '%s' '%s/%03d.vdr'", *srcFn, FileName(), n); -+ SystemExec(cmd); -+ isyslog("DVD-ARCHIVE: Linking %s/%03d.vdr -> %s", FileName(), n, *srcFn); -+ } -+ else -+ break; -+ } while ( ++n < 999); -+ -+ if (!CheckFileExistence("index.vdr")) { -+ if (dvdtrack == NULL) -+ srcFn = cString::sprintf("%s/index.vdr", dirname); -+ else -+ srcFn = cString::sprintf("%s/index_%02d.vdr", dirname, atoi(dvdtrack)); -+ -+ if (!CheckFileExistence(srcFn, false)) { -+ msg = cString::sprintf(tr("No index-file found. Creating may take minutes. Create one?")); -+ if (Interface->Confirm(msg, 300)) { -+ Skins.Message(mtStatus, tr("Please wait. Creating index-file...")); -+ cmd = cString::sprintf("speedcontrol -x 999 %s; cd %s && genindex &", DVD_DEVICE, FileName()); -+ SystemExec(cmd); -+ return MOUNT_DVD_ABORT; -+ } -+ } -+ else { -+ cmd = cString::sprintf("ln -sf '%s' '%s/index.vdr'", *srcFn, FileName()); -+ SystemExec(cmd); -+ isyslog("DVD-ARCHIVE: Linking %s/index.vdr -> %s", FileName(), *srcFn); -+ } -+ } -+ return MOUNT_DVD_REPLAY; -+ } -+ } -+ else { -+ Skins.Message(mtError, tr("Wrong DVD!"), 3); -+ Skins.Flush(); -+ } -+ } -+ pclose(file); -+ } -+ else { -+ Skins.Message(mtError, tr("Wrong DVD!"), 3); -+ Skins.Flush(); -+ } -+ } -+ else { -+ rep = false; -+ } -+ } -+ return MOUNT_DVD_ABORT; -+} -+ -+#endif /* DVDARCHIVE */ -+#ifdef USE_LIEMIEXT -+const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level, bool Original) const -+#else - const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) const -+#endif /* LIEMIEXT */ - { -+#ifdef USE_WAREAGLEICON -+ const char *New = NewIndicator && IsNew() ? Setup.WarEagleIcons ? IsLangUtf8() ? ICON_NEW_UTF8 : ICON_NEW : "*" : " "; -+#else - char New = NewIndicator && IsNew() ? '*' : ' '; -+#endif /* WAREAGLEICON */ - free(titleBuffer); - titleBuffer = NULL; - if (Level < 0 || Level == HierarchyLevels()) { -@@ -850,7 +1318,14 @@ const char *cRecording::Title(char Delim - s++; - else - s = name; -+#ifdef USE_LIEMIEXT -+ if (Original) { -+#endif /* LIEMIEXT */ -+#ifdef USE_WAREAGLEICON -+ titleBuffer = strdup(cString::sprintf("%02d.%02d.%02d%c%02d:%02d%s%c%s", -+#else - titleBuffer = strdup(cString::sprintf("%02d.%02d.%02d%c%02d:%02d%c%c%s", -+#endif /* WAREAGLEICON */ - t->tm_mday, - t->tm_mon + 1, - t->tm_year % 100, -@@ -860,6 +1335,92 @@ const char *cRecording::Title(char Delim - New, - Delimiter, - s)); -+#ifdef USE_LIEMIEXT -+ } -+ else { -+ cString RecLength("---"); -+ if (Setup.ShowRecLength && FileName()) { -+ cString filename = cString::sprintf("%s%s", FileName(), INDEXFILESUFFIX); -+ if (*filename) { -+ if (access(filename, R_OK) == 0) { -+ struct stat buf; -+ if (stat(filename, &buf) == 0) { -+ struct tIndex { int offset; uchar type; uchar number; short reserved; }; -+ int delta = buf.st_size % sizeof(tIndex); -+ if (delta) { -+ delta = sizeof(tIndex) - delta; -+ esyslog("ERROR: invalid file size (%ld) in '%s'", (long int)buf.st_size, *filename); -+ } -+ RecLength = cString::sprintf("%ld'", (long int)(buf.st_size + delta) / sizeof(tIndex) / SecondsToFrames(60)); -+ } -+ } -+ } -+ } -+#endif /* LIEMIEXT */ -+#ifdef USE_DVDARCHIVE -+#ifdef USE_WAREAGLEICON -+ if (isArchived && !isOnlyOnDvd) New = Setup.WarEagleIcons ? IsLangUtf8() ? ICON_DVD_UTF8 : ICON_DVD : "~"; -+#else -+ if (isArchived && !isOnlyOnDvd) New = '~'; -+#endif /* WAREAGLEICON */ -+ -+ if (isOnlyOnDvd && Setup.DvdDisplayMode >= 1) { -+ char oldLength[21]; -+ -+ if (strrchr(RecLength, '\'')) -+ sprintf(oldLength,"%s", *RecLength); -+ else -+ oldLength[0] = 0; -+ -+ if (dvdname) { -+ if (atoi(dvdname) != 0) { -+ cString tmp; -+ if (Setup.DvdDisplayZeros) -+ tmp = cString::sprintf("%04d", atoi(dvdname)); -+ else { -+ int num = atoi(dvdname); -+ bool displaySpace = !(Setup.DvdDisplayMode == 1 && oldLength[0] != 0); -+ // ugly hack to have 2 spaces instead of one 0 for each place -+ tmp = cString::sprintf("%s%s%s%d", displaySpace && (num < 1000) ? " " : "", -+ displaySpace && (num < 100) ? " " : "", -+ displaySpace && (num < 10) ? " " : "", -+ num); -+ } -+ ((cRecording*)this)->dvdname = strdup(tmp); -+ } -+ } -+ -+ RecLength = strdup(cString::sprintf("%s%s%s%s", (Setup.ShowRecLength && (Setup.DvdDisplayMode == 1) && (oldLength[0] != 0)) ? oldLength : "", -+ (dvdname && isArchived && isOnlyOnDvd && Setup.ShowRecLength && (Setup.DvdDisplayMode == 1) && (oldLength[0] != 0)) ? " / " : "", -+ (dvdname && isArchived && isOnlyOnDvd) ? dvdname : "", -+ (dvdname && isArchived && isOnlyOnDvd) ? " " : "" -+ )); -+ } -+#endif /* DVDARCHIVE */ -+#ifdef USE_LIEMIEXT -+ cString RecDate = cString::sprintf("%02d.%02d.%02d", t->tm_mday, t->tm_mon + 1, t->tm_year % 100); -+ cString RecTime = cString::sprintf("%02d:%02d", t->tm_hour, t->tm_min); -+ cString RecDelimiter = cString::sprintf("%c", Delimiter); -+#ifdef USE_WAREAGLEICON -+ titleBuffer = strdup(cString::sprintf("%s%s%s%s%s%s%s%s", -+#else -+ titleBuffer = strdup(cString::sprintf("%s%s%s%c%s%s%s%s", -+#endif /* WAREAGLEICON */ -+ (Setup.ShowRecDate ? *RecDate : ""), -+ (Setup.ShowRecDate && Setup.ShowRecTime ? *RecDelimiter : ""), -+ (Setup.ShowRecTime ? *RecTime : ""), -+ New, -+ (Setup.ShowRecTime || Setup.ShowRecDate ? *RecDelimiter : ""), -+#ifdef USE_DVDARCHIVE -+ (((Setup.ShowRecLength + Setup.DvdDisplayMode) > 0) ? *RecLength : ""), -+ (((Setup.ShowRecLength + Setup.DvdDisplayMode) > 0) ? *RecDelimiter : ""), -+#else -+ (Setup.ShowRecLength ? *RecLength : ""), -+ (Setup.ShowRecLength ? *RecDelimiter : ""), -+#endif /* DVDARCHIVE */ -+ s)); -+ } -+#endif /* LIEMIEXT */ - // let's not display a trailing '~': - if (!NewIndicator) - stripspace(titleBuffer); -@@ -888,6 +1449,17 @@ const char *cRecording::Title(char Delim - return titleBuffer; - } - -+#ifdef USE_CUTTIME -+void cRecording::SetStartTime(time_t Start) -+{ -+ start = Start; -+ if (fileName) { -+ free(fileName); -+ fileName = NULL; -+ } -+} -+#endif /* CUTTIME */ -+ - const char *cRecording::PrefixFileName(char Prefix) - { - cString p = PrefixVideoFileName(FileName(), Prefix); -@@ -941,10 +1513,20 @@ bool cRecording::Delete(void) - // the new name already exists, so let's remove that one first: - isyslog("removing recording '%s'", NewName); - RemoveVideoFile(NewName); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgRecordingChange(this, scDel); -+#endif /* STREAMDEVEXT */ - } - isyslog("deleting recording '%s'", FileName()); -+#ifdef USE_STREAMDEVEXT -+ if (access(FileName(), F_OK) == 0) { -+ result = RenameVideoFile(FileName(), NewName); -+ cStatus::MsgRecordingChange(this, scDel); -+ } -+#else - if (access(FileName(), F_OK) == 0) - result = RenameVideoFile(FileName(), NewName); -+#endif /* STREAMDEVEXT */ - else { - isyslog("recording '%s' vanished", FileName()); - result = true; // well, we were going to delete it, anyway -@@ -962,7 +1544,13 @@ bool cRecording::Remove(void) - return false; - } - isyslog("removing recording %s", FileName()); -+#ifdef USE_STREAMDEVEXT -+ bool ret = RemoveVideoFile(FileName()); -+ cStatus::MsgRecordingChange(this, scDel); -+ return ret; -+#else - return RemoveVideoFile(FileName()); -+#endif /* STREAMDEVEXT */ - } - - bool cRecording::Undelete(void) -@@ -979,8 +1567,15 @@ bool cRecording::Undelete(void) - } - else { - isyslog("undeleting recording '%s'", FileName()); -+#ifdef USE_STREAMDEVEXT -+ if (access(FileName(), F_OK) == 0) { -+ result = RenameVideoFile(FileName(), NewName); -+ cStatus::MsgRecordingChange(this, scAdd); -+ } -+#else - if (access(FileName(), F_OK) == 0) - result = RenameVideoFile(FileName(), NewName); -+#endif /* STREAMDEVEXT */ - else { - isyslog("deleted recording '%s' vanished", FileName()); - result = false; -@@ -996,6 +1591,54 @@ void cRecording::ResetResume(void) const - resume = RESUME_NOT_INITIALIZED; - } - -+#ifdef USE_LIEMIEXT -+bool cRecording::Rename(const char *newName) -+{ -+ bool result = false; -+ struct tm tm_r; -+ struct tm *t = localtime_r(&start, &tm_r); -+ char *localNewName = ExchangeChars(strdup(newName), true); -+ const char *fmt = isPesRecording ? NAMEFORMATPES : NAMEFORMATTS; -+ int ch = isPesRecording ? priority : channel; -+ int ri = isPesRecording ? lifetime : instanceId; -+ char *newFileName = strdup(cString::sprintf(fmt, VideoDirectory, localNewName, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, ch, ri)); -+ free(localNewName); -+ if (strcmp(FileName(), newFileName)) { -+ if (access(newFileName, F_OK) == 0) { -+ isyslog("recording %s already exists", newFileName); -+ } -+ else { -+ isyslog("renaming recording %s to %s", FileName(), newFileName); -+ result = MakeDirs(newFileName, true); -+ if (result) -+ result = RenameVideoFile(FileName(), newFileName); -+ if (result) { -+ free(fileName); -+ fileName = strdup(newFileName); -+ free(name); -+ name = strdup(newName); -+#ifdef USE_SORTRECORDS -+ for (int i = 0; i < MAXSORTMODES; i++) { -+ free(sortBuffer[i]); -+ sortBuffer[i] = NULL; -+ } -+#else -+ free(sortBuffer); -+ sortBuffer = NULL; -+#endif /* SORTRECORDS */ -+ free(titleBuffer); -+ titleBuffer = NULL; -+ } -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgRecordingChange(this, scMod); -+#endif /* STREAMDEVEXT */ -+ } -+ } -+ free(newFileName); -+ return result; -+} -+#endif /* LIEMIEXT */ -+ - // --- cRecordings ----------------------------------------------------------- - - cRecordings Recordings; -@@ -1008,6 +1651,9 @@ cRecordings::cRecordings(bool Deleted) - deleted = Deleted; - lastUpdate = 0; - state = 0; -+#ifdef USE_SORTRECORDS -+ SortOrder = 1; -+#endif /* SORTRECORDS */ - } - - cRecordings::~cRecordings() -@@ -1294,14 +1940,70 @@ cMark *cMarks::GetNext(int Position) - return NULL; - } - -+#ifdef USE_JUMPPLAY -+// --- cMarksReload ---------------------------------------------------------- -+ -+#define MARKS_RELOAD_MS 10000 -+ -+time_t cMarksReload::lastsavetime = 0; -+ -+cMarksReload::cMarksReload(const char *RecordingFileName) -+:recDir(RecordingFileName) -+{ -+ struct stat sbuf; -+ if (Load(recDir) && stat(FileName(), &sbuf) == 0) -+ lastmodtime = sbuf.st_mtime; -+ else -+ lastmodtime = 0; -+ nextreload.Set(MARKS_RELOAD_MS - cTimeMs::Now() % MARKS_RELOAD_MS); -+} -+ -+bool cMarksReload::Reload(void) -+{ -+ // Check the timestamp of marks.vdr in 10 seconds intervals -+ // Independent but synchronized reloading of marks in two threads -+ if ((Setup.ReloadMarks && nextreload.TimedOut()) || lastsavetime > lastmodtime) { -+ nextreload.Set(MARKS_RELOAD_MS - cTimeMs::Now() % MARKS_RELOAD_MS); -+ struct stat sbuf; -+ if (stat(FileName(), &sbuf) == 0 && sbuf.st_mtime != lastmodtime) { -+ lastmodtime = sbuf.st_mtime; -+ if (Load(recDir)) -+ return true; -+ } -+ } -+ return false; -+} -+ -+bool cMarksReload::Save(void) -+{ -+ bool ok = cMarks::Save(); -+ struct stat sbuf; -+ if (ok && stat(FileName(), &sbuf) == 0) -+ lastsavetime = lastmodtime = sbuf.st_mtime; -+ return ok; -+} -+#endif /* JUMPPLAY */ -+ - // --- cRecordingUserCommand ------------------------------------------------- - - const char *cRecordingUserCommand::command = NULL; - -+#ifdef USE_DVLRECSCRIPTADDON -+void cRecordingUserCommand::InvokeCommand(const char *State, const char *RecordingFileName, char *chanName) -+#else - void cRecordingUserCommand::InvokeCommand(const char *State, const char *RecordingFileName) -+#endif /* DVLRECSCRIPTADDON */ - { - if (command) { -+#ifdef USE_DVLRECSCRIPTADDON -+ cString cmd; -+ if (chanName != NULL) -+ cmd = cString::sprintf("%s %s \"%s\" \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$"), chanName); -+ else -+ cmd = cString::sprintf("%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$")); -+#else - cString cmd = cString::sprintf("%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$")); -+#endif /* DVLRECSCRIPTADDON */ - isyslog("executing '%s'", *cmd); - SystemExec(cmd); - } -@@ -1309,7 +2011,9 @@ void cRecordingUserCommand::InvokeComman - - // --- cIndexFile ------------------------------------------------------------ - -+#ifndef USE_LIEMIEXT - #define INDEXFILESUFFIX "/index" -+#endif /* LIEMIEXT */ - - // The number of frames to stay off the end in case of time shift: - #define INDEXSAFETYLIMIT 150 // frames -@@ -1625,6 +2329,48 @@ cFileName::cFileName(const char *FileNam - cFileName::~cFileName() - { - Close(); -+#ifdef USE_DVDARCHIVE -+ -+ char fn[BUFSIZ]; -+ strcpy(fn, fileName); -+ -+ char *p; -+ if((p = strrchr(fn, '/'))) { -+ p[0] = 0; -+ } -+ -+ cString cmd = cString::sprintf("find \"%s\" -type l -lname \"%s/*\"", fn, DVD_MOUNT_PATH); -+ -+ bool isOnDvd = false; -+ -+ cReadLine pipe; -+ FILE* file; -+ char* filename; -+ if ((file = popen(cmd, "r")) != (FILE *)NULL) { -+ while ((filename = pipe.Read(file)) != NULL) { -+ isOnDvd = true; -+ unlink(filename); -+ isyslog("DVD-ARCHIVE: Deleting %s", filename); -+ } -+ pclose(file); -+ } -+ -+ if (isOnDvd) { -+ if (Setup.DvdTrayMode==2 || Setup.DvdTrayMode==3) -+ cmd = cString::sprintf("umount %s; eject %s", DVD_DEVICE, DVD_DEVICE); -+ else -+ cmd = cString::sprintf("umount %s", DVD_DEVICE); -+ -+ SystemExec(cmd); -+ -+ if (Setup.DvdSpeedLimit > 0) { -+ cmd = cString::sprintf("speedcontrol -x 999 %s", DVD_DEVICE); -+ SystemExec(cmd); -+ } -+ } -+ -+#endif /* DVDARCHIVE */ -+ - free(fileName); - } - -@@ -1703,6 +2449,22 @@ cUnbufferedFile *cFileName::SetOffset(in - return NULL; - } - -+#ifdef USE_HARDLINKCUTTER -+off_t cFileName::MaxFileSize() { -+ const int maxVideoFileSize = isPesRecording ? MAXVIDEOFILESIZEPES : MAXVIDEOFILESIZETS; -+ const int setupMaxVideoFileSize = min(maxVideoFileSize, Setup.MaxVideoFileSize); -+ const int maxFileNumber = isPesRecording ? 255 : 65535; -+ -+ const off_t smallFiles = (maxFileNumber * off_t(maxVideoFileSize) - 1024 * Setup.MaxRecordingSize) -+ / max(maxVideoFileSize - setupMaxVideoFileSize, 1); -+ -+ if (fileNumber <= smallFiles) -+ return MEGABYTE(off_t(setupMaxVideoFileSize)); -+ -+ return MEGABYTE(off_t(maxVideoFileSize)); -+} -+#endif /* HARDLINKCUTTER */ -+ - cUnbufferedFile *cFileName::NextFile(void) - { - return SetOffset(fileNumber + 1); -@@ -1754,3 +2516,113 @@ int ReadFrame(cUnbufferedFile *f, uchar - LOG_ERROR; - return r; - } -+ -+#ifdef USE_DVLFRIENDLYFNAMES -+char *MakeFriendlyFilename(char **buf) -+{ -+ char *b, *x, *y; -+ -+ if (buf == NULL || *buf == NULL) -+ return(NULL); -+ -+ b = (char *)malloc(strlen(*buf) * 2); -+ x = *buf; -+ y = b; -+ -+ while (*x != 0) { -+ switch (*x) { -+ case 'Ä': -+ *y = 'A'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'ä': -+ *y = 'a'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'Ö': -+ *y = 'O'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'ö': -+ *y = 'o'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'Ü': -+ *y = 'U'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'ü': -+ *y = 'u'; -+ y++; -+ *y = 'e'; -+ y++; x++; -+ break; -+ -+ case 'ß': -+ *y = 's'; -+ y++; -+ *y = 's'; -+ y++; x++; -+ break; -+ -+ // chars to replace -+ case ':': -+ case ';': -+ case '?': -+ case ' ': -+ case '\t': -+ *y = '_'; -+ y++; x++; -+ break; -+ -+ // chars to simply strip -+ case '\"': -+ case '*': -+ case '{': -+ case '}': -+ case '[': -+ case ']': -+ case '=': -+ case '<': -+ case '>': -+ case '#': -+ case '`': -+ case '|': -+ case '\\': -+ case '\n': -+ case '\r': -+ x++; -+ break; -+ -+ default: -+ *y = *x; -+ y++; x++; -+ break; -+ } -+ } -+ *y = 0; -+ -+ x = strdup(b); -+ free(b); -+ -+ free(*buf); -+ *buf = x; -+ -+ return(*buf); -+} -+#endif /* DVLFRIENDLYFNAMES */ -diff -ruNp vdr-1.7.5/recording.h vdr-1.7.5-extensions/recording.h ---- vdr-1.7.5/recording.h 2009-02-28 11:50:12.000000000 +0100 -+++ vdr-1.7.5-extensions/recording.h 2009-04-12 13:37:59.000000000 +0200 -@@ -20,6 +20,9 @@ - - extern bool VfatFileSystem; - extern int InstanceId; -+#ifdef USE_LIEMIEXT -+extern bool DirOrderState; -+#endif /* LIEMIEXT */ - - void RemoveDeletedRecordings(void); - void AssertFreeDiskSpace(int Priority = 0, bool Force = false); -@@ -63,6 +66,9 @@ public: - const cEvent *GetEvent(void) const { return event; } - const char *Title(void) const { return event->Title(); } - const char *ShortText(void) const { return event->ShortText(); } -+#ifdef USE_GRAPHTFT -+ tEventID EventID(void) const { return event->EventID(); } -+#endif /* GRAPHTFT */ - const char *Description(void) const { return event->Description(); } - const cComponents *Components(void) const { return event->Components(); } - const char *Aux(void) const { return aux; } -@@ -74,12 +80,36 @@ public: - bool Write(void) const; - }; - -+#ifdef USE_SORTRECORDS -+#define SORTRECORDINGSVERSNUM 3 -+#define MAXSORTMODES 4 -+#endif /* SORTRECORDS */ -+ -+#ifdef USE_DVDARCHIVE -+#define MOUNT_DVD_ABORT 0 -+#define MOUNT_DVD_REPLAY 1 -+#define MOUNT_DVD_LAUNCH_DVD_PLUGIN 2 -+#define DVD_DEVICE "/dev/cdrom" -+#define DVD_MOUNT_PATH "/tmp/vdr.dvd" -+ -+#define DVD_TYPE_UNKNOWN -1 -+#define DVD_TYPE_NOT_READ 0 -+#define DVD_VIDEO_TYPE 1 -+#define DVD_ARCHIVE_TYPE 2 -+#define DVD_VIDEO_ARCHIVE_TYPE 3 -+#endif /* DVDARCHIVE */ -+ - class cRecording : public cListObject { - friend class cRecordings; - private: - mutable int resume; - mutable char *titleBuffer; -+#ifdef USE_SORTRECORDS -+ mutable char *sortBuffer[MAXSORTMODES]; -+ mutable char lastDirsFirst[MAXSORTMODES]; -+#else - mutable char *sortBuffer; -+#endif /* SORTRECORDS */ - mutable char *fileName; - mutable char *name; - mutable int fileSizeMB; -@@ -88,6 +118,15 @@ private: - bool isPesRecording; - double framesPerSecond; - cRecordingInfo *info; -+#ifdef USE_DVDARCHIVE -+ char *dvdname; -+ char *dvdtrack; -+ char *dvdchapters; -+ bool isArchived; -+ bool isOnlyOnDvd; -+ int dvdtype; -+ bool GetDvdChaptersFromDvd(int title) const; -+#endif /* DVDARCHIVE */ - cRecording(const cRecording&); // can't copy cRecording - cRecording &operator=(const cRecording &); // can't assign cRecording - static char *StripEpisodeName(char *s); -@@ -104,8 +143,23 @@ public: - virtual int Compare(const cListObject &ListObject) const; - const char *Name(void) const { return name; } - const char *FileName(void) const; -+#ifdef USE_DVDARCHIVE -+ bool CheckFileExistence(const char* FileNameToTest, const bool useVideoDir = true) const; -+ bool GetDvdName(const char* Directory) const; -+ bool IsOnlyOnDvd(void) const { return isOnlyOnDvd; } -+ int MountDvd(void) const; -+ int GetDvdType(void) const { return dvdtype; } -+ const char *GetDvdChapters(void) const ; -+#endif /* DVDARCHIVE */ -+#ifdef USE_LIEMIEXT -+ const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1, bool Original = true) const; -+#else - const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1) const; -+#endif /* LIEMIEXT */ - const cRecordingInfo *Info(void) const { return info; } -+#ifdef USE_CUTTIME -+ void SetStartTime(time_t Start); -+#endif /* CUTTIME */ - const char *PrefixFileName(char Prefix); - int HierarchyLevels(void) const; - void ResetResume(void) const; -@@ -124,6 +178,11 @@ public: - // Changes the file name so that it will be visible in the "Recordings" menu again and - // not processed by cRemoveDeletedRecordingsThread. - // Returns false in case of error -+#ifdef USE_LIEMIEXT -+ bool Rename(const char *newName); -+ // Changes the file name -+ // Returns false in case of error -+#endif /* LIEMIEXT */ - }; - - class cRecordings : public cList<cRecording>, public cThread { -@@ -132,6 +191,9 @@ private: - bool deleted; - time_t lastUpdate; - int state; -+#ifdef USE_SORTRECORDS -+ int SortOrder; -+#endif /* SORTRECORDS */ - const char *UpdateFileName(void); - void Refresh(bool Foreground = false); - void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0); -@@ -162,6 +224,10 @@ public: - void AddByName(const char *FileName, bool TriggerUpdate = true); - void DelByName(const char *FileName); - int TotalFileSizeMB(void); ///< Only for deleted recordings! -+#ifdef USE_SORTRECORDS -+ void ToggleSortOrder(void) { SortOrder *= -1; } -+ const int GetSortOrder(void) { return SortOrder; } -+#endif /* SORTRECORDS */ - }; - - extern cRecordings Recordings; -@@ -194,6 +260,20 @@ public: - cMark *GetNext(int Position); - }; - -+#ifdef USE_JUMPPLAY -+class cMarksReload : public cMarks { -+private: -+ cString recDir; -+ cTimeMs nextreload; -+ time_t lastmodtime; -+ static time_t lastsavetime; -+public: -+ cMarksReload(const char *RecordingFileName); -+ bool Reload(void); -+ bool Save(void); -+ }; -+#endif /* JUMPPLAY */ -+ - #define RUC_BEFORERECORDING "before" - #define RUC_AFTERRECORDING "after" - #define RUC_EDITEDRECORDING "edited" -@@ -202,8 +282,15 @@ class cRecordingUserCommand { - private: - static const char *command; - public: -+#ifdef USE_DELTIMESHIFTREC -+ static const char *GetCommand(void) { return command; } -+#endif /* DELTIMESHIFTREC */ - static void SetCommand(const char *Command) { command = Command; } -+#ifdef USE_DVLRECSCRIPTADDON -+ static void InvokeCommand(const char *State, const char *RecordingFileName, char *chanName = NULL); -+#else - static void InvokeCommand(const char *State, const char *RecordingFileName); -+#endif /* DVLRECSCRIPTADDON */ - }; - - // The maximum size of a single frame (up to HDTV 1920x1080): -@@ -216,9 +303,23 @@ public: - // before the next independent frame, to have a complete Group Of Pictures): - #define MAXVIDEOFILESIZETS 1048570 // MB - #define MAXVIDEOFILESIZEPES 2000 // MB -+#ifdef USE_HARDLINKCUTTER -+#define MINVIDEOFILESIZE 1 // MB -+#else - #define MINVIDEOFILESIZE 100 // MB -+#endif /* HARDLINKCUTTER */ - #define MAXVIDEOFILESIZEDEFAULT MAXVIDEOFILESIZEPES - -+#ifdef USE_HARDLINKCUTTER -+#define MINRECORDINGSIZE 25 // GB -+#define MAXRECORDINGSIZE 500 // GB -+#define DEFAULTRECORDINGSIZE 100 // GB -+// Dynamic recording size: -+// Keep recording file size at Setup.MaxVideoFileSize for as long as possible, -+// but switch to MAXVIDEOFILESIZE early enough, so that Setup.MaxRecordingSize -+// will be reached, before recording to file 255.vdr -+#endif /* HARDLINKCUTTER */ -+ - struct tIndexTs; - - class cIndexFile { -@@ -233,6 +334,9 @@ private: - void ConvertFromPes(tIndexTs *IndexTs, int Count); - void ConvertToPes(tIndexTs *IndexTs, int Count); - bool CatchUp(int Index = -1); -+#ifdef USE_DVDARCHIVE -+ bool isOnDVD; -+#endif /* DVDARCHIVE */ - public: - cIndexFile(const char *FileName, bool Record, bool IsPesRecording = false); - ~cIndexFile(); -@@ -263,6 +367,9 @@ public: - cUnbufferedFile *Open(void); - void Close(void); - cUnbufferedFile *SetOffset(int Number, off_t Offset = 0); -+#ifdef USE_HARDLINKCUTTER -+ off_t MaxFileSize(); // Dynamic file size for this file -+#endif /* HARDLINKCUTTER */ - cUnbufferedFile *NextFile(void); - }; - -diff -ruNp vdr-1.7.5/skinclassic.c vdr-1.7.5-extensions/skinclassic.c ---- vdr-1.7.5/skinclassic.c 2008-02-23 11:31:58.000000000 +0100 -+++ vdr-1.7.5-extensions/skinclassic.c 2009-04-12 13:37:59.000000000 +0200 -@@ -314,8 +314,52 @@ void cSkinClassicDisplayMenu::SetItem(co - for (int i = 0; i < MaxTabs; i++) { - const char *s = GetTabbedText(Text, i); - if (s) { -+#ifdef USE_LIEMIEXT -+ bool isprogressbar = false; -+ int now = 0, total = 0; -+ // check if progress bar: "[||||||| ]" -+ if ((strlen(s) > 5 && s[0] == '[' && s[strlen(s) - 1] == ']')) { -+ const char *p = s + 1; -+ // update status -+ isprogressbar = true; -+ for (; *p != ']'; ++p) { -+ // check if progressbar characters -+ if (*p == ' ' || *p == '|') { -+ // update counters -+ ++total; -+ if (*p == '|') -+ ++now; -+ } -+ else { -+ // wrong character detected; not a progressbar -+ isprogressbar = false; -+ break; -+ } -+ } -+ } -+ int xt = x0 + Tab(i); -+ if (Setup.ShowProgressBar && isprogressbar) { -+ // define x coordinates of progressbar -+ int px0 = xt; -+ int px1 = (Tab(i + 1)?Tab(i+1):x1) - 5; -+ int px = px0 + max((int)((float) now * (float) (px1 - px0) / (float) total), 1); -+ // define y coordinates of progressbar -+ int py0 = y + 4; -+ int py1 = y + lineHeight - 4; -+ // draw background -+ osd->DrawRectangle(px0, y, (Tab(i + 1)?Tab(i+1):x1) - 1, y + lineHeight - 1, ColorBg); -+ // draw progressbar -+ osd->DrawRectangle(px0, py0, px, py1, ColorFg); -+ osd->DrawRectangle(px + 1, py0, px1, py0 + 1, ColorFg); -+ osd->DrawRectangle(px + 1, py1 - 1, px1, py1, ColorFg); -+ osd->DrawRectangle(px1 - 1, py0, px1, py1, ColorFg); -+ } -+ else -+ osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x2 - xt); -+#else - int xt = x0 + Tab(i); - osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x2 - xt); -+#endif /* LIEMIEXT */ - } - if (!Tab(i + 1)) - break; -diff -ruNp vdr-1.7.5/skinsttng.c vdr-1.7.5-extensions/skinsttng.c ---- vdr-1.7.5/skinsttng.c 2008-02-23 11:23:44.000000000 +0100 -+++ vdr-1.7.5-extensions/skinsttng.c 2009-04-12 13:37:59.000000000 +0200 -@@ -558,8 +558,52 @@ void cSkinSTTNGDisplayMenu::SetItem(cons - for (int i = 0; i < MaxTabs; i++) { - const char *s = GetTabbedText(Text, i); - if (s) { -+#ifdef USE_LIEMIEXT -+ bool isprogressbar = false; -+ int now = 0, total = 0; -+ // check if progress bar: "[||||||| ]" -+ if ((strlen(s) > 5 && s[0] == '[' && s[strlen(s) - 1] == ']')) { -+ const char *p = s + 1; -+ // update status -+ isprogressbar = true; -+ for (; *p != ']'; ++p) { -+ // check if progressbar characters -+ if (*p == ' ' || *p == '|') { -+ // update counters -+ ++total; -+ if (*p == '|') -+ ++now; -+ } -+ else { -+ // wrong character detected; not a progressbar -+ isprogressbar = false; -+ break; -+ } -+ } -+ } -+ int xt = x3 + 5 + Tab(i); -+ if (Setup.ShowProgressBar && isprogressbar) { -+ // define x coordinates of progressbar -+ int px0 = xt; -+ int px1 = x3 + (Tab(i + 1)?Tab(i + 1):x4-x3-5) - 1; -+ int px = px0 + max((int)((float) now * (float) (px1 - px0) / (float) total), 1); -+ // define y coordinates of progressbar -+ int py0 = y + 4; -+ int py1 = y + lineHeight - 4; -+ // draw background -+ osd->DrawRectangle(px0, y, (Tab(i + 1)?Tab(i + 1):x4-x3-5) - 1, y + lineHeight - 1, ColorBg); -+ // draw progressbar -+ osd->DrawRectangle(px0, py0, px, py1, ColorFg); -+ osd->DrawRectangle(px + 1, py0, px1, py0 + 1, ColorFg); -+ osd->DrawRectangle(px + 1, py1 - 1, px1, py1, ColorFg); -+ osd->DrawRectangle(px1 - 1, py0, px1, py1, ColorFg); -+ } -+ else -+ osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x4 - xt); -+#else - int xt = x3 + 5 + Tab(i); - osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x4 - xt); -+#endif /* LIEMIEXT */ - } - if (!Tab(i + 1)) - break; -@@ -602,6 +646,21 @@ void cSkinSTTNGDisplayMenu::SetEvent(con - y += ts.Height(); - } - y += font->Height(); -+#ifdef USE_PARENTALRATING -+ if (!isempty(Event->GetParentalRatingString())) { -+ const cFont *font = cFont::GetFont(fontSml); -+ ts.Set(osd, xl, y, x4 - xl, y4 - y, Event->GetParentalRatingString(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground)); -+ y += ts.Height(); -+ } -+ int i = 0; -+ while (Event->Contents(i++)) { -+ if (!isempty(Event->GetContentsString())) { -+ const cFont *font = cFont::GetFont(fontSml); -+ ts.Set(osd, xl, y, x4 - xl, y4 - y, Event->GetContentsString(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground)); -+ y += ts.Height(); -+ } -+ } -+#endif /* PARENTALRATING */ - if (!isempty(Event->Description())) { - int yt = y; - int yb = y4 - Roundness; -diff -ruNp vdr-1.7.5/sources.c vdr-1.7.5-extensions/sources.c ---- vdr-1.7.5/sources.c 2008-02-10 15:07:26.000000000 +0100 -+++ vdr-1.7.5-extensions/sources.c 2009-04-12 13:37:59.000000000 +0200 -@@ -37,6 +37,9 @@ cString cSource::ToString(int Code) - char buffer[16]; - char *q = buffer; - switch (Code & st_Mask) { -+#ifdef USE_PLUGINPARAM -+ case stPlug: *q++ = 'P'; break; -+#endif /* PLUGINPARAM */ - case stCable: *q++ = 'C'; break; - case stSat: *q++ = 'S'; - { -@@ -56,6 +59,9 @@ int cSource::FromString(const char *s) - { - int type = stNone; - switch (toupper(*s)) { -+#ifdef USE_PLUGINPARAM -+ case 'P': type = stPlug; break; -+#endif /* PLUGINPARAM */ - case 'C': type = stCable; break; - case 'S': type = stSat; break; - case 'T': type = stTerr; break; -@@ -68,7 +74,11 @@ int cSource::FromString(const char *s) - int pos = 0; - bool dot = false; - bool neg = false; -+#ifdef USE_SOURCECAPS -+ while (*++s && !isblank(*s)) { -+#else - while (*++s) { -+#endif /* SOURCECAPS */ - switch (toupper(*s)) { - case '0' ... '9': pos *= 10; - pos += *s - '0'; -diff -ruNp vdr-1.7.5/sources.conf vdr-1.7.5-extensions/sources.conf ---- vdr-1.7.5/sources.conf 2008-08-16 12:02:27.000000000 +0200 -+++ vdr-1.7.5-extensions/sources.conf 2009-04-12 13:37:59.000000000 +0200 -@@ -194,3 +194,7 @@ C Cable - # Terrestrial - - T Terrestrial -+ -+# Plugin PLUGINPARAM -+ -+#P Plugin -diff -ruNp vdr-1.7.5/sources.h vdr-1.7.5-extensions/sources.h ---- vdr-1.7.5/sources.h 2005-05-14 11:30:41.000000000 +0200 -+++ vdr-1.7.5-extensions/sources.h 2009-04-12 13:37:59.000000000 +0200 -@@ -16,10 +16,17 @@ class cSource : public cListObject { - public: - enum eSourceType { - stNone = 0x0000, -+#ifdef USE_PLUGINPARAM -+ stPlug = 0x2000, -+#endif /* PLUGINPARAM */ - stCable = 0x4000, - stSat = 0x8000, - stTerr = 0xC000, -+#ifdef USE_PLUGINPARAM -+ st_Mask = 0xE000, -+#else - st_Mask = 0xC000, -+#endif /* PLUGINPARAM */ - st_Neg = 0x0800, - st_Pos = 0x07FF, - }; -@@ -35,6 +42,9 @@ public: - static cString ToString(int Code); - static int FromString(const char *s); - static int FromData(eSourceType SourceType, int Position = 0, bool East = false); -+#ifdef USE_PLUGINPARAM -+ static bool IsPlug(int Code) { return (Code & st_Mask) == stPlug; } -+#endif /* PLUGINPARAM */ - static bool IsCable(int Code) { return (Code & st_Mask) == stCable; } - static bool IsSat(int Code) { return (Code & st_Mask) == stSat; } - static bool IsTerr(int Code) { return (Code & st_Mask) == stTerr; } -diff -ruNp vdr-1.7.5/status.c vdr-1.7.5-extensions/status.c ---- vdr-1.7.5/status.c 2008-02-16 15:46:31.000000000 +0100 -+++ vdr-1.7.5-extensions/status.c 2009-04-12 13:37:59.000000000 +0200 -@@ -29,6 +29,20 @@ void cStatus::MsgTimerChange(const cTime - sm->TimerChange(Timer, Change); - } - -+#ifdef USE_STREAMDEVEXT -+void cStatus::MsgRecordingChange(const cRecording *Recording, eStatusChange Change) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->RecordingChange(Recording, Change); -+} -+ -+void cStatus::MsgChannelChange(const cChannel *Channel, eStatusChange Change) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->ChannelChange(Channel, Change); -+} -+#endif /* STREAMDEVEXT */ -+ - void cStatus::MsgChannelSwitch(const cDevice *Device, int ChannelNumber) - { - for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -@@ -124,3 +138,88 @@ void cStatus::MsgOsdProgramme(time_t Pre - for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) - sm->OsdProgramme(PresentTime, PresentTitle, PresentSubtitle, FollowingTime, FollowingTitle, FollowingSubtitle); - } -+ -+#ifdef USE_PINPLUGIN -+bool cStatus::MsgChannelProtected(const cDevice* Device, const cChannel* Channel) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ if (sm->ChannelProtected(Device, Channel) == true) -+ return true; -+ return false; -+} -+ -+bool cStatus::MsgReplayProtected(const cRecording* Recording, const char* Name, const char* Base, bool isDirectory, int menuView) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ if (sm->ReplayProtected(Recording, Name, Base, isDirectory, menuView) == true) -+ return true; -+ return false; -+} -+ -+void cStatus::MsgRecordingFile(const char* FileName) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->RecordingFile(FileName); -+} -+ -+void cStatus::MsgTimerCreation(cTimer* Timer, const cEvent *Event) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->TimerCreation(Timer, Event); -+} -+ -+bool cStatus::MsgPluginProtected(cPlugin* Plugin, int menuView) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ if (sm->PluginProtected(Plugin, menuView) == true) -+ return true; -+ return false; -+} -+ -+void cStatus::MsgUserAction(const eKeys key, const cOsdObject* Interact) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->UserAction(key, Interact); -+} -+ -+bool cStatus::MsgMenuItemProtected(const char* Name, int menuView) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ if (sm->MenuItemProtected(Name, menuView) == true) -+ return true; -+ return false; -+} -+#endif /* PINPLUGIN */ -+ -+#ifdef USE_GRAPHTFT -+void cStatus::MsgOsdSetEvent(const cEvent* event) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdSetEvent(event); -+} -+ -+void cStatus::MsgOsdSetRecording(const cRecording* recording) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdSetRecording(recording); -+} -+ -+void cStatus::MsgOsdMenuDisplay(const char* kind) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdMenuDisplay(kind); -+} -+ -+void cStatus::MsgOsdMenuDestroy() -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdMenuDestroy(); -+} -+ -+void cStatus::MsgOsdEventItem(const cEvent* Event, const char *Text, int Index, int Count) -+{ -+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) -+ sm->OsdEventItem(Event, Text, Index, Count); -+} -+#endif /* GRAPHTFT */ -+ -diff -ruNp vdr-1.7.5/status.h vdr-1.7.5-extensions/status.h ---- vdr-1.7.5/status.h 2008-02-16 16:00:33.000000000 +0100 -+++ vdr-1.7.5-extensions/status.h 2009-04-12 13:37:59.000000000 +0200 -@@ -14,8 +14,14 @@ - #include "device.h" - #include "player.h" - #include "tools.h" -+#ifdef USE_PINPLUGIN -+#include "plugin.h" -+#endif /* PINPLUGIN */ - - enum eTimerChange { tcMod, tcAdd, tcDel }; -+#ifdef USE_STREAMDEVEXT -+enum eStatusChange { scMod, scAdd, scDel }; -+#endif /* STREAMDEVEXT */ - - class cTimer; - -@@ -30,6 +36,16 @@ protected: - // been added or will be deleted, respectively. In case of tcMod, - // Timer is NULL; this indicates that some timer has been changed. - // Note that tcAdd and tcDel are always also followed by a tcMod. -+#ifdef USE_STREAMDEVEXT -+ virtual void RecordingChange(const cRecording *Recording, eStatusChange Change) {} -+ // Indicates a change in the recordings settings. -+ // If Change is scAdd or scDel, Recording points to the recording that has -+ // been added or will be deleted, respectively. In case of scMod, -+ // Timer is NULL; this indicates that some timer has been changed. -+ // Note that scAdd and scDel are always also followed by a scMod. -+ virtual void ChannelChange(const cChannel *Channel, eStatusChange Change) {} -+ // Indicates a change in the channel list. -+#endif /* STREAMDEVEXT */ - virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber) {} - // Indicates a channel switch on the given DVB device. - // If ChannelNumber is 0, this is before the channel is being switched, -@@ -80,11 +96,46 @@ protected: - // The OSD displays the single line Text with the current channel information. - virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle) {} - // The OSD displays the given programme information. -+#ifdef USE_PINPLUGIN -+ virtual bool ChannelProtected(const cDevice *Device, const cChannel* Channel) { return false; } -+ // Checks if a channel is protected. -+ virtual bool ReplayProtected(const cRecording* Recording, const char* Name, const char* Base, bool isDirectory, int menuView = false) { return false; } -+ // Checks if a recording is protected. -+ virtual void RecordingFile(const char* FileName) {} -+ // The given DVB device has started recording to FileName. FileName is the name of the -+ // recording directory -+ virtual void TimerCreation(cTimer* Timer, const cEvent *Event) {} -+ // The given timer is created -+ virtual bool PluginProtected(cPlugin* Plugin, int menuView = false) { return false; } -+ // Checks if a plugin is protected. -+ virtual void UserAction(const eKeys key, const cOsdObject* Interact) {} -+ // report user action -+ virtual bool MenuItemProtected(const char* Name, int menuView = false) { return false; } -+ // Checks if a menu entry is protected. -+#endif /* PINPLUGIN */ -+#ifdef USE_GRAPHTFT -+ virtual void OsdSetRecording(const cRecording* recording) {} -+ // The OSD displays the recording information. -+ virtual void OsdSetEvent(const cEvent* event) {} -+ // The OSD displays the event information. -+ virtual void OsdMenuDisplay(const char* kind) {} -+ // report menu creation -+ virtual void OsdMenuDestroy() {} -+ // report menu destruvtion -+ virtual void OsdEventItem(const cEvent* Event, const char *Text, int Index, int Count) {} -+ // The OSD displays the given single line Event as menu item at Index. -+ -+#endif /* GRAPHTFT */ -+ - public: - cStatus(void); - virtual ~cStatus(); - // These functions are called whenever the related status information changes: - static void MsgTimerChange(const cTimer *Timer, eTimerChange Change); -+#ifdef USE_STREAMDEVEXT -+ static void MsgRecordingChange(const cRecording *Recording, eStatusChange Change); -+ static void MsgChannelChange(const cChannel *Channel, eStatusChange Change); -+#endif /* STREAMDEVEXT */ - static void MsgChannelSwitch(const cDevice *Device, int ChannelNumber); - static void MsgRecording(const cDevice *Device, const char *Name, const char *FileName, bool On); - static void MsgReplaying(const cControl *Control, const char *Name, const char *FileName, bool On); -@@ -101,6 +152,22 @@ public: - static void MsgOsdTextItem(const char *Text, bool Scroll = false); - static void MsgOsdChannel(const char *Text); - static void MsgOsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle); -+#ifdef USE_PINPLUGIN -+ static bool MsgChannelProtected(const cDevice* Device, const cChannel* Channel); -+ static bool MsgReplayProtected(const cRecording* Recording, const char* Name, const char* Base, bool isDirectory, int menuView = false); -+ static void MsgRecordingFile(const char* FileName); -+ static void MsgTimerCreation(cTimer* Timer, const cEvent *Event); -+ static bool MsgPluginProtected(cPlugin* Plugin, int menuView = false); -+ static void MsgUserAction(const eKeys key, const cOsdObject* Interact); -+ static bool MsgMenuItemProtected(const char* Name, int menuView = false); -+#endif /* PINPLUGIN */ -+#ifdef USE_GRAPHTFT -+ static void MsgOsdSetEvent(const cEvent* event); -+ static void MsgOsdSetRecording(const cRecording* recording); -+ static void MsgOsdMenuDisplay(const char* kind); -+ static void MsgOsdMenuDestroy(); -+ static void MsgOsdEventItem(const cEvent* Event, const char *Text, int Index, int Count); -+#endif /* GRAPHTFT */ - }; - - #endif //__STATUS_H -diff -ruNp vdr-1.7.5/submenu.c vdr-1.7.5-extensions/submenu.c ---- vdr-1.7.5/submenu.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/submenu.c 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,952 @@ -+#ifdef USE_SETUP -+/**************************************************************************** -+ * DESCRIPTION: -+ * Submenu -+ * -+ * $Id: vdr-1.3.44-Setup-0.3.0.diff,v 1.1 2006/03/04 09:58:47 ralf Exp $ -+ * -+ * Contact: ranga@teddycats.de -+ * -+ * Copyright (C) 2004, 2005 by Ralf Dotzert -+ * -+ * modified for the VDR Extensions Patch by zulu @vdr-portal -+ ****************************************************************************/ -+ -+#ifndef SUBMENU_H -+#include "submenu.h" -+#include "plugin.h" -+ -+static const char* TAG_SYSTEM = "system"; -+static const char* TAG_PLUGIN = "plugin"; -+static const char* TAG_COMMAND = "command"; -+static const char* TAG_THREAD = "thread"; -+static const char* TAG_MENU = "menu"; -+static const char* TAG_UNDEFINED = "undefined"; -+static const char* TRUE_STR = "yes"; -+ -+ -+//################################################################################ -+//# SubMenuNode -+//################################################################################ -+ -+cSubMenuNode::cSubMenuNode(TiXmlElement * xml, int level, cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu) -+{ -+ init(); -+ _parentMenu = parentMenu; -+ _currentMenu = currentMenu; -+ _level = level; -+ -+ if (xml != NULL && xml->Type() == TiXmlNode::ELEMENT) { -+ const char *tag = xml->Value(); -+ -+ if (cSubMenuNode::IsType(tag) != cSubMenuNode::UNDEFINED) { -+ SetType(tag); -+ SetName(xml->Attribute("name")); -+ if ((_type == COMMAND) || (_type == THREAD)) { -+ SetCommand(xml->Attribute("execute")); -+ const char * confirmStr = xml->Attribute("confirm"); -+ if (confirmStr != NULL && strcmp(confirmStr, TRUE_STR) == 0) -+ _commandConfirm = true; -+ } -+ else if (_type == PLUGIN) { // Add Plugin Index -+ SetCustomTitle(xml->Attribute("title")); -+ SetPlugin(); -+ } -+ else if (_type == MENU && xml->NoChildren() == false) { -+ xml = xml->FirstChildElement(); -+ do { -+ cSubMenuNode *node = new cSubMenuNode(xml, level+1, &_subMenus, currentMenu); -+ _subMenus.Add(node); -+ } while ((xml=xml->NextSiblingElement()) != NULL); -+ } -+ } -+ } -+ else -+ throw "Invalid XML Node"; -+} -+ -+/** -+ * Construct new Node empty Node -+ * -+ * -+ */ -+cSubMenuNode::cSubMenuNode(cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu) -+{ -+ init(); -+ _parentMenu = parentMenu; -+ _currentMenu = currentMenu; -+ -+} -+ -+ -+/** -+ * -+ */ -+void cSubMenuNode::init() -+{ -+ _name = NULL; -+ _command = NULL; -+ _title = NULL; -+ _pluginMainMenuEntry = NULL; -+ _type = UNDEFINED; -+ _level = 0; -+ _parentMenu = NULL; -+ _currentMenu = NULL; -+ _pluginIndex = 0; -+ _commandConfirm = false; -+} -+ -+ -+cSubMenuNode::~ cSubMenuNode() -+{ -+ if (_name != NULL) -+ free((void*)_name); -+ if (_command != NULL) -+ free((void*)_command); -+ if (_title != NULL) -+ free((void*)_title); -+ if (_pluginMainMenuEntry != NULL) -+ free((void*)_pluginMainMenuEntry); -+} -+ -+/** -+ * -+ */ -+void cSubMenuNode::SetPlugin() -+{ -+ bool found = false; -+ for (int i = 0; ; i++) { -+ cPlugin *p = cPluginManager::GetPlugin(i); -+ if (p) { -+ if (strcmp(_name, p->Name()) == 0 && p->MainMenuEntry() != NULL) { -+ SetPluginMainMenuEntry(p->MainMenuEntry()); -+ _pluginIndex = i; -+ found = true; -+ break; -+ } -+ } -+ else -+ break; -+ } -+ -+ if (!found) -+ _type = UNDEFINED; -+} -+ -+ -+bool cSubMenuNode::SaveXml(TiXmlElement * root) -+{ -+ bool ok = true; -+ -+ if (root!=NULL) { -+ TiXmlElement *e = NULL; -+ switch(_type) { -+ case SYSTEM: -+ e = new TiXmlElement(TAG_SYSTEM); -+ e->SetAttribute("name", GetName()); -+ break; -+ case COMMAND: -+ e = new TiXmlElement(TAG_COMMAND); -+ e->SetAttribute("name", GetName()); -+ e->SetAttribute("execute", GetCommand()); -+ if (_commandConfirm) -+ e->SetAttribute("confirm", TRUE_STR); -+ break; -+ case THREAD: -+ e = new TiXmlElement(TAG_THREAD); -+ e->SetAttribute("name", GetName()); -+ e->SetAttribute("execute", GetCommand()); -+ if (_commandConfirm) -+ e->SetAttribute("confirm", TRUE_STR); -+ break; -+ case PLUGIN: -+ e = new TiXmlElement(TAG_PLUGIN); -+ e->SetAttribute("name", GetName()); -+ if (GetCustomTitle() != NULL && strcmp(GetCustomTitle(), "") != 0) -+ e->SetAttribute("title", GetCustomTitle()); -+ break; -+ case MENU: -+ e = new TiXmlElement(TAG_MENU); -+ e->SetAttribute("name", GetName()); -+ break; -+ case UNDEFINED: -+ default: -+ ok = false; -+ break; -+ } -+ if (ok) { -+ root->LinkEndChild(e); -+ if (HasSubMenus()) -+ for (cSubMenuNode *node = _subMenus.First(); node; node = _subMenus.Next(node)) -+ node->SaveXml(e); -+ } -+ } -+ -+ return(ok); -+} -+ -+ -+cSubMenuNode::Type cSubMenuNode::IsType(const char *name) -+{ -+ Type type = UNDEFINED; -+ -+ if (strcmp(name ,TAG_SYSTEM) == 0) -+ type = cSubMenuNode::SYSTEM; -+ else if (strcmp(name ,TAG_PLUGIN) == 0) -+ type = cSubMenuNode::PLUGIN; -+ else if (strcmp(name ,TAG_COMMAND) == 0) -+ type = cSubMenuNode::COMMAND; -+ else if (strcmp(name ,TAG_THREAD) == 0) -+ type = cSubMenuNode::THREAD; -+ else if (strcmp(name ,TAG_MENU) == 0) -+ type = cSubMenuNode::MENU; -+ -+ return(type); -+} -+ -+void cSubMenuNode::SetType(const char * name) -+{ -+ _type = IsType(name); -+} -+ -+void cSubMenuNode::SetType(enum Type type) -+{ -+ _type = type; -+} -+ -+ -+cSubMenuNode::Type cSubMenuNode::GetType() -+{ -+ return(_type); -+} -+ -+const char * cSubMenuNode::GetTypeAsString() -+{ -+ const char *str=NULL; -+ switch(_type) { -+ case SYSTEM: -+ str = TAG_SYSTEM; -+ break; -+ case COMMAND: -+ str = TAG_COMMAND; -+ break; -+ case THREAD: -+ str = TAG_THREAD; -+ break; -+ case PLUGIN: -+ str = TAG_PLUGIN; -+ break; -+ case MENU: -+ str = TAG_MENU; -+ break; -+ case UNDEFINED: -+ str = TAG_UNDEFINED; -+ default: -+ break; -+ } -+ -+ return(str); -+} -+ -+void cSubMenuNode::SetCommand(const char * command) -+{ -+ if (_command != NULL) -+ free((void*)_command); -+ -+ if (command != NULL) -+ _command = strdup(command); -+ else -+ _command = NULL; -+} -+ -+const char * cSubMenuNode::GetCommand() -+{ -+ return(_command); -+} -+ -+bool cSubMenuNode::CommandConfirm() -+{ -+ return(_commandConfirm); -+} -+ -+void cSubMenuNode::SetCommandConfirm(int val) -+{ -+ if (val == 1) -+ _commandConfirm = true; -+ else -+ _commandConfirm = false; -+} -+ -+void cSubMenuNode::SetCustomTitle(const char * title) -+{ -+ if (_title != NULL) -+ free((void*)_title); -+ -+ if (title != NULL) -+ _title = strdup(title); -+ else -+ _title = NULL; -+} -+ -+const char * cSubMenuNode::GetCustomTitle() -+{ -+ return(_title); -+} -+ -+void cSubMenuNode::SetName(const char * name) -+{ -+ if (_name) -+ free ((void*)_name); -+ -+ if (name != NULL) -+ _name = strdup(name); -+ else -+ _name = NULL; -+} -+ -+const char * cSubMenuNode::GetName() -+{ -+ return(_name); -+} -+ -+int cSubMenuNode::GetLevel() -+{ -+ return(_level); -+} -+ -+void cSubMenuNode::SetLevel(int level) -+{ -+ _level = level; -+ if (HasSubMenus()) { //Adjust Levels of Subnodes -+ for (cSubMenuNode *node = _subMenus.First(); node; node = _subMenus.Next(node)) -+ node->SetLevel(level+1); -+ } -+} -+ -+int cSubMenuNode::GetPluginIndex() -+{ -+ return(_pluginIndex); -+} -+ -+void cSubMenuNode::SetPluginIndex(int index) -+{ -+ _pluginIndex = index; -+} -+ -+void cSubMenuNode::SetPluginMainMenuEntry(const char * mainMenuEntry) -+{ -+ if (_pluginMainMenuEntry != NULL) -+ free((void*)_pluginMainMenuEntry); -+ -+ if (_title != NULL && strcmp(_title, "") != 0) -+ _pluginMainMenuEntry = strdup(_title); -+ else if (mainMenuEntry != NULL) -+ _pluginMainMenuEntry = strdup(mainMenuEntry); -+ else -+ _pluginMainMenuEntry = NULL; -+} -+ -+const char * cSubMenuNode::GetPluginMainMenuEntry() -+{ -+ return(_pluginMainMenuEntry); -+} -+ -+ -+ -+cSubMenuNodes * cSubMenuNode::GetParentMenu() -+{ -+ return(_parentMenu); -+} -+ -+void cSubMenuNode::SetParentMenu(cSubMenuNodes * parent) -+{ -+ _parentMenu = parent; -+} -+ -+cSubMenuNodes * cSubMenuNode::GetCurrentMenu() -+{ -+ return(_currentMenu); -+} -+ -+void cSubMenuNode::SetCurrentMenu(cSubMenuNodes * current) -+{ -+ _currentMenu = current; -+} -+ -+ -+cSubMenuNodes * cSubMenuNode::GetSubMenus() -+{ -+ return(&_subMenus); -+} -+ -+bool cSubMenuNode::HasSubMenus() -+{ -+ if (_subMenus.Count() > 0) -+ return(true); -+ else -+ return(false); -+} -+ -+ -+void cSubMenuNode::Print(int index) -+{ -+ for (int i = 0; i < index; i++) -+ printf(" "); -+ -+ printf("Name=%s Type=%s Level=%d", _name, GetTypeAsString(), _level); -+ if (_type == COMMAND || _type == THREAD) -+ printf(" Command=%s", _command); -+ else if (_type == PLUGIN && _title != NULL) -+ printf(" Title=%s", _title); -+ printf("\n"); -+ -+ for (cSubMenuNode *node = _subMenus.First(); node; node = _subMenus.Next(node)) -+ node->Print(index+4); -+} -+ -+ -+//################################################################################ -+//# -+//################################################################################ -+cSubMenu::cSubMenu() -+{ -+ _menuSuffix = NULL; -+ _fname = NULL; -+ _commandResult = NULL; -+ _currentMenuTree = &_menuTree; -+ _currentParentMenuTree = NULL; -+#ifdef USE_PINPLUGIN -+ _currentParentIndex = -1; -+#endif /* PINPLUGIN */ -+ _nodeArray = NULL; -+ _nrNodes = 0; -+} -+ -+ -+cSubMenu::~cSubMenu() -+{ -+ if (_menuSuffix) -+ free(_menuSuffix); -+ if (_fname) -+ free(_fname); -+ if (_commandResult) -+ free(_commandResult); -+ if (_nodeArray) -+ free(_nodeArray); -+ _nrNodes = 0; -+} -+ -+ -+bool cSubMenu::LoadXml(char *fname) -+{ -+ TiXmlDocument xmlDoc = TiXmlDocument(fname); -+ TiXmlElement *root = NULL; -+ cSubMenuNode *node = NULL; -+ -+ bool ok = true; -+ //Clear previously loaded Menu -+ if (_fname != NULL) -+ free(_fname); -+ _menuTree.Clear(); -+ _fname = strdup(fname); -+ -+ if ((ok = xmlDoc.LoadFile())) { -+ if ((root = xmlDoc.FirstChildElement("menus")) != NULL) { -+ char *tmp = NULL; -+ if ((tmp = (char*)root->Attribute("suffix")) == NULL) -+ asprintf(&_menuSuffix, " "); // set default menuSuffix // asprintf(&_menuSuffix, " ..."); -+ else -+ asprintf(&_menuSuffix, tmp); -+ -+ if ((root = root->FirstChildElement()) != NULL) { -+ do { -+ try { -+ node = new cSubMenuNode(root, 0, &_menuTree, NULL); -+ _menuTree.Add(node); -+ } -+ catch (char *message) { -+ esyslog("ERROR: while decoding XML Node"); -+ ok = false; -+ } -+ } while (ok == true && (root = root->NextSiblingElement()) != NULL); -+ addMissingPlugins(); -+ removeUndefinedNodes(); -+ } -+ } -+ else { -+ esyslog("ERROR: in %s, missing Tag <menus>\n", fname); -+ ok = false; -+ } -+ } -+ else { -+ esyslog("ERROR: in %s : %s Col=%d Row=%d\n", -+ fname, -+ xmlDoc.ErrorDesc(), -+ xmlDoc.ErrorCol(), -+ xmlDoc.ErrorRow()); -+ ok = false; -+ } -+ -+ return(ok); -+} -+ -+ -+bool cSubMenu::SaveXml() -+{ -+ return(SaveXml(_fname)); -+} -+ -+ -+bool cSubMenu::SaveXml(char *fname) -+{ -+ bool ok = true; -+ -+ if (_fname != NULL) { -+ TiXmlDocument xml = TiXmlDocument(fname); -+ TiXmlComment comment; -+ comment.SetValue("\n\ -+- VDR Menu-Configuration File\n\ -+-\n\ -+-\n\ -+- Example:\n\ -+-\n\ -+ <menus>\n\ -+ <system name=\"Schedule\" />\n\ -+ <system name=\"Channels\" />\n\ -+ <system name=\"Timers\" />\n\ -+ <system name=\"Recordings\" />\n\ -+ <menu name=\"System\">\n\ -+ <system name=\"Setup\" />\n\ -+ <system name=\"Commands\" />\n\ -+ <plugin name=\"setup\" title=\"My Setup\" />\n\ -+ <command name=\"myCommand1\" execute=\"/usr/bin/mycommand1\" />\n\ -+ <command name=\"myCommand2\" execute=\"/usr/bin/mycommand2\" confirm=\"yes\" />\n\ -+ <thread name=\"myCommand3\" execute=\"/usr/bin/mycommand3\" confirm=\"yes\" />\n\ -+ <plugin name=\"epgsearch\" title=\"myProgram\" />\n\ -+ <menu name=\"mySubSubMenu\">\n\ -+ ...\n\ -+ </menu>\n\ -+ </menu>\n\ -+ <menu name=\"Suche\">\n\ -+ <plugin name=\"epgsearch\" />\n\ -+ ...\n\ -+ </menu>\n\ -+ </menus>\n\ -+"); -+ -+ TiXmlElement root("menus"); -+ root.SetAttribute("suffix", _menuSuffix); -+ for (cSubMenuNode *node = _menuTree.First(); node; node = _menuTree.Next(node)) -+ node->SaveXml(&root); -+ -+ if (xml.InsertEndChild(comment) != NULL && xml.InsertEndChild(root) != NULL) -+ ok = xml.SaveFile(fname); -+ } -+ else -+ ok = false; -+ -+ return(ok); -+} -+ -+ -+ -+cSubMenuNodes * cSubMenu::GetMenuTree() -+{ -+ return(_currentMenuTree); -+} -+ -+ -+void cSubMenu::PrintMenuTree() -+{ -+ for (cSubMenuNode *node = _menuTree.First(); node; node = _menuTree.Next(node)) -+ node->Print(); -+} -+ -+ -+int cSubMenu::GetNrOfNodes() -+{ -+ if (_nrNodes == 0) { -+ if ((_nrNodes = countNodes(&_menuTree)) > 0) { -+ _nodeArray = (cSubMenuNode**) malloc(sizeof(cSubMenuNode*)*_nrNodes); -+ int index = 0; -+ tree2Array(&_menuTree, index); -+ } -+ } -+ -+ return(_nrNodes); -+} -+ -+ -+/** -+ * returns the specified node within the current menu -+ * @param index position in the current menu -+ * @return node or null if not found -+ */ -+cSubMenuNode * cSubMenu::GetNode(int index) -+{ -+ cSubMenuNode *node = NULL; -+ if (_currentMenuTree == NULL || (node=_currentMenuTree->Get(index)) == NULL) -+ esyslog("ERROR: illegal call of cSubMenu::GetNode(%d)", index); -+ -+ return(node); -+} -+ -+ -+/** -+ * Get the specified Node -+ * @param index specfies the absolut indes in the list of all nodes -+ * @return node or NULL if not found -+ */ -+cSubMenuNode * cSubMenu::GetAbsNode(int index) -+{ -+ cSubMenuNode *node = NULL; -+ GetNrOfNodes(); -+ if (_nrNodes > 0 && index >= 0 && index < _nrNodes) -+ node = _nodeArray[index]; -+ -+ return(node); -+} -+ -+ -+#ifdef USE_PINPLUGIN -+bool cSubMenu::Down(cSubMenuNode *node, int currentIndex) -+#else -+bool cSubMenu::Down(int index) -+#endif /* PINPLUGIN */ -+{ -+ bool ok = true; -+#ifdef USE_PINPLUGIN -+ if (_currentMenuTree != NULL && node && node->GetType() == cSubMenuNode::MENU) { -+#else -+ cSubMenuNode *node = NULL; -+ -+ if (_currentMenuTree != NULL && (node=_currentMenuTree->Get(index)) != NULL && node->GetType() == cSubMenuNode::MENU) { -+#endif /* PINPLUGIN */ -+ _currentParentMenuTree = _currentMenuTree; -+#ifdef USE_PINPLUGIN -+ _currentParentIndex = currentIndex; -+#endif /* PINPLUGIN */ -+ _currentMenuTree = node->GetSubMenus(); -+ } -+ else { -+ ok = false; -+#ifdef USE_PINPLUGIN -+ esyslog("ERROR: illegal call of cSubMenu::Down"); -+#else -+ esyslog("ERROR: illegal call of cSubMenu::Down(%d)", index); -+#endif /* PINPLUGIN */ -+ } -+ -+ return(ok); -+} -+ -+bool cSubMenu::Up(int *parentIndex) -+{ -+ bool ok = true; -+ -+ if (_currentMenuTree != NULL && parentIndex != NULL) { -+#ifndef USE_PINPLUGIN -+ cSubMenuNode *node = NULL; -+#endif /* PINPLUGIN */ -+ *parentIndex = 0; -+#ifdef USE_PINPLUGIN -+ if (_currentParentIndex >= 0) -+ *parentIndex = _currentParentIndex; -+#else -+ if (_currentParentMenuTree != NULL) -+ for (int i = 0; (node = _currentParentMenuTree->Get(i)) != NULL; i++) { -+ if (_currentMenuTree == node->GetSubMenus()) { -+ *parentIndex = i; -+ break; -+ } -+ } -+#endif /* PINPLUGIN */ -+ -+ _currentMenuTree = _currentParentMenuTree; -+ if (_currentMenuTree != NULL) -+ _currentParentMenuTree = _currentMenuTree->Get(0)->GetParentMenu(); -+ else -+ ok = false; -+ } -+ else { -+ ok = false; -+ esyslog("ERROR: illegal call of cSubMenu::Up()"); -+ } -+ -+ return(ok); -+} -+ -+const char * cSubMenu::ExecuteCommand(const char * cmd) -+{ -+ free(_commandResult); -+ _commandResult = NULL; -+ -+ dsyslog("executing command '%s'", cmd); -+ FILE *p = popen(cmd, "r"); -+ if (p) { -+ int l = 0; -+ int c; -+ while ((c = fgetc(p)) != EOF) { -+ if (l % 20 == 0) -+ _commandResult = (char *)realloc(_commandResult, l + 21); -+ _commandResult[l++] = c; -+ } -+ if (_commandResult) -+ _commandResult[l] = 0; -+ pclose(p); -+ } -+ else -+ esyslog("ERROR: can't open pipe for command '%s'", cmd); -+ -+ return _commandResult; -+} -+ -+/** -+ * Move Menu Entry to new Position -+ * @param index index of menu entry to move -+ * @param toIndex index of destination -+ * @param where After ore before the destination index -+ */ -+void cSubMenu::MoveMenu(int index, int toIndex, enum Where where) -+{ -+ if (index < 0 || index > _nrNodes || // invalid index is ignored -+ toIndex < 0 || toIndex > _nrNodes || index == toIndex) -+ return; -+ -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ cSubMenuNode *destNode = GetAbsNode(toIndex); -+ -+ if (where == cSubMenu::INTO && destNode->GetType() != cSubMenuNode::MENU) -+ return; -+ -+ if (where == cSubMenu::INTO) { -+ if (destNode->GetType() == cSubMenuNode::MENU) { -+ srcNode->GetCurrentMenu()->Del(srcNode, false); -+ srcNode->SetLevel(destNode->GetLevel()+1); -+ srcNode->SetParentMenu(destNode->GetCurrentMenu()); -+ srcNode->SetCurrentMenu(destNode->GetSubMenus()); -+ -+ destNode->GetSubMenus()->Add(srcNode); -+ reloadNodeArray(); -+ } -+ } -+ else { -+ srcNode->GetCurrentMenu()->Del(srcNode, false); -+ srcNode->SetLevel(destNode->GetLevel()); -+ srcNode->SetParentMenu(destNode->GetParentMenu()); -+ srcNode->SetCurrentMenu(destNode->GetCurrentMenu()); -+ -+ if (where == cSubMenu::BEHIND) { -+ destNode->GetCurrentMenu()->Add(srcNode, GetAbsNode(toIndex)); -+ reloadNodeArray(); -+ } -+ else { -+ destNode->GetCurrentMenu()->Ins(srcNode, GetAbsNode(toIndex)); -+ reloadNodeArray(); -+ } -+ } -+} -+ -+/** -+ * Create a new Menu Entry -+ * @param index index of destination -+ * @param menuTitle Titel of new Menu entry -+ */ -+void cSubMenu::CreateMenu(int index, const char * menuTitle) -+{ -+ if (index >= 0 && index < _nrNodes) { -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ if (srcNode != NULL) { -+ cSubMenuNode *newNode = new cSubMenuNode(srcNode->GetParentMenu(), srcNode->GetCurrentMenu()); -+ newNode->SetLevel(srcNode->GetLevel()); -+ newNode->SetName(menuTitle); -+ newNode->SetType(cSubMenuNode::MENU); -+ newNode->SetParentMenu(srcNode->GetParentMenu()); -+ newNode->SetCurrentMenu(srcNode->GetCurrentMenu()); -+ -+ srcNode->GetCurrentMenu()->Add(newNode, GetAbsNode(index)); -+ reloadNodeArray(); -+ } -+ } -+} -+ -+/** -+ * delete the specified entry, or subtree if the specified entry is a menu -+ * @param index destion index -+ */ -+void cSubMenu::DeleteMenu(int index) -+{ -+ if (index >= 0 && index < _nrNodes) { -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ srcNode->GetCurrentMenu()->Del(srcNode, true); -+ reloadNodeArray(); -+ } -+} -+ -+ -+// Private Methods -+ -+int cSubMenu::countNodes(cSubMenuNodes * tree) -+{ -+ int count = 0; -+ if (tree != NULL) { -+ for (cSubMenuNode *node = tree->First(); node; node = tree->Next(node)) { -+ count++; -+ if (node->HasSubMenus()) -+ count += countNodes(node->GetSubMenus()); -+ } -+ } -+ return(count); -+} -+ -+ -+void cSubMenu::tree2Array(cSubMenuNodes * tree, int &index) -+{ -+ if (tree != NULL) { -+ for (cSubMenuNode *node = tree->First(); node; node = tree->Next(node)) { -+ _nodeArray[index++]=node; -+ if (node->HasSubMenus()) -+ tree2Array(node->GetSubMenus(), index); -+ } -+ } -+ -+} -+ -+bool cSubMenu::IsPluginInMenu(const char * name) -+{ -+ bool found = false; -+ for (int i = 0; i < _nrNodes && found == false; i++) { -+ cSubMenuNode *node = GetAbsNode(i); -+ if (node != NULL && node->GetType() == cSubMenuNode::PLUGIN && strcmp(name, node->GetName()) == 0) -+ found = true; -+ } -+ return(found); -+} -+ -+/** -+ * Adds the given plugin to the Menu-Tree if not allready in List -+ * @param name specifies the name of the plugin -+ */ -+void cSubMenu::AddPlugin(const char * name) -+{ -+ if (! IsPluginInMenu(name)) { -+ cSubMenuNode *node = new cSubMenuNode(&_menuTree, NULL); -+ node->SetName(name); -+ node->SetType("plugin"); -+ node->SetPlugin(); -+ _menuTree.Add(node); -+ } -+} -+ -+void cSubMenu::addMissingPlugins() -+{ -+ _nrNodes = GetNrOfNodes(); -+ for (int i = 0; ; i++) { -+ cPlugin *p = cPluginManager::GetPlugin(i); -+ if (p) -+ AddPlugin(p->Name()); -+ else -+ break; -+ } -+ reloadNodeArray(); -+} -+ -+/** -+ * Adds the given command to the Menu-Tree -+ * @param name specifies the name of the command -+ */ -+void cSubMenu::CreateCommand(int index, const char * name, const char * execute, int confirm) -+{ -+ if (index >= 0 && index < _nrNodes) { -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ if (srcNode != NULL) { -+ cSubMenuNode *newNode = new cSubMenuNode(srcNode->GetParentMenu(), srcNode->GetCurrentMenu()); -+ newNode->SetLevel(srcNode->GetLevel()); -+ newNode->SetName(name); -+ newNode->SetType("command"); -+ newNode->SetCommand(execute); -+ newNode->SetCommandConfirm(confirm); -+ newNode->SetParentMenu(srcNode->GetParentMenu()); -+ newNode->SetCurrentMenu(srcNode->GetCurrentMenu()); -+ -+ srcNode->GetCurrentMenu()->Add(newNode, GetAbsNode(index)); -+ reloadNodeArray(); -+ } -+ } -+} -+ -+void cSubMenu::CreateThread(int index, const char * name, const char * execute, int confirm) -+{ -+ if (index >= 0 && index < _nrNodes) { -+ cSubMenuNode *srcNode = GetAbsNode(index); -+ if (srcNode != NULL) { -+ cSubMenuNode *newNode = new cSubMenuNode(srcNode->GetParentMenu(), srcNode->GetCurrentMenu()); -+ newNode->SetLevel(srcNode->GetLevel()); -+ newNode->SetName(name); -+ newNode->SetType("thread"); -+ newNode->SetCommand(execute); -+ newNode->SetCommandConfirm(confirm); -+ newNode->SetParentMenu(srcNode->GetParentMenu()); -+ newNode->SetCurrentMenu(srcNode->GetCurrentMenu()); -+ -+ srcNode->GetCurrentMenu()->Add(newNode, GetAbsNode(index)); -+ reloadNodeArray(); -+ } -+ } -+} -+ -+/** -+ * reloads the internal Array of Nodes -+ */ -+void cSubMenu::reloadNodeArray() -+{ -+ if (_nrNodes > 0) -+ free(_nodeArray); -+ _nodeArray = NULL; -+ _nrNodes = 0; -+ _nrNodes = GetNrOfNodes(); -+} -+ -+/** -+ * remove Undefined Nodes -+ */ -+void cSubMenu::removeUndefinedNodes() -+{ -+ bool remove = false; -+ -+ reloadNodeArray(); -+ for (int i = 0; i < _nrNodes; i++) { -+ cSubMenuNode *node = GetAbsNode(i); -+ if (node != NULL && node->GetType() == cSubMenuNode::UNDEFINED) { -+ cSubMenuNodes *pMenu = node->GetCurrentMenu(); -+ pMenu->Del(node, true); -+ remove = true; -+ } -+ } -+ if (remove) -+ reloadNodeArray(); -+} -+ -+ -+/** -+* Retrieves the Menutitel of the parent Menu -+*/ -+const char *cSubMenu::GetParentMenuTitel() -+{ -+ const char * result = ""; -+ -+ if (_currentMenuTree != NULL && _currentParentMenuTree != NULL) { -+ cSubMenuNode *node = NULL; -+ for (int i = 0; (node = _currentParentMenuTree->Get(i)) != NULL; i++) { -+ if (_currentMenuTree == node->GetSubMenus()) { -+ result = node->GetName(); -+ break; -+ } -+ } -+ } -+ -+ return(result); -+} -+ -+#endif -+#endif /* SETUP */ -diff -ruNp vdr-1.7.5/submenu.h vdr-1.7.5-extensions/submenu.h ---- vdr-1.7.5/submenu.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/submenu.h 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,160 @@ -+#ifdef USE_SETUP -+/**************************************************************************** -+ * DESCRIPTION: -+ * Submenu -+ * -+ * $Id: vdr-1.3.44-Setup-0.3.0.diff,v 1.1 2006/03/04 09:58:47 ralf Exp $ -+ * -+ * Contact: ranga@teddycats.de -+ * -+ * Copyright (C) 2004, 2005 by Ralf Dotzert -+ * -+ * modified for the VDR Extensions Patch by zulu @vdr-portal -+ ****************************************************************************/ -+ -+#ifndef SUBMENU_H -+#define SUBMENU_H -+ -+#include "thread.h" -+#include "tools.h" -+#include "tinystr.h" -+ -+class cSubMenuNode; -+class cSubMenuNodes; -+class cSubMenu; -+ -+ -+class cSubMenuNodes : public cList<cSubMenuNode> {}; -+ -+// execute cmd thread -+class cExecCmdThread : public cThread { -+private: -+ char *ExecCmd; -+protected: -+ virtual void Action(void) { -+ if (system(ExecCmd) == 0) -+ esyslog("%s - finished", ExecCmd); -+ delete(this); -+ }; -+public: -+ cExecCmdThread(char *cmd) { -+ asprintf(&ExecCmd, "%s", cmd); -+ } -+ cExecCmdThread(const char *cmd) { -+ asprintf(&ExecCmd, "%s", cmd); -+ } -+ ~cExecCmdThread() { -+ free(ExecCmd); -+ }; -+ }; -+ -+//################################################################################ -+//# SubMenuNode -+//################################################################################ -+class cSubMenuNode : public cListObject { -+public: -+ enum Type { UNDEFINED, SYSTEM, COMMAND, THREAD, PLUGIN, MENU }; -+ cSubMenuNode(TiXmlElement * xml, int level, cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu); -+ cSubMenuNode(cSubMenuNodes *currentMenu, cSubMenuNodes *parentMenu); -+ ~cSubMenuNode(); -+ bool SaveXml(TiXmlElement * root); -+ static cSubMenuNode::Type IsType(const char *name); -+ void SetType(const char *name); -+ void SetType(enum Type type); -+ void SetPlugin(); -+ cSubMenuNode::Type GetType(); -+ const char *GetTypeAsString(); -+ void SetCommand(const char *command); -+ bool CommandConfirm(); -+ void SetCommandConfirm(int val); -+ const char *GetCommand(); -+ void SetCustomTitle(const char *title); -+ const char *GetCustomTitle(); -+ void SetName(const char *name); -+ const char*GetName(); -+ int GetLevel(); -+ void SetLevel(int level); -+ int GetPluginIndex(); -+ void SetPluginIndex(int index); -+ void SetPluginMainMenuEntry(const char *mainMenuEntry); -+ const char *GetPluginMainMenuEntry(); -+ cSubMenuNodes *GetParentMenu(); -+ void SetParentMenu(cSubMenuNodes *parent); -+ cSubMenuNodes *GetCurrentMenu(); -+ void SetCurrentMenu(cSubMenuNodes *current); -+ cSubMenuNodes *GetSubMenus(); -+ bool HasSubMenus(); -+ void Print(int index = 0); -+private: -+ Type _type; -+ int _level; -+ // Plugin Variables -+ int _pluginIndex; -+ const char *_pluginMainMenuEntry; -+ // common -+ const char *_name; -+ const char *_command; -+ bool _commandConfirm; -+ const char *_title; -+ cSubMenuNodes _subMenus; -+ cSubMenuNodes *_parentMenu; -+ cSubMenuNodes *_currentMenu; -+ void init(); -+ }; -+ -+ -+//################################################################################ -+//# SubMenu Class -+//################################################################################ -+class cSubMenu { -+public: -+ cSubMenu(); -+ ~cSubMenu(); -+ enum Where { BEFORE, BEHIND, INTO}; -+ bool LoadXml(char *fname); -+ bool SaveXml(char *fname); -+ bool SaveXml(); -+ cSubMenuNodes *GetMenuTree(); -+ bool Up(int *ParentIndex); -+#ifdef USE_PINPLUGIN -+ bool Down(cSubMenuNode* node, int currentIndex); -+#else -+ bool Down(int index); -+#endif /* PINPLUGIN */ -+ int GetNrOfNodes(); -+ cSubMenuNode* GetAbsNode(int index); -+ cSubMenuNode* GetNode(int index); -+ void PrintMenuTree(); -+ bool IsPluginInMenu(const char *name); -+ void AddPlugin(const char *name); -+ void CreateCommand(int index, const char *name, const char *execute, int confirm); -+ void CreateThread(int index, const char *name, const char *execute, int confirm); -+ const char *ExecuteCommand(const char *command); -+ void MoveMenu(int index, int toindex, enum Where); -+ void CreateMenu(int index, const char *menuTitle); -+ void DeleteMenu(int index); -+ char *GetMenuSuffix() { return _menuSuffix; } -+ void SetMenuSuffix(char *suffix) { if (_menuSuffix) free(_menuSuffix); asprintf(&_menuSuffix, suffix); } -+ bool isTopMenu() { return (_currentParentMenuTree == NULL); } -+ const char *GetParentMenuTitel(); -+private: -+ cSubMenuNodes _menuTree; -+ cSubMenuNodes *_currentMenuTree; -+ cSubMenuNodes *_currentParentMenuTree; -+#ifdef USE_PINPLUGIN -+ int _currentParentIndex; -+#endif /* PINPLUGIN */ -+ char *_fname; -+ char *_commandResult; -+ int _nrNodes; -+ cSubMenuNode **_nodeArray; -+ char *_menuSuffix; -+ int countNodes(cSubMenuNodes *tree); -+ void tree2Array(cSubMenuNodes *tree, int &index); -+ void addMissingPlugins(); -+ void reloadNodeArray(); -+ void removeUndefinedNodes(); -+ }; -+ -+#endif //__SUBMENU_H -+#endif /* SETUP */ -diff -ruNp vdr-1.7.5/svdrp.c vdr-1.7.5-extensions/svdrp.c ---- vdr-1.7.5/svdrp.c 2009-01-06 15:35:45.000000000 +0100 -+++ vdr-1.7.5-extensions/svdrp.c 2009-04-12 13:37:59.000000000 +0200 -@@ -39,6 +39,9 @@ - #include "timers.h" - #include "tools.h" - #include "videodir.h" -+#ifdef USE_STREAMDEVEXT -+#include "status.h" -+#endif /* STREAMDEVEXT */ - - // --- cSocket --------------------------------------------------------------- - -@@ -296,6 +299,10 @@ const char *HelpPages[] = { - "REMO [ on | off ]\n" - " Turns the remote control on or off. Without a parameter, the current\n" - " status of the remote control is reported.", -+#ifdef USE_LIEMIEXT -+ "RENR <number> <new name>\n" -+ " Rename recording. Number must be the Number as returned by LSTR command.", -+#endif /* LIEMIEXT */ - "SCAN\n" - " Forces an EPG scan. If this is a single DVB device system, the scan\n" - " will be done on the primary device unless it is currently recording.", -@@ -616,6 +623,9 @@ void cSVDRP::CmdDELC(const char *Option) - Channels.ReNumber(); - Channels.SetModified(true); - isyslog("channel %s deleted", Option); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(NULL, scDel); -+#endif /* STREAMDEVEXT */ - if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { - if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) - Channels.SwitchTo(CurrentChannel->Number()); -@@ -1135,6 +1145,9 @@ void cSVDRP::CmdMODC(const char *Option) - Channels.ReNumber(); - Channels.SetModified(true); - isyslog("modifed channel %d %s", channel->Number(), *channel->ToText()); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(channel, scMod); -+#endif /* STREAMDEVEXT */ - Reply(250, "%d %s", channel->Number(), *channel->ToText()); - } - else -@@ -1221,6 +1234,9 @@ void cSVDRP::CmdMOVC(const char *Option) - else - cDevice::SetCurrentChannel(CurrentChannel); - } -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(ToChannel, scMod); -+#endif /* STREAMDEVEXT */ - isyslog("channel %d moved to %d", FromNumber, ToNumber); - Reply(250,"Channel \"%d\" moved to \"%d\"", From, To); - } -@@ -1264,6 +1280,9 @@ void cSVDRP::CmdNEWC(const char *Option) - Channels.ReNumber(); - Channels.SetModified(true); - isyslog("new channel %d %s", channel->Number(), *channel->ToText()); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(channel, scAdd); -+#endif /* STREAMDEVEXT */ - Reply(250, "%d %s", channel->Number(), *channel->ToText()); - } - else -@@ -1466,6 +1485,38 @@ void cSVDRP::CmdSCAN(const char *Option) - Reply(250, "EPG scan triggered"); - } - -+#ifdef USE_LIEMIEXT -+void cSVDRP::CmdRENR(const char *Option) -+{ -+ bool recordings = Recordings.Update(true); -+ if (recordings) { -+ if (*Option) { -+ char *tail; -+ int n = strtol(Option, &tail, 10); -+ cRecording *recording = Recordings.Get(n - 1); -+ if (recording && tail && tail != Option) { -+ char *oldName = strdup(recording->Name()); -+ tail = skipspace(tail); -+ if (recording->Rename(tail)) { -+ Reply(250, "Renamed \"%s\" to \"%s\"", oldName, recording->Name()); -+ Recordings.ChangeState(); -+ Recordings.TouchUpdate(); -+ } -+ else -+ Reply(501, "Renaming \"%s\" to \"%s\" failed", oldName, tail); -+ free(oldName); -+ } -+ else -+ Reply(501, "Recording not found or wrong syntax"); -+ } -+ else -+ Reply(501, "Missing Input settings"); -+ } -+ else -+ Reply(550, "No recordings available"); -+} -+#endif /* LIEMIEXT */ -+ - void cSVDRP::CmdSTAT(const char *Option) - { - if (*Option) { -@@ -1581,6 +1632,9 @@ void cSVDRP::Execute(char *Cmd) - else if (CMD("PLUG")) CmdPLUG(s); - else if (CMD("PUTE")) CmdPUTE(s); - else if (CMD("REMO")) CmdREMO(s); -+#ifdef USE_LIEMIEXT -+ else if (CMD("RENR")) CmdRENR(s); -+#endif /* LIEMIEXT */ - else if (CMD("SCAN")) CmdSCAN(s); - else if (CMD("STAT")) CmdSTAT(s); - else if (CMD("UPDT")) CmdUPDT(s); -diff -ruNp vdr-1.7.5/svdrp.h vdr-1.7.5-extensions/svdrp.h ---- vdr-1.7.5/svdrp.h 2007-04-30 14:28:28.000000000 +0200 -+++ vdr-1.7.5-extensions/svdrp.h 2009-04-12 13:37:59.000000000 +0200 -@@ -79,6 +79,9 @@ private: - void CmdPLUG(const char *Option); - void CmdPUTE(const char *Option); - void CmdREMO(const char *Option); -+#ifdef USE_LIEMIEXT -+ void CmdRENR(const char *Option); -+#endif /* LIEMIEXT */ - void CmdSCAN(const char *Option); - void CmdSTAT(const char *Option); - void CmdUPDT(const char *Option); -diff -ruNp vdr-1.7.5/timers.c vdr-1.7.5-extensions/timers.c ---- vdr-1.7.5/timers.c 2008-04-13 14:41:41.000000000 +0200 -+++ vdr-1.7.5-extensions/timers.c 2009-04-12 13:37:59.000000000 +0200 -@@ -46,6 +46,9 @@ cTimer::cTimer(bool Instant, bool Pause, - stop -= 2400; - priority = Pause ? Setup.PausePriority : Setup.DefaultPriority; - lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime; -+#ifdef USE_PINPLUGIN -+ fskProtection = 0; -+#endif /* PINPLUGIN */ - *file = 0; - aux = NULL; - event = NULL; -@@ -79,12 +82,18 @@ cTimer::cTimer(const cEvent *Event) - stop -= 2400; - priority = Setup.DefaultPriority; - lifetime = Setup.DefaultLifetime; -+#ifdef USE_PINPLUGIN -+ fskProtection = 0; -+#endif /* PINPLUGIN */ - *file = 0; - const char *Title = Event->Title(); - if (!isempty(Title)) - Utf8Strn0Cpy(file, Event->Title(), sizeof(file)); - aux = NULL; - event = NULL; // let SetEvent() be called to get a log message -+#ifdef USE_PINPLUGIN -+ cStatus::MsgTimerCreation(this, Event); -+#endif /* PINPLUGIN */ - } - - cTimer::cTimer(const cTimer &Timer) -@@ -119,6 +128,9 @@ cTimer& cTimer::operator= (const cTimer - stop = Timer.stop; - priority = Timer.priority; - lifetime = Timer.lifetime; -+#ifdef USE_PINPLUGIN -+ fskProtection = Timer.fskProtection; -+#endif /* PINPLUGIN */ - strncpy(file, Timer.file, sizeof(file)); - free(aux); - aux = Timer.aux ? strdup(Timer.aux) : NULL; -@@ -313,6 +325,9 @@ bool cTimer::Parse(const char *s) - result = false; - } - } -+#ifdef USE_PINPLUGIN -+ fskProtection = aux && strstr(aux, "<pin-plugin><protected>yes</protected></pin-plugin>"); -+#endif /* PINPLUGIN */ - free(channelbuffer); - free(daybuffer); - free(filebuffer); -@@ -559,6 +574,9 @@ void cTimer::SetRecording(bool Recording - SetFlags(tfRecording); - else - ClrFlags(tfRecording); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgRecordingChange(NULL, scAdd); -+#endif /* STREAMDEVEXT */ - isyslog("timer %s %s", *ToDescr(), recording ? "start" : "stop"); - } - -@@ -622,6 +640,35 @@ void cTimer::OnOff(void) - Matches(); // refresh start and end time - } - -+#ifdef USE_PINPLUGIN -+void cTimer::SetFskProtection(int aFlag) -+{ -+ char* p; -+ char* tmp = 0; -+ -+ fskProtection = aFlag; -+ -+ if (fskProtection && (!aux || !strstr(aux, "<pin-plugin><protected>yes</protected></pin-plugin>"))) -+ { -+ // add protection info to aux -+ -+ if (aux) { tmp = strdup(aux); free(aux); } -+ asprintf(&aux,"%s<pin-plugin><protected>yes</protected></pin-plugin>", tmp ? tmp : ""); -+ } -+ else if (!fskProtection && aux && (p = strstr(aux, "<pin-plugin><protected>yes</protected></pin-plugin>"))) -+ { -+ // remove protection info to aux -+ -+ asprintf(&tmp, "%.*s%s", p-aux, aux, p+strlen("<pin-plugin><protected>yes</protected></pin-plugin>")); -+ free(aux); -+ aux = strdup(tmp); -+ } -+ -+ if (tmp) -+ free(tmp); -+} -+#endif /* PINPLUGIN */ -+ - // --- cTimers --------------------------------------------------------------- - - cTimers Timers; -diff -ruNp vdr-1.7.5/timers.h vdr-1.7.5-extensions/timers.h ---- vdr-1.7.5/timers.h 2008-02-16 15:33:23.000000000 +0100 -+++ vdr-1.7.5-extensions/timers.h 2009-04-12 13:37:59.000000000 +0200 -@@ -37,6 +37,9 @@ private: - int start; - int stop; - int priority; -+#ifdef USE_PINPLUGIN -+ int fskProtection; -+#endif /* PINPLUGIN */ - int lifetime; - mutable char file[MaxFileName]; - char *aux; -@@ -58,6 +61,9 @@ public: - int Start(void) const { return start; } - int Stop(void) const { return stop; } - int Priority(void) const { return priority; } -+#ifdef USE_PINPLUGIN -+ int FskProtection(void) const { return fskProtection; } -+#endif /* PINPLUGIN */ - int Lifetime(void) const { return lifetime; } - const char *File(void) const { return file; } - time_t FirstDay(void) const { return weekdays ? day : 0; } -@@ -86,6 +92,9 @@ public: - void SetInVpsMargin(bool InVpsMargin); - void SetPriority(int Priority); - void SetFlags(uint Flags); -+#ifdef USE_PINPLUGIN -+ void SetFskProtection(int aFlag); -+#endif /* PINPLUGIN */ - void ClrFlags(uint Flags); - void InvFlags(uint Flags); - bool HasFlags(uint Flags) const; -diff -ruNp vdr-1.7.5/tinystr.c vdr-1.7.5-extensions/tinystr.c ---- vdr-1.7.5/tinystr.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/tinystr.c 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,301 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original file by Yves Berquin. -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include "tinyxml.h" -+ -+#ifndef TIXML_USE_STL -+ -+ -+#include <stdlib.h> -+#include <string.h> -+#include <ctype.h> -+ -+#include "tinystr.h" -+ -+// TiXmlString constructor, based on a C string -+TiXmlString::TiXmlString (const char* instring) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ if (!instring) -+ { -+ allocated = 0; -+ cstring = NULL; -+ current_length = 0; -+ return; -+ } -+ newlen = strlen (instring) + 1; -+ newstring = new char [newlen]; -+ memcpy (newstring, instring, newlen); -+ // strcpy (newstring, instring); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+// TiXmlString copy constructor -+TiXmlString::TiXmlString (const TiXmlString& copy) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ // Prevent copy to self! -+ if ( © == this ) -+ return; -+ -+ if (! copy . allocated) -+ { -+ allocated = 0; -+ cstring = NULL; -+ current_length = 0; -+ return; -+ } -+ newlen = copy . length () + 1; -+ newstring = new char [newlen]; -+ // strcpy (newstring, copy . cstring); -+ memcpy (newstring, copy . cstring, newlen); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+// TiXmlString = operator. Safe when assign own content -+void TiXmlString ::operator = (const char * content) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ if (! content) -+ { -+ empty_it (); -+ return; -+ } -+ newlen = strlen (content) + 1; -+ newstring = new char [newlen]; -+ // strcpy (newstring, content); -+ memcpy (newstring, content, newlen); -+ empty_it (); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+// = operator. Safe when assign own content -+void TiXmlString ::operator = (const TiXmlString & copy) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ if (! copy . length ()) -+ { -+ empty_it (); -+ return; -+ } -+ newlen = copy . length () + 1; -+ newstring = new char [newlen]; -+ // strcpy (newstring, copy . c_str ()); -+ memcpy (newstring, copy . c_str (), newlen); -+ empty_it (); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+ -+// append a const char * to an existing TiXmlString -+void TiXmlString::append( const char* str, int len ) -+{ -+ char * new_string; -+ unsigned new_alloc, new_size, size_suffix; -+ -+ // don't use strlen - it can overrun the len passed in! -+ const char* p = str; -+ size_suffix = 0; -+ -+ while ( *p && size_suffix < (unsigned)len ) -+ { -+ ++p; -+ ++size_suffix; -+ } -+ if ( !size_suffix) -+ return; -+ -+ new_size = length () + size_suffix + 1; -+ // check if we need to expand -+ if (new_size > allocated) -+ { -+ // compute new size -+ new_alloc = assign_new_size (new_size); -+ -+ // allocate new buffer -+ new_string = new char [new_alloc]; -+ new_string [0] = 0; -+ -+ // copy the previous allocated buffer into this one -+ if (allocated && cstring) -+ // strcpy (new_string, cstring); -+ memcpy (new_string, cstring, length ()); -+ -+ // append the suffix. It does exist, otherwize we wouldn't be expanding -+ // strncat (new_string, str, len); -+ memcpy (new_string + length (), -+ str, -+ size_suffix); -+ -+ // return previsously allocated buffer if any -+ if (allocated && cstring) -+ delete [] cstring; -+ -+ // update member variables -+ cstring = new_string; -+ allocated = new_alloc; -+ } -+ else -+ { -+ // we know we can safely append the new string -+ // strncat (cstring, str, len); -+ memcpy (cstring + length (), -+ str, -+ size_suffix); -+ } -+ current_length = new_size - 1; -+ cstring [current_length] = 0; -+} -+ -+ -+// append a const char * to an existing TiXmlString -+void TiXmlString::append( const char * suffix ) -+{ -+ char * new_string; -+ unsigned new_alloc, new_size; -+ -+ new_size = length () + strlen (suffix) + 1; -+ // check if we need to expand -+ if (new_size > allocated) -+ { -+ // compute new size -+ new_alloc = assign_new_size (new_size); -+ -+ // allocate new buffer -+ new_string = new char [new_alloc]; -+ new_string [0] = 0; -+ -+ // copy the previous allocated buffer into this one -+ if (allocated && cstring) -+ memcpy (new_string, cstring, 1 + length ()); -+ // strcpy (new_string, cstring); -+ -+ // append the suffix. It does exist, otherwize we wouldn't be expanding -+ // strcat (new_string, suffix); -+ memcpy (new_string + length (), -+ suffix, -+ strlen (suffix) + 1); -+ -+ // return previsously allocated buffer if any -+ if (allocated && cstring) -+ delete [] cstring; -+ -+ // update member variables -+ cstring = new_string; -+ allocated = new_alloc; -+ } -+ else -+ { -+ // we know we can safely append the new string -+ // strcat (cstring, suffix); -+ memcpy (cstring + length (), -+ suffix, -+ strlen (suffix) + 1); -+ } -+ current_length = new_size - 1; -+} -+ -+// Check for TiXmlString equuivalence -+//bool TiXmlString::operator == (const TiXmlString & compare) const -+//{ -+// return (! strcmp (c_str (), compare . c_str ())); -+//} -+ -+//unsigned TiXmlString::length () const -+//{ -+// if (allocated) -+// // return strlen (cstring); -+// return current_length; -+// return 0; -+//} -+ -+ -+unsigned TiXmlString::find (char tofind, unsigned offset) const -+{ -+ char * lookup; -+ -+ if (offset >= length ()) -+ return (unsigned) notfound; -+ for (lookup = cstring + offset; * lookup; lookup++) -+ if (* lookup == tofind) -+ return lookup - cstring; -+ return (unsigned) notfound; -+} -+ -+ -+bool TiXmlString::operator == (const TiXmlString & compare) const -+{ -+ if ( allocated && compare.allocated ) -+ { -+ assert( cstring ); -+ assert( compare.cstring ); -+ return ( strcmp( cstring, compare.cstring ) == 0 ); -+ } -+ return false; -+} -+ -+ -+bool TiXmlString::operator < (const TiXmlString & compare) const -+{ -+ if ( allocated && compare.allocated ) -+ { -+ assert( cstring ); -+ assert( compare.cstring ); -+ return ( strcmp( cstring, compare.cstring ) > 0 ); -+ } -+ return false; -+} -+ -+ -+bool TiXmlString::operator > (const TiXmlString & compare) const -+{ -+ if ( allocated && compare.allocated ) -+ { -+ assert( cstring ); -+ assert( compare.cstring ); -+ return ( strcmp( cstring, compare.cstring ) < 0 ); -+ } -+ return false; -+} -+ -+ -+#endif // TIXML_USE_STL -+#endif /* SETUP */ -diff -ruNp vdr-1.7.5/tinystr.h vdr-1.7.5-extensions/tinystr.h ---- vdr-1.7.5/tinystr.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/tinystr.h 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,244 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original file by Yves Berquin. -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include "tinyxml.h" -+ -+ -+#ifndef TIXML_USE_STL -+ -+#ifndef TIXML_STRING_INCLUDED -+#define TIXML_STRING_INCLUDED -+ -+#ifdef _MSC_VER -+#pragma warning( disable : 4786 ) // Debugger truncating names. -+#endif -+ -+#include <assert.h> -+ -+/* -+ TiXmlString is an emulation of the std::string template. -+ Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. -+ Only the member functions relevant to the TinyXML project have been implemented. -+ The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase -+ a string and there's no more room, we allocate a buffer twice as big as we need. -+*/ -+class TiXmlString -+{ -+ public : -+ // TiXmlString constructor, based on a string -+ TiXmlString (const char * instring); -+ -+ // TiXmlString empty constructor -+ TiXmlString () -+ { -+ allocated = 0; -+ cstring = NULL; -+ current_length = 0; -+ } -+ -+ // TiXmlString copy constructor -+ TiXmlString (const TiXmlString& copy); -+ -+ // TiXmlString destructor -+ ~ TiXmlString () -+ { -+ empty_it (); -+ } -+ -+ // Convert a TiXmlString into a classical char * -+ const char * c_str () const -+ { -+ if (allocated) -+ return cstring; -+ return ""; -+ } -+ -+ // Return the length of a TiXmlString -+ unsigned length () const -+ { -+ return ( allocated ) ? current_length : 0; -+ } -+ -+ // TiXmlString = operator -+ void operator = (const char * content); -+ -+ // = operator -+ void operator = (const TiXmlString & copy); -+ -+ // += operator. Maps to append -+ TiXmlString& operator += (const char * suffix) -+ { -+ append (suffix); -+ return *this; -+ } -+ -+ // += operator. Maps to append -+ TiXmlString& operator += (char single) -+ { -+ append (single); -+ return *this; -+ } -+ -+ // += operator. Maps to append -+ TiXmlString& operator += (TiXmlString & suffix) -+ { -+ append (suffix); -+ return *this; -+ } -+ bool operator == (const TiXmlString & compare) const; -+ bool operator < (const TiXmlString & compare) const; -+ bool operator > (const TiXmlString & compare) const; -+ -+ // Checks if a TiXmlString is empty -+ bool empty () const -+ { -+ return length () ? false : true; -+ } -+ -+ // single char extraction -+ const char& at (unsigned index) const -+ { -+ assert( index < length ()); -+ return cstring [index]; -+ } -+ -+ // find a char in a string. Return TiXmlString::notfound if not found -+ unsigned find (char lookup) const -+ { -+ return find (lookup, 0); -+ } -+ -+ // find a char in a string from an offset. Return TiXmlString::notfound if not found -+ unsigned find (char tofind, unsigned offset) const; -+ -+ /* Function to reserve a big amount of data when we know we'll need it. Be aware that this -+ function clears the content of the TiXmlString if any exists. -+ */ -+ void reserve (unsigned size) -+ { -+ empty_it (); -+ if (size) -+ { -+ allocated = size; -+ cstring = new char [size]; -+ cstring [0] = 0; -+ current_length = 0; -+ } -+ } -+ -+ // [] operator -+ char& operator [] (unsigned index) const -+ { -+ assert( index < length ()); -+ return cstring [index]; -+ } -+ -+ // Error value for find primitive -+ enum { notfound = 0xffffffff, -+ npos = notfound }; -+ -+ void append (const char *str, int len ); -+ -+ protected : -+ -+ // The base string -+ char * cstring; -+ // Number of chars allocated -+ unsigned allocated; -+ // Current string size -+ unsigned current_length; -+ -+ // New size computation. It is simplistic right now : it returns twice the amount -+ // we need -+ unsigned assign_new_size (unsigned minimum_to_allocate) -+ { -+ return minimum_to_allocate * 2; -+ } -+ -+ // Internal function that clears the content of a TiXmlString -+ void empty_it () -+ { -+ if (cstring) -+ delete [] cstring; -+ cstring = NULL; -+ allocated = 0; -+ current_length = 0; -+ } -+ -+ void append (const char *suffix ); -+ -+ // append function for another TiXmlString -+ void append (const TiXmlString & suffix) -+ { -+ append (suffix . c_str ()); -+ } -+ -+ // append for a single char. -+ void append (char single) -+ { -+ if ( cstring && current_length < (allocated-1) ) -+ { -+ cstring[ current_length ] = single; -+ ++current_length; -+ cstring[ current_length ] = 0; -+ } -+ else -+ { -+ char smallstr [2]; -+ smallstr [0] = single; -+ smallstr [1] = 0; -+ append (smallstr); -+ } -+ } -+ -+} ; -+ -+/* -+ TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. -+ Only the operators that we need for TinyXML have been developped. -+*/ -+class TiXmlOutStream : public TiXmlString -+{ -+public : -+ TiXmlOutStream () : TiXmlString () {} -+ -+ // TiXmlOutStream << operator. Maps to TiXmlString::append -+ TiXmlOutStream & operator << (const char * in) -+ { -+ append (in); -+ return (* this); -+ } -+ -+ // TiXmlOutStream << operator. Maps to TiXmlString::append -+ TiXmlOutStream & operator << (const TiXmlString & in) -+ { -+ append (in . c_str ()); -+ return (* this); -+ } -+} ; -+ -+#endif // TIXML_STRING_INCLUDED -+#endif // TIXML_USE_STL -+#endif /* SETUP */ -diff -ruNp vdr-1.7.5/tinyxml.c vdr-1.7.5-extensions/tinyxml.c ---- vdr-1.7.5/tinyxml.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/tinyxml.c 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,1429 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include <ctype.h> -+#include "tinyxml.h" -+ -+#ifdef TIXML_USE_STL -+#include <sstream> -+#endif -+ -+ -+bool TiXmlBase::condenseWhiteSpace = true; -+ -+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream ) -+{ -+ TIXML_STRING buffer; -+ PutString( str, &buffer ); -+ (*stream) << buffer; -+} -+ -+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString ) -+{ -+ int i=0; -+ -+ while( i<(int)str.length() ) -+ { -+ unsigned char c = (unsigned char) str[i]; -+ -+ if ( c == '&' -+ && i < ( (int)str.length() - 2 ) -+ && str[i+1] == '#' -+ && str[i+2] == 'x' ) -+ { -+ // Hexadecimal character reference. -+ // Pass through unchanged. -+ // © -- copyright symbol, for example. -+ // -+ // The -1 is a bug fix from Rob Laveaux. It keeps -+ // an overflow from happening if there is no ';'. -+ // There are actually 2 ways to exit this loop - -+ // while fails (error case) and break (semicolon found). -+ // However, there is no mechanism (currently) for -+ // this function to return an error. -+ while ( i<(int)str.length()-1 ) -+ { -+ outString->append( str.c_str() + i, 1 ); -+ ++i; -+ if ( str[i] == ';' ) -+ break; -+ } -+ } -+ else if ( c == '&' ) -+ { -+ outString->append( entity[0].str, entity[0].strLength ); -+ ++i; -+ } -+ else if ( c == '<' ) -+ { -+ outString->append( entity[1].str, entity[1].strLength ); -+ ++i; -+ } -+ else if ( c == '>' ) -+ { -+ outString->append( entity[2].str, entity[2].strLength ); -+ ++i; -+ } -+ else if ( c == '\"' ) -+ { -+ outString->append( entity[3].str, entity[3].strLength ); -+ ++i; -+ } -+ else if ( c == '\'' ) -+ { -+ outString->append( entity[4].str, entity[4].strLength ); -+ ++i; -+ } -+ else if ( c < 32 ) -+ { -+ // Easy pass at non-alpha/numeric/symbol -+ // Below 32 is symbolic. -+ char buf[ 32 ]; -+ sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); -+ outString->append( buf, strlen( buf ) ); -+ ++i; -+ } -+ else -+ { -+ //char realc = (char) c; -+ //outString->append( &realc, 1 ); -+ *outString += (char) c; // somewhat more efficient function call. -+ ++i; -+ } -+ } -+} -+ -+ -+// <-- Strange class for a bug fix. Search for STL_STRING_BUG -+TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str ) -+{ -+ buffer = new char[ str.length()+1 ]; -+ if ( buffer ) -+ { -+ strcpy( buffer, str.c_str() ); -+ } -+} -+ -+ -+TiXmlBase::StringToBuffer::~StringToBuffer() -+{ -+ delete [] buffer; -+} -+// End strange bug fix. --> -+ -+ -+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() -+{ -+ parent = 0; -+ type = _type; -+ firstChild = 0; -+ lastChild = 0; -+ prev = 0; -+ next = 0; -+} -+ -+ -+TiXmlNode::~TiXmlNode() -+{ -+ TiXmlNode* node = firstChild; -+ TiXmlNode* temp = 0; -+ -+ while ( node ) -+ { -+ temp = node; -+ node = node->next; -+ delete temp; -+ } -+} -+ -+ -+void TiXmlNode::CopyTo( TiXmlNode* target ) const -+{ -+ target->SetValue (value.c_str() ); -+ target->userData = userData; -+} -+ -+ -+void TiXmlNode::Clear() -+{ -+ TiXmlNode* node = firstChild; -+ TiXmlNode* temp = 0; -+ -+ while ( node ) -+ { -+ temp = node; -+ node = node->next; -+ delete temp; -+ } -+ -+ firstChild = 0; -+ lastChild = 0; -+} -+ -+ -+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) -+{ -+ node->parent = this; -+ -+ node->prev = lastChild; -+ node->next = 0; -+ -+ if ( lastChild ) -+ lastChild->next = node; -+ else -+ firstChild = node; // it was an empty list. -+ -+ lastChild = node; -+ return node; -+} -+ -+ -+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) -+{ -+ TiXmlNode* node = addThis.Clone(); -+ if ( !node ) -+ return 0; -+ -+ return LinkEndChild( node ); -+} -+ -+ -+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) -+{ -+ if ( !beforeThis || beforeThis->parent != this ) -+ return 0; -+ -+ TiXmlNode* node = addThis.Clone(); -+ if ( !node ) -+ return 0; -+ node->parent = this; -+ -+ node->next = beforeThis; -+ node->prev = beforeThis->prev; -+ if ( beforeThis->prev ) -+ { -+ beforeThis->prev->next = node; -+ } -+ else -+ { -+ assert( firstChild == beforeThis ); -+ firstChild = node; -+ } -+ beforeThis->prev = node; -+ return node; -+} -+ -+ -+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) -+{ -+ if ( !afterThis || afterThis->parent != this ) -+ return 0; -+ -+ TiXmlNode* node = addThis.Clone(); -+ if ( !node ) -+ return 0; -+ node->parent = this; -+ -+ node->prev = afterThis; -+ node->next = afterThis->next; -+ if ( afterThis->next ) -+ { -+ afterThis->next->prev = node; -+ } -+ else -+ { -+ assert( lastChild == afterThis ); -+ lastChild = node; -+ } -+ afterThis->next = node; -+ return node; -+} -+ -+ -+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) -+{ -+ if ( replaceThis->parent != this ) -+ return 0; -+ -+ TiXmlNode* node = withThis.Clone(); -+ if ( !node ) -+ return 0; -+ -+ node->next = replaceThis->next; -+ node->prev = replaceThis->prev; -+ -+ if ( replaceThis->next ) -+ replaceThis->next->prev = node; -+ else -+ lastChild = node; -+ -+ if ( replaceThis->prev ) -+ replaceThis->prev->next = node; -+ else -+ firstChild = node; -+ -+ delete replaceThis; -+ node->parent = this; -+ return node; -+} -+ -+ -+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) -+{ -+ if ( removeThis->parent != this ) -+ { -+ assert( 0 ); -+ return false; -+ } -+ -+ if ( removeThis->next ) -+ removeThis->next->prev = removeThis->prev; -+ else -+ lastChild = removeThis->prev; -+ -+ if ( removeThis->prev ) -+ removeThis->prev->next = removeThis->next; -+ else -+ firstChild = removeThis->next; -+ -+ delete removeThis; -+ return true; -+} -+ -+TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = firstChild; node; node = node->next ) -+ { -+ if ( node->SValue() == TIXML_STRING( _value )) -+ return node; -+ } -+ return 0; -+} -+ -+TiXmlNode* TiXmlNode::LastChild( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = lastChild; node; node = node->prev ) -+ { -+ if ( node->SValue() == TIXML_STRING (_value)) -+ return node; -+ } -+ return 0; -+} -+ -+TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) const -+{ -+ if ( !previous ) -+ { -+ return FirstChild(); -+ } -+ else -+ { -+ assert( previous->parent == this ); -+ return previous->NextSibling(); -+ } -+} -+ -+TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous ) const -+{ -+ if ( !previous ) -+ { -+ return FirstChild( val ); -+ } -+ else -+ { -+ assert( previous->parent == this ); -+ return previous->NextSibling( val ); -+ } -+} -+ -+TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = next; node; node = node->next ) -+ { -+ if ( node->SValue() == TIXML_STRING (_value)) -+ return node; -+ } -+ return 0; -+} -+ -+ -+TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = prev; node; node = node->prev ) -+ { -+ if ( node->SValue() == TIXML_STRING (_value)) -+ return node; -+ } -+ return 0; -+} -+ -+void TiXmlElement::RemoveAttribute( const char * name ) -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( node ) -+ { -+ attributeSet.Remove( node ); -+ delete node; -+ } -+} -+ -+TiXmlElement* TiXmlNode::FirstChildElement() const -+{ -+ TiXmlNode* node; -+ -+ for ( node = FirstChild(); -+ node; -+ node = node->NextSibling() ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const -+{ -+ TiXmlNode* node; -+ -+ for ( node = FirstChild( _value ); -+ node; -+ node = node->NextSibling( _value ) ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+ -+TiXmlElement* TiXmlNode::NextSiblingElement() const -+{ -+ TiXmlNode* node; -+ -+ for ( node = NextSibling(); -+ node; -+ node = node->NextSibling() ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const -+{ -+ TiXmlNode* node; -+ -+ for ( node = NextSibling( _value ); -+ node; -+ node = node->NextSibling( _value ) ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+ -+ -+TiXmlDocument* TiXmlNode::GetDocument() const -+{ -+ const TiXmlNode* node; -+ -+ for( node = this; node; node = node->parent ) -+ { -+ if ( node->ToDocument() ) -+ return node->ToDocument(); -+ } -+ return 0; -+} -+ -+ -+TiXmlElement::TiXmlElement (const char * _value) -+ : TiXmlNode( TiXmlNode::ELEMENT ) -+{ -+ firstChild = lastChild = 0; -+ value = _value; -+} -+ -+ -+#ifdef TIXML_USE_STL -+TiXmlElement::TiXmlElement( const std::string& _value ) -+ : TiXmlNode( TiXmlNode::ELEMENT ) -+{ -+ firstChild = lastChild = 0; -+ value = _value; -+} -+#endif -+ -+ -+TiXmlElement::TiXmlElement( const TiXmlElement& copy) -+ : TiXmlNode( TiXmlNode::ELEMENT ) -+{ -+ firstChild = lastChild = 0; -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlElement::operator=( const TiXmlElement& base ) -+{ -+ ClearThis(); -+ base.CopyTo( this ); -+} -+ -+ -+TiXmlElement::~TiXmlElement() -+{ -+ ClearThis(); -+} -+ -+ -+void TiXmlElement::ClearThis() -+{ -+ Clear(); -+ while( attributeSet.First() ) -+ { -+ TiXmlAttribute* node = attributeSet.First(); -+ attributeSet.Remove( node ); -+ delete node; -+ } -+} -+ -+ -+const char * TiXmlElement::Attribute( const char * name ) const -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ -+ if ( node ) -+ return node->Value(); -+ -+ return 0; -+} -+ -+ -+const char * TiXmlElement::Attribute( const char * name, int* i ) const -+{ -+ const char * s = Attribute( name ); -+ if ( i ) -+ { -+ if ( s ) -+ *i = atoi( s ); -+ else -+ *i = 0; -+ } -+ return s; -+} -+ -+ -+const char * TiXmlElement::Attribute( const char * name, double* d ) const -+{ -+ const char * s = Attribute( name ); -+ if ( d ) -+ { -+ if ( s ) -+ *d = atof( s ); -+ else -+ *d = 0; -+ } -+ return s; -+} -+ -+ -+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( !node ) -+ return TIXML_NO_ATTRIBUTE; -+ -+ return node->QueryIntValue( ival ); -+} -+ -+ -+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( !node ) -+ return TIXML_NO_ATTRIBUTE; -+ -+ return node->QueryDoubleValue( dval ); -+} -+ -+ -+void TiXmlElement::SetAttribute( const char * name, int val ) -+{ -+ char buf[64]; -+ sprintf( buf, "%d", val ); -+ SetAttribute( name, buf ); -+} -+ -+ -+void TiXmlElement::SetDoubleAttribute( const char * name, double val ) -+{ -+ char buf[128]; -+ sprintf( buf, "%f", val ); -+ SetAttribute( name, buf ); -+} -+ -+ -+void TiXmlElement::SetAttribute( const char * name, const char * _value ) -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( node ) -+ { -+ node->SetValue( _value ); -+ return; -+ } -+ -+ TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); -+ if ( attrib ) -+ { -+ attributeSet.Add( attrib ); -+ } -+ else -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ } -+} -+ -+void TiXmlElement::Print( FILE* cfile, int depth ) const -+{ -+ int i; -+ for ( i=0; i<depth; i++ ) -+ { -+ fprintf( cfile, " " ); -+ } -+ -+ fprintf( cfile, "<%s", value.c_str() ); -+ -+ TiXmlAttribute* attrib; -+ for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) -+ { -+ fprintf( cfile, " " ); -+ attrib->Print( cfile, depth ); -+ } -+ -+ // There are 3 different formatting approaches: -+ // 1) An element without children is printed as a <foo /> node -+ // 2) An element with only a text child is printed as <foo> text </foo> -+ // 3) An element with children is printed on multiple lines. -+ TiXmlNode* node; -+ if ( !firstChild ) -+ { -+ fprintf( cfile, " />" ); -+ } -+ else if ( firstChild == lastChild && firstChild->ToText() ) -+ { -+ fprintf( cfile, ">" ); -+ firstChild->Print( cfile, depth + 1 ); -+ fprintf( cfile, "</%s>", value.c_str() ); -+ } -+ else -+ { -+ fprintf( cfile, ">" ); -+ -+ for ( node = firstChild; node; node=node->NextSibling() ) -+ { -+ if ( !node->ToText() ) -+ { -+ fprintf( cfile, "\n" ); -+ } -+ node->Print( cfile, depth+1 ); -+ } -+ fprintf( cfile, "\n" ); -+ for( i=0; i<depth; ++i ) -+ fprintf( cfile, " " ); -+ fprintf( cfile, "</%s>", value.c_str() ); -+ } -+} -+ -+void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*stream) << "<" << value; -+ -+ TiXmlAttribute* attrib; -+ for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) -+ { -+ (*stream) << " "; -+ attrib->StreamOut( stream ); -+ } -+ -+ // If this node has children, give it a closing tag. Else -+ // make it an empty tag. -+ TiXmlNode* node; -+ if ( firstChild ) -+ { -+ (*stream) << ">"; -+ -+ for ( node = firstChild; node; node=node->NextSibling() ) -+ { -+ node->StreamOut( stream ); -+ } -+ (*stream) << "</" << value << ">"; -+ } -+ else -+ { -+ (*stream) << " />"; -+ } -+} -+ -+ -+void TiXmlElement::CopyTo( TiXmlElement* target ) const -+{ -+ // superclass: -+ TiXmlNode::CopyTo( target ); -+ -+ // Element class: -+ // Clone the attributes, then clone the children. -+ TiXmlAttribute* attribute = 0; -+ for( attribute = attributeSet.First(); -+ attribute; -+ attribute = attribute->Next() ) -+ { -+ target->SetAttribute( attribute->Name(), attribute->Value() ); -+ } -+ -+ TiXmlNode* node = 0; -+ for ( node = firstChild; node; node = node->NextSibling() ) -+ { -+ target->LinkEndChild( node->Clone() ); -+ } -+} -+ -+ -+TiXmlNode* TiXmlElement::Clone() const -+{ -+ TiXmlElement* clone = new TiXmlElement( Value() ); -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) -+{ -+ tabsize = 4; -+ ClearError(); -+} -+ -+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) -+{ -+ tabsize = 4; -+ value = documentName; -+ ClearError(); -+} -+ -+ -+#ifdef TIXML_USE_STL -+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) -+{ -+ tabsize = 4; -+ value = documentName; -+ ClearError(); -+} -+#endif -+ -+ -+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) -+{ -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlDocument::operator=( const TiXmlDocument& copy ) -+{ -+ Clear(); -+ copy.CopyTo( this ); -+} -+ -+ -+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) -+{ -+ // See STL_STRING_BUG below. -+ StringToBuffer buf( value ); -+ -+ if ( buf.buffer && LoadFile( buf.buffer, encoding ) ) -+ return true; -+ -+ return false; -+} -+ -+ -+bool TiXmlDocument::SaveFile() const -+{ -+ // See STL_STRING_BUG below. -+ StringToBuffer buf( value ); -+ -+ if ( buf.buffer && SaveFile( buf.buffer ) ) -+ return true; -+ -+ return false; -+} -+ -+bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding ) -+{ -+ // Delete the existing data: -+ Clear(); -+ location.Clear(); -+ -+ // There was a really terrifying little bug here. The code: -+ // value = filename -+ // in the STL case, cause the assignment method of the std::string to -+ // be called. What is strange, is that the std::string had the same -+ // address as it's c_str() method, and so bad things happen. Looks -+ // like a bug in the Microsoft STL implementation. -+ // See STL_STRING_BUG above. -+ // Fixed with the StringToBuffer class. -+ value = filename; -+ -+ FILE* file = fopen( value.c_str (), "r" ); -+ -+ if ( file ) -+ { -+ // Get the file size, so we can pre-allocate the string. HUGE speed impact. -+ long length = 0; -+ fseek( file, 0, SEEK_END ); -+ length = ftell( file ); -+ fseek( file, 0, SEEK_SET ); -+ -+ // Strange case, but good to handle up front. -+ if ( length == 0 ) -+ { -+ fclose( file ); -+ return false; -+ } -+ -+ // If we have a file, assume it is all one big XML file, and read it in. -+ // The document parser may decide the document ends sooner than the entire file, however. -+ TIXML_STRING data; -+ data.reserve( length ); -+ -+ const int BUF_SIZE = 2048; -+ char buf[BUF_SIZE]; -+ -+ while( fgets( buf, BUF_SIZE, file ) ) -+ { -+ data += buf; -+ } -+ fclose( file ); -+ -+ Parse( data.c_str(), 0, encoding ); -+ -+ if ( Error() ) -+ return false; -+ else -+ return true; -+ } -+ SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return false; -+} -+ -+bool TiXmlDocument::SaveFile( const char * filename ) const -+{ -+ // The old c stuff lives on... -+ FILE* fp = fopen( filename, "w" ); -+ if ( fp ) -+ { -+ Print( fp, 0 ); -+ fclose( fp ); -+ return true; -+ } -+ return false; -+} -+ -+ -+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+ -+ target->error = error; -+ target->errorDesc = errorDesc.c_str (); -+ -+ TiXmlNode* node = 0; -+ for ( node = firstChild; node; node = node->NextSibling() ) -+ { -+ target->LinkEndChild( node->Clone() ); -+ } -+} -+ -+ -+TiXmlNode* TiXmlDocument::Clone() const -+{ -+ TiXmlDocument* clone = new TiXmlDocument(); -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+void TiXmlDocument::Print( FILE* cfile, int depth ) const -+{ -+ TiXmlNode* node; -+ for ( node=FirstChild(); node; node=node->NextSibling() ) -+ { -+ node->Print( cfile, depth ); -+ fprintf( cfile, "\n" ); -+ } -+} -+ -+void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const -+{ -+ TiXmlNode* node; -+ for ( node=FirstChild(); node; node=node->NextSibling() ) -+ { -+ node->StreamOut( out ); -+ -+ // Special rule for streams: stop after the root element. -+ // The stream in code will only read one element, so don't -+ // write more than one. -+ if ( node->ToElement() ) -+ break; -+ } -+} -+ -+ -+TiXmlAttribute* TiXmlAttribute::Next() const -+{ -+ // We are using knowledge of the sentinel. The sentinel -+ // have a value or name. -+ if ( next->value.empty() && next->name.empty() ) -+ return 0; -+ return next; -+} -+ -+ -+TiXmlAttribute* TiXmlAttribute::Previous() const -+{ -+ // We are using knowledge of the sentinel. The sentinel -+ // have a value or name. -+ if ( prev->value.empty() && prev->name.empty() ) -+ return 0; -+ return prev; -+} -+ -+ -+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const -+{ -+ TIXML_STRING n, v; -+ -+ PutString( name, &n ); -+ PutString( value, &v ); -+ -+ if (value.find ('\"') == TIXML_STRING::npos) -+ fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); -+ else -+ fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); -+} -+ -+ -+void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ if (value.find( '\"' ) != TIXML_STRING::npos) -+ { -+ PutString( name, stream ); -+ (*stream) << "=" << "'"; -+ PutString( value, stream ); -+ (*stream) << "'"; -+ } -+ else -+ { -+ PutString( name, stream ); -+ (*stream) << "=" << "\""; -+ PutString( value, stream ); -+ (*stream) << "\""; -+ } -+} -+ -+int TiXmlAttribute::QueryIntValue( int* ival ) const -+{ -+ if ( sscanf( value.c_str(), "%d", ival ) == 1 ) -+ return TIXML_SUCCESS; -+ return TIXML_WRONG_TYPE; -+} -+ -+int TiXmlAttribute::QueryDoubleValue( double* dval ) const -+{ -+ if ( sscanf( value.c_str(), "%lf", dval ) == 1 ) -+ return TIXML_SUCCESS; -+ return TIXML_WRONG_TYPE; -+} -+ -+void TiXmlAttribute::SetIntValue( int _value ) -+{ -+ char buf [64]; -+ sprintf (buf, "%d", _value); -+ SetValue (buf); -+} -+ -+void TiXmlAttribute::SetDoubleValue( double _value ) -+{ -+ char buf [64]; -+ sprintf (buf, "%lf", _value); -+ SetValue (buf); -+} -+ -+const int TiXmlAttribute::IntValue() const -+{ -+ return atoi (value.c_str ()); -+} -+ -+const double TiXmlAttribute::DoubleValue() const -+{ -+ return atof (value.c_str ()); -+} -+ -+ -+TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) -+{ -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlComment::operator=( const TiXmlComment& base ) -+{ -+ Clear(); -+ base.CopyTo( this ); -+} -+ -+ -+void TiXmlComment::Print( FILE* cfile, int depth ) const -+{ -+ for ( int i=0; i<depth; i++ ) -+ { -+ fputs( " ", cfile ); -+ } -+ fprintf( cfile, "<!--%s-->", value.c_str() ); -+} -+ -+void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*stream) << "<!--"; -+ //PutString( value, stream ); -+ (*stream) << value; -+ (*stream) << "-->"; -+} -+ -+ -+void TiXmlComment::CopyTo( TiXmlComment* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+} -+ -+ -+TiXmlNode* TiXmlComment::Clone() const -+{ -+ TiXmlComment* clone = new TiXmlComment(); -+ -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const -+{ -+ TIXML_STRING buffer; -+ PutString( value, &buffer ); -+ fprintf( cfile, "%s", buffer.c_str() ); -+} -+ -+ -+void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ PutString( value, stream ); -+} -+ -+ -+void TiXmlText::CopyTo( TiXmlText* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+} -+ -+ -+TiXmlNode* TiXmlText::Clone() const -+{ -+ TiXmlText* clone = 0; -+ clone = new TiXmlText( "" ); -+ -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+TiXmlDeclaration::TiXmlDeclaration( const char * _version, -+ const char * _encoding, -+ const char * _standalone ) -+ : TiXmlNode( TiXmlNode::DECLARATION ) -+{ -+ version = _version; -+ encoding = _encoding; -+ standalone = _standalone; -+} -+ -+ -+#ifdef TIXML_USE_STL -+TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, -+ const std::string& _encoding, -+ const std::string& _standalone ) -+ : TiXmlNode( TiXmlNode::DECLARATION ) -+{ -+ version = _version; -+ encoding = _encoding; -+ standalone = _standalone; -+} -+#endif -+ -+ -+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) -+ : TiXmlNode( TiXmlNode::DECLARATION ) -+{ -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) -+{ -+ Clear(); -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const -+{ -+ fprintf (cfile, "<?xml "); -+ -+ if ( !version.empty() ) -+ fprintf (cfile, "version=\"%s\" ", version.c_str ()); -+ if ( !encoding.empty() ) -+ fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ()); -+ if ( !standalone.empty() ) -+ fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ()); -+ fprintf (cfile, "?>"); -+} -+ -+void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*stream) << "<?xml "; -+ -+ if ( !version.empty() ) -+ { -+ (*stream) << "version=\""; -+ PutString( version, stream ); -+ (*stream) << "\" "; -+ } -+ if ( !encoding.empty() ) -+ { -+ (*stream) << "encoding=\""; -+ PutString( encoding, stream ); -+ (*stream ) << "\" "; -+ } -+ if ( !standalone.empty() ) -+ { -+ (*stream) << "standalone=\""; -+ PutString( standalone, stream ); -+ (*stream) << "\" "; -+ } -+ (*stream) << "?>"; -+} -+ -+ -+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+ -+ target->version = version; -+ target->encoding = encoding; -+ target->standalone = standalone; -+} -+ -+ -+TiXmlNode* TiXmlDeclaration::Clone() const -+{ -+ TiXmlDeclaration* clone = new TiXmlDeclaration(); -+ -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+void TiXmlUnknown::Print( FILE* cfile, int depth ) const -+{ -+ for ( int i=0; i<depth; i++ ) -+ fprintf( cfile, " " ); -+ fprintf( cfile, "<%s>", value.c_str() ); -+} -+ -+ -+void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown. -+} -+ -+ -+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const -+{ -+ TiXmlNode::CopyTo( target ); -+} -+ -+ -+TiXmlNode* TiXmlUnknown::Clone() const -+{ -+ TiXmlUnknown* clone = new TiXmlUnknown(); -+ -+ if ( !clone ) -+ return 0; -+ -+ CopyTo( clone ); -+ return clone; -+} -+ -+ -+TiXmlAttributeSet::TiXmlAttributeSet() -+{ -+ sentinel.next = &sentinel; -+ sentinel.prev = &sentinel; -+} -+ -+ -+TiXmlAttributeSet::~TiXmlAttributeSet() -+{ -+ assert( sentinel.next == &sentinel ); -+ assert( sentinel.prev == &sentinel ); -+} -+ -+ -+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) -+{ -+ assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. -+ -+ addMe->next = &sentinel; -+ addMe->prev = sentinel.prev; -+ -+ sentinel.prev->next = addMe; -+ sentinel.prev = addMe; -+} -+ -+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) -+{ -+ TiXmlAttribute* node; -+ -+ for( node = sentinel.next; node != &sentinel; node = node->next ) -+ { -+ if ( node == removeMe ) -+ { -+ node->prev->next = node->next; -+ node->next->prev = node->prev; -+ node->next = 0; -+ node->prev = 0; -+ return; -+ } -+ } -+ assert( 0 ); // we tried to remove a non-linked attribute. -+} -+ -+TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const -+{ -+ TiXmlAttribute* node; -+ -+ for( node = sentinel.next; node != &sentinel; node = node->next ) -+ { -+ if ( node->name == name ) -+ return node; -+ } -+ return 0; -+} -+ -+ -+#ifdef TIXML_USE_STL -+TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base) -+{ -+ TIXML_STRING tag; -+ tag.reserve( 8 * 1000 ); -+ base.StreamIn( &in, &tag ); -+ -+ base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); -+ return in; -+} -+#endif -+ -+ -+TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base) -+{ -+ base.StreamOut (& out); -+ return out; -+} -+ -+ -+#ifdef TIXML_USE_STL -+std::string & operator<< (std::string& out, const TiXmlNode& base ) -+{ -+ std::ostringstream os_stream( std::ostringstream::out ); -+ base.StreamOut( &os_stream ); -+ -+ out.append( os_stream.str() ); -+ return out; -+} -+#endif -+ -+ -+TiXmlHandle TiXmlHandle::FirstChild() const -+{ -+ if ( node ) -+ { -+ TiXmlNode* child = node->FirstChild(); -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const -+{ -+ if ( node ) -+ { -+ TiXmlNode* child = node->FirstChild( value ); -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::FirstChildElement() const -+{ -+ if ( node ) -+ { -+ TiXmlElement* child = node->FirstChildElement(); -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const -+{ -+ if ( node ) -+ { -+ TiXmlElement* child = node->FirstChildElement( value ); -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::Child( int count ) const -+{ -+ if ( node ) -+ { -+ int i; -+ TiXmlNode* child = node->FirstChild(); -+ for ( i=0; -+ child && i<count; -+ child = child->NextSibling(), ++i ) -+ { -+ // nothing -+ } -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const -+{ -+ if ( node ) -+ { -+ int i; -+ TiXmlNode* child = node->FirstChild( value ); -+ for ( i=0; -+ child && i<count; -+ child = child->NextSibling( value ), ++i ) -+ { -+ // nothing -+ } -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::ChildElement( int count ) const -+{ -+ if ( node ) -+ { -+ int i; -+ TiXmlElement* child = node->FirstChildElement(); -+ for ( i=0; -+ child && i<count; -+ child = child->NextSiblingElement(), ++i ) -+ { -+ // nothing -+ } -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+ -+ -+TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const -+{ -+ if ( node ) -+ { -+ int i; -+ TiXmlElement* child = node->FirstChildElement( value ); -+ for ( i=0; -+ child && i<count; -+ child = child->NextSiblingElement( value ), ++i ) -+ { -+ // nothing -+ } -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+#endif /* SETUP */ -diff -ruNp vdr-1.7.5/tinyxmlerror.c vdr-1.7.5-extensions/tinyxmlerror.c ---- vdr-1.7.5/tinyxmlerror.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/tinyxmlerror.c 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,53 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include "tinyxml.h" -+ -+// The goal of the seperate error file is to make the first -+// step towards localization. tinyxml (currently) only supports -+// latin-1, but at least the error messages could now be translated. -+// -+// It also cleans up the code a bit. -+// -+ -+const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = -+{ -+ "No error", -+ "Error", -+ "Failed to open file", -+ "Memory allocation failed.", -+ "Error parsing Element.", -+ "Failed to read Element name", -+ "Error reading Element value.", -+ "Error reading Attributes.", -+ "Error: empty tag.", -+ "Error reading end tag.", -+ "Error parsing Unknown.", -+ "Error parsing Comment.", -+ "Error parsing Declaration.", -+ "Error document empty.", -+ "Error null (0) or unexpected EOF found in input stream.", -+}; -+#endif /* SETUP */ -diff -ruNp vdr-1.7.5/tinyxml.h vdr-1.7.5-extensions/tinyxml.h ---- vdr-1.7.5/tinyxml.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/tinyxml.h 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,1372 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+ -+#ifndef TINYXML_INCLUDED -+#define TINYXML_INCLUDED -+ -+#ifdef _MSC_VER -+#pragma warning( disable : 4530 ) -+#pragma warning( disable : 4786 ) -+#endif -+ -+#include <ctype.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+#include <assert.h> -+ -+// Help out windows: -+#if defined( _DEBUG ) && !defined( DEBUG ) -+#define DEBUG -+#endif -+ -+#if defined( DEBUG ) && defined( _MSC_VER ) -+#include <windows.h> -+#define TIXML_LOG OutputDebugString -+#else -+#define TIXML_LOG printf -+#endif -+ -+#ifdef TIXML_USE_STL -+ #include <string> -+ #include <iostream> -+ #define TIXML_STRING std::string -+ #define TIXML_ISTREAM std::istream -+ #define TIXML_OSTREAM std::ostream -+#else -+ #include "tinystr.h" -+ #define TIXML_STRING TiXmlString -+ #define TIXML_OSTREAM TiXmlOutStream -+#endif -+ -+class TiXmlDocument; -+class TiXmlElement; -+class TiXmlComment; -+class TiXmlUnknown; -+class TiXmlAttribute; -+class TiXmlText; -+class TiXmlDeclaration; -+class TiXmlParsingData; -+ -+const int TIXML_MAJOR_VERSION = 2; -+const int TIXML_MINOR_VERSION = 3; -+const int TIXML_PATCH_VERSION = 2; -+ -+/* Internal structure for tracking location of items -+ in the XML file. -+*/ -+struct TiXmlCursor -+{ -+ TiXmlCursor() { Clear(); } -+ void Clear() { row = col = -1; } -+ -+ int row; // 0 based. -+ int col; // 0 based. -+}; -+ -+ -+// Only used by Attribute::Query functions -+enum -+{ -+ TIXML_SUCCESS, -+ TIXML_NO_ATTRIBUTE, -+ TIXML_WRONG_TYPE -+}; -+ -+ -+// Used by the parsing routines. -+enum TiXmlEncoding -+{ -+ TIXML_ENCODING_UNKNOWN, -+ TIXML_ENCODING_UTF8, -+ TIXML_ENCODING_LEGACY -+}; -+ -+const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; -+ -+/** TiXmlBase is a base class for every class in TinyXml. -+ It does little except to establish that TinyXml classes -+ can be printed and provide some utility functions. -+ -+ In XML, the document and elements can contain -+ other elements and other types of nodes. -+ -+ @verbatim -+ A Document can contain: Element (container or leaf) -+ Comment (leaf) -+ Unknown (leaf) -+ Declaration( leaf ) -+ -+ An Element can contain: Element (container or leaf) -+ Text (leaf) -+ Attributes (not on tree) -+ Comment (leaf) -+ Unknown (leaf) -+ -+ A Decleration contains: Attributes (not on tree) -+ @endverbatim -+*/ -+class TiXmlBase -+{ -+ friend class TiXmlNode; -+ friend class TiXmlElement; -+ friend class TiXmlDocument; -+ -+public: -+ TiXmlBase() : userData(0) {} -+ virtual ~TiXmlBase() {} -+ -+ /** All TinyXml classes can print themselves to a filestream. -+ This is a formatted print, and will insert tabs and newlines. -+ -+ (For an unformatted stream, use the << operator.) -+ */ -+ virtual void Print( FILE* cfile, int depth ) const = 0; -+ -+ /** The world does not agree on whether white space should be kept or -+ not. In order to make everyone happy, these global, static functions -+ are provided to set whether or not TinyXml will condense all white space -+ into a single space or not. The default is to condense. Note changing this -+ values is not thread safe. -+ */ -+ static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } -+ -+ /// Return the current white space setting. -+ static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } -+ -+ /** Return the position, in the original source file, of this node or attribute. -+ The row and column are 1-based. (That is the first row and first column is -+ 1,1). If the returns values are 0 or less, then the parser does not have -+ a row and column value. -+ -+ Generally, the row and column value will be set when the TiXmlDocument::Load(), -+ TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set -+ when the DOM was created from operator>>. -+ -+ The values reflect the initial load. Once the DOM is modified programmatically -+ (by adding or changing nodes and attributes) the new values will NOT update to -+ reflect changes in the document. -+ -+ There is a minor performance cost to computing the row and column. Computation -+ can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. -+ -+ @sa TiXmlDocument::SetTabSize() -+ */ -+ int Row() const { return location.row + 1; } -+ int Column() const { return location.col + 1; } ///< See Row() -+ -+ void SetUserData( void* user ) { userData = user; } -+ void* GetUserData() { return userData; } -+ -+ // Table that returs, for a given lead byte, the total number of bytes -+ // in the UTF-8 sequence. -+ static const int utf8ByteTable[256]; -+ -+ virtual const char* Parse( const char* p, -+ TiXmlParsingData* data, -+ TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; -+ -+protected: -+ -+ // See STL_STRING_BUG -+ // Utility class to overcome a bug. -+ class StringToBuffer -+ { -+ public: -+ StringToBuffer( const TIXML_STRING& str ); -+ ~StringToBuffer(); -+ char* buffer; -+ }; -+ -+ static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); -+ inline static bool IsWhiteSpace( char c ) -+ { -+ return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); -+ } -+ -+ virtual void StreamOut (TIXML_OSTREAM *) const = 0; -+ -+ #ifdef TIXML_USE_STL -+ static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ); -+ #endif -+ -+ /* Reads an XML name into the string provided. Returns -+ a pointer just past the last character of the name, -+ or 0 if the function has an error. -+ */ -+ static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); -+ -+ /* Reads text. Returns a pointer past the given end tag. -+ Wickedly complex options, but it keeps the (sensitive) code in one place. -+ */ -+ static const char* ReadText( const char* in, // where to start -+ TIXML_STRING* text, // the string read -+ bool ignoreWhiteSpace, // whether to keep the white space -+ const char* endTag, // what ends this text -+ bool ignoreCase, // whether to ignore case in the end tag -+ TiXmlEncoding encoding ); // the current encoding -+ -+ // If an entity has been found, transform it into a character. -+ static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); -+ -+ // Get a character, while interpreting entities. -+ // The length can be from 0 to 4 bytes. -+ inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) -+ { -+ assert( p ); -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ *length = utf8ByteTable[ *((unsigned char*)p) ]; -+ assert( *length >= 0 && *length < 5 ); -+ } -+ else -+ { -+ *length = 1; -+ } -+ -+ if ( *length == 1 ) -+ { -+ if ( *p == '&' ) -+ return GetEntity( p, _value, length, encoding ); -+ *_value = *p; -+ return p+1; -+ } -+ else if ( *length ) -+ { -+ strncpy( _value, p, *length ); -+ return p + (*length); -+ } -+ else -+ { -+ // Not valid text. -+ return 0; -+ } -+ } -+ -+ // Puts a string to a stream, expanding entities as it goes. -+ // Note this should not contian the '<', '>', etc, or they will be transformed into entities! -+ static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out ); -+ -+ static void PutString( const TIXML_STRING& str, TIXML_STRING* out ); -+ -+ // Return true if the next characters in the stream are any of the endTag sequences. -+ // Ignore case only works for english, and should only be relied on when comparing -+ // to Engilish words: StringEqual( p, "version", true ) is fine. -+ static bool StringEqual( const char* p, -+ const char* endTag, -+ bool ignoreCase, -+ TiXmlEncoding encoding ); -+ -+ -+ enum -+ { -+ TIXML_NO_ERROR = 0, -+ TIXML_ERROR, -+ TIXML_ERROR_OPENING_FILE, -+ TIXML_ERROR_OUT_OF_MEMORY, -+ TIXML_ERROR_PARSING_ELEMENT, -+ TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, -+ TIXML_ERROR_READING_ELEMENT_VALUE, -+ TIXML_ERROR_READING_ATTRIBUTES, -+ TIXML_ERROR_PARSING_EMPTY, -+ TIXML_ERROR_READING_END_TAG, -+ TIXML_ERROR_PARSING_UNKNOWN, -+ TIXML_ERROR_PARSING_COMMENT, -+ TIXML_ERROR_PARSING_DECLARATION, -+ TIXML_ERROR_DOCUMENT_EMPTY, -+ TIXML_ERROR_EMBEDDED_NULL, -+ -+ TIXML_ERROR_STRING_COUNT -+ }; -+ static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; -+ -+ TiXmlCursor location; -+ -+ /// Field containing a generic user pointer -+ void* userData; -+ -+ // None of these methods are reliable for any language except English. -+ // Good for approximation, not great for accuracy. -+ static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); -+ static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); -+ inline static int ToLower( int v, TiXmlEncoding encoding ) -+ { -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ if ( v < 128 ) return tolower( v ); -+ return v; -+ } -+ else -+ { -+ return tolower( v ); -+ } -+ } -+ static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); -+ -+private: -+ TiXmlBase( const TiXmlBase& ); // not implemented. -+ void operator=( const TiXmlBase& base ); // not allowed. -+ -+ struct Entity -+ { -+ const char* str; -+ unsigned int strLength; -+ char chr; -+ }; -+ enum -+ { -+ NUM_ENTITY = 5, -+ MAX_ENTITY_LENGTH = 6 -+ -+ }; -+ static Entity entity[ NUM_ENTITY ]; -+ static bool condenseWhiteSpace; -+}; -+ -+ -+/** The parent class for everything in the Document Object Model. -+ (Except for attributes). -+ Nodes have siblings, a parent, and children. A node can be -+ in a document, or stand on its own. The type of a TiXmlNode -+ can be queried, and it can be cast to its more defined type. -+*/ -+class TiXmlNode : public TiXmlBase -+{ -+ friend class TiXmlDocument; -+ friend class TiXmlElement; -+ -+public: -+ #ifdef TIXML_USE_STL -+ -+ /** An input stream operator, for every class. Tolerant of newlines and -+ formatting, but doesn't expect them. -+ */ -+ friend std::istream& operator >> (std::istream& in, TiXmlNode& base); -+ -+ /** An output stream operator, for every class. Note that this outputs -+ without any newlines or formatting, as opposed to Print(), which -+ includes tabs and new lines. -+ -+ The operator<< and operator>> are not completely symmetric. Writing -+ a node to a stream is very well defined. You'll get a nice stream -+ of output, without any extra whitespace or newlines. -+ -+ But reading is not as well defined. (As it always is.) If you create -+ a TiXmlElement (for example) and read that from an input stream, -+ the text needs to define an element or junk will result. This is -+ true of all input streams, but it's worth keeping in mind. -+ -+ A TiXmlDocument will read nodes until it reads a root element, and -+ all the children of that root element. -+ */ -+ friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); -+ -+ /// Appends the XML node or attribute to a std::string. -+ friend std::string& operator<< (std::string& out, const TiXmlNode& base ); -+ -+ #else -+ // Used internally, not part of the public API. -+ friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base); -+ #endif -+ -+ /** The types of XML nodes supported by TinyXml. (All the -+ unsupported types are picked up by UNKNOWN.) -+ */ -+ enum NodeType -+ { -+ DOCUMENT, -+ ELEMENT, -+ COMMENT, -+ UNKNOWN, -+ TEXT, -+ DECLARATION, -+ TYPECOUNT -+ }; -+ -+ virtual ~TiXmlNode(); -+ -+ /** The meaning of 'value' changes for the specific type of -+ TiXmlNode. -+ @verbatim -+ Document: filename of the xml file -+ Element: name of the element -+ Comment: the comment text -+ Unknown: the tag contents -+ Text: the text string -+ @endverbatim -+ -+ The subclasses will wrap this function. -+ */ -+ const char * Value() const { return value.c_str (); } -+ -+ /** Changes the value of the node. Defined as: -+ @verbatim -+ Document: filename of the xml file -+ Element: name of the element -+ Comment: the comment text -+ Unknown: the tag contents -+ Text: the text string -+ @endverbatim -+ */ -+ void SetValue(const char * _value) { value = _value;} -+ -+ #ifdef TIXML_USE_STL -+ /// STL std::string form. -+ void SetValue( const std::string& _value ) -+ { -+ StringToBuffer buf( _value ); -+ SetValue( buf.buffer ? buf.buffer : "" ); -+ } -+ #endif -+ -+ /// Delete all the children of this node. Does not affect 'this'. -+ void Clear(); -+ -+ /// One step up the DOM. -+ TiXmlNode* Parent() const { return parent; } -+ -+ TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. -+ TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. -+ -+ TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. -+ TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. -+ -+ #ifdef TIXML_USE_STL -+ TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. -+ TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ /** An alternate way to walk the children of a node. -+ One way to iterate over nodes is: -+ @verbatim -+ for( child = parent->FirstChild(); child; child = child->NextSibling() ) -+ @endverbatim -+ -+ IterateChildren does the same thing with the syntax: -+ @verbatim -+ child = 0; -+ while( child = parent->IterateChildren( child ) ) -+ @endverbatim -+ -+ IterateChildren takes the previous child as input and finds -+ the next one. If the previous child is null, it returns the -+ first. IterateChildren will return null when done. -+ */ -+ TiXmlNode* IterateChildren( TiXmlNode* previous ) const; -+ -+ /// This flavor of IterateChildren searches for children with a particular 'value' -+ TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. -+ #endif -+ -+ /** Add a new node related to this. Adds a child past the LastChild. -+ Returns a pointer to the new object or NULL if an error occured. -+ */ -+ TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); -+ -+ -+ /** Add a new node related to this. Adds a child past the LastChild. -+ -+ NOTE: the node to be added is passed by pointer, and will be -+ henceforth owned (and deleted) by tinyXml. This method is efficient -+ and avoids an extra copy, but should be used with care as it -+ uses a different memory model than the other insert functions. -+ -+ @sa InsertEndChild -+ */ -+ TiXmlNode* LinkEndChild( TiXmlNode* addThis ); -+ -+ /** Add a new node related to this. Adds a child before the specified child. -+ Returns a pointer to the new object or NULL if an error occured. -+ */ -+ TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); -+ -+ /** Add a new node related to this. Adds a child after the specified child. -+ Returns a pointer to the new object or NULL if an error occured. -+ */ -+ TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); -+ -+ /** Replace a child of this node. -+ Returns a pointer to the new object or NULL if an error occured. -+ */ -+ TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); -+ -+ /// Delete a child of this node. -+ bool RemoveChild( TiXmlNode* removeThis ); -+ -+ /// Navigate to a sibling node. -+ TiXmlNode* PreviousSibling() const { return prev; } -+ -+ /// Navigate to a sibling node. -+ TiXmlNode* PreviousSibling( const char * ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. -+ TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ /// Navigate to a sibling node. -+ TiXmlNode* NextSibling() const { return next; } -+ -+ /// Navigate to a sibling node with the given 'value'. -+ TiXmlNode* NextSibling( const char * ) const; -+ -+ /** Convenience function to get through elements. -+ Calls NextSibling and ToElement. Will skip all non-Element -+ nodes. Returns 0 if there is not another element. -+ */ -+ TiXmlElement* NextSiblingElement() const; -+ -+ /** Convenience function to get through elements. -+ Calls NextSibling and ToElement. Will skip all non-Element -+ nodes. Returns 0 if there is not another element. -+ */ -+ TiXmlElement* NextSiblingElement( const char * ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ /// Convenience function to get through elements. -+ TiXmlElement* FirstChildElement() const; -+ -+ /// Convenience function to get through elements. -+ TiXmlElement* FirstChildElement( const char * value ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ /** Query the type (as an enumerated value, above) of this node. -+ The possible types are: DOCUMENT, ELEMENT, COMMENT, -+ UNKNOWN, TEXT, and DECLARATION. -+ */ -+ virtual int Type() const { return type; } -+ -+ /** Return a pointer to the Document this node lives in. -+ Returns null if not in a document. -+ */ -+ TiXmlDocument* GetDocument() const; -+ -+ /// Returns true if this node has no children. -+ bool NoChildren() const { return !firstChild; } -+ -+ TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlText* ToText() const { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. -+ -+ /** Create an exact duplicate of this node and return it. The memory must be deleted -+ by the caller. -+ */ -+ virtual TiXmlNode* Clone() const = 0; -+ -+protected: -+ TiXmlNode( NodeType _type ); -+ -+ // Copy to the allocated object. Shared functionality between Clone, Copy constructor, -+ // and the assignment operator. -+ void CopyTo( TiXmlNode* target ) const; -+ -+ #ifdef TIXML_USE_STL -+ // The real work of the input operator. -+ virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0; -+ #endif -+ -+ // Figure out what is at *p, and parse it. Returns null if it is not an xml node. -+ TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); -+ -+ // Internal Value function returning a TIXML_STRING -+ const TIXML_STRING& SValue() const { return value ; } -+ -+ TiXmlNode* parent; -+ NodeType type; -+ -+ TiXmlNode* firstChild; -+ TiXmlNode* lastChild; -+ -+ TIXML_STRING value; -+ -+ TiXmlNode* prev; -+ TiXmlNode* next; -+ -+private: -+ TiXmlNode( const TiXmlNode& ); // not implemented. -+ void operator=( const TiXmlNode& base ); // not allowed. -+}; -+ -+ -+/** An attribute is a name-value pair. Elements have an arbitrary -+ number of attributes, each with a unique name. -+ -+ @note The attributes are not TiXmlNodes, since they are not -+ part of the tinyXML document object model. There are other -+ suggested ways to look at this problem. -+*/ -+class TiXmlAttribute : public TiXmlBase -+{ -+ friend class TiXmlAttributeSet; -+ -+public: -+ /// Construct an empty attribute. -+ TiXmlAttribute() : TiXmlBase() -+ { -+ document = 0; -+ prev = next = 0; -+ } -+ -+ #ifdef TIXML_USE_STL -+ /// std::string constructor. -+ TiXmlAttribute( const std::string& _name, const std::string& _value ) -+ { -+ name = _name; -+ value = _value; -+ document = 0; -+ prev = next = 0; -+ } -+ #endif -+ -+ /// Construct an attribute with a name and value. -+ TiXmlAttribute( const char * _name, const char * _value ) -+ { -+ name = _name; -+ value = _value; -+ document = 0; -+ prev = next = 0; -+ } -+ -+ const char* Name() const { return name.c_str (); } ///< Return the name of this attribute. -+ const char* Value() const { return value.c_str (); } ///< Return the value of this attribute. -+ const int IntValue() const; ///< Return the value of this attribute, converted to an integer. -+ const double DoubleValue() const; ///< Return the value of this attribute, converted to a double. -+ -+ /** QueryIntValue examines the value string. It is an alternative to the -+ IntValue() method with richer error checking. -+ If the value is an integer, it is stored in 'value' and -+ the call returns TIXML_SUCCESS. If it is not -+ an integer, it returns TIXML_WRONG_TYPE. -+ -+ A specialized but useful call. Note that for success it returns 0, -+ which is the opposite of almost all other TinyXml calls. -+ */ -+ int QueryIntValue( int* value ) const; -+ /// QueryDoubleValue examines the value string. See QueryIntValue(). -+ int QueryDoubleValue( double* value ) const; -+ -+ void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. -+ void SetValue( const char* _value ) { value = _value; } ///< Set the value. -+ -+ void SetIntValue( int value ); ///< Set the value from an integer. -+ void SetDoubleValue( double value ); ///< Set the value from a double. -+ -+ #ifdef TIXML_USE_STL -+ /// STL std::string form. -+ void SetName( const std::string& _name ) -+ { -+ StringToBuffer buf( _name ); -+ SetName ( buf.buffer ? buf.buffer : "error" ); -+ } -+ /// STL std::string form. -+ void SetValue( const std::string& _value ) -+ { -+ StringToBuffer buf( _value ); -+ SetValue( buf.buffer ? buf.buffer : "error" ); -+ } -+ #endif -+ -+ /// Get the next sibling attribute in the DOM. Returns null at end. -+ TiXmlAttribute* Next() const; -+ /// Get the previous sibling attribute in the DOM. Returns null at beginning. -+ TiXmlAttribute* Previous() const; -+ -+ bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } -+ bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } -+ bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } -+ -+ /* Attribute parsing starts: first letter of the name -+ returns: the next char after the value end quote -+ */ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+ // Prints this Attribute to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ virtual void StreamOut( TIXML_OSTREAM * out ) const; -+ // [internal use] -+ // Set the document pointer so the attribute can report errors. -+ void SetDocument( TiXmlDocument* doc ) { document = doc; } -+ -+private: -+ TiXmlAttribute( const TiXmlAttribute& ); // not implemented. -+ void operator=( const TiXmlAttribute& base ); // not allowed. -+ -+ TiXmlDocument* document; // A pointer back to a document, for error reporting. -+ TIXML_STRING name; -+ TIXML_STRING value; -+ TiXmlAttribute* prev; -+ TiXmlAttribute* next; -+}; -+ -+ -+/* A class used to manage a group of attributes. -+ It is only used internally, both by the ELEMENT and the DECLARATION. -+ -+ The set can be changed transparent to the Element and Declaration -+ classes that use it, but NOT transparent to the Attribute -+ which has to implement a next() and previous() method. Which makes -+ it a bit problematic and prevents the use of STL. -+ -+ This version is implemented with circular lists because: -+ - I like circular lists -+ - it demonstrates some independence from the (typical) doubly linked list. -+*/ -+class TiXmlAttributeSet -+{ -+public: -+ TiXmlAttributeSet(); -+ ~TiXmlAttributeSet(); -+ -+ void Add( TiXmlAttribute* attribute ); -+ void Remove( TiXmlAttribute* attribute ); -+ -+ TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } -+ TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } -+ TiXmlAttribute* Find( const char * name ) const; -+ -+private: -+ TiXmlAttribute sentinel; -+}; -+ -+ -+/** The element is a container class. It has a value, the element name, -+ and can contain other elements, text, comments, and unknowns. -+ Elements also contain an arbitrary number of attributes. -+*/ -+class TiXmlElement : public TiXmlNode -+{ -+public: -+ /// Construct an element. -+ TiXmlElement (const char * in_value); -+ -+ #ifdef TIXML_USE_STL -+ /// std::string constructor. -+ TiXmlElement( const std::string& _value ); -+ #endif -+ -+ TiXmlElement( const TiXmlElement& ); -+ -+ void operator=( const TiXmlElement& base ); -+ -+ virtual ~TiXmlElement(); -+ -+ /** Given an attribute name, Attribute() returns the value -+ for the attribute of that name, or null if none exists. -+ */ -+ const char* Attribute( const char* name ) const; -+ -+ /** Given an attribute name, Attribute() returns the value -+ for the attribute of that name, or null if none exists. -+ If the attribute exists and can be converted to an integer, -+ the integer value will be put in the return 'i', if 'i' -+ is non-null. -+ */ -+ const char* Attribute( const char* name, int* i ) const; -+ -+ /** Given an attribute name, Attribute() returns the value -+ for the attribute of that name, or null if none exists. -+ If the attribute exists and can be converted to an double, -+ the double value will be put in the return 'd', if 'd' -+ is non-null. -+ */ -+ const char* Attribute( const char* name, double* d ) const; -+ -+ /** QueryIntAttribute examines the attribute - it is an alternative to the -+ Attribute() method with richer error checking. -+ If the attribute is an integer, it is stored in 'value' and -+ the call returns TIXML_SUCCESS. If it is not -+ an integer, it returns TIXML_WRONG_TYPE. If the attribute -+ does not exist, then TIXML_NO_ATTRIBUTE is returned. -+ */ -+ int QueryIntAttribute( const char* name, int* value ) const; -+ /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). -+ int QueryDoubleAttribute( const char* name, double* value ) const; -+ -+ /** Sets an attribute of name to a given value. The attribute -+ will be created if it does not exist, or changed if it does. -+ */ -+ void SetAttribute( const char* name, const char * value ); -+ -+ #ifdef TIXML_USE_STL -+ const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); } -+ const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); } -+ const char* Attribute( const std::string& name, double* d ) const { return Attribute( name.c_str(), d ); } -+ int QueryIntAttribute( const std::string& name, int* value ) const { return QueryIntAttribute( name.c_str(), value ); } -+ int QueryDoubleAttribute( const std::string& name, double* value ) const { return QueryDoubleAttribute( name.c_str(), value ); } -+ -+ /// STL std::string form. -+ void SetAttribute( const std::string& name, const std::string& _value ) -+ { -+ StringToBuffer n( name ); -+ StringToBuffer v( _value ); -+ if ( n.buffer && v.buffer ) -+ SetAttribute (n.buffer, v.buffer ); -+ } -+ ///< STL std::string form. -+ void SetAttribute( const std::string& name, int _value ) -+ { -+ StringToBuffer n( name ); -+ if ( n.buffer ) -+ SetAttribute (n.buffer, _value); -+ } -+ #endif -+ -+ /** Sets an attribute of name to a given value. The attribute -+ will be created if it does not exist, or changed if it does. -+ */ -+ void SetAttribute( const char * name, int value ); -+ -+ /** Sets an attribute of name to a given value. The attribute -+ will be created if it does not exist, or changed if it does. -+ */ -+ void SetDoubleAttribute( const char * name, double value ); -+ -+ /** Deletes an attribute with the given name. -+ */ -+ void RemoveAttribute( const char * name ); -+ #ifdef TIXML_USE_STL -+ void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. -+ #endif -+ -+ TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. -+ TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. -+ -+ /// Creates a new Element and returns it - the returned element is a copy. -+ virtual TiXmlNode* Clone() const; -+ // Print the Element to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ /* Attribtue parsing starts: next char past '<' -+ returns: next char past '>' -+ */ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected: -+ -+ void CopyTo( TiXmlElement* target ) const; -+ void ClearThis(); // like clear, but initializes 'this' object as well -+ -+ // Used to be public [internal use] -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ virtual void StreamOut( TIXML_OSTREAM * out ) const; -+ -+ /* [internal use] -+ Reads the "value" of the element -- another element, or text. -+ This should terminate with the current end tag. -+ */ -+ const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); -+ -+private: -+ -+ TiXmlAttributeSet attributeSet; -+}; -+ -+ -+/** An XML comment. -+*/ -+class TiXmlComment : public TiXmlNode -+{ -+public: -+ /// Constructs an empty comment. -+ TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} -+ TiXmlComment( const TiXmlComment& ); -+ void operator=( const TiXmlComment& base ); -+ -+ virtual ~TiXmlComment() {} -+ -+ /// Returns a copy of this Comment. -+ virtual TiXmlNode* Clone() const; -+ /// Write this Comment to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ /* Attribtue parsing starts: at the ! of the !-- -+ returns: next char past '>' -+ */ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected: -+ void CopyTo( TiXmlComment* target ) const; -+ -+ // used to be public -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ virtual void StreamOut( TIXML_OSTREAM * out ) const; -+ -+private: -+ -+}; -+ -+ -+/** XML text. Contained in an element. -+*/ -+class TiXmlText : public TiXmlNode -+{ -+ friend class TiXmlElement; -+public: -+ /// Constructor. -+ TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT) -+ { -+ SetValue( initValue ); -+ } -+ virtual ~TiXmlText() {} -+ -+ #ifdef TIXML_USE_STL -+ /// Constructor. -+ TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) -+ { -+ SetValue( initValue ); -+ } -+ #endif -+ -+ TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } -+ void operator=( const TiXmlText& base ) { base.CopyTo( this ); } -+ -+ /// Write this text object to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected : -+ /// [internal use] Creates a new Element and returns it. -+ virtual TiXmlNode* Clone() const; -+ void CopyTo( TiXmlText* target ) const; -+ -+ virtual void StreamOut ( TIXML_OSTREAM * out ) const; -+ bool Blank() const; // returns true if all white space and new lines -+ // [internal use] -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ -+private: -+}; -+ -+ -+/** In correct XML the declaration is the first entry in the file. -+ @verbatim -+ <?xml version="1.0" standalone="yes"?> -+ @endverbatim -+ -+ TinyXml will happily read or write files without a declaration, -+ however. There are 3 possible attributes to the declaration: -+ version, encoding, and standalone. -+ -+ Note: In this version of the code, the attributes are -+ handled as special cases, not generic attributes, simply -+ because there can only be at most 3 and they are always the same. -+*/ -+class TiXmlDeclaration : public TiXmlNode -+{ -+public: -+ /// Construct an empty declaration. -+ TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} -+ -+#ifdef TIXML_USE_STL -+ /// Constructor. -+ TiXmlDeclaration( const std::string& _version, -+ const std::string& _encoding, -+ const std::string& _standalone ); -+#endif -+ -+ /// Construct. -+ TiXmlDeclaration( const char* _version, -+ const char* _encoding, -+ const char* _standalone ); -+ -+ TiXmlDeclaration( const TiXmlDeclaration& copy ); -+ void operator=( const TiXmlDeclaration& copy ); -+ -+ virtual ~TiXmlDeclaration() {} -+ -+ /// Version. Will return an empty string if none was found. -+ const char *Version() const { return version.c_str (); } -+ /// Encoding. Will return an empty string if none was found. -+ const char *Encoding() const { return encoding.c_str (); } -+ /// Is this a standalone document? -+ const char *Standalone() const { return standalone.c_str (); } -+ -+ /// Creates a copy of this Declaration and returns it. -+ virtual TiXmlNode* Clone() const; -+ /// Print this declaration to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected: -+ void CopyTo( TiXmlDeclaration* target ) const; -+ // used to be public -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ virtual void StreamOut ( TIXML_OSTREAM * out) const; -+ -+private: -+ -+ TIXML_STRING version; -+ TIXML_STRING encoding; -+ TIXML_STRING standalone; -+}; -+ -+ -+/** Any tag that tinyXml doesn't recognize is saved as an -+ unknown. It is a tag of text, but should not be modified. -+ It will be written back to the XML, unchanged, when the file -+ is saved. -+ -+ DTD tags get thrown into TiXmlUnknowns. -+*/ -+class TiXmlUnknown : public TiXmlNode -+{ -+public: -+ TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} -+ virtual ~TiXmlUnknown() {} -+ -+ TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } -+ void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } -+ -+ /// Creates a copy of this Unknown and returns it. -+ virtual TiXmlNode* Clone() const; -+ /// Print this Unknown to a FILE stream. -+ virtual void Print( FILE* cfile, int depth ) const; -+ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); -+ -+protected: -+ void CopyTo( TiXmlUnknown* target ) const; -+ -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ virtual void StreamOut ( TIXML_OSTREAM * out ) const; -+ -+private: -+ -+}; -+ -+ -+/** Always the top level node. A document binds together all the -+ XML pieces. It can be saved, loaded, and printed to the screen. -+ The 'value' of a document node is the xml file name. -+*/ -+class TiXmlDocument : public TiXmlNode -+{ -+public: -+ /// Create an empty document, that has no name. -+ TiXmlDocument(); -+ /// Create a document with a name. The name of the document is also the filename of the xml. -+ TiXmlDocument( const char * documentName ); -+ -+ #ifdef TIXML_USE_STL -+ /// Constructor. -+ TiXmlDocument( const std::string& documentName ); -+ #endif -+ -+ TiXmlDocument( const TiXmlDocument& copy ); -+ void operator=( const TiXmlDocument& copy ); -+ -+ virtual ~TiXmlDocument() {} -+ -+ /** Load a file using the current document value. -+ Returns true if successful. Will delete any existing -+ document data before loading. -+ */ -+ bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); -+ /// Save a file using the current document value. Returns true if successful. -+ bool SaveFile() const; -+ /// Load a file using the given filename. Returns true if successful. -+ bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); -+ /// Save a file using the given filename. Returns true if successful. -+ bool SaveFile( const char * filename ) const; -+ -+ #ifdef TIXML_USE_STL -+ bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. -+ { -+ StringToBuffer f( filename ); -+ return ( f.buffer && LoadFile( f.buffer, encoding )); -+ } -+ bool SaveFile( const std::string& filename ) const ///< STL std::string version. -+ { -+ StringToBuffer f( filename ); -+ return ( f.buffer && SaveFile( f.buffer )); -+ } -+ #endif -+ -+ /** Parse the given null terminated block of xml data. Passing in an encoding to this -+ method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml -+ to use that encoding, regardless of what TinyXml might otherwise try to detect. -+ */ -+ virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); -+ -+ /** Get the root element -- the only top level element -- of the document. -+ In well formed XML, there should only be one. TinyXml is tolerant of -+ multiple elements at the document level. -+ */ -+ TiXmlElement* RootElement() const { return FirstChildElement(); } -+ -+ /** If an error occurs, Error will be set to true. Also, -+ - The ErrorId() will contain the integer identifier of the error (not generally useful) -+ - The ErrorDesc() method will return the name of the error. (very useful) -+ - The ErrorRow() and ErrorCol() will return the location of the error (if known) -+ */ -+ bool Error() const { return error; } -+ -+ /// Contains a textual (english) description of the error if one occurs. -+ const char * ErrorDesc() const { return errorDesc.c_str (); } -+ -+ /** Generally, you probably want the error string ( ErrorDesc() ). But if you -+ prefer the ErrorId, this function will fetch it. -+ */ -+ const int ErrorId() const { return errorId; } -+ -+ /** Returns the location (if known) of the error. The first column is column 1, -+ and the first row is row 1. A value of 0 means the row and column wasn't applicable -+ (memory errors, for example, have no row/column) or the parser lost the error. (An -+ error in the error reporting, in that case.) -+ -+ @sa SetTabSize, Row, Column -+ */ -+ int ErrorRow() { return errorLocation.row+1; } -+ int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() -+ -+ /** By calling this method, with a tab size -+ greater than 0, the row and column of each node and attribute is stored -+ when the file is loaded. Very useful for tracking the DOM back in to -+ the source file. -+ -+ The tab size is required for calculating the location of nodes. If not -+ set, the default of 4 is used. The tabsize is set per document. Setting -+ the tabsize to 0 disables row/column tracking. -+ -+ Note that row and column tracking is not supported when using operator>>. -+ -+ The tab size needs to be enabled before the parse or load. Correct usage: -+ @verbatim -+ TiXmlDocument doc; -+ doc.SetTabSize( 8 ); -+ doc.Load( "myfile.xml" ); -+ @endverbatim -+ -+ @sa Row, Column -+ */ -+ void SetTabSize( int _tabsize ) { tabsize = _tabsize; } -+ -+ int TabSize() const { return tabsize; } -+ -+ /** If you have handled the error, it can be reset with this call. The error -+ state is automatically cleared if you Parse a new XML block. -+ */ -+ void ClearError() { error = false; -+ errorId = 0; -+ errorDesc = ""; -+ errorLocation.row = errorLocation.col = 0; -+ //errorLocation.last = 0; -+ } -+ -+ /** Dump the document to standard out. */ -+ void Print() const { Print( stdout, 0 ); } -+ -+ /// Print this Document to a FILE stream. -+ virtual void Print( FILE* cfile, int depth = 0 ) const; -+ // [internal use] -+ void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); -+ -+protected : -+ virtual void StreamOut ( TIXML_OSTREAM * out) const; -+ // [internal use] -+ virtual TiXmlNode* Clone() const; -+ #ifdef TIXML_USE_STL -+ virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); -+ #endif -+ -+private: -+ void CopyTo( TiXmlDocument* target ) const; -+ -+ bool error; -+ int errorId; -+ TIXML_STRING errorDesc; -+ int tabsize; -+ TiXmlCursor errorLocation; -+}; -+ -+ -+/** -+ A TiXmlHandle is a class that wraps a node pointer with null checks; this is -+ an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml -+ DOM structure. It is a separate utility class. -+ -+ Take an example: -+ @verbatim -+ <Document> -+ <Element attributeA = "valueA"> -+ <Child attributeB = "value1" /> -+ <Child attributeB = "value2" /> -+ </Element> -+ <Document> -+ @endverbatim -+ -+ Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very -+ easy to write a *lot* of code that looks like: -+ -+ @verbatim -+ TiXmlElement* root = document.FirstChildElement( "Document" ); -+ if ( root ) -+ { -+ TiXmlElement* element = root->FirstChildElement( "Element" ); -+ if ( element ) -+ { -+ TiXmlElement* child = element->FirstChildElement( "Child" ); -+ if ( child ) -+ { -+ TiXmlElement* child2 = child->NextSiblingElement( "Child" ); -+ if ( child2 ) -+ { -+ // Finally do something useful. -+ @endverbatim -+ -+ And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity -+ of such code. A TiXmlHandle checks for null pointers so it is perfectly safe -+ and correct to use: -+ -+ @verbatim -+ TiXmlHandle docHandle( &document ); -+ TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element(); -+ if ( child2 ) -+ { -+ // do something useful -+ @endverbatim -+ -+ Which is MUCH more concise and useful. -+ -+ It is also safe to copy handles - internally they are nothing more than node pointers. -+ @verbatim -+ TiXmlHandle handleCopy = handle; -+ @endverbatim -+ -+ What they should not be used for is iteration: -+ -+ @verbatim -+ int i=0; -+ while ( true ) -+ { -+ TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element(); -+ if ( !child ) -+ break; -+ // do something -+ ++i; -+ } -+ @endverbatim -+ -+ It seems reasonable, but it is in fact two embedded while loops. The Child method is -+ a linear walk to find the element, so this code would iterate much more than it needs -+ to. Instead, prefer: -+ -+ @verbatim -+ TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element(); -+ -+ for( child; child; child=child->NextSiblingElement() ) -+ { -+ // do something -+ } -+ @endverbatim -+*/ -+class TiXmlHandle -+{ -+public: -+ /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. -+ TiXmlHandle( TiXmlNode* node ) { this->node = node; } -+ /// Copy constructor -+ TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } -+ TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } -+ -+ /// Return a handle to the first child node. -+ TiXmlHandle FirstChild() const; -+ /// Return a handle to the first child node with the given name. -+ TiXmlHandle FirstChild( const char * value ) const; -+ /// Return a handle to the first child element. -+ TiXmlHandle FirstChildElement() const; -+ /// Return a handle to the first child element with the given name. -+ TiXmlHandle FirstChildElement( const char * value ) const; -+ -+ /** Return a handle to the "index" child with the given name. -+ The first child is 0, the second 1, etc. -+ */ -+ TiXmlHandle Child( const char* value, int index ) const; -+ /** Return a handle to the "index" child. -+ The first child is 0, the second 1, etc. -+ */ -+ TiXmlHandle Child( int index ) const; -+ /** Return a handle to the "index" child element with the given name. -+ The first child element is 0, the second 1, etc. Note that only TiXmlElements -+ are indexed: other types are not counted. -+ */ -+ TiXmlHandle ChildElement( const char* value, int index ) const; -+ /** Return a handle to the "index" child element. -+ The first child element is 0, the second 1, etc. Note that only TiXmlElements -+ are indexed: other types are not counted. -+ */ -+ TiXmlHandle ChildElement( int index ) const; -+ -+ #ifdef TIXML_USE_STL -+ TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } -+ TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } -+ -+ TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } -+ TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } -+ #endif -+ -+ /// Return the handle as a TiXmlNode. This may return null. -+ TiXmlNode* Node() const { return node; } -+ /// Return the handle as a TiXmlElement. This may return null. -+ TiXmlElement* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } -+ /// Return the handle as a TiXmlText. This may return null. -+ TiXmlText* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } -+ /// Return the handle as a TiXmlUnknown. This may return null; -+ TiXmlUnknown* Unknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } -+ -+private: -+ TiXmlNode* node; -+}; -+ -+ -+#endif -+#endif /* SETUP */ -diff -ruNp vdr-1.7.5/tinyxmlparser.c vdr-1.7.5-extensions/tinyxmlparser.c ---- vdr-1.7.5/tinyxmlparser.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.5-extensions/tinyxmlparser.c 2009-04-12 13:37:59.000000000 +0200 -@@ -0,0 +1,1494 @@ -+#ifdef USE_SETUP -+/* -+www.sourceforge.net/projects/tinyxml -+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) -+ -+This software is provided 'as-is', without any express or implied -+warranty. In no event will the authors be held liable for any -+damages arising from the use of this software. -+ -+Permission is granted to anyone to use this software for any -+purpose, including commercial applications, and to alter it and -+redistribute it freely, subject to the following restrictions: -+ -+1. The origin of this software must not be misrepresented; you must -+not claim that you wrote the original software. If you use this -+software in a product, an acknowledgment in the product documentation -+would be appreciated but is not required. -+ -+2. Altered source versions must be plainly marked as such, and -+must not be misrepresented as being the original software. -+ -+3. This notice may not be removed or altered from any source -+distribution. -+*/ -+ -+#include "tinyxml.h" -+#include <ctype.h> -+ -+//#define DEBUG_PARSER -+ -+// Note tha "PutString" hardcodes the same list. This -+// is less flexible than it appears. Changing the entries -+// or order will break putstring. -+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = -+{ -+ { "&", 5, '&' }, -+ { "<", 4, '<' }, -+ { ">", 4, '>' }, -+ { """, 6, '\"' }, -+ { "'", 6, '\'' } -+}; -+ -+// Bunch of unicode info at: -+// http://www.unicode.org/faq/utf_bom.html -+// Including the basic of this table, which determines the #bytes in the -+// sequence from the lead byte. 1 placed for invalid sequences -- -+// although the result will be junk, pass it through as much as possible. -+// Beware of the non-characters in UTF-8: -+// ef bb bf (Microsoft "lead bytes") -+// ef bf be -+// ef bf bf -+ -+ -+ -+const int TiXmlBase::utf8ByteTable[256] = -+{ -+ // 0 1 2 3 4 5 6 7 8 9 a b c d e f -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 -+ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 -+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte -+ 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid -+}; -+ -+ -+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -+{ -+ const unsigned long BYTE_MASK = 0xBF; -+ const unsigned long BYTE_MARK = 0x80; -+ const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; -+ -+ if (input < 0x80) -+ *length = 1; -+ else if ( input < 0x800 ) -+ *length = 2; -+ else if ( input < 0x10000 ) -+ *length = 3; -+ else if ( input < 0x200000 ) -+ *length = 4; -+ else -+ { *length = 0; return; } // This code won't covert this correctly anyway. -+ -+ output += *length; -+ -+ // Scary scary fall throughs. -+ switch (*length) -+ { -+ case 4: -+ --output; -+ *output = (char)((input | BYTE_MARK) & BYTE_MASK); -+ input >>= 6; -+ case 3: -+ --output; -+ *output = (char)((input | BYTE_MARK) & BYTE_MASK); -+ input >>= 6; -+ case 2: -+ --output; -+ *output = (char)((input | BYTE_MARK) & BYTE_MASK); -+ input >>= 6; -+ case 1: -+ --output; -+ *output = (char)(input | FIRST_BYTE_MARK[*length]); -+ } -+} -+ -+ -+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ) -+{ -+ // This will only work for low-ascii, everything else is assumed to be a valid -+ // letter. I'm not sure this is the best approach, but it is quite tricky trying -+ // to figure out alhabetical vs. not across encoding. So take a very -+ // conservative approach. -+ -+// if ( encoding == TIXML_ENCODING_UTF8 ) -+// { -+ if ( anyByte < 127 ) -+ return isalpha( anyByte ); -+ else -+ return 1; // What else to do? The unicode set is huge...get the english ones right. -+// } -+// else -+// { -+// return isalpha( anyByte ); -+// } -+} -+ -+ -+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ) -+{ -+ // This will only work for low-ascii, everything else is assumed to be a valid -+ // letter. I'm not sure this is the best approach, but it is quite tricky trying -+ // to figure out alhabetical vs. not across encoding. So take a very -+ // conservative approach. -+ -+// if ( encoding == TIXML_ENCODING_UTF8 ) -+// { -+ if ( anyByte < 127 ) -+ return isalnum( anyByte ); -+ else -+ return 1; // What else to do? The unicode set is huge...get the english ones right. -+// } -+// else -+// { -+// return isalnum( anyByte ); -+// } -+} -+ -+ -+class TiXmlParsingData -+{ -+ friend class TiXmlDocument; -+ public: -+ void Stamp( const char* now, TiXmlEncoding encoding ); -+ -+ const TiXmlCursor& Cursor() { return cursor; } -+ -+ private: -+ // Only used by the document! -+ TiXmlParsingData( const char* start, int _tabsize, int row, int col ) -+ { -+ assert( start ); -+ stamp = start; -+ tabsize = _tabsize; -+ cursor.row = row; -+ cursor.col = col; -+ } -+ -+ TiXmlCursor cursor; -+ const char* stamp; -+ int tabsize; -+}; -+ -+ -+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) -+{ -+ assert( now ); -+ -+ // Do nothing if the tabsize is 0. -+ if ( tabsize < 1 ) -+ { -+ return; -+ } -+ -+ // Get the current row, column. -+ int row = cursor.row; -+ int col = cursor.col; -+ const char* p = stamp; -+ assert( p ); -+ -+ while ( p < now ) -+ { -+ // Code contributed by Fletcher Dunn: (modified by lee) -+ switch (*p) { -+ case 0: -+ // We *should* never get here, but in case we do, don't -+ // advance past the terminating null character, ever -+ return; -+ -+ case '\r': -+ // bump down to the next line -+ ++row; -+ col = 0; -+ // Eat the character -+ ++p; -+ -+ // Check for \r\n sequence, and treat this as a single character -+ if (*p == '\n') { -+ ++p; -+ } -+ break; -+ -+ case '\n': -+ // bump down to the next line -+ ++row; -+ col = 0; -+ -+ // Eat the character -+ ++p; -+ -+ // Check for \n\r sequence, and treat this as a single -+ // character. (Yes, this bizarre thing does occur still -+ // on some arcane platforms...) -+ if (*p == '\r') { -+ ++p; -+ } -+ break; -+ -+ case '\t': -+ // Eat the character -+ ++p; -+ -+ // Skip to next tab stop -+ col = (col / tabsize + 1) * tabsize; -+ break; -+ -+ case (char)(0xef): -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ if ( *(p+1) && *(p+2) ) -+ { -+ // In these cases, don't advance the column. These are -+ // 0-width spaces. -+ if ( *(p+1)==(char)(0xbb) && *(p+2)==(char)(0xbf) ) -+ p += 3; -+ else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbe) ) -+ p += 3; -+ else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbf) ) -+ p += 3; -+ else -+ { p +=3; ++col; } // A normal character. -+ } -+ } -+ else -+ { -+ ++p; -+ ++col; -+ } -+ break; -+ -+ default: -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ // Eat the 1 to 4 byte utf8 character. -+ int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)]; -+ if ( step == 0 ) -+ step = 1; // Error case from bad encoding, but handle gracefully. -+ p += step; -+ -+ // Just advance one column, of course. -+ ++col; -+ } -+ else -+ { -+ ++p; -+ ++col; -+ } -+ break; -+ } -+ } -+ cursor.row = row; -+ cursor.col = col; -+ assert( cursor.row >= -1 ); -+ assert( cursor.col >= -1 ); -+ stamp = p; -+ assert( stamp ); -+} -+ -+ -+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) -+{ -+ if ( !p || !*p ) -+ { -+ return 0; -+ } -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ while ( *p ) -+ { -+ // Skip the stupid Microsoft UTF-8 Byte order marks -+ if ( *(p+0)==(char) 0xef -+ && *(p+1)==(char) 0xbb -+ && *(p+2)==(char) 0xbf ) -+ { -+ p += 3; -+ continue; -+ } -+ else if(*(p+0)==(char) 0xef -+ && *(p+1)==(char) 0xbf -+ && *(p+2)==(char) 0xbe ) -+ { -+ p += 3; -+ continue; -+ } -+ else if(*(p+0)==(char) 0xef -+ && *(p+1)==(char) 0xbf -+ && *(p+2)==(char) 0xbf ) -+ { -+ p += 3; -+ continue; -+ } -+ -+ if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. -+ ++p; -+ else -+ break; -+ } -+ } -+ else -+ { -+ while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) -+ ++p; -+ } -+ -+ return p; -+} -+ -+#ifdef TIXML_USE_STL -+/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ for( ;; ) -+ { -+ if ( !in->good() ) return false; -+ -+ int c = in->peek(); -+ // At this scope, we can't get to a document. So fail silently. -+ if ( !IsWhiteSpace( c ) || c <= 0 ) -+ return true; -+ -+ *tag += (char) in->get(); -+ } -+} -+ -+/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ) -+{ -+ //assert( character > 0 && character < 128 ); // else it won't work in utf-8 -+ while ( in->good() ) -+ { -+ int c = in->peek(); -+ if ( c == character ) -+ return true; -+ if ( c <= 0 ) // Silent failure: can't get document at this scope -+ return false; -+ -+ in->get(); -+ *tag += (char) c; -+ } -+ return false; -+} -+#endif -+ -+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) -+{ -+ *name = ""; -+ assert( p ); -+ -+ // Names start with letters or underscores. -+ // Of course, in unicode, tinyxml has no idea what a letter *is*. The -+ // algorithm is generous. -+ // -+ // After that, they can be letters, underscores, numbers, -+ // hyphens, or colons. (Colons are valid ony for namespaces, -+ // but tinyxml can't tell namespaces from names.) -+ if ( p && *p -+ && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) -+ { -+ while( p && *p -+ && ( IsAlphaNum( (unsigned char ) *p, encoding ) -+ || *p == '_' -+ || *p == '-' -+ || *p == '.' -+ || *p == ':' ) ) -+ { -+ (*name) += *p; -+ ++p; -+ } -+ return p; -+ } -+ return 0; -+} -+ -+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) -+{ -+ // Presume an entity, and pull it out. -+ TIXML_STRING ent; -+ int i; -+ *length = 0; -+ -+ if ( *(p+1) && *(p+1) == '#' && *(p+2) ) -+ { -+ unsigned long ucs = 0; -+ unsigned delta = 0; -+ unsigned mult = 1; -+ -+ if ( *(p+2) == 'x' ) -+ { -+ // Hexadecimal. -+ if ( !*(p+3) ) return 0; -+ -+ const char* q = p+3; -+ q = strchr( q, ';' ); -+ -+ if ( !q || !*q ) return 0; -+ -+ delta = q-p; -+ --q; -+ -+ while ( *q != 'x' ) -+ { -+ if ( *q >= '0' && *q <= '9' ) -+ ucs += mult * (*q - '0'); -+ else if ( *q >= 'a' && *q <= 'f' ) -+ ucs += mult * (*q - 'a' + 10); -+ else if ( *q >= 'A' && *q <= 'F' ) -+ ucs += mult * (*q - 'A' + 10 ); -+ else -+ return 0; -+ mult *= 16; -+ --q; -+ } -+ } -+ else -+ { -+ // Decimal. -+ if ( !*(p+2) ) return 0; -+ -+ const char* q = p+2; -+ q = strchr( q, ';' ); -+ -+ if ( !q || !*q ) return 0; -+ -+ delta = q-p; -+ --q; -+ -+ while ( *q != '#' ) -+ { -+ if ( *q >= '0' && *q <= '9' ) -+ ucs += mult * (*q - '0'); -+ else -+ return 0; -+ mult *= 10; -+ --q; -+ } -+ } -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ // convert the UCS to UTF-8 -+ ConvertUTF32ToUTF8( ucs, value, length ); -+ } -+ else -+ { -+ *value = (char)ucs; -+ *length = 1; -+ } -+ return p + delta + 1; -+ } -+ -+ // Now try to match it. -+ for( i=0; i<NUM_ENTITY; ++i ) -+ { -+ if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 ) -+ { -+ assert( strlen( entity[i].str ) == entity[i].strLength ); -+ *value = entity[i].chr; -+ *length = 1; -+ return ( p + entity[i].strLength ); -+ } -+ } -+ -+ // So it wasn't an entity, its unrecognized, or something like that. -+ *value = *p; // Don't put back the last one, since we return it! -+ return p+1; -+} -+ -+ -+bool TiXmlBase::StringEqual( const char* p, -+ const char* tag, -+ bool ignoreCase, -+ TiXmlEncoding encoding ) -+{ -+ assert( p ); -+ assert( tag ); -+ if ( !p || !*p ) -+ { -+ assert( 0 ); -+ return false; -+ } -+ -+ const char* q = p; -+ -+ if ( ignoreCase ) -+ { -+ while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) ) -+ { -+ ++q; -+ ++tag; -+ } -+ -+ if ( *tag == 0 ) -+ return true; -+ } -+ else -+ { -+ while ( *q && *tag && *q == *tag ) -+ { -+ ++q; -+ ++tag; -+ } -+ -+ if ( *tag == 0 ) // Have we found the end of the tag, and everything equal? -+ return true; -+ } -+ return false; -+} -+ -+const char* TiXmlBase::ReadText( const char* p, -+ TIXML_STRING * text, -+ bool trimWhiteSpace, -+ const char* endTag, -+ bool caseInsensitive, -+ TiXmlEncoding encoding ) -+{ -+ *text = ""; -+ if ( !trimWhiteSpace // certain tags always keep whitespace -+ || !condenseWhiteSpace ) // if true, whitespace is always kept -+ { -+ // Keep all the white space. -+ while ( p && *p -+ && !StringEqual( p, endTag, caseInsensitive, encoding ) -+ ) -+ { -+ int len; -+ char cArr[4] = { 0, 0, 0, 0 }; -+ p = GetChar( p, cArr, &len, encoding ); -+ text->append( cArr, len ); -+ } -+ } -+ else -+ { -+ bool whitespace = false; -+ -+ // Remove leading white space: -+ p = SkipWhiteSpace( p, encoding ); -+ while ( p && *p -+ && !StringEqual( p, endTag, caseInsensitive, encoding ) ) -+ { -+ if ( *p == '\r' || *p == '\n' ) -+ { -+ whitespace = true; -+ ++p; -+ } -+ else if ( IsWhiteSpace( *p ) ) -+ { -+ whitespace = true; -+ ++p; -+ } -+ else -+ { -+ // If we've found whitespace, add it before the -+ // new character. Any whitespace just becomes a space. -+ if ( whitespace ) -+ { -+ (*text) += ' '; -+ whitespace = false; -+ } -+ int len; -+ char cArr[4] = { 0, 0, 0, 0 }; -+ p = GetChar( p, cArr, &len, encoding ); -+ if ( len == 1 ) -+ (*text) += cArr[0]; // more efficient -+ else -+ text->append( cArr, len ); -+ } -+ } -+ } -+ return p + strlen( endTag ); -+} -+ -+#ifdef TIXML_USE_STL -+ -+void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ // The basic issue with a document is that we don't know what we're -+ // streaming. Read something presumed to be a tag (and hope), then -+ // identify it, and call the appropriate stream method on the tag. -+ // -+ // This "pre-streaming" will never read the closing ">" so the -+ // sub-tag can orient itself. -+ -+ if ( !StreamTo( in, '<', tag ) ) -+ { -+ SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ -+ while ( in->good() ) -+ { -+ int tagIndex = (int) tag->length(); -+ while ( in->good() && in->peek() != '>' ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ break; -+ } -+ (*tag) += (char) c; -+ } -+ -+ if ( in->good() ) -+ { -+ // We now have something we presume to be a node of -+ // some sort. Identify it, and call the node to -+ // continue streaming. -+ TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); -+ -+ if ( node ) -+ { -+ node->StreamIn( in, tag ); -+ bool isElement = node->ToElement() != 0; -+ delete node; -+ node = 0; -+ -+ // If this is the root element, we're done. Parsing will be -+ // done by the >> operator. -+ if ( isElement ) -+ { -+ return; -+ } -+ } -+ else -+ { -+ SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ } -+ } -+ // We should have returned sooner. -+ SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); -+} -+ -+#endif -+ -+const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) -+{ -+ ClearError(); -+ -+ // Parse away, at the document level. Since a document -+ // contains nothing but other tags, most of what happens -+ // here is skipping white space. -+ if ( !p || !*p ) -+ { -+ SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return 0; -+ } -+ -+ // Note that, for a document, this needs to come -+ // before the while space skip, so that parsing -+ // starts from the pointer we are given. -+ location.Clear(); -+ if ( prevData ) -+ { -+ location.row = prevData->cursor.row; -+ location.col = prevData->cursor.col; -+ } -+ else -+ { -+ location.row = 0; -+ location.col = 0; -+ } -+ TiXmlParsingData data( p, TabSize(), location.row, location.col ); -+ location = data.Cursor(); -+ -+ if ( encoding == TIXML_ENCODING_UNKNOWN ) -+ { -+ // Check for the Microsoft UTF-8 lead bytes. -+ if ( *(p+0) && *(p+0) == (char)(0xef) -+ && *(p+1) && *(p+1) == (char)(0xbb) -+ && *(p+2) && *(p+2) == (char)(0xbf) ) -+ { -+ encoding = TIXML_ENCODING_UTF8; -+ } -+ } -+ -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p ) -+ { -+ SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return 0; -+ } -+ -+ while ( p && *p ) -+ { -+ TiXmlNode* node = Identify( p, encoding ); -+ if ( node ) -+ { -+ p = node->Parse( p, &data, encoding ); -+ LinkEndChild( node ); -+ } -+ else -+ { -+ break; -+ } -+ -+ // Did we get encoding info? -+ if ( encoding == TIXML_ENCODING_UNKNOWN -+ && node->ToDeclaration() ) -+ { -+ TiXmlDeclaration* dec = node->ToDeclaration(); -+ const char* enc = dec->Encoding(); -+ assert( enc ); -+ -+ if ( *enc == 0 ) -+ encoding = TIXML_ENCODING_UTF8; -+ else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) -+ encoding = TIXML_ENCODING_UTF8; -+ else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) -+ encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice -+ else -+ encoding = TIXML_ENCODING_LEGACY; -+ } -+ -+ p = SkipWhiteSpace( p, encoding ); -+ } -+ -+ // All is well. -+ return p; -+} -+ -+void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ // The first error in a chain is more accurate - don't set again! -+ if ( error ) -+ return; -+ -+ assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); -+ error = true; -+ errorId = err; -+ errorDesc = errorString[ errorId ]; -+ -+ errorLocation.Clear(); -+ if ( pError && data ) -+ { -+ //TiXmlParsingData data( pError, prevData ); -+ data->Stamp( pError, encoding ); -+ errorLocation = data->Cursor(); -+ } -+} -+ -+ -+TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) -+{ -+ TiXmlNode* returnNode = 0; -+ -+ p = SkipWhiteSpace( p, encoding ); -+ if( !p || !*p || *p != '<' ) -+ { -+ return 0; -+ } -+ -+ TiXmlDocument* doc = GetDocument(); -+ p = SkipWhiteSpace( p, encoding ); -+ -+ if ( !p || !*p ) -+ { -+ return 0; -+ } -+ -+ // What is this thing? -+ // - Elements start with a letter or underscore, but xml is reserved. -+ // - Comments: <!-- -+ // - Decleration: <?xml -+ // - Everthing else is unknown to tinyxml. -+ // -+ -+ const char* xmlHeader = { "<?xml" }; -+ const char* commentHeader = { "<!--" }; -+ const char* dtdHeader = { "<!" }; -+ -+ if ( StringEqual( p, xmlHeader, true, encoding ) ) -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Declaration\n" ); -+ #endif -+ returnNode = new TiXmlDeclaration(); -+ } -+ else if ( StringEqual( p, commentHeader, false, encoding ) ) -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Comment\n" ); -+ #endif -+ returnNode = new TiXmlComment(); -+ } -+ else if ( StringEqual( p, dtdHeader, false, encoding ) ) -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Unknown(1)\n" ); -+ #endif -+ returnNode = new TiXmlUnknown(); -+ } -+ else if ( IsAlpha( *(p+1), encoding ) -+ || *(p+1) == '_' ) -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Element\n" ); -+ #endif -+ returnNode = new TiXmlElement( "" ); -+ } -+ else -+ { -+ #ifdef DEBUG_PARSER -+ TIXML_LOG( "XML parsing Unknown(2)\n" ); -+ #endif -+ returnNode = new TiXmlUnknown(); -+ } -+ -+ if ( returnNode ) -+ { -+ // Set the parent, so it can report errors -+ returnNode->parent = this; -+ } -+ else -+ { -+ if ( doc ) -+ doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ } -+ return returnNode; -+} -+ -+#ifdef TIXML_USE_STL -+ -+void TiXmlElement::StreamIn (TIXML_ISTREAM * in, TIXML_STRING * tag) -+{ -+ // We're called with some amount of pre-parsing. That is, some of "this" -+ // element is in "tag". Go ahead and stream to the closing ">" -+ while( in->good() ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ (*tag) += (char) c ; -+ -+ if ( c == '>' ) -+ break; -+ } -+ -+ if ( tag->length() < 3 ) return; -+ -+ // Okay...if we are a "/>" tag, then we're done. We've read a complete tag. -+ // If not, identify and stream. -+ -+ if ( tag->at( tag->length() - 1 ) == '>' -+ && tag->at( tag->length() - 2 ) == '/' ) -+ { -+ // All good! -+ return; -+ } -+ else if ( tag->at( tag->length() - 1 ) == '>' ) -+ { -+ // There is more. Could be: -+ // text -+ // closing tag -+ // another node. -+ for ( ;; ) -+ { -+ StreamWhiteSpace( in, tag ); -+ -+ // Do we have text? -+ if ( in->good() && in->peek() != '<' ) -+ { -+ // Yep, text. -+ TiXmlText text( "" ); -+ text.StreamIn( in, tag ); -+ -+ // What follows text is a closing tag or another node. -+ // Go around again and figure it out. -+ continue; -+ } -+ -+ // We now have either a closing tag...or another node. -+ // We should be at a "<", regardless. -+ if ( !in->good() ) return; -+ assert( in->peek() == '<' ); -+ int tagIndex = tag->length(); -+ -+ bool closingTag = false; -+ bool firstCharFound = false; -+ -+ for( ;; ) -+ { -+ if ( !in->good() ) -+ return; -+ -+ int c = in->peek(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ -+ if ( c == '>' ) -+ break; -+ -+ *tag += (char) c; -+ in->get(); -+ -+ if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) ) -+ { -+ firstCharFound = true; -+ if ( c == '/' ) -+ closingTag = true; -+ } -+ } -+ // If it was a closing tag, then read in the closing '>' to clean up the input stream. -+ // If it was not, the streaming will be done by the tag. -+ if ( closingTag ) -+ { -+ if ( !in->good() ) -+ return; -+ -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ assert( c == '>' ); -+ *tag += (char) c; -+ -+ // We are done, once we've found our closing tag. -+ return; -+ } -+ else -+ { -+ // If not a closing tag, id it, and stream. -+ const char* tagloc = tag->c_str() + tagIndex; -+ TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING ); -+ if ( !node ) -+ return; -+ node->StreamIn( in, tag ); -+ delete node; -+ node = 0; -+ -+ // No return: go around from the beginning: text, closing tag, or node. -+ } -+ } -+ } -+} -+#endif -+ -+const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ p = SkipWhiteSpace( p, encoding ); -+ TiXmlDocument* document = GetDocument(); -+ -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding ); -+ return 0; -+ } -+ -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ -+ if ( *p != '<' ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding ); -+ return 0; -+ } -+ -+ p = SkipWhiteSpace( p+1, encoding ); -+ -+ // Read the name. -+ const char* pErr = p; -+ -+ p = ReadName( p, &value, encoding ); -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding ); -+ return 0; -+ } -+ -+ TIXML_STRING endTag ("</"); -+ endTag += value; -+ endTag += ">"; -+ -+ // Check for and read attributes. Also look for an empty -+ // tag or an end tag. -+ while ( p && *p ) -+ { -+ pErr = p; -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); -+ return 0; -+ } -+ if ( *p == '/' ) -+ { -+ ++p; -+ // Empty tag. -+ if ( *p != '>' ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding ); -+ return 0; -+ } -+ return (p+1); -+ } -+ else if ( *p == '>' ) -+ { -+ // Done with attributes (if there were any.) -+ // Read the value -- which can include other -+ // elements -- read the end tag, and return. -+ ++p; -+ p = ReadValue( p, data, encoding ); // Note this is an Element method, and will set the error if one happens. -+ if ( !p || !*p ) -+ return 0; -+ -+ // We should find the end tag now -+ if ( StringEqual( p, endTag.c_str(), false, encoding ) ) -+ { -+ p += endTag.length(); -+ return p; -+ } -+ else -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding ); -+ return 0; -+ } -+ } -+ else -+ { -+ // Try to read an attribute: -+ TiXmlAttribute* attrib = new TiXmlAttribute(); -+ if ( !attrib ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding ); -+ return 0; -+ } -+ -+ attrib->SetDocument( document ); -+ const char* pErr = p; -+ p = attrib->Parse( p, data, encoding ); -+ -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding ); -+ delete attrib; -+ return 0; -+ } -+ -+ // Handle the strange case of double attributes: -+ TiXmlAttribute* node = attributeSet.Find( attrib->Name() ); -+ if ( node ) -+ { -+ node->SetValue( attrib->Value() ); -+ delete attrib; -+ return 0; -+ } -+ -+ attributeSet.Add( attrib ); -+ } -+ } -+ return p; -+} -+ -+ -+const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ TiXmlDocument* document = GetDocument(); -+ -+ const char* pWithWhiteSpace = p; -+ // Read in text and elements in any order. -+ p = SkipWhiteSpace( p, encoding ); -+ while ( p && *p ) -+ { -+ if ( *p != '<' ) -+ { -+ // Take what we have, make a text element. -+ TiXmlText* textNode = new TiXmlText( "" ); -+ -+ if ( !textNode ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding ); -+ return 0; -+ } -+ -+ if ( TiXmlBase::IsWhiteSpaceCondensed() ) -+ { -+ p = textNode->Parse( p, data, encoding ); -+ } -+ else -+ { -+ // Special case: we want to keep the white space -+ // so that leading spaces aren't removed. -+ p = textNode->Parse( pWithWhiteSpace, data, encoding ); -+ } -+ -+ if ( !textNode->Blank() ) -+ LinkEndChild( textNode ); -+ else -+ delete textNode; -+ } -+ else -+ { -+ // We hit a '<' -+ // Have we hit a new element or an end tag? -+ if ( StringEqual( p, "</", false, encoding ) ) -+ { -+ return p; -+ } -+ else -+ { -+ TiXmlNode* node = Identify( p, encoding ); -+ if ( node ) -+ { -+ p = node->Parse( p, data, encoding ); -+ LinkEndChild( node ); -+ } -+ else -+ { -+ return 0; -+ } -+ } -+ } -+ p = SkipWhiteSpace( p, encoding ); -+ } -+ -+ if ( !p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding ); -+ } -+ return p; -+} -+ -+ -+#ifdef TIXML_USE_STL -+void TiXmlUnknown::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ while ( in->good() ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ (*tag) += (char) c; -+ -+ if ( c == '>' ) -+ { -+ // All is well. -+ return; -+ } -+ } -+} -+#endif -+ -+ -+const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ TiXmlDocument* document = GetDocument(); -+ p = SkipWhiteSpace( p, encoding ); -+ -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ if ( !p || !*p || *p != '<' ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding ); -+ return 0; -+ } -+ ++p; -+ value = ""; -+ -+ while ( p && *p && *p != '>' ) -+ { -+ value += *p; -+ ++p; -+ } -+ -+ if ( !p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding ); -+ } -+ if ( *p == '>' ) -+ return p+1; -+ return p; -+} -+ -+#ifdef TIXML_USE_STL -+void TiXmlComment::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ while ( in->good() ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ -+ (*tag) += (char) c; -+ -+ if ( c == '>' -+ && tag->at( tag->length() - 2 ) == '-' -+ && tag->at( tag->length() - 3 ) == '-' ) -+ { -+ // All is well. -+ return; -+ } -+ } -+} -+#endif -+ -+ -+const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ TiXmlDocument* document = GetDocument(); -+ value = ""; -+ -+ p = SkipWhiteSpace( p, encoding ); -+ -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ const char* startTag = "<!--"; -+ const char* endTag = "-->"; -+ -+ if ( !StringEqual( p, startTag, false, encoding ) ) -+ { -+ document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); -+ return 0; -+ } -+ p += strlen( startTag ); -+ p = ReadText( p, &value, false, endTag, false, encoding ); -+ return p; -+} -+ -+ -+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p || !*p ) return 0; -+ -+ int tabsize = 4; -+ if ( document ) -+ tabsize = document->TabSize(); -+ -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ // Read the name, the '=' and the value. -+ const char* pErr = p; -+ p = ReadName( p, &name, encoding ); -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); -+ return 0; -+ } -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p || !*p || *p != '=' ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); -+ return 0; -+ } -+ -+ ++p; // skip '=' -+ p = SkipWhiteSpace( p, encoding ); -+ if ( !p || !*p ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); -+ return 0; -+ } -+ -+ const char* end; -+ -+ if ( *p == '\'' ) -+ { -+ ++p; -+ end = "\'"; -+ p = ReadText( p, &value, false, end, false, encoding ); -+ } -+ else if ( *p == '"' ) -+ { -+ ++p; -+ end = "\""; -+ p = ReadText( p, &value, false, end, false, encoding ); -+ } -+ else -+ { -+ // All attribute values should be in single or double quotes. -+ // But this is such a common error that the parser will try -+ // its best, even without them. -+ value = ""; -+ while ( p && *p // existence -+ && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace -+ && *p != '/' && *p != '>' ) // tag end -+ { -+ value += *p; -+ ++p; -+ } -+ } -+ return p; -+} -+ -+#ifdef TIXML_USE_STL -+void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ while ( in->good() ) -+ { -+ int c = in->peek(); -+ if ( c == '<' ) -+ return; -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ -+ (*tag) += (char) c; -+ in->get(); -+ } -+} -+#endif -+ -+const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -+{ -+ value = ""; -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, encoding ); -+ location = data->Cursor(); -+ } -+ bool ignoreWhite = true; -+ -+ const char* end = "<"; -+ p = ReadText( p, &value, ignoreWhite, end, false, encoding ); -+ if ( p ) -+ return p-1; // don't truncate the '<' -+ return 0; -+} -+ -+#ifdef TIXML_USE_STL -+void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ while ( in->good() ) -+ { -+ int c = in->get(); -+ if ( c <= 0 ) -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) -+ document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ return; -+ } -+ (*tag) += (char) c; -+ -+ if ( c == '>' ) -+ { -+ // All is well. -+ return; -+ } -+ } -+} -+#endif -+ -+const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) -+{ -+ p = SkipWhiteSpace( p, _encoding ); -+ // Find the beginning, find the end, and look for -+ // the stuff in-between. -+ TiXmlDocument* document = GetDocument(); -+ if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) ) -+ { -+ if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); -+ return 0; -+ } -+// TiXmlParsingData data( p, prevData ); -+ if ( data ) -+ { -+ data->Stamp( p, _encoding ); -+ location = data->Cursor(); -+ } -+ p += 5; -+ -+ version = ""; -+ encoding = ""; -+ standalone = ""; -+ -+ while ( p && *p ) -+ { -+ if ( *p == '>' ) -+ { -+ ++p; -+ return p; -+ } -+ -+ p = SkipWhiteSpace( p, _encoding ); -+ if ( StringEqual( p, "version", true, _encoding ) ) -+ { -+ TiXmlAttribute attrib; -+ p = attrib.Parse( p, data, _encoding ); -+ version = attrib.Value(); -+ } -+ else if ( StringEqual( p, "encoding", true, _encoding ) ) -+ { -+ TiXmlAttribute attrib; -+ p = attrib.Parse( p, data, _encoding ); -+ encoding = attrib.Value(); -+ } -+ else if ( StringEqual( p, "standalone", true, _encoding ) ) -+ { -+ TiXmlAttribute attrib; -+ p = attrib.Parse( p, data, _encoding ); -+ standalone = attrib.Value(); -+ } -+ else -+ { -+ // Read over whatever it is. -+ while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) -+ ++p; -+ } -+ } -+ return 0; -+} -+ -+bool TiXmlText::Blank() const -+{ -+ for ( unsigned i=0; i<value.length(); i++ ) -+ if ( !IsWhiteSpace( value[i] ) ) -+ return false; -+ return true; -+} -+#endif /* SETUP */ -diff -ruNp vdr-1.7.5/vdr.c vdr-1.7.5-extensions/vdr.c ---- vdr-1.7.5/vdr.c 2009-04-05 15:21:46.000000000 +0200 -+++ vdr-1.7.5-extensions/vdr.c 2009-04-12 13:37:59.000000000 +0200 -@@ -139,10 +139,17 @@ static bool SetKeepCaps(bool On) - return true; - } - -+#ifdef USE_SETTIME -+char *SetTime=NULL; -+#endif /* SETTIME */ -+ - static void SignalHandler(int signum) - { - switch (signum) { - case SIGPIPE: -+#ifdef USE_EM84XX -+ case SIGINT: -+#endif /* EM84XX */ - break; - case SIGHUP: - LastSignal = signum; -@@ -163,6 +170,10 @@ static void Watchdog(int signum) - exit(1); - } - -+#ifdef USE_CMDRECCMDI18N -+const char *ConfigDirectory = NULL; -+#endif /* CMDRECCMDI18N */ -+ - int main(int argc, char *argv[]) - { - // Save terminal settings: -@@ -187,8 +198,11 @@ int main(int argc, char *argv[]) - bool UserDump = false; - int SVDRPport = DEFAULTSVDRPPORT; - const char *AudioCommand = NULL; -+#ifndef USE_CMDRECCMDI18N - const char *ConfigDirectory = NULL; -+#endif /* CMDRECCMDI18N */ - const char *EpgDataFileName = DEFAULTEPGDATAFILENAME; -+ bool DisplayExtensions = false; - bool DisplayHelp = false; - bool DisplayVersion = false; - bool DaemonMode = false; -@@ -221,6 +235,7 @@ int main(int argc, char *argv[]) - { "daemon", no_argument, NULL, 'd' }, - { "device", required_argument, NULL, 'D' }, - { "epgfile", required_argument, NULL, 'E' }, -+ { "extensions",no_argument, NULL, 'e' | 0x100 }, - { "grab", required_argument, NULL, 'g' }, - { "help", no_argument, NULL, 'h' }, - { "instance", required_argument, NULL, 'i' }, -@@ -236,6 +251,9 @@ int main(int argc, char *argv[]) - { "record", required_argument, NULL, 'r' }, - { "shutdown", required_argument, NULL, 's' }, - { "terminal", required_argument, NULL, 't' }, -+#ifdef USE_SETTIME -+ { "timeset", required_argument, NULL, 'T' }, -+#endif /* SETTIME */ - { "user", required_argument, NULL, 'u' }, - { "userdump", no_argument, NULL, 'u' | 0x100 }, - { "version", no_argument, NULL, 'V' }, -@@ -246,7 +264,11 @@ int main(int argc, char *argv[]) - }; - - int c; -+#ifdef USE_SETTIME -+ while ((c = getopt_long(argc, argv, "a:c:dD:E:g:hi:l:L:mp:P:r:s:t:T:u:v:Vw:", long_options, NULL)) != -1) { -+#else - while ((c = getopt_long(argc, argv, "a:c:dD:E:g:hi:l:L:mp:P:r:s:t:u:v:Vw:", long_options, NULL)) != -1) { -+#endif /* SETTIME */ - switch (c) { - case 'a': AudioCommand = optarg; - break; -@@ -263,6 +285,9 @@ int main(int argc, char *argv[]) - fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg); - return 2; - break; -+ case 'e' | 0x100: -+ DisplayExtensions = true; -+ break; - case 'E': EpgDataFileName = (*optarg != '-' ? optarg : NULL); - break; - case 'g': cSVDRP::SetGrabImageDir(*optarg != '-' ? optarg : NULL); -@@ -341,6 +366,10 @@ int main(int argc, char *argv[]) - break; - case 's': ShutdownHandler.SetShutdownCommand(optarg); - break; -+#ifdef USE_SETTIME -+ case 'T': SetTime = strdup(optarg); -+ break; -+#endif /* SETTIME */ - case 't': Terminal = optarg; - if (access(Terminal, R_OK | W_OK) < 0) { - fprintf(stderr, "vdr: can't access terminal: %s\n", Terminal); -@@ -406,6 +435,7 @@ int main(int argc, char *argv[]) - " -D NUM, --device=NUM use only the given DVB device (NUM = 0, 1, 2...)\n" - " there may be several -D options (default: all DVB\n" - " devices will be used)\n" -+ " --extensions print patchlevel and exit\n" - " -E FILE, --epgfile=FILE write the EPG data into the given FILE (default is\n" - " '%s' in the video directory)\n" - " '-E-' disables this\n" -@@ -437,6 +467,9 @@ int main(int argc, char *argv[]) - " -r CMD, --record=CMD call CMD before and after a recording\n" - " -s CMD, --shutdown=CMD call CMD to shutdown the computer\n" - " -t TTY, --terminal=TTY controlling tty\n" -+#ifdef USE_SETTIME -+ " -T CMD, --timeset=CMD call CMD to set the system time\n" -+#endif /* SETTIME */ - " -u USER, --user=USER run as user USER; only applicable if started as\n" - " root\n" - " --userdump allow coredumps if -u is given (debugging)\n" -@@ -480,6 +513,197 @@ int main(int argc, char *argv[]) - return 0; - } - -+ if (DisplayExtensions) { -+ printf("VDR %s\n", VDRVERSION); -+ printf("VDREXTENSIONS %d\n", VDREXTENSIONS); -+ -+#ifdef USE_ANALOGTV -+ printf(" ANALOGTV\n"); -+#endif /* ANALOGTV */ -+ -+#ifdef USE_ATSC -+ printf(" ATSC\n"); -+#endif /* ATSC */ -+ -+#ifdef USE_CHANNELSCAN -+ printf(" CHANNELSCAN\n"); -+#endif /* CHANNELSCAN */ -+ -+#ifdef USE_CMDRECCMDI18N -+ printf(" CMDRECCMDI18N\n"); -+#endif /* CMDRECCMDI18N */ -+ -+#ifdef USE_CMDSUBMENU -+ printf(" CMDSUBMENU %d\n", CMDSUBMENUVERSNUM); -+#endif /* CMDSUBMENU */ -+ -+#ifdef USE_CUTTERLIMIT -+ printf(" CUTTERLIMIT\n"); -+#endif /* CUTTERLIMIT */ -+ -+#ifdef USE_CUTTERQUEUE -+ printf(" CUTTERQUEUE\n"); -+#endif /* CUTTERQUEUE */ -+ -+#ifdef USE_CUTTIME -+ printf(" CUTTIME\n"); -+#endif /* CUTTIME */ -+ -+#ifdef USE_DDEPGENTRY -+ printf(" DDEPGENTRY\n"); -+#endif /* DDEPGENTRY */ -+ -+#ifdef USE_DELTIMESHIFTREC -+ printf(" DELTIMESHIFTREC\n"); -+#endif /* DELTIMESHIFTREC */ -+ -+#ifdef USE_DOLBYINREC -+ printf(" DOLBYINREC\n"); -+#endif /* DOLBYINREC */ -+ -+#ifdef USE_DVBSETUP -+ printf(" DVBSETUP\n"); -+#endif /* DVBSETUP */ -+ -+#ifdef USE_DVDARCHIVE -+ printf(" DVDARCHIVE\n"); -+#endif /* DVDARCHIVE */ -+ -+#ifdef USE_DVDCHAPJUMP -+ printf(" DVDCHAPJUMP\n"); -+#endif /* DVDCHAPJUMP */ -+ -+#ifdef USE_DVLRECSCRIPTADDON -+ printf(" DVLRECSCRIPTADDON\n"); -+#endif /* DVLRECSCRIPTADDON */ -+ -+#ifdef USE_DVLVIDPREFER -+ printf(" DVLVIDPREFER\n"); -+#endif /* DVLVIDPREFER */ -+ -+#ifdef USE_DVLFRIENDLYFNAMES -+ printf(" DVLFRIENDLYFNAMES\n"); -+#endif /* DVLFRIENDLYFNAMES */ -+ -+#ifdef USE_EM84XX -+ printf(" EM84XX\n"); -+#endif /* EM84XX */ -+ -+#ifdef USE_GRAPHTFT -+ printf(" GRAPHTFT\n"); -+#endif /* GRAPHTFT */ -+ -+#ifdef USE_HARDLINKCUTTER -+ printf(" HARDLINKCUTTER\n"); -+#endif /* HARDLINKCUTTER */ -+ -+#ifdef USE_JUMPPLAY -+ printf(" JUMPPLAY %d\n", JUMPPLAYVERSNUM); -+#endif /* JUMPPLAY */ -+ -+#ifdef USE_LIEMIEXT -+ printf(" LIEMIEXT %d\n", LIEMIKUUTIO); -+#endif /* LIEMIEXT */ -+ -+#ifdef USE_LIRCSETTINGS -+ printf(" LIRCSETTINGS\n"); -+#endif /* LIRCSETTINGS */ -+ -+#ifdef USE_LNBSHARE -+ printf(" LNBSHARE\n"); -+#endif /* LNBSHARE */ -+ -+#ifdef USE_MAINMENUHOOKS -+ printf(" MAINMENUHOOKS %3.1f\n", MAINMENUHOOKSVERSNUM); -+#endif /* MAINMENUHOOKS */ -+ -+#ifdef USE_MENUORG -+ printf(" MENUORG\n"); -+#endif /* MENUORG */ -+ -+#ifdef USE_NOEPG -+ printf(" NOEPG\n"); -+#endif /* NOEPG */ -+ -+#ifdef USE_OSDMAXITEMS -+ printf(" OSDMAXITEMS\n"); -+#endif /* OSDMAXITEMS */ -+ -+#ifdef USE_PARENTALRATING -+ printf(" PARENTALRATING\n"); -+#endif /* PARENTALRATING */ -+ -+#ifdef USE_PINPLUGIN -+ printf(" PINPLUGIN %d\n", PIN_PLUGIN_PATCH); -+#endif /* PINPLUGIN */ -+ -+#ifdef USE_PLUGINAPI -+ printf(" PLUGINAPI\n"); -+#endif /* PLUGINAPI */ -+ -+#ifdef USE_PLUGINMISSING -+ printf(" PLUGINMISSING\n"); -+#endif /* PLUGINMISSING */ -+ -+#ifdef USE_PLUGINPARAM -+ printf(" PLUGINPARAM %d\n", PLUGINPARAMPATCHVERSNUM); -+#endif /* PLUGINPARAM */ -+ -+#ifdef USE_ROTOR -+ printf(" ROTOR\n"); -+#endif /* ROTOR */ -+ -+#ifdef USE_SETTIME -+ printf(" SETTIME\n"); -+#endif /* SETTIME */ -+ -+#ifdef USE_SETUP -+ printf(" SETUP\n"); -+#endif /* SETUP */ -+ -+#ifdef USE_SOFTOSD -+ printf(" SOFTOSD\n"); -+#endif /* SOFTOSD */ -+ -+#ifdef USE_SOURCECAPS -+ printf(" SOURCECAPS\n"); -+#endif /* SOURCECAPS */ -+ -+#ifdef USE_SORTRECORDS -+ printf(" SORTRECORDS\n"); -+#endif /* SORTRECORDS */ -+ -+#ifdef USE_STREAMDEVEXT -+ printf(" STREAMDEVEXT\n"); -+#endif /* STREAMDEVEXT */ -+ -+#ifdef USE_TIMERCMD -+ printf(" TIMERCMD\n"); -+#endif /* TIMERCMD */ -+ -+#ifdef USE_TIMERINFO -+ printf(" TIMERINFO\n"); -+#endif /* TIMERINFO */ -+ -+#ifdef USE_VALIDINPUT -+ printf(" VALIDINPUT\n"); -+#endif /* VALIDINPUT */ -+ -+#ifdef USE_VOLCTRL -+ printf(" VOLCTRL\n"); -+#endif /* VOLCTRL */ -+ -+#ifdef USE_WAREAGLEICON -+ printf(" WAREAGLEICON\n"); -+#endif /* WAREAGLEICON */ -+ -+#ifdef USE_YAEPG -+ printf(" YAEPG\n"); -+#endif /* YAEPG */ -+ -+ return 0; -+ } -+ - // Log file: - - if (SysLogLevel > 0) -@@ -573,8 +797,20 @@ int main(int argc, char *argv[]) - Diseqcs.Load(AddDirectory(ConfigDirectory, "diseqc.conf"), true, Setup.DiSEqC); - Channels.Load(AddDirectory(ConfigDirectory, "channels.conf"), false, true); - Timers.Load(AddDirectory(ConfigDirectory, "timers.conf")); -+#ifdef USE_CMDRECCMDI18N -+ LoadCommandsI18n(Commands,AddDirectory(ConfigDirectory, "commands.conf"), true); -+ LoadCommandsI18n(RecordingCommands, AddDirectory(ConfigDirectory, "reccmds.conf"), true); -+#else - Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"), true); - RecordingCommands.Load(AddDirectory(ConfigDirectory, "reccmds.conf"), true); -+#endif /* CMDRECCMDI18N */ -+#ifdef USE_TIMERCMD -+#ifdef USE_CMDRECCMDI18N -+ LoadCommandsI18n(TimerCommands, AddDirectory(ConfigDirectory, "timercmds.conf"), true); -+#else -+ TimerCommands.Load(AddDirectory(ConfigDirectory, "timercmds.conf"), true); -+#endif /* CMDRECCMDI18N */ -+#endif /* TIMERCMD */ - SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true); - Keys.Load(AddDirectory(ConfigDirectory, "remote.conf")); - KeyMacros.Load(AddDirectory(ConfigDirectory, "keymacros.conf"), true); -@@ -735,7 +971,11 @@ int main(int argc, char *argv[]) - // Make sure we have a visible programme in case device usage has changed: - if (!EITScanner.Active() && cDevice::PrimaryDevice()->HasDecoder() && !cDevice::PrimaryDevice()->HasProgramme()) { - static time_t lastTime = 0; -+#ifdef USE_CHANNELSCAN -+ if (!scanning_on_receiving_device && (!Menu || CheckHasProgramme) && Now - lastTime > MINCHANNELWAIT) { -+#else - if ((!Menu || CheckHasProgramme) && Now - lastTime > MINCHANNELWAIT) { // !Menu to avoid interfering with the CAM if a CAM menu is open -+#endif /* CHANNELSCAN */ - cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel()); - if (Channel && (Channel->Vpid() || Channel->Apid(0))) { - if (!Channels.SwitchTo(cDevice::CurrentChannel()) // try to switch to the original channel... -@@ -910,6 +1150,9 @@ int main(int argc, char *argv[]) - cOsdObject *Interact = Menu ? Menu : cControl::Control(); - eKeys key = Interface->GetKey(!Interact || !Interact->NeedsFastResponse()); - if (ISREALKEY(key)) { -+#ifdef USE_PINPLUGIN -+ cStatus::MsgUserAction(key, Interact); -+#endif /* PINPLUGIN */ - EITScanner.Activity(); - // Cancel shutdown countdown: - if (ShutdownHandler.countdown) -@@ -982,10 +1225,16 @@ int main(int argc, char *argv[]) - cControl::Control()->Hide(); - cPlugin *plugin = cPluginManager::GetPlugin(PluginName); - if (plugin) { -+#ifdef USE_PINPLUGIN -+ if (!cStatus::MsgPluginProtected(plugin)) { -+#endif /* PINPLUGIN */ - Menu = plugin->MainMenuAction(); - if (Menu) - Menu->Show(); - } -+#ifdef USE_PINPLUGIN -+ } -+#endif /* PINPLUGIN */ - else - esyslog("ERROR: unknown plugin '%s'", PluginName); - } -@@ -1062,8 +1311,15 @@ int main(int argc, char *argv[]) - // Instant recording: - case kRecord: - if (!cControl::Control()) { -+#ifdef USE_STREAMDEVEXT -+ if (cRecordControls::Start()) { -+ Skins.Message(mtInfo, tr("Recording started")); -+ cStatus::MsgRecordingChange(NULL, scAdd); -+ } -+#else - if (cRecordControls::Start()) - Skins.Message(mtInfo, tr("Recording started")); -+#endif /* STREAMDEVEXT */ - key = kNone; // nobody else needs to see this key - } - break; -@@ -1119,8 +1375,15 @@ int main(int argc, char *argv[]) - Skins.Message(mtError, tr("No free DVB device to record!")); - break; - case osRecord: DELETE_MENU; -+#ifdef USE_STREAMDEVEXT -+ if (cRecordControls::Start()) { -+ Skins.Message(mtInfo, tr("Recording started")); -+ cStatus::MsgRecordingChange(NULL, scAdd); -+ } -+#else - if (cRecordControls::Start()) - Skins.Message(mtInfo, tr("Recording started")); -+#endif /* STREAMDEVEXT */ - break; - case osRecordings: - DELETE_MENU; -@@ -1171,13 +1434,26 @@ int main(int argc, char *argv[]) - Channels.SwitchTo(PreviousChannel[PreviousChannelIndex ^= 1]); - break; - } -+#ifdef USE_VOLCTRL -+ // Left/Right volume control -+#else - // Direct Channel Select: - case k1 ... k9: - // Left/Right rotates through channel groups: -+#endif /* VOLCTRL */ - case kLeft|k_Repeat: - case kLeft: - case kRight|k_Repeat: - case kRight: -+#ifdef USE_VOLCTRL -+ if (Setup.LRVolumeControl && Setup.LRChannelGroups < 2) { -+ cRemote::Put(NORMALKEY(key) == kLeft ? kVolDn : kVolUp, true); -+ break; -+ } -+ // else fall through -+ // Direct Channel Select: -+ case k1 ... k9: -+#endif /* VOLCTRL */ - // Previous/Next rotates through channel groups: - case kPrev|k_Repeat: - case kPrev: -@@ -1195,9 +1471,15 @@ int main(int argc, char *argv[]) - // Instant resume of the last viewed recording: - case kPlay: - if (cReplayControl::LastReplayed()) { -+#ifdef USE_PINPLUGIN -+ if (cStatus::MsgReplayProtected(0, cReplayControl::LastReplayed(), 0, false) == false) { -+#endif /* PINPLUGIN */ - cControl::Shutdown(); - cControl::Launch(new cReplayControl); - } -+#ifdef USE_PINPLUGIN -+ } -+#endif /* PINPLUGIN */ - break; - default: break; - } -diff -ruNp vdr-1.7.5/videodir.c vdr-1.7.5-extensions/videodir.c ---- vdr-1.7.5/videodir.c 2008-02-16 14:00:03.000000000 +0100 -+++ vdr-1.7.5-extensions/videodir.c 2009-04-12 13:37:59.000000000 +0200 -@@ -19,6 +19,13 @@ - #include "recording.h" - #include "tools.h" - -+#ifdef USE_HARDLINKCUTTER -+//#define HARDLINK_TEST_ONLY -+#ifdef USE_STREAMDEVEXT -+#include "status.h" -+#endif /* STREAMDEVEXT */ -+#endif /* HARDLINKCUTTER */ -+ - const char *VideoDirectory = VIDEODIR; - - class cVideoDirectory { -@@ -36,6 +43,11 @@ public: - bool Next(void); - void Store(void); - const char *Adjust(const char *FileName); -+#ifdef USE_DVLVIDPREFER -+ char *GetVidPath(int nVid); -+ bool GetPreferedVideoDir(void); -+ bool IsVidDirOK(int nVid, int *freeMB = NULL); -+#endif /* DVLVIDPREFER */ - }; - - cVideoDirectory::cVideoDirectory(void) -@@ -117,6 +129,9 @@ cUnbufferedFile *OpenVideoFile(const cha - if ((Flags & O_CREAT) != 0) { - cVideoDirectory Dir; - if (Dir.IsDistributed()) { -+#ifdef USE_DVLVIDPREFER -+ if (Setup.UseVidPrefer == 0) { -+#endif /* DVLVIDPREFER */ - // Find the directory with the most free space: - int MaxFree = Dir.FreeMB(); - while (Dir.Next()) { -@@ -126,14 +141,24 @@ cUnbufferedFile *OpenVideoFile(const cha - MaxFree = Free; - } - } -+#ifdef USE_DVLVIDPREFER -+ } -+ else Dir.GetPreferedVideoDir(); -+#endif /* DVLVIDPREFER */ - if (Dir.Stored()) { - ActualFileName = Dir.Adjust(FileName); - if (!MakeDirs(ActualFileName, false)) - return NULL; // errno has been set by MakeDirs() -+#ifdef USE_DVLVIDPREFER -+ if (strcmp(ActualFileName, FileName) != 0) { -+#endif /* DVLVIDPREFER */ - if (symlink(ActualFileName, FileName) < 0) { - LOG_ERROR_STR(FileName); - return NULL; - } -+#ifdef USE_DVLVIDPREFER -+ } -+#endif /* DVLVIDPREFER */ - ActualFileName = strdup(ActualFileName); // must survive Dir! - } - } -@@ -168,6 +193,125 @@ bool RemoveVideoFile(const char *FileNam - return RemoveFileOrDir(FileName, true); - } - -+#ifdef USE_HARDLINKCUTTER -+static bool StatNearestDir(const char *FileName, struct stat *Stat) -+{ -+ cString Name(FileName); -+ char *p; -+ while ((p = strrchr((const char*)Name + 1, '/')) != NULL) { -+ *p = 0; // truncate at last '/' -+ if (stat(Name, Stat) == 0) { -+ isyslog("StatNearestDir: Stating %s", (const char*)Name); -+ return true; -+ } -+ } -+ return false; -+} -+ -+bool HardLinkVideoFile(const char *OldName, const char *NewName) -+{ -+ // Incoming name must be in base video directory: -+ if (strstr(OldName, VideoDirectory) != OldName) { -+ esyslog("ERROR: %s not in %s", OldName, VideoDirectory); -+ return false; -+ } -+ if (strstr(NewName, VideoDirectory) != NewName) { -+ esyslog("ERROR: %s not in %s", NewName, VideoDirectory); -+ return false; -+ } -+ -+ const char *ActualNewName = NewName; -+ cString ActualOldName(ReadLink(OldName), true); -+ -+ // Some safety checks: -+ struct stat StatOldName; -+ if (lstat(ActualOldName, &StatOldName) == 0) { -+ if (S_ISLNK(StatOldName.st_mode)) { -+ esyslog("HardLinkVideoFile: Failed to resolve symbolic link %s", (const char*)ActualOldName); -+ return false; -+ } -+ } -+ else { -+ esyslog("HardLinkVideoFile: lstat failed on %s", (const char*)ActualOldName); -+ return false; -+ } -+ isyslog("HardLinkVideoFile: %s is on %i", (const char*)ActualOldName, (int)StatOldName.st_dev); -+ -+ // Find the video directory where ActualOldName is located -+ -+ cVideoDirectory Dir; -+ struct stat StatDir; -+ if (!StatNearestDir(NewName, &StatDir)) { -+ esyslog("HardLinkVideoFile: stat failed on %s", NewName); -+ return false; -+ } -+ -+ isyslog("HardLinkVideoFile: %s is on %i", NewName, (int)StatDir.st_dev); -+ if (StatDir.st_dev != StatOldName.st_dev) { -+ // Not yet found. -+ -+ if (!Dir.IsDistributed()) { -+ esyslog("HardLinkVideoFile: No matching video folder to hard link %s", (const char*)ActualOldName); -+ return false; -+ } -+ -+ // Search in video01 and upwards -+ bool found = false; -+ while (Dir.Next()) { -+ Dir.Store(); -+ const char *TmpNewName = Dir.Adjust(NewName); -+ if (StatNearestDir(TmpNewName, &StatDir) && StatDir.st_dev == StatOldName.st_dev) { -+ isyslog("HardLinkVideoFile: %s is on %i (match)", TmpNewName, (int)StatDir.st_dev); -+ ActualNewName = TmpNewName; -+ found = true; -+ break; -+ } -+ isyslog("HardLinkVideoFile: %s is on %i", TmpNewName, (int)StatDir.st_dev); -+ } -+ if (ActualNewName == NewName) { -+ esyslog("HardLinkVideoFile: No matching video folder to hard link %s", (const char*)ActualOldName); -+ return false; -+ } -+ -+ // Looking good, we have a match. Create necessary folders. -+ if (!MakeDirs(ActualNewName, false)) -+ return false; -+ // There's no guarantee that the directory of ActualNewName -+ // is on the same device as the dir that StatNearestDir found. -+ // But worst case is that the link fails. -+ } -+ -+#ifdef HARDLINK_TEST_ONLY -+ // Do the hard link to *.vdr_ for testing only -+ char *name = NULL; -+ asprintf(&name, "%s_",ActualNewName); -+ link(ActualOldName, name); -+ free(name); -+ return false; -+#endif // HARDLINK_TEST_ONLY -+ -+ // Try creating the hard link -+ if (link(ActualOldName, ActualNewName) != 0) { -+ // Failed to hard link. Maybe not allowed on file system. -+ LOG_ERROR_STR(ActualNewName); -+ isyslog("HardLinkVideoFile: failed to hard link from %s to %s", (const char*)ActualOldName, ActualNewName); -+ return false; -+ } -+ -+ if (ActualNewName != NewName) { -+ // video01 and up. Do the remaining symlink -+ if (symlink(ActualNewName, NewName) < 0) { -+ LOG_ERROR_STR(NewName); -+ return false; -+ } -+ } -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgRecordingChange(Recordings.GetByName(NewName), scMod); -+#endif /* STREAMDEVEXT */ -+ return true; -+} -+#endif /* HARDLINKCUTTER */ -+ - bool VideoFileSpaceAvailable(int SizeMB) - { - cVideoDirectory Dir; -@@ -232,6 +376,129 @@ void RemoveEmptyVideoDirectories(void) - } while (Dir.Next()); - } - -+#ifdef USE_DVLVIDPREFER -+// returns path to nVid'th video directory or NULL if not existing -+char *cVideoDirectory::GetVidPath(int nVid) -+{ -+ char *b = strdup(VideoDirectory); -+ int l = strlen(b), di, n; -+ -+ while (l-- > 0 && isdigit(b[ l ])); -+ -+ l++; -+ di = strlen(b) - l; -+ -+ // di == number of digits -+ n = atoi(&b[ l ]); -+ if (n != 0) -+ return NULL; -+ -+ // add requested number to dir name -+ sprintf(&b[ l ], "%0*d", di, nVid); -+ -+ if (DirectoryOk(b) == true) -+ return b; -+ -+ free(b); -+ return NULL; -+} -+ -+// checks if a video dir is 'valid' -+bool cVideoDirectory::IsVidDirOK(int nVid, int *freeMB) -+{ -+ char *dn; -+ int fMB; -+ -+ if (nVid >= Setup.nVidPrefer) -+ return false; -+ -+ if (Setup.VidPreferSize[ nVid ] == -1) -+ return false; -+ -+ dn = GetVidPath(nVid); -+ if (dn == NULL) -+ return false; -+ -+ fMB = FreeDiskSpaceMB(dn, NULL); -+ if (freeMB != NULL) -+ *freeMB = fMB; -+ -+ free(dn); -+ -+ if (Setup.VidPreferSize[ nVid ] >= fMB) -+ return false; -+ return true; -+} -+ -+ -+// calculates which video dir to use -+bool cVideoDirectory::GetPreferedVideoDir(void) -+{ -+ cVideoDirectory d; -+ int nDirs = 1, -+ vidUse = Setup.nVidPrefer; -+ int i, top, topFree, x; -+ -+ if (name == NULL) -+ return(false); -+ -+ // count available video dirs -+ while (d.Next() == true) -+ nDirs++; -+ -+ if (vidUse > nDirs) -+ vidUse = nDirs; -+ -+ // check for prefered video dir -+ for (i = 0, top = -1, topFree = 0; i < vidUse; i++) { -+ if (IsVidDirOK(i, &x) == true) { -+ if (top == -1) { -+ // nothing set yet, use first 'ok' dir -+ top = i; -+ topFree = x; -+ } -+ else { -+ // check if we got a higher priority -+ if (Setup.VidPreferPrio[ i ] >= Setup.VidPreferPrio[ top ]) { -+ top = i; -+ topFree = x; -+ } -+ // check if we got same priority but more space -+ else if (Setup.VidPreferPrio[ i ] == Setup.VidPreferPrio[ top ] && x >= topFree) { -+ top = i; -+ topFree = x; -+ } -+ } -+ } -+ } -+ -+ if (top == -1) { -+ isyslog("VidPrefer: no prefered video directory could be determined!"); -+ -+ // something went wrong here... -+ // let VDR determine the video directory -+ int MaxFree = FreeMB(); -+ -+ while (Next()) { -+ int Free = FreeDiskSpaceMB(Name()); -+ -+ if (Free > MaxFree) { -+ Store(); -+ MaxFree = Free; -+ } -+ } -+ } -+ else { -+ isyslog("VidPrefer: prefered video directory '%d' set.", top); -+ if (stored != NULL) -+ free(stored); -+ stored = GetVidPath(top); -+ } -+ -+ return true; -+} -+#endif /* DVLVIDPREFER */ -+ - bool IsOnVideoDirectoryFileSystem(const char *FileName) - { - cVideoDirectory Dir; -diff -ruNp vdr-1.7.5/videodir.h vdr-1.7.5-extensions/videodir.h ---- vdr-1.7.5/videodir.h 2008-02-16 13:53:11.000000000 +0100 -+++ vdr-1.7.5-extensions/videodir.h 2009-04-12 13:37:59.000000000 +0200 -@@ -19,6 +19,9 @@ cUnbufferedFile *OpenVideoFile(const cha - int CloseVideoFile(cUnbufferedFile *File); - bool RenameVideoFile(const char *OldName, const char *NewName); - bool RemoveVideoFile(const char *FileName); -+#ifdef USE_HARDLINKCUTTER -+bool HardLinkVideoFile(const char *OldName, const char *NewName); -+#endif /* HARDLINKCUTTER */ - bool VideoFileSpaceAvailable(int SizeMB); - int VideoDiskSpace(int *FreeMB = NULL, int *UsedMB = NULL); // returns the used disk space in percent - cString PrefixVideoFileName(const char *FileName, char Prefix); |
