diff --git a/HISTORY b/HISTORY index 012f54d4..a0f8adea 100644 --- a/HISTORY +++ b/HISTORY @@ -242,13 +242,9 @@ Video Disk Recorder Revision History stopped replay session (suggested by Martin Hammerschmid). - The low and high LNB frequencies can now be changed in the "Setup" menu. -2000-10-29: Version 0.67 +2000-11-01: Version 0.67 - The EIT information is now gathered in a separate thread. -- While the "current/next" information is being displayed (either after switching - channels or due to pressing the "Ok" button in normal viewing mode), the "Green" - and "Yellow" button display detailed information about the current/next broad- - cast (if such information is available). - The sytem time can now be synchronized to the time broadcast in the DVB data stream. This can be enabled in the "Setup" menu by setting "SetSystemTime" to 1. Note that this works only if VDR is running under a user id that has diff --git a/MANUAL b/MANUAL index 9f0c2d68..ffcc10b8 100644 --- a/MANUAL +++ b/MANUAL @@ -115,11 +115,6 @@ Video Disk Recorder User's Manual To bring up the channel display without switching channels you can press the "Ok" button. - When the "current/next" information is being displayed, pressing the "Green" - button will display the detailed information about the current broadcast, - if such information is available. The "Yellow" button will do the same thing - for the next broadcast. - * Switching through channel groups If the 'channels.conf' file contains "group separators" you can switch diff --git a/config.c b/config.c index 18234f53..730ed8a6 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.27 2000/10/29 13:04:37 kls Exp $ + * $Id: config.c 1.28 2000/11/01 13:42:52 kls Exp $ */ #include "config.h" @@ -628,14 +628,6 @@ const char *cChannels::GetChannelNameByNumber(int Number) return channel ? channel->name : NULL; } -eKeys cChannels::ShowChannel(int Number, bool Switched, bool Group) -{ - cChannel *channel = Group ? Get(Number) : GetByNumber(Number); - if (channel) - return Interface->DisplayChannel(channel->number, channel->name, !Switched || Setup.ShowInfoOnChSwitch); - return kNone; -} - // -- cTimers ---------------------------------------------------------------- cTimers Timers; diff --git a/config.h b/config.h index 59e7c696..f9bd579e 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.28 2000/10/29 09:34:10 kls Exp $ + * $Id: config.h 1.29 2000/11/01 13:42:29 kls Exp $ */ #ifndef __CONFIG_H @@ -210,7 +210,6 @@ public: const char *GetChannelNameByNumber(int Number); bool SwitchTo(int Number, cDvbApi *DvbApi = NULL); int MaxNumber(void) { return maxNumber; } - eKeys ShowChannel(int Number, bool Switched, bool Group = false); }; class cTimers : public cConfig { diff --git a/interface.c b/interface.c index c0554ca3..810270fe 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.27 2000/11/01 11:25:25 kls Exp $ + * $Id: interface.c 1.28 2000/11/01 15:27:52 kls Exp $ */ #include "interface.h" @@ -115,6 +115,18 @@ void cInterface::ClearEol(int x, int y, eDvbColor Color) cDvbApi::PrimaryDvbApi->ClrEol(x, y, Color); } +void cInterface::Fill(int x, int y, int w, int h, eDvbColor Color) +{ + if (open) + cDvbApi::PrimaryDvbApi->Fill(x, y, w, h, Color); +} + +void cInterface::Flush(void) +{ + if (open) + cDvbApi::PrimaryDvbApi->Flush(); +} + void cInterface::SetCols(int *c) { for (int i = 0; i < MaxCols; i++) { @@ -403,160 +415,9 @@ void cInterface::LearnKeys(void) } } -eKeys cInterface::DisplayChannel(int Number, const char *Name, bool WithInfo) +void cInterface::DisplayChannelNumber(int Number) { - // Number = 0 is used for channel group display and no EIT - if (Number) - rcIo->Number(Number); - if (Name && !Recording()) { - Open(MenuColumns, 5); - cDvbApi::PrimaryDvbApi->Fill(0, 0, MenuColumns, 1, clrBackground); - int BufSize = MenuColumns + 1; - char buffer[BufSize]; - if (Number) - snprintf(buffer, BufSize, "%d %s", Number, Name ? Name : ""); - else - snprintf(buffer, BufSize, "%s", Name ? Name : ""); - Write(0, 0, buffer); - time_t t = time(NULL); - struct tm *now = localtime(&t); - snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min); - Write(-5, 0, buffer); - cDvbApi::PrimaryDvbApi->Flush(); - -#define INFO_TIMEOUT 5 - - const cEventInfo *Present = NULL, *Following = NULL; - - int Tries = 0; - if (Number && WithInfo) { - for (; Tries < INFO_TIMEOUT; Tries++) { - { - cThreadLock ThreadLock; - const cSchedules *Schedules = cDvbApi::PrimaryDvbApi->Schedules(&ThreadLock); - if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(); - if (Schedule) { - const char *PresentTitle = NULL, *PresentSubtitle = NULL, *FollowingTitle = NULL, *FollowingSubtitle = NULL; - int Lines = 0; - if ((Present = Schedule->GetPresentEvent()) != NULL) { - PresentTitle = Present->GetTitle(); - if (!isempty(PresentTitle)) - Lines++; - PresentSubtitle = Present->GetSubtitle(); - if (!isempty(PresentSubtitle)) - Lines++; - } - if ((Following = Schedule->GetFollowingEvent()) != NULL) { - FollowingTitle = Following->GetTitle(); - if (!isempty(FollowingTitle)) - Lines++; - FollowingSubtitle = Following->GetSubtitle(); - if (!isempty(FollowingSubtitle)) - Lines++; - } - if (Lines > 0) { - const int t = 6; - int l = 1; - cDvbApi::PrimaryDvbApi->Fill(0, 1, MenuColumns, Lines, clrBackground); - if (!isempty(PresentTitle)) { - Write(0, l, Present->GetTimeString(), clrYellow, clrBackground); - Write(t, l, PresentTitle, clrCyan, clrBackground); - l++; - } - if (!isempty(PresentSubtitle)) { - Write(t, l, PresentSubtitle, clrCyan, clrBackground); - l++; - } - if (!isempty(FollowingTitle)) { - Write(0, l, Following->GetTimeString(), clrYellow, clrBackground); - Write(t, l, FollowingTitle, clrCyan, clrBackground); - l++; - } - if (!isempty(FollowingSubtitle)) { - Write(t, l, FollowingSubtitle, clrCyan, clrBackground); - } - cDvbApi::PrimaryDvbApi->Flush(); - if (Lines == 4) { - Tries = 0; - break; - } - } - } - } - } - eKeys Key = Wait(1, true); - if (Key != kNone) - break; - } - } - eKeys Key = Wait(INFO_TIMEOUT - Tries, true); - Close(); - if (Key == kOk) - GetKey(); - if (Key == kGreen || Key == kYellow) { - GetKey(); - do { - Key = DisplayDescription((Key == kGreen) ? Present : Following); - } while (Key == kGreen || Key == kYellow); - Key = kNone; - } - return Key; - } - return kNone; -} - -eKeys cInterface::DisplayDescription(const cEventInfo *EventInfo) -{ - eKeys Key = kNone; - - if (EventInfo) { - int line = 0; - - Open(); - Clear(); - - char buffer[MenuColumns + 1]; - snprintf(buffer, sizeof(buffer), "%s %s", EventInfo->GetDate() ? EventInfo->GetDate() : "", EventInfo->GetTimeString() ? EventInfo->GetTimeString() : ""); - Write(-strlen(buffer), line, buffer, clrYellow); - - line = WriteParagraph(line, EventInfo->GetTitle()); - line = WriteParagraph(line, EventInfo->GetSubtitle()); - line = WriteParagraph(line, EventInfo->GetExtendedDescription()); - - Key = Wait(300); - Close(); - } - return Key; -} - -int cInterface::WriteParagraph(int Line, const char *Text) -{ - if (Line < Height() && Text) { - Line++; - char *s = strdup(Text); - char *pStart = s, *pEnd; - char *pEndText = &s[strlen(s) - 1]; - - while (pStart < pEndText) { - if (strlen(pStart) > (unsigned)(MenuColumns - 2)) - pEnd = &pStart[MenuColumns - 2]; - else - pEnd = &pStart[strlen(pStart)]; - - while (*pEnd != 0 && *pEnd != ' ' && pEnd > pStart) - pEnd--; - - //XXX what if there are no blanks??? - //XXX need to scroll if text is longer - *pEnd = 0; - Write(1, Line++, pStart, clrCyan); - if (Line >= Height()) - return Line; - pStart = pEnd + 1; - } - } - return Line; + rcIo->Number(Number); } void cInterface::DisplayRecording(int Index, bool On) diff --git a/interface.h b/interface.h index 2c9344cc..5dd8ee3a 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.18 2000/11/01 11:18:23 kls Exp $ + * $Id: interface.h 1.19 2000/11/01 15:27:23 kls Exp $ */ #ifndef __INTERFACE_H @@ -29,8 +29,6 @@ private: void QueryKeys(void); void HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor); eKeys Wait(int Seconds = 1, bool KeepChar = false); - eKeys DisplayDescription(const cEventInfo *EventInfo); - int WriteParagraph(int Line, const char *Text); public: cInterface(int SVDRPport = 0); ~cInterface(); @@ -42,6 +40,8 @@ public: void PutKey(eKeys Key); void Clear(void); void ClearEol(int x, int y, eDvbColor Color = clrBackground); + void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground); + void Flush(void); void SetCols(int *c); char *WrapText(const char *Text, int Width, int *Height); void Write(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground); @@ -53,7 +53,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, bool WithInfo = false); + void DisplayChannelNumber(int Number); void DisplayRecording(int Index, bool On); bool Recording(void); }; diff --git a/menu.c b/menu.c index 06d3dd4e..b102861f 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.38 2000/11/01 11:45:05 kls Exp $ + * $Id: menu.c 1.39 2000/11/01 15:35:43 kls Exp $ */ #include "menu.h" @@ -767,7 +767,7 @@ cMenuTextItem::~cMenuTextItem() void cMenuTextItem::Clear(void) { - cDvbApi::PrimaryDvbApi->Fill(x, y, w, h, bgColor); + Interface->Fill(x, y, w, h, bgColor); } void cMenuTextItem::Display(int Offset, eDvbColor FgColor, eDvbColor BgColor) @@ -1059,6 +1059,7 @@ private: const cEventInfo *eventInfo; public: cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch = false); + cMenuEvent(bool Now); virtual eOSState ProcessKey(eKeys Key); }; @@ -1518,58 +1519,166 @@ eOSState cMenuMain::ProcessKey(eKeys Key) return state; } -// --- cDirectChannelSelect -------------------------------------------------- +// --- cDisplayChannel ------------------------------------------------------- -#define DIRECTCHANNELTIMEOUT 500 //ms +#define DIRECTCHANNELTIMEOUT 500 //ms +#define INFOTIMEOUT 5000 //ms -cDirectChannelSelect::cDirectChannelSelect(eKeys FirstKey) +cDisplayChannel::cDisplayChannel(int Number, bool Switched, bool Group) +:cOsdBase(true) +{ + group = Group; + withInfo = !group && (!Switched || Setup.ShowInfoOnChSwitch); + lines = 0; + oldNumber = number = 0; + cChannel *channel = Group ? Channels.Get(Number) : Channels.GetByNumber(Number); + Interface->Open(MenuColumns, 5); + if (channel) { + DisplayChannel(channel); + DisplayInfo(); + } + lastTime = time_ms(); +} + +cDisplayChannel::cDisplayChannel(eKeys FirstKey) :cOsdBase(true) { oldNumber = CurrentChannel; number = 0; lastTime = time_ms(); - Interface->Open(MenuColumns, 1); + Interface->Open(MenuColumns, 5); ProcessKey(FirstKey); } -cDirectChannelSelect::~cDirectChannelSelect() +cDisplayChannel::~cDisplayChannel() { if (number < 0) - Interface->DisplayChannel(oldNumber); + Interface->DisplayChannelNumber(oldNumber); Interface->Close(); } -eOSState cDirectChannelSelect::ProcessKey(eKeys Key) +void cDisplayChannel::DisplayChannel(const cChannel *Channel) +{ + if (!Interface->Recording()) { + if (Channel && Channel->number) + Interface->DisplayChannelNumber(Channel->number); + int BufSize = Width() + 1; + char buffer[BufSize]; + if (Channel && Channel->number) + snprintf(buffer, BufSize, "%d %s", Channel->number, Channel->name); + else + snprintf(buffer, BufSize, "%s", Channel ? Channel->name : "*** Invalid Channel ***"); + Interface->Fill(0, 0, MenuColumns, 1, clrBackground); + Interface->Write(0, 0, buffer); + time_t t = time(NULL); + struct tm *now = localtime(&t); + snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min); + Interface->Write(-5, 0, buffer); + Interface->Flush(); + } +} + +void cDisplayChannel::DisplayInfo(void) +{ + if (withInfo) { + const cEventInfo *Present = NULL, *Following = NULL; + cThreadLock ThreadLock; + const cSchedules *Schedules = cDvbApi::PrimaryDvbApi->Schedules(&ThreadLock); + if (Schedules) { + const cSchedule *Schedule = Schedules->GetSchedule(); + if (Schedule) { + const char *PresentTitle = NULL, *PresentSubtitle = NULL, *FollowingTitle = NULL, *FollowingSubtitle = NULL; + int Lines = 0; + if ((Present = Schedule->GetPresentEvent()) != NULL) { + PresentTitle = Present->GetTitle(); + if (!isempty(PresentTitle)) + Lines++; + PresentSubtitle = Present->GetSubtitle(); + if (!isempty(PresentSubtitle)) + Lines++; + } + if ((Following = Schedule->GetFollowingEvent()) != NULL) { + FollowingTitle = Following->GetTitle(); + if (!isempty(FollowingTitle)) + Lines++; + FollowingSubtitle = Following->GetSubtitle(); + if (!isempty(FollowingSubtitle)) + Lines++; + } + if (Lines > lines) { + const int t = 6; + int l = 1; + Interface->Fill(0, 1, MenuColumns, Lines, clrBackground); + if (!isempty(PresentTitle)) { + Interface->Write(0, l, Present->GetTimeString(), clrYellow, clrBackground); + Interface->Write(t, l, PresentTitle, clrCyan, clrBackground); + l++; + } + if (!isempty(PresentSubtitle)) { + Interface->Write(t, l, PresentSubtitle, clrCyan, clrBackground); + l++; + } + if (!isempty(FollowingTitle)) { + Interface->Write(0, l, Following->GetTimeString(), clrYellow, clrBackground); + Interface->Write(t, l, FollowingTitle, clrCyan, clrBackground); + l++; + } + if (!isempty(FollowingSubtitle)) { + Interface->Write(t, l, FollowingSubtitle, clrCyan, clrBackground); + } + Interface->Flush(); + lines = Lines; + lastTime = time_ms(); + } + } + } + } +} + +eOSState cDisplayChannel::ProcessKey(eKeys Key) { switch (Key) { - case k0 ... k9: + case k0: + if (number == 0) { + // keep the "Toggle channels" function working + Interface->PutKey(Key); + return osEnd; + } + case k1 ... k9: if (number >= 0) { number = number * 10 + Key - k0; - cChannel *channel = Channels.GetByNumber(number); - const char *Name = channel ? channel->name : "*** Invalid Channel ***"; - int BufSize = MenuColumns + 1; - char buffer[BufSize]; - snprintf(buffer, BufSize, "%d %s", number, Name); - Interface->DisplayChannel(number); - Interface->Clear(); - Interface->Write(0, 0, buffer); - lastTime = time_ms(); - if (!channel) { - number = -1; - lastTime += 1000; + if (number > 0) { + cChannel *channel = Channels.GetByNumber(number); + DisplayChannel(channel); + lastTime = time_ms(); + if (!channel) { + number = -1; + lastTime += 1000; + } } } break; case kNone: - if (time_ms() - lastTime > DIRECTCHANNELTIMEOUT) { + if (number && time_ms() - lastTime > DIRECTCHANNELTIMEOUT) { if (number > 0 && !Channels.SwitchTo(number)) number = -1; + return osEnd; } - else - break; - default: return osEnd; + break; + //TODO + //XXX case kGreen: return osEventNow; + //XXX case kYellow: return osEventNext; + case kOk: if (group) + Channels.SwitchTo(Channels.Get(Channels.GetNextNormal(CurrentGroup))->number); + return osEnd; + default: Interface->PutKey(Key); + return osEnd; }; - return osContinue; + if (time_ms() - lastTime < INFOTIMEOUT) { + DisplayInfo(); + return osContinue; + } + return osEnd; } // --- cRecordControl -------------------------------------------------------- diff --git a/menu.h b/menu.h index c36427f1..d979069e 100644 --- a/menu.h +++ b/menu.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.12 2000/10/08 15:21:52 kls Exp $ + * $Id: menu.h 1.13 2000/11/01 14:03:09 kls Exp $ */ #ifndef _MENU_H @@ -24,14 +24,18 @@ public: virtual eOSState ProcessKey(eKeys Key); }; -class cDirectChannelSelect : public cOsdBase { +class cDisplayChannel : public cOsdBase { private: - int oldNumber; - int number; + bool withInfo, group; + int lines; int lastTime; + int oldNumber, number; + void DisplayChannel(const cChannel *Channel); + void DisplayInfo(void); public: - cDirectChannelSelect(eKeys FirstKey); - virtual ~cDirectChannelSelect(); + cDisplayChannel(int Number, bool Switched, bool Group = false); + cDisplayChannel(eKeys FirstKey); + virtual ~cDisplayChannel(); virtual eOSState ProcessKey(eKeys Key); }; diff --git a/osd.h b/osd.h index 2b9359a6..473e87de 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.13 2000/11/01 11:20:15 kls Exp $ + * $Id: osd.h 1.14 2000/11/01 14:29:07 kls Exp $ */ #ifndef __OSD_H @@ -61,8 +61,10 @@ protected: public: cOsdBase(bool FastResponse = false) { needsFastResponse = FastResponse; } virtual ~cOsdBase() {} - virtual eOSState ProcessKey(eKeys Key) = 0; + int Width(void) { return Interface->Width(); } + int Height(void) { return Interface->Height(); } bool NeedsFastResponse(void) { return needsFastResponse; } + virtual eOSState ProcessKey(eKeys Key) = 0; }; class cOsdMenu : public cOsdBase, public cList { @@ -90,8 +92,6 @@ protected: public: cOsdMenu(const char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0); virtual ~cOsdMenu(); - int Width(void) { return Interface->Width(); } - int Height(void) { return Interface->Height(); } int Current(void) { return current; } void Add(cOsdItem *Item, bool Current = false); void Display(void); diff --git a/vdr.c b/vdr.c index 268f45b9..b1321aef 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.40 2000/10/29 14:00:00 kls Exp $ + * $Id: vdr.c 1.41 2000/11/01 14:31:32 kls Exp $ */ #include @@ -205,7 +205,7 @@ int main(int argc, char *argv[]) // Channel display: if (CurrentChannel != LastChannel) { if (!Menu) - Channels.ShowChannel(CurrentChannel, LastChannel > 0); + Menu = new cDisplayChannel(CurrentChannel, LastChannel > 0); PreviousChannel = LastChannel; LastChannel = CurrentChannel; } @@ -265,7 +265,7 @@ int main(int argc, char *argv[]) // Direct Channel Select: case k1 ... k9: if (!Interface->Recording()) - Menu = new cDirectChannelSelect(key); + Menu = new cDisplayChannel(key); break; // Left/Right rotates trough channel groups: case kLeft|k_Repeat: @@ -279,8 +279,7 @@ int main(int argc, char *argv[]) CurrentGroup = Channels.GetPrevGroup(CurrentGroup < 1 ? 1 : CurrentGroup); if (CurrentGroup < 0) CurrentGroup = SaveGroup; - if (Channels.ShowChannel(CurrentGroup, false, true) == kOk) - Channels.SwitchTo(Channels.Get(Channels.GetNextNormal(CurrentGroup))->number); + Menu = new cDisplayChannel(CurrentGroup, false, true); } break; // Up/Down Channel Select: