summaryrefslogtreecommitdiff
path: root/menu.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2002-02-24 18:00:00 +0100
committerKlaus Schmidinger <kls (at) cadsoft (dot) de>2002-02-24 18:00:00 +0100
commitfb8e7fa302ef8a73feb6958b0cb32cc54f76e677 (patch)
tree74cf9dd5cd1892aaf1c05db32796eb356d7bc860 /menu.c
parenta1da0e5c5de55009716e2c327dda16c61c1dae83 (diff)
downloadvdr-patch-lnbsharing-fb8e7fa302ef8a73feb6958b0cb32cc54f76e677.tar.gz
vdr-patch-lnbsharing-fb8e7fa302ef8a73feb6958b0cb32cc54f76e677.tar.bz2
Version 1.0.0pre1vdr-1.0.0pre1
- Added scanning for EPG data for another 4 days on channels that support this (thanks to Oleg Assovski). - Removed '#define VFAT 1' from recording.c (was a leftover from testing). - Fixed the "Low disk space!" message (thanks to Sergei Haller). - Added the TPID to Hessen-3 in 'channels.conf' (thanks to Sergei Haller). - Fixed a crash when replaying with DEBUG_OSD=1 (thanks to Stefan Huelswitt). - Implemented the "First day" parameter for repeating timers. See FORMATS for information about the enhanced 'timers.conf' file format, and MANUAL for a description of the new item in the "Edit Timer" menu and the enhanced functionality of the "Blue" button in the "Timers" menu. - When deleting a recording that is currently still being recorded, the related timer will now automatically be terminated. If this is a repeating timer, it will receive a "First day" setting that skips the timer for this day. - Fixed closing all unused file descriptors when opening a pipe (thanks to Werner Fink). - Instant recordings now take the EPG data from the point in time at 5 minutes from the start time of the recording. In order for this to work the 'active' parameter of a timer now uses the second bit to indicate that this is an "instant" recording (see FORMATS for details). - Fixed the SVDRP GRAB command in case the video device can't be opened (thanks to Adrian Stabiszewski). - At startup the data written into 'epg.data' is now read into the EPG data structures. In order for this to work, the 'E' record has been extended to (optionally) contain the 'table ID' (see FORMATS for details). - The new SVDRP command PUTE can be used to put EPG data into the EPG list. See FORMATS for details about the required data format. - Taking the German umlauts 'as is' when compiled with VFAT. - The new Setup parameter RecordDolbyDigital can be used to generally turn off recording the Dolby Digital audio channels in case you want to save disk space or don't have the equipment to replay Dolby Digital audio. - Reading the 'setup.conf' file no longer terminates in case of an error, but rather attempts to read the rest of the file. - Removed DVD support from the core VDR source, since the current version from Andreas Schultz is already much further developed (DVD menu navigation) and the concept of "additional players" in VDR is going to change in version 1.1.0, where a new "plugin" interface shall allow the easy implementation of new players without having to patch the core VDR source. Until then, Andreas has agreed to provide his DVD support as a completely external patch. - The contents of the distribution archive now contains the directory name with the current version number, as in 'vdr-1.0.0pre1/...' in order to avoid inadvertently overwriting an existing VDR directory with a new version. - Added a missing error message in SVDRP command LSTC in case the given channel can't be found.
Diffstat (limited to 'menu.c')
-rw-r--r--menu.c323
1 files changed, 146 insertions, 177 deletions
diff --git a/menu.c b/menu.c
index a7a98ec..28e5d4d 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.152 2002/02/10 11:52:34 kls Exp $
+ * $Id: menu.c 1.159 2002/02/24 12:55:49 kls Exp $
*/
#include "menu.h"
@@ -254,6 +254,62 @@ eOSState cMenuEditDayItem::ProcessKey(eKeys Key)
return osContinue;
}
+// --- cMenuEditDateItem -----------------------------------------------------
+
+class cMenuEditDateItem : public cMenuEditItem {
+protected:
+ time_t *value;
+ virtual void Set(void);
+public:
+ cMenuEditDateItem(const char *Name, time_t *Value);
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+
+cMenuEditDateItem::cMenuEditDateItem(const char *Name, time_t *Value)
+:cMenuEditItem(Name)
+{
+ value = Value;
+ Set();
+}
+
+void cMenuEditDateItem::Set(void)
+{
+#define DATEBUFFERSIZE 32
+ char buf[DATEBUFFERSIZE];
+ if (*value) {
+ struct tm tm_r;
+ localtime_r(value, &tm_r);
+ strftime(buf, DATEBUFFERSIZE, "%Y-%m-%d ", &tm_r);
+ strcat(buf, WeekDayName(tm_r.tm_wday));
+ }
+ else
+ *buf = 0;
+ SetValue(buf);
+}
+
+eOSState cMenuEditDateItem::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?
+ *value -= SECSINDAY;
+ if (*value < time(NULL))
+ *value = 0;
+ }
+ else if (NORMALKEY(Key) == kRight) {
+ if (!*value)
+ *value = cTimer::SetTime(time(NULL), 0);
+ *value += SECSINDAY;
+ }
+ else
+ return state;
+ Set();
+ state = osContinue;
+ }
+ return state;
+}
+
// --- cMenuEditTimeItem -----------------------------------------------------
class cMenuEditTimeItem : public cMenuEditItem {
@@ -905,6 +961,8 @@ class cMenuEditTimer : public cOsdMenu {
private:
cTimer *timer;
cTimer data;
+ cMenuEditDateItem *firstday;
+ void SetFirstDayItem(void);
public:
cMenuEditTimer(int Index, bool New = false);
virtual eOSState ProcessKey(eKeys Key);
@@ -913,6 +971,7 @@ public:
cMenuEditTimer::cMenuEditTimer(int Index, bool New)
:cOsdMenu(tr("Edit Timer"), 12)
{
+ firstday = NULL;
timer = Timers.Get(Index);
if (timer) {
data = *timer;
@@ -927,6 +986,21 @@ cMenuEditTimer::cMenuEditTimer(int Index, bool New)
Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY));
Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME));
Add(new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file), FileNameChars));
+ SetFirstDayItem();
+ }
+}
+
+void cMenuEditTimer::SetFirstDayItem(void)
+{
+ if (!firstday && !data.IsSingleEvent()) {
+ Add(firstday = new cMenuEditDateItem(tr("First day"), &data.firstday));
+ Display();
+ }
+ else if (firstday && data.IsSingleEvent()) {
+ Del(firstday->Index());
+ firstday = NULL;
+ data.firstday = 0;
+ Display();
}
}
@@ -953,6 +1027,8 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key)
default: break;
}
}
+ if (Key != kNone)
+ SetFirstDayItem();
return state;
}
@@ -983,7 +1059,7 @@ void cMenuTimerItem::Set(void)
{
char *buffer = NULL;
asprintf(&buffer, "%c\t%d\t%s\t%02d:%02d\t%02d:%02d\t%s",
- timer->active ? timer->recording ? '#' : '>' : ' ',
+ !timer->active ? ' ' : timer->firstday ? '!' : timer->recording ? '#' : '>',
timer->channel,
timer->PrintDay(timer->day),
timer->start / 100,
@@ -998,10 +1074,10 @@ void cMenuTimerItem::Set(void)
class cMenuTimers : public cOsdMenu {
private:
- eOSState Activate(bool On);
eOSState Edit(void);
eOSState New(void);
eOSState Del(void);
+ eOSState OnOff(void);
virtual void Move(int From, int To);
eOSState Summary(void);
cTimer *CurrentTimer(void);
@@ -1022,7 +1098,7 @@ cMenuTimers::cMenuTimers(void)
}
if (Setup.SortTimers)
Sort();
- SetHelp(tr("Edit"), tr("New"), tr("Delete"), Setup.SortTimers ? NULL : tr("Mark"));
+ SetHelp(tr("Edit"), tr("New"), tr("Delete"), Setup.SortTimers ? tr("On/Off") : tr("Mark"));
}
cTimer *cMenuTimers::CurrentTimer(void)
@@ -1031,14 +1107,27 @@ cTimer *cMenuTimers::CurrentTimer(void)
return item ? item->Timer() : NULL;
}
-eOSState cMenuTimers::Activate(bool On)
+eOSState cMenuTimers::OnOff(void)
{
cTimer *timer = CurrentTimer();
- if (timer && timer->active != On) {
- timer->active = On;
+ if (timer) {
+ if (timer->IsSingleEvent())
+ timer->active = !timer->active;
+ else if (timer->firstday) {
+ timer->firstday = 0;
+ timer->active = false;
+ }
+ else if (timer->active)
+ timer->SkipToday();
+ else
+ timer->active = true;
+ timer->Matches(); // refresh start and end time
RefreshCurrent();
DisplayCurrent(true);
- isyslog(LOG_INFO, "timer %d %sactivated", timer->Index() + 1, timer->active ? "" : "de");
+ if (timer->firstday)
+ isyslog(LOG_INFO, "timer %d first day set to %s", timer->Index() + 1, timer->PrintFirstDay());
+ else
+ isyslog(LOG_INFO, "timer %d %sactivated", timer->Index() + 1, timer->active ? "" : "de");
Timers.Save();
}
return osContinue;
@@ -1106,27 +1195,17 @@ eOSState cMenuTimers::Summary(void)
eOSState cMenuTimers::ProcessKey(eKeys Key)
{
- // Must do these before calling cOsdMenu::ProcessKey() because cOsdMenu
- // uses them to page up/down:
- if (!HasSubMenu()) {
- switch (Key) {
- case kLeft:
- case kRight: return Activate(Key == kRight);
- default: break;
- }
- }
-
eOSState state = cOsdMenu::ProcessKey(Key);
if (state == osUnknown) {
switch (Key) {
- case kLeft:
- case kRight: return Activate(Key == kRight);
case kOk: return Summary();
case kRed: return Edit();
case kGreen: return New();
case kYellow: return Del();
- case kBlue: if (!Setup.SortTimers)
+ case kBlue: if (Setup.SortTimers)
+ OnOff();
+ else
Mark();
break;
default: break;
@@ -1350,7 +1429,7 @@ cMenuScheduleItem::cMenuScheduleItem(const cEventInfo *EventInfo)
class cMenuSchedule : public cOsdMenu {
private:
- cThreadLock threadLock;
+ cMutexLock mutexLock;
const cSchedules *schedules;
bool now, next;
int otherChannel;
@@ -1370,7 +1449,7 @@ cMenuSchedule::cMenuSchedule(void)
cChannel *channel = Channels.GetByNumber(cDvbApi::CurrentChannel());
if (channel) {
cMenuWhatsOn::SetCurrentChannel(channel->number);
- schedules = cDvbApi::PrimaryDvbApi->Schedules(&threadLock);
+ schedules = cSIProcessor::Schedules(mutexLock);
PrepareSchedule(channel);
SetHelp(tr("Record"), tr("Now"), tr("Next"));
}
@@ -1670,26 +1749,34 @@ eOSState cMenuRecordings::Del(void)
{
cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
if (ri && !ri->IsDirectory()) {
-//XXX what if this recording's file is currently in use???
-//XXX if (!ti->recording) {
- if (Interface->Confirm(tr("Delete recording?"))) {
- cRecording *recording = GetRecording(ri);
- if (recording) {
- if (recording->Delete()) {
- cReplayControl::ClearLastReplayed(ri->FileName());
- cOsdMenu::Del(Current());
- Recordings.Del(recording);
- Display();
- if (!Count())
- return osBack;
+ if (Interface->Confirm(tr("Delete recording?"))) {
+ cRecordControl *rc = cRecordControls::GetRecordControl(ri->FileName());
+ if (rc) {
+ if (Interface->Confirm(tr("Timer still recording - really delete?"))) {
+ cTimer *timer = rc->Timer();
+ if (timer) {
+ timer->SkipToday();
+ cRecordControls::Process(time(NULL));
+ Timers.Save();
}
- else
- Interface->Error(tr("Error while deleting recording!"));
}
+ else
+ return osContinue;
}
-//XXX }
-//XXX else
-//XXX Interface->Error(tr("Timer is recording!"));
+ cRecording *recording = GetRecording(ri);
+ if (recording) {
+ if (recording->Delete()) {
+ cReplayControl::ClearLastReplayed(ri->FileName());
+ cOsdMenu::Del(Current());
+ Recordings.Del(recording);
+ Display();
+ if (!Count())
+ return osBack;
+ }
+ else
+ Interface->Error(tr("Error while deleting recording!"));
+ }
+ }
}
return osContinue;
}
@@ -1735,81 +1822,6 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
return state;
}
-#ifdef DVDSUPPORT
-// --- cMenuDVDItem ----------------------------------------------------------
-
-class cMenuDVDItem : public cOsdItem {
- private:
- int title;
- int chapters;
- virtual void Set(void);
-public:
- cMenuDVDItem(int Title, int Chapters);
- int Title(void) { return title; }
- };
-
-cMenuDVDItem::cMenuDVDItem(int Title, int Chapters)
-{
- title = Title;
- chapters = Chapters;
- Set();
-}
-
-void cMenuDVDItem::Set(void)
-{
- char *buffer = NULL;
- asprintf(&buffer, " %2d.\tTitle - \t%2d\tChapters", title + 1, chapters);
- SetText(buffer, false);
-}
-
-// --- cMenuDVD --------------------------------------------------------------
-
-cMenuDVD::cMenuDVD(void)
-:cOsdMenu(tr("DVD"), 5, 8, 3)
-{
- if ((dvd = cDVD::getDVD())) {
- dvd->Open();
- ifo_handle_t *vmg = dvd->openVMG();
- if (vmg) {
- int lastTitleID = cReplayControl::LastTitleID();
- dsyslog(LOG_INFO, "DVD: vmg: %p", vmg);//XXX
- tt_srpt_t *tt_srpt = vmg->tt_srpt;
- dsyslog(LOG_INFO, "DVD: tt_srpt: %p", tt_srpt);//XXX
- for (int i = 0; i < tt_srpt->nr_of_srpts; i++)
- Add(new cMenuDVDItem(i, tt_srpt->title[i].nr_of_ptts), i == lastTitleID);
- }
- }
- SetHelp(tr("Play"), NULL, NULL, NULL);
- Display();
-}
-
-eOSState cMenuDVD::Play(void)
-{
- cMenuDVDItem *ri = (cMenuDVDItem *)Get(Current());
- if (ri) {
- cReplayControl::SetDVD(dvd, ri->Title());
- isyslog(LOG_INFO, "DVD: playing title %d", ri->Title());
- return osReplay;
- }
- return osContinue;
-}
-
-eOSState cMenuDVD::ProcessKey(eKeys Key)
-{
- eOSState state = cOsdMenu::ProcessKey(Key);
-
- if (state == osUnknown) {
- switch (Key) {
- case kOk:
- case kRed: return Play();
- case kMenu: return osEnd;
- default: break;
- }
- }
- return state;
-}
-#endif //DVDSUPPORT
-
// --- cMenuSetup ------------------------------------------------------------
class cMenuSetup : public cOsdMenu {
@@ -1857,6 +1869,7 @@ void cMenuSetup::Set(void)
Add(new cMenuEditBoolItem(tr("UseSubtitle"), &data.UseSubtitle));
Add(new cMenuEditBoolItem(tr("RecordingDirs"), &data.RecordingDirs));
Add(new cMenuEditBoolItem(tr("VideoFormat"), &data.VideoFormat, "4:3", "16:9"));
+ Add(new cMenuEditBoolItem(tr("RecordDolbyDigital"), &data.RecordDolbyDigital));
Add(new cMenuEditBoolItem(tr("ChannelInfoPos"), &data.ChannelInfoPos, tr("bottom"), tr("top")));
Add(new cMenuEditIntItem( tr("OSDwidth"), &data.OSDwidth, MINOSDWIDTH, MAXOSDWIDTH));
Add(new cMenuEditIntItem( tr("OSDheight"), &data.OSDheight, MINOSDHEIGHT, MAXOSDHEIGHT));
@@ -1971,10 +1984,6 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
Add(new cOsdItem(hk(tr("Channels")), osChannels));
Add(new cOsdItem(hk(tr("Timers")), osTimers));
Add(new cOsdItem(hk(tr("Recordings")), osRecordings));
-#ifdef DVDSUPPORT
- if (cDVD::DriveExists())
- Add(new cOsdItem(hk(tr("DVD")), osDVD));
-#endif //DVDSUPPORT
Add(new cOsdItem(hk(tr("Setup")), osSetup));
if (Commands.Count())
Add(new cOsdItem(hk(tr("Commands")), osCommands));
@@ -2007,13 +2016,7 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
// Color buttons:
- const char *DVDbutton =
-#ifdef DVDSUPPORT
- cDVD::DiscOk() ? tr("Eject") : NULL;
-#else
- NULL;
-#endif //DVDSUPPORT
- SetHelp(tr("Record"), cDvbApi::PrimaryDvbApi->CanToggleAudioTrack() ? tr("Language") : NULL, DVDbutton, cReplayControl::LastReplayed() ? tr("Resume") : NULL);
+ SetHelp(tr("Record"), cDvbApi::PrimaryDvbApi->CanToggleAudioTrack() ? tr("Language") : NULL, NULL, cReplayControl::LastReplayed() ? tr("Resume") : NULL);
Display();
lastActivity = time(NULL);
SetHasHotkeys();
@@ -2022,9 +2025,6 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
switch (State) {
case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break;
-#ifdef DVDSUPPORT
- case osDVD: AddSubMenu(new cMenuDVD); break;
-#endif //DVDSUPPORT
default: break;
}
}
@@ -2049,9 +2049,6 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
case osChannels: return AddSubMenu(new cMenuChannels);
case osTimers: return AddSubMenu(new cMenuTimers);
case osRecordings: return AddSubMenu(new cMenuRecordings);
-#ifdef DVDSUPPORT
- case osDVD: return AddSubMenu(new cMenuDVD);
-#endif //DVDSUPPORT
case osSetup: return AddSubMenu(new cMenuSetup);
case osCommands: return AddSubMenu(new cMenuCommands);
case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) {
@@ -2084,23 +2081,6 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
}
}
break;
-#ifdef DVDSUPPORT
- case kYellow: if (!HasSubMenu()) {
- if (cDVD::DiscOk()) {
- // We need to stop replaying a DVD before ejecting,
- // otherwise the replay thread crashes. Currently
- // checking LastReplayed() is pretty much the only way
- // of finding out whether we are currently replaying a DVD
- // (i.e. if LastReplayed() returns non-NULL, we are either
- // replaying a normal recording, or nothing at all):
- if (!cReplayControl::LastReplayed())
- cDvbApi::PrimaryDvbApi->StopReplay();
- cDVD::Eject();
- state = osEnd;
- }
- }
- break;
-#endif //DVDSUPPORT
case kBlue: if (!HasSubMenu())
state = osReplay;
break;
@@ -2175,8 +2155,8 @@ void cDisplayChannel::DisplayInfo(void)
{
if (withInfo) {
const cEventInfo *Present = NULL, *Following = NULL;
- cThreadLock ThreadLock;
- const cSchedules *Schedules = cDvbApi::PrimaryDvbApi->Schedules(&ThreadLock);
+ cMutexLock MutexLock;
+ const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
if (Schedules) {
const cSchedule *Schedule = Schedules->GetSchedule();
if (Schedule) {
@@ -2350,14 +2330,16 @@ cRecordControl::~cRecordControl()
delete fileName;
}
+#define INSTANT_REC_EPG_LOOKAHEAD 300 // seconds to look into the EPG data for an instant recording
+
bool cRecordControl::GetEventInfo(void)
{
cChannel *channel = Channels.GetByNumber(timer->channel);
- time_t Time = timer->IsSingleEvent() ? timer->StartTime() + ((Setup.MarginStart * 2) + 1) * 60 : timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2;
+ time_t Time = timer->active == taActInst ? timer->StartTime() + INSTANT_REC_EPG_LOOKAHEAD : timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2;
for (int seconds = 0; seconds <= MAXWAIT4EPGINFO; seconds++) {
{
- cThreadLock ThreadLock;
- const cSchedules *Schedules = dvbApi->Schedules(&ThreadLock);
+ cMutexLock MutexLock;
+ const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
if (Schedules) {
const cSchedule *Schedule = Schedules->GetSchedule(channel->pnr);
if (Schedule) {
@@ -2481,6 +2463,15 @@ const char *cRecordControls::GetInstantId(const char *LastInstantId)
return NULL;
}
+cRecordControl *cRecordControls::GetRecordControl(const char *FileName)
+{
+ for (int i = 0; i < MAXDVBAPI; i++) {
+ if (RecordControls[i] && strcmp(RecordControls[i]->FileName(), FileName) == 0)
+ return RecordControls[i];
+ }
+ return NULL;
+}
+
void cRecordControls::Process(time_t t)
{
for (int i = 0; i < MAXDVBAPI; i++) {
@@ -2548,10 +2539,6 @@ void cProgressBar::Mark(int x, bool Start, bool Current)
char *cReplayControl::fileName = NULL;
char *cReplayControl::title = NULL;
-#ifdef DVDSUPPORT
-cDVD *cReplayControl::dvd = NULL;//XXX
-int cReplayControl::titleid = 0;//XXX
-#endif //DVDSUPPORT
cReplayControl::cReplayControl(void)
{
@@ -2565,10 +2552,6 @@ cReplayControl::cReplayControl(void)
if (!dvbApi->StartReplay(fileName))
Interface->Error(tr("Channel locked (recording)!"));
}
-#ifdef DVDSUPPORT
- else if (dvd)
- dvbApi->StartDVDplay(dvd, titleid);//XXX
-#endif //DVDSUPPORT
}
cReplayControl::~cReplayControl()
@@ -2585,20 +2568,6 @@ void cReplayControl::SetRecording(const char *FileName, const char *Title)
title = Title ? strdup(Title) : NULL;
}
-#ifdef DVDSUPPORT
-void cReplayControl::SetDVD(cDVD *DVD, int Title)//XXX
-{
- SetRecording(NULL, NULL);
- dvd = DVD;
- titleid = Title;
-}
-
-int cReplayControl::LastTitleID(void)
-{
- return titleid;
-}
-#endif //DVDSUPPORT
-
const char *cReplayControl::LastReplayed(void)
{
return fileName;
@@ -2966,7 +2935,7 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
else
Show();
break;
- case kBack: return fileName ? osRecordings : osDVD;
+ case kBack: return osRecordings;
default: return osUnknown;
}
}