diff --git a/packages/multimedia/vdr/patches/10_vdr-1.7.10_extensions.diff b/packages/multimedia/vdr/patches/10_vdr-1.7.10_extensions.diff deleted file mode 100644 index db800268f2..0000000000 --- a/packages/multimedia/vdr/patches/10_vdr-1.7.10_extensions.diff +++ /dev/null @@ -1,20088 +0,0 @@ -diff -Naur vdr-1.7.10/channels.c vdr-1.7.10b/channels.c ---- vdr-1.7.10/channels.c 2009-08-30 13:25:50.000000000 +0200 -+++ vdr-1.7.10b/channels.c 2009-12-30 11:33:26.000000000 +0100 -@@ -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 @@ - 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 @@ - shortName = NULL; - provider = NULL; - portalName = NULL; -+#ifdef USE_PLUGINPARAM -+ pluginParam = NULL; -+#endif /* PLUGINPARAM */ - schedule = NULL; - linkChannels = NULL; - refChannel = NULL; -@@ -239,6 +248,9 @@ - free(shortName); - free(provider); - free(portalName); -+#ifdef USE_PLUGINPARAM -+ free(pluginParam); -+#endif /* PLUGINPARAM */ - } - - cChannel& cChannel::operator= (const cChannel &Channel) -@@ -247,6 +259,9 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - } - } - -+#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 - -@@ -550,6 +603,17 @@ - } - } - -+#ifdef USE_TTXTSUBS -+void cChannel::SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[]) -+{ -+ for (int i = 0; i < MAXTPAGES; i++) { -+ tpages[i] = TPages[i]; -+ strn0cpy(tlangs[i], TLangs[i], MAXLANGCODE2); -+ } -+ tpages[MAXTPAGES] = 0; -+} -+#endif /* TTXTSUBS */ -+ - void cChannel::SetCaIds(const int *CaIds) - { - if (caids[0] && caids[0] <= CA_USER_MAX) -@@ -651,7 +715,11 @@ - 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); -@@ -665,6 +733,9 @@ - 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; - } - -@@ -693,7 +764,11 @@ - - 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; -@@ -811,7 +886,11 @@ - 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) { -@@ -906,6 +985,9 @@ - shortName = strcpyrealloc(shortName, p); - } - name = strcpyrealloc(name, namebuf); -+#ifdef USE_PLUGINPARAM -+ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, parambuf); -+#endif /* PLUGINPARAM */ - - free(parambuf); - free(sourcebuf); -@@ -1151,6 +1233,9 @@ - NewChannel->SetName(Name, ShortName, Provider); - Add(NewChannel); - ReNumber(); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgChannelChange(NewChannel, scAdd); -+#endif /* STREAMDEVEXT */ - return NewChannel; - } - return NULL; -diff -Naur vdr-1.7.10/channels.h vdr-1.7.10b/channels.h ---- vdr-1.7.10/channels.h 2009-08-30 13:05:54.000000000 +0200 -+++ vdr-1.7.10b/channels.h 2009-12-30 11:33:26.000000000 +0100 -@@ -35,6 +35,9 @@ - #define MAXDPIDS 16 // dolby (AC3 + DTS) - #define MAXSPIDS 32 // subtitles - #define MAXCAIDS 8 // conditional access -+#ifdef USE_TTXTSUBS -+#define MAXTPAGES 8 // teletext pages -+#endif /* TTXTSUBS */ - - #define MAXLANGCODE1 4 // a 3 letter language code, zero terminated - #define MAXLANGCODE2 8 // up to two 3 letter language codes, separated by '+' and zero terminated -@@ -116,6 +119,9 @@ - char *shortName; - char *provider; - char *portalName; -+#ifdef USE_PLUGINPARAM -+ char *pluginParam; -+#endif /* PLUGINPARAM */ - int __BeginData__; - int frequency; // MHz - int source; -@@ -133,6 +139,10 @@ - uint16_t compositionPageIds[MAXSPIDS]; - uint16_t ancillaryPageIds[MAXSPIDS]; - int tpid; -+#ifdef USE_TTXTSUBS -+ char tlangs[MAXTPAGES][MAXLANGCODE2]; -+ int tpages[MAXTPAGES + 1]; // list is zero-terminated -+#endif /* TTXTSUBS */ - int caids[MAXCAIDS + 1]; // list is zero-terminated - int nid; - int tid; -@@ -174,6 +184,9 @@ - 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; } -@@ -192,6 +205,10 @@ - uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : 0; } - uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : 0; } - int Tpid(void) const { return tpid; } -+#ifdef USE_TTXTSUBS -+ const char *Tlang(int i) const { return (0 <= i && i < MAXTPAGES) ? tlangs[i] : ""; } -+ const int TPages(int i) const { return (0 <= i && i < MAXTPAGES) ? tpages[i] : 0; } -+#endif /* TTXTSUBS */ - const int *Caids(void) const { return caids; } - int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; } - int Nid(void) const { return nid; } -@@ -214,6 +231,9 @@ - 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); } -@@ -221,13 +241,22 @@ - 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); -+#ifdef USE_TTXTSUBS -+ void SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[]); -+#endif /* TTXTSUBS */ - void SetCaIds(const int *CaIds); // list must be zero-terminated - void SetCaDescriptors(int Level); - void SetLinkChannels(cLinkChannels *LinkChannels); -diff -Naur vdr-1.7.10/config.c vdr-1.7.10b/config.c ---- vdr-1.7.10/config.c 2009-06-13 12:25:05.000000000 +0200 -+++ vdr-1.7.10b/config.c 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -@@ -30,18 +33,32 @@ - { - 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); -@@ -87,6 +104,20 @@ - 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) -@@ -127,6 +158,26 @@ - - 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::Add(Object); -+} -+#endif /* CMDSUBMENU */ - - // --- cSVDRPhosts ----------------------------------------------------------- - -@@ -218,6 +269,12 @@ - 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; -@@ -263,6 +320,15 @@ - 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; - OSDLeftP = 0.08; -@@ -287,24 +353,135 @@ - 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; - } - -@@ -400,11 +577,62 @@ - 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); -@@ -450,6 +678,18 @@ - 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, "OSDLeftP")) OSDLeftP = atof(Value); -@@ -474,21 +714,144 @@ - 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; - } - -@@ -497,6 +860,12 @@ - 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); -@@ -542,6 +911,15 @@ - 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("OSDLeftP", OSDLeftP); -@@ -566,25 +944,152 @@ - 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::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 -+ cString FullPath = cString::sprintf("%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); -+ } -+ } -+ 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 -Naur vdr-1.7.10/config.h vdr-1.7.10b/config.h ---- vdr-1.7.10/config.h 2009-08-29 14:47:03.000000000 +0200 -+++ vdr-1.7.10b/config.h 2009-12-30 11:33:26.000000000 +0100 -@@ -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 72 -+ -+#ifdef USE_JUMPPLAY -+#define JUMPPLAYVERSNUM 100 -+#endif /* JUMPPLAY */ -+ -+#ifdef USE_LIEMIEXT -+#define LIEMIKUUTIO 127 -+#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 1920 - #define MINOSDHEIGHT 324 - #define MAXOSDHEIGHT 1200 - -+#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 @@ - 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 @@ - public: - cConfig(void) { fileName = NULL; } - virtual ~cConfig() { free(fileName); } -+#ifdef USE_CMDSUBMENU -+ virtual void AddConfig(T *Object) { cList::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 @@ - 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 @@ - } - }; - -+#ifdef USE_CMDSUBMENU -+class cCommands : public cConfig { -+public: -+ virtual void AddConfig(cCommand *Object); -+ }; -+#else - class cCommands : public cConfig {}; -+#endif /* CMDSUBMENU */ - - class cSVDRPhosts : public cConfig { - public: -@@ -167,6 +240,9 @@ - - 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 @@ - 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 @@ - 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; -@@ -243,6 +329,14 @@ - 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; - double OSDLeftP, OSDTopP, OSDWidthP, OSDHeightP; -@@ -261,20 +355,111 @@ - 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); -@@ -282,4 +467,8 @@ - - 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 -Naur vdr-1.7.10/cutter.c vdr-1.7.10b/cutter.c ---- vdr-1.7.10/cutter.c 2009-04-19 12:56:33.000000000 +0200 -+++ vdr-1.7.10b/cutter.c 2009-12-30 11:33:26.000000000 +0100 -@@ -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; -@@ -67,6 +80,22 @@ - - 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(); -@@ -78,6 +107,9 @@ - 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(); -@@ -96,12 +128,101 @@ - - // 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) { -@@ -118,6 +239,7 @@ - break; - } - } -+#ifndef USE_HARDLINKCUTTER - else { - // Error, unless we're past the last cut-in and there's no cut-out - if (Mark || LastMark) -@@ -125,12 +247,17 @@ - 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"; -@@ -140,7 +267,11 @@ - } - LastIFrame = 0; - -+#ifndef USE_HARDLINKCUTTER - if (cutIn) { -+#else -+ if (!SkipThisSourceFile && cutIn) { -+#endif /* HARDLINKCUTTER */ - if (isPesRecording) - cRemux::SetBrokenLink(buffer, Length); - else -@@ -148,7 +279,11 @@ - 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; - } -@@ -183,8 +318,44 @@ - } - } - 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(); - } -@@ -194,18 +365,74 @@ - - // --- 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 /**cCutter::*/cutterQueue /*= new cList*/; -+#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: -@@ -231,6 +458,9 @@ - - 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; -@@ -242,11 +472,20 @@ - 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; -@@ -257,12 +496,40 @@ - 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; -@@ -270,6 +537,9 @@ - - bool cCutter::Ended(void) - { -+#ifdef USE_CUTTERQUEUE -+ cMutexLock(cutterLock); -+#endif /* CUTTERQUEUE */ - bool result = ended; - ended = false; - return result; -diff -Naur vdr-1.7.10/cutter.h vdr-1.7.10b/cutter.h ---- vdr-1.7.10/cutter.h 2002-06-22 12:03:15.000000000 +0200 -+++ vdr-1.7.10b/cutter.h 2009-12-30 11:33:26.000000000 +0100 -@@ -11,6 +11,9 @@ - #define __CUTTER_H - - class cCuttingThread; -+#ifdef USE_CUTTERQUEUE -+class cMutex; -+#endif /* CUTTERQUEUE */ - - class cCutter { - private: -@@ -18,6 +21,9 @@ - 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 -Naur vdr-1.7.10/device.c vdr-1.7.10b/device.c ---- vdr-1.7.10/device.c 2009-11-22 14:19:03.000000000 +0100 -+++ vdr-1.7.10b/device.c 2009-12-30 11:33:26.000000000 +0100 -@@ -18,6 +18,17 @@ - #include "receiver.h" - #include "status.h" - #include "transfer.h" -+#ifdef USE_TTXTSUBS -+#include "vdrttxtsubshooks.h" -+#endif /* TTXTSUBS */ -+ -+#ifdef USE_LNBSHARE -+#include "diseqc.h" -+#endif /* LNBSHARE */ -+ -+#ifdef USE_CHANNELSCAN -+bool scanning_on_receiving_device = false; -+#endif /* CHANNELSCAN */ - - // --- cLiveSubtitle --------------------------------------------------------- - -@@ -69,6 +80,12 @@ - - SetVideoFormat(Setup.VideoFormat); - -+#ifdef USE_LNBSHARE -+ LNBstate = -1; -+ LNBnr = Setup.CardUsesLNBnr[cardIndex]; -+ LNBsource = NULL; -+#endif /* LNBSHARE */ -+ - mute = false; - volume = Setup.CurrentVolume; - -@@ -94,8 +111,15 @@ - 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!"); - } -@@ -130,6 +154,16 @@ - 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) { -@@ -190,6 +224,98 @@ - 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; -@@ -239,6 +365,10 @@ - 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 -@@ -272,7 +402,31 @@ - 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]; -@@ -313,6 +467,18 @@ - 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; -@@ -571,7 +737,11 @@ - 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; -@@ -599,6 +769,24 @@ - - 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 -@@ -628,7 +816,14 @@ - 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; - } -@@ -649,6 +844,13 @@ - - 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); -@@ -661,11 +863,37 @@ - - 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())); -@@ -683,6 +911,10 @@ - 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) -@@ -975,7 +1207,12 @@ - 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: -@@ -1182,6 +1419,15 @@ - } - break; - case 0xBD: { // private stream 1 -+#ifdef USE_TTXTSUBS -+ // EBU Teletext data, ETSI EN 300 472 -+ // if PES data header length = 24 and data_identifier = 0x10..0x1F (EBU Data) -+ if (Data[8] == 0x24 && Data[45] >= 0x10 && Data[45] < 0x20) { -+ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uint8_t*)Data, Length); -+ break; -+ } -+#endif /* TTXTSUBS */ -+ - int PayloadOffset = Data[8] + 9; - - // Compatibility mode for old subtitles plugin: -@@ -1209,7 +1455,11 @@ - 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); -@@ -1341,6 +1591,9 @@ - tsToPesVideo.Reset(); - tsToPesAudio.Reset(); - tsToPesSubtitle.Reset(); -+#ifdef USE_TTXTSUBS -+ tsToPesTeletext.Reset(); -+#endif /* TTXTSUBS */ - } - else if (Length < TS_SIZE) { - esyslog("ERROR: skipped %d bytes of TS fragment", Length); -@@ -1386,6 +1639,19 @@ - if (!VideoOnly || HasIBPTrickSpeed()) - PlayTsSubtitle(Data, TS_SIZE); - } -+#ifdef USE_TTXTSUBS -+ else if (Pid == patPmtParser.Tpid()) { -+ if (!VideoOnly || HasIBPTrickSpeed()) { -+ int l; -+ tsToPesTeletext.PutTs(Data, Length); -+ if (const uchar *p = tsToPesTeletext.GetPes(l)) { -+ if ((l > 45) && (p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xbd) && (p[8] == 0x24) && (p[45] >= 0x10) && (p[45] < 0x20)) -+ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uchar *)p, l, false); -+ tsToPesTeletext.Reset(); -+ } -+ } -+ } -+#endif /* TTXTSUBS */ - } - } - Played += TS_SIZE; -diff -Naur vdr-1.7.10/device.h vdr-1.7.10b/device.h ---- vdr-1.7.10/device.h 2009-11-22 14:21:00.000000000 +0100 -+++ vdr-1.7.10b/device.h 2009-12-30 11:33:26.000000000 +0100 -@@ -24,13 +24,22 @@ - #include "spu.h" - #include "thread.h" - #include "tools.h" -+#ifdef USE_ROTOR -+#include -+#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 @@ - ///< 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 @@ - 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 @@ - 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 @@ - 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 - -@@ -496,6 +553,9 @@ - cTsToPes tsToPesVideo; - cTsToPes tsToPesAudio; - cTsToPes tsToPesSubtitle; -+#ifdef USE_TTXTSUBS -+ cTsToPes tsToPesTeletext; -+#endif /* TTXTSUBS */ - bool isPlayingVideo; - protected: - virtual bool CanReplay(void) const; -diff -Naur vdr-1.7.10/dvbdevice.c vdr-1.7.10b/dvbdevice.c ---- vdr-1.7.10/dvbdevice.c 2009-06-06 13:17:20.000000000 +0200 -+++ vdr-1.7.10b/dvbdevice.c 2009-12-30 11:33:26.000000000 +0100 -@@ -71,6 +71,9 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - } - } - diseqcCommands = diseqc->Commands(); -+#ifdef USE_DVBSETUP -+ isyslog("Sent DISEQC command: %s", diseqcCommands); -+#endif /* DVBSETUP */ - } - frequency -= diseqc->Lof(); - } -@@ -303,6 +331,18 @@ - 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 @@ - 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 @@ - - 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; -@@ -796,6 +847,13 @@ - - 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; -@@ -901,14 +959,43 @@ - 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())) -@@ -920,10 +1007,31 @@ - - 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)) { -@@ -1040,6 +1148,13 @@ - 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 -Naur vdr-1.7.10/dvbdevice.h vdr-1.7.10b/dvbdevice.h ---- vdr-1.7.10/dvbdevice.h 2009-10-25 14:58:20.000000000 +0100 -+++ vdr-1.7.10b/dvbdevice.h 2009-12-30 11:33:26.000000000 +0100 -@@ -75,6 +75,9 @@ - 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 -Naur vdr-1.7.10/dvbosd.c vdr-1.7.10b/dvbosd.c ---- vdr-1.7.10/dvbosd.c 2007-09-16 10:55:54.000000000 +0200 -+++ vdr-1.7.10b/dvbosd.c 2009-12-30 11:33:26.000000000 +0100 -@@ -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 @@ - } - 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 @@ - 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 @@ - 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 @@ - 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 -Naur vdr-1.7.10/dvbplayer.c vdr-1.7.10b/dvbplayer.c ---- vdr-1.7.10/dvbplayer.c 2009-05-31 16:12:42.000000000 +0200 -+++ vdr-1.7.10b/dvbplayer.c 2009-12-30 11:33:26.000000000 +0100 -@@ -204,6 +204,9 @@ - cNonBlockingFileReader *nonBlockingFileReader; - cRingBufferFrame *ringBuffer; - cPtsIndex ptsIndex; -+#ifdef USE_JUMPPLAY -+ cMarksReload marks; -+#endif /* JUMPPLAY */ - cFileName *fileName; - cIndexFile *index; - cUnbufferedFile *replayFile; -@@ -249,7 +252,11 @@ - 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 @@ - 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) <= int(round(RESUMEBACKUP * framesPerSecond))) -+ Index = 0; -+#endif /* JUMPPLAY */ - Index -= int(round(RESUMEBACKUP * framesPerSecond)); - if (Index > 0) - Index = index->GetNextIFrame(Index, false); -@@ -383,11 +395,29 @@ - { - 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, framesPerSecond)); -+ readIndex = Index; -+ } -+ } -+ -+ bool LastMarkPause = false; -+#endif /* JUMPPLAY */ -+ - nonBlockingFileReader = new cNonBlockingFileReader; - int Length = 0; - bool Sleep = false; -@@ -410,7 +440,11 @@ - - // 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))) { -@@ -451,6 +485,42 @@ - readIndex++; - else - eof = true; -+#ifdef USE_JUMPPLAY -+ if (Setup.PlayJump || Setup.PauseLastMark) { -+ // check for end mark - jump to next mark or pause -+ readIndex++; -+ 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, framesPerSecond)); -+ 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() - int(round(MAXSTUCKATEOF * framesPerSecond)), 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, framesPerSecond)); -+ readIndex = Index; -+ cutIn = true; -+ } -+ } -+ readIndex--; -+ } -+ // for detecting growing length of live-recordings -+ if (index->Get(readIndex + 1, &FileNumber, &FileOffset, &readIndependent) && readIndependent) -+ total = index->Last(); -+#endif /* JUMPPLAY */ - } - else // allows replay even if the index file is missing - Length = MAXFRAMESIZE; -@@ -491,6 +561,15 @@ - // Store the frame in the buffer: - - if (readFrame) { -+#ifdef USE_JUMPPLAY -+ if (cutIn) { -+ if (isPesRecording) -+ cRemux::SetBrokenLink(readFrame->Data(), readFrame->Count()); -+ else -+ TsSetTeiOnBrokenPackets(readFrame->Data(), readFrame->Count()); -+ cutIn = false; -+ } -+#endif /* JUMPPLAY */ - if (ringBuffer->Put(readFrame)) - readFrame = NULL; - else -@@ -550,8 +629,18 @@ - p = NULL; - } - } -+#ifdef USE_JUMPPLAY -+ else { -+ if (LastMarkPause) { -+ LastMarkPause = false; -+ playMode = pmPause; -+ } -+ Sleep = true; -+ } -+#else - else - Sleep = true; -+#endif /* JUMPPLAY */ - - // Handle hitting begin/end of recording: - -diff -Naur vdr-1.7.10/eit.c vdr-1.7.10b/eit.c ---- vdr-1.7.10/eit.c 2009-06-21 15:46:20.000000000 +0200 -+++ vdr-1.7.10b/eit.c 2009-12-30 11:33:26.000000000 +0100 -@@ -19,13 +19,40 @@ - - #define VALID_TIME (31536000 * 2) // two years - -+#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) - { -@@ -37,6 +64,14 @@ - 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; -@@ -82,8 +117,74 @@ - // 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. -@@ -108,7 +209,11 @@ - 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) -@@ -154,8 +259,46 @@ - } - 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; -@@ -266,6 +409,62 @@ - 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) -@@ -304,10 +503,26 @@ - 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 -Naur vdr-1.7.10/eitscan.c vdr-1.7.10b/eitscan.c ---- vdr-1.7.10/eitscan.c 2006-01-07 15:10:17.000000000 +0100 -+++ vdr-1.7.10b/eitscan.c 2009-12-30 11:33:26.000000000 +0100 -@@ -151,9 +151,17 @@ - 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 -Naur vdr-1.7.10/epg.c vdr-1.7.10b/epg.c ---- vdr-1.7.10/epg.c 2008-05-01 16:53:55.000000000 +0200 -+++ vdr-1.7.10b/epg.c 2009-12-30 11:33:26.000000000 +0100 -@@ -114,6 +114,11 @@ - 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 @@ - 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 @@ - 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 @@ - 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 -Naur vdr-1.7.10/epg.h vdr-1.7.10b/epg.h ---- vdr-1.7.10/epg.h 2006-10-07 15:47:19.000000000 +0200 -+++ vdr-1.7.10b/epg.h 2009-12-30 11:33:26.000000000 +0100 -@@ -50,6 +50,22 @@ - - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 -Naur vdr-1.7.10/HISTORY-liemikuutio vdr-1.7.10b/HISTORY-liemikuutio ---- vdr-1.7.10/HISTORY-liemikuutio 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/HISTORY-liemikuutio 2009-12-30 11:33:26.000000000 +0100 -@@ -0,0 +1,132 @@ -+----------------------------------- -+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. -+ -+2009-02-27: Version 1.24 -+ -+- Fixed compilation under gcc-4.4. -+ -+2009-04-05: Version 1.25 -+ -+- Fixed the length detection of recordings (Thanks to Thomas G?nther). -+ -+2009-04-17: Version 1.26 -+ -+- Fixed the length detection of audio recordings (Thanks to Thomas G?nther). -+ -+2009-04-26: Version 1.27 -+ -+- Fixed the length detection of empty recordings (Thanks to Thomas G?nther). -diff -Naur vdr-1.7.10/iconpatch.c vdr-1.7.10b/iconpatch.c ---- vdr-1.7.10/iconpatch.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/iconpatch.c 2009-12-30 11:33:26.000000000 +0100 -@@ -0,0 +1,31 @@ -+#ifdef USE_WAREAGLEICON -+ -+#include "iconpatch.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+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 -Naur vdr-1.7.10/iconpatch.h vdr-1.7.10b/iconpatch.h ---- vdr-1.7.10/iconpatch.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/iconpatch.h 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -Naur vdr-1.7.10/keys.h vdr-1.7.10b/keys.h ---- vdr-1.7.10/keys.h 2007-08-26 14:34:50.000000000 +0200 -+++ vdr-1.7.10b/keys.h 2009-12-30 11:33:26.000000000 +0100 -@@ -71,6 +71,10 @@ - #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 -Naur vdr-1.7.10/lirc.c vdr-1.7.10b/lirc.c ---- vdr-1.7.10/lirc.c 2006-05-28 10:48:13.000000000 +0200 -+++ vdr-1.7.10b/lirc.c 2009-12-30 11:33:26.000000000 +0100 -@@ -12,6 +12,9 @@ - #include "lirc.h" - #include - #include -+#ifdef USE_LIRCSETTINGS -+#include "config.h" -+#endif /* LIRCSETTINGS */ - - #define REPEATDELAY 350 // ms - #define REPEATFREQ 100 // ms -@@ -94,7 +97,11 @@ - 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 @@ - 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 -Naur vdr-1.7.10/mainmenuitemsprovider.h vdr-1.7.10b/mainmenuitemsprovider.h ---- vdr-1.7.10/mainmenuitemsprovider.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/mainmenuitemsprovider.h 2009-12-30 11:33:26.000000000 +0100 -@@ -0,0 +1,62 @@ -+#ifdef USE_MENUORG -+/* -+ * vdr-menuorg - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2007 - 2008 Tobias Grimm -+ * -+ * 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 -+ -+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 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 -Naur vdr-1.7.10/Make.config.template vdr-1.7.10b/Make.config.template ---- vdr-1.7.10/Make.config.template 2009-01-18 11:46:13.000000000 +0100 -+++ vdr-1.7.10b/Make.config.template 2009-12-30 11:33:26.000000000 +0100 -@@ -42,8 +42,247 @@ - ## 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 -+#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 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 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 -Naur vdr-1.7.10/Makefile vdr-1.7.10b/Makefile ---- vdr-1.7.10/Makefile 2009-10-18 15:59:25.000000000 +0200 -+++ vdr-1.7.10b/Makefile 2009-12-30 11:33:26.000000000 +0100 -@@ -43,6 +43,18 @@ - 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 -+ -+ifdef TTXTSUBS -+OBJS += vdrttxtsubshooks.o -+endif -+ - ifndef NO_KBD - DEFINES += -DREMOTE_KBD - endif -@@ -72,6 +84,14 @@ - 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 +157,26 @@ - - # 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 +191,7 @@ - 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 -Naur vdr-1.7.10/MANUAL vdr-1.7.10b/MANUAL ---- vdr-1.7.10/MANUAL 2009-11-22 15:28:15.000000000 +0100 -+++ vdr-1.7.10b/MANUAL 2009-12-30 11:33:26.000000000 +0100 -@@ -822,6 +822,30 @@ - 0 resulting in a file named 'resume', and any other - value resulting in 'resume.n'. - -+ 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 -Naur vdr-1.7.10/menu.c vdr-1.7.10b/menu.c ---- vdr-1.7.10/menu.c 2009-06-21 11:56:06.000000000 +0200 -+++ vdr-1.7.10b/menu.c 2009-12-30 11:33:26.000000000 +0100 -@@ -8,12 +8,18 @@ - */ - - #include "menu.h" -+#ifdef USE_WAREAGLEICON -+#include "iconpatch.h" -+#endif /* WAREAGLEICON */ - #include - #include - #include - #include - #include - #include -+#ifdef USE_LIEMIEXT -+#include -+#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 @@ - 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 @@ - - // 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - cMenuTimerItem::cMenuTimerItem(cTimer *Timer) - { - timer = Timer; -+#ifdef USE_TIMERINFO -+ diskStatus = ' '; -+#endif /* TIMERINFO */ - Set(); - } - -@@ -751,8 +870,56 @@ - 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 @@ - 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 @@ - 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 @@ - SetCurrent(First()); - SetHelpKeys(); - Timers.IncBeingEdited(); -+#ifdef USE_TIMERINFO -+ actualiseDiskStatus = true; -+#endif /* TIMERINFO */ - } - - cMenuTimers::~cMenuTimers() -@@ -832,7 +1075,11 @@ - 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 @@ - 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 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 @@ - 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 @@ - { - cOsdMenu::Display(); - DisplayMenu()->SetEvent(event); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdSetEvent(event); -+#endif /* GRAPHTFT */ - if (event->Description()) - cStatus::MsgOsdTextItem(event->Description()); - } -@@ -987,7 +1370,12 @@ - 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 @@ - - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - - // --- cMenuCommands --------------------------------------------------------- - -+#ifndef USE_TIMERCMD - class cMenuCommands : public cOsdMenu { - private: - cCommands *commands; -@@ -1496,7 +1993,11 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - { - 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 @@ - 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,196 @@ - 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; -+ -+ const char* pname = strrchr(recording->Name(), '~'); -+ if (pname) { -+ Utf8Strn0Cpy(name, pname + 1, sizeof(name)); -+ Utf8Strn0Cpy(path, recording->Name(), sizeof(path)); -+ char *ppath = strrchr(path, '~'); -+ if (ppath) -+ ppath[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)); -+ -+ int recLen = cIndexFile::Length(recording->FileName(), recording->IsPesRecording()); -+ if (recLen >= 0) -+ Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Length"), *IndexToHMSF(recLen, false, recording->FramesPerSecond())), osUnknown, false)); -+ else -+ recLen = 0; -+ -+ int dirSize = DirSizeMB(recording->FileName()); -+ double seconds = recLen / recording->FramesPerSecond(); -+ cString bitRate = seconds ? cString::sprintf(" (%.2f MBit/s)", 8.0 * dirSize / seconds) : 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 +2624,12 @@ - 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 +2679,43 @@ - { - 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 +2816,34 @@ - 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 +2852,26 @@ - 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; -@@ -2142,6 +2921,9 @@ - class cMenuSetupOSD : public cMenuSetupBase { - private: - const char *useSmallFontTexts[3]; -+#ifdef USE_LIEMIEXT -+ const char *mainMenuTitle[MAXMAINMENUTITLE]; -+#endif /* LIEMIEXT */ - int osdLanguageIndex; - int numSkins; - int originalSkinIndex; -@@ -2157,6 +2939,9 @@ - cMenuSetupOSD(void); - virtual ~cMenuSetupOSD(); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupOsd"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupOSD::cMenuSetupOSD(void) -@@ -2192,12 +2977,21 @@ - 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 cMenuEditPrcItem( tr("Setup.OSD$Left (%)"), &data.OSDLeftP, 0.0, 0.5)); - Add(new cMenuEditPrcItem( tr("Setup.OSD$Top (%)"), &data.OSDTopP, 0.0, 0.5)); - Add(new cMenuEditPrcItem( tr("Setup.OSD$Width (%)"), &data.OSDWidthP, 0.5, 1.0)); -@@ -2219,6 +3013,24 @@ - 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(); - } -@@ -2259,6 +3071,12 @@ - - 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 (ModifiedAppearance) { -@@ -2283,6 +3101,25 @@ - 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; - } - -@@ -2290,12 +3127,18 @@ - - 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) -@@ -2312,11 +3155,19 @@ - { - 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)); -@@ -2325,6 +3176,15 @@ - 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(); -@@ -2381,6 +3241,10 @@ - - class cMenuSetupDVB : public cMenuSetupBase { - private: -+#ifdef USE_DVBSETUP -+ const char *ChannelBlockers[7]; -+ const char *ChannelBlockerModes[4]; -+#endif /* DVBSETUP */ - int originalNumAudioLanguages; - int numAudioLanguages; - int originalNumSubtitleLanguages; -@@ -2391,6 +3255,9 @@ - public: - cMenuSetupDVB(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupDvb"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupDVB::cMenuSetupDVB(void) -@@ -2419,6 +3286,21 @@ - { - 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())); -@@ -2439,6 +3321,11 @@ - 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(); -@@ -2520,6 +3407,9 @@ - public: - cMenuSetupLNB(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupLnb"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupLNB::cMenuSetupLNB(void) -@@ -2534,6 +3424,23 @@ - - 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)); -@@ -2550,6 +3457,10 @@ - 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; -@@ -2600,6 +3511,9 @@ - public: - cMenuSetupCAM(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupCam"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupCAM::cMenuSetupCAM(void) -@@ -2674,13 +3588,72 @@ - - class cMenuSetupRecord : public cMenuSetupBase { - private: -+#ifdef USE_SORTRECORDS -+ const char *RecordingsSortModeTexts[MAXSORTMODES]; -+#endif /* SORTRECORDS */ -+#ifdef USE_DELTIMESHIFTREC -+ const char *DelTimeshiftRecValues[3]; -+#endif /* DELTIMESHIFTREC */ - const char *pauseKeyHandlingTexts[3]; - 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 */ - pauseKeyHandlingTexts[0] = tr("do not pause live video"); - pauseKeyHandlingTexts[1] = tr("confirm pause live video"); - pauseKeyHandlingTexts[2] = tr("pause live video"); -@@ -2693,14 +3666,61 @@ - Add(new cMenuEditStraItem(tr("Setup.Recording$Pause key handling"), &data.PauseKeyHandling, 3, pauseKeyHandlingTexts)); - 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 ------------------------------------------------------ -@@ -2718,6 +3738,31 @@ - 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) -@@ -2730,13 +3775,48 @@ - // --- 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)); -@@ -2744,7 +3824,21 @@ - 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 -------------------------------------------------- -@@ -2769,6 +3863,9 @@ - public: - cMenuSetupPlugins(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetupPlugins"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetupPlugins::cMenuSetupPlugins(void) -@@ -2818,6 +3915,9 @@ - public: - cMenuSetup(void); - virtual eOSState ProcessKey(eKeys Key); -+#ifdef USE_GRAPHTFT -+ virtual const char* MenuKind() { return "MenuSetup"; } -+#endif /* GRAPHTFT */ - }; - - cMenuSetup::cMenuSetup(void) -@@ -2907,24 +4007,90 @@ - cMenuMain::cMenuMain(eOSState State) - :cOsdMenu("") - { -+#ifdef USE_SETUP -+ // Load Menu Configuration -+ cString menuXML = cString::sprintf("%s/setup/vdr-menu.%s.xml", cPlugin::ConfigDirectory(), Setup.OSDLanguage); -+ if (access(menuXML, 04) == -1) -+ menuXML = cString::sprintf("%s/setup/vdr-menu.xml", cPlugin::ConfigDirectory()); -+ subMenu.LoadXml(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) -@@ -2934,38 +4100,159 @@ - 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) { -+ cString itemSetup = cString::sprintf("%s%s", tr("Setup"), *subMenu.GetMenuSuffix()); -+ Add(new cOsdItem(hk(itemSetup), osSetup)); -+ } -+ else if (strcmp(item, "Commands") == 0 && Commands.Count() > 0) { -+ cString itemCommands = cString::sprintf("%s%s", tr("Commands"), *subMenu.GetMenuSuffix()); -+ Add(new cOsdItem(hk(itemCommands), osCommands)); -+ } -+ } -+ } -+ if (current >=0 && currentMainMenuEntry(); - 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(); -@@ -2974,13 +4261,40 @@ - 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) { -@@ -2988,6 +4302,9 @@ - // 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()); -@@ -3002,6 +4319,9 @@ - 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; - } -@@ -3022,6 +4342,9 @@ - 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; -@@ -3029,6 +4352,12 @@ - result = true; - } - -+#ifdef USE_SETUP -+ // adjust nrDynamicMenuEntries -+ if (fMenu != NULL) -+ nrDynamicMenuEntries = fMenu->Index(); -+#endif /* SETUP */ -+ - return result; - } - -@@ -3039,13 +4368,69 @@ - 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) { -@@ -3064,6 +4449,9 @@ - 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()) -@@ -3075,9 +4463,60 @@ - } - } - } -+#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) -@@ -3094,9 +4533,67 @@ - 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) { -@@ -3242,7 +4739,14 @@ - 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; - } - } -@@ -3300,6 +4804,13 @@ - 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: -@@ -3459,6 +4970,17 @@ - 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: -@@ -3708,6 +5230,10 @@ - - 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; -@@ -3752,11 +5278,26 @@ - 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(); -+#ifdef USE_TTXTSUBS -+ int TPid[2] = { ch->Tpid(), 0 }; -+ recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids(), TPid); -+#else - recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids()); -+#endif /* TTXTSUBS */ - if (device->AttachReceiver(recorder)) { - Recording.WriteInfo(); - cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true); -@@ -3814,11 +5355,25 @@ - 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 */ - } - } - -@@ -3865,6 +5420,19 @@ - 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(); -@@ -3874,6 +5442,9 @@ - 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)); - } - } -@@ -4004,12 +5575,22 @@ - - // --- 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; -@@ -4017,23 +5598,96 @@ - 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); -@@ -4128,6 +5782,9 @@ - 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) { -@@ -4249,8 +5906,15 @@ - 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(); - } -@@ -4263,8 +5927,22 @@ - 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, FramesPerSecond())) { -+ Goto(m->position); -+ Play(); -+ } -+ else { -+ Goto(m->position, true); -+ displayFrames = true; -+ } -+#else - Goto(m->position, true); - displayFrames = true; -+#endif /* JUMPPLAY */ - } - } - } -@@ -4293,11 +5971,43 @@ - } - } - -+#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)) -@@ -4319,7 +6029,11 @@ - 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())); -@@ -4341,6 +6055,9 @@ - { - if (!Active()) - return osEnd; -+#ifdef USE_JUMPPLAY -+ marks.Reload(); -+#endif /* JUMPPLAY */ - if (visible) { - if (timeoutShow && time(NULL) > timeoutShow) { - Hide(); -@@ -4358,7 +6075,32 @@ - 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: -@@ -4376,25 +6118,82 @@ - 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: -@@ -4414,7 +6213,16 @@ - 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 -Naur vdr-1.7.10/menu.h vdr-1.7.10b/menu.h ---- vdr-1.7.10/menu.h 2008-02-10 17:01:53.000000000 +0100 -+++ vdr-1.7.10b/menu.h 2009-12-30 11:33:26.000000000 +0100 -@@ -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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 -Naur vdr-1.7.10/menuitems.c vdr-1.7.10b/menuitems.c ---- vdr-1.7.10/menuitems.c 2009-05-03 15:37:55.000000000 +0200 -+++ vdr-1.7.10b/menuitems.c 2009-12-30 11:33:26.000000000 +0100 -@@ -33,9 +33,20 @@ - 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); - } -@@ -127,7 +138,11 @@ - { - char buf[16]; - snprintf(buf, sizeof(buf), "%s", *value ? trueString : falseString); -+#ifdef USE_VALIDINPUT -+ SetValue(buf, *value, !*value); -+#else - SetValue(buf); -+#endif /* VALIDINPUT */ - } - - // --- cMenuEditBitItem ------------------------------------------------------ -@@ -685,6 +700,170 @@ - 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) -@@ -696,7 +875,11 @@ - - void cMenuEditStraItem::Set(void) - { -+#ifdef USE_VALIDINPUT -+ SetValue(strings[*value], (*value > min), (*value < max)); -+#else - SetValue(strings[*value]); -+#endif /* VALIDINPUT */ - } - - // --- cMenuEditChanItem ----------------------------------------------------- -diff -Naur vdr-1.7.10/menuitems.h vdr-1.7.10b/menuitems.h ---- vdr-1.7.10/menuitems.h 2009-05-03 14:50:34.000000000 +0200 -+++ vdr-1.7.10b/menuitems.h 2009-12-30 11:33:26.000000000 +0100 -@@ -21,7 +21,11 @@ - 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 { -@@ -90,26 +94,46 @@ - - 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; } -@@ -119,6 +143,21 @@ - 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; -@@ -197,6 +236,9 @@ - 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 -Naur vdr-1.7.10/menuorgpatch.h vdr-1.7.10b/menuorgpatch.h ---- vdr-1.7.10/menuorgpatch.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/menuorgpatch.h 2009-12-30 11:33:26.000000000 +0100 -@@ -0,0 +1,102 @@ -+#ifdef USE_MENUORG -+/* -+ * vdr-menuorg - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2007 - 2008 Tobias Grimm -+ * -+ * 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 -Naur vdr-1.7.10/osdbase.c vdr-1.7.10b/osdbase.c ---- vdr-1.7.10/osdbase.c 2009-06-01 13:54:50.000000000 +0200 -+++ vdr-1.7.10b/osdbase.c 2009-12-30 11:33:26.000000000 +0100 -@@ -22,6 +22,9 @@ - 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 @@ - 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 @@ - { - isMenu = true; - digit = 0; -+#ifdef USE_LIEMIEXT -+ key_nr = -1; -+#endif /* LIEMIEXT */ - hasHotkeys = false; - title = NULL; - SetTitle(Title); -@@ -97,6 +118,9 @@ - free(status); - displayMenu->Clear(); - cStatus::MsgOsdClear(); -+#ifdef USE_GRAPHTFT -+ cStatus::MsgOsdMenuDestroy(); -+#endif /* GRAPHTFT */ - if (!--displayMenuCount) - DELETENULL(displayMenu); - } -@@ -119,7 +143,11 @@ - 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 @@ - 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); -@@ -297,6 +331,9 @@ - - void cOsdMenu::CursorUp(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int tmpCurrent = current; - int lastOnScreen = first + displayMenuItems - 1; - int last = Count() - 1; -@@ -335,6 +372,9 @@ - - void cOsdMenu::CursorDown(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int tmpCurrent = current; - int lastOnScreen = first + displayMenuItems - 1; - int last = Count() - 1; -@@ -375,6 +415,9 @@ - - void cOsdMenu::PageUp(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int oldCurrent = current; - int oldFirst = first; - current -= displayMenuItems; -@@ -409,6 +452,9 @@ - - void cOsdMenu::PageDown(void) - { -+#ifdef USE_OSDMAXITEMS -+ displayMenuItems = displayMenu->MaxItems(); -+#endif /* OSDMAXITEMS */ - int oldCurrent = current; - int oldFirst = first; - current += displayMenuItems; -@@ -449,6 +495,64 @@ - } - } - -+#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)) { -@@ -463,6 +567,7 @@ - } - } - } -+#endif /* LIEMIEXT */ - return osContinue; - } - -@@ -501,8 +606,13 @@ - } - } - 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 -Naur vdr-1.7.10/osdbase.h vdr-1.7.10b/osdbase.h ---- vdr-1.7.10/osdbase.h 2007-11-03 15:50:52.000000000 +0100 -+++ vdr-1.7.10b/osdbase.h 2009-12-30 11:33:26.000000000 +0100 -@@ -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 @@ - 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 @@ - 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 @@ - 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 -Naur vdr-1.7.10/osd.c vdr-1.7.10b/osd.c ---- vdr-1.7.10/osd.c 2009-05-09 12:42:35.000000000 +0200 -+++ vdr-1.7.10b/osd.c 2009-12-30 11:33:26.000000000 +0100 -@@ -725,6 +725,9 @@ - int cOsd::osdWidth = 0; - int cOsd::osdHeight = 0; - cVector cOsd::Osds; -+#ifdef USE_PINPLUGIN -+bool cOsd::pinValid = false; -+#endif /* PINPLUGIN */ - - cOsd::cOsd(int Left, int Top, uint Level) - { -@@ -735,6 +738,9 @@ - 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 -Naur vdr-1.7.10/osd.h vdr-1.7.10b/osd.h ---- vdr-1.7.10/osd.h 2009-05-08 15:41:03.000000000 +0200 -+++ vdr-1.7.10b/osd.h 2009-12-30 11:33:26.000000000 +0100 -@@ -401,6 +401,12 @@ - ///< 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 -Naur vdr-1.7.10/pat.c vdr-1.7.10b/pat.c ---- vdr-1.7.10/pat.c 2009-08-16 17:01:03.000000000 +0200 -+++ vdr-1.7.10b/pat.c 2009-12-30 11:33:26.000000000 +0100 -@@ -13,6 +13,9 @@ - #include "libsi/section.h" - #include "libsi/descriptor.h" - #include "thread.h" -+#ifdef USE_TTXTSUBS -+#include "vdrttxtsubshooks.h" -+#endif /* TTXTSUBS */ - - #define PMT_SCAN_TIMEOUT 10 // seconds - -@@ -341,6 +344,11 @@ - char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" }; - char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" }; - int Tpid = 0; -+#ifdef USE_TTXTSUBS -+ char TLangs[MAXTPAGES][MAXLANGCODE2] = { "" }; -+ int TPages[MAXTPAGES + 1] = { 0 }; -+ int NumTPages = 0; -+#endif /* TTXTSUBS */ - int NumApids = 0; - int NumDpids = 0; - int NumSpids = 0; -@@ -422,8 +430,24 @@ - NumSpids++; - } - break; -+#ifdef USE_TTXTSUBS -+ case SI::TeletextDescriptorTag: { -+ Tpid = esPid; -+ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; -+ SI::TeletextDescriptor::Teletext ttxt; -+ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { -+ if ((NumTPages < MAXTPAGES) && ttxt.languageCode[0] && ((ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05))) { -+ char *s = TLangs[NumTPages]; -+ strn0cpy(s, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); -+ TPages[NumTPages] = (ttxt.getTeletextPageNumber() & 0xff) | ((ttxt.getTeletextMagazineNumber() & 0xff) << 8) | ((ttxt.getTeletextType() & 0xff) << 16); -+ NumTPages++; -+ } -+ } -+ } -+#else - case SI::TeletextDescriptorTag: - Tpid = esPid; -+#endif /* TTXTSUBS */ - break; - case SI::ISO639LanguageDescriptorTag: { - SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; -@@ -452,6 +476,18 @@ - } - if (Setup.UpdateChannels >= 2) { - Channel->SetPids(Vpid, Ppid, Vtype, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid); -+#ifdef USE_TTXTSUBS -+ if (NumTPages < MAXTPAGES) { -+ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel); -+ if (manualPageNumber) { -+ char *s = TLangs[NumTPages]; -+ strn0cpy(s, "man", MAXLANGCODE1); -+ TPages[NumTPages] = manualPageNumber; -+ NumTPages++; -+ } -+ } -+ Channel->SetTPidData(TLangs, TPages); -+#endif /* TTXTSUBS */ - Channel->SetCaIds(CaDescriptors->CaIds()); - Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); - } -diff -Naur vdr-1.7.10/plugin.c vdr-1.7.10b/plugin.c ---- vdr-1.7.10/plugin.c 2009-04-05 12:16:48.000000000 +0200 -+++ vdr-1.7.10b/plugin.c 2009-12-30 11:33:26.000000000 +0100 -@@ -317,6 +317,14 @@ - 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 @@ - { - 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 -Naur vdr-1.7.10/po/de_DE.po vdr-1.7.10b/po/de_DE.po ---- vdr-1.7.10/po/de_DE.po 2009-11-22 12:30:27.000000000 +0100 -+++ vdr-1.7.10b/po/de_DE.po 2009-12-30 11:33:26.000000000 +0100 -@@ -806,6 +806,30 @@ - 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" - -@@ -1028,3 +1052,306 @@ - #, 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.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!" -diff -Naur vdr-1.7.10/po/et_EE.po vdr-1.7.10b/po/et_EE.po ---- vdr-1.7.10/po/et_EE.po 2009-11-22 12:28:38.000000000 +0100 -+++ vdr-1.7.10b/po/et_EE.po 2009-12-30 11:34:37.000000000 +0100 -@@ -1028,3 +1028,33 @@ - #, c-format - msgid "VDR will shut down in %s minutes" - msgstr "VDR lülitub välja %s minuti pärast" -+ -+msgid "Rename recording" -+msgstr "Ümbernimetamine" -+ -+msgid "Setup.OSD$Main menu command position" -+msgstr "Käsu asukoht peamenüüs" -+ -+msgid "Setup.EPG$Show progress bar" -+msgstr "Edenemisriba" -+ -+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 "Rename$Up" -+msgstr "Üles" -+ -+msgid "Rename$Down" -+msgstr "Alla" -+ -+msgid "Rename$Previous" -+msgstr "Eelmine" -+ -+msgid "Rename$Next" -+msgstr "Järgmine" -diff -Naur vdr-1.7.10/po/fi_FI.po vdr-1.7.10b/po/fi_FI.po ---- vdr-1.7.10/po/fi_FI.po 2009-11-22 12:28:39.000000000 +0100 -+++ vdr-1.7.10b/po/fi_FI.po 2009-12-30 11:34:37.000000000 +0100 -@@ -42,6 +42,253 @@ - 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ä" - -@@ -1031,3 +1278,252 @@ - #, 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.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" -diff -Naur vdr-1.7.10/po/fr_FR.po vdr-1.7.10b/po/fr_FR.po ---- vdr-1.7.10/po/fr_FR.po 2009-11-22 12:28:39.000000000 +0100 -+++ vdr-1.7.10b/po/fr_FR.po 2009-12-30 11:34:37.000000000 +0100 -@@ -8,6 +8,7 @@ - # Pierre Briec , 2006 - # Bruno Roussel , 2007 - # Michael Nival , 2007 -+# Patrice Staudt , 2007, 2008 - # - msgid "" - msgstr "" -@@ -1034,3 +1035,249 @@ - #, 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.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!" -diff -Naur vdr-1.7.10/po/it_IT.po vdr-1.7.10b/po/it_IT.po ---- vdr-1.7.10/po/it_IT.po 2009-11-22 12:28:39.000000000 +0100 -+++ vdr-1.7.10b/po/it_IT.po 2009-12-30 11:38:20.000000000 +0100 -@@ -37,6 +37,9 @@ - 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 @@ - 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 "Trasmissione dal vivo" -+ -+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" - -@@ -325,6 +575,9 @@ - msgid "Rolloff" - msgstr "Rolloff" - -+msgid "Parameters" -+msgstr "Parametri" -+ - msgid "Channel settings are not unique!" - msgstr "Parametri canale non univoci!" - -@@ -376,9 +629,15 @@ - 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 +656,9 @@ - msgid "Timer still recording - really delete?" - msgstr "Timer in registrazione - eliminare?" - -+msgid "Timer commands" -+msgstr "Comandi timer" -+ - msgid "Event" - msgstr "Evento" - -@@ -457,6 +719,24 @@ - 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 "Recordings" - msgstr "Registrazioni" - -@@ -469,6 +749,9 @@ - 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 +761,21 @@ - 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 +785,18 @@ - 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 +809,9 @@ - msgid "Setup.OSD$Theme" - msgstr "Tema colori" - -+msgid "Setup.OSD$WarEagle icons" -+msgstr "Icone WarEagle" -+ - msgid "Setup.OSD$Left (%)" - msgstr "Sinistra (%)" - -@@ -568,12 +881,30 @@ - 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 +914,9 @@ - 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 +931,27 @@ - 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 +982,27 @@ - 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 +1042,25 @@ - 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 "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" - -@@ -720,6 +1112,9 @@ - msgid "pause live video" - msgstr "pausa video dal vivo" - -+msgid "request" -+msgstr "chiedi" -+ - msgid "Recording" - msgstr "Registrazione" - -@@ -747,9 +1142,29 @@ - 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" - -@@ -768,9 +1183,39 @@ - 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" - -@@ -783,6 +1228,63 @@ - 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" - -@@ -810,9 +1312,27 @@ - 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 "Plugins" - msgstr "Plugins" - -@@ -885,10 +1405,22 @@ - 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!" - -@@ -919,6 +1451,18 @@ - 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" - -@@ -937,6 +1481,30 @@ - msgid "Index file regeneration complete" - msgstr "" - -+#, 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!" - -diff -Naur vdr-1.7.10/po/nl_NL.po vdr-1.7.10b/po/nl_NL.po ---- vdr-1.7.10/po/nl_NL.po 2009-11-22 12:28:39.000000000 +0100 -+++ vdr-1.7.10b/po/nl_NL.po 2009-12-30 11:33:26.000000000 +0100 -@@ -1032,3 +1032,240 @@ - #, 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.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!" -diff -Naur vdr-1.7.10/po/ru_RU.po vdr-1.7.10b/po/ru_RU.po ---- vdr-1.7.10/po/ru_RU.po 2009-11-22 12:28:39.000000000 +0100 -+++ vdr-1.7.10b/po/ru_RU.po 2009-12-30 11:34:37.000000000 +0100 -@@ -1029,3 +1029,249 @@ - #, 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.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!" -diff -Naur vdr-1.7.10/README.cmdsubmenu vdr-1.7.10b/README.cmdsubmenu ---- vdr-1.7.10/README.cmdsubmenu 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/README.cmdsubmenu 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -+ - Added Define CMD_SUBMENUS in Makefile -+ -+ 2004-05-28: Version 0.3 - Thomas G?nther -+ - 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 -+ - 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 -+ - 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 -+ - 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 -+ - Fixed build with G++ 4.1 (extra qualification) -+ http://toms-cafe.de/vdr/download/vdr-cmdsubmenu-0.7-1.4.0.diff -diff -Naur vdr-1.7.10/README-HLCUTTER vdr-1.7.10b/README-HLCUTTER ---- vdr-1.7.10/README-HLCUTTER 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/README-HLCUTTER 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -Naur vdr-1.7.10/README.jumpplay vdr-1.7.10b/README.jumpplay ---- vdr-1.7.10/README.jumpplay 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/README.jumpplay 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -+ Jump&Play -+ -+ 2003-12-06: Version 0.0 - Torsten Kunkel -+ 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 -+ 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 -+ 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 -+ Jump&Play: -+ - fixed display frames -+ Play&Jump: -+ - fixed end of playing at last mark -+ -+ 2004-07-11: Version 0.4 - Thomas G?nther -+ 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 -+ 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 -+ Adapted noad extensions (from the Noad ) 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 -+ 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 -+ 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 -+ 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 -+ Play&Jump: -+ - set resume position to 0 if replay stops at the first mark -+ Added French language texts (thanks to Micha?l Nival) -diff -Naur vdr-1.7.10/README.MainMenuHooks vdr-1.7.10b/README.MainMenuHooks ---- vdr-1.7.10/README.MainMenuHooks 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/README.MainMenuHooks 2009-12-30 11:33:26.000000000 +0100 -@@ -0,0 +1,55 @@ -+This is a "patch" for the Video Disk Recorder (VDR). -+ -+* Authors: -+Tobias Grimm -+Martin Prochnow -+Frank Schmirler -+Christian Wieninger -+ -+* 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 -Naur vdr-1.7.10/README.sortrec vdr-1.7.10b/README.sortrec ---- vdr-1.7.10/README.sortrec 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/README.sortrec 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -Naur vdr-1.7.10/README.timer-info vdr-1.7.10b/README.timer-info ---- vdr-1.7.10/README.timer-info 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/README.timer-info 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -+ - 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 -+ - 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 -+ - 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 -+ - Adapted to vdr-1.3.45 -+ http://toms-cafe.de/vdr/download/vdr-timer-info-0.4-1.3.45.diff -diff -Naur vdr-1.7.10/receiver.c vdr-1.7.10b/receiver.c ---- vdr-1.7.10/receiver.c 2007-08-12 13:52:59.000000000 +0200 -+++ vdr-1.7.10b/receiver.c 2009-12-30 11:33:26.000000000 +0100 -@@ -12,7 +12,11 @@ - #include - #include "tools.h" - -+#ifdef USE_TTXTSUBS -+cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3, const int *Pids4) -+#else - cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3) -+#endif /* TTXTSUBS */ - { - device = NULL; - channelID = ChannelID; -@@ -32,6 +36,12 @@ - while (*Pids3 && numPids < MAXRECEIVEPIDS) - pids[numPids++] = *Pids3++; - } -+#ifdef USE_TTXTSUBS -+ if (Pids4) { -+ while (*Pids4 && numPids < MAXRECEIVEPIDS) -+ pids[numPids++] = *Pids4++; -+ } -+#endif /* TTXTSUBS */ - if (numPids >= MAXRECEIVEPIDS) - dsyslog("too many PIDs in cReceiver"); - } -diff -Naur vdr-1.7.10/receiver.h vdr-1.7.10b/receiver.h ---- vdr-1.7.10/receiver.h 2007-01-05 12:00:36.000000000 +0100 -+++ vdr-1.7.10b/receiver.h 2009-12-30 11:33:26.000000000 +0100 -@@ -38,10 +38,15 @@ - ///< will be delivered only ONCE, so the cReceiver must make sure that - ///< it will be able to buffer the data if necessary. - public: -+#ifdef USE_TTXTSUBS -+ cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL, const int *Pids4 = NULL); -+#else - cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL); -+#endif /* TTXTSUBS */ - ///< Creates a new receiver for the channel with the given ChannelID with - ///< the given Priority. Pid is a single PID (typically the video PID), while - ///< Pids1...Pids3 are pointers to zero terminated lists of PIDs. -+ ///< ifdef USE_TTXTSUBS: Pids1...Pids4 are pointers to zero terminated lists of PIDs. - ///< If any of these PIDs are 0, they will be silently ignored. - ///< The total number of non-zero PIDs must not exceed MAXRECEIVEPIDS. - ///< Priority may be any value in the range -99..99. Negative values indicate -diff -Naur vdr-1.7.10/recorder.c vdr-1.7.10b/recorder.c ---- vdr-1.7.10/recorder.c 2009-11-21 16:58:12.000000000 +0100 -+++ vdr-1.7.10b/recorder.c 2009-12-30 11:33:26.000000000 +0100 -@@ -21,8 +21,21 @@ - - // --- cRecorder ------------------------------------------------------------- - -+#ifdef USE_TTXTSUBS -+cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, const int *EPids) -+#ifdef USE_DOLBYINREC -+:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyInRecordings ? DPids : NULL, SPids, EPids) -+#else -+:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, EPids) -+#endif /* DOLBYINREC */ -+#else - 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 */ -+#endif /* TTXTSUBS */ - ,cThread("recording") - ,recordingInfo(FileName) - { -@@ -87,7 +100,11 @@ - 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 -Naur vdr-1.7.10/recorder.h vdr-1.7.10b/recorder.h ---- vdr-1.7.10/recorder.h 2009-01-06 11:44:58.000000000 +0100 -+++ vdr-1.7.10b/recorder.h 2009-12-30 11:33:26.000000000 +0100 -@@ -34,7 +34,11 @@ - virtual void Receive(uchar *Data, int Length); - virtual void Action(void); - public: -+#ifdef USE_TTXTSUBS -+ cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, const int *EPids = NULL); -+#else - cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids); -+#endif /* 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 -Naur vdr-1.7.10/recording.c vdr-1.7.10b/recording.c ---- vdr-1.7.10/recording.c 2009-11-22 12:20:53.000000000 +0100 -+++ vdr-1.7.10b/recording.c 2009-12-30 11:33:26.000000000 +0100 -@@ -8,6 +8,9 @@ - */ - - #include "recording.h" -+#ifdef USE_WAREAGLEICON -+#include "iconpatch.h" -+#endif /* WAREAGLEICON */ - #include - #include - #include -@@ -25,6 +28,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 -+/* libdvdread stuff */ -+#include -+#include -+#include -+#endif /* DVDCHAPJUMP & DVDARCHIVE */ - - #define SUMMARYFALLBACK - -@@ -50,6 +64,9 @@ - #endif - #define INFOFILESUFFIX "/info" - #define MARKSFILESUFFIX "/marks" -+#ifdef USE_DVDARCHIVE /* ??? */ -+#define DVDARCHIVEFILENAME "/dvd.vdr" -+#endif /* DVDARCHIVE */ - - #define MINDISKSPACE 1024 // MB - -@@ -67,6 +84,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); - -@@ -602,9 +626,24 @@ - { - 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; -@@ -639,6 +678,11 @@ - 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(); - } -@@ -649,6 +693,10 @@ - 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(); -@@ -671,12 +719,27 @@ - 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; - const 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); -@@ -765,15 +828,34 @@ - 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; - } - -@@ -793,21 +875,46 @@ - 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 -@@ -822,7 +929,15 @@ - 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 -@@ -840,9 +955,359 @@ - 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 -+ */ -+ { -+ 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; ptitle[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; cplayback_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()) { -@@ -853,7 +1318,14 @@ - 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, -@@ -863,6 +1335,80 @@ - New, - Delimiter, - s)); -+#ifdef USE_LIEMIEXT -+ } -+ else { -+ cString RecLength("---"); -+ if (Setup.ShowRecLength && FileName()) { -+ int length = cIndexFile::Length(FileName(), IsPesRecording()); -+ if (length >= 0) -+ RecLength = cString::sprintf("%d'", length / SecondsToFrames(60, framesPerSecond)); -+ } -+#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); -@@ -891,6 +1437,17 @@ - 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); -@@ -944,10 +1501,20 @@ - // 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 -@@ -965,7 +1532,13 @@ - 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) -@@ -982,8 +1555,15 @@ - } - 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; -@@ -999,6 +1579,54 @@ - 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; -@@ -1011,6 +1639,9 @@ - deleted = Deleted; - lastUpdate = 0; - state = 0; -+#ifdef USE_SORTRECORDS -+ SortOrder = 1; -+#endif /* SORTRECORDS */ - } - - cRecordings::~cRecordings() -@@ -1297,14 +1928,72 @@ - 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; -+ cRecording rec(recDir); -+ if (Load(recDir, rec.FramesPerSecond(), rec.IsPesRecording()) && 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; -+ cRecording rec(recDir); -+ if (Load(recDir, rec.FramesPerSecond(), rec.IsPesRecording())) -+ 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); - } -@@ -1412,8 +2101,11 @@ - // Read data: - else if (ReplayFile) { - int Result = Buffer.Read(ReplayFile, BufferChunks); -- if (Result == 0) // EOF -+ if (Result == 0) { // EOF - ReplayFile = FileName.NextFile(); -+ FileSize = 0; -+ FrameOffset = -1; -+ } - } - // Recording has been processed: - else { -@@ -1746,6 +2438,17 @@ - } - } - -+#ifdef USE_LIEMIEXT -+int cIndexFile::Length(const char *FileName, bool IsPesRecording) -+{ -+ struct stat buf; -+ cString fullname = cString::sprintf("%s%s", FileName, IsPesRecording ? INDEXFILESUFFIX ".vdr" : INDEXFILESUFFIX); -+ if (FileName && *fullname && access(fullname, R_OK) == 0 && stat(fullname, &buf) == 0) -+ return buf.st_size ? (buf.st_size - 1) / sizeof(tIndexTs) + 1 : 0; -+ return -1; -+} -+#endif /* LIEMIEXT */ -+ - // --- cFileName ------------------------------------------------------------- - - #define MAXFILESPERRECORDINGPES 255 -@@ -1775,6 +2478,48 @@ - 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); - } - -@@ -1904,6 +2649,22 @@ - 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); -@@ -1955,3 +2716,113 @@ - 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 -Naur vdr-1.7.10/recording.h vdr-1.7.10b/recording.h ---- vdr-1.7.10/recording.h 2009-11-21 17:12:55.000000000 +0100 -+++ vdr-1.7.10b/recording.h 2009-12-30 11:33:26.000000000 +0100 -@@ -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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - // 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, public cThread { -@@ -132,6 +191,9 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - // 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 cIndexFileGenerator; - -@@ -235,6 +336,10 @@ - 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(); -@@ -248,6 +353,10 @@ - bool StoreResume(int Index) { return resumeFile.Save(Index); } - bool IsStillRecording(void); - void Delete(void); -+ #ifdef USE_LIEMIEXT -+ static int Length(const char *FileName, bool IsPesRecording = false); -+ ///< Calculates the recording length without reading the index. -+ #endif /* LIEMIEXT */ - }; - - class cFileName { -@@ -267,6 +376,12 @@ - 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 -Naur vdr-1.7.10/remux.c vdr-1.7.10b/remux.c ---- vdr-1.7.10/remux.c 2009-11-22 12:23:27.000000000 +0100 -+++ vdr-1.7.10b/remux.c 2009-12-30 11:33:26.000000000 +0100 -@@ -215,6 +215,32 @@ - return i; - } - -+#ifdef USE_TTXTSUBS -+int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, cChannel *Channel) -+{ -+ int i = 0, j = 0; -+ Target[i++] = SI::TeletextDescriptorTag; -+ int l = i; -+ Target[i++] = 0x00; // length -+ for (int n = 0; Channel->TPages(n); n++) { -+ const char *Language = Channel->Tlang(n); -+ int Pages = Channel->TPages(n); -+ Target[i++] = *Language++; -+ Target[i++] = *Language++; -+ Target[i++] = *Language++; -+ Target[i++] = ((Pages >> 13) & 0xf8) | ((Pages >> 8) & 0x7); // teletext type & magazine number -+ Target[i++] = Pages & 0xff; // teletext page number -+ j++; -+ } -+ if (j > 0) { -+ Target[l] = j * 5; // update length -+ IncEsInfoLength(i); -+ return i; -+ } -+ return 0; -+} -+#endif /* TTXTSUBS */ -+ - int cPatPmtGenerator::MakeLanguageDescriptor(uchar *Target, const char *Language) - { - int i = 0; -@@ -295,6 +321,9 @@ - numPmtPackets = 0; - if (Channel) { - int Vpid = Channel->Vpid(); -+ #ifdef USE_TTXTSUBS -+ int Tpid = Channel->Tpid(); -+ #endif /* TTXTSUBS */ - int Ppid = Channel->Ppid(); - uchar *p = buf; - int i = 0; -@@ -330,6 +359,12 @@ - i += MakeStream(buf + i, 0x06, Channel->Spid(n)); - i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n), Channel->SubtitlingType(n), Channel->CompositionPageId(n), Channel->AncillaryPageId(n)); - } -+#ifdef USE_TTXTSUBS -+ if (Tpid) { -+ i += MakeStream(buf + i, 0x06, Tpid); -+ i += MakeTeletextDescriptor(buf + i, Channel); -+ } -+#endif /* TTXTSUBS */ - - int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC - buf[SectionLength] |= (sl >> 8) & 0x0F; -@@ -402,6 +437,9 @@ - patVersion = pmtVersion = -1; - pmtPid = -1; - vpid = vtype = 0; -+#ifdef USE_TTXTSUBS -+ tpid = 0; -+#endif /* TTXTSUBS */ - } - - void cPatPmtParser::ParsePat(const uchar *Data, int Length) -@@ -486,6 +524,9 @@ - int NumDpids = 0; - int NumSpids = 0; - vpid = vtype = 0; -+#ifdef USE_TTXTSUBS -+ tpid = 0; -+#endif /* TTXTSUBS */ - SI::PMT::Stream stream; - for (SI::Loop::Iterator it; Pmt.streamLoop.getNext(stream, it); ) { - dbgpatpmt(" stream type = %02X, pid = %d", stream.getStreamType(), stream.getPid()); -@@ -566,6 +607,12 @@ - NumSpids++; - } - break; -+#ifdef USE_TTXTSUBS -+ case SI::TeletextDescriptorTag: -+ dbgpatpmt(" teletext"); -+ tpid = stream.getPid(); -+ break; -+#endif /* TTXTSUBS */ - case SI::ISO639LanguageDescriptorTag: { - SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; - dbgpatpmt(" '%s'", ld->languageCode); -diff -Naur vdr-1.7.10/remux.h vdr-1.7.10b/remux.h ---- vdr-1.7.10/remux.h 2009-11-21 16:55:34.000000000 +0100 -+++ vdr-1.7.10b/remux.h 2009-12-30 11:33:26.000000000 +0100 -@@ -170,6 +170,9 @@ - int MakeStream(uchar *Target, uchar Type, int Pid); - int MakeAC3Descriptor(uchar *Target); - int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId); -+#ifdef USE_TTXTSUBS -+ int MakeTeletextDescriptor(uchar *Target, cChannel *Channel); -+#endif /* TTXTSUBS */ - int MakeLanguageDescriptor(uchar *Target, const char *Language); - int MakeCRC(uchar *Target, const uchar *Data, int Length); - void GeneratePmtPid(cChannel *Channel); -@@ -215,6 +218,9 @@ - int vpid; - int vtype; - bool updatePrimaryDevice; -+#ifdef USE_TTXTSUBS -+ int tpid; -+#endif /* TTXTSUBS */ - protected: - int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; } - public: -@@ -242,6 +248,9 @@ - ///< Returns the video pid as defined by the current PMT, or 0 if no video - ///< pid has been detected, yet. - int Vtype(void) { return vtype; } -+ #ifdef USE_TTXTSUBS -+ int Tpid(void) { return tpid; } -+ #endif /* TTXTSUBS */ - ///< Returns the video stream type as defined by the current PMT, or 0 if no video - ///< stream type has been detected, yet. - }; -diff -Naur vdr-1.7.10/skinclassic.c vdr-1.7.10b/skinclassic.c ---- vdr-1.7.10/skinclassic.c 2008-02-23 11:31:58.000000000 +0100 -+++ vdr-1.7.10b/skinclassic.c 2009-12-30 11:33:26.000000000 +0100 -@@ -314,8 +314,52 @@ - 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 -Naur vdr-1.7.10/skinsttng.c vdr-1.7.10b/skinsttng.c ---- vdr-1.7.10/skinsttng.c 2008-02-23 11:23:44.000000000 +0100 -+++ vdr-1.7.10b/skinsttng.c 2009-12-30 11:33:26.000000000 +0100 -@@ -558,8 +558,52 @@ - 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 @@ - 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 -Naur vdr-1.7.10/sources.c vdr-1.7.10b/sources.c ---- vdr-1.7.10/sources.c 2008-02-10 15:07:26.000000000 +0100 -+++ vdr-1.7.10b/sources.c 2009-12-30 11:33:26.000000000 +0100 -@@ -37,6 +37,9 @@ - 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 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 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 -Naur vdr-1.7.10/sources.conf vdr-1.7.10b/sources.conf ---- vdr-1.7.10/sources.conf 2009-10-18 16:08:53.000000000 +0200 -+++ vdr-1.7.10b/sources.conf 2009-12-30 11:33:26.000000000 +0100 -@@ -194,3 +194,7 @@ - # Terrestrial - - T Terrestrial -+ -+# Plugin PLUGINPARAM -+ -+#P Plugin -diff -Naur vdr-1.7.10/sources.h vdr-1.7.10b/sources.h ---- vdr-1.7.10/sources.h 2005-05-14 11:30:41.000000000 +0200 -+++ vdr-1.7.10b/sources.h 2009-12-30 11:33:26.000000000 +0100 -@@ -16,10 +16,17 @@ - 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 @@ - 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 -Naur vdr-1.7.10/status.c vdr-1.7.10b/status.c ---- vdr-1.7.10/status.c 2008-02-16 15:46:31.000000000 +0100 -+++ vdr-1.7.10b/status.c 2009-12-30 11:33:26.000000000 +0100 -@@ -29,6 +29,20 @@ - 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 @@ - 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 -Naur vdr-1.7.10/status.h vdr-1.7.10b/status.h ---- vdr-1.7.10/status.h 2008-02-16 16:00:33.000000000 +0100 -+++ vdr-1.7.10b/status.h 2009-12-30 11:33:26.000000000 +0100 -@@ -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 @@ - // 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 @@ - // 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 @@ - 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 -Naur vdr-1.7.10/submenu.c vdr-1.7.10b/submenu.c ---- vdr-1.7.10/submenu.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/submenu.c 2009-12-30 11:33:26.000000000 +0100 -@@ -0,0 +1,949 @@ -+#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" -+#ifdef USE_WAREAGLEICON -+#include "iconpatch.h" -+#endif /* WAREAGLEICON */ -+ -+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() -+{ -+ _commandResult = NULL; -+ _currentMenuTree = &_menuTree; -+ _currentParentMenuTree = NULL; -+#ifdef USE_PINPLUGIN -+ _currentParentIndex = -1; -+#endif /* PINPLUGIN */ -+ _nodeArray = NULL; -+ _nrNodes = 0; -+} -+ -+ -+cSubMenu::~cSubMenu() -+{ -+ if (_commandResult) -+ free(_commandResult); -+ if (_nodeArray) -+ free(_nodeArray); -+ _nrNodes = 0; -+} -+ -+ -+bool cSubMenu::LoadXml(cString fname) -+{ -+ TiXmlDocument xmlDoc = TiXmlDocument(fname); -+ TiXmlElement *root = NULL; -+ cSubMenuNode *node = NULL; -+ -+ bool ok = true; -+ // Clear previously loaded Menu -+ _menuTree.Clear(); -+ _fname = fname; -+ -+ if ((ok = xmlDoc.LoadFile())) { -+ if ((root = xmlDoc.FirstChildElement("menus")) != NULL) { -+ cString tmp = root->Attribute("suffix"); -+#ifdef USE_WAREAGLEICON -+ if (strcmp(tmp, "ICON_FOLDER") == 0) tmp = cString::sprintf(" %s", IsLangUtf8() ? ICON_FOLDER_UTF8 : ICON_FOLDER); -+ else if (strcmp(tmp, "ICON_MOVE_FOLDER") == 0) tmp = cString::sprintf(" %s", IsLangUtf8() ? ICON_MOVE_FOLDER_UTF8 : ICON_MOVE_FOLDER); -+#endif /* WAREAGLEICON */ -+ if (*tmp) -+ _menuSuffix = tmp; -+ else -+ _menuSuffix = cString::sprintf(" "); -+ -+ 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 \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(cString fname) -+{ -+ bool ok = true; -+ -+ if (*_fname) { -+ TiXmlDocument xml = TiXmlDocument(fname); -+ TiXmlComment comment; -+ comment.SetValue("\n\ -+- VDR Menu-Configuration File\n\ -+-\n\ -+-\n\ -+- Example:\n\ -+-\n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ ...\n\ -+ \n\ -+ \n\ -+ \n\ -+ \n\ -+ ...\n\ -+ \n\ -+ \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 -Naur vdr-1.7.10/submenu.h vdr-1.7.10b/submenu.h ---- vdr-1.7.10/submenu.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/submenu.h 2009-12-30 11:33:26.000000000 +0100 -@@ -0,0 +1,159 @@ -+#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 {}; -+ -+// execute cmd thread -+class cExecCmdThread : public cThread { -+private: -+ cString ExecCmd; -+protected: -+ virtual void Action(void) { -+ if (system(ExecCmd) == 0) -+ esyslog("%s - finished", *ExecCmd); -+ delete(this); -+ }; -+public: -+ cExecCmdThread(char *cmd) { -+ ExecCmd = cString::sprintf("%s", cmd); -+ } -+ cExecCmdThread(const char *cmd) { -+ ExecCmd = cString::sprintf("%s", cmd); -+ } -+ ~cExecCmdThread() { -+ }; -+ }; -+ -+//################################################################################ -+//# 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(cString fname); -+ bool SaveXml(cString 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); -+ cString GetMenuSuffix() { return _menuSuffix; } -+ void SetMenuSuffix(char *suffix) { _menuSuffix = suffix; } -+ bool isTopMenu() { return (_currentParentMenuTree == NULL); } -+ const char *GetParentMenuTitel(); -+private: -+ cSubMenuNodes _menuTree; -+ cSubMenuNodes *_currentMenuTree; -+ cSubMenuNodes *_currentParentMenuTree; -+#ifdef USE_PINPLUGIN -+ int _currentParentIndex; -+#endif /* PINPLUGIN */ -+ cString _fname; -+ char *_commandResult; -+ int _nrNodes; -+ cSubMenuNode **_nodeArray; -+ cString _menuSuffix; -+ int countNodes(cSubMenuNodes *tree); -+ void tree2Array(cSubMenuNodes *tree, int &index); -+ void addMissingPlugins(); -+ void reloadNodeArray(); -+ void removeUndefinedNodes(); -+ }; -+ -+#endif //__SUBMENU_H -+#endif /* SETUP */ -diff -Naur vdr-1.7.10/svdrp.c vdr-1.7.10b/svdrp.c ---- vdr-1.7.10/svdrp.c 2009-10-18 16:08:58.000000000 +0200 -+++ vdr-1.7.10b/svdrp.c 2009-12-30 11:33:26.000000000 +0100 -@@ -39,6 +39,9 @@ - #include "timers.h" - #include "tools.h" - #include "videodir.h" -+#ifdef USE_STREAMDEVEXT -+#include "status.h" -+#endif /* STREAMDEVEXT */ - - // --- cSocket --------------------------------------------------------------- - -@@ -299,6 +302,10 @@ - "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 \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.", -@@ -619,6 +626,9 @@ - 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()); -@@ -1139,6 +1149,9 @@ - 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 -@@ -1225,6 +1238,9 @@ - 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); - } -@@ -1268,6 +1284,9 @@ - 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 -@@ -1486,6 +1505,38 @@ - 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) { -@@ -1601,6 +1652,9 @@ - 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 -Naur vdr-1.7.10/svdrp.h vdr-1.7.10b/svdrp.h ---- vdr-1.7.10/svdrp.h 2007-04-30 14:28:28.000000000 +0200 -+++ vdr-1.7.10b/svdrp.h 2009-12-30 11:33:26.000000000 +0100 -@@ -79,6 +79,9 @@ - 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 -Naur vdr-1.7.10/timers.c vdr-1.7.10b/timers.c ---- vdr-1.7.10/timers.c 2009-08-09 14:43:20.000000000 +0200 -+++ vdr-1.7.10b/timers.c 2009-12-30 11:33:26.000000000 +0100 -@@ -46,6 +46,9 @@ - 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; -@@ -84,6 +87,9 @@ - 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)) -@@ -95,6 +101,9 @@ - } - 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) -@@ -129,6 +138,9 @@ - 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; -@@ -323,6 +335,9 @@ - result = false; - } - } -+#ifdef USE_PINPLUGIN -+ fskProtection = aux && strstr(aux, "yes"); -+#endif /* PINPLUGIN */ - free(channelbuffer); - free(daybuffer); - free(filebuffer); -@@ -569,6 +584,9 @@ - SetFlags(tfRecording); - else - ClrFlags(tfRecording); -+#ifdef USE_STREAMDEVEXT -+ cStatus::MsgRecordingChange(NULL, scAdd); -+#endif /* STREAMDEVEXT */ - isyslog("timer %s %s", *ToDescr(), recording ? "start" : "stop"); - } - -@@ -632,6 +650,35 @@ - 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, "yes"))) -+ { -+ // add protection info to aux -+ -+ if (aux) { tmp = strdup(aux); free(aux); } -+ asprintf(&aux,"%syes", tmp ? tmp : ""); -+ } -+ else if (!fskProtection && aux && (p = strstr(aux, "yes"))) -+ { -+ // remove protection info to aux -+ -+ asprintf(&tmp, "%.*s%s", p-aux, aux, p+strlen("yes")); -+ free(aux); -+ aux = strdup(tmp); -+ } -+ -+ if (tmp) -+ free(tmp); -+} -+#endif /* PINPLUGIN */ -+ - // --- cTimers --------------------------------------------------------------- - - cTimers Timers; -diff -Naur vdr-1.7.10/timers.h vdr-1.7.10b/timers.h ---- vdr-1.7.10/timers.h 2008-02-16 15:33:23.000000000 +0100 -+++ vdr-1.7.10b/timers.h 2009-12-30 11:33:26.000000000 +0100 -@@ -37,6 +37,9 @@ - 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 @@ - 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 @@ - 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 -Naur vdr-1.7.10/tinystr.c vdr-1.7.10b/tinystr.c ---- vdr-1.7.10/tinystr.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/tinystr.c 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -+#include -+#include -+ -+#include "tinystr.h" -+ -+// TiXmlString constructor, based on a C string -+TiXmlString::TiXmlString (const char* instring) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ if (!instring) -+ { -+ allocated = 0; -+ cstring = NULL; -+ current_length = 0; -+ return; -+ } -+ newlen = strlen (instring) + 1; -+ newstring = new char [newlen]; -+ memcpy (newstring, instring, newlen); -+ // strcpy (newstring, instring); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+// TiXmlString copy constructor -+TiXmlString::TiXmlString (const TiXmlString& copy) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ // Prevent copy to self! -+ if ( © == this ) -+ return; -+ -+ if (! copy . allocated) -+ { -+ allocated = 0; -+ cstring = NULL; -+ current_length = 0; -+ return; -+ } -+ newlen = copy . length () + 1; -+ newstring = new char [newlen]; -+ // strcpy (newstring, copy . cstring); -+ memcpy (newstring, copy . cstring, newlen); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+// TiXmlString = operator. Safe when assign own content -+void TiXmlString ::operator = (const char * content) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ if (! content) -+ { -+ empty_it (); -+ return; -+ } -+ newlen = strlen (content) + 1; -+ newstring = new char [newlen]; -+ // strcpy (newstring, content); -+ memcpy (newstring, content, newlen); -+ empty_it (); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+// = operator. Safe when assign own content -+void TiXmlString ::operator = (const TiXmlString & copy) -+{ -+ unsigned newlen; -+ char * newstring; -+ -+ if (! copy . length ()) -+ { -+ empty_it (); -+ return; -+ } -+ newlen = copy . length () + 1; -+ newstring = new char [newlen]; -+ // strcpy (newstring, copy . c_str ()); -+ memcpy (newstring, copy . c_str (), newlen); -+ empty_it (); -+ allocated = newlen; -+ cstring = newstring; -+ current_length = newlen - 1; -+} -+ -+ -+// append a const char * to an existing TiXmlString -+void TiXmlString::append( const char* str, int len ) -+{ -+ char * new_string; -+ unsigned new_alloc, new_size, size_suffix; -+ -+ // don't use strlen - it can overrun the len passed in! -+ const char* p = str; -+ size_suffix = 0; -+ -+ while ( *p && size_suffix < (unsigned)len ) -+ { -+ ++p; -+ ++size_suffix; -+ } -+ if ( !size_suffix) -+ return; -+ -+ new_size = length () + size_suffix + 1; -+ // check if we need to expand -+ if (new_size > allocated) -+ { -+ // compute new size -+ new_alloc = assign_new_size (new_size); -+ -+ // allocate new buffer -+ new_string = new char [new_alloc]; -+ new_string [0] = 0; -+ -+ // copy the previous allocated buffer into this one -+ if (allocated && cstring) -+ // strcpy (new_string, cstring); -+ memcpy (new_string, cstring, length ()); -+ -+ // append the suffix. It does exist, otherwize we wouldn't be expanding -+ // strncat (new_string, str, len); -+ memcpy (new_string + length (), -+ str, -+ size_suffix); -+ -+ // return previsously allocated buffer if any -+ if (allocated && cstring) -+ delete [] cstring; -+ -+ // update member variables -+ cstring = new_string; -+ allocated = new_alloc; -+ } -+ else -+ { -+ // we know we can safely append the new string -+ // strncat (cstring, str, len); -+ memcpy (cstring + length (), -+ str, -+ size_suffix); -+ } -+ current_length = new_size - 1; -+ cstring [current_length] = 0; -+} -+ -+ -+// append a const char * to an existing TiXmlString -+void TiXmlString::append( const char * suffix ) -+{ -+ char * new_string; -+ unsigned new_alloc, new_size; -+ -+ new_size = length () + strlen (suffix) + 1; -+ // check if we need to expand -+ if (new_size > allocated) -+ { -+ // compute new size -+ new_alloc = assign_new_size (new_size); -+ -+ // allocate new buffer -+ new_string = new char [new_alloc]; -+ new_string [0] = 0; -+ -+ // copy the previous allocated buffer into this one -+ if (allocated && cstring) -+ memcpy (new_string, cstring, 1 + length ()); -+ // strcpy (new_string, cstring); -+ -+ // append the suffix. It does exist, otherwize we wouldn't be expanding -+ // strcat (new_string, suffix); -+ memcpy (new_string + length (), -+ suffix, -+ strlen (suffix) + 1); -+ -+ // return previsously allocated buffer if any -+ if (allocated && cstring) -+ delete [] cstring; -+ -+ // update member variables -+ cstring = new_string; -+ allocated = new_alloc; -+ } -+ else -+ { -+ // we know we can safely append the new string -+ // strcat (cstring, suffix); -+ memcpy (cstring + length (), -+ suffix, -+ strlen (suffix) + 1); -+ } -+ current_length = new_size - 1; -+} -+ -+// Check for TiXmlString equuivalence -+//bool TiXmlString::operator == (const TiXmlString & compare) const -+//{ -+// return (! strcmp (c_str (), compare . c_str ())); -+//} -+ -+//unsigned TiXmlString::length () const -+//{ -+// if (allocated) -+// // return strlen (cstring); -+// return current_length; -+// return 0; -+//} -+ -+ -+unsigned TiXmlString::find (char tofind, unsigned offset) const -+{ -+ char * lookup; -+ -+ if (offset >= length ()) -+ return (unsigned) notfound; -+ for (lookup = cstring + offset; * lookup; lookup++) -+ if (* lookup == tofind) -+ return lookup - cstring; -+ return (unsigned) notfound; -+} -+ -+ -+bool TiXmlString::operator == (const TiXmlString & compare) const -+{ -+ if ( allocated && compare.allocated ) -+ { -+ assert( cstring ); -+ assert( compare.cstring ); -+ return ( strcmp( cstring, compare.cstring ) == 0 ); -+ } -+ return false; -+} -+ -+ -+bool TiXmlString::operator < (const TiXmlString & compare) const -+{ -+ if ( allocated && compare.allocated ) -+ { -+ assert( cstring ); -+ assert( compare.cstring ); -+ return ( strcmp( cstring, compare.cstring ) > 0 ); -+ } -+ return false; -+} -+ -+ -+bool TiXmlString::operator > (const TiXmlString & compare) const -+{ -+ if ( allocated && compare.allocated ) -+ { -+ assert( cstring ); -+ assert( compare.cstring ); -+ return ( strcmp( cstring, compare.cstring ) < 0 ); -+ } -+ return false; -+} -+ -+ -+#endif // TIXML_USE_STL -+#endif /* SETUP */ -diff -Naur vdr-1.7.10/tinystr.h vdr-1.7.10b/tinystr.h ---- vdr-1.7.10/tinystr.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/tinystr.h 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -+ -+/* -+ 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 -Naur vdr-1.7.10/tinyxml.c vdr-1.7.10b/tinyxml.c ---- vdr-1.7.10/tinyxml.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/tinyxml.c 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -+#include "tinyxml.h" -+ -+#ifdef TIXML_USE_STL -+#include -+#endif -+ -+ -+bool TiXmlBase::condenseWhiteSpace = true; -+ -+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream ) -+{ -+ TIXML_STRING buffer; -+ PutString( str, &buffer ); -+ (*stream) << buffer; -+} -+ -+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString ) -+{ -+ int i=0; -+ -+ while( i<(int)str.length() ) -+ { -+ unsigned char c = (unsigned char) str[i]; -+ -+ if ( c == '&' -+ && i < ( (int)str.length() - 2 ) -+ && str[i+1] == '#' -+ && str[i+2] == 'x' ) -+ { -+ // Hexadecimal character reference. -+ // Pass through unchanged. -+ // © -- copyright symbol, for example. -+ // -+ // The -1 is a bug fix from Rob Laveaux. It keeps -+ // an overflow from happening if there is no ';'. -+ // There are actually 2 ways to exit this loop - -+ // while fails (error case) and break (semicolon found). -+ // However, there is no mechanism (currently) for -+ // this function to return an error. -+ while ( i<(int)str.length()-1 ) -+ { -+ outString->append( str.c_str() + i, 1 ); -+ ++i; -+ if ( str[i] == ';' ) -+ break; -+ } -+ } -+ else if ( c == '&' ) -+ { -+ outString->append( entity[0].str, entity[0].strLength ); -+ ++i; -+ } -+ else if ( c == '<' ) -+ { -+ outString->append( entity[1].str, entity[1].strLength ); -+ ++i; -+ } -+ else if ( c == '>' ) -+ { -+ outString->append( entity[2].str, entity[2].strLength ); -+ ++i; -+ } -+ else if ( c == '\"' ) -+ { -+ outString->append( entity[3].str, entity[3].strLength ); -+ ++i; -+ } -+ else if ( c == '\'' ) -+ { -+ outString->append( entity[4].str, entity[4].strLength ); -+ ++i; -+ } -+ else if ( c < 32 ) -+ { -+ // Easy pass at non-alpha/numeric/symbol -+ // Below 32 is symbolic. -+ char buf[ 32 ]; -+ sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); -+ outString->append( buf, strlen( buf ) ); -+ ++i; -+ } -+ else -+ { -+ //char realc = (char) c; -+ //outString->append( &realc, 1 ); -+ *outString += (char) c; // somewhat more efficient function call. -+ ++i; -+ } -+ } -+} -+ -+ -+// <-- Strange class for a bug fix. Search for STL_STRING_BUG -+TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str ) -+{ -+ buffer = new char[ str.length()+1 ]; -+ if ( buffer ) -+ { -+ strcpy( buffer, str.c_str() ); -+ } -+} -+ -+ -+TiXmlBase::StringToBuffer::~StringToBuffer() -+{ -+ delete [] buffer; -+} -+// End strange bug fix. --> -+ -+ -+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() -+{ -+ parent = 0; -+ type = _type; -+ firstChild = 0; -+ lastChild = 0; -+ prev = 0; -+ next = 0; -+} -+ -+ -+TiXmlNode::~TiXmlNode() -+{ -+ TiXmlNode* node = firstChild; -+ TiXmlNode* temp = 0; -+ -+ while ( node ) -+ { -+ temp = node; -+ node = node->next; -+ delete temp; -+ } -+} -+ -+ -+void TiXmlNode::CopyTo( TiXmlNode* target ) const -+{ -+ target->SetValue (value.c_str() ); -+ target->userData = userData; -+} -+ -+ -+void TiXmlNode::Clear() -+{ -+ TiXmlNode* node = firstChild; -+ TiXmlNode* temp = 0; -+ -+ while ( node ) -+ { -+ temp = node; -+ node = node->next; -+ delete temp; -+ } -+ -+ firstChild = 0; -+ lastChild = 0; -+} -+ -+ -+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) -+{ -+ node->parent = this; -+ -+ node->prev = lastChild; -+ node->next = 0; -+ -+ if ( lastChild ) -+ lastChild->next = node; -+ else -+ firstChild = node; // it was an empty list. -+ -+ lastChild = node; -+ return node; -+} -+ -+ -+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) -+{ -+ TiXmlNode* node = addThis.Clone(); -+ if ( !node ) -+ return 0; -+ -+ return LinkEndChild( node ); -+} -+ -+ -+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) -+{ -+ if ( !beforeThis || beforeThis->parent != this ) -+ return 0; -+ -+ TiXmlNode* node = addThis.Clone(); -+ if ( !node ) -+ return 0; -+ node->parent = this; -+ -+ node->next = beforeThis; -+ node->prev = beforeThis->prev; -+ if ( beforeThis->prev ) -+ { -+ beforeThis->prev->next = node; -+ } -+ else -+ { -+ assert( firstChild == beforeThis ); -+ firstChild = node; -+ } -+ beforeThis->prev = node; -+ return node; -+} -+ -+ -+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) -+{ -+ if ( !afterThis || afterThis->parent != this ) -+ return 0; -+ -+ TiXmlNode* node = addThis.Clone(); -+ if ( !node ) -+ return 0; -+ node->parent = this; -+ -+ node->prev = afterThis; -+ node->next = afterThis->next; -+ if ( afterThis->next ) -+ { -+ afterThis->next->prev = node; -+ } -+ else -+ { -+ assert( lastChild == afterThis ); -+ lastChild = node; -+ } -+ afterThis->next = node; -+ return node; -+} -+ -+ -+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) -+{ -+ if ( replaceThis->parent != this ) -+ return 0; -+ -+ TiXmlNode* node = withThis.Clone(); -+ if ( !node ) -+ return 0; -+ -+ node->next = replaceThis->next; -+ node->prev = replaceThis->prev; -+ -+ if ( replaceThis->next ) -+ replaceThis->next->prev = node; -+ else -+ lastChild = node; -+ -+ if ( replaceThis->prev ) -+ replaceThis->prev->next = node; -+ else -+ firstChild = node; -+ -+ delete replaceThis; -+ node->parent = this; -+ return node; -+} -+ -+ -+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) -+{ -+ if ( removeThis->parent != this ) -+ { -+ assert( 0 ); -+ return false; -+ } -+ -+ if ( removeThis->next ) -+ removeThis->next->prev = removeThis->prev; -+ else -+ lastChild = removeThis->prev; -+ -+ if ( removeThis->prev ) -+ removeThis->prev->next = removeThis->next; -+ else -+ firstChild = removeThis->next; -+ -+ delete removeThis; -+ return true; -+} -+ -+TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = firstChild; node; node = node->next ) -+ { -+ if ( node->SValue() == TIXML_STRING( _value )) -+ return node; -+ } -+ return 0; -+} -+ -+TiXmlNode* TiXmlNode::LastChild( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = lastChild; node; node = node->prev ) -+ { -+ if ( node->SValue() == TIXML_STRING (_value)) -+ return node; -+ } -+ return 0; -+} -+ -+TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) const -+{ -+ if ( !previous ) -+ { -+ return FirstChild(); -+ } -+ else -+ { -+ assert( previous->parent == this ); -+ return previous->NextSibling(); -+ } -+} -+ -+TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous ) const -+{ -+ if ( !previous ) -+ { -+ return FirstChild( val ); -+ } -+ else -+ { -+ assert( previous->parent == this ); -+ return previous->NextSibling( val ); -+ } -+} -+ -+TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = next; node; node = node->next ) -+ { -+ if ( node->SValue() == TIXML_STRING (_value)) -+ return node; -+ } -+ return 0; -+} -+ -+ -+TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const -+{ -+ TiXmlNode* node; -+ for ( node = prev; node; node = node->prev ) -+ { -+ if ( node->SValue() == TIXML_STRING (_value)) -+ return node; -+ } -+ return 0; -+} -+ -+void TiXmlElement::RemoveAttribute( const char * name ) -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( node ) -+ { -+ attributeSet.Remove( node ); -+ delete node; -+ } -+} -+ -+TiXmlElement* TiXmlNode::FirstChildElement() const -+{ -+ TiXmlNode* node; -+ -+ for ( node = FirstChild(); -+ node; -+ node = node->NextSibling() ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const -+{ -+ TiXmlNode* node; -+ -+ for ( node = FirstChild( _value ); -+ node; -+ node = node->NextSibling( _value ) ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+ -+TiXmlElement* TiXmlNode::NextSiblingElement() const -+{ -+ TiXmlNode* node; -+ -+ for ( node = NextSibling(); -+ node; -+ node = node->NextSibling() ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const -+{ -+ TiXmlNode* node; -+ -+ for ( node = NextSibling( _value ); -+ node; -+ node = node->NextSibling( _value ) ) -+ { -+ if ( node->ToElement() ) -+ return node->ToElement(); -+ } -+ return 0; -+} -+ -+ -+ -+TiXmlDocument* TiXmlNode::GetDocument() const -+{ -+ const TiXmlNode* node; -+ -+ for( node = this; node; node = node->parent ) -+ { -+ if ( node->ToDocument() ) -+ return node->ToDocument(); -+ } -+ return 0; -+} -+ -+ -+TiXmlElement::TiXmlElement (const char * _value) -+ : TiXmlNode( TiXmlNode::ELEMENT ) -+{ -+ firstChild = lastChild = 0; -+ value = _value; -+} -+ -+ -+#ifdef TIXML_USE_STL -+TiXmlElement::TiXmlElement( const std::string& _value ) -+ : TiXmlNode( TiXmlNode::ELEMENT ) -+{ -+ firstChild = lastChild = 0; -+ value = _value; -+} -+#endif -+ -+ -+TiXmlElement::TiXmlElement( const TiXmlElement& copy) -+ : TiXmlNode( TiXmlNode::ELEMENT ) -+{ -+ firstChild = lastChild = 0; -+ copy.CopyTo( this ); -+} -+ -+ -+void TiXmlElement::operator=( const TiXmlElement& base ) -+{ -+ ClearThis(); -+ base.CopyTo( this ); -+} -+ -+ -+TiXmlElement::~TiXmlElement() -+{ -+ ClearThis(); -+} -+ -+ -+void TiXmlElement::ClearThis() -+{ -+ Clear(); -+ while( attributeSet.First() ) -+ { -+ TiXmlAttribute* node = attributeSet.First(); -+ attributeSet.Remove( node ); -+ delete node; -+ } -+} -+ -+ -+const char * TiXmlElement::Attribute( const char * name ) const -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ -+ if ( node ) -+ return node->Value(); -+ -+ return 0; -+} -+ -+ -+const char * TiXmlElement::Attribute( const char * name, int* i ) const -+{ -+ const char * s = Attribute( name ); -+ if ( i ) -+ { -+ if ( s ) -+ *i = atoi( s ); -+ else -+ *i = 0; -+ } -+ return s; -+} -+ -+ -+const char * TiXmlElement::Attribute( const char * name, double* d ) const -+{ -+ const char * s = Attribute( name ); -+ if ( d ) -+ { -+ if ( s ) -+ *d = atof( s ); -+ else -+ *d = 0; -+ } -+ return s; -+} -+ -+ -+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( !node ) -+ return TIXML_NO_ATTRIBUTE; -+ -+ return node->QueryIntValue( ival ); -+} -+ -+ -+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( !node ) -+ return TIXML_NO_ATTRIBUTE; -+ -+ return node->QueryDoubleValue( dval ); -+} -+ -+ -+void TiXmlElement::SetAttribute( const char * name, int val ) -+{ -+ char buf[64]; -+ sprintf( buf, "%d", val ); -+ SetAttribute( name, buf ); -+} -+ -+ -+void TiXmlElement::SetDoubleAttribute( const char * name, double val ) -+{ -+ char buf[128]; -+ sprintf( buf, "%f", val ); -+ SetAttribute( name, buf ); -+} -+ -+ -+void TiXmlElement::SetAttribute( const char * name, const char * _value ) -+{ -+ TiXmlAttribute* node = attributeSet.Find( name ); -+ if ( node ) -+ { -+ node->SetValue( _value ); -+ return; -+ } -+ -+ TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); -+ if ( attrib ) -+ { -+ attributeSet.Add( attrib ); -+ } -+ else -+ { -+ TiXmlDocument* document = GetDocument(); -+ if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); -+ } -+} -+ -+void TiXmlElement::Print( FILE* cfile, int depth ) const -+{ -+ int i; -+ for ( i=0; iNext() ) -+ { -+ fprintf( cfile, " " ); -+ attrib->Print( cfile, depth ); -+ } -+ -+ // There are 3 different formatting approaches: -+ // 1) An element without children is printed as a node -+ // 2) An element with only a text child is printed as text -+ // 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, "", 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", 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) << ""; -+ } -+ 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", value.c_str() ); -+} -+ -+void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*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, ""); -+} -+ -+void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const -+{ -+ (*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", 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 && iNextSibling(), ++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 && iNextSibling( 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 && iNextSiblingElement(), ++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 && iNextSiblingElement( value ), ++i ) -+ { -+ // nothing -+ } -+ if ( child ) -+ return TiXmlHandle( child ); -+ } -+ return TiXmlHandle( 0 ); -+} -+#endif /* SETUP */ -diff -Naur vdr-1.7.10/tinyxmlerror.c vdr-1.7.10b/tinyxmlerror.c ---- vdr-1.7.10/tinyxmlerror.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/tinyxmlerror.c 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -Naur vdr-1.7.10/tinyxml.h vdr-1.7.10b/tinyxml.h ---- vdr-1.7.10/tinyxml.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/tinyxml.h 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -+#include -+#include -+#include -+#include -+ -+// Help out windows: -+#if defined( _DEBUG ) && !defined( DEBUG ) -+#define DEBUG -+#endif -+ -+#if defined( DEBUG ) && defined( _MSC_VER ) -+#include -+#define TIXML_LOG OutputDebugString -+#else -+#define TIXML_LOG printf -+#endif -+ -+#ifdef TIXML_USE_STL -+ #include -+ #include -+ #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 -+ -+ @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 -+ -+ -+ -+ -+ -+ -+ @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 -Naur vdr-1.7.10/tinyxmlparser.c vdr-1.7.10b/tinyxmlparser.c ---- vdr-1.7.10/tinyxmlparser.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/tinyxmlparser.c 2009-12-30 11:33:26.000000000 +0100 -@@ -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 -+ -+//#define DEBUG_PARSER -+ -+// Note tha "PutString" hardcodes the same list. This -+// is less flexible than it appears. Changing the entries -+// or order will break putstring. -+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = -+{ -+ { "&", 5, '&' }, -+ { "<", 4, '<' }, -+ { ">", 4, '>' }, -+ { """, 6, '\"' }, -+ { "'", 6, '\'' } -+}; -+ -+// Bunch of unicode info at: -+// http://www.unicode.org/faq/utf_bom.html -+// Including the basic of this table, which determines the #bytes in the -+// sequence from the lead byte. 1 placed for invalid sequences -- -+// although the result will be junk, pass it through as much as possible. -+// Beware of the non-characters in UTF-8: -+// ef bb bf (Microsoft "lead bytes") -+// ef bf be -+// ef bf bf -+ -+ -+ -+const int TiXmlBase::utf8ByteTable[256] = -+{ -+ // 0 1 2 3 4 5 6 7 8 9 a b c d e f -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 -+ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 -+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte -+ 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid -+}; -+ -+ -+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -+{ -+ const unsigned long BYTE_MASK = 0xBF; -+ const unsigned long BYTE_MARK = 0x80; -+ const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; -+ -+ if (input < 0x80) -+ *length = 1; -+ else if ( input < 0x800 ) -+ *length = 2; -+ else if ( input < 0x10000 ) -+ *length = 3; -+ else if ( input < 0x200000 ) -+ *length = 4; -+ else -+ { *length = 0; return; } // This code won't covert this correctly anyway. -+ -+ output += *length; -+ -+ // Scary scary fall throughs. -+ switch (*length) -+ { -+ case 4: -+ --output; -+ *output = (char)((input | BYTE_MARK) & BYTE_MASK); -+ input >>= 6; -+ case 3: -+ --output; -+ *output = (char)((input | BYTE_MARK) & BYTE_MASK); -+ input >>= 6; -+ case 2: -+ --output; -+ *output = (char)((input | BYTE_MARK) & BYTE_MASK); -+ input >>= 6; -+ case 1: -+ --output; -+ *output = (char)(input | FIRST_BYTE_MARK[*length]); -+ } -+} -+ -+ -+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ) -+{ -+ // This will only work for low-ascii, everything else is assumed to be a valid -+ // letter. I'm not sure this is the best approach, but it is quite tricky trying -+ // to figure out alhabetical vs. not across encoding. So take a very -+ // conservative approach. -+ -+// if ( encoding == TIXML_ENCODING_UTF8 ) -+// { -+ if ( anyByte < 127 ) -+ return isalpha( anyByte ); -+ else -+ return 1; // What else to do? The unicode set is huge...get the english ones right. -+// } -+// else -+// { -+// return isalpha( anyByte ); -+// } -+} -+ -+ -+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ) -+{ -+ // This will only work for low-ascii, everything else is assumed to be a valid -+ // letter. I'm not sure this is the best approach, but it is quite tricky trying -+ // to figure out alhabetical vs. not across encoding. So take a very -+ // conservative approach. -+ -+// if ( encoding == TIXML_ENCODING_UTF8 ) -+// { -+ if ( anyByte < 127 ) -+ return isalnum( anyByte ); -+ else -+ return 1; // What else to do? The unicode set is huge...get the english ones right. -+// } -+// else -+// { -+// return isalnum( anyByte ); -+// } -+} -+ -+ -+class TiXmlParsingData -+{ -+ friend class TiXmlDocument; -+ public: -+ void Stamp( const char* now, TiXmlEncoding encoding ); -+ -+ const TiXmlCursor& Cursor() { return cursor; } -+ -+ private: -+ // Only used by the document! -+ TiXmlParsingData( const char* start, int _tabsize, int row, int col ) -+ { -+ assert( start ); -+ stamp = start; -+ tabsize = _tabsize; -+ cursor.row = row; -+ cursor.col = col; -+ } -+ -+ TiXmlCursor cursor; -+ const char* stamp; -+ int tabsize; -+}; -+ -+ -+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) -+{ -+ assert( now ); -+ -+ // Do nothing if the tabsize is 0. -+ if ( tabsize < 1 ) -+ { -+ return; -+ } -+ -+ // Get the current row, column. -+ int row = cursor.row; -+ int col = cursor.col; -+ const char* p = stamp; -+ assert( p ); -+ -+ while ( p < now ) -+ { -+ // Code contributed by Fletcher Dunn: (modified by lee) -+ switch (*p) { -+ case 0: -+ // We *should* never get here, but in case we do, don't -+ // advance past the terminating null character, ever -+ return; -+ -+ case '\r': -+ // bump down to the next line -+ ++row; -+ col = 0; -+ // Eat the character -+ ++p; -+ -+ // Check for \r\n sequence, and treat this as a single character -+ if (*p == '\n') { -+ ++p; -+ } -+ break; -+ -+ case '\n': -+ // bump down to the next line -+ ++row; -+ col = 0; -+ -+ // Eat the character -+ ++p; -+ -+ // Check for \n\r sequence, and treat this as a single -+ // character. (Yes, this bizarre thing does occur still -+ // on some arcane platforms...) -+ if (*p == '\r') { -+ ++p; -+ } -+ break; -+ -+ case '\t': -+ // Eat the character -+ ++p; -+ -+ // Skip to next tab stop -+ col = (col / tabsize + 1) * tabsize; -+ break; -+ -+ case (char)(0xef): -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ if ( *(p+1) && *(p+2) ) -+ { -+ // In these cases, don't advance the column. These are -+ // 0-width spaces. -+ if ( *(p+1)==(char)(0xbb) && *(p+2)==(char)(0xbf) ) -+ p += 3; -+ else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbe) ) -+ p += 3; -+ else if ( *(p+1)==(char)(0xbf) && *(p+2)==(char)(0xbf) ) -+ p += 3; -+ else -+ { p +=3; ++col; } // A normal character. -+ } -+ } -+ else -+ { -+ ++p; -+ ++col; -+ } -+ break; -+ -+ default: -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ // Eat the 1 to 4 byte utf8 character. -+ int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)]; -+ if ( step == 0 ) -+ step = 1; // Error case from bad encoding, but handle gracefully. -+ p += step; -+ -+ // Just advance one column, of course. -+ ++col; -+ } -+ else -+ { -+ ++p; -+ ++col; -+ } -+ break; -+ } -+ } -+ cursor.row = row; -+ cursor.col = col; -+ assert( cursor.row >= -1 ); -+ assert( cursor.col >= -1 ); -+ stamp = p; -+ assert( stamp ); -+} -+ -+ -+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) -+{ -+ if ( !p || !*p ) -+ { -+ return 0; -+ } -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ while ( *p ) -+ { -+ // Skip the stupid Microsoft UTF-8 Byte order marks -+ if ( *(p+0)==(char) 0xef -+ && *(p+1)==(char) 0xbb -+ && *(p+2)==(char) 0xbf ) -+ { -+ p += 3; -+ continue; -+ } -+ else if(*(p+0)==(char) 0xef -+ && *(p+1)==(char) 0xbf -+ && *(p+2)==(char) 0xbe ) -+ { -+ p += 3; -+ continue; -+ } -+ else if(*(p+0)==(char) 0xef -+ && *(p+1)==(char) 0xbf -+ && *(p+2)==(char) 0xbf ) -+ { -+ p += 3; -+ continue; -+ } -+ -+ if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. -+ ++p; -+ else -+ break; -+ } -+ } -+ else -+ { -+ while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) -+ ++p; -+ } -+ -+ return p; -+} -+ -+#ifdef TIXML_USE_STL -+/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ) -+{ -+ for( ;; ) -+ { -+ if ( !in->good() ) return false; -+ -+ int c = in->peek(); -+ // At this scope, we can't get to a document. So fail silently. -+ if ( !IsWhiteSpace( c ) || c <= 0 ) -+ return true; -+ -+ *tag += (char) in->get(); -+ } -+} -+ -+/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ) -+{ -+ //assert( character > 0 && character < 128 ); // else it won't work in utf-8 -+ while ( in->good() ) -+ { -+ int c = in->peek(); -+ if ( c == character ) -+ return true; -+ if ( c <= 0 ) // Silent failure: can't get document at this scope -+ return false; -+ -+ in->get(); -+ *tag += (char) c; -+ } -+ return false; -+} -+#endif -+ -+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) -+{ -+ *name = ""; -+ assert( p ); -+ -+ // Names start with letters or underscores. -+ // Of course, in unicode, tinyxml has no idea what a letter *is*. The -+ // algorithm is generous. -+ // -+ // After that, they can be letters, underscores, numbers, -+ // hyphens, or colons. (Colons are valid ony for namespaces, -+ // but tinyxml can't tell namespaces from names.) -+ if ( p && *p -+ && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) -+ { -+ while( p && *p -+ && ( IsAlphaNum( (unsigned char ) *p, encoding ) -+ || *p == '_' -+ || *p == '-' -+ || *p == '.' -+ || *p == ':' ) ) -+ { -+ (*name) += *p; -+ ++p; -+ } -+ return p; -+ } -+ return 0; -+} -+ -+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) -+{ -+ // Presume an entity, and pull it out. -+ TIXML_STRING ent; -+ int i; -+ *length = 0; -+ -+ if ( *(p+1) && *(p+1) == '#' && *(p+2) ) -+ { -+ unsigned long ucs = 0; -+ unsigned delta = 0; -+ unsigned mult = 1; -+ -+ if ( *(p+2) == 'x' ) -+ { -+ // Hexadecimal. -+ if ( !*(p+3) ) return 0; -+ -+ const char* q = p+3; -+ q = strchr( q, ';' ); -+ -+ if ( !q || !*q ) return 0; -+ -+ delta = q-p; -+ --q; -+ -+ while ( *q != 'x' ) -+ { -+ if ( *q >= '0' && *q <= '9' ) -+ ucs += mult * (*q - '0'); -+ else if ( *q >= 'a' && *q <= 'f' ) -+ ucs += mult * (*q - 'a' + 10); -+ else if ( *q >= 'A' && *q <= 'F' ) -+ ucs += mult * (*q - 'A' + 10 ); -+ else -+ return 0; -+ mult *= 16; -+ --q; -+ } -+ } -+ else -+ { -+ // Decimal. -+ if ( !*(p+2) ) return 0; -+ -+ const char* q = p+2; -+ q = strchr( q, ';' ); -+ -+ if ( !q || !*q ) return 0; -+ -+ delta = q-p; -+ --q; -+ -+ while ( *q != '#' ) -+ { -+ if ( *q >= '0' && *q <= '9' ) -+ ucs += mult * (*q - '0'); -+ else -+ return 0; -+ mult *= 10; -+ --q; -+ } -+ } -+ if ( encoding == TIXML_ENCODING_UTF8 ) -+ { -+ // convert the UCS to UTF-8 -+ ConvertUTF32ToUTF8( ucs, value, length ); -+ } -+ else -+ { -+ *value = (char)ucs; -+ *length = 1; -+ } -+ return p + delta + 1; -+ } -+ -+ // Now try to match it. -+ for( i=0; iappend( 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: "; -+ -+ 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, "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 0) -@@ -574,8 +802,20 @@ - 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); -@@ -736,7 +976,11 @@ - // 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... -@@ -919,6 +1163,9 @@ - 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) -@@ -991,10 +1238,16 @@ - 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); - } -@@ -1075,8 +1328,15 @@ - // 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; -@@ -1132,8 +1392,15 @@ - 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; -@@ -1184,13 +1451,26 @@ - 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: -@@ -1208,9 +1488,15 @@ - // 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 -Naur vdr-1.7.10/vdrttxtsubshooks.c vdr-1.7.10b/vdrttxtsubshooks.c ---- vdr-1.7.10/vdrttxtsubshooks.c 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/vdrttxtsubshooks.c 2009-12-30 11:33:26.000000000 +0100 -@@ -0,0 +1,65 @@ -+#ifdef USE_TTXTSUBS -+/* -+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2003 - 2008 Ragnar Sundblad -+ * -+ * 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 -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#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, bool IsPesRecording) -+ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording); }; -+ virtual int ManualPageNumber(const cChannel *channel) -+ { if(gListener) return gListener->ManualPageNumber(channel); else return 0; }; -+}; -+ -+ -+// ------ 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 -Naur vdr-1.7.10/vdrttxtsubshooks.h vdr-1.7.10b/vdrttxtsubshooks.h ---- vdr-1.7.10/vdrttxtsubshooks.h 1970-01-01 01:00:00.000000000 +0100 -+++ vdr-1.7.10b/vdrttxtsubshooks.h 2009-12-30 11:33:26.000000000 +0100 -@@ -0,0 +1,50 @@ -+#ifdef USE_TTXTSUBS -+/* -+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2003 - 2008 Ragnar Sundblad -+ * -+ * 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 -+ * -+ */ -+ -+#ifndef __VDRTTXTSUBSHOOKS_H -+#define __VDRTTXTSUBSHOOKS_H -+ -+#define TTXTSUBSVERSNUM 1 -+ -+class cDevice; -+class cChannel; -+ -+#define VDRTTXTSUBSHOOKS -+ -+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, bool IsPesRecording = true) {}; -+ virtual int ManualPageNumber(const cChannel *channel) -+ { return 0; }; -+ -+ // used by VDR to call hook listeners -+ static cVDRTtxtsubsHookListener *Hook(void); -+}; -+ -+#endif -+#endif /* TTXTSUBS */ -diff -Naur vdr-1.7.10/videodir.c vdr-1.7.10b/videodir.c ---- vdr-1.7.10/videodir.c 2008-02-16 14:00:03.000000000 +0100 -+++ vdr-1.7.10b/videodir.c 2009-12-30 11:33:26.000000000 +0100 -@@ -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 @@ - 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 @@ - 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 @@ - 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 @@ - 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 @@ - } 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 -Naur vdr-1.7.10/videodir.h vdr-1.7.10b/videodir.h ---- vdr-1.7.10/videodir.h 2008-02-16 13:53:11.000000000 +0100 -+++ vdr-1.7.10b/videodir.h 2009-12-30 11:33:26.000000000 +0100 -@@ -19,6 +19,9 @@ - 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/packages/multimedia/vdr/patches/40_vdr-1.7.7-gotox.diff b/packages/multimedia/vdr/patches/40_vdr-1.7.7-gotox.diff deleted file mode 100644 index 8097b037e0..0000000000 --- a/packages/multimedia/vdr/patches/40_vdr-1.7.7-gotox.diff +++ /dev/null @@ -1,449 +0,0 @@ -diff -ruNp vdr-1.7.7-extensions/config.c vdr-1.7.7-ext-gotox/config.c ---- vdr-1.7.7-extensions/config.c 2009-05-04 21:24:29.000000000 +0200 -+++ vdr-1.7.7-ext-gotox/config.c 2009-05-04 21:30:15.000000000 +0200 -@@ -286,6 +286,13 @@ cSetup::cSetup(void) - LnbFrequLo = 9750; - LnbFrequHi = 10600; - DiSEqC = 0; -+#ifdef USE_GOTOX -+ UseGotox = 0; -+ GotoxSpeed = 100; -+ GotoxRepeat = 0; -+ GotoxSN = 0; GotoxLat = 613; GotoxEW = 1; GotoxLong = 236; // Somewhere at Tampere, Finland :^) -+ GotoxPrevSource = 0; -+#endif /* GOTOX */ - SetSystemTime = 0; - TimeSource = 0; - TimeTransponder = 0; -@@ -642,6 +649,16 @@ bool cSetup::Parse(const char *Name, con - else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value); - else if (!strcasecmp(Name, "LnbFrequHi")) LnbFrequHi = atoi(Value); - else if (!strcasecmp(Name, "DiSEqC")) DiSEqC = atoi(Value); -+#ifdef USE_GOTOX -+ else if (!strcasecmp(Name, "UseGotox")) UseGotox = atoi(Value); -+ else if (!strcasecmp(Name, "GotoxSpeed")) GotoxSpeed = atoi(Value); -+ else if (!strcasecmp(Name, "GotoxRepeat")) GotoxRepeat = atoi(Value); -+ else if (!strcasecmp(Name, "GotoxSN")) GotoxSN = atoi(Value); -+ else if (!strcasecmp(Name, "GotoxLat")) GotoxLat = atoi(Value); -+ else if (!strcasecmp(Name, "GotoxEW")) GotoxEW = atoi(Value); -+ else if (!strcasecmp(Name, "GotoxLong")) GotoxLong = atoi(Value); -+ else if (!strcasecmp(Name, "GotoxPrevSource")) GotoxPrevSource = atoi(Value); -+#endif /* GOTOX */ - else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value); - else if (!strcasecmp(Name, "TimeSource")) TimeSource = cSource::FromString(Value); - else if (!strcasecmp(Name, "TimeTransponder")) TimeTransponder = atoi(Value); -@@ -873,6 +890,16 @@ bool cSetup::Save(void) - Store("LnbFrequLo", LnbFrequLo); - Store("LnbFrequHi", LnbFrequHi); - Store("DiSEqC", DiSEqC); -+#ifdef USE_GOTOX -+ Store("UseGotox", UseGotox); -+ Store("GotoxSpeed", GotoxSpeed); -+ Store("GotoxRepeat", GotoxRepeat); -+ Store("GotoxSN", GotoxSN); -+ Store("GotoxLat", GotoxLat); -+ Store("GotoxEW", GotoxEW); -+ Store("GotoxLong", GotoxLong); -+ Store("GotoxPrevSource", GotoxPrevSource); -+#endif /* GOTOX */ - Store("SetSystemTime", SetSystemTime); - Store("TimeSource", cSource::ToString(TimeSource)); - Store("TimeTransponder", TimeTransponder); -diff -ruNp vdr-1.7.7-extensions/config.h vdr-1.7.7-ext-gotox/config.h ---- vdr-1.7.7-extensions/config.h 2009-05-04 21:24:29.000000000 +0200 -+++ vdr-1.7.7-ext-gotox/config.h 2009-05-04 21:30:15.000000000 +0200 -@@ -301,6 +301,16 @@ public: - int LnbFrequLo; - int LnbFrequHi; - int DiSEqC; -+#ifdef USE_GOTOX -+ int GotoxRepeat; -+ int GotoxSN; -+ int GotoxEW; -+ int GotoxSpeed; -+ int GotoxLat; -+ int GotoxLong; -+ int UseGotox; -+ int GotoxPrevSource; -+#endif /* GOTOX */ - int SetSystemTime; - int TimeSource; - int TimeTransponder; -diff -ruNp vdr-1.7.7-extensions/diseqc.c vdr-1.7.7-ext-gotox/diseqc.c ---- vdr-1.7.7-extensions/diseqc.c 2008-02-10 15:09:27.000000000 +0100 -+++ vdr-1.7.7-ext-gotox/diseqc.c 2009-05-04 21:30:15.000000000 +0200 -@@ -114,6 +114,9 @@ cDiseqc::eDiseqcActions cDiseqc::Execute - case 'V': return daVoltage18; - case 'A': return daMiniA; - case 'B': return daMiniB; -+#ifdef USE_GOTOX -+ case 'G': return daGotoX; -+#endif /* GOTOX */ - case 'W': *CurrentAction = Wait(*CurrentAction); break; - case '[': *CurrentAction = Codes(*CurrentAction); return *CurrentAction ? daCodes : daNone; - default: return daNone; -diff -ruNp vdr-1.7.7-extensions/diseqc.h vdr-1.7.7-ext-gotox/diseqc.h ---- vdr-1.7.7-extensions/diseqc.h 2002-12-07 14:54:02.000000000 +0100 -+++ vdr-1.7.7-ext-gotox/diseqc.h 2009-05-04 21:30:15.000000000 +0200 -@@ -22,6 +22,9 @@ public: - daVoltage18, - daMiniA, - daMiniB, -+#ifdef USE_GOTOX -+ daGotoX, -+#endif /* GOTOX */ - daCodes, - }; - enum { MaxDiseqcCodes = 6 }; -diff -ruNp vdr-1.7.7-extensions/dvbdevice.c vdr-1.7.7-ext-gotox/dvbdevice.c ---- vdr-1.7.7-extensions/dvbdevice.c 2009-05-04 21:24:29.000000000 +0200 -+++ vdr-1.7.7-ext-gotox/dvbdevice.c 2009-05-04 21:30:15.000000000 +0200 -@@ -17,6 +17,9 @@ - #include - #include - #include -+#ifdef USE_GOTOX -+#include -+#endif /* GOTOX */ - #include "channels.h" - #include "diseqc.h" - #include "dvbci.h" -@@ -214,6 +217,87 @@ static unsigned int FrequencyToHz(unsign - return f; - } - -+#ifdef USE_GOTOX -+void HandleGotox(int fd_frontend, int new_source) -+{ -+ int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E }; -+ int satlong; -+ int satprev; -+ float waitseconds = 0; -+ -+ if (Setup.UseGotox == 0) -+ return; -+ -+ // Check if zapped into new source position? -+ if (new_source != Setup.GotoxPrevSource) { -+ satlong = (new_source & ~0xC800); -+ satprev = (Setup.GotoxPrevSource & ~0xC800); -+ if ((new_source & 0xC000) != 0x8000) -+ return; // Fail -+ if (new_source & 0x0800) -+ satlong = satlong * (-1); -+ if (Setup.GotoxPrevSource & 0x0800) -+ satprev = satprev * (-1); -+ if (Setup.GotoxSpeed > 0) { -+ waitseconds = fabs(satlong-satprev)/(float)(Setup.GotoxSpeed); -+ if (waitseconds < 0.0) waitseconds = 0.0; // Should not happen but ... -+ if (waitseconds > 60.0) waitseconds = 60.0; // Limit wait time to 60s -+ } -+ int Long = Setup.GotoxEW ? -Setup.GotoxLong : Setup.GotoxLong; -+ int Lat = Setup.GotoxSN ? -Setup.GotoxLat : Setup.GotoxLat; -+ double azimuth = M_PI+atan(tan((satlong-Long)*M_PI/1800)/sin(Lat*M_PI/1800)); -+ double x = acos(cos((satlong-Long)*M_PI/1800)*cos(Lat*M_PI/1800)); -+ double elevation = atan((cos(x)-0.1513)/sin(x)); -+ double SatHourangle = 180+atan((-cos(elevation)*sin(azimuth))/(sin(elevation)*cos(Lat*M_PI/1800) -+ -cos(elevation)*sin(Lat*M_PI/1800)*cos(azimuth)))*180/M_PI; -+ int tmp = (int)(fabs(180-SatHourangle)*10); -+ tmp = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ]; -+ int p2 = (tmp%0x0100); -+ int p1 = (tmp/0x0100); -+ if (SatHourangle < 180) -+ p1 |= 0xe0; -+ else -+ p1 |= 0xd0; -+ -+ dsyslog("DiSEqC GotoX %d (%d) -> %d (%d), wait time %4.1fs", -+ satprev, Setup.GotoxPrevSource, satlong, new_source, waitseconds); -+ -+#if 1 -+ // Set high LNB voltage and tone off, then wait > 15ms -+ CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); -+ CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); -+ usleep(20000); -+ -+ // Send 1st GotoX command, then wait > 15ms -+ uchar gotox_bytes[5] = { 0xe0, 0x31, 0x6e, p1, p2}; -+ struct dvb_diseqc_master_cmd gotox_cmd; -+ memcpy(gotox_cmd.msg, gotox_bytes, 5); -+ gotox_cmd.msg_len = 5; -+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd)); -+ usleep(20000); -+ -+ // Send repeated GotoX command, then wait > 15ms -+ if (Setup.GotoxRepeat) { -+ gotox_bytes[0] = 0xe1; -+ memcpy(gotox_cmd.msg, gotox_bytes, 5); -+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd)); -+ usleep(20000); -+ } -+ -+ // Wait for dish movement -+ while (waitseconds > 0.0) { -+ usleep(100000); // 100ms -+ waitseconds = waitseconds - 100e-3; -+ } -+ -+#endif -+ -+ Setup.GotoxPrevSource = new_source; -+ dsyslog("DiSEqC GotoX done."); -+ } -+} -+#endif /* GOTOX */ -+ - bool cDvbTuner::SetFrontend(void) - { - #define MAXFRONTENDCMDS 16 -@@ -252,6 +336,9 @@ bool cDvbTuner::SetFrontend(void) - case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break; - case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break; - case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; -+#ifdef USE_GOTOX -+ case cDiseqc::daGotoX: HandleGotox(fd_frontend, channel.Source()); break; -+#endif /* GOTOX */ - case cDiseqc::daCodes: { - int n = 0; - uchar *codes = diseqc->Codes(n); -@@ -278,6 +365,11 @@ bool cDvbTuner::SetFrontend(void) - } - } - else { -+#ifdef USE_GOTOX -+ // Send GotoX DiSEqC command if activated in vdr setup. Then wait with high LNB voltage -+ // estimated time for dish movement -+ HandleGotox(fd_frontend, channel.Source()); -+#endif /* GOTOX */ - int tone = SEC_TONE_OFF; - if (frequency < (unsigned int)Setup.LnbSLOF) { - frequency -= Setup.LnbFrequLo; -diff -ruNp vdr-1.7.7-extensions/Make.config.template vdr-1.7.7-ext-gotox/Make.config.template ---- vdr-1.7.7-extensions/Make.config.template 2009-05-04 21:24:29.000000000 +0200 -+++ vdr-1.7.7-ext-gotox/Make.config.template 2009-05-04 21:30:15.000000000 +0200 -@@ -67,6 +67,7 @@ DOLBYINREC = 1 - #DVLRECSCRIPTADDON = 1 - #DVLVIDPREFER = 1 - #EM84XX = 1 -+#GOTOX = 1 - #GRAPHTFT = 1 - #HARDLINKCUTTER = 1 - #JUMPPLAY = 1 -@@ -173,6 +174,10 @@ ifdef EM84XX - DEFINES += -DUSE_EM84XX - endif - -+ifdef GOTOX -+DEFINES += -DUSE_GOTOX -+endif -+ - ifdef GRAPHTFT - DEFINES += -DUSE_GRAPHTFT - endif -diff -ruNp vdr-1.7.7-extensions/menu.c vdr-1.7.7-ext-gotox/menu.c ---- vdr-1.7.7-extensions/menu.c 2009-05-04 21:24:29.000000000 +0200 -+++ vdr-1.7.7-ext-gotox/menu.c 2009-05-04 21:30:15.000000000 +0200 -@@ -3447,6 +3447,15 @@ void cMenuSetupLNB::Setup(void) - Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi)); - } - -+#ifdef USE_GOTOX -+ Add(new cMenuEditBoolItem(tr("Setup.LNB$Use GotoX dish positioning"), &data.UseGotox)); -+ if (data.UseGotox) { -+ Add(new cMenuEditBoolItem(tr("Setup.LNB$Repeat GotoX commands"), &data.GotoxRepeat)); -+ Add(new cMenuEditIntpItem(tr("Setup.LNB$Latitude"), &data.GotoxLat, 0, 900, &data.GotoxSN, tr("North"), tr("South"))); -+ Add(new cMenuEditIntpItem(tr("Setup.LNB$Longitude"), &data.GotoxLong, 0, 1800, &data.GotoxEW, tr("West"), tr("East"))); -+ Add(new cMenuEditIntdItem(tr("Setup.LNB$Rotor speed (deg/s)"), &data.GotoxSpeed, 1, 100)); -+ } -+#endif /* GOTOX */ - SetCurrent(Get(current)); - Display(); - } -@@ -3454,6 +3463,9 @@ void cMenuSetupLNB::Setup(void) - eOSState cMenuSetupLNB::ProcessKey(eKeys Key) - { - int oldDiSEqC = data.DiSEqC; -+#ifdef USE_GOTOX -+ int oldUseGotox = data.UseGotox; -+#endif /* GOTOX */ - eOSState state = cMenuSetupBase::ProcessKey(Key); - - #ifdef USE_LNBSHARE -@@ -3462,6 +3474,12 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys - - if (Key != kNone && data.DiSEqC != oldDiSEqC) - Setup(); -+ -+#ifdef USE_GOTOX -+ if (Key != kNone && data.UseGotox != oldUseGotox) -+ Setup(); -+#endif /* GOTOX */ -+ - return state; - } - -diff -ruNp vdr-1.7.7-extensions/menuitems.c vdr-1.7.7-ext-gotox/menuitems.c ---- vdr-1.7.7-extensions/menuitems.c 2009-05-04 21:24:29.000000000 +0200 -+++ vdr-1.7.7-ext-gotox/menuitems.c 2009-05-04 21:30:15.000000000 +0200 -@@ -1286,3 +1286,119 @@ void cMenuSetupPage::SetupStore(const ch - if (plugin) - plugin->SetupStore(Name, Value); - } -+ -+#ifdef USE_GOTOX -+// cMenuEditIntpItem & cMenuEditIntdItem for GotoX function -+ -+void cMenuEditIntpItem::Set(void) -+{ -+ char buf[16]; -+ snprintf(buf, sizeof(buf), "%d.%d %s", *value/10, *value % 10, *value2 ? trueString : falseString); -+ SetValue(buf); -+} -+ -+void cMenuEditIntdItem::Set(void) -+{ -+ char buf[16]; -+ snprintf(buf, sizeof(buf), "%d.%d", *value/10, *value % 10); -+ SetValue(buf); -+} -+ -+ -+cMenuEditIntpItem::cMenuEditIntpItem(const char *Name, int *Value, int Min, int Max,int *Value2, const char *FalseString, const char *TrueString):cMenuEditIntItem(Name, Value, Min, Max) -+{ -+ value = Value; -+ value2= Value2; -+ trueString = TrueString; -+ falseString = FalseString; -+ min = Min; -+ max = Max; -+ Set(); -+} -+ -+cMenuEditIntdItem::cMenuEditIntdItem(const char *Name, int *Value, int Min, int Max):cMenuEditIntItem(Name, Value, Min, Max) -+{ -+ value = Value; -+ min = Min; -+ max = Max; -+ Set(); -+} -+ -+eOSState cMenuEditIntpItem::ProcessKey(eKeys Key) -+{ -+ eOSState state = cMenuEditItem::ProcessKey(Key); -+ if (state == osUnknown) { -+ int newValue = *value; -+ int newValue2 = *value2; -+ Key = NORMALKEY(Key); -+ switch (Key) { -+ case kNone : break; -+ case k0...k9: -+ if (fresh) { -+ *value = 0; -+ fresh = false; -+ } -+ newValue = *value * 10 + (Key - k0); -+ break; -+ case kLeft : -+ newValue2 = 0; -+ fresh = true; -+ break; -+ case kRight : -+ newValue2 = 1; -+ fresh = true; -+ break; -+ default : -+ if (*value < min) { *value = min; Set(); } -+ if (*value > max) { *value = max; Set(); } -+ return state; -+ } -+ -+ if ((!fresh || min <= newValue) && newValue <= max) { -+ *value = newValue; -+ *value2 = newValue2; -+ Set(); -+ } -+ state = osContinue; -+ } -+ return state; -+} -+ -+eOSState cMenuEditIntdItem::ProcessKey(eKeys Key) -+{ -+ eOSState state = cMenuEditItem::ProcessKey(Key); -+ if (state == osUnknown) { -+ int newValue = *value; -+ Key = NORMALKEY(Key); -+ switch (Key) { -+ case kNone : break; -+ case k0...k9: -+ if (fresh) { -+ *value = 0; -+ fresh = false; -+ } -+ newValue = *value * 10 + (Key - k0); -+ break; -+ case kLeft : -+ newValue = *value - 1; -+ fresh = true; -+ break; -+ case kRight : -+ newValue = *value + 1; -+ fresh = true; -+ break; -+ default : -+ if (*value < min) { *value = min; Set(); } -+ if (*value > max) { *value = max; Set(); } -+ return state; -+ } -+ -+ if ((!fresh || min <= newValue) && newValue <= max) { -+ *value = newValue; -+ Set(); -+ } -+ state = osContinue; -+ } -+ return state; -+} -+#endif /* GOTOX */ -diff -ruNp vdr-1.7.7-extensions/menuitems.h vdr-1.7.7-ext-gotox/menuitems.h ---- vdr-1.7.7-extensions/menuitems.h 2009-05-04 21:24:29.000000000 +0200 -+++ vdr-1.7.7-ext-gotox/menuitems.h 2009-05-04 21:30:15.000000000 +0200 -@@ -241,4 +241,24 @@ public: - #endif /* GRAPHTFT */ - }; - -+#ifdef USE_GOTOX -+class cMenuEditIntpItem : public cMenuEditIntItem { -+protected: -+ virtual void Set(void); -+ const char *falseString, *trueString; -+ int *value2; -+public: -+ cMenuEditIntpItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX, int *Value2=0, const char *FalseString = "", const char *TrueSting = NULL); -+ virtual eOSState ProcessKey(eKeys Key); -+}; -+ -+class cMenuEditIntdItem : public cMenuEditIntItem { -+protected: -+ virtual void Set(void); -+public: -+ cMenuEditIntdItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX); -+ virtual eOSState ProcessKey(eKeys Key); -+}; -+#endif /* GOTOX */ -+ - #endif //__MENUITEMS_H -diff -ruNp vdr-1.7.7-extensions/vdr.c vdr-1.7.7-ext-gotox/vdr.c ---- vdr-1.7.7-extensions/vdr.c 2009-05-04 21:24:29.000000000 +0200 -+++ vdr-1.7.7-ext-gotox/vdr.c 2009-05-04 21:30:15.000000000 +0200 -@@ -589,6 +589,10 @@ int main(int argc, char *argv[]) - printf(" EM84XX\n"); - #endif /* EM84XX */ - -+#ifdef USE_GOTOX -+ printf(" GOTOX\n"); -+#endif /* GOTOX */ -+ - #ifdef USE_GRAPHTFT - printf(" GRAPHTFT\n"); - #endif /* GRAPHTFT */