diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2004-11-01 18:00:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2004-11-01 18:00:00 +0100 |
commit | 3038be2a6a849e726d6fe99236d5dc61b679198f (patch) | |
tree | 9901f3dd92799de71853ed18faf8665f17e5cc79 | |
parent | 6f93a5f7819b3c7030a5b199e502bedd4eb7844c (diff) | |
download | vdr-patch-lnbsharing-3038be2a6a849e726d6fe99236d5dc61b679198f.tar.gz vdr-patch-lnbsharing-3038be2a6a849e726d6fe99236d5dc61b679198f.tar.bz2 |
Version 1.3.15vdr-1.3.15
- Fixed some typos in the Makefile's 'font' target (thanks to Uwe Hanke).
- Added more checks and polling when getting frontend events (based on a patch
from Werner Fink).
- No longer explicitly waiting for a tuner lock when switching channels
(apparently setting "live" PIDs before the tuner is locked doesn't hurt).
Moved the wait into cDevice::AttachReceiver() instead.
- Immediately displaying the new channel info when switching channel groups.
- Moved the main program loop variables further up to allow compilation with
older compiler versions (thanks to Marco Schlüßler for reporting this one).
- Now calling pthread_cond_broadcast() in the destructor of cCondWait and
cCondVar to make sure any sleepers will wake up (suggested by Werner Fink).
Also using pthread_cond_broadcast() instead of pthread_cond_signal() in
cCondWait, in case there is more than one sleeper.
- Making sure that timers and channels are only saved together, in a consistent
manner (thanks to Mirko Dölle for reporting a problem with inconsistent
channel and timer lists).
- Now handling the channel name, short name and provider separately. cChannel
therefore has two new functions, ShortName() and Provider(). ShortName()
can be used to display a short version of the name (in case such a version
is available). The optional boolean parameter of ShortName() can be set to
true to make it return the name, if no short name is available.
The sequence of 'name' and 'short name' in the channels.conf file has been
swapped (see man vdr(5)).
- Added the 'portal name' to cChannels (thanks to Marco Schlüßler).
- Fixed handling key codes that start with 0x1B in the KBD remote control code.
- Now using qsort() to sort cListBase lists. For this, the virtual function
cListObject::operator<() has been replaced with cListObject::Compare().
Plugins that implement derived cListObject classes may need to adjust their
code.
- The "Channels" menu can now be sorted "by number" (default), "by name" and
"by provider". While in the "Channels" menu, pressing the '0' key switches
through these modes.
- Fixed the buffer size in cRecording::SortName().
- Now displaying the name of the remote control for which the keys are being
learned inside the menu to avoid overwriting the date/time in the 'classic'
skin (thanks to Oliver Endriss for reporting this one).
-rw-r--r-- | CONTRIBUTORS | 10 | ||||
-rw-r--r-- | HISTORY | 39 | ||||
-rw-r--r-- | MANUAL | 4 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | channels.c | 83 | ||||
-rw-r--r-- | channels.conf | 36 | ||||
-rw-r--r-- | channels.h | 16 | ||||
-rw-r--r-- | config.c | 12 | ||||
-rw-r--r-- | config.h | 8 | ||||
-rw-r--r-- | device.c | 9 | ||||
-rw-r--r-- | device.h | 6 | ||||
-rw-r--r-- | dvbdevice.c | 55 | ||||
-rw-r--r-- | dvbdevice.h | 4 | ||||
-rw-r--r-- | eit.c | 12 | ||||
-rw-r--r-- | eitscan.c | 19 | ||||
-rw-r--r-- | epg.c | 6 | ||||
-rw-r--r-- | epg.h | 4 | ||||
-rw-r--r-- | i18n.c | 40 | ||||
-rw-r--r-- | interface.c | 44 | ||||
-rw-r--r-- | menu.c | 103 | ||||
-rw-r--r-- | recording.c | 12 | ||||
-rw-r--r-- | recording.h | 10 | ||||
-rw-r--r-- | remote.c | 5 | ||||
-rw-r--r-- | sdt.c | 26 | ||||
-rw-r--r-- | svdrp.c | 10 | ||||
-rw-r--r-- | thread.c | 6 | ||||
-rw-r--r-- | timers.c | 40 | ||||
-rw-r--r-- | timers.h | 29 | ||||
-rw-r--r-- | tools.c | 35 | ||||
-rw-r--r-- | tools.h | 6 | ||||
-rw-r--r-- | vdr.5 | 14 | ||||
-rw-r--r-- | vdr.c | 38 |
32 files changed, 485 insertions, 264 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 86f1e28..b869c6b 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -258,6 +258,7 @@ Werner Fink <werner@suse.de> AC3 replay for changing thread handling to make it work with NPTL ("Native Posix Thread Library") for suggesting to replace usleep() calls with a pthread_cond_timedwait() based wait + for suggesting to add more checks and polling when getting frontend events Rolf Hakenes <hakenes@hippomi.de> for providing 'libdtv' and adapting the EIT mechanisms to it @@ -380,6 +381,7 @@ Mirko Dölle <mdoelle@linux-user.de> for reporting a bug when a timer records over midnight of a day that had a change in Daylight Saving Time for suggesting to avoid the external 'find' command to scan the video directory + for reporting a problem with inconsistent channel and timer lists Michael Rakowski <mrak@gmx.de> for translating OSD texts to the Polish language @@ -532,6 +534,8 @@ Oliver Endriss <o.endriss@gmx.de> for reporting some missing cStatus::MsgOsdTextItem() calls for reporting a missing "Editing process finished" message with skins for adding a sample setup for 'DisiCon-4 Single Cable Network' to 'diseqc.conf' + for reporting a problem with the name of the remote control for which the keys are + being learned overwriting the date/time in the 'classic' skin Reinhard Walter Buchner <rw.buchner@freenet.de> for adding some satellites to 'sources.conf' @@ -1064,6 +1068,9 @@ Marco Schlüßler <marco@lordzodiac.de> should fail and all PIDs added so far should be deleted for fixing attaching a cPlayer to a cDevice, so that 'Operation not permited' errors don't occur any more + for reporting a problem with initialization of the main program loop variables + with older compiler versions + for adding the 'portal name' to cChannels Jürgen Schmitz <j.schmitz@web.de> for reporting a bug in displaying the current channel when switching via the SVDRP @@ -1122,3 +1129,6 @@ Lucian Muresan <lucianm@users.sourceforge.net> Mattias Grönlund <Mattias@Gronlund.net> for pointing out a missing cleanup at program exit in case there is a problem with a plugin + +Uwe Hanke <uhanke@gmx.de> + for fixing some typos in the Makefile's 'font' target @@ -3077,3 +3077,42 @@ Video Disk Recorder Revision History into account if the event has been "seen" within the past 30 seconds. This avoids shortly seeing the wrong events in the channel display when switching to a channel that hasn't been tuned to in a while. + +2004-11-01: Version 1.3.15 + +- Fixed some typos in the Makefile's 'font' target (thanks to Uwe Hanke). +- Added more checks and polling when getting frontend events (based on a patch + from Werner Fink). +- No longer explicitly waiting for a tuner lock when switching channels + (apparently setting "live" PIDs before the tuner is locked doesn't hurt). + Moved the wait into cDevice::AttachReceiver() instead. +- Immediately displaying the new channel info when switching channel groups. +- Moved the main program loop variables further up to allow compilation with + older compiler versions (thanks to Marco Schlüßler for reporting this one). +- Now calling pthread_cond_broadcast() in the desctructor of cCondWait and + cCondVar to make sure any sleepers will wake up (suggested by Werner Fink). + Also using pthread_cond_broadcast() instead of pthread_cond_signal() in + cCondWait, in case there is more than one sleeper. +- Making sure that timers and channels are only saved together, in a consistent + manner (thanks to Mirko Dölle for reporting a problem with inconsistent + channel and timer lists). +- Now handling the channel name, short name and provider separately. cChannel + therefore has two new functions, ShortName() and Provider(). ShortName() + can be used to display a short version of the name (in case such a version + is available). The optional boolean parameter of ShortName() can be set to + true to make it return the name, if no short name is available. + The sequence of 'name' and 'short name' in the channels.conf file has been + swapped (see man vdr(5)). +- Added the 'portal name' to cChannels (thanks to Marco Schlüßler). +- Fixed handling key codes that start with 0x1B in the KBD remote control code. +- Now using qsort() to sort cListBase lists. For this, the virtual function + cListObject::operator<() has been replaced with cListObject::Compare(). + Plugins that implement derived cListObject classes may need to adjust their + code. +- The "Channels" menu can now be sorted "by number" (default), "by name" and + "by provider". While in the "Channels" menu, pressing the '0' key switches + through these modes. +- Fixed the buffer size in cRecording::SortName(). +- Now displaying the name of the remote control for which the keys are being + learned inside the menu to avoid overwriting the date/time in the 'classic' + skin (thanks to Oliver Endriss for reporting this one). @@ -24,7 +24,7 @@ Version 1.2 Green - Language New New Ins/Ovr Rewind Skip -60s Yellow - Pause live Delete Delete Delete Delete Skip +60s Blue - Stop/Resume Mark On/Off(1) - Summary Stop - 0..9 Ch select - - - Numeric inp. Exec cmd(2) Editing + 0..9 Ch select - Sort(3) - Numeric inp. Exec cmd(2) Editing In a numerical input field (like the response to a CAM enquiry) the keys 0..9 are used to enter the data, and the Left key can be used to delete the last @@ -71,6 +71,8 @@ Version 1.2 has been enabled in the "Setup" menu. Otherwise the Blue button is used to "mark" a timer for moving. (2) See "Processing Recordings" below. + (3) In the "Channels" menu the '0' key switches the sort mode through "by number", + "by name" and "by provider". * Navigating through the On Screen Menus @@ -4,7 +4,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 1.68 2004/10/16 11:58:14 kls Exp $ +# $Id: Makefile 1.69 2004/10/30 11:51:09 kls Exp $ .DELETE_ON_ERROR: @@ -80,9 +80,9 @@ all: vdr font: genfontfile\ fontfix.c fontosd.c fontsml.c\ fontfix-iso8859-2.c fontosd-iso8859-2.c fontsml-iso8859-2.c\ - fontfix_iso8859_5.c fontosd_iso8859_5.c fontsml_iso8859_5.c\ - fontfix_iso8859_7.c fontosd_iso8859_7.c fontsml_iso8859_7.c\ - fontfix_iso8859_15.c fontosd_iso8859_15.c fontsml_iso8859_15.c + fontfix_iso8859-5.c fontosd_iso8859-5.c fontsml_iso8859-5.c\ + fontfix_iso8859-7.c fontosd_iso8859-7.c fontsml_iso8859-7.c\ + fontfix_iso8859-15.c fontosd_iso8859-15.c fontsml_iso8859-15.c @echo "font files created." # Implicit rules: @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.c 1.28 2004/10/22 14:11:07 kls Exp $ + * $Id: channels.c 1.30 2004/10/31 12:54:06 kls Exp $ */ #include "channels.h" @@ -166,6 +166,10 @@ char *cChannel::buffer = NULL; cChannel::cChannel(void) { + name = strdup(""); + shortName = strdup(""); + provider = strdup(""); + portalName = strdup(""); memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__); inversion = INVERSION_AUTO; bandwidth = BANDWIDTH_AUTO; @@ -182,8 +186,11 @@ cChannel::cChannel(void) cChannel::cChannel(const cChannel &Channel) { + name = strdup(""); + shortName = strdup(""); + provider = strdup(""); + portalName = strdup(""); *this = Channel; - *name = 0; vpid = 0; ppid = 0; apids[0] = 0; @@ -219,10 +226,18 @@ cChannel::~cChannel() } } } + free(name); + free(shortName); + free(provider); + free(portalName); } cChannel& cChannel::operator= (const cChannel &Channel) { + name = strcpyrealloc(name, Channel.name); + shortName = strcpyrealloc(shortName, Channel.shortName); + provider = strcpyrealloc(provider, Channel.provider); + portalName = strcpyrealloc(portalName, Channel.portalName); memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__); return *this; } @@ -341,15 +356,29 @@ void cChannel::SetId(int Nid, int Tid, int Sid, int Rid) } } -void cChannel::SetName(const char *Name) +void cChannel::SetName(const char *Name, const char *ShortName, const char *Provider) { if (!isempty(Name) && strcmp(name, Name) != 0) { if (Number()) { - dsyslog("changing name of channel %d from '%s' to '%s'", Number(), name, Name); + dsyslog("changing name of channel %d from '%s,%s;%s' to '%s,%s;%s'", Number(), name, shortName, provider, Name, ShortName, Provider); modification |= CHANNELMOD_NAME; Channels.SetModified(); } - strn0cpy(name, Name, MaxChannelName); + name = strcpyrealloc(name, Name); + shortName = strcpyrealloc(shortName, ShortName); + provider = strcpyrealloc(provider, Provider); + } +} + +void cChannel::SetPortalName(const char *PortalName) +{ + if (!isempty(PortalName) && strcmp(portalName, PortalName) != 0) { + if (Number()) { + dsyslog("changing portal name of channel %d from '%s' to '%s'", Number(), portalName, PortalName); + modification |= CHANNELMOD_NAME; + Channels.SetModified(); + } + portalName = strcpyrealloc(portalName, PortalName); } } @@ -565,16 +594,21 @@ bool cChannel::StringToParameters(const char *s) const char *cChannel::ToText(const cChannel *Channel) { - char buf[MaxChannelName * 2]; - const char *s = Channel->name; - if (strchr(s, ':')) - s = strreplace(strcpy(buf, s), ':', '|'); + char FullName[strlen(Channel->name) + 1 + strlen(Channel->shortName) + 1 + strlen(Channel->provider) + 1 + 10]; // +10: paranoia + char *q = FullName; + q += sprintf(q, "%s", Channel->name); + if (!isempty(Channel->shortName)) + q += sprintf(q, ",%s", Channel->shortName); + if (!isempty(Channel->provider)) + q += sprintf(q, ";%s", Channel->provider); + *q = 0; + strreplace(FullName, ':', '|'); free(buffer); if (Channel->groupSep) { if (Channel->number) - asprintf(&buffer, ":@%d %s\n", Channel->number, s); + asprintf(&buffer, ":@%d %s\n", Channel->number, FullName); else - asprintf(&buffer, ":%s\n", s); + asprintf(&buffer, ":%s\n", FullName); } else { char vpidbuf[32]; @@ -595,7 +629,7 @@ const char *cChannel::ToText(const cChannel *Channel) q = caidbuf; q += IntArrayToString(q, Channel->caids, 16); *q = 0; - asprintf(&buffer, "%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", s, Channel->frequency, Channel->ParametersToString(), cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid); + asprintf(&buffer, "%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, Channel->ParametersToString(), cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid); } return buffer; } @@ -619,7 +653,8 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID) s = p; } } - strn0cpy(name, skipspace(s), MaxChannelName); + name = strcpyrealloc(name, skipspace(s)); + strreplace(name, '|', ':'); } else { groupSep = false; @@ -717,7 +752,20 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID) caids[NumCaIds] = 0; } } - strn0cpy(name, namebuf, MaxChannelName); + strreplace(namebuf, '|', ':'); + + char *p = strchr(namebuf, ';'); + if (p) { + *p++ = 0; + provider = strcpyrealloc(provider, p); + } + p = strchr(namebuf, ','); + if (p) { + *p++ = 0; + shortName = strcpyrealloc(shortName, p); + } + name = strcpyrealloc(name, namebuf); + free(parambuf); free(sourcebuf); free(vpidbuf); @@ -736,7 +784,6 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID) else return false; } - strreplace(name, '|', ':'); return ok; } @@ -878,13 +925,13 @@ int cChannels::Modified(void) return Result; } -cChannel *cChannels::NewChannel(const cChannel *Transponder, const char *Name, int Nid, int Tid, int Sid, int Rid) +cChannel *cChannels::NewChannel(const cChannel *Transponder, const char *Name, const char *ShortName, const char *Provider, int Nid, int Tid, int Sid, int Rid) { if (Transponder) { - dsyslog("creating new channel '%s' on %s transponder %d with id %d-%d-%d-%d", Name, cSource::ToString(Transponder->Source()), Transponder->Transponder(), Nid, Tid, Sid, Rid); + dsyslog("creating new channel '%s,%s;%s' on %s transponder %d with id %d-%d-%d-%d", Name, ShortName, Provider, cSource::ToString(Transponder->Source()), Transponder->Transponder(), Nid, Tid, Sid, Rid); cChannel *NewChannel = new cChannel(*Transponder); NewChannel->SetId(Nid, Tid, Sid, Rid); - NewChannel->SetName(Name); + NewChannel->SetName(Name, ShortName, Provider); Add(NewChannel); ReNumber(); return NewChannel; diff --git a/channels.conf b/channels.conf index d7f7db0..acb25d5 100644 --- a/channels.conf +++ b/channels.conf @@ -1,4 +1,4 @@ -RTL,RTL Television;RTL World:12187:hC34:S19.2E:27500:163:104=deu:105:0:12003:1:1089:0 +RTL Television,RTL;RTL World:12187:hC34:S19.2E:27500:163:104=deu:105:0:12003:1:1089:0 SAT.1;ProSiebenSat.1:12480:vC34:S19.2E:27500:1791:1792=deu;1795=deu:34:0:46:133:33:0 ProSieben;ProSiebenSat.1:12480:vC34:S19.2E:27500:255:256=deu;257=deu:32:0:898:133:33:0 RTL2;RTL World:12187:hC34:S19.2E:27500:166:128=deu:68:0:12020:1:1089:0 @@ -19,10 +19,10 @@ ORF 1;ORF:12692:hC56:S19.2E:22000:160:161=deu;163=deu:165:1762,D05,1702,1801:130 ORF 2;ORF:12692:hC56:S19.2E:22000:500:501=deu;503=deu:505:1762,D05,1702,1801:13002:1:1117:0 ZDFinfokanal;ZDFvision:11953:hC34:S19.2E:27500:610:620=deu:130:0:28011:1:1079:0 CNN Int.;CNN:11778:vC34:S19.2E:27500:165:100=eng:47:0:28522:1:1068:0 -S RTL,Super RTL;RTL World:12187:hC34:S19.2E:27500:165:120=deu:65:0:12040:1:1089:0 +Super RTL,S RTL;RTL World:12187:hC34:S19.2E:27500:165:120=deu:65:0:12040:1:1089:0 VOX;RTL World:12187:hC34:S19.2E:27500:167:136=deu:71:0:12060:1:1089:0 KABEL1;ProSiebenSat.1:12480:vC34:S19.2E:27500:511:512=deu:33:0:899:133:33:0 -NEUN LIVE,NEUN LIVE Television;BetaDigital:12480:vC34:S19.2E:27500:767:768=deu:35:0:897:133:33:0 +NEUN LIVE Television,NEUN LIVE;BetaDigital:12480:vC34:S19.2E:27500:767:768=deu:35:0:897:133:33:0 DSF;BetaDigital:12480:vC34:S19.2E:27500:1023:1024=deu:0:0:900:133:33:0 HSE24;BetaDigital:12480:vC34:S19.2E:27500:1279:1280=deu:37:0:40:133:33:0 Bloomberg TV Germany;Bloomberg:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:1108:0 @@ -44,23 +44,23 @@ ZDFdokukanal;ZDFvision:11953:hC34:S19.2E:27500:660:670=deu:130:0:28014:1:1079:0 MDR FERNSEHEN;ARD:12109:hC34:S19.2E:27500:401:402=deu:404:0:28204:1:1073:0 rbb Berlin;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0 :Premiere World -START,PREMIERE START;PREMIERE:11797:hC34:S19.2E:27500:255:256=deu:32:1702,1801,1722:8:133:2:0 -PREM 1,PREMIERE 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu;515=deu:32:1702,1801,1722:10:133:2:0 -PREM 2,PREMIERE 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu;1795=deu:32:1702,1722,1801:11:133:2:0 -PREM 3,PREMIERE 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1801,1702:43:133:2:0 -PREM 4,PREMIERE 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu,769=deu:32:1801,1722,1702:9:133:2:0 -PREM 5,PREMIERE 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu:32:1722,1702,1801:29:133:2:0 -PREM 6,PREMIERE 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1722,1801:41:133:2:0 -PREM 7,PREMIERE 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1722,1702,1801:20:133:2:0 -DISNEY,DISNEY CHANNEL;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:0:1722,1702,1801:34:133:17:0 +PREMIERE START,START;PREMIERE:11797:hC34:S19.2E:27500:255:256=deu:32:1702,1801,1722:8:133:2:0 +PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1702,1801,1722:10:133:2:0 +PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1702,1722,1801:11:133:2:0 +PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1801,1702:43:133:2:0 +PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu,769=deu:32:1801,1722,1702:9:133:2:0 +PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:32:1722,1702,1801:29:133:2:0 +PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1722,1801:41:133:2:0 +PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1722,1702,1801:20:133:2:0 +DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:0:1722,1702,1801:34:133:17:0 :Premiere Direkt -DIREKT,PREMIERE DIREKT;PREMIERE:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0:0:18:133:4:0 +PREMIERE DIREKT,DIREKT;PREMIERE:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0:0:18:133:4:0 :PW Erotic -B-UHSE,BEATE-UHSE.TV;PREMIERE:12070:hC34:S19.2E:27500:1023:1024=deu:32:1801,1702,1722:21:133:1:0 -EROTIK,DIREKT EROTIK;PREMIERE:12031:hC34:S19.2E:27500:1279:0:0:1722,1702,1801:513:133:4:0 +BEATE-UHSE.TV,B-UHSE;PREMIERE:12070:hC34:S19.2E:27500:1023:1024=deu:32:1801,1702,1722:21:133:1:0 +DIREKT EROTIK,EROTIK;PREMIERE:12031:hC34:S19.2E:27500:1279:0:0:1722,1702,1801:513:133:4:0 :Sportsworld -Konferenz:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1801,1702,1722:17:133:3:0 -Formel 1:12031:hC34:S19.2E:27500:3839:3840=deu,3841=deu:32:1702,1722,1801:27:133:4:0 +PREMIERE SPORT 1,SPORT 1;PREMIERE:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1801,1702,1722:17:133:3:0 +PREMIERE SPORT 2,SPORT 2;PREMIERE:12031:hC34:S19.2E:27500:3839:3840=deu,3841=deu:32:1722,1702,1801:27:133:4:0 :Beta Digital N24;ProSiebenSat.1:12480:vC34:S19.2E:27500:2047:2048=deu:36:0:47:133:33:0 Liberty TV.com;Maastricht Multimedia:12610:vC56:S19.2E:22000:941:943=deu:0:0:12199:1:1112:0 @@ -94,7 +94,7 @@ Sky Mix;BSkyB:12226:hC23:S28.2E:27500:2314+2304:2315=eng,2316=NAR:2317:960,961:5 ITV2;BSkyB:10906:vC56:S28.2E:22000:2350:2351=eng,2352=eng:2353:960,961:10240:2:2054:0 Sci-Fi;BSkyB:12148:hC23:S28.2E:27500:2314+2304:2315=eng:2316:960,961:4905:2:2023:0 Paramount;BSkyB:12187:hC23:S28.2E:27500:2313+2304:2314=eng:2315:960,961:5904:2:2025:0 -Discovery;BSkyB:11875:hC23:S28.2E:27500:2304:2306=eng:2305:960,961:6201:2:2009:0 +Discovery;BSkyB:11875:hC23:S28.2E:27500:2304:2306=eng,2307=NAR:2305:960,961:6201:2:2009:0 Sky Movies 1;BSkyB:11836:hC23:S28.2E:27500:2310+2304:2311=eng,2312=NAR;2314=eng:2313:960,961:4303:2:2007:0 Sky Movies 2;BSkyB:11836:hC23:S28.2E:27500:2305+2304:2306=eng,2307=NAR;2309=eng:2308:960,961:4302:2:2007:0 Sky Movies 3;BSkyB:11836:hC23:S28.2E:27500:2315+2304:2316=eng,2317=NAR;2319=eng:2318:960,961:4403:2:2007:0 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.h 1.20 2004/10/22 14:09:47 kls Exp $ + * $Id: channels.h 1.22 2004/10/31 12:54:26 kls Exp $ */ #ifndef __CHANNELS_H @@ -89,9 +89,11 @@ class cChannel : public cListObject { private: static char *buffer; static const char *ToText(const cChannel *Channel); - enum { MaxChannelName = 64 }; // 63 chars + terminating 0! + char *name; + char *shortName; + char *provider; + char *portalName; int __BeginData__; - char name[MaxChannelName]; int frequency; // MHz int source; int srate; @@ -133,6 +135,9 @@ public: bool Parse(const char *s, bool AllowNonUniqueID = false); bool Save(FILE *f); const char *Name(void) const { return name; } + const char *ShortName(bool OrName = false) const { return (OrName && isempty(shortName)) ? name : shortName; } + const char *Provider(void) const { return provider; } + const char *PortalName(void) const { return portalName; } 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 @@ -171,7 +176,8 @@ public: 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); + void SetName(const char *Name, const char *ShortName, const char *Provider); + void SetPortalName(const char *PortalName); void SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][4], int *Dpids, char DLangs[][4], int Tpid); void SetCaIds(const int *CaIds); // list must be zero-terminated void SetCaDescriptors(int Level); @@ -205,7 +211,7 @@ public: ///< Returns 0 if no channels have been modified, 1 if an automatic ///< modification has been made, and 2 if the user has made a modification. ///< Calling this function resets the 'modified' flag to 0. - cChannel *NewChannel(const cChannel *Transponder, const char *Name, int Nid, int Tid, int Sid, int Rid = 0); + cChannel *NewChannel(const cChannel *Transponder, const char *Name, const char *ShortName, const char *Provider, int Nid, int Tid, int Sid, int Rid = 0); }; extern cChannels Channels; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.127 2004/05/16 12:43:55 kls Exp $ + * $Id: config.c 1.128 2004/10/31 16:17:39 kls Exp $ */ #include "config.h" @@ -193,19 +193,19 @@ cSetupLine::~cSetupLine() free(value); } -bool cSetupLine::operator< (const cListObject &ListObject) +int cSetupLine::Compare(const cListObject &ListObject) const { const cSetupLine *sl = (cSetupLine *)&ListObject; if (!plugin && !sl->plugin) - return strcasecmp(name, sl->name) < 0; + return strcasecmp(name, sl->name); if (!plugin) - return true; + return -1; if (!sl->plugin) - return false; + return 1; int result = strcasecmp(plugin, sl->plugin); if (result == 0) result = strcasecmp(name, sl->name); - return result < 0; + return result; } bool cSetupLine::Parse(char *s) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.201 2004/10/22 13:29:38 kls Exp $ + * $Id: config.h 1.203 2004/10/31 16:17:02 kls Exp $ */ #ifndef __CONFIG_H @@ -20,8 +20,8 @@ #include "i18n.h" #include "tools.h" -#define VDRVERSION "1.3.14" -#define VDRVERSNUM 10314 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.3.15" +#define VDRVERSNUM 10315 // Version * 10000 + Major * 100 + Minor #define MAXPRIORITY 99 #define MAXLIFETIME 99 @@ -185,7 +185,7 @@ public: cSetupLine(void); cSetupLine(const char *Name, const char *Value, const char *Plugin = NULL); virtual ~cSetupLine(); - virtual bool operator< (const cListObject &ListObject); + virtual int Compare(const cListObject &ListObject) const; const char *Plugin(void) { return plugin; } const char *Name(void) { return name; } const char *Value(void) { return value; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 1.61 2004/10/23 10:15:31 kls Exp $ + * $Id: device.c 1.62 2004/10/30 14:53:38 kls Exp $ */ #include "device.h" @@ -23,6 +23,7 @@ // The default priority for non-primary devices: #define DEFAULTPRIORITY -1 +#define TUNER_LOCK_TIMEOUT 5000 // ms int cDevice::numDevices = 0; int cDevice::useDevice = 0; @@ -467,7 +468,7 @@ bool cDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) return false; } -bool cDevice::HasLock(void) +bool cDevice::HasLock(int TimeoutMs) { return true; } @@ -765,6 +766,10 @@ bool cDevice::AttachReceiver(cReceiver *Receiver) return false; if (Receiver->device == this) return true; + if (!HasLock(TUNER_LOCK_TIMEOUT)) { + esyslog("ERROR: device %d has no lock, can't attach receiver!", CardIndex() + 1); + return false; + } for (int i = 0; i < MAXRECEIVERS; i++) { if (!receiver[i]) { for (int n = 0; n < MAXRECEIVEPIDS; n++) { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 1.45 2004/09/24 14:07:22 kls Exp $ + * $Id: device.h 1.46 2004/10/30 14:49:56 kls Exp $ */ #ifndef __DEVICE_H @@ -187,10 +187,12 @@ protected: public: static int CurrentChannel(void) { return primaryDevice ? currentChannel : 0; } ///< Returns the number of the current channel on the primary device. - virtual bool HasLock(void);//XXX PLUGINS.html + virtual bool HasLock(int TimeoutMs = 0);//XXX PLUGINS.html ///< Returns true if the device has a lock on the requested transponder. ///< Default is true, a specific device implementation may return false ///< to indicate that it is not ready yet. + ///< If TimeoutMs is not zero, waits for the given number of milliseconds + ///< before returning false. virtual bool HasProgramme(void); ///< Returns true if the device is currently showing any programme to ///< the user, either through replaying or live. diff --git a/dvbdevice.c b/dvbdevice.c index 3f38a0a..fb87ae4 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 1.100 2004/10/24 11:06:37 kls Exp $ + * $Id: dvbdevice.c 1.102 2004/10/30 14:53:30 kls Exp $ */ #include "dvbdevice.h" @@ -35,7 +35,6 @@ extern "C" { #define DO_REC_AND_PLAY_ON_PRIMARY_DEVICE 1 #define DO_MULTIPLE_RECORDINGS 1 -#define TUNER_LOCK_TIMEOUT 5000 // ms #define DEV_VIDEO "/dev/video" #define DEV_DVB_ADAPTER "/dev/dvb/adapter" @@ -81,6 +80,7 @@ private: cMutex mutex; cCondVar locked; cCondWait newSet; + bool GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs = 0); bool SetFrontend(void); virtual void Action(void); public: @@ -144,6 +144,36 @@ bool cDvbTuner::Locked(int TimeoutMs) return tunerStatus >= tsLocked; } +bool cDvbTuner::GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs) +{ + if (TimeoutMs) { + struct pollfd pfd; + pfd.fd = fd_frontend; + pfd.events = POLLIN | POLLPRI; + do { + int stat = poll(&pfd, 1, TimeoutMs); + if (stat == 1) + break; + if (stat < 0) { + if (errno == EINTR) + continue; + esyslog("ERROR: frontend %d poll failed: %m", cardIndex); + } + return false; + } while (0); + } + do { + int stat = ioctl(fd_frontend, FE_GET_EVENT, &Event); + if (stat == 0) + return true; + if (stat < 0) { + if (errno == EINTR) + continue; + } + } while (0); + return false; +} + static unsigned int FrequencyToHz(unsigned int f) { while (f && f < 1000000) @@ -260,18 +290,17 @@ bool cDvbTuner::SetFrontend(void) void cDvbTuner::Action(void) { + dvb_frontend_event event; active = true; while (active) { Lock(); if (tunerStatus == tsSet) { - dvb_frontend_event event; - while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) + while (GetFrontendEvent(event)) ; // discard stale events tunerStatus = SetFrontend() ? tsTuned : tsIdle; } if (tunerStatus != tsIdle) { - dvb_frontend_event event; - while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) { + while (GetFrontendEvent(event, 10)) { if (event.status & FE_REINIT) { tunerStatus = tsSet; esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex); @@ -306,7 +335,8 @@ void cDvbTuner::Action(void) } Unlock(); // in the beginning we loop more often to let the CAM connection start up fast - newSet.Wait((tunerStatus == tsTuned || ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000); + if (tunerStatus != tsTuned) + newSet.Wait((ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000); } } @@ -764,13 +794,6 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) if (EITScanner.UsesDevice(this)) return true; - // Wait for a lock: - - if (!dvbTuner->Locked(TUNER_LOCK_TIMEOUT)) { - esyslog("ERROR: no lock for channel %d on device %d", Channel->Number(), CardIndex() + 1); - return false; - } - // PID settings: if (TurnOnLivePIDs) { @@ -793,9 +816,9 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) return true; } -bool cDvbDevice::HasLock(void) +bool cDvbDevice::HasLock(int TimeoutMs) { - return dvbTuner ? dvbTuner->Locked() : false; + return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false; } void cDvbDevice::SetVolumeDevice(int Volume) diff --git a/dvbdevice.h b/dvbdevice.h index f7a4b92..7dd6174 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.h 1.28 2004/06/19 08:51:33 kls Exp $ + * $Id: dvbdevice.h 1.29 2004/10/30 14:48:27 kls Exp $ */ #ifndef __DVBDEVICE_H @@ -64,7 +64,7 @@ public: protected: virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); public: - virtual bool HasLock(void); + virtual bool HasLock(int TimeoutMs = 0); // PID handle facilities @@ -8,7 +8,7 @@ * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>. * - * $Id: eit.c 1.98 2004/10/24 14:56:39 kls Exp $ + * $Id: eit.c 1.100 2004/10/31 12:56:24 kls Exp $ */ #include "eit.h" @@ -161,17 +161,17 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data) time_t now = time(NULL); bool hit = SiEitEvent.getStartTime() <= now && now < SiEitEvent.getStartTime() + SiEitEvent.getDuration(); if (hit) { + char linkName[ld->privateData.getLength() + 1]; + strn0cpy(linkName, (const char *)ld->privateData.getData(), sizeof(linkName)); cChannel *link = Channels.GetByChannelID(linkID); if (link != channel) { // only link to other channels, not the same one - char linkName[ld->privateData.getLength() + 1]; - strn0cpy(linkName, (const char *)ld->privateData.getData(), sizeof(linkName)); //fprintf(stderr, "Linkage %s %4d %4d %5d %5d %5d %5d %02X '%s'\n", hit ? "*" : "", channel->Number(), link ? link->Number() : -1, SiEitEvent.getEventId(), ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId(), ld->getLinkageType(), linkName);//XXX if (link) { if (Setup.UpdateChannels >= 1) - link->SetName(linkName); + link->SetName(linkName, "", ""); } else if (Setup.UpdateChannels >= 3) { - link = Channels.NewChannel(channel, linkName, ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId()); + link = Channels.NewChannel(channel, linkName, "", "", ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId()); //XXX patFilter->Trigger(); } if (link) { @@ -180,6 +180,8 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data) LinkChannels->Add(new cLinkChannel(link)); } } + else + channel->SetPortalName(linkName); } } } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: eitscan.c 1.22 2004/04/16 13:33:34 kls Exp $ + * $Id: eitscan.c 1.23 2004/10/31 16:19:49 kls Exp $ */ #include "eitscan.h" @@ -20,10 +20,10 @@ private: cChannel channel; public: cScanData(const cChannel *Channel); - virtual bool operator< (const cListObject &ListObject); - int Source(void) { return channel.Source(); } - int Transponder(void) { return channel.Transponder(); } - const cChannel *GetChannel(void) { return &channel; } + virtual int Compare(const cListObject &ListObject) const; + int Source(void) const { return channel.Source(); } + int Transponder(void) const { return channel.Transponder(); } + const cChannel *GetChannel(void) const { return &channel; } }; cScanData::cScanData(const cChannel *Channel) @@ -31,10 +31,13 @@ cScanData::cScanData(const cChannel *Channel) channel = *Channel; } -bool cScanData::operator< (const cListObject &ListObject) +int cScanData::Compare(const cListObject &ListObject) const { - cScanData *sd = (cScanData *)&ListObject; - return Source() < sd->Source() || Source() == sd->Source() && Transponder() < sd->Transponder(); + const cScanData *sd = (const cScanData *)&ListObject; + int r = Source() - sd->Source(); + if (r == 0) + r = Transponder() - sd->Transponder(); + return r; } // --- cScanList ------------------------------------------------------------- @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * - * $Id: epg.c 1.20 2004/10/24 15:01:50 kls Exp $ + * $Id: epg.c 1.21 2004/10/31 16:12:36 kls Exp $ */ #include "epg.h" @@ -40,10 +40,10 @@ cEvent::~cEvent() free(description); } -bool cEvent::operator< (const cListObject &ListObject) +int cEvent::Compare(const cListObject &ListObject) const { cEvent *e = (cEvent *)&ListObject; - return startTime < e->startTime; + return startTime - e->startTime; } void cEvent::SetEventID(u_int16_t EventID) @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * - * $Id: epg.h 1.16 2004/10/24 13:56:00 kls Exp $ + * $Id: epg.h 1.17 2004/10/31 16:17:10 kls Exp $ */ #ifndef __EPG_H @@ -40,7 +40,7 @@ private: public: cEvent(tChannelID ChannelID, u_int16_t EventID); ~cEvent(); - virtual bool operator< (const cListObject &ListObject); + virtual int Compare(const cListObject &ListObject) const; tChannelID ChannelID(void) const { return channelID; } u_int16_t EventID(void) const { return eventID; } uchar TableID(void) const { return tableID; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.160 2004/10/23 13:57:38 kls Exp $ + * $Id: i18n.c 1.161 2004/11/01 14:18:48 kls Exp $ * * Translations provided by: * @@ -3652,25 +3652,25 @@ const tI18nPhrase Phrases[] = { " abcdefghijklmnopqrsðzþtuvwõäöüxyå0123456789-.#~", }, // Learning keys: - { "Learning Remote Control Keys (%s)", - "Fernbedienungs-Codes lernen (%s)", - "Ucenje kod upravljalca (%s)", - "Apprendimento tasti unita` remota (%s)", - "Leren toetsen afstandsbediening (%s)", - "Aprender as teclas do telecomando (%s)", - "Apprentissage des codes de télécommande (%s)", - "Lære fjernkontrolltaster (%s)", - "Kaukosäätimen opettaminen (%s)", - "Nauka kodu pilota (%s)", - "Aprendiendo teclas del telemando (%s)", - "ÅêìÜèçóç ðëÞêôñùí ôçëå÷åéñéóìïý (%s)", - "Inlärning av fjärrkontrollsknappar (%s)", - "Învãþare taste telecomandã (%s)", - "Távirányító betanítása (%s)", - "Aprenent les tecles del comandament a distància (%s)", - "²ÒÞÔ ÚÞÔÞÒ ÚÝÞßÞÚ ßãÛìâÐ (%s)", - "Uèenje kôda daljinskog upravljaèa (%s)", - "Kaugjuhtimispuldi õpetamine (%s)", + { "Learning Remote Control Keys", + "Fernbedienungs-Codes lernen", + "Ucenje kod upravljalca", + "Apprendimento tasti unita` remota", + "Leren toetsen afstandsbediening", + "Aprender as teclas do telecomando", + "Apprentissage des codes de télécommande", + "Lære fjernkontrolltaster", + "Kaukosäätimen opettaminen", + "Nauka kodu pilota", + "Aprendiendo teclas del telemando", + "ÅêìÜèçóç ðëÞêôñùí ôçëå÷åéñéóìïý", + "Inlärning av fjärrkontrollsknappar", + "Învãþare taste telecomandã", + "Távirányító betanítása", + "Aprenent les tecles del comandament a distància", + "²ÒÞÔ ÚÞÔÞÒ ÚÝÞßÞÚ ßãÛìâÐ", + "Uèenje kôda daljinskog upravljaèa", + "Kaugjuhtimispuldi õpetamine", }, { "Phase 1: Detecting RC code type", "Phase 1: FB Code feststellen", diff --git a/interface.c b/interface.c index 06ba331..3373743 100644 --- a/interface.c +++ b/interface.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: interface.c 1.67 2004/05/02 10:57:06 kls Exp $ + * $Id: interface.c 1.68 2004/11/01 14:23:28 kls Exp $ */ #include "interface.h" @@ -76,23 +76,23 @@ bool cInterface::Confirm(const char *s, int Seconds, bool WaitForTimeout) bool cInterface::QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu) { - DisplayMenu->SetItem(tr("Phase 1: Detecting RC code type"), 1, false, false); - DisplayMenu->SetItem(tr("Press any key on the RC unit"), 3, false, false); + DisplayMenu->SetItem(tr("Phase 1: Detecting RC code type"), 2, false, false); + DisplayMenu->SetItem(tr("Press any key on the RC unit"), 4, false, false); DisplayMenu->Flush(); if (Remote->Initialize()) { - DisplayMenu->SetItem(tr("RC code detected!"), 3, false, false); - DisplayMenu->SetItem(tr("Do not press any key..."), 4, false, false); + DisplayMenu->SetItem(tr("RC code detected!"), 4, false, false); + DisplayMenu->SetItem(tr("Do not press any key..."), 5, false, false); DisplayMenu->Flush(); sleep(3); - DisplayMenu->SetItem("", 3, false, false); DisplayMenu->SetItem("", 4, false, false); + DisplayMenu->SetItem("", 5, false, false); - DisplayMenu->SetItem(tr("Phase 2: Learning specific key codes"), 1, false, false); + DisplayMenu->SetItem(tr("Phase 2: Learning specific key codes"), 2, false, false); eKeys NewKey = kUp; while (NewKey != kNone) { char *Prompt; asprintf(&Prompt, tr("Press key for '%s'"), tr(cKey::ToString(NewKey))); - DisplayMenu->SetItem(Prompt, 3, false, false); + DisplayMenu->SetItem(Prompt, 4, false, false); free(Prompt); cRemote::Clear(); DisplayMenu->Flush(); @@ -107,11 +107,11 @@ bool cInterface::QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu) Keys.Del(last); } break; - case kDown: DisplayMenu->SetItem(tr("Press 'Up' to confirm"), 3, false, false); - DisplayMenu->SetItem(tr("Press 'Down' to continue"), 4, false, false); - DisplayMenu->SetItem("", 5, false, false); + case kDown: DisplayMenu->SetItem(tr("Press 'Up' to confirm"), 4, false, false); + DisplayMenu->SetItem(tr("Press 'Down' to continue"), 5, false, false); DisplayMenu->SetItem("", 6, false, false); DisplayMenu->SetItem("", 7, false, false); + DisplayMenu->SetItem("", 8, false, false); DisplayMenu->Flush(); for (;;) { Key = cRemote::Get(100); @@ -120,7 +120,7 @@ bool cInterface::QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu) return true; } else if (Key == kDown) { - DisplayMenu->SetItem("", 4, false, false); + DisplayMenu->SetItem("", 5, false, false); k = kNone; // breaks the outer for() loop break; } @@ -139,17 +139,17 @@ bool cInterface::QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu) } } if (NewKey > kUp) - DisplayMenu->SetItem(tr("(press 'Up' to go back)"), 5, false, false); + DisplayMenu->SetItem(tr("(press 'Up' to go back)"), 6, false, false); else - DisplayMenu->SetItem("", 5, false, false); + DisplayMenu->SetItem("", 6, false, false); if (NewKey > kDown) - DisplayMenu->SetItem(tr("(press 'Down' to end key definition)"), 6, false, false); + DisplayMenu->SetItem(tr("(press 'Down' to end key definition)"), 7, false, false); else - DisplayMenu->SetItem("", 6, false, false); + DisplayMenu->SetItem("", 7, false, false); if (NewKey > kMenu) - DisplayMenu->SetItem(tr("(press 'Menu' to skip this key)"), 7, false, false); + DisplayMenu->SetItem(tr("(press 'Menu' to skip this key)"), 8, false, false); else - DisplayMenu->SetItem("", 7, false, false); + DisplayMenu->SetItem("", 8, false, false); } return true; } @@ -168,9 +168,10 @@ void cInterface::LearnKeys(void) if (!known) { cSkinDisplayMenu *DisplayMenu = Skins.Current()->DisplayMenu(); char Headline[256]; - snprintf(Headline, sizeof(Headline), tr("Learning Remote Control Keys (%s)"), Remote->Name()); + snprintf(Headline, sizeof(Headline), tr("Learning Remote Control Keys")); cRemote::Clear(); DisplayMenu->SetTitle(Headline); + DisplayMenu->SetItem(Remote->Name(), 0, false, false); cRemote::SetLearning(Remote); bool rc = QueryKeys(Remote, DisplayMenu); cRemote::SetLearning(NULL); @@ -179,8 +180,9 @@ void cInterface::LearnKeys(void) delete DisplayMenu; continue; } - DisplayMenu->SetItem(tr("Phase 3: Saving key codes"), 1, false, false); - DisplayMenu->SetItem(tr("Press 'Up' to save, 'Down' to cancel"), 3, false, false); + DisplayMenu->SetItem(Remote->Name(), 0, false, false); + DisplayMenu->SetItem(tr("Phase 3: Saving key codes"), 2, false, false); + DisplayMenu->SetItem(tr("Press 'Up' to save, 'Down' to cancel"), 4, false, false); for (;;) { eKeys key = GetKey(); if (key == kUp) { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.314 2004/10/17 10:28:27 kls Exp $ + * $Id: menu.c 1.319 2004/11/01 13:49:40 kls Exp $ */ #include "menu.h" @@ -223,6 +223,7 @@ class cMenuEditChannel : public cOsdMenu { private: cChannel *channel; cChannel data; + char name[256]; void Setup(void); public: cMenuEditChannel(cChannel *Channel, bool New = false); @@ -254,7 +255,8 @@ void cMenuEditChannel::Setup(void) Clear(); // Parameters for all types of sources: - Add(new cMenuEditStrItem( tr("Name"), data.name, sizeof(data.name), tr(FileNameChars))); + strn0cpy(name, data.name, sizeof(name)); + Add(new cMenuEditStrItem( tr("Name"), name, sizeof(name), tr(FileNameChars))); Add(new cMenuEditSrcItem( tr("Source"), &data.source)); Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency)); Add(new cMenuEditIntItem( tr("Vpid"), &data.vpid, 0, 0x1FFF)); @@ -295,6 +297,7 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key) if (state == osUnknown) { if (Key == kOk) { if (Channels.HasUniqueChannelID(&data, channel)) { + data.name = strcpyrealloc(data.name, name); if (channel) { *channel = data; isyslog("edited channel %d %s", channel->Number(), data.ToText()); @@ -324,14 +327,23 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key) // --- cMenuChannelItem ------------------------------------------------------ class cMenuChannelItem : public cOsdItem { +public: + enum eChannelSortMode { csmNumber, csmName, csmProvider }; private: + static eChannelSortMode sortMode; cChannel *channel; public: cMenuChannelItem(cChannel *Channel); + static void SetSortMode(eChannelSortMode SortMode) { sortMode = SortMode; } + static void IncSortMode(void) { sortMode = eChannelSortMode((sortMode == csmProvider) ? csmNumber : sortMode + 1); } + virtual int Compare(const cListObject &ListObject) const; virtual void Set(void); cChannel *Channel(void) { return channel; } + static eChannelSortMode SortMode(void) { return sortMode; } }; +cMenuChannelItem::eChannelSortMode cMenuChannelItem::sortMode = csmNumber; + cMenuChannelItem::cMenuChannelItem(cChannel *Channel) { channel = Channel; @@ -340,11 +352,28 @@ cMenuChannelItem::cMenuChannelItem(cChannel *Channel) Set(); } +int cMenuChannelItem::Compare(const cListObject &ListObject) const +{ + cMenuChannelItem *p = (cMenuChannelItem *)&ListObject; + int r = -1; + if (sortMode == csmProvider) + r = strcoll(channel->Provider(), p->channel->Provider()); + if (sortMode == csmName || r == 0) + r = strcoll(channel->Name(), p->channel->Name()); + if (sortMode == csmNumber || r == 0) + r = channel->Number() - p->channel->Number(); + return r; +} + void cMenuChannelItem::Set(void) { char *buffer = NULL; - if (!channel->GroupSep()) - asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name()); + if (!channel->GroupSep()) { + if (sortMode == csmProvider) + asprintf(&buffer, "%d\t%s - %s", channel->Number(), channel->Provider(), channel->Name()); + else + asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name()); + } else asprintf(&buffer, "---\t%s ----------------------------------------------------------------", channel->Name()); SetText(buffer, false); @@ -354,6 +383,7 @@ void cMenuChannelItem::Set(void) class cMenuChannels : public cOsdMenu { private: + void Setup(void); cChannel *GetChannel(int Index); void Propagate(void); protected: @@ -371,11 +401,7 @@ public: cMenuChannels::cMenuChannels(void) :cOsdMenu(tr("Channels"), CHNUMWIDTH) { - for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) { - if (!channel->GroupSep() || *channel->Name()) - Add(new cMenuChannelItem(channel), channel->Number() == cDevice::CurrentChannel()); - } - SetHelp(tr("Edit"), tr("New"), tr("Delete"), tr("Mark")); + Setup(); Channels.IncBeingEdited(); } @@ -384,6 +410,28 @@ cMenuChannels::~cMenuChannels() Channels.DecBeingEdited(); } +void cMenuChannels::Setup(void) +{ + cChannel *currentChannel = GetChannel(Current()); + if (!currentChannel) + currentChannel = Channels.GetByNumber(cDevice::CurrentChannel()); + cMenuChannelItem *currentItem = NULL; + Clear(); + for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) { + if (!channel->GroupSep() || cMenuChannelItem::SortMode() == cMenuChannelItem::csmNumber && *channel->Name()) { + cMenuChannelItem *item = new cMenuChannelItem(channel); + Add(item); + if (channel == currentChannel) + currentItem = item; + } + } + if (cMenuChannelItem::SortMode() != cMenuChannelItem::csmNumber) + Sort(); + SetCurrent(currentItem); + SetHelp(tr("Edit"), tr("New"), tr("Delete"), cMenuChannelItem::SortMode() == cMenuChannelItem::csmNumber ? tr("Mark") : NULL); + Display(); +} + cChannel *cMenuChannels::GetChannel(int Index) { cMenuChannelItem *p = (cMenuChannelItem *)Get(Index); @@ -483,11 +531,14 @@ eOSState cMenuChannels::ProcessKey(eKeys Key) default: if (state == osUnknown) { switch (Key) { + case k0: cMenuChannelItem::IncSortMode(); + Setup(); + break; case kOk: return Switch(); case kRed: return Edit(); case kGreen: return New(); case kYellow: return Delete(); - case kBlue: if (!HasSubMenu()) + case kBlue: if (!HasSubMenu() && cMenuChannelItem::SortMode() == cMenuChannelItem::csmNumber) Mark(); break; default: break; @@ -629,7 +680,7 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key) break; } if (!*data.file) - strcpy(data.file, data.Channel()->Name()); + strcpy(data.file, data.Channel()->ShortName(true)); if (timer) { if (memcmp(timer, &data, sizeof(data)) != 0) { *timer = data; @@ -639,7 +690,7 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key) if (addIfConfirmed) Timers.Add(timer); timer->Matches(); - Timers.Save(); + Timers.SetModified(); isyslog("timer %d %s (%s)", timer->Index() + 1, addIfConfirmed ? "added" : "modified", timer->HasFlags(tfActive) ? "active" : "inactive"); addIfConfirmed = false; } @@ -664,7 +715,7 @@ private: cTimer *timer; public: cMenuTimerItem(cTimer *Timer); - virtual bool operator< (const cListObject &ListObject); + virtual int Compare(const cListObject &ListObject) const; virtual void Set(void); cTimer *Timer(void) { return timer; } }; @@ -675,9 +726,9 @@ cMenuTimerItem::cMenuTimerItem(cTimer *Timer) Set(); } -bool cMenuTimerItem::operator< (const cListObject &ListObject) +int cMenuTimerItem::Compare(const cListObject &ListObject) const { - return *timer < *((cMenuTimerItem *)&ListObject)->timer; + return timer->Compare(*((cMenuTimerItem *)&ListObject)->timer); } void cMenuTimerItem::Set(void) @@ -747,7 +798,7 @@ eOSState cMenuTimers::OnOff(void) isyslog("timer %d first day set to %s", timer->Index() + 1, timer->PrintFirstDay()); else isyslog("timer %d %sactivated", timer->Index() + 1, timer->HasFlags(tfActive) ? "" : "de"); - Timers.Save(); + Timers.SetModified(); } return osContinue; } @@ -784,7 +835,7 @@ eOSState cMenuTimers::Delete(void) int Index = ti->Index(); Timers.Del(ti); cOsdMenu::Del(Current()); - Timers.Save(); + Timers.SetModified(); Display(); isyslog("timer %d deleted", Index + 1); } @@ -796,7 +847,7 @@ void cMenuTimers::Move(int From, int To) { Timers.Move(From, To); cOsdMenu::Move(From, To); - Timers.Save(); + Timers.SetModified(); Display(); isyslog("timer %d moved to %d", From + 1, To + 1); } @@ -918,7 +969,7 @@ cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel) char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' '; char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' '; char r = event->IsRunning() ? '*' : ' '; - asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->Name(), event->GetTimeString(), t, v, r, event->Title()); + asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), event->GetTimeString(), t, v, r, event->Title()); SetText(buffer, false); } @@ -1556,7 +1607,7 @@ eOSState cMenuRecordings::Delete(void) Timers.Del(timer); isyslog("timer %d deleted", Index + 1); } - Timers.Save(); + Timers.SetModified(); } } else @@ -2629,9 +2680,13 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) //XXX case kGreen: return osEventNow; //XXX case kYellow: return osEventNext; case kOk: if (group >= 0) { - cChannel *channel = Channels.Get(Channels.GetNextNormal(group)); + channel = Channels.Get(Channels.GetNextNormal(group)); if (channel) Channels.SwitchTo(channel->Number()); + withInfo = true; + group = -1; + Refresh(); + break; } return osEnd; default: if ((Key & (k_Repeat | k_Release)) == 0) { @@ -2730,7 +2785,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) if (!timer) { timer = new cTimer(true, Pause); Timers.Add(timer); - Timers.Save(); + Timers.SetModified(); asprintf(&instantId, cDevice::NumDevices() > 1 ? "%s - %d" : "%s", timer->Channel()->Name(), device->CardIndex() + 1); } timer->SetPending(true); @@ -2759,7 +2814,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) } else { Timers.Del(timer); - Timers.Save(); + Timers.SetModified(); if (!cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo() cReplayControl::SetRecording(fileName, Recording.Name()); } @@ -2829,7 +2884,7 @@ void cRecordControl::Stop(bool KeepInstant) if ((IsInstant() && !KeepInstant) || (timer->IsSingleEvent() && timer->StopTime() <= time(NULL))) { isyslog("deleting timer %d", timer->Index() + 1); Timers.Del(timer); - Timers.Save(); + Timers.SetModified(); } timer = NULL; cStatus::MsgRecording(device, NULL); diff --git a/recording.c b/recording.c index e33e231..5a703db 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.89 2004/07/17 11:22:29 kls Exp $ + * $Id: recording.c 1.92 2004/11/01 14:04:47 kls Exp $ */ #include "recording.h" @@ -335,7 +335,7 @@ cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, c name = strreplace(name, TIMERMACRO_EPISODE, Subtitle); if (Timer->IsSingleEvent()) { Timer->SetFile(name); // this was an instant recording, so let's set the actual data - Timers.Save(); + Timers.SetModified(); } } else if (Timer->IsSingleEvent() || !Setup.UseSubtitle) @@ -451,11 +451,11 @@ char *cRecording::StripEpisodeName(char *s) return s; } -char *cRecording::SortName(void) +char *cRecording::SortName(void) const { if (!sortBuffer) { char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory) + 1)); - int l = strxfrm(NULL, s, 0); + int l = strxfrm(NULL, s, 0) + 1; sortBuffer = MALLOC(char, l); strxfrm(sortBuffer, s, l); free(s); @@ -472,10 +472,10 @@ int cRecording::GetResume(void) const return resume; } -bool cRecording::operator< (const cListObject &ListObject) +int cRecording::Compare(const cListObject &ListObject) const { cRecording *r = (cRecording *)&ListObject; - return strcasecmp(SortName(), r->SortName()) < 0; + return strcasecmp(SortName(), r->SortName()); } const char *cRecording::FileName(void) const diff --git a/recording.h b/recording.h index 88b90d3..184f49e 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.h 1.31 2004/07/17 11:09:49 kls Exp $ + * $Id: recording.h 1.32 2004/10/31 16:24:38 kls Exp $ */ #ifndef __RECORDING_H @@ -36,12 +36,12 @@ class cRecording : public cListObject { private: mutable int resume; mutable char *titleBuffer; - char *sortBuffer; + mutable char *sortBuffer; mutable char *fileName; mutable char *name; char *summary; - char *StripEpisodeName(char *s); - char *SortName(void); + static char *StripEpisodeName(char *s); + char *SortName(void) const; int GetResume(void) const; public: time_t start; @@ -50,7 +50,7 @@ public: cRecording(cTimer *Timer, const char *Title, const char *Subtitle, const char *Summary); cRecording(const char *FileName); ~cRecording(); - virtual bool operator< (const cListObject &ListObject); + virtual int Compare(const cListObject &ListObject) const; const char *Name(void) const { return name; } const char *FileName(void) const; const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1) const; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remote.c 1.40 2004/05/28 14:19:52 kls Exp $ + * $Id: remote.c 1.41 2004/10/31 14:05:12 kls Exp $ */ #include "remote.h" @@ -265,7 +265,6 @@ void cKbdRemote::Action(void) if (Poller.Poll(100)) { uint64 Command = 0; uint i = 0; - int t0 = time_ms(); while (active && i < sizeof(Command)) { uchar ch; int r = read(STDIN_FILENO, &ch, 1); @@ -280,7 +279,7 @@ void cKbdRemote::Action(void) // of their codes, so we'll need to wait some 100ms to see if // there is more coming up - or whether this really is the 'ESC' // key (if somebody knows how to clean this up, please let me know): - if (Command == 0x1B && time_ms() - t0 < 100) + if (Command == 0x1B && Poller.Poll(100)) continue; if (Command) { if (rawMode || !Put(Command)) { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: sdt.c 1.12 2004/10/16 10:02:23 kls Exp $ + * $Id: sdt.c 1.13 2004/10/31 12:10:20 kls Exp $ */ #include "sdt.h" @@ -58,28 +58,16 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length { char NameBuf[1024]; char ShortNameBuf[1024]; + char ProviderNameBuf[1024]; sd->serviceName.getText(NameBuf, ShortNameBuf, sizeof(NameBuf), sizeof(ShortNameBuf)); char *pn = compactspace(NameBuf); char *ps = compactspace(ShortNameBuf); - if (*NameBuf && *ShortNameBuf && strcmp(NameBuf, ShortNameBuf) != 0) { - ps = ShortNameBuf + strlen(ShortNameBuf); - *ps++ = ','; - strcpy(ps, NameBuf); - pn = ShortNameBuf; - } - if (*pn) { - char ProviderNameBuf[1024]; - sd->providerName.getText(ProviderNameBuf, sizeof(ProviderNameBuf)); - if (*ProviderNameBuf) { - char *p = pn + strlen(pn); - *p++ = ';'; - strcpy(p, ProviderNameBuf); - } - } + sd->providerName.getText(ProviderNameBuf, sizeof(ProviderNameBuf)); + char *pp = compactspace(ProviderNameBuf); if (channel) { channel->SetId(sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId()); if (Setup.UpdateChannels >= 1) - channel->SetName(pn); + channel->SetName(pn, ps, pp); // Using SiSdtService.getFreeCaMode() is no good, because some // tv stations set this flag even for non-encrypted channels :-( // The special value 0xFFFF was supposed to mean "unknown encryption" @@ -87,7 +75,7 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length // channel->SetCa(SiSdtService.getFreeCaMode() ? 0xFFFF : 0); } else if (*pn && Setup.UpdateChannels >= 3) { - channel = Channels.NewChannel(Channel(), pn, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId()); + channel = Channels.NewChannel(Channel(), pn, ps, pp, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId()); patFilter->Trigger(); } } @@ -112,7 +100,7 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length for (SI::Loop::Iterator it; nrd->serviceLoop.getNext(Service, it); ) { cChannel *link = Channels.GetByChannelID(tChannelID(Source(), Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId())); if (!link && Setup.UpdateChannels >= 3) { - link = Channels.NewChannel(Channel(), "NVOD", Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId()); + link = Channels.NewChannel(Channel(), "NVOD", "", "", Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId()); patFilter->Trigger(); } if (link) { @@ -10,7 +10,7 @@ * and interact with the Video Disk Recorder - or write a full featured * graphical interface that sits on top of an SVDRP connection. * - * $Id: svdrp.c 1.64 2004/10/17 10:28:47 kls Exp $ + * $Id: svdrp.c 1.65 2004/10/31 10:09:53 kls Exp $ */ #include "svdrp.h" @@ -529,7 +529,7 @@ void cSVDRP::CmdDELT(const char *Option) if (timer) { if (!timer->Recording()) { Timers.Del(timer); - Timers.Save(); + Timers.SetModified(); isyslog("timer %s deleted", Option); Reply(250, "Timer \"%s\" deleted", Option); } @@ -915,7 +915,7 @@ void cSVDRP::CmdMODT(const char *Option) return; } *timer = t; - Timers.Save(); + Timers.SetModified(); isyslog("timer %d modified (%s)", timer->Index() + 1, timer->HasFlags(tfActive) ? "active" : "inactive"); Reply(250, "%d %s", timer->Index() + 1, timer->ToText()); } @@ -973,7 +973,7 @@ void cSVDRP::CmdNEWT(const char *Option) cTimer *t = Timers.GetTimer(timer); if (!t) { Timers.Add(timer); - Timers.Save(); + Timers.SetModified(); isyslog("timer %d added", timer->Index() + 1); Reply(250, "%d %s", timer->Index() + 1, timer->ToText()); return; @@ -1057,7 +1057,7 @@ void cSVDRP::CmdUPDT(const char *Option) Timers.Add(timer); isyslog("timer %d added", timer->Index() + 1); } - Timers.Save(); + Timers.SetModified(); Reply(250, "%d %s", timer->Index() + 1, timer->ToText()); return; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.c 1.35 2004/10/24 11:05:56 kls Exp $ + * $Id: thread.c 1.36 2004/10/31 09:54:02 kls Exp $ */ #include "thread.h" @@ -28,6 +28,7 @@ cCondWait::cCondWait(void) cCondWait::~cCondWait() { + pthread_cond_broadcast(&cond); // wake up any sleepers pthread_cond_destroy(&cond); pthread_mutex_destroy(&mutex); } @@ -71,7 +72,7 @@ void cCondWait::Signal(void) { pthread_mutex_lock(&mutex); signaled = true; - pthread_cond_signal(&cond); + pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mutex); } @@ -84,6 +85,7 @@ cCondVar::cCondVar(void) cCondVar::~cCondVar() { + pthread_cond_broadcast(&cond); // wake up any sleepers pthread_cond_destroy(&cond); } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.c 1.14 2004/10/24 14:56:55 kls Exp $ + * $Id: timers.c 1.16 2004/10/31 16:41:30 kls Exp $ */ #include "timers.h" @@ -95,12 +95,15 @@ cTimer& cTimer::operator= (const cTimer &Timer) return *this; } -bool cTimer::operator< (const cListObject &ListObject) +int cTimer::Compare(const cListObject &ListObject) const { cTimer *ti = (cTimer *)&ListObject; time_t t1 = StartTime(); time_t t2 = ti->StartTime(); - return t1 < t2 || (t1 == t2 && priority > ti->priority); + int r = t1 - t2; + if (r == 0) + r = ti->priority - priority; + return r; } const char *cTimer::ToText(bool UseChannelID) @@ -248,25 +251,25 @@ bool cTimer::Save(FILE *f) return fprintf(f, ToText(true)) > 0; } -bool cTimer::IsSingleEvent(void) +bool cTimer::IsSingleEvent(void) const { return (day & 0x80000000) == 0; } -int cTimer::GetMDay(time_t t) +int cTimer::GetMDay(time_t t) const { struct tm tm_r; return localtime_r(&t, &tm_r)->tm_mday; } -int cTimer::GetWDay(time_t t) +int cTimer::GetWDay(time_t t) const { struct tm tm_r; int weekday = localtime_r(&t, &tm_r)->tm_wday; return weekday == 0 ? 6 : weekday - 1; // we start with monday==0! } -bool cTimer::DayMatches(time_t t) +bool cTimer::DayMatches(time_t t) const { return IsSingleEvent() ? GetMDay(t) == day : (day & (1 << GetWDay(t))) != 0; } @@ -301,7 +304,7 @@ char *cTimer::SetFile(const char *File) return file; } -bool cTimer::Matches(time_t t, bool Directly) +bool cTimer::Matches(time_t t, bool Directly) const { startTime = stopTime = 0; if (t == 0) @@ -363,14 +366,14 @@ int cTimer::Matches(const cEvent *Event) return tmNone; } -time_t cTimer::StartTime(void) +time_t cTimer::StartTime(void) const { if (!startTime) Matches(); return startTime; } -time_t cTimer::StopTime(void) +time_t cTimer::StopTime(void) const { if (!stopTime) Matches(); @@ -425,7 +428,7 @@ void cTimer::InvFlags(int Flags) flags ^= Flags; } -bool cTimer::HasFlags(int Flags) +bool cTimer::HasFlags(int Flags) const { return (flags & Flags) == Flags; } @@ -458,6 +461,7 @@ cTimers Timers; cTimers::cTimers(void) { + modified = false; beingEdited = 0;; lastSetEvents = 0; } @@ -505,12 +509,24 @@ cTimer *cTimers::GetNextActiveTimer(void) { cTimer *t0 = NULL; for (cTimer *ti = First(); ti; ti = Next(ti)) { - if ((ti->HasFlags(tfActive)) && (!t0 || *ti < *t0)) + if ((ti->HasFlags(tfActive)) && (!t0 || ti->Compare(*t0) < 0)) t0 = ti; } return t0; } +void cTimers::SetModified(void) +{ + modified = true; +} + +bool cTimers::Modified(void) +{ + bool Result = modified; + modified = false; + return Result; +} + void cTimers::SetEvents(void) { if (time(NULL) - lastSetEvents < 5) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.h 1.8 2004/10/24 14:40:37 kls Exp $ + * $Id: timers.h 1.10 2004/10/31 16:41:17 kls Exp $ */ #ifndef __TIMERS_H @@ -26,7 +26,7 @@ enum eTimerMatch { tmNone, tmPartial, tmFull }; class cTimer : public cListObject { friend class cMenuEditTimer; private: - time_t startTime, stopTime; + mutable time_t startTime, stopTime; static char *buffer; bool recording, pending, inVpsMargin; int flags; @@ -37,7 +37,7 @@ private: int priority; int lifetime; char file[MaxFileName]; - time_t firstday; + mutable time_t firstday; char *summary; const cEvent *event; public: @@ -45,7 +45,7 @@ public: cTimer(const cEvent *Event); virtual ~cTimer(); cTimer& operator= (const cTimer &Timer); - virtual bool operator< (const cListObject &ListObject); + virtual int Compare(const cListObject &ListObject) const; bool Recording(void) { return recording; } bool Pending(void) { return pending; } bool InVpsMargin(void) { return inVpsMargin; } @@ -63,17 +63,17 @@ public: const cEvent *Event(void) { return event; } bool Parse(const char *s); bool Save(FILE *f); - bool IsSingleEvent(void); - int GetMDay(time_t t); - int GetWDay(time_t t); - bool DayMatches(time_t t); + bool IsSingleEvent(void) const; + int GetMDay(time_t t) const; + int GetWDay(time_t t) const; + bool DayMatches(time_t t) const; static time_t IncDay(time_t t, int Days); static time_t SetTime(time_t t, int SecondsFromMidnight); char *SetFile(const char *File); - bool Matches(time_t t = 0, bool Directly = false); + bool Matches(time_t t = 0, bool Directly = false) const; int Matches(const cEvent *Event); - time_t StartTime(void); - time_t StopTime(void); + time_t StartTime(void) const; + time_t StopTime(void) const; void SetEvent(const cEvent *Event); void SetRecording(bool Recording); void SetPending(bool Pending); @@ -81,7 +81,7 @@ public: void SetFlags(int Flags); void ClrFlags(int Flags); void InvFlags(int Flags); - bool HasFlags(int Flags); + bool HasFlags(int Flags) const; void Skip(void); void OnOff(void); const char *PrintFirstDay(void); @@ -92,6 +92,7 @@ public: class cTimers : public cConfig<cTimer> { private: + bool modified; int beingEdited; time_t lastSetEvents; public: @@ -103,6 +104,10 @@ public: int BeingEdited(void) { return beingEdited; } void IncBeingEdited(void) { beingEdited++; } void DecBeingEdited(void) { if (!--beingEdited) lastSetEvents = 0; } + void SetModified(void); + bool Modified(void); + ///< Returns true if any of the timers have been modified. + ///< Calling this function resets the 'modified' flag to false. void SetEvents(void); }; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.80 2004/06/13 14:36:41 kls Exp $ + * $Id: tools.c 1.81 2004/10/31 16:42:36 kls Exp $ */ #include "tools.h" @@ -939,19 +939,28 @@ int cListBase::Count(void) const return n; } +static int CompareListObjects(const void *a, const void *b) +{ + const cListObject *la = *(const cListObject **)a; + const cListObject *lb = *(const cListObject **)b; + return la->Compare(*lb); +} + void cListBase::Sort(void) { - bool swapped; - do { - swapped = false; - cListObject *object = objects; - while (object) { - if (object->Next() && *object->Next() < *object) { - Move(object->Next(), object); - swapped = true; - } - object = object->Next(); - } - } while (swapped); + int n = Count(); + cListObject *a[n]; + cListObject *object = objects; + int i = 0; + while (object && i < n) { + a[i++] = object; + object = object->Next(); + } + qsort(a, n, sizeof(cListObject *), CompareListObjects); + objects = lastObject = NULL; + for (i = 0; i < n; i++) { + a[i]->Unlink(); + Add(a[i]); + } } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 1.57 2004/06/13 14:13:26 kls Exp $ + * $Id: tools.h 1.58 2004/10/31 16:16:37 kls Exp $ */ #ifndef __TOOLS_H @@ -148,7 +148,9 @@ private: public: cListObject(void); virtual ~cListObject(); - virtual bool operator< (const cListObject &ListObject) { return false; } + virtual int Compare(const cListObject &ListObject) const { return 0; } + ///< Must return 0 if this object is equal to ListObject, a positive value + ///< if it is "greater", and a negative value if it is "smaller". void Append(cListObject *Object); void Insert(cListObject *Object); void Unlink(void); @@ -2,15 +2,15 @@ .\" ** The above line should force tbl to be a preprocessor ** .\" Man page for vdr file formats .\" -.\" Copyright (C) 2003 Klaus Schmidinger +.\" Copyright (C) 2004 Klaus Schmidinger .\" .\" You may distribute under the terms of the GNU General Public .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 1.28 2004/07/18 11:06:54 kls Exp $ +.\" $Id: vdr.5 1.29 2004/10/31 12:13:43 kls Exp $ .\" -.TH vdr 5 "1 Jun 2003" "1.2.0" "Video Disk Recorder Files" +.TH vdr 5 "31 Oct 2004" "1.3.15" "Video Disk Recorder Files" .SH NAME vdr file formats - the Video Disk Recorder Files .SH DESCRIPTION @@ -45,7 +45,7 @@ Such a delimiter will not appear in the Channels menu. A \fBchannel definition\fR is a line with channel data, where the fields are separated by ':' characters. Example: -\fBRTL,RTL Television:12188:h:S19.2E:27500:163:104:105:0:12003:1:1089:0\fR +\fBRTL Television,RTL:12188:h:S19.2E:27500:163:104:105:0:12003:1:1089:0\fR The line number of a channel definition (not counting group separators, and based on a possible previous '@...' parameter) @@ -60,15 +60,15 @@ it has to be replaced by '|'). Some tv stations provide a way of deriving a "short name" from the channel name, which can be used in situations where there is not much space for displaying a long name. If a short name is available -for this channel, it preceeds the full name and is delimited by a comma, +for this channel, it follows the full name and is delimited by a comma, as in -\fBRTL,RTL Television:...\fR +\fBRTL Television,RTL:...\fR If present, the name of the service provider or "bouquet" is appended to the channel name, separated by a semicolon, as in -\fBRTL,RTL Television;RTL World:...\fR +\fBRTL Television,RTL;RTL World:...\fR .TP .B Frequency The transponder frequency (as an integer). For DVB-S this value is in MHz. For DVB-C @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/vdr * - * $Id: vdr.c 1.190 2004/10/24 14:01:11 kls Exp $ + * $Id: vdr.c 1.192 2004/10/31 10:17:23 kls Exp $ */ #include <getopt.h> @@ -347,6 +347,21 @@ int main(int argc, char *argv[]) isyslog("VDR version %s started", VDRVERSION); + // Main program loop variables - need to be here to have them initialized before any EXIT(): + + cOsdObject *Menu = NULL; + cOsdObject *Temp = NULL; + int LastChannel = -1; + int LastTimerChannel = -1; + int PreviousChannel[2] = { 1, 1 }; + int PreviousChannelIndex = 0; + time_t LastChannelChanged = time(NULL); + time_t LastActivity = 0; + int MaxLatencyTime = 0; + bool ForceShutdown = false; + bool UserShutdown = false; + bool TimerInVpsMargin = false; + // Load plugins: if (!PluginManager.LoadPlugins(true)) @@ -490,19 +505,6 @@ int main(int argc, char *argv[]) // Main program loop: - static cOsdObject *Menu = NULL; - static cOsdObject *Temp = NULL; - static int LastChannel = -1; - static int LastTimerChannel = -1; - static int PreviousChannel[2] = { 1, 1 }; - static int PreviousChannelIndex = 0; - static time_t LastChannelChanged = time(NULL); - static time_t LastActivity = 0; - static int MaxLatencyTime = 0; - static bool ForceShutdown = false; - static bool UserShutdown = false; - static bool TimerInVpsMargin = false; - while (!Interrupted) { // Handle emergency exits: if (cThread::EmergencyExit()) { @@ -538,11 +540,13 @@ int main(int argc, char *argv[]) dsyslog("max. latency time %d seconds", MaxLatencyTime); } } - // Handle channel modifications: - if (!Channels.BeingEdited()) { + // Handle channel and timer modifications: + if (!Channels.BeingEdited() && !Timers.BeingEdited()) { int modified = Channels.Modified(); static time_t ChannelSaveTimeout = 0; - if (modified == CHANNELSMOD_USER) + // Channels and timers need to be stored in a consistent manner, + // therefore if one of them is changed, we save both. + if (modified == CHANNELSMOD_USER || Timers.Modified()) ChannelSaveTimeout = 1; // triggers an immediate save else if (modified && !ChannelSaveTimeout) ChannelSaveTimeout = time(NULL) + CHANNELSAVEDELTA; |