From a001a4bf97715d62b387d1da9fd1e48382508428 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 3 Mar 2002 18:00:00 +0100 Subject: Version 1.0.0pre3 - Fixed parsing 'E' records in epg2html.pl. - Fixed a deadlock when switching channels via Schedule/Now|Next/Switch (reported by Martin Hammerschmid). - Changed the meaning of the 'Ca' parameter in 'channels.conf'. Each channel can now define which decryption method it needs in order to be accessed. The new configuration file 'ca.conf' contains the defined values, and the default 'channels.conf' has been modifed to contain the new values for 'Premiere World' and 'ORF'. If you use the default 'channels.conf' and have the conditional access hardware to receive encrypted channels, please make sure you copy the file 'ca.conf' into your /video directory (or wherever your configuration files are located) and go into the "Setup" menu and set the CICAM values according to your hardware setup. Currently there are two possible CICAM entries per DVB card, so any card can implement up to two different conditional access modes (besides the default "Free To Air" mode, which is always assumed to be available on any DVB card). - Updated French language texts (thanks to Jean-Claude Repetto). --- CONTRIBUTORS | 1 + FORMATS | 19 +++++++- HISTORY | 19 ++++++++ MANUAL | 8 ++++ ca.conf | 22 ++++++++++ channels.conf | 138 +++++++++++++++++++++++++++++----------------------------- config.c | 73 ++++++++++++++++++++++++++++++- config.h | 25 ++++++++++- dvbapi.c | 127 ++++++++++++++++++++++++++++++++++++++--------------- dvbapi.h | 31 +++++++++---- eit.c | 22 +++------- epg2html.pl | 4 +- i18n.c | 76 ++++++++++++++++---------------- menu.c | 65 ++++++++++++++++++++++++++- vdr.c | 3 +- 15 files changed, 457 insertions(+), 176 deletions(-) create mode 100644 ca.conf diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 1acaafc..ed63a4b 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -39,6 +39,7 @@ Martin Hammerschmid for suggesting to display the direct channel select input on the OSD for suggesting to use the "Blue" button in the main menu to resume replay for implementing pege up/down with the "Left" and "Right" keys + for detecting a deadlock when switching channels via Schedule/Now|Next/Switch Bastian Guse for writing the FORMATS entry for timers.conf diff --git a/FORMATS b/FORMATS index 0da2939..9190338 100644 --- a/FORMATS +++ b/FORMATS @@ -29,8 +29,9 @@ Video Disk Recorder File Formats If this channel also carries Dolby Digital sound, the Dolby PIDs follow the audio PIDs, separated by a semicolon, as in "...:101,102;103,104:..." - Teletext PID - - Conditional Access (0 = Free To Air, 1 = can be decrypted by the first - DVB card, 2 = can be decrypted by the second DVB card) + - Conditional Access (0 = Free To Air, 1..4 = explicitly requires the DVB card + with the given number, >=100 = requires a specific decryption method defined + in 'ca.conf'). - Program Number Fields marked with ** are only meaningful for DVB-S receivers. @@ -38,6 +39,20 @@ Video Disk Recorder File Formats Fields marked with *** are only meaningful for DVB-S and DVB-C receivers. DVB-T receivers simply ignore these. +* ca.conf + + This file contains the definitions of the various conditional access code + numbers. Anything after (and including) a '#' character is comment. + Value lines consist of an integer number, followed by a text describing + this decryption method (typically the name of the pay tv service using this + decryption method). + The special value 0 means "Free To Air", i.e. can be used for channels that + don't require additional decryption hardware. + The values 1..4 can be used for channels that for some reason explicitly + need a given DVB card (for backward compatibility). + The values defined in this file are the ones used in the 'Ca' parameter of + 'channels.conf'. + * timers.conf This file contains the timer setup. diff --git a/HISTORY b/HISTORY index 2b0093e..84c1460 100644 --- a/HISTORY +++ b/HISTORY @@ -1047,3 +1047,22 @@ Video Disk Recorder Revision History - Fixed a crash in case there is no 'epg.data' at program start (thanks to Andreas Schultz). + +2002-03-03: Version 1.0.0pre3 + +- Fixed parsing 'E' records in epg2html.pl. +- Fixed a deadlock when switching channels via Schedule/Now|Next/Switch (reported + by Martin Hammerschmid). +- Changed the meaning of the 'Ca' parameter in 'channels.conf'. Each channel can + now define which decryption method it needs in order to be accessed. The new + configuration file 'ca.conf' contains the defined values, and the default + 'channels.conf' has been modifed to contain the new values for 'Premiere World' + and 'ORF'. If you use the default 'channels.conf' and have the conditional + access hardware to receive encrypted channels, please make sure you copy the + file 'ca.conf' into your /video directory (or wherever your configuration files + are located) and go into the "Setup" menu and set the CICAM values according + to your hardware setup. Currently there are two possible CICAM entries per + DVB card, so any card can implement up to two different conditional access + modes (besides the default "Free To Air" mode, which is always assumed to be + available on any DVB card). +- Updated French language texts (thanks to Jean-Claude Repetto). diff --git a/MANUAL b/MANUAL index 320d24d..c4cda08 100644 --- a/MANUAL +++ b/MANUAL @@ -526,6 +526,14 @@ Video Disk Recorder User's Manual 0 = off 1 = on + CaCaps (no default) Defines the "Conditional Access Capabilities" of a DVB + card. The value consists of the card number, followed by + a list of decryption method values (defined in 'ca.conf'). + For instance + CaCaps = 3 101 102 + would define that card number 3 is able to decrypt + "Premiere World" and the "ORF". + * Executing system commands The "Main" menu option "Commands" allows you to execute any system commands diff --git a/ca.conf b/ca.conf new file mode 100644 index 0000000..7024ee4 --- /dev/null +++ b/ca.conf @@ -0,0 +1,22 @@ +# Conditional Access configuration for VDR +# +# Format: +# +# number description +# +# Please contact kls@cadsoft.de before assigning a new number +# to a description, in order to keep them unique. + +0 Free To Air + +# BetaCrypt + +101 Premiere World +102 ORF + +# Special values to "hard code" a channel to a specific DVB card: + +1 DVB 1 +2 DVB 2 +3 DVB 3 +4 DVB 4 diff --git a/channels.conf b/channels.conf index 4642edc..db1cbf4 100644 --- a/channels.conf +++ b/channels.conf @@ -15,8 +15,8 @@ ZDF:11954:h:0:27500:110:120:130:0:28006 3sat:11954:h:0:27500:210:220:230:0:28007 KiKa:11954:h:0:27500:310:320:330:0:28008 arte:11836:h:0:27500:401:402:404:0:28109 -ORF1:12692:h:0:22000:160:161:165:3:13001 -ORF2:12692:h:0:22000:500:501:505:3:13002 +ORF1:12692:h:0:22000:160:161:165:102:13001 +ORF2:12692:h:0:22000:500:501:505:102:13002 ORF Sat:11954:h:0:27500:506:507:0:0:28010 ZDF.info:11954:h:0:27500:610:620:0:0:28011 CNN:12168:v:0:27500:165:100:0:0:28512 @@ -49,82 +49,82 @@ B1:12110:h:0:27500:601:602:604:0:28206 ARD Online-Kanal:12722:h:0:22000:0:701:0:0:0 :Premiere World Premiere World:11797:h:0:27500:255:256:32:0:8 -Premiere 1:11797:h:0:27500:511:512:0:3:10 -Premiere 2:11797:h:0:27500:1791:1792:0:3:11 -Premiere 3:11797:h:0:27500:2303:2304:0:3:43 -Premiere One:12032:h:0:27500:3071:3072:0:3:51 -Premiere Star:11797:h:0:27500:767:768:0:3:9 -Premiere Sci-Fi:11797:h:0:27500:1535:1536:0:3:41 -Premiere Action:11797:h:0:27500:1023:1024:0:3:20 -Premiere X-Action:11798:h:0:27500:2047:2048:0:3:50 -Premiere Comedy:11797:h:0:27500:1279:1280:0:3:29 -13th Street:12031:h:0:27500:2303:2304:0:3:42 -Studio Universal:12090:V:0:27500:255:256:0:3:36 -Filmpalast:12031:h:0:27500:2559:2560:0:3:516 -Heimatkanal:12031:h:0:27500:2815:2816:0:3:517 -Discovery Channel:12031:h:0:27500:1791:1792:0:3:14 -Planet:12090:V:0:27500:1279:1280:0:3:13 -Fox Kids:12031:h:0:27500:1279:1280:0:3:28 -Fox Kids Türkce:11914:H:0:27500:767:768:8191:3:54 -Junior:12031:h:0:27500:255:256:0:3:19 -K-Toon:12031:h:0:27500:511:512:0:3:12 -Disney Channel:12090:V:0:27500:767:768:0:3:34 -Sunset:12031:h:0:27500:1023:1024:0:3:16 -Krimi&Co:12031:h:0:27500:1535:1536:0:3:23 -Goldstar TV:12031:h:0:27500:3839:3840:0:3:518 -Classica:12031:h:0:27500:767:768:0:3:15 -Seasons:12090:V:0:27500:511:512:0:3:33 +Premiere 1:11797:h:0:27500:511:512:0:101:10 +Premiere 2:11797:h:0:27500:1791:1792:0:101:11 +Premiere 3:11797:h:0:27500:2303:2304:0:101:43 +Premiere One:12032:h:0:27500:3071:3072:0:101:51 +Premiere Star:11797:h:0:27500:767:768:0:101:9 +Premiere Sci-Fi:11797:h:0:27500:1535:1536:0:101:41 +Premiere Action:11797:h:0:27500:1023:1024:0:101:20 +Premiere X-Action:11798:h:0:27500:2047:2048:0:101:50 +Premiere Comedy:11797:h:0:27500:1279:1280:0:101:29 +13th Street:12031:h:0:27500:2303:2304:0:101:42 +Studio Universal:12090:V:0:27500:255:256:0:101:36 +Filmpalast:12031:h:0:27500:2559:2560:0:101:516 +Heimatkanal:12031:h:0:27500:2815:2816:0:101:517 +Discovery Channel:12031:h:0:27500:1791:1792:0:101:14 +Planet:12090:V:0:27500:1279:1280:0:101:13 +Fox Kids:12031:h:0:27500:1279:1280:0:101:28 +Fox Kids Türkce:11914:H:0:27500:767:768:8191:101:54 +Junior:12031:h:0:27500:255:256:0:101:19 +K-Toon:12031:h:0:27500:511:512:0:101:12 +Disney Channel:12090:V:0:27500:767:768:0:101:34 +Sunset:12031:h:0:27500:1023:1024:0:101:16 +Krimi&Co:12031:h:0:27500:1535:1536:0:101:23 +Goldstar TV:12031:h:0:27500:3839:3840:0:101:518 +Classica:12031:h:0:27500:767:768:0:101:15 +Seasons:12090:V:0:27500:511:512:0:101:33 :Cinedom -Cinedom Deluxe:11758:h:0:27500:255:256,257;259:0:3:189 -Cinedom 1A:11758:h:0:27500:511:512,513:0:3:190 -Cinedom 1B:12070:h:0:27500:1535:1536,1537:0:3:178 -Cinedom 1C:11720:h:0:27500:511:512,513:0:3:180 -Cinedom 1D:11720:h:0:27500:1535:1536,1537:0:3:176 -Cinedom 2A:11758:h:0:27500:1023:1024,1025:0:3:193 -Cinedom 2B:11720:h:0:27500:1279:1280:0:3:183 -Cinedom 2C:12070:h:0:27500:1791:1792:0:3:179 -Cinedom 2D:12070:h:0:27500:511:512:0:3:184 -Cinedom 2E:12070:h:0:27500:1279:1280:0:3:188 -Cinedom 3A:11758:h:0:27500:2559:2560:0:3:192 -Cinedom 3B:11758:h:0:27500:1535:1536:0:3:195 -Cinedom 3C:12070:h:0:27500:767:768:0:3:185 -Cinedom 3D:11720:h:0:27500:1023:1024:0:3:182 -Cinedom 4A:11758:h:0:27500:767:768:0:3:191 -Cinedom 4B:11720:h:0:27500:767:768:0:3:181 -Cinedom 4C:12070:h:0:27500:2047:2048:0:3:187 -Cinedom 5A:11758:h:0:27500:1279:1280:0:3:194 -Cinedom 5B:11720:h:0:27500:1791:1792:0:3:177 -Cinedom 5C:12070:h:0:27500:1023:1024:0:3:186 +Cinedom Deluxe:11758:h:0:27500:255:256,257;259:0:101:189 +Cinedom 1A:11758:h:0:27500:511:512,513:0:101:190 +Cinedom 1B:12070:h:0:27500:1535:1536,1537:0:101:178 +Cinedom 1C:11720:h:0:27500:511:512,513:0:101:180 +Cinedom 1D:11720:h:0:27500:1535:1536,1537:0:101:176 +Cinedom 2A:11758:h:0:27500:1023:1024,1025:0:101:193 +Cinedom 2B:11720:h:0:27500:1279:1280:0:101:183 +Cinedom 2C:12070:h:0:27500:1791:1792:0:101:179 +Cinedom 2D:12070:h:0:27500:511:512:0:101:184 +Cinedom 2E:12070:h:0:27500:1279:1280:0:101:188 +Cinedom 3A:11758:h:0:27500:2559:2560:0:101:192 +Cinedom 3B:11758:h:0:27500:1535:1536:0:101:195 +Cinedom 3C:12070:h:0:27500:767:768:0:101:185 +Cinedom 3D:11720:h:0:27500:1023:1024:0:101:182 +Cinedom 4A:11758:h:0:27500:767:768:0:101:191 +Cinedom 4B:11720:h:0:27500:767:768:0:101:181 +Cinedom 4C:12070:h:0:27500:2047:2048:0:101:187 +Cinedom 5A:11758:h:0:27500:1279:1280:0:101:194 +Cinedom 5B:11720:h:0:27500:1791:1792:0:101:177 +Cinedom 5C:12070:h:0:27500:1023:1024:0:101:186 :Beta Digital N24:12480:v:0:27500:2047:2048:0:0:47 CNBC:11954:h:0:27500:510:520:0:0:28010 Liberty TV.com:12610:V:0:22000:941:943,942:0:0:12199 :PW Erotic -Beate-Uhse.TV:11758:h:0:27500:3839:3840:0:3:21 -Blue Movie 1:11758:h:0:27500:1791:1792:0:3:513 -Blue Movie 2:11758:h:0:27500:2047:2048:0:3:514 -Blue Movie 3:11758:h:0:27500:2303:2304:0:3:515 +Beate-Uhse.TV:11758:h:0:27500:3839:3840:0:101:21 +Blue Movie 1:11758:h:0:27500:1791:1792:0:101:513 +Blue Movie 2:11758:h:0:27500:2047:2048:0:101:514 +Blue Movie 3:11758:h:0:27500:2303:2304:0:101:515 :Sportsworld -Premiere Sport 1:11720:h:0:27500:255:256,257:0:3:17 -Premiere Sport 2:12070:h:0:27500:3839:3840:0:3:27 -Premiere Sport 3:12070:h:0:27500:255:256:0:3:26 +Premiere Sport 1:11720:h:0:27500:255:256,257:0:101:17 +Premiere Sport 2:12070:h:0:27500:3839:3840:0:101:27 +Premiere Sport 3:12070:h:0:27500:255:256:0:101:26 :Formel 1 -Infokanal:11720:h:0:27500:3071:3072:0:3:244 -Multikanal:11720:h:0:27500:2815:2816:0:3:243 -Supersignal:11720:h:0:27500:255:256:0:3:17 -Verfolgerfeld:11720:h:0:27500:2303:2304:0:3:241 -Cockpitkanal:11720:h:0:27500:2559:2560:0:3:242 -Boxengasse:11720:h:0:27500:2047:2048:0:3:240 +Infokanal:11720:h:0:27500:3071:3072:0:101:244 +Multikanal:11720:h:0:27500:2815:2816:0:101:243 +Supersignal:11720:h:0:27500:255:256:0:101:17 +Verfolgerfeld:11720:h:0:27500:2303:2304:0:101:241 +Cockpitkanal:11720:h:0:27500:2559:2560:0:101:242 +Boxengasse:11720:h:0:27500:2047:2048:0:101:240 :Premiere World Bundesliga -Superdom:11758:h:0:27500:2815:8192:0:3:18 -BuLi-Konferenz:11758:h:0:27500:3327:3328,3329:0:3:215 -BuLi-Spiel 1:11720:h:0:27500:255:256,257:0:3:17 -BuLi-Spiel 2:11720:h:0:27500:2047:2048,2049:0:3:240 -BuLi-Spiel 3:11720:h:0:27500:2303:2304,2305:0:3:241 -BuLi-Spiel 4:11720:h:0:27500:2559:2560,2561:0:3:242 -BuLi-Spiel 5:11720:h:0:27500:2815:2816,2817:0:3:243 -BuLi-Spiel 6:11720:h:0:27500:3071:3072,3073:0:3:244 -BuLi-Spiel 7:11758:h:0:27500:3071:3072,3073:0:3:214 +Superdom:11758:h:0:27500:2815:8192:0:101:18 +BuLi-Konferenz:11758:h:0:27500:3327:3328,3329:0:101:215 +BuLi-Spiel 1:11720:h:0:27500:255:256,257:0:101:17 +BuLi-Spiel 2:11720:h:0:27500:2047:2048,2049:0:101:240 +BuLi-Spiel 3:11720:h:0:27500:2303:2304,2305:0:101:241 +BuLi-Spiel 4:11720:h:0:27500:2559:2560,2561:0:101:242 +BuLi-Spiel 5:11720:h:0:27500:2815:2816,2817:0:101:243 +BuLi-Spiel 6:11720:h:0:27500:3071:3072,3073:0:101:244 +BuLi-Spiel 7:11758:h:0:27500:3071:3072,3073:0:101:214 : TV Niepokalanow:11876:h:0:27500:305:321:0:0:20601 Mosaico:11934:v:0:27500:165:100:0:0:29010 diff --git a/config.c b/config.c index 213fe2c..a91cb8a 100644 --- a/config.c +++ b/config.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.87 2002/02/24 11:59:14 kls Exp $ + * $Id: config.c 1.88 2002/03/03 16:04:21 kls Exp $ */ #include "config.h" @@ -732,6 +732,24 @@ bool cSVDRPhost::Accepts(in_addr_t Address) return (Address & mask) == addr.s_addr; } +// -- cCaDefinition ---------------------------------------------------------- + +cCaDefinition::cCaDefinition(void) +{ + number = 0; + description = NULL; +} + +cCaDefinition::~cCaDefinition() +{ + delete description; +} + +bool cCaDefinition::Parse(const char *s) +{ + return 2 == sscanf(s, "%d %a[^\n]", &number, &description) && description && *description; +} + // -- cKeys ------------------------------------------------------------------ cKeys Keys; @@ -879,6 +897,21 @@ bool cSVDRPhosts::Acceptable(in_addr_t Address) return false; } +// -- cCaDefinitions --------------------------------------------------------- + +cCaDefinitions CaDefinitions; + +const cCaDefinition *cCaDefinitions::Get(int Number) +{ + cCaDefinition *p = First(); + while (p) { + if (p->Number() == Number) + return p; + p = (cCaDefinition *)p->Next(); + } + return NULL; +} + // -- cSetup ----------------------------------------------------------------- cSetup Setup; @@ -921,10 +954,46 @@ cSetup::cSetup(void) MinUserInactivity = 120; MultiSpeedMode = 0; ShowReplayMode = 0; + memset(CaCaps, sizeof(CaCaps), 0); CurrentChannel = -1; CurrentVolume = MAXVOLUME; } +void cSetup::PrintCaCaps(FILE *f, const char *Name) +{ + for (int d = 0; d < MAXDVBAPI; d++) { + if (CaCaps[d][0]) { + fprintf(f, "CaCaps = %d", d + 1); + for (int i = 0; i < MAXCACAPS && CaCaps[d][i]; i++) + fprintf(f, " %d", CaCaps[d][i]); + fprintf(f, "\n"); + } + } +} + +bool cSetup::ParseCaCaps(const char *Value) +{ + char *p; + int d = strtol(Value, &p, 10); + if (d > 0 && d < MAXDVBAPI) { + d--; + int i = 0; + while (p != Value && p && *p) { + if (i < MAXCACAPS) { + int c = strtol(p, &p, 10); + if (c > 0) + CaCaps[d][i++] = c; + else + return false; + } + else + return false; + } + return true; + } + return false; +} + bool cSetup::Parse(char *s) { char *p = strchr(s, '='); @@ -967,6 +1036,7 @@ bool cSetup::Parse(char *s) else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value); else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value); else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value); + else if (!strcasecmp(Name, "CaCaps")) return ParseCaCaps(Value); else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value); else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value); else @@ -1047,6 +1117,7 @@ bool cSetup::Save(const char *FileName) fprintf(f, "MinUserInactivity = %d\n", MinUserInactivity); fprintf(f, "MultiSpeedMode = %d\n", MultiSpeedMode); fprintf(f, "ShowReplayMode = %d\n", ShowReplayMode); + PrintCaCaps(f, "CaCaps"); fprintf(f, "CurrentChannel = %d\n", CurrentChannel); fprintf(f, "CurrentVolume = %d\n", CurrentVolume); if (f.Close()) { diff --git a/config.h b/config.h index b5860d1..f5e8343 100644 --- a/config.h +++ b/config.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.100 2002/02/25 16:29:09 kls Exp $ + * $Id: config.h 1.102 2002/03/03 16:04:43 kls Exp $ */ #ifndef __CONFIG_H @@ -19,7 +19,7 @@ #include "eit.h" #include "tools.h" -#define VDRVERSION "1.0.0pre2" +#define VDRVERSION "1.0.0pre3" #define MAXPRIORITY 99 #define MAXLIFETIME 99 @@ -195,6 +195,18 @@ public: bool Accepts(in_addr_t Address); }; +class cCaDefinition : public cListObject { +private: + int number; + char *description; +public: + cCaDefinition(void); + ~cCaDefinition(); + bool Parse(const char *s); + int Number(void) const { return number; } + const char *Description(void) const { return description; } + }; + template class cConfig : public cList { private: char *fileName; @@ -297,15 +309,23 @@ public: bool Acceptable(in_addr_t Address); }; +class cCaDefinitions : public cConfig { +public: + const cCaDefinition *Get(int Number); + }; + extern cChannels Channels; extern cTimers Timers; extern cKeys Keys; extern cCommands Commands; extern cSVDRPhosts SVDRPhosts; +extern cCaDefinitions CaDefinitions; class cSetup { private: static char *fileName; + void PrintCaCaps(FILE *f, const char *Name); + bool ParseCaCaps(const char *Value); bool Parse(char *s); public: // Also adjust cMenuSetup (menu.c) when adding parameters here! @@ -339,6 +359,7 @@ public: int MinEventTimeout, MinUserInactivity; int MultiSpeedMode; int ShowReplayMode; + int CaCaps[MAXDVBAPI][MAXCACAPS]; int CurrentChannel; int CurrentVolume; cSetup(void); diff --git a/dvbapi.c b/dvbapi.c index 55bc573..2f1ca14 100644 --- a/dvbapi.c +++ b/dvbapi.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.c 1.152 2002/02/24 12:53:51 kls Exp $ + * $Id: dvbapi.c 1.154 2002/03/03 15:43:24 kls Exp $ */ #include "dvbapi.h" @@ -1684,9 +1684,10 @@ cDvbApi::cDvbApi(int n) replayBuffer = NULL; transferBuffer = NULL; transferringFromDvbApi = NULL; - ca = 0; + ca = -1; priority = -1; cardIndex = n; + SetCaCaps(); // Devices that are only present on DVB-C or DVB-S cards: @@ -1783,37 +1784,93 @@ bool cDvbApi::SetPrimaryDvbApi(int n) return false; } +int cDvbApi::CanShift(int Ca, int Priority) +{ + // Test whether a recording on this DVB device can be shifted to another one + // in order to perform a new recording with the given Ca and Priority on this device: + int ShiftLevel = -1; // default means this device can't be shifted + if (Recording()) { + if (ProvidesCa(Ca) // this device provides the requested Ca + && (Ca != this->Ca() // the requested Ca is different from the one currently used... + || Priority > this->Priority())) { // ...or the request comes from a higher priority + cDvbApi *d = NULL; + int Provides[MAXDVBAPI]; + for (int i = 0; i < NumDvbApis; i++) { + if ((Provides[i] = dvbApi[i]->ProvidesCa(this->Ca())) != 0) { // this device is basicly able to do the job + if (dvbApi[i] != this) { // it is not _this_ device + int sl = dvbApi[i]->CanShift(this->Ca(), Priority); // this is the original Priority! + if (sl >= 0 && (ShiftLevel < 0 || sl < ShiftLevel)) { + d = dvbApi[i]; + ShiftLevel = sl; + } + } + } + } + if (ShiftLevel >= 0) + ShiftLevel++; // adds the device's own shift + } + } + else if (Priority > this->Priority()) + ShiftLevel = 0; // no shifting necessary, this device can do the job + return ShiftLevel; +} + cDvbApi *cDvbApi::GetDvbApi(int Ca, int Priority) { - cDvbApi *d = NULL, *dMinPriority = NULL; - int index = Ca - 1; - for (int i = 0; i < MAXDVBAPI; i++) { - if (dvbApi[i]) { - if (dvbApi[i]->CardIndex() == index) { // means we need exactly _this_ device + cDvbApi *d = NULL; + int Provides[MAXDVBAPI]; + // Check which devices provide Ca: + for (int i = 0; i < NumDvbApis; i++) { + if ((Provides[i] = dvbApi[i]->ProvidesCa(Ca)) != 0) { // this device is basicly able to do the job + if (Priority > dvbApi[i]->Priority() // Priority is high enough to use this device + && (!d // we don't have a device yet, or... + || dvbApi[i]->Priority() < d->Priority() // ...this one has an even lower Priority + || (dvbApi[i]->Priority() == d->Priority() // ...same Priority... + && Provides[i] < Provides[d->CardIndex()]))) // ...but this one provides fewer Ca values d = dvbApi[i]; - break; - } - else if (Ca == 0) { // means any device would be acceptable - if (!d || !dvbApi[i]->Recording() || (d->Recording() && d->Priority() > dvbApi[i]->Priority())) - d = dvbApi[i]; // this is one that is either not currently recording or has the lowest priority - if (d && d != PrimaryDvbApi && !d->Recording()) // avoids the PrimaryDvbApi if possible - break; - if (d && d->Recording() && d->Priority() < Setup.PrimaryLimit && (!dMinPriority || d->Priority() < dMinPriority->Priority())) - dMinPriority = d; // this is the one with the lowest priority below Setup.PrimaryLimit - } } } - if (d == PrimaryDvbApi) { // the PrimaryDvbApi was the only one that was free - if (Priority < Setup.PrimaryLimit) - return NULL; // not enough priority to use the PrimaryDvbApi - if (dMinPriority) // there's one that must not use the PrimaryDvbApi... - d = dMinPriority; // ...so let's kick out that one + if (!d && Ca > MAXDVBAPI) { + // We didn't find one the easy way, so now we have to try harder: + int ShiftLevel = -1; + for (int i = 0; i < NumDvbApis; i++) { + if (Provides[i]) { // this device is basicly able to do the job, but for some reason we didn't get it above + int sl = dvbApi[i]->CanShift(Ca, Priority); // asks this device to shift its job to another device + if (sl >= 0 && (ShiftLevel < 0 || sl < ShiftLevel)) { + d = dvbApi[i]; // found one that can be shifted with the fewest number of subsequent shifts + ShiftLevel = sl; + } + } + } } - return (d // we found one... - && (!d->Recording() // ...that's either not currently recording... - || d->Priority() < Priority // ...or has a lower priority... - || (!d->Ca() && Ca))) // ...or doesn't need this card - ? d : NULL; + return d; +} + +void cDvbApi::SetCaCaps(void) +{ + for (int i = 0; i < MAXCACAPS; i++) + caCaps[i] = Setup.CaCaps[CardIndex()][i]; +} + +int cDvbApi::ProvidesCa(int Ca) +{ + if (Ca == CardIndex() + 1) + return 1; // exactly _this_ card was requested + if (Ca && Ca <= MAXDVBAPI) + return 0; // a specific card was requested, but not _this_ one + int result = Ca ? 0 : 1; // by default every card can provide FTA + int others = Ca ? 1 : 0; + for (int i = 0; i < MAXCACAPS; i++) { + if (caCaps[i]) { + if (caCaps[i] == Ca) + result = 1; + else + others++; + } + else + break; + } + return result ? result + others : 0; } bool cDvbApi::Probe(const char *FileName) @@ -1854,7 +1911,7 @@ bool cDvbApi::Init(void) void cDvbApi::Cleanup(void) { - for (int i = 0; i < MAXDVBAPI; i++) { + for (int i = 0; i < NumDvbApis; i++) { delete dvbApi[i]; dvbApi[i] = NULL; } @@ -2148,6 +2205,11 @@ void cDvbApi::Flush(void) #endif } +int cDvbApi::Priority(void) +{ + return (this == PrimaryDvbApi && !Recording()) ? Setup.PrimaryLimit - 1 : priority; +} + int cDvbApi::SetModeRecord(void) { // Sets up the DVB device for recording @@ -2238,9 +2300,6 @@ bool cDvbApi::SetPids(bool ForRecording) eSetChannelResult cDvbApi::SetChannel(int ChannelNumber, int Frequency, char Polarization, int Diseqc, int Srate, int Vpid, int Apid1, int Apid2, int Dpid1, int Dpid2, int Tpid, int Ca, int Pnr) { - // Make sure the siProcessor won't access the device while switching - cThreadLock ThreadLock(siProcessor); - StopTransfer(); StopReplay(); @@ -2265,7 +2324,7 @@ eSetChannelResult cDvbApi::SetChannel(int ChannelNumber, int Frequency, char Pol // If this card can't receive this channel, we must not actually switch // the channel here, because that would irritate the driver when we // start replaying in Transfer Mode immediately after switching the channel: - bool NeedsTransferMode = (this == PrimaryDvbApi && Ca && Ca != CardIndex() + 1); + bool NeedsTransferMode = (this == PrimaryDvbApi && !ProvidesCa(Ca)); if (!NeedsTransferMode) { @@ -2507,7 +2566,7 @@ void cDvbApi::StopRecord(void) if (recordBuffer) { delete recordBuffer; recordBuffer = NULL; - ca = 0; + ca = -1; priority = -1; } } @@ -2706,7 +2765,7 @@ void cEITScanner::Process(void) time_t now = time(NULL); if (now - lastScan > ScanTimeout && now - lastActivity > ActivityTimeout) { for (int i = 0; i < MAXDVBAPI; i++) { - cDvbApi *DvbApi = cDvbApi::GetDvbApi(i + 1, MAXPRIORITY); + cDvbApi *DvbApi = cDvbApi::GetDvbApi(i + 1, MAXPRIORITY + 1); if (DvbApi) { if (DvbApi != cDvbApi::PrimaryDvbApi || (cDvbApi::NumDvbApis == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) { if (!(DvbApi->Recording() || DvbApi->Replaying() || DvbApi->Transferring())) { diff --git a/dvbapi.h b/dvbapi.h index 06028f0..396b5c2 100644 --- a/dvbapi.h +++ b/dvbapi.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.h 1.63 2002/02/24 12:38:08 kls Exp $ + * $Id: dvbapi.h 1.64 2002/03/03 14:51:20 kls Exp $ */ #ifndef __DVBAPI_H @@ -94,12 +94,16 @@ private: public: ~cDvbApi(); -#define MAXDVBAPI 4 +#define MAXDVBAPI 4 // the maximum number of DVB cards in the system +#define MAXCACAPS 16 // the maximum number of different CA values per DVB card + static int NumDvbApis; private: static cDvbApi *dvbApi[MAXDVBAPI]; static int useDvbApi; int cardIndex; + int caCaps[MAXCACAPS]; + int CanShift(int Ca, int Priority); public: static cDvbApi *PrimaryDvbApi; static void SetUseDvbApi(int n); @@ -110,9 +114,10 @@ public: // Sets the primary DVB device to 'n' (which must be in the range // 1...NumDvbApis) and returns true if this was possible. static cDvbApi *GetDvbApi(int Ca, int Priority); - // Selects a free DVB device, starting with the highest device number - // (but avoiding, if possible, the PrimaryDvbApi). - // If Ca is not 0, the device with the given number will be returned. + // Selects a free DVB device, avoiding the PrimaryDvbApi if possible. + // If Ca is not 0, the device with the given number will be returned + // in case Ca is <= MAXDVBAPI, or the device that provides the given + // value in its caCaps. // If all DVB devices are currently recording, the one recording the // lowest priority timer (if any) that is lower than the given Priority // will be returned. @@ -120,6 +125,15 @@ public: // recording and stop recording if necessary. int CardIndex(void) { return cardIndex; } // Returns the card index of this DvbApi (0 ... MAXDVBAPI - 1). + void SetCaCaps(void); + // Sets the CaCaps of this DVB device according to the Setup data. + int ProvidesCa(int Ca); + // Checks whether this DVB device provides the given value in its + // caCaps. Returns 0 if the value is not provided, 1 if only this + // value is provided, and > 1 if this and other values are provided. + // If the given value is equal to the number of this DVB device, + // 1 is returned. If it is 0 (FTA), 1 plus the number of other values + // in caCaps is returned. static bool Probe(const char *FileName); // Probes for existing DVB devices. static bool Init(void); @@ -204,16 +218,17 @@ private: cPlayBuffer *replayBuffer; int ca; int priority; - int Priority(void) { return priority; } + int Priority(void); // Returns the priority of the current recording session (0..MAXPRIORITY), - // or -1 if no recording is currently active. + // or -1 if no recording is currently active. The primary DVB device will + // always return at least Setup.PrimaryLimit-1. int SetModeRecord(void); // Initiates recording mode and returns the file handle to read from. void SetModeReplay(void); void SetModeNormal(bool FromRecording); public: int Ca(void) { return ca; } - // Returns the ca of the current recording session (0..MAXDVBAPI). + // Returns the ca of the current recording session. int SecondsToFrames(int Seconds); // Returns the number of frames corresponding to the given number of seconds. bool Recording(void); diff --git a/eit.c b/eit.c index 8f4c037..9985fbb 100644 --- a/eit.c +++ b/eit.c @@ -16,7 +16,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.c 1.38 2002/02/25 16:30:42 kls Exp $ + * $Id: eit.c 1.39 2002/03/01 16:32:11 kls Exp $ ***************************************************************************/ #include "eit.h" @@ -1047,8 +1047,6 @@ const char *cSIProcessor::GetEpgDataFileName(void) void cSIProcessor::SetStatus(bool On) { - LOCK_THREAD; - schedulesMutex.Lock(); ShutDownFilters(); if (On) { @@ -1061,7 +1059,6 @@ void cSIProcessor::SetStatus(bool On) AddFilter(0x12, 0x51); // event info, actual TS, schedule for another 4 days AddFilter(0x12, 0x61); // event info, other TS, schedule for another 4 days } - schedulesMutex.Unlock(); } /** use the vbi device to parse all relevant SI @@ -1085,20 +1082,15 @@ void cSIProcessor::Action() struct tm *ptm = localtime_r(&now, &tm_r); if (now - lastCleanup > 3600 && ptm->tm_hour == 5) { - LOCK_THREAD; - - schedulesMutex.Lock(); + cMutexLock MutexLock(&schedulesMutex); isyslog(LOG_INFO, "cleaning up schedules data"); schedules->Cleanup(); - schedulesMutex.Unlock(); lastCleanup = now; ReportEpgBugFixStats(true); } if (epgDataFileName && now - lastDump > 600) { - LOCK_THREAD; - - schedulesMutex.Lock(); + cMutexLock MutexLock(&schedulesMutex); FILE *f = fopen(GetEpgDataFileName(), "w"); if (f) { schedules->Dump(f); @@ -1107,7 +1099,6 @@ void cSIProcessor::Action() else LOG_ERROR; lastDump = now; - schedulesMutex.Unlock(); } } @@ -1162,12 +1153,9 @@ void cSIProcessor::Action() case 0x12: if (buf[0] != 0x72) { - LOCK_THREAD; - - schedulesMutex.Lock(); + cMutexLock MutexLock(&schedulesMutex); cEIT ceit(buf, seclen, schedules); ceit.ProcessEIT(buf); - schedulesMutex.Unlock(); } else dsyslog(LOG_INFO, "Received stuffing section in EIT\n"); @@ -1261,6 +1249,6 @@ bool cSIProcessor::ShutDownFilters(void) /** */ bool cSIProcessor::SetCurrentServiceID(unsigned short servid) { - LOCK_THREAD; + cMutexLock MutexLock(&schedulesMutex); return schedules ? schedules->SetCurrentServiceID(servid) : false; } diff --git a/epg2html.pl b/epg2html.pl index 215eb73..cdeb638 100755 --- a/epg2html.pl +++ b/epg2html.pl @@ -12,7 +12,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: epg2html.pl 1.2 2000/12/01 18:37:46 kls Exp $ +# $Id: epg2html.pl 1.3 2002/02/26 22:10:47 kls Exp $ @Index = (); @@ -45,7 +45,7 @@ while (<>) { push(@Index, qq{$Channel
\n}); my %Events = (); while (<>) { - if (/^E (.*) (.*) (.*)/) { + if (/^E (.*?) (.*?) (.*?)/) { (my $Time, $Duration) = ($2, $3); my $Title = "", $Subtitle = "", $Description = ""; while (<>) { diff --git a/i18n.c b/i18n.c index 0839715..2b52c68 100644 --- a/i18n.c +++ b/i18n.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.57 2002/02/24 12:54:12 kls Exp $ + * $Id: i18n.c 1.59 2002/03/03 16:38:57 kls Exp $ * * Slovenian translations provided by Miha Setina * Italian translations provided by Alberto Carraro @@ -257,7 +257,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Marche/Arr", "", // TODO "", // TODO }, @@ -317,7 +317,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Ouvrir", "", // TODO "Avaa", }, @@ -418,7 +418,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Enregistrement en cours - confirmez la suppression", "", // TODO "", // TODO }, @@ -438,7 +438,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "sur la carte principale", "", // TODO "päävastaanottimella", }, @@ -458,7 +458,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Enregistrement en cours - confirmez l'arrêt", "", // TODO "Nauhoitus kesken - lopetetaanko se?", }, @@ -468,7 +468,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Enregistrement dans %d minutes - confirmez l'arrêt", // TODO "", // TODO "", // TODO }, @@ -478,7 +478,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Appuyez sur une touche pour annuler l'arrêt", "", // TODO "Peruuta pysäytys painamalla jotakin näppäintä", }, @@ -700,7 +700,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Premier jour", "", // TODO "", // TODO }, @@ -741,7 +741,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Impossible d'accèder à l'enregistrement", "", // TODO "Nauhoituksen toistaminen epäonnistui!", }, @@ -791,7 +791,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Impossible d'utiliser le mode transfert!", "", // TODO "Käsittämättömiä teknisiä ongelmia!", }, @@ -821,7 +821,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Arrêt impossible - option '-s' absente!", "", // TODO "Ei voida sammuttaa '-s' parametria ei annettu!", }, @@ -831,7 +831,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Disque presque plein!", "", // TODO "Kovalevy lähes täynnä!", }, @@ -892,7 +892,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Noms enregistr. immédiats", "", // TODO "Nimeä välitön nauh.", }, @@ -982,7 +982,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Niveau de correction EPG", "", // TODO "EPGBugfixLevel", }, @@ -1002,7 +1002,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Trier les programmations", "", // TODO "Järjestä ajastimet", }, @@ -1042,7 +1042,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Utiliser les sous-titres", "", // TODO "Tekstitys käytössä", }, @@ -1052,7 +1052,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Dossiers d'enregistrements", "", // TODO "Nauhoitushakemistot", }, @@ -1072,7 +1072,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Enregistrer en Dolby Digital", "", // TODO "", // TODO }, @@ -1112,7 +1112,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Durée affichage écran", "", // TODO "Ilmoitusten näkymisaika", }, @@ -1122,7 +1122,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Taille maxi des fichiers", "", // TODO "Maksimi tiedoston koko", }, @@ -1132,7 +1132,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Séparer les séquences", "", // TODO "Paloittele muokatut", }, @@ -1141,8 +1141,8 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO - "", // TODO + "", // TODO + "MinEventTimeout", // Too difficult to translate - read the manual! "", // TODO "Minimi tapahtuman odotus", }, @@ -1152,7 +1152,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Durée minimale d'inactivité", "", // TODO "Minimi käyttäjän odotus", }, @@ -1162,7 +1162,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Mode multi-vitesses", "", // TODO "Moninopeustila", }, @@ -1172,7 +1172,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Affichage mode de lecture", "", // TODO "Näytä toiston tila", }, @@ -1193,7 +1193,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "LunMarMerJeuVenSamDim", "", // TODO "MaaTiiKesTorPerLauSun", }, @@ -1445,7 +1445,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Arrêt", "", // TODO "Virtakytkin", }, @@ -1455,7 +1455,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Volume+", "", // TODO "Äänenvoimakkuus+", }, @@ -1465,7 +1465,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Volume-", "", // TODO "Äänenvoimakkuus-", }, @@ -1475,7 +1475,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Coupure du son", "", // TODO "Äänen vaimennus", }, @@ -1526,7 +1526,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "restant", "", // TODO "vapaa", }, @@ -1536,9 +1536,9 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO + "Accès direct: ", "", // TODO - "", // TODO - "Hyppää", + "Hyppää:", }, { " Stop replaying", // note the leading blank! " Wiedergabe beenden", @@ -1606,7 +1606,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Montage terminé", "", // TODO "Muokkaus lopetettu", }, @@ -1616,7 +1616,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Echec du montage", "", // TODO "Muokkaus epäonnistui", }, @@ -1626,7 +1626,7 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Recherche des enregistrements...", "", // TODO "haetaan nauhoituksia...", }, diff --git a/menu.c b/menu.c index 28e5d4d..b1e7e49 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.159 2002/02/24 12:55:49 kls Exp $ + * $Id: menu.c 1.160 2002/03/03 16:12:29 kls Exp $ */ #include "menu.h" @@ -585,6 +585,60 @@ void cMenuEditStraItem::Set(void) SetValue(strings[*value]); } +// --- cMenuEditCaItem ------------------------------------------------------- + +class cMenuEditCaItem : public cMenuEditIntItem { +private: + const cCaDefinition *ca; + bool allowCardNr; +protected: + virtual void Set(void); +public: + cMenuEditCaItem(const char *Name, int *Value, bool AllowCardNr = false); + eOSState ProcessKey(eKeys Key); + }; + +cMenuEditCaItem::cMenuEditCaItem(const char *Name, int *Value, bool AllowCardNr) +:cMenuEditIntItem(Name, Value, 0) +{ + ca = CaDefinitions.Get(*Value); + allowCardNr = AllowCardNr; + Set(); +} + +void cMenuEditCaItem::Set(void) +{ + if (ca) + SetValue(ca->Description()); + else + cMenuEditIntItem::Set(); +} + +eOSState cMenuEditCaItem::ProcessKey(eKeys Key) +{ + eOSState state = cMenuEditItem::ProcessKey(Key); + + if (state == osUnknown) { + if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly? + if (ca && ca->Prev()) { + ca = (cCaDefinition *)ca->Prev(); + *value = ca->Number(); + } + } + else if (NORMALKEY(Key) == kRight) { + if (ca && ca->Next() && (allowCardNr || ((cCaDefinition *)ca->Next())->Number() > MAXDVBAPI)) { + ca = (cCaDefinition *)ca->Next(); + *value = ca->Number(); + } + } + else + return cMenuEditIntItem::ProcessKey(Key); + Set(); + state = osContinue; + } + return state; +} + // --- cMenuEditChannel ------------------------------------------------------ class cMenuEditChannel : public cOsdMenu { @@ -613,7 +667,7 @@ cMenuEditChannel::cMenuEditChannel(int Index) Add(new cMenuEditIntItem( tr("Dpid1"), &data.dpid1, 0, 0x1FFF)); Add(new cMenuEditIntItem( tr("Dpid2"), &data.dpid2, 0, 0x1FFF)); Add(new cMenuEditIntItem( tr("Tpid"), &data.tpid, 0, 0x1FFF)); - Add(new cMenuEditIntItem( tr("CA"), &data.ca, 0, cDvbApi::NumDvbApis)); + Add(new cMenuEditCaItem( tr("CA"), &data.ca, true)); Add(new cMenuEditIntItem( tr("Pnr"), &data.pnr, 0)); } } @@ -1880,6 +1934,13 @@ void cMenuSetup::Set(void) Add(new cMenuEditIntItem( tr("MinUserInactivity"), &data.MinUserInactivity)); Add(new cMenuEditBoolItem(tr("MultiSpeedMode"), &data.MultiSpeedMode)); Add(new cMenuEditBoolItem(tr("ShowReplayMode"), &data.ShowReplayMode)); + for (int d = 0; d < cDvbApi::NumDvbApis; d++) { + for (int i = 0; i < 2; i++) { + char buffer[32]; + snprintf(buffer, sizeof(buffer), "%s%d %d", tr("CICAM DVB"), d + 1, i + 1); + Add(new cMenuEditCaItem(buffer, &data.CaCaps[d][i])); + } + } } eOSState cMenuSetup::ProcessKey(eKeys Key) diff --git a/vdr.c b/vdr.c index 90c1d84..a246be1 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.97 2002/02/24 12:55:10 kls Exp $ + * $Id: vdr.c 1.98 2002/03/03 14:56:03 kls Exp $ */ #include @@ -252,6 +252,7 @@ int main(int argc, char *argv[]) Timers.Load(AddDirectory(ConfigDirectory, "timers.conf")); Commands.Load(AddDirectory(ConfigDirectory, "commands.conf")); SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true); + CaDefinitions.Load(AddDirectory(ConfigDirectory, "ca.conf"), true); #if defined(REMOTE_LIRC) Keys.SetDummyValues(); #elif !defined(REMOTE_NONE) -- cgit v1.2.3