diff --git a/HISTORY b/HISTORY index 859e783e..1e6b5d3b 100644 --- a/HISTORY +++ b/HISTORY @@ -139,16 +139,18 @@ Video Disk Recorder Revision History parameters in the default 'channels.conf' have also been updated, so please make sure your timers still use the correct channels! -2000-09-09: Version 0.63 +2000-09-10: Version 0.63 +- The new "Setup" menu allows the user to configure several parameters to his/her + personal taste (see MANUAL for details). - Workaround for a driver timing problem in cDvbApi::Cmd(), which sometimes caused the OSD to no longer be displayed (thanks to Niels de Carpentier). - Added the '-m486' option to the compiler call. - If a channel name contains a colon (':') it is now replaced with a '|' in channels.conf. - Not everybody appears to like the "page scrolling" mechanism introduced by - Heino Goldenstein in version 0.61, so the Makefile now reacts on NO_PAGE_SCROLL=1 - to suppress that. + Heino Goldenstein in version 0.61, so this is now configurable via the "Setup" + menu. - The new 'dvbrc2vdr' tool (thanks to Plamen Ganev!) can be used to convert 'dvbrc' channel files into 'vdr' format. - Channels can now be "grouped" (thanks to Plamen Ganev!). See MANUAL for details. @@ -158,3 +160,6 @@ Video Disk Recorder Revision History XXX additional fields for 'preferred' etc??? - Started a new file named FORMATS with a description of the various file formats used by VDR. +- The "Primary DVB interface" can now be chosen via the "Setup" menu. +- Display of the "current/next" information when switching channels can now + be disabled via the "Setup" menu. diff --git a/MANUAL b/MANUAL index 4291f76b..6cf91423 100644 --- a/MANUAL +++ b/MANUAL @@ -165,3 +165,32 @@ Video Disk Recorder User's Manual their date and time). If this field is left blank, the channel name will be used to form the name of the recording. + +* Parameters in the "Setup" menu + + Select "Setup" from the main menu to enter the setup menu. From there you can + modify the following system parameters (note that "boolean" values will be + displayed as "no" and "yes" in the "Setup" menu, while in the setup file they + are stored as '0' and '1', respectively): + + PrimaryDVB = 1 Defines the primary DVB interface (i.e. the one that + will display the menus and will react on input through + the remote control). Valid values range from '1' to the + number of installed DVB cards. If more than one DVB card + is installed and a recording is to be started, the + program will try to use a free DVB card that is different + from the primary DVB interface, so that the viewer will + be disturbed as little as possible. + + ShowInfoOnChSwitch = 1 Turns the display of the current/next information on + or off when switching the channel. The information is + always displayed when pressing the "Ok" button in + normal viewing mode. + + MenuScrollPage = 1 0 = when pressing the "Down" ("Up") key while the cursor + is on the last (first) line of a list page, the + list is advanced by a full page and the cursor will + be at the top (bottom) of that page + 1 = dto., but the cursor remains at the bottom (top) of + the page (this mode allows for faster scrolling + through long lists) diff --git a/Makefile b/Makefile index 6f3e7014..2f00459b 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 1.8 2000/09/03 15:38:18 kls Exp $ +# $Id: Makefile 1.9 2000/09/10 08:55:45 kls Exp $ DVBDIR = ../DVB @@ -21,10 +21,6 @@ ifdef DEBUG_OSD DEFINES += -DDEBUG_OSD endif -ifdef NO_PAGE_SCROLL -DEFINES += -DNO_PAGE_SCROLL -endif - %.o: %.c g++ -g -O2 -Wall -m486 -c $(DEFINES) $(INCLUDES) $< diff --git a/config.c b/config.c index 32f910ec..48ac3e5e 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.19 2000/09/09 14:50:58 kls Exp $ + * $Id: config.c 1.20 2000/09/10 10:30:15 kls Exp $ */ #include "config.h" @@ -575,3 +575,81 @@ cTimer *cTimers::GetTimer(cTimer *Timer) return NULL; } +// -- cSetup ----------------------------------------------------------------- + +cSetup Setup; + +char *cSetup::fileName = NULL; + +cSetup::cSetup(void) +{ + PrimaryDVB = 1; + ShowInfoOnChSwitch = 1; + MenuScrollPage = 1; +} + +bool cSetup::Parse(char *s) +{ + const char *Delimiters = " \t\n="; + char *Name = strtok(s, Delimiters); + char *Value = strtok(NULL, Delimiters); + if (Name && Value) { + if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value); + else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value); + else if (!strcasecmp(Name, "MenuScrollPage")) MenuScrollPage = atoi(Value); + else + return false; + return true; + } + return false; +} + +bool cSetup::Load(const char *FileName) +{ + isyslog(LOG_INFO, "loading %s", FileName); + delete fileName; + fileName = strdup(FileName); + FILE *f = fopen(fileName, "r"); + if (f) { + int line = 0; + char buffer[MaxBuffer]; + bool result = true; + while (fgets(buffer, sizeof(buffer), f) > 0) { + line++; + if (*buffer != '#' && !Parse(buffer)) { + esyslog(LOG_ERR, "error in %s, line %d\n", fileName, line); + result = false; + break; + } + } + fclose(f); + return result; + } + else + LOG_ERROR_STR(FileName); + return false; +} + +bool cSetup::Save(const char *FileName) +{ + if (!FileName) + FileName = fileName; + if (FileName) { + FILE *f = fopen(FileName, "w"); + if (f) { + fprintf(f, "# VDR Setup\n"); + fprintf(f, "PrimaryDVB = %d\n", PrimaryDVB); + fprintf(f, "ShowInfoOnChSwitch = %d\n", ShowInfoOnChSwitch); + fprintf(f, "MenuScrollPage = %d\n", MenuScrollPage); + fclose(f); + isyslog(LOG_INFO, "saved setup to %s", FileName); + return true; + } + else + LOG_ERROR_STR(FileName); + } + else + esyslog(LOG_ERR, "attempt to save setup without file name"); + return false; +} + diff --git a/config.h b/config.h index 2a8954b7..0d54ffb9 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.16 2000/09/09 14:21:35 kls Exp $ + * $Id: config.h 1.17 2000/09/10 10:29:05 kls Exp $ */ #ifndef __CONFIG_H @@ -156,7 +156,7 @@ public: fclose(f); } else { - esyslog(LOG_ERR, "can't open '%s'\n", fileName); + LOG_ERROR_STR(fileName); result = false; } return result; @@ -177,8 +177,10 @@ public: } fclose(f); } - else + else { + LOG_ERROR_STR(fileName); result = false; + } return result; } }; @@ -211,4 +213,20 @@ extern cChannels Channels; extern cTimers Timers; extern cKeys Keys; +class cSetup { +private: + static char *fileName; + bool Parse(char *s); +public: + // Also adjust cMenuSetup (menu.c) when adding parameters here! + int PrimaryDVB; + int ShowInfoOnChSwitch; + int MenuScrollPage; + cSetup(void); + bool Load(const char *FileName); + bool Save(const char *FileName = NULL); + }; + +extern cSetup Setup; + #endif //__CONFIG_H diff --git a/dvbapi.c b/dvbapi.c index 271d93b0..9f9cbab4 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.23 2000/09/09 12:13:55 kls Exp $ + * $Id: dvbapi.c 1.24 2000/09/10 10:25:09 kls Exp $ */ #include "dvbapi.h" @@ -1097,16 +1097,34 @@ cDvbApi::~cDvbApi() delete replayTitle; } +bool cDvbApi::SetPrimaryDvbApi(int n) +{ + n--; + if (0 <= n && n < NumDvbApis && dvbApi[n]) { + isyslog(LOG_INFO, "setting primary DVB to %d", n + 1); + PrimaryDvbApi = dvbApi[n]; + return true; + } + esyslog(LOG_ERR, "invalid DVB interface: %d", n + 1); + return false; +} + cDvbApi *cDvbApi::GetDvbApi(int Ca) { + cDvbApi *d = NULL; Ca--; for (int i = MAXDVBAPI; --i >= 0; ) { - if (dvbApi[i]) { - if ((i == Ca || Ca < 0) && !dvbApi[i]->Recording()) + if (dvbApi[i] && !dvbApi[i]->Recording()) { + if (i == Ca) return dvbApi[i]; + if (Ca < 0) { + d = dvbApi[i]; + if (d != PrimaryDvbApi) + break; + } } } - return NULL; + return d; } int cDvbApi::Index(void) diff --git a/dvbapi.h b/dvbapi.h index 9f954302..a43e7075 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.13 2000/09/03 09:25:53 kls Exp $ + * $Id: dvbapi.h 1.14 2000/09/10 10:03:29 kls Exp $ */ #ifndef __DVBAPI_H @@ -53,9 +53,13 @@ private: static cDvbApi *dvbApi[MAXDVBAPI]; public: static cDvbApi *PrimaryDvbApi; + static bool SetPrimaryDvbApi(int n); + // 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 = 0); - // Selects a free DVB device, starting with the highest device number. - // If Ca is nor 0, the device with the given number will be returned + // 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 // if it is not currently recording. int Index(void); // Returns the index of this DvbApi. diff --git a/interface.c b/interface.c index 52879b64..5aed127a 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.12 2000/09/09 14:17:48 kls Exp $ + * $Id: interface.c 1.13 2000/09/10 10:35:18 kls Exp $ */ #include "interface.h" @@ -313,14 +313,14 @@ void cInterface::LearnKeys(void) } } -eKeys cInterface::DisplayChannel(int Number, const char *Name) +eKeys cInterface::DisplayChannel(int Number, const char *Name, bool WithInfo) { // Number = 0 is used for channel group display and no EIT if (Number) RcIo.Number(Number); if (Name && !Recording()) { //XXX Maybe show only those lines that have actual information??? - Open(MenuColumns, Number && EIT.IsValid() ? 5 : 1); + Open(MenuColumns, Number && WithInfo && EIT.IsValid() ? 5 : 1); int BufSize = MenuColumns + 1; char buffer[BufSize]; if (Number) @@ -332,7 +332,7 @@ eKeys cInterface::DisplayChannel(int Number, const char *Name) struct tm *now = localtime(&t); snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min); Write(-5, 0, buffer); - if (Number && EIT.IsValid()) { + if (Number && WithInfo && EIT.IsValid()) { const int t = 6; int w = MenuColumns - t; Write(0, 1, EIT.GetRunningTime(), clrYellow, clrBackground); diff --git a/interface.h b/interface.h index ce4646bf..4503dc65 100644 --- a/interface.h +++ b/interface.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: interface.h 1.10 2000/09/03 14:34:24 kls Exp $ + * $Id: interface.h 1.11 2000/09/10 10:35:46 kls Exp $ */ #ifndef __INTERFACE_H @@ -42,7 +42,7 @@ public: bool Confirm(const char *s); void Help(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL); void LearnKeys(void); - eKeys DisplayChannel(int Number, const char *Name = NULL); + eKeys DisplayChannel(int Number, const char *Name = NULL, bool WithInfo = false); void DisplayRecording(int Index, bool On); bool Recording(void); }; diff --git a/menu.c b/menu.c index e8a79966..2d201a14 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.23 2000/09/09 14:43:37 kls Exp $ + * $Id: menu.c 1.24 2000/09/10 10:28:46 kls Exp $ */ #include "menu.h" @@ -1072,6 +1072,41 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key) return state; } +// --- cMenuSetup ------------------------------------------------------------ + +class cMenuSetup : public cOsdMenu { +private: + cSetup data; +public: + cMenuSetup(void); + virtual eOSState ProcessKey(eKeys Key); + }; + +cMenuSetup::cMenuSetup(void) +:cOsdMenu("Setup", 20) +{ + data = Setup; + Add(new cMenuEditIntItem( "PrimaryDVB", &data.PrimaryDVB, 1, cDvbApi::NumDvbApis)); + Add(new cMenuEditBoolItem("ShowInfoOnChSwitch", &data.ShowInfoOnChSwitch)); + Add(new cMenuEditBoolItem("MenuScrollPage", &data.MenuScrollPage)); +} + +eOSState cMenuSetup::ProcessKey(eKeys Key) +{ + eOSState state = cOsdMenu::ProcessKey(Key); + + if (state == osUnknown) { + switch (Key) { + case kOk: state = (Setup.PrimaryDVB != data.PrimaryDVB) ? osSwitchDvb : osBack; + Setup = data; + Setup.Save(); + break; + default: break; + } + } + return state; +} + // --- cMenuMain ------------------------------------------------------------- #define STOP_RECORDING "Stop recording " @@ -1082,6 +1117,7 @@ cMenuMain::cMenuMain(bool Replaying) Add(new cOsdItem("Channels", osChannels)); Add(new cOsdItem("Timer", osTimer)); Add(new cOsdItem("Recordings", osRecordings)); + Add(new cOsdItem("Setup", osSetup)); if (Replaying) Add(new cOsdItem("Stop replaying", osStopReplay)); const char *s = NULL; @@ -1104,6 +1140,7 @@ eOSState cMenuMain::ProcessKey(eKeys Key) case osChannels: return AddSubMenu(new cMenuChannels); case osTimer: return AddSubMenu(new cMenuTimers); case osRecordings: return AddSubMenu(new cMenuRecordings); + case osSetup: return AddSubMenu(new cMenuSetup); case osStopRecord: if (Interface.Confirm("Stop Recording?")) { cOsdItem *item = Get(Current()); if (item) { diff --git a/osd.c b/osd.c index 0efa837b..e1c99b44 100644 --- a/osd.c +++ b/osd.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.6 2000/09/09 14:28:57 kls Exp $ + * $Id: osd.c 1.7 2000/09/10 08:24:50 kls Exp $ */ #include "osd.h" @@ -199,9 +199,8 @@ void cOsdMenu::CursorUp(void) current = tmpCurrent; if (current < first) { first = first > MAXOSDITEMS - 1 ? first - (MAXOSDITEMS - 1) : 0; -#ifndef NO_PAGE_SCROLL - current = SpecialItem(first) ? first + 1 : first; -#endif + if (Setup.MenuScrollPage) + current = SpecialItem(first) ? first + 1 : first; Display(); } else @@ -229,9 +228,8 @@ void cOsdMenu::CursorDown(void) first = last - (MAXOSDITEMS - 1); lastOnScreen = last; } -#ifndef NO_PAGE_SCROLL - current = SpecialItem(lastOnScreen) ? lastOnScreen - 1 : lastOnScreen; -#endif + if (Setup.MenuScrollPage) + current = SpecialItem(lastOnScreen) ? lastOnScreen - 1 : lastOnScreen; Display(); } else diff --git a/osd.h b/osd.h index 1fd4b209..876c87cf 100644 --- a/osd.h +++ b/osd.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.h 1.10 2000/09/03 14:50:22 kls Exp $ + * $Id: osd.h 1.11 2000/09/10 09:50:38 kls Exp $ */ #ifndef __OSD_H @@ -22,10 +22,12 @@ enum eOSState { osUnknown, osChannels, osTimer, osRecordings, + osSetup, osRecord, osReplay, osStopRecord, osStopReplay, + osSwitchDvb, osBack, osEnd, }; diff --git a/vdr.c b/vdr.c index 5e322390..5d714e7a 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.28 2000/09/09 14:18:25 kls Exp $ + * $Id: vdr.c 1.29 2000/09/10 10:42:32 kls Exp $ */ #include @@ -53,11 +53,11 @@ void SignalHandler(int signum) Interrupted = signum; } -static eKeys ShowChannel(int Number, bool Group = false) +static eKeys ShowChannel(int Number, bool Switched, bool Group = false) { cChannel *channel = Group ? Channels.Get(Number) : Channels.GetByNumber(Number); if (channel) - return Interface.DisplayChannel(channel->number, channel->name); + return Interface.DisplayChannel(channel->number, channel->name, !Switched || Setup.ShowInfoOnChSwitch); return kNone; } @@ -164,6 +164,7 @@ int main(int argc, char *argv[]) // Configuration data: + Setup.Load("setup.conf"); Channels.Load("channels.conf"); Timers.Load("timers.conf"); #ifdef REMOTE_LIRC @@ -174,6 +175,8 @@ int main(int argc, char *argv[]) #endif Interface.Init(); + cDvbApi::SetPrimaryDvbApi(Setup.PrimaryDVB); + Channels.SwitchTo(CurrentChannel); // Signal handlers: @@ -194,7 +197,7 @@ int main(int argc, char *argv[]) // Channel display: if (CurrentChannel != LastChannel) { if (!Menu) - ShowChannel(CurrentChannel); + ShowChannel(CurrentChannel, LastChannel > 0); LastChannel = CurrentChannel; } // Direct Channel Select (action): @@ -233,6 +236,11 @@ int main(int argc, char *argv[]) DELETENULL(*Interact); DELETENULL(ReplayControl); break; + case osSwitchDvb: + DELETENULL(*Interact); + Interface.Info("Switching primary DVB..."); + cDvbApi::SetPrimaryDvbApi(Setup.PrimaryDVB); + break; case osBack: case osEnd: DELETENULL(*Interact); break; @@ -261,7 +269,7 @@ int main(int argc, char *argv[]) CurrentGroup = Channels.GetPrevGroup(CurrentGroup < 1 ? 1 : CurrentGroup); if (CurrentGroup < 0) CurrentGroup = SaveGroup; - if (ShowChannel(CurrentGroup, true) == kOk) + if (ShowChannel(CurrentGroup, false, true) == kOk) Channels.SwitchTo(Channels.Get(Channels.GetNextNormal(CurrentGroup))->number); } break;