diff --git a/HISTORY b/HISTORY index 88998b3a..f2c944f1 100644 --- a/HISTORY +++ b/HISTORY @@ -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). diff --git a/device.c b/device.c index d7db99b3..ab1067d0 100644 --- a/device.c +++ b/device.c @@ -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); diff --git a/device.h b/device.h index d1fce5ca..0bf9d3db 100644 --- a/device.h +++ b/device.h @@ -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 diff --git a/eitscan.c b/eitscan.c index 9dc82649..069a133d 100644 --- a/eitscan.c +++ b/eitscan.c @@ -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; diff --git a/svdrp.c b/svdrp.c index c5a71cdb..3115349c 100644 --- a/svdrp.c +++ b/svdrp.c @@ -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) diff --git a/tools.h b/tools.h index ebabb470..f8bf43f2 100644 --- a/tools.h +++ b/tools.h @@ -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 inline T min(T a, T b) { return a <= b ? a : b; } template inline T max(T a, T b) { return a >= b ? a : b; } +template inline int sgn(T a) { return a < 0 ? -1 : a > 0 ? 1 : 0; } template 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); diff --git a/vdr.c b/vdr.c index d63bd18a..355a5158 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.121 2002/09/04 13:29:19 kls Exp $ + * $Id: vdr.c 1.122 2002/09/08 11:19:01 kls Exp $ */ #include @@ -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;