Skipping unavailable channels when switching with 'Up' and 'Down' keys

This commit is contained in:
Klaus Schmidinger 2002-09-08 11:46:53 +02:00
parent f47655ef0f
commit 1b396902e4
7 changed files with 70 additions and 34 deletions

View File

@ -1450,3 +1450,8 @@ Video Disk Recorder Revision History
cDevice classes.
- Changed the interface if cDevice::GetTSPacket() to avoid unnecessary copying
of data.
- Removed cDevice::Channel(), since this makes no more sense with devices
receiving multiple channels.
- Switching through channels with the 'Up' and 'Down' keys now skips channels
that are currently not available (for instance because all devices are
recording and these channels are on different transponders).

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.c 1.17 2002/09/08 09:36:16 kls Exp $
* $Id: device.c 1.18 2002/09/08 11:46:53 kls Exp $
*/
#include "device.h"
@ -30,6 +30,7 @@
int cDevice::numDevices = 0;
int cDevice::useDevice = 0;
int cDevice::nextCardIndex = 0;
int cDevice::currentChannel = 0;
cDevice *cDevice::device[MAXDEVICES] = { NULL };
cDevice *cDevice::primaryDevice = NULL;
@ -41,8 +42,6 @@ cDevice::cDevice(void)
active = false;
currentChannel = 0;
mute = false;
volume = Setup.CurrentVolume;
@ -285,6 +284,32 @@ bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView)
return false;
}
bool cDevice::SwitchChannel(int Direction)
{
bool result = false;
Direction = sgn(Direction);
if (Direction) {
int n = CurrentChannel() + Direction;
int first = n;
for (;;) {
cChannel *channel = Channels.GetByNumber(n);
if (!channel)
break;
if (PrimaryDevice()->SwitchChannel(channel, true)) {
result = true;
break;
}
n += Direction;
}
int d = n - first;
if (abs(d) == 1)
dsyslog("skipped channel %d", first);
else if (d)
dsyslog("skipped channels %d..%d", first, n - sgn(d));
}
return result;
}
eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
{
cStatus::MsgChannelSwitch(this, 0);
@ -292,10 +317,6 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
if (LiveView)
StopReplay();
// Must set this anyway to avoid getting stuck when switching through
// channels with 'Up' and 'Down' keys:
currentChannel = Channel->number;
// 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:
@ -320,8 +341,10 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
else if (!SetChannelDevice(Channel, LiveView))
Result = scrFailed;
if (IsPrimaryDevice())
if (Result == scrOk && LiveView && IsPrimaryDevice()) {
cSIProcessor::SetCurrentServiceID(Channel->pnr);
currentChannel = Channel->number;
}
cStatus::MsgChannelSwitch(this, Channel->number);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.h 1.13 2002/09/08 08:56:46 kls Exp $
* $Id: device.h 1.14 2002/09/08 11:17:41 kls Exp $
*/
#ifndef __DEVICE_H
@ -132,7 +132,7 @@ public:
// Channel facilities
protected:
int currentChannel;
static int currentChannel;
public:
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL);
// Returns true if this device can provide the given channel.
@ -152,6 +152,10 @@ public:
bool SwitchChannel(const cChannel *Channel, bool LiveView);
// Switches the device to the given Channel, initiating transfer mode
// if necessary.
static bool SwitchChannel(int Direction);
// Switches the primary device to the next available channel in the given
// Direction (only the sign of Direction is evaluated, positive values
// switch to higher channel numbers).
private:
eSetChannelResult SetChannel(const cChannel *Channel, bool LiveView);
// Sets the device to the given channel (general setup).
@ -159,10 +163,8 @@ protected:
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
// Sets the device to the given channel (actual physical setup).
public:
static int CurrentChannel(void) { return primaryDevice ? primaryDevice->currentChannel : 0; }
static int CurrentChannel(void) { return primaryDevice ? currentChannel : 0; }
// Returns the number of the current channel on the primary device.
int Channel(void) { return currentChannel; }
// Returns the number of the current channel on this device.
// PID handle facilities

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: eitscan.c 1.6 2002/09/04 13:32:38 kls Exp $
* $Id: eitscan.c 1.7 2002/09/08 11:08:52 kls Exp $
*/
#include "eitscan.h"
@ -68,7 +68,7 @@ void cEITScanner::Process(void)
break;
if (Channel->pnr && !TransponderScanned(Channel)) {
if (Device == cDevice::PrimaryDevice() && !currentChannel)
currentChannel = Device->Channel();
currentChannel = Device->CurrentChannel();
Device->SwitchChannel(Channel, false);
lastChannel = ch;
break;

31
svdrp.c
View File

@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
* $Id: svdrp.c 1.41 2002/09/04 10:49:42 kls Exp $
* $Id: svdrp.c 1.42 2002/09/08 11:22:57 kls Exp $
*/
#include "svdrp.h"
@ -387,6 +387,7 @@ void cSVDRP::CmdCHAN(const char *Option)
{
if (*Option) {
int n = -1;
int d = 0;
if (isnumber(Option)) {
int o = strtol(Option, NULL, 10);
if (o >= 1 && o <= Channels.MaxNumber())
@ -394,13 +395,17 @@ void cSVDRP::CmdCHAN(const char *Option)
}
else if (strcmp(Option, "-") == 0) {
n = cDevice::CurrentChannel();
if (n > 1)
if (n > 1) {
n--;
d = -1;
}
}
else if (strcmp(Option, "+") == 0) {
n = cDevice::CurrentChannel();
if (n < Channels.MaxNumber())
if (n < Channels.MaxNumber()) {
n++;
d = 1;
}
}
else {
int i = 1;
@ -417,17 +422,21 @@ void cSVDRP::CmdCHAN(const char *Option)
Reply(501, "Undefined channel \"%s\"", Option);
return;
}
cChannel *channel = Channels.GetByNumber(n);
if (channel) {
if (!cDevice::PrimaryDevice()->SwitchChannel(channel, true)) {
Reply(554, "Error switching to channel \"%d\"", channel->number);
if (!d) {
cChannel *channel = Channels.GetByNumber(n);
if (channel) {
if (!cDevice::PrimaryDevice()->SwitchChannel(channel, true)) {
Reply(554, "Error switching to channel \"%d\"", channel->number);
return;
}
}
else {
Reply(550, "Unable to find channel \"%s\"", Option);
return;
}
}
else {
Reply(550, "Unable to find channel \"%s\"", Option);
return;
}
else
cDevice::SwitchChannel(d);
}
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel)

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.h 1.49 2002/08/16 08:52:01 kls Exp $
* $Id: tools.h 1.50 2002/09/08 10:22:29 kls Exp $
*/
#ifndef __TOOLS_H
@ -46,6 +46,7 @@ extern int SysLogLevel;
template<class T> inline T min(T a, T b) { return a <= b ? a : b; }
template<class T> inline T max(T a, T b) { return a >= b ? a : b; }
template<class T> inline int sgn(T a) { return a < 0 ? -1 : a > 0 ? 1 : 0; }
template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
ssize_t safe_read(int filedes, void *buffer, size_t size);

10
vdr.c
View File

@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/people/kls/vdr
*
* $Id: vdr.c 1.121 2002/09/04 13:29:19 kls Exp $
* $Id: vdr.c 1.122 2002/09/08 11:19:01 kls Exp $
*/
#include <getopt.h>
@ -544,13 +544,9 @@ int main(int argc, char *argv[])
case kUp|k_Repeat:
case kUp:
case kDown|k_Repeat:
case kDown: {
int n = cDevice::CurrentChannel() + (NORMALKEY(key) == kUp ? 1 : -1);
cChannel *channel = Channels.GetByNumber(n);
if (channel)
cDevice::PrimaryDevice()->SwitchChannel(channel, true);
case kDown:
cDevice::SwitchChannel(NORMALKEY(key) == kUp ? 1 : -1);
break;
}
// Viewing Control:
case kOk: LastChannel = -1; break; // forces channel display
default: break;