summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2012-03-03 11:51:32 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2012-03-03 11:51:32 +0100
commit0432198e0b3fb7f77711a2ccb832cdc6c092df58 (patch)
tree73dc1bf816ea03462f80b49b2bafbd13b6208733
parentc5eb60f07a560d9baed751edbb5b5c0246c8e903 (diff)
downloadvdr-0432198e0b3fb7f77711a2ccb832cdc6c092df58.tar.gz
vdr-0432198e0b3fb7f77711a2ccb832cdc6c092df58.tar.bz2
Moved the call to cStatus::MsgChannelSwitch(this, 0) to the beginning of cDevice::SetChannel()1.7.25
-rw-r--r--HISTORY9
-rw-r--r--device.c6
-rw-r--r--rcu.c329
-rw-r--r--rcu.h46
4 files changed, 11 insertions, 379 deletions
diff --git a/HISTORY b/HISTORY
index eecf35bd..9c4e7e39 100644
--- a/HISTORY
+++ b/HISTORY
@@ -6889,7 +6889,7 @@ Video Disk Recorder Revision History
- Fixed switching into time shift mode when pausing live video (thanks to Reinhard
Nissl for helping to debug this one).
-2012-03-02: Version 1.7.25
+2012-03-03: Version 1.7.25
- The fps value for channels where it differs from the default is now set correctly
when pausing live video.
@@ -6952,3 +6952,10 @@ Video Disk Recorder Revision History
color button texts, these should not set the texts directly by calling
cSkinDisplay::Current()->SetButtons(), but rather call the new member function
cMenuEditItem::SetHelp().
+- Moved the call to cStatus::MsgChannelSwitch(this, 0) to the beginning of
+ cDevice::SetChannel(), so that any receivers that have been attached to the
+ device by plugins may be detached before the final call to GetDevice().
+ This actually reverts "Only calling cStatus::MsgChannelSwitch() if a channel
+ is actually going to be switched or has actually been switched successfully"
+ which was made in version 1.1.10, so please report if this has any unwanted
+ side effects.
diff --git a/device.c b/device.c
index 7a8c8c37..663f91ad 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 2.54 2012/03/02 10:46:06 kls Exp $
+ * $Id: device.c 2.55 2012/03/03 11:43:05 kls Exp $
*/
#include "device.h"
@@ -708,6 +708,8 @@ bool cDevice::SwitchChannel(int Direction)
eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
{
+ cStatus::MsgChannelSwitch(this, 0);
+
if (LiveView) {
StopReplay();
DELETENULL(liveSubtitle);
@@ -725,7 +727,6 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
if (NeedsTransferMode) {
if (Device && CanReplay()) {
- cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel
if (Device->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()!
cControl::Launch(new cTransferControl(Device, Channel));
else
@@ -736,7 +737,6 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
}
else {
Channels.Lock(false);
- cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel
// Stop section handling:
if (sectionHandler) {
sectionHandler->SetStatus(false);
diff --git a/rcu.c b/rcu.c
deleted file mode 100644
index 34b43877..00000000
--- a/rcu.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * rcu.c: RCU remote control
- *
- * See the main source file 'vdr.c' for copyright information and
- * how to reach the author.
- *
- * $Id: rcu.c 1.16 2007/08/24 13:15:48 kls Exp $
- */
-
-#include "rcu.h"
-#include <netinet/in.h>
-#include <termios.h>
-#include <unistd.h>
-#include "tools.h"
-
-#define REPEATLIMIT 150 // ms
-#define REPEATDELAY 350 // ms
-#define HANDSHAKETIMEOUT 20 // ms
-
-cRcuRemote::cRcuRemote(const char *DeviceName)
-:cRemote("RCU")
-,cThread("RCU remote control")
-{
- dp = 0;
- mode = modeB;
- code = 0;
- number = 0;
- data = 0;
- receivedCommand = false;
- if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
- struct termios t;
- if (tcgetattr(f, &t) == 0) {
- cfsetspeed(&t, B9600);
- cfmakeraw(&t);
- if (tcsetattr(f, TCSAFLUSH, &t) == 0) {
- SetNumber(8888);
- const char *Setup = GetSetup();
- if (Setup) {
- code = *Setup;
- SetCode(code);
- isyslog("connecting to %s remote control using code %c", Name(), code);
- }
- Start();
- return;
- }
- }
- LOG_ERROR_STR(DeviceName);
- close(f);
- }
- else
- LOG_ERROR_STR(DeviceName);
- f = -1;
-}
-
-cRcuRemote::~cRcuRemote()
-{
- Cancel();
-}
-
-bool cRcuRemote::Ready(void)
-{
- return f >= 0;
-}
-
-bool cRcuRemote::Initialize(void)
-{
- if (f >= 0) {
- unsigned char Code = '0';
- isyslog("trying codes for %s remote control...", Name());
- for (;;) {
- if (DetectCode(&Code)) {
- code = Code;
- break;
- }
- }
- isyslog("established connection to %s remote control using code %c", Name(), code);
- char buffer[16];
- snprintf(buffer, sizeof(buffer), "%c", code);
- PutSetup(buffer);
- return true;
- }
- return false;
-}
-
-void cRcuRemote::Action(void)
-{
-#pragma pack(1)
- union {
- struct {
- unsigned short address;
- unsigned int command;
- } data;
- unsigned char raw[6];
- } buffer;
-#pragma pack()
-
- time_t LastCodeRefresh = 0;
- cTimeMs FirstTime;
- unsigned char LastCode = 0, LastMode = 0;
- uint64_t LastCommand = ~0; // 0x00 might be a valid command
- unsigned int LastData = 0;
- bool repeat = false;
-
- while (Running() && f >= 0) {
- if (ReceiveByte(REPEATLIMIT) == 'X') {
- for (int i = 0; i < 6; i++) {
- int b = ReceiveByte();
- if (b >= 0) {
- buffer.raw[i] = b;
- if (i == 5) {
- unsigned short Address = ntohs(buffer.data.address); // the PIC sends bytes in "network order"
- uint64_t Command = ntohl(buffer.data.command);
- if (code == 'B' && Address == 0x0000 && Command == 0x00004000)
- // Well, well, if it isn't the "d-box"...
- // This remote control sends the above command before and after
- // each keypress - let's just drop this:
- break;
- Command |= uint64_t(Address) << 32;
- if (Command != LastCommand) {
- LastCommand = Command;
- repeat = false;
- FirstTime.Set();
- }
- else {
- if (FirstTime.Elapsed() < REPEATDELAY)
- break; // repeat function kicks in after a short delay
- repeat = true;
- }
- Put(Command, repeat);
- receivedCommand = true;
- }
- }
- else
- break;
- }
- }
- else if (repeat) { // the last one was a repeat, so let's generate a release
- Put(LastCommand, false, true);
- repeat = false;
- LastCommand = ~0;
- }
- else {
- unsigned int d = data;
- if (d != LastData) {
- SendData(d);
- LastData = d;
- }
- unsigned char c = code;
- if (c != LastCode) {
- SendCommand(c);
- LastCode = c;
- }
- unsigned char m = mode;
- if (m != LastMode) {
- SendCommand(m);
- LastMode = m;
- }
- LastCommand = ~0;
- }
- if (!repeat && code && time(NULL) - LastCodeRefresh > 60) {
- SendCommand(code); // in case the PIC listens to the wrong code
- LastCodeRefresh = time(NULL);
- }
- }
-}
-
-int cRcuRemote::ReceiveByte(int TimeoutMs)
-{
- // Returns the byte if one was received within a timeout, -1 otherwise
- if (cFile::FileReady(f, TimeoutMs)) {
- unsigned char b;
- if (safe_read(f, &b, 1) == 1)
- return b;
- else
- LOG_ERROR;
- }
- return -1;
-}
-
-bool cRcuRemote::SendByteHandshake(unsigned char c)
-{
- if (f >= 0) {
- int w = write(f, &c, 1);
- if (w == 1) {
- for (int reply = ReceiveByte(HANDSHAKETIMEOUT); reply >= 0;) {
- if (reply == c)
- return true;
- else if (reply == 'X') {
- // skip any incoming RC code - it will come again
- for (int i = 6; i--;) {
- if (ReceiveByte() < 0)
- return false;
- }
- }
- else
- return false;
- }
- }
- LOG_ERROR;
- }
- return false;
-}
-
-bool cRcuRemote::SendByte(unsigned char c)
-{
- for (int retry = 5; retry--;) {
- if (SendByteHandshake(c))
- return true;
- }
- return false;
-}
-
-bool cRcuRemote::SendData(unsigned int n)
-{
- for (int i = 0; i < 4; i++) {
- if (!SendByte(n & 0x7F))
- return false;
- n >>= 8;
- }
- return SendCommand(mode);
-}
-
-void cRcuRemote::SetCode(unsigned char Code)
-{
- code = Code;
-}
-
-void cRcuRemote::SetMode(unsigned char Mode)
-{
- mode = Mode;
-}
-
-bool cRcuRemote::SendCommand(unsigned char Cmd)
-{
- return SendByte(Cmd | 0x80);
-}
-
-void cRcuRemote::SetNumber(int n, bool Hex)
-{
- number = n;
- if (!Hex) {
- char buf[8];
- sprintf(buf, "%4d", n & 0xFFFF);
- n = 0;
- for (char *d = buf; *d; d++) {
- if (*d == ' ')
- *d = 0xF;
- n = (n << 4) | ((*d - '0') & 0x0F);
- }
- }
- unsigned int m = 0;
- for (int i = 0; i < 4; i++) {
- m <<= 8;
- m |= ((i & 0x03) << 5) | (n & 0x0F) | (((dp >> i) & 0x01) << 4);
- n >>= 4;
- }
- data = m;
-}
-
-void cRcuRemote::SetString(const char *s)
-{
- const char *chars = mode == modeH ? "0123456789ABCDEF" : "0123456789-EHLP ";
- int n = 0;
-
- for (int i = 0; *s && i < 4; s++, i++) {
- n <<= 4;
- for (const char *c = chars; *c; c++) {
- if (*c == *s) {
- n |= c - chars;
- break;
- }
- }
- }
- SetNumber(n, true);
-}
-
-void cRcuRemote::SetPoints(unsigned char Dp, bool On)
-{
- if (On)
- dp |= Dp;
- else
- dp &= ~Dp;
- SetNumber(number);
-}
-
-bool cRcuRemote::DetectCode(unsigned char *Code)
-{
- // Caller should initialize 'Code' to 0 and call DetectCode()
- // until it returns true. Whenever DetectCode() returns false
- // and 'Code' is not 0, the caller can use 'Code' to display
- // a message like "Trying code '%c'". If false is returned and
- // 'Code' is 0, all possible codes have been tried and the caller
- // can either stop calling DetectCode() (and give some error
- // message), or start all over again.
- if (*Code < 'A' || *Code > 'D') {
- *Code = 'A';
- return false;
- }
- if (*Code <= 'D') {
- SetMode(modeH);
- char buf[5];
- sprintf(buf, "C0D%c", *Code);
- SetString(buf);
- SetCode(*Code);
- cCondWait::SleepMs(2 * REPEATDELAY);
- if (receivedCommand) {
- SetMode(modeB);
- SetString("----");
- return true;
- }
- if (*Code < 'D') {
- (*Code)++;
- return false;
- }
- }
- *Code = 0;
- return false;
-}
-
-void cRcuRemote::ChannelSwitch(const cDevice *Device, int ChannelNumber)
-{
- if (ChannelNumber && Device->IsPrimaryDevice())
- SetNumber(cDevice::CurrentChannel());
-}
-
-void cRcuRemote::Recording(const cDevice *Device, const char *Name, const char *FileName, bool On)
-{
- SetPoints(1 << Device->DeviceNumber(), Device->Receiving());
-}
diff --git a/rcu.h b/rcu.h
deleted file mode 100644
index 8824f660..00000000
--- a/rcu.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * rcu.h: RCU remote control
- *
- * See the main source file 'vdr.c' for copyright information and
- * how to reach the author.
- *
- * $Id: rcu.h 1.7 2007/08/24 13:15:48 kls Exp $
- */
-
-#ifndef __RCU_H
-#define __RCU_H
-
-#include "remote.h"
-#include "status.h"
-#include "thread.h"
-
-class cRcuRemote : public cRemote, private cThread, private cStatus {
-private:
- enum { modeH = 'h', modeB = 'b', modeS = 's' };
- int f;
- unsigned char dp, code, mode;
- int number;
- unsigned int data;
- bool receivedCommand;
- bool SendCommand(unsigned char Cmd);
- int ReceiveByte(int TimeoutMs = 0);
- bool SendByteHandshake(unsigned char c);
- bool SendByte(unsigned char c);
- bool SendData(unsigned int n);
- void SetCode(unsigned char Code);
- void SetMode(unsigned char Mode);
- void SetNumber(int n, bool Hex = false);
- void SetPoints(unsigned char Dp, bool On);
- void SetString(const char *s);
- bool DetectCode(unsigned char *Code);
- virtual void Action(void);
- virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber);
- virtual void Recording(const cDevice *Device, const char *Name, const char *FileName, bool On);
-public:
- cRcuRemote(const char *DeviceName);
- virtual ~cRcuRemote();
- virtual bool Ready(void);
- virtual bool Initialize(void);
- };
-
-#endif //__RCU_H