summaryrefslogtreecommitdiff
path: root/vdr/extensions
diff options
context:
space:
mode:
authorroot <root@elwms02.(none)>2010-04-06 17:58:16 +0200
committerroot <root@elwms02.(none)>2010-04-06 17:58:16 +0200
commitb0e043bce24d58896dd6bbec46fc7f5fb8bec595 (patch)
tree3dab97cfc9217fcf91e0c7b0bc7bdd75cc833e94 /vdr/extensions
parent0e7005fcc7483c01aa102fbea358c5ac65a48d62 (diff)
downloadx-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.diff5483
-rw-r--r--vdr/extensions/vdr-1.7.0_extensions.diff28873
-rw-r--r--vdr/extensions/vdr-1.7.5_extensions.diff23830
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 ( &copy == 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.
-+ // &#xA9; -- 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 ] =
-+{
-+ { "&amp;", 5, '&' },
-+ { "&lt;", 4, '<' },
-+ { "&gt;", 4, '>' },
-+ { "&quot;", 6, '\"' },
-+ { "&apos;", 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 ( &copy == 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.
-+ // &#xA9; -- 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 ] =
-+{
-+ { "&amp;", 5, '&' },
-+ { "&lt;", 4, '<' },
-+ { "&gt;", 4, '>' },
-+ { "&quot;", 6, '\"' },
-+ { "&apos;", 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);