summaryrefslogtreecommitdiff
path: root/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'menu.c')
-rw-r--r--menu.c271
1 files changed, 232 insertions, 39 deletions
diff --git a/menu.c b/menu.c
index f482ad1..6f8ef28 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.320 2004/11/20 10:49:17 kls Exp $
+ * $Id: menu.c 1.334 2005/01/09 13:04:49 kls Exp $
*/
#include "menu.h"
@@ -116,7 +116,7 @@ void cMenuEditSrcItem::Set(void)
{
if (source) {
char *buffer = NULL;
- asprintf(&buffer, "%s - %s", cSource::ToString(source->Code()), source->Description());
+ asprintf(&buffer, "%s - %s", *cSource::ToString(source->Code()), source->Description());
SetValue(buffer);
free(buffer);
}
@@ -249,7 +249,7 @@ cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New)
void cMenuEditChannel::Setup(void)
{
int current = Current();
- char type = *cSource::ToString(data.source);
+ char type = **cSource::ToString(data.source);
#define ST(s) if (strchr(s, type))
Clear();
@@ -274,7 +274,7 @@ void cMenuEditChannel::Setup(void)
Add(new cMenuEditIntItem( tr("Rid"), &data.rid, 0));
XXX*/
// Parameters for specific types of sources:
- ST(" S ") Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hv"));
+ ST(" S ") Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hvlr"));
ST("CS ") Add(new cMenuEditIntItem( tr("Srate"), &data.srate));
ST("CST") Add(new cMenuEditMapItem( tr("Inversion"), &data.inversion, InversionValues, tr("off")));
ST("CST") Add(new cMenuEditMapItem( tr("CoderateH"), &data.coderateH, CoderateValues, tr("none")));
@@ -300,7 +300,7 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key)
data.name = strcpyrealloc(data.name, name);
if (channel) {
*channel = data;
- isyslog("edited channel %d %s", channel->Number(), data.ToText());
+ isyslog("edited channel %d %s", channel->Number(), *data.ToText());
state = osBack;
}
else {
@@ -308,7 +308,7 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key)
*channel = data;
Channels.Add(channel);
Channels.ReNumber();
- isyslog("added channel %d %s", channel->Number(), data.ToText());
+ isyslog("added channel %d %s", channel->Number(), *data.ToText());
state = osUser1;
}
Channels.SetModified(true);
@@ -737,9 +737,9 @@ void cMenuTimerItem::Set(void)
asprintf(&buffer, "%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s",
!(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>',
timer->Channel()->Number(),
- timer->IsSingleEvent() ? WeekDayName(timer->StartTime()) : "",
+ timer->IsSingleEvent() ? *WeekDayName(timer->StartTime()) : "",
timer->IsSingleEvent() ? " " : "",
- timer->PrintDay(timer->Day()),
+ *timer->PrintDay(timer->Day()),
timer->Start() / 100,
timer->Start() % 100,
timer->Stop() / 100,
@@ -795,7 +795,7 @@ eOSState cMenuTimers::OnOff(void)
RefreshCurrent();
DisplayCurrent(true);
if (timer->FirstDay())
- isyslog("timer %d first day set to %s", timer->Index() + 1, timer->PrintFirstDay());
+ isyslog("timer %d first day set to %s", timer->Index() + 1, *timer->PrintFirstDay());
else
isyslog("timer %d %sactivated", timer->Index() + 1, timer->HasFlags(tfActive) ? "" : "de");
Timers.SetModified();
@@ -969,7 +969,7 @@ cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel)
char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
char r = event->IsRunning() ? '*' : ' ';
- asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), event->GetTimeString(), t, v, r, event->Title());
+ asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), *event->GetTimeString(), t, v, r, event->Title());
SetText(buffer, false);
}
@@ -1087,7 +1087,7 @@ cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event)
char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
char r = event->IsRunning() ? '*' : ' ';
- asprintf(&buffer, "%.*s\t%s\t%c%c%c\t%s", 6, event->GetDateString(), event->GetTimeString(), t, v, r, event->Title());
+ asprintf(&buffer, "%.*s\t%s\t%c%c%c\t%s", 6, *event->GetDateString(), *event->GetTimeString(), t, v, r, event->Title());
SetText(buffer, false);
}
@@ -1911,6 +1911,9 @@ eOSState cMenuSetupEPG::ProcessKey(eKeys Key)
class cMenuSetupDVB : public cMenuSetupBase {
private:
+ int originalNumAudioLanguages;
+ int numAudioLanguages;
+ void Setup(void);
const char *updateChannelsTexts[5];
public:
cMenuSetupDVB(void);
@@ -1919,6 +1922,9 @@ public:
cMenuSetupDVB::cMenuSetupDVB(void)
{
+ for (numAudioLanguages = 0; numAudioLanguages < I18nNumLanguages && data.AudioLanguages[numAudioLanguages] >= 0; numAudioLanguages++)
+ ;
+ originalNumAudioLanguages = numAudioLanguages;
updateChannelsTexts[0] = tr("no");
updateChannelsTexts[1] = tr("names only");
updateChannelsTexts[2] = tr("names and PIDs");
@@ -1926,22 +1932,59 @@ cMenuSetupDVB::cMenuSetupDVB(void)
updateChannelsTexts[4] = tr("add new transponders");
SetSection(tr("DVB"));
+ Setup();
+}
+
+void cMenuSetupDVB::Setup(void)
+{
+ int current = Current();
+
+ Clear();
+
Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDevice::NumDevices()));
Add(new cMenuEditBoolItem(tr("Setup.DVB$Video format"), &data.VideoFormat, "4:3", "16:9"));
+ Add(new cMenuEditBoolItem(tr("Setup.DVB$Use Dolby Digital"), &data.UseDolbyDigital));
Add(new cMenuEditStraItem(tr("Setup.DVB$Update channels"), &data.UpdateChannels, 5, updateChannelsTexts));
+ Add(new cMenuEditIntItem( tr("Setup.DVB$Audio languages"), &numAudioLanguages, 0, I18nNumLanguages));
+ for (int i = 0; i < numAudioLanguages; i++)
+ Add(new cMenuEditStraItem(tr("Setup.EPG$Audio language"), &data.AudioLanguages[i], I18nNumLanguages, I18nLanguages()));
+
+ SetCurrent(Get(current));
+ Display();
}
eOSState cMenuSetupDVB::ProcessKey(eKeys Key)
{
- int oldPrimaryDVB = Setup.PrimaryDVB;
- bool oldVideoFormat = Setup.VideoFormat;
+ int oldPrimaryDVB = ::Setup.PrimaryDVB;
+ bool oldVideoFormat = ::Setup.VideoFormat;
+ int oldnumAudioLanguages = numAudioLanguages;
eOSState state = cMenuSetupBase::ProcessKey(Key);
+ if (Key != kNone) {
+ if (numAudioLanguages != oldnumAudioLanguages) {
+ for (int i = oldnumAudioLanguages; i < numAudioLanguages; i++) {
+ data.AudioLanguages[i] = 0;
+ for (int l = 0; l < I18nNumLanguages; l++) {
+ int k;
+ for (k = 0; k < oldnumAudioLanguages; k++) {
+ if (data.AudioLanguages[k] == l)
+ break;
+ }
+ if (k >= oldnumAudioLanguages) {
+ data.AudioLanguages[i] = l;
+ break;
+ }
+ }
+ }
+ data.AudioLanguages[numAudioLanguages] = -1;
+ Setup();
+ }
+ }
if (state == osBack && Key == kOk) {
- if (Setup.PrimaryDVB != oldPrimaryDVB)
+ if (::Setup.PrimaryDVB != oldPrimaryDVB)
state = osSwitchDvb;
- if (Setup.VideoFormat != oldVideoFormat)
- cDevice::PrimaryDevice()->SetVideoFormat(Setup.VideoFormat);
+ if (::Setup.VideoFormat != oldVideoFormat)
+ cDevice::PrimaryDevice()->SetVideoFormat(::Setup.VideoFormat);
}
return state;
}
@@ -2111,7 +2154,6 @@ cMenuSetupRecord::cMenuSetupRecord(void)
Add(new cMenuEditBoolItem(tr("Setup.Recording$Mark instant recording"), &data.MarkInstantRecord));
Add(new cMenuEditStrItem( tr("Setup.Recording$Name instant recording"), data.NameInstantRecord, sizeof(data.NameInstantRecord), tr(FileNameChars)));
Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 1, MAXINSTANTRECTIME));
- Add(new cMenuEditBoolItem(tr("Setup.Recording$Record Dolby Digital"), &data.RecordDolbyDigital));
Add(new cMenuEditIntItem( tr("Setup.Recording$Max. video file size (MB)"), &data.MaxVideoFileSize, MINVIDEOFILESIZE, MAXVIDEOFILESIZE));
Add(new cMenuEditBoolItem(tr("Setup.Recording$Split edited files"), &data.SplitEditedFiles));
}
@@ -2410,7 +2452,7 @@ void cMenuMain::Set(const char *Plugin)
// Color buttons:
- SetHelp(!replaying ? tr("Record") : NULL, cDevice::PrimaryDevice()->NumAudioTracks() > 1 ? tr("Language") : NULL, replaying ? NULL : tr("Pause"), replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL);
+ SetHelp(!replaying ? tr("Record") : NULL, cDevice::PrimaryDevice()->NumAudioTracks() > 1 ? tr("Audio") : NULL, replaying ? NULL : tr("Pause"), replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL);
Display();
lastActivity = time(NULL);
}
@@ -2471,13 +2513,8 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
state = replaying ? osContinue : osRecord;
break;
case kGreen: if (!HadSubMenu) {
- int CurrentAudioTrack = -1;
- const char **AudioTracks = cDevice::PrimaryDevice()->GetAudioTracks(&CurrentAudioTrack);
- if (AudioTracks) {
- const char **at = &AudioTracks[CurrentAudioTrack];
- if (!*++at)
- at = AudioTracks;
- cDevice::PrimaryDevice()->SetAudioTrack(at - AudioTracks);
+ if (cDevice::PrimaryDevice()->NumAudioTracks() > 1) {
+ cRemote::Put(kAudio, true);
state = osEnd;
}
}
@@ -2504,6 +2541,40 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
return state;
}
+// --- SetTrackDescriptions --------------------------------------------------
+
+static void SetTrackDescriptions(void)
+{
+ cDevice::PrimaryDevice()->ClrAvailableTracks(true);
+ cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel());
+ if (Channel) {
+ cSchedulesLock SchedulesLock;
+ const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
+ if (Schedules) {
+ const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID());
+ if (Schedule) {
+ const cEvent *Present = Schedule->GetPresentEvent(true);
+ if (Present) {
+ const cComponents *Components = Present->Components();
+ if (Components) {
+ int indexAudio = 0;
+ int indexDolby = 0;
+ for (int i = 0; i < Components->NumComponents(); i++) {
+ const tComponent *p = Components->Component(i);
+ if (p->stream == 2) {
+ if (p->type == 0x05)
+ cDevice::PrimaryDevice()->SetAvailableTrack(ttDolby, indexDolby++, 0, NULL, p->description);
+ else
+ cDevice::PrimaryDevice()->SetAvailableTrack(ttAudio, indexAudio++, 0, NULL, p->description);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
// --- cDisplayChannel -------------------------------------------------------
#define DIRECTCHANNELTIMEOUT 1000 //ms
@@ -2523,7 +2594,7 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched)
DisplayInfo();
displayChannel->Flush();
}
- lastTime = time_ms();
+ lastTime.Set();
}
cDisplayChannel::cDisplayChannel(eKeys FirstKey)
@@ -2532,7 +2603,7 @@ cDisplayChannel::cDisplayChannel(eKeys FirstKey)
group = -1;
number = 0;
lastPresent = lastFollowing = NULL;
- lastTime = time_ms();
+ lastTime.Set();
withInfo = Setup.ShowInfoOnChSwitch;
displayChannel = Skins.Current()->DisplayChannel(withInfo);
ProcessKey(FirstKey);
@@ -2562,6 +2633,7 @@ void cDisplayChannel::DisplayInfo(void)
const cEvent *Present = Schedule->GetPresentEvent(true);
const cEvent *Following = Schedule->GetFollowingEvent(true);
if (Present != lastPresent || Following != lastFollowing) {
+ SetTrackDescriptions();
displayChannel->SetEvents(Present, Following);
cStatus::MsgOsdProgramme(Present ? Present->StartTime() : 0, Present ? Present->Title() : NULL, Present ? Present->ShortText() : NULL, Following ? Following->StartTime() : 0, Following ? Following->Title() : NULL, Following ? Following->ShortText() : NULL);
lastPresent = Present;
@@ -2577,7 +2649,7 @@ void cDisplayChannel::Refresh(void)
channel = Channels.GetByNumber(cDevice::CurrentChannel());
DisplayChannel();
displayChannel->SetEvents(NULL, NULL);
- lastTime = time_ms();
+ lastTime.Set();
}
eOSState cDisplayChannel::ProcessKey(eKeys Key)
@@ -2597,7 +2669,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
displayChannel->SetEvents(NULL, NULL);
withInfo = false;
DisplayChannel();
- lastTime = time_ms();
+ lastTime.Set();
// Lets see if there can be any useful further input:
int n = channel ? number * 10 : 0;
cChannel *ch = channel;
@@ -2646,7 +2718,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
group = -1;
}
}
- lastTime = time_ms();
+ lastTime.Set();
break;
case kUp|k_Repeat:
case kUp:
@@ -2663,14 +2735,14 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
Refresh();
break;
case kNone:
- if (number && time_ms() - lastTime > DIRECTCHANNELTIMEOUT) {
+ if (number && lastTime.Elapsed() > DIRECTCHANNELTIMEOUT) {
if (Channels.GetByNumber(number))
Channels.SwitchTo(number);
else {
number = 0;
channel = NULL;
DisplayChannel();
- lastTime = time_ms();
+ lastTime.Set();
return osContinue;
}
return osEnd;
@@ -2694,7 +2766,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
return osEnd;
}
};
- if (time_ms() - lastTime < INFOTIMEOUT) {
+ if (lastTime.Elapsed() < INFOTIMEOUT) {
if (!number && group < 0 && channel && channel->Number() != cDevice::CurrentChannel())
Refresh(); // makes sure a channel switch through the SVDRP CHAN command is displayed
DisplayInfo();
@@ -2715,7 +2787,7 @@ cDisplayVolume::cDisplayVolume(void)
:cOsdObject(true)
{
currentDisplayVolume = this;
- timeout = time_ms() + (cDevice::PrimaryDevice()->IsMute() ? MUTETIMEOUT : VOLUMETIMEOUT);
+ timeout.Set(cDevice::PrimaryDevice()->IsMute() ? MUTETIMEOUT : VOLUMETIMEOUT);
displayVolume = Skins.Current()->DisplayVolume();
Show();
}
@@ -2752,15 +2824,15 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key)
case kVolDn|k_Repeat:
case kVolDn:
Show();
- timeout = time_ms() + VOLUMETIMEOUT;
+ timeout.Set(VOLUMETIMEOUT);
break;
case kMute:
if (cDevice::PrimaryDevice()->IsMute()) {
Show();
- timeout = time_ms() + MUTETIMEOUT;
+ timeout.Set(MUTETIMEOUT);
}
else
- timeout = 0;
+ timeout.Set();
break;
case kNone: break;
default: if ((Key & k_Release) == 0) {
@@ -2768,7 +2840,128 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key)
return osEnd;
}
}
- return time_ms() < timeout ? osContinue : osEnd;
+ return timeout.TimedOut() ? osEnd : osContinue;
+}
+
+// --- cDisplayTracks --------------------------------------------------------
+
+#define TRACKTIMEOUT 5000 //ms
+
+cDisplayTracks *cDisplayTracks::currentDisplayTracks = NULL;
+
+cDisplayTracks::cDisplayTracks(void)
+:cOsdObject(true)
+{
+ // Get the actual audio track descriptions from the EPG if we're not replaying:
+ if (!cDevice::PrimaryDevice()->Replaying() || cTransferControl::ReceiverDevice())
+ SetTrackDescriptions();
+ currentDisplayTracks = this;
+ numTracks = track = 0;
+ audioChannel = cDevice::PrimaryDevice()->GetAudioChannel();
+ eTrackType CurrentAudioTrack = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
+ for (int i = ttAudioFirst; i <= ttDolbyLast; i++) {
+ const tTrackId *TrackId = cDevice::PrimaryDevice()->GetTrack(eTrackType(i));
+ if (TrackId && TrackId->id) {
+ types[numTracks] = eTrackType(i);
+ descriptions[numTracks] = strdup(*TrackId->description ? TrackId->description : *TrackId->language ? TrackId->language : *itoa(i));
+ if (i == CurrentAudioTrack)
+ track = numTracks;
+ numTracks++;
+ }
+ }
+ timeout.Set(TRACKTIMEOUT);
+ displayTracks = Skins.Current()->DisplayTracks(tr("Audio"), numTracks, descriptions);
+ Show();
+}
+
+cDisplayTracks::~cDisplayTracks()
+{
+ delete displayTracks;
+ currentDisplayTracks = NULL;
+ for (int i = 0; i < numTracks; i++)
+ free(descriptions[i]);
+ cStatus::MsgOsdClear();
+}
+
+void cDisplayTracks::Show(void)
+{
+ int ac = IS_AUDIO_TRACK(types[track]) ? audioChannel : -1;
+ displayTracks->SetTrack(track, descriptions);
+ displayTracks->SetAudioChannel(ac);
+ displayTracks->Flush();
+ cStatus::MsgSetAudioTrack(track, descriptions);
+ cStatus::MsgSetAudioChannel(ac);
+}
+
+cDisplayTracks *cDisplayTracks::Create(void)
+{
+ if (cDevice::PrimaryDevice()->NumAudioTracks() > 0) {
+ if (!currentDisplayTracks)
+ new cDisplayTracks;
+ return currentDisplayTracks;
+ }
+ Skins.Message(mtWarning, tr("No audio available!"));
+ return NULL;
+}
+
+void cDisplayTracks::Process(eKeys Key)
+{
+ if (currentDisplayTracks)
+ currentDisplayTracks->ProcessKey(Key);
+}
+
+eOSState cDisplayTracks::ProcessKey(eKeys Key)
+{
+ int oldTrack = track;
+ int oldAudioChannel = audioChannel;
+ switch (Key) {
+ case kUp|k_Repeat:
+ case kUp:
+ case kDown|k_Repeat:
+ case kDown:
+ if (NORMALKEY(Key) == kUp && track > 0)
+ track--;
+ else if (NORMALKEY(Key) == kDown && track < numTracks - 1)
+ track++;
+ timeout.Set(TRACKTIMEOUT);
+ break;
+ case kLeft|k_Repeat:
+ case kLeft:
+ case kRight|k_Repeat:
+ case kRight: if (IS_AUDIO_TRACK(types[track])) {
+ static int ac[] = { 1, 0, 2 };
+ audioChannel = ac[cDevice::PrimaryDevice()->GetAudioChannel()];
+ if (NORMALKEY(Key) == kLeft && audioChannel > 0)
+ audioChannel--;
+ else if (NORMALKEY(Key) == kRight && audioChannel < 2)
+ audioChannel++;
+ audioChannel = ac[audioChannel];
+ timeout.Set(TRACKTIMEOUT);
+ }
+ break;
+ case kAudio:
+ if (++track >= numTracks)
+ track = 0;
+ timeout.Set(TRACKTIMEOUT);
+ break;
+ case kOk:
+ if (track != cDevice::PrimaryDevice()->GetCurrentAudioTrack())
+ oldTrack = -1; // make sure we explicitly switch to that track
+ timeout.Set();
+ break;
+ case kNone: break;
+ default: if ((Key & k_Release) == 0)
+ return osEnd;
+ }
+ if (track != oldTrack || audioChannel != oldAudioChannel)
+ Show();
+ if (track != oldTrack) {
+ cDevice::PrimaryDevice()->SetCurrentAudioTrack(types[track]);
+ Setup.CurrentDolby = IS_DOLBY_TRACK(types[track]);
+ }
+ if (audioChannel != oldAudioChannel)
+ cDevice::PrimaryDevice()->SetAudioChannel(audioChannel);
+ return timeout.TimedOut() ? osEnd : osContinue;
}
// --- cRecordControl --------------------------------------------------------
@@ -2826,7 +3019,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
isyslog("record %s", fileName);
if (MakeDirs(fileName, true)) {
const cChannel *ch = timer->Channel();
- recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid1(), ch->Apid2(), ch->Dpid1(), ch->Dpid2());
+ recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid(0), ch->Apid(1), ch->Dpid(0), ch->Dpid(1));
if (device->AttachReceiver(recorder)) {
Recording.WriteSummary();
cStatus::MsgRecording(device, Recording.Name());