summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2002-12-08 18:00:00 +0100
committerKlaus Schmidinger <kls (at) cadsoft (dot) de>2002-12-08 18:00:00 +0100
commit2b15337b71d71c5e486efe738a507b550bb28843 (patch)
treedcd6fe2d5a57366e0c39ab1fd400ec20a4226ed6
parent96ebdbf4b1e495d44f8f837068af7c2d925bab62 (diff)
downloadvdr-patch-lnbsharing-2b15337b71d71c5e486efe738a507b550bb28843.tar.gz
vdr-patch-lnbsharing-2b15337b71d71c5e486efe738a507b550bb28843.tar.bz2
Version 1.1.19vdr-1.1.19
- The character '|' in description texts of EPG records is now interpreted as a newline character (suggested by Gerhard Steiner). - Updated 'channels.conf.cable' (thanks to Andreas Kool). - Improved handling of repeated remote keys. - The RCU now only sets the channel number display when there are no incoming remote control keys, which improves reaction on repeated keys. - The actual tuning is now done in a separate thread, which makes zapping through the channels a lot faster and no longer gets stuck on channels that don't broadcast. This also makes "Motor-DiSEqC" work (thanks to Reinhard Walter Buchner for his help in testing this). Since switching channels now no longer explicitly waits for a channel lock in the foreground thread, the "panic level" mechanism is no longer used (maybe we don't need it any more, anyway). - The keyboard is now by default always active to control VDR. The 'make' option REMOTE=KBD is therefore obsolete. When compiling VDR with REMOTE=RCU or REMOTE=LIRC, the keyboard can thus now be active together with the remote control. If you want to build VDR _without_ keyboard support you can set NO_KBD=1 in the 'make' call. Since the keyboard codes are now different from the ones used previously (which were mapped by the 'ncurses' library) you will need to go through the "Learning keys" procedure again. To do so, either delete the file /video/remote.conf or remove the KBD.* entries from it before starting this version of VDR. (Thanks to Thomas Sailer for pointing out how to set the terminal parameters to read from the keyboard). - The 'ncurses' library is now only necessary when compiling VDR with DEBUG_OSD=1.
-rw-r--r--CONTRIBUTORS18
-rw-r--r--HISTORY26
-rw-r--r--INSTALL10
-rw-r--r--Makefile10
-rw-r--r--PLUGINS/src/sky/README5
-rw-r--r--channels.conf.cable10
-rw-r--r--config.h4
-rw-r--r--diseqc.c25
-rw-r--r--diseqc.h12
-rw-r--r--dvbdevice.c355
-rw-r--r--dvbdevice.h11
-rw-r--r--interface.c4
-rw-r--r--osd.c14
-rw-r--r--osd.h4
-rw-r--r--params.txt4
-rw-r--r--rcu.c16
-rw-r--r--rcu.h3
-rw-r--r--remote.c67
-rw-r--r--remote.h9
-rw-r--r--vdr.56
-rw-r--r--vdr.c19
21 files changed, 383 insertions, 249 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index ef28cad..9709026 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -322,8 +322,8 @@ Ruben Nunez Francisco <ruben.nunez@tang-it.com>
for translating OSD texts to the Spanish language
Mirko Dölle <mdoelle@linux-user.de>
- for reporting a bug when a timer records over midnight of a day that had a
- change in Daylight Saving Time
+ for reporting a bug when a timer records over midnight of a day that had a
+ change in Daylight Saving Time
Michael Rakowski <mrak@gmx.de>
for translating OSD texts to the Polish language
@@ -441,6 +441,7 @@ Oliver Endriss <o.endriss@gmx.de>
Reinhard Walter Buchner <rw.buchner@freenet.de>
for adding some satellites to 'sources.conf'
+ for his help in testing tuning with "Motor-DiSEqC"
Lauri Tischler <lauri.tischler@efore.fi>
for helping to test and debug the new channel source and DiSEqC handling
@@ -458,6 +459,8 @@ Gerhard Steiner <steiner@mail.austria.com>
the 'epg.data' file
for suggesting the new configuration file 'reccmds.conf' to define commands that
shall be executed from the "Recordings" menu
+ for suggesting to interpret the character '|' in the description texts of EPG
+ records as a newline character
Jaakko Hyvätti <jaakko@hyvatti.iki.fi>
for translating OSD texts to the Finnish language
@@ -476,14 +479,14 @@ Stefan Schluenss <dxr3_osd@schluenss.de>
for reporting a bug where PID handles were not closed correctly
Régis Bossut <rbossut@auchan.com>
- for pointing out that with some providers the channels can only be distinguished
- through the RID
+ for pointing out that with some providers the channels can only be distinguished
+ through the RID
Andreas Kool <akool@akool.de>
- for pointing out problems with non-unique definitions in 'channels.conf.cable'
+ for his help in keeping 'channels.conf.cable' up to date
Guy Roussin <guy.roussin@teledetection.fr>
- for suggesting not to display channel group delimiters without text
+ for suggesting not to display channel group delimiters without text
Georg Hitsch <georg@hitsch.at>
for his help in keeping 'channels.conf' up to date
@@ -498,3 +501,6 @@ Emil Naepflein <Emil.Naepflein@philosys.de>
Gerald Berwolf <genka@genka.de>
for suggesting to deactivate some templates in tools.h in case some plugin needs to
use the STL
+
+Thomas Sailer <sailer@scs.ch>
+ for pointing out how to set the terminal parameters to read from the keyboard
diff --git a/HISTORY b/HISTORY
index 6f9a025..d189379 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1836,3 +1836,29 @@ Video Disk Recorder Revision History
function of a given plugin (see man vdr(5) for details).
- The new plugin 'sky' can be used to integrate a Sky Digibox into the VDR system,
using a Kfir MPEG2 encoder card (see PLUGINS/src/sky/README for details).
+
+2002-12-08: Version 1.1.19
+
+- The character '|' in description texts of EPG records is now interpreted as a
+ newline character (suggested by Gerhard Steiner).
+- Updated 'channels.conf.cable' (thanks to Andreas Kool).
+- Improved handling of repeated remote keys.
+- The RCU now only sets the channel number display when there are no incoming remote
+ control keys, which improves reaction on repeated keys.
+- The actual tuning is now done in a separate thread, which makes zapping through the
+ channels a lot faster and no longer gets stuck on channels that don't broadcast.
+ This also makes "Motor-DiSEqC" work (thanks to Reinhard Walter Buchner for his help
+ in testing this). Since switching channels now no longer explicitly waits for a
+ channel lock in the foreground thread, the "panic level" mechanism is no longer
+ used (maybe we don't need it nay more, anyway).
+- The keyboard is now by default always active to control VDR. The 'make' option
+ REMOTE=KBD is therefore obsolete. When compiling VDR with REMOTE=RCU or REMOTE=LIRC,
+ the keyboard can thus now be active together with the remote control. If you want
+ to build VDR _without_ keyboard support you can set NO_KBD=1 in the 'make' call.
+ Since the keyboard codes are now different from the ones used previously (which
+ were mapped by the 'ncurses' library) you will need to go through the "Learning
+ keys" procedure again. To do so, either delete the file /video/remote.conf or
+ remove the KBD.* entries from it before starting this version of VDR.
+ (Thanks to Thomas Sailer for pointing out how to set the terminal parameters to
+ read from the keyboard).
+- The 'ncurses' library is now only necessary when compiling VDR with DEBUG_OSD=1.
diff --git a/INSTALL b/INSTALL
index 841575d..8e61605 100644
--- a/INSTALL
+++ b/INSTALL
@@ -26,17 +26,17 @@ installed.
IMPORTANT: See "Configuration files" below for information on how
========= to set up the configuration files at the proper location!
-The 'vdr' program can be controlled via the PC keyboard or
-an infrared remote control unit. Define the REMOTE macro to one of the
-following values 'make' call to activate the respective control mode:
+By default the 'vdr' program can be controlled via the PC keyboard. If you have
+an infrared remote control unit you can define the REMOTE macro to one of the
+following values in the 'make' call to activate the respective control mode:
- REMOTE=KBD control via the PC keyboard (default)
REMOTE=RCU control via the "Remote Control Unit" receiver
(see http://www.cadsoft.de/vdr/remote.htm)
REMOTE=LIRC control via the "Linux Infrared Remote Control"
(see http://www.lirc.org)
- REMOTE=NONE no remote control (in case only SVDRP shall be used)
+If you want to disable control via the PC keyboard, you can add NO_KBD=1
+to the 'make' call.
Adding "DEBUG_OSD=1" will use the PC screen (or current window)
to display texts instead of the DVB card's on-screen display
interface. These modes are useful when testing new menus if you
diff --git a/Makefile b/Makefile
index 1494cd6..7d169ce 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
-# $Id: Makefile 1.52 2002/11/29 15:23:02 kls Exp $
+# $Id: Makefile 1.53 2002/12/08 12:20:37 kls Exp $
.DELETE_ON_ERROR:
@@ -38,12 +38,8 @@ OBJS = audio.o channels.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbosd
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
-ifndef REMOTE
-REMOTE = KBD
-endif
-
-ifeq ($(REMOTE), KBD)
-NCURSESLIB = -lncurses
+ifndef NO_KBD
+DEFINES += -DREMOTE_KBD
endif
DEFINES += -DREMOTE_$(REMOTE)
diff --git a/PLUGINS/src/sky/README b/PLUGINS/src/sky/README
index e383279..bd089cc 100644
--- a/PLUGINS/src/sky/README
+++ b/PLUGINS/src/sky/README
@@ -19,6 +19,9 @@ illegal, like decrypting the Sky programme without a subscription. You
will need a Sky Digibox and a valid subscription in order to use this
plugin.
+The 'kfir' module must be loaded with the option 'streamtype=4' to make it
+produce a Transport Stream.
+
The Digibox is remotely controlled through VDR via LIRC (see lirc.org).
The file lircd.conf.sky contains the remote control codes necessary to
control the Digibox.
@@ -43,3 +46,5 @@ uses to generate the EPG pages are stored as the 'sid' parameter in
the channels.conf definitions of the Sky channels. You can keep your
EPG data up-to-date by entering a call to getskyepg.pl into your
/etc/crontab. Call 'getskyepg.pl -h' for a list of options.
+The getskyepg.pl script requires the programs /usr/bin/wget and /usr/bin/logger
+to be installed on your system.
diff --git a/channels.conf.cable b/channels.conf.cable
index 1be4c53..58dc20d 100644
--- a/channels.conf.cable
+++ b/channels.conf.cable
@@ -37,9 +37,9 @@ Premiere 7:370:M64:C:6900:1023:1024:0:101:20:0:0:0
Premiere SERIE:378:M64:C:6900:1023:1024:0:101:16:0:0:0
Premiere Nostalgie:378:M64:C:6900:2559:2560:0:101:516:0:0:0
13 TH STREET:354:M64:C:6900:2303:2304:0:101:42:0:0:0
-Studio Universal:402:M64:C:6900:1050:1054:0:101:36:0:0:0
+Studio Universal:354:M64:C:6900:2047:2048:0:101:36:0:0:0
Krimi & Co:378:M64:C:6900:1535:1536:0:101:23:0:0:0
-Disney Channel:402:M64:C:6900:1030:1034:0:101:34:0:0:0
+Disney Channel:354:M64:C:6900:2559:2560:0:101:34:0:0:0
Discovery Channel:378:M64:C:6900:1791:1792:0:101:14:0:0:0
PLANET:354:M64:C:6900:1791:1792:0:101:13:0:0:0
Fox Kids:354:M64:C:6900:1279:1280:0:101:28:0:0:0
@@ -48,12 +48,6 @@ K-TOON:354:M64:C:6900:511:512:0:101:12:0:0:0
HEIMATKANAL:354:M64:C:6900:1535:1536:0:101:22:0:0:0
GOLDSTAR TV:354:M64:C:6900:3839:3840:0:101:518:0:0:0
CLASSICA:354:M64:C:6900:767:768:0:101:15:0:0:0
-:Mediavision
-Bloomberg:346:M64:C:6900:811:812:0:101:50701:0:0:0
-Fashion TV:346:M64:C:6900:821:822:0:101:50702:0:0:0
-Einstein:346:M64:C:6900:623:624:0:101:50719:0:0:0
-Extreme Sport:346:M64:C:6900:801:802:0:101:50700:0:0:0
-LANDSCAPE:346:M64:C:6900:831:832:0:101:50703:0:0:0
:DIGIKABEL D
Avante:113:M64:C:6900:741:742,743:0:101:53404:0:0:0
BBC Prime:113:M64:C:6900:761:762:763:101:53406:0:0:0
diff --git a/config.h b/config.h
index 43fbfba..50e3156 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 1.142 2002/11/24 20:09:56 kls Exp $
+ * $Id: config.h 1.143 2002/12/06 14:17:55 kls Exp $
*/
#ifndef __CONFIG_H
@@ -19,7 +19,7 @@
#include "device.h"
#include "tools.h"
-#define VDRVERSION "1.1.18"
+#define VDRVERSION "1.1.19"
#define MAXPRIORITY 99
#define MAXLIFETIME 99
diff --git a/diseqc.c b/diseqc.c
index 92b92cb..0766db8 100644
--- a/diseqc.c
+++ b/diseqc.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: diseqc.c 1.1 2002/10/05 13:54:32 kls Exp $
+ * $Id: diseqc.c 1.2 2002/12/07 13:44:56 kls Exp $
*/
#include "diseqc.h"
@@ -16,7 +16,6 @@
cDiseqc::cDiseqc(void)
{
commands = NULL;
- currentAction = NULL;;
parsing = false;
numCodes = 0;
}
@@ -39,11 +38,11 @@ bool cDiseqc::Parse(const char *s)
polarization = toupper(polarization);
if (polarization == 'V' || polarization == 'H') {
parsing = true;
- bool Start = true;
- while (Execute(Start) != daNone)
- Start = false;
+ char *CurrentAction = NULL;
+ while (Execute(&CurrentAction) != daNone)
+ ;
parsing = false;
- result = !commands || currentAction && !*currentAction;
+ result = !commands || !*CurrentAction;
}
else
esyslog("ERROR: unknown polarization '%c'", polarization);
@@ -101,12 +100,12 @@ char *cDiseqc::Codes(char *s)
return NULL;
}
-cDiseqc::eDiseqcActions cDiseqc::Execute(bool Start)
+cDiseqc::eDiseqcActions cDiseqc::Execute(char **CurrentAction)
{
- if (Start)
- currentAction = commands;
- while (currentAction && *currentAction) {
- switch (*currentAction++) {
+ if (!*CurrentAction)
+ *CurrentAction = commands;
+ while (*CurrentAction && **CurrentAction) {
+ switch (*(*CurrentAction)++) {
case ' ': break;
case 't': return daToneOff;
case 'T': return daToneOn;
@@ -114,8 +113,8 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(bool Start)
case 'V': return daVoltage18;
case 'A': return daMiniA;
case 'B': return daMiniB;
- case 'W': currentAction = Wait(currentAction); break;
- case '[': currentAction = Codes(currentAction); return currentAction ? daCodes : daNone;
+ case 'W': *CurrentAction = Wait(*CurrentAction); break;
+ case '[': *CurrentAction = Codes(*CurrentAction); return *CurrentAction ? daCodes : daNone;
default: return daNone;
}
}
diff --git a/diseqc.h b/diseqc.h
index f2b0e99..602bdec 100644
--- a/diseqc.h
+++ b/diseqc.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: diseqc.h 1.1 2002/10/05 13:02:52 kls Exp $
+ * $Id: diseqc.h 1.2 2002/12/07 13:54:02 kls Exp $
*/
#ifndef __DISEQC_H
@@ -31,7 +31,6 @@ private:
char polarization;
int lof;
char *commands;
- char *currentAction;
bool parsing;
uchar codes[MaxDiseqcCodes];
int numCodes;
@@ -41,7 +40,14 @@ public:
cDiseqc(void);
~cDiseqc();
bool Parse(const char *s);
- eDiseqcActions Execute(bool Start = false);
+ eDiseqcActions Execute(char **CurrentAction);
+ // Parses the DiSEqC commands and returns the appropriate action code
+ // with every call. CurrentAction must be the address of a character pointer,
+ // which is initialized to NULL. This pointer is used internally while parsing
+ // the commands and shall not be modified once Execute() has been called with
+ // it. Call Execute() repeatedly (always providing the same CurrentAction pointer)
+ // until it returns daNone. After a successful execution of all commands
+ // *CurrentAction points to the value 0x00.
int Source(void) const { return source; }
int Slof(void) const { return slof; }
char Polarization(void) const { return polarization; }
diff --git a/dvbdevice.c b/dvbdevice.c
index 3aa9f93..a2b4ce9 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.c 1.37 2002/11/15 15:17:30 kls Exp $
+ * $Id: dvbdevice.c 1.38 2002/12/07 14:50:46 kls Exp $
*/
#include "dvbdevice.h"
@@ -60,8 +60,207 @@ static int DvbOpen(const char *Name, int n, int Mode, bool ReportError = false)
return fd;
}
+// --- cDvbTuner -------------------------------------------------------------
+
+class cDvbTuner : public cThread {
+private:
+ enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
+ int fd_frontend;
+ int cardIndex;
+ fe_type_t frontendType;
+ cChannel channel;
+ const char *diseqcCommands;
+ bool active;
+ eTunerStatus tunerStatus;
+ cMutex mutex;
+ cCondVar newSet;
+ bool SetFrontend(void);
+ virtual void Action(void);
+public:
+ cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType);
+ virtual ~cDvbTuner();
+ bool IsTunedTo(const cChannel *Channel) const;
+ void Set(const cChannel *Channel);
+ bool Locked(void) { return tunerStatus == tsLocked; }
+ };
+
+cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType)
+{
+ fd_frontend = Fd_Frontend;
+ cardIndex = CardIndex;
+ frontendType = FrontendType;
+ diseqcCommands = NULL;
+ active = false;
+ tunerStatus = tsIdle;
+ Start();
+}
+
+cDvbTuner::~cDvbTuner()
+{
+ active = false;
+ tunerStatus = tsIdle;
+ newSet.Broadcast();
+ Cancel(3);
+}
+
+bool cDvbTuner::IsTunedTo(const cChannel *Channel) const
+{
+ return tunerStatus != tsIdle && channel.Source() == Channel->Source() && channel.Frequency() == Channel->Frequency();
+}
+
+void cDvbTuner::Set(const cChannel *Channel)
+{
+ cMutexLock MutexLock(&mutex);
+ channel = *Channel;
+ tunerStatus = tsSet;
+ newSet.Broadcast();
+}
+
+static unsigned int FrequencyToHz(unsigned int f)
+{
+ while (f && f < 1000000)
+ f *= 1000;
+ return f;
+}
+
+bool cDvbTuner::SetFrontend(void)
+{
+ dvb_frontend_parameters Frontend;
+
+ memset(&Frontend, 0, sizeof(Frontend));
+
+ switch (frontendType) {
+ case FE_QPSK: { // DVB-S
+
+ unsigned int frequency = channel.Frequency();
+
+ if (Setup.DiSEqC) {
+ cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization());
+ if (diseqc) {
+ if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
+ cDiseqc::eDiseqcActions da;
+ for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
+ switch (da) {
+ case cDiseqc::daNone: break;
+ case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
+ case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
+ case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
+ case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
+ case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
+ case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+ case cDiseqc::daCodes: {
+ int n = 0;
+ uchar *codes = diseqc->Codes(n);
+ if (codes) {
+ struct dvb_diseqc_master_cmd cmd;
+ memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
+ cmd.msg_len = n;
+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
+ }
+ }
+ break;
+ }
+ }
+ diseqcCommands = diseqc->Commands();
+ }
+ frequency -= diseqc->Lof();
+ }
+ else {
+ esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
+ return false;
+ }
+ }
+ else {
+ int tone = SEC_TONE_OFF;
+
+ if (frequency < (unsigned int)Setup.LnbSLOF) {
+ frequency -= Setup.LnbFrequLo;
+ tone = SEC_TONE_OFF;
+ }
+ else {
+ frequency -= Setup.LnbFrequHi;
+ tone = SEC_TONE_ON;
+ }
+ int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
+ CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
+ CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
+ }
+
+ Frontend.frequency = frequency * 1000UL;
+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+ Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL;
+ Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH());
+ }
+ break;
+ case FE_QAM: { // DVB-C
+
+ // Frequency and symbol rate:
+
+ Frontend.frequency = FrequencyToHz(channel.Frequency());
+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+ Frontend.u.qam.symbol_rate = channel.Srate() * 1000UL;
+ Frontend.u.qam.fec_inner = fe_code_rate_t(channel.CoderateH());
+ Frontend.u.qam.modulation = fe_modulation_t(channel.Modulation());
+ }
+ break;
+ case FE_OFDM: { // DVB-T
+
+ // Frequency and OFDM paramaters:
+
+ Frontend.frequency = FrequencyToHz(channel.Frequency());
+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+ Frontend.u.ofdm.bandwidth = fe_bandwidth_t(channel.Bandwidth());
+ Frontend.u.ofdm.code_rate_HP = fe_code_rate_t(channel.CoderateH());
+ Frontend.u.ofdm.code_rate_LP = fe_code_rate_t(channel.CoderateL());
+ Frontend.u.ofdm.constellation = fe_modulation_t(channel.Modulation());
+ Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(channel.Transmission());
+ Frontend.u.ofdm.guard_interval = fe_guard_interval_t(channel.Guard());
+ Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(channel.Hierarchy());
+ }
+ break;
+ default:
+ esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
+ return false;
+ }
+ if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) {
+ esyslog("ERROR: frontend %d: %m", cardIndex);
+ return false;
+ }
+ return true;
+}
+
+void cDvbTuner::Action(void)
+{
+ dsyslog("tuner thread started on device %d (pid=%d)", cardIndex + 1, getpid());
+ active = true;
+ while (active) {
+ cMutexLock MutexLock(&mutex);
+ if (tunerStatus == tsSet)
+ tunerStatus = SetFrontend() ? tsTuned : tsIdle;
+ if (tunerStatus == tsTuned) {
+ fe_status_t status = fe_status_t(0);
+ CHECK(ioctl(fd_frontend, FE_READ_STATUS, &status));
+ if (status & FE_HAS_LOCK)
+ tunerStatus = tsLocked;
+ }
+ dvb_frontend_event event;
+ if (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) {
+ if (tunerStatus != tsIdle && event.status & FE_REINIT) {
+ tunerStatus = tsSet;
+ esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
+ continue;
+ }
+ }
+ newSet.TimedWait(mutex, 1000);
+ }
+ dsyslog("tuner thread ended on device %d (pid=%d)", cardIndex + 1, getpid());
+}
+
+// --- cDvbDevice ------------------------------------------------------------
+
cDvbDevice::cDvbDevice(int n)
{
+ dvbTuner = NULL;
frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
siProcessor = NULL;
spuDecoder = NULL;
@@ -69,7 +268,7 @@ cDvbDevice::cDvbDevice(int n)
// Devices that are present on all card types:
- fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK);
+ int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK);
// Devices that are only present on cards with decoders:
@@ -90,8 +289,10 @@ cDvbDevice::cDvbDevice(int n)
if (fd_frontend >= 0) {
dvb_frontend_info feinfo;
siProcessor = new cSIProcessor(DvbName(DEV_DVB_DEMUX, n));
- if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0)
+ if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
frontendType = feinfo.type;
+ dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType);
+ }
else
LOG_ERROR;
}
@@ -99,16 +300,13 @@ cDvbDevice::cDvbDevice(int n)
esyslog("ERROR: can't open DVB device %d", n);
aPid1 = aPid2 = 0;
-
- source = -1;
- frequency = -1;
- diseqcCommands = NULL;
}
cDvbDevice::~cDvbDevice()
{
delete spuDecoder;
delete siProcessor;
+ delete dvbTuner;
// We're not explicitly closing any device files here, since this sometimes
// caused segfaults. Besides, the program is about to terminate anyway...
}
@@ -322,11 +520,6 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On)
return true;
}
-bool cDvbDevice::IsTunedTo(const cChannel *Channel) const
-{
- return source == Channel->Source() && frequency == Channel->Frequency();
-}
-
bool cDvbDevice::ProvidesSource(int Source) const
{
int type = Source & cSource::st_Mask;
@@ -346,7 +539,7 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
if (ProvidesSource(Channel->Source()) && ProvidesCa(Channel->Ca())) {
#ifdef DO_MULTIPLE_RECORDINGS
if (Receiving()) {
- if (IsTunedTo(Channel)) {
+ if (dvbTuner->IsTunedTo(Channel)) {
needsDetachReceivers = false;
if (!HasPid(Channel->Vpid())) {
if (Channel->Ca() > CACONFBASE) {
@@ -375,18 +568,11 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
return result;
}
-static unsigned int FrequencyToHz(unsigned int f)
-{
- while (f && f < 1000000)
- f *= 1000;
- return f;
-}
-
bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
{
bool IsEncrypted = Channel->Ca() > CACONFBASE;
- bool DoTune = !IsTunedTo(Channel);
+ bool DoTune = !dvbTuner->IsTunedTo(Channel);
bool TurnOffLivePIDs = HasDecoder()
&& (DoTune
@@ -436,136 +622,15 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
}
if (DoTune) {
-
- dvb_frontend_parameters Frontend;
-
- memset(&Frontend, 0, sizeof(Frontend));
-
- switch (frontendType) {
- case FE_QPSK: { // DVB-S
-
- unsigned int frequency = Channel->Frequency();
-
- if (Setup.DiSEqC) {
- cDiseqc *diseqc = Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization());
- if (diseqc) {
- if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
- cDiseqc::eDiseqcActions da;
- for (bool Start = true; (da = diseqc->Execute(Start)) != cDiseqc::daNone; Start = false) {
- switch (da) {
- case cDiseqc::daNone: break;
- case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
- case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
- case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
- case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
- case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
- case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
- case cDiseqc::daCodes: {
- int n = 0;
- uchar *codes = diseqc->Codes(n);
- if (codes) {
- struct dvb_diseqc_master_cmd cmd;
- memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
- cmd.msg_len = n;
- CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
- }
- }
- break;
- }
- }
- diseqcCommands = diseqc->Commands();
- }
- frequency -= diseqc->Lof();
- }
- else {
- esyslog("ERROR: no DiSEqC parameters found for channel %d", Channel->Number());
- return false;
- }
- }
- else {
- int tone = SEC_TONE_OFF;
-
- if (frequency < (unsigned int)Setup.LnbSLOF) {
- frequency -= Setup.LnbFrequLo;
- tone = SEC_TONE_OFF;
- }
- else {
- frequency -= Setup.LnbFrequHi;
- tone = SEC_TONE_ON;
- }
- int volt = (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
- CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
- CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
- }
-
- Frontend.frequency = frequency * 1000UL;
- Frontend.inversion = fe_spectral_inversion_t(Channel->Inversion());
- Frontend.u.qpsk.symbol_rate = Channel->Srate() * 1000UL;
- Frontend.u.qpsk.fec_inner = fe_code_rate_t(Channel->CoderateH());
- }
- break;
- case FE_QAM: { // DVB-C
-
- // Frequency and symbol rate:
-
- Frontend.frequency = FrequencyToHz(Channel->Frequency());
- Frontend.inversion = fe_spectral_inversion_t(Channel->Inversion());
- Frontend.u.qam.symbol_rate = Channel->Srate() * 1000UL;
- Frontend.u.qam.fec_inner = fe_code_rate_t(Channel->CoderateH());
- Frontend.u.qam.modulation = fe_modulation_t(Channel->Modulation());
- }
- break;
- case FE_OFDM: { // DVB-T
-
- // Frequency and OFDM paramaters:
-
- Frontend.frequency = FrequencyToHz(Channel->Frequency());
- Frontend.inversion = fe_spectral_inversion_t(Channel->Inversion());
- Frontend.u.ofdm.bandwidth = fe_bandwidth_t(Channel->Bandwidth());
- Frontend.u.ofdm.code_rate_HP = fe_code_rate_t(Channel->CoderateH());
- Frontend.u.ofdm.code_rate_LP = fe_code_rate_t(Channel->CoderateL());
- Frontend.u.ofdm.constellation = fe_modulation_t(Channel->Modulation());
- Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(Channel->Transmission());
- Frontend.u.ofdm.guard_interval = fe_guard_interval_t(Channel->Guard());
- Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(Channel->Hierarchy());
- }
- break;
- default:
- esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
- return false;
- }
-
- // Discard stale events:
-
- for (;;) {
- dvb_frontend_event event;
- if (ioctl(fd_frontend, FE_GET_EVENT, &event) < 0)
- break;
- }
-
- // Tuning:
-
- CHECK(ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend));
-
- // Wait for channel lock:
-
- fe_status_t status = fe_status_t(0);
- for (int i = 0; i < 100; i++) {
- CHECK(ioctl(fd_frontend, FE_READ_STATUS, &status));
- if (status & FE_HAS_LOCK)
- break;
- usleep(10 * 1000);
- }
+ dvbTuner->Set(Channel);
+ /*XXX do we still need this???
if (!(status & FE_HAS_LOCK)) {
esyslog("ERROR: channel %d not locked on DVB card %d!", Channel->Number(), CardIndex() + 1);
if (LiveView && IsPrimaryDevice())
cThread::RaisePanic();
return false;
}
-
- source = Channel->Source();
- frequency = Channel->Frequency();
-
+ XXX*/
}
// PID settings:
diff --git a/dvbdevice.h b/dvbdevice.h
index 709790c..d135a29 100644
--- a/dvbdevice.h
+++ b/dvbdevice.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.h 1.18 2002/11/03 12:31:15 kls Exp $
+ * $Id: dvbdevice.h 1.19 2002/12/07 14:44:29 kls Exp $
*/
#ifndef __DVBDEVICE_H
@@ -22,6 +22,8 @@
#define MAXDVBDEVICES 4
+class cDvbTuner;
+
class cDvbDevice : public cDevice {
friend class cDvbOsd;
private:
@@ -33,7 +35,7 @@ public:
// Must be called before accessing any DVB functions.
private:
fe_type_t frontendType;
- int fd_osd, fd_frontend, fd_audio, fd_video, fd_dvr;
+ int fd_osd, fd_audio, fd_video, fd_dvr;
int OsdDeviceHandle(void) const { return fd_osd; }
protected:
virtual void MakePrimaryDevice(bool On);
@@ -53,10 +55,7 @@ public:
// Channel facilities
private:
- int source;
- int frequency;
- const char *diseqcCommands;
- bool IsTunedTo(const cChannel *Channel) const;
+ cDvbTuner *dvbTuner;
public:
virtual bool ProvidesSource(int Source) const;
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
diff --git a/interface.c b/interface.c
index 804747a..7466a9a 100644
--- a/interface.c
+++ b/interface.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: interface.c 1.60 2002/11/01 10:50:38 kls Exp $
+ * $Id: interface.c 1.61 2002/12/06 14:13:16 kls Exp $
*/
#include "interface.h"
@@ -157,6 +157,8 @@ char *cInterface::WrapText(const char *Text, int Width, int *Height)
t[strlen(t) - 1] = 0; // skips trailing newlines
for (char *p = t; *p; ) {
+ if (*p == '|')
+ *p = '\n';
if (*p == '\n') {
Lines++;
w = 0;
diff --git a/osd.c b/osd.c
index eb0d2dc..7622955 100644
--- a/osd.c
+++ b/osd.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.c 1.38 2002/11/16 14:20:26 kls Exp $
+ * $Id: osd.c 1.39 2002/12/08 13:17:13 kls Exp $
*/
#include "osd.h"
@@ -26,15 +26,8 @@
void cOsd::Initialize(void)
{
-#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
- initscr();
- keypad(stdscr, true);
- nonl();
- cbreak();
- noecho();
- timeout(10);
-#endif
#if defined(DEBUG_OSD)
+ initscr();
start_color();
leaveok(stdscr, true);
#endif
@@ -43,7 +36,7 @@ void cOsd::Initialize(void)
void cOsd::Shutdown(void)
{
Close();
-#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
+#if defined(DEBUG_OSD)
endwin();
#endif
}
@@ -150,6 +143,7 @@ void cOsd::Clear(void)
#ifdef DEBUG_OSD
SetColor(clrBackground, clrBackground);
Fill(0, 0, cols, rows, clrBackground);
+ refresh();
#else
osd->Clear();
#endif
diff --git a/osd.h b/osd.h
index 2cd2f4b..5f1ec96 100644
--- a/osd.h
+++ b/osd.h
@@ -4,13 +4,13 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.h 1.37 2002/11/24 10:32:29 kls Exp $
+ * $Id: osd.h 1.38 2002/12/08 12:21:26 kls Exp $
*/
#ifndef __OSD_H
#define __OSD_H
-#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
+#if defined(DEBUG_OSD)
#include <ncurses.h>
#endif
#include "config.h"
diff --git a/params.txt b/params.txt
deleted file mode 100644
index 480a1a6..0000000
--- a/params.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Are the parameter names well chosen?
-
- "Coderate" <--> FEC
-
diff --git a/rcu.c b/rcu.c
index 6345bea..4157c0d 100644
--- a/rcu.c
+++ b/rcu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: rcu.c 1.2 2002/10/06 15:49:03 kls Exp $
+ * $Id: rcu.c 1.3 2002/12/07 12:22:40 kls Exp $
*/
#include "rcu.h"
@@ -22,6 +22,7 @@ cRcuRemote::cRcuRemote(char *DeviceName)
dp = 0;
mode = modeB;
code = 0;
+ numberToSend = -1;
lastNumber = 0;
receivedCommand = false;
if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
@@ -136,8 +137,13 @@ void cRcuRemote::Action(void)
repeat = false;
LastCommand = 0;
}
- else
+ else {
LastCommand = 0;
+ if (numberToSend >= 0) {
+ Number(numberToSend);
+ numberToSend = -1;
+ }
+ }
if (code && time(NULL) - LastCodeRefresh > 60) {
SendCommand(code); // in case the PIC listens to the wrong code
LastCodeRefresh = time(NULL);
@@ -302,8 +308,10 @@ bool cRcuRemote::DetectCode(unsigned char *Code)
void cRcuRemote::ChannelSwitch(const cDevice *Device, int ChannelNumber)
{
- if (ChannelNumber && Device->IsPrimaryDevice())
- Number(ChannelNumber);
+ if (ChannelNumber && Device->IsPrimaryDevice()) {
+ LOCK_THREAD;
+ numberToSend = ChannelNumber;
+ }
}
void cRcuRemote::Recording(const cDevice *Device, const char *Name)
diff --git a/rcu.h b/rcu.h
index 1c54999..d314275 100644
--- a/rcu.h
+++ b/rcu.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: rcu.h 1.1 2002/09/29 08:56:15 kls Exp $
+ * $Id: rcu.h 1.2 2002/12/07 12:21:25 kls Exp $
*/
#ifndef __RCU_H
@@ -19,6 +19,7 @@ private:
enum { modeH = 'h', modeB = 'b', modeS = 's' };
int f;
unsigned char dp, code, mode;
+ int numberToSend;
int lastNumber;
bool receivedCommand;
bool SendCommand(unsigned char Cmd);
diff --git a/remote.c b/remote.c
index 7157a5f..d4f1702 100644
--- a/remote.c
+++ b/remote.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: remote.c 1.32 2002/12/01 10:40:04 kls Exp $
+ * $Id: remote.c 1.34 2002/12/08 13:37:13 kls Exp $
*/
#include "remote.h"
@@ -13,13 +13,7 @@
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
-#include <termios.h>
#include <unistd.h>
-
-#if defined REMOTE_KBD
-#include <ncurses.h>
-#endif
-
#include "tools.h"
// --- cRemote ---------------------------------------------------------------
@@ -68,7 +62,7 @@ bool cRemote::Put(eKeys Key)
{
if (Key != kNone) {
cMutexLock MutexLock(&mutex);
- if ((Key & k_Release) != 0)
+ if (in != out && (keys[out] & k_Repeat) && (Key & k_Release))
Clear();
int d = out - in;
if (d <= 0)
@@ -155,30 +149,65 @@ cRemotes Remotes;
// --- cKbdRemote ------------------------------------------------------------
-#if defined REMOTE_KBD
-
cKbdRemote::cKbdRemote(void)
:cRemote("KBD")
{
+ active = false;
+ tcgetattr(STDIN_FILENO, &savedTm);
+ struct termios tm;
+ if (tcgetattr(STDIN_FILENO, &tm) == 0) {
+ tm.c_iflag = 0;
+ tm.c_lflag &= ~(ICANON | ECHO);
+ tm.c_cc[VMIN] = 0;
+ tm.c_cc[VTIME] = 0;
+ tcsetattr(STDIN_FILENO, TCSANOW, &tm);
+ }
Start();
}
cKbdRemote::~cKbdRemote()
{
- Cancel();
+ active = false;
+ Cancel(3);
+ tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
}
void cKbdRemote::Action(void)
{
dsyslog("KBD remote control thread started (pid=%d)", getpid());
cPoller Poller(STDIN_FILENO);
- for (;;) {//XXX
- int Command = getch();
- if (Command != EOF)
- Put(Command);
- Poller.Poll(100);
- }
+ active = true;
+ while (active) {
+ if (Poller.Poll(100)) {
+ uint64 Command = 0;
+ uint i = 0;
+ int t0 = time_ms();
+ while (active && i < sizeof(Command)) {
+ uchar ch;
+ int r = read(STDIN_FILENO, &ch, 1);
+ if (r == 1) {
+ Command <<= 8;
+ Command |= ch;
+ i++;
+ }
+ else if (r == 0) {
+ // don't know why, but sometimes special keys that start with
+ // 0x1B ('ESC') cause a short gap between the 0x1B and the rest
+ // of their codes, so we'll need to wait some 100ms to see if
+ // there is more coming up - or whether this really is the 'ESC'
+ // key (if somebody knows how to clean this up, please let me know):
+ if (Command == 0x1B && time_ms() - t0 < 100)
+ continue;
+ if (Command)
+ Put(Command);
+ break;
+ }
+ else {
+ LOG_ERROR;
+ break;
+ }
+ }
+ }
+ }
dsyslog("KBD remote control thread ended (pid=%d)", getpid());
}
-
-#endif
diff --git a/remote.h b/remote.h
index 2aeec78..1c087d0 100644
--- a/remote.h
+++ b/remote.h
@@ -4,13 +4,14 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: remote.h 1.21 2002/12/01 10:39:10 kls Exp $
+ * $Id: remote.h 1.22 2002/12/08 13:37:02 kls Exp $
*/
#ifndef __REMOTE_H
#define __REMOTE_H
#include <stdio.h>
+#include <termios.h>
#include <time.h>
#include "keys.h"
#include "thread.h"
@@ -50,16 +51,14 @@ class cRemotes : public cList<cRemote> {};
extern cRemotes Remotes;
-#if defined REMOTE_KBD
-
class cKbdRemote : public cRemote, private cThread {
private:
+ bool active;
+ struct termios savedTm;
virtual void Action(void);
public:
cKbdRemote(void);
virtual ~cKbdRemote();
};
-#endif
-
#endif //__REMOTE_H
diff --git a/vdr.5 b/vdr.5
index 8a76fdd..8b833a2 100644
--- a/vdr.5
+++ b/vdr.5
@@ -8,9 +8,9 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
-.\" $Id: vdr.5 1.16 2002/12/01 10:34:40 kls Exp $
+.\" $Id: vdr.5 1.17 2002/12/08 14:35:12 kls Exp $
.\"
-.TH vdr 5 "24 Nov 2002" "1.2.0" "Video Disk Recorder Files"
+.TH vdr 5 "6 Dec 2002" "1.2.0" "Video Disk Recorder Files"
.SH NAME
vdr file formats - the Video Disk Recorder Files
.SH DESCRIPTION
@@ -549,7 +549,7 @@ in (if this is left empty or 0 this event will not be overwritten\
or modified by data that comes from the DVB stream)
<title> @is the title of the event
<subtitle> @is the subtitle (typically the name of the episode etc.)
-<description> @is the description of the event
+<description> @is the description of the event (any '|' characters will be interpreted as newlines)
.TE
This file will be read at program startup in order to restore the results of
diff --git a/vdr.c b/vdr.c
index 438f98f..8f22f11 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,13 +22,14 @@
*
* The project's page is at http://www.cadsoft.de/people/kls/vdr
*
- * $Id: vdr.c 1.136 2002/12/01 10:44:48 kls Exp $
+ * $Id: vdr.c 1.137 2002/12/08 13:34:39 kls Exp $
*/
#include <getopt.h>
#include <locale.h>
#include <signal.h>
#include <stdlib.h>
+#include <termios.h>
#include <unistd.h>
#include "audio.h"
#include "channels.h"
@@ -77,6 +78,11 @@ static void Watchdog(int signum)
int main(int argc, char *argv[])
{
+ // Save terminal settings:
+
+ struct termios savedTm;
+ tcgetattr(STDIN_FILENO, &savedTm);
+
// Initiate locale:
setlocale(LC_ALL, "");
@@ -294,7 +300,7 @@ int main(int argc, char *argv[])
// Daemon mode:
if (DaemonMode) {
-#if !defined(DEBUG_OSD) && !defined(REMOTE_KBD)
+#if !defined(DEBUG_OSD)
pid_t pid = fork();
if (pid < 0) {
fprintf(stderr, "%m\n");
@@ -307,7 +313,7 @@ int main(int argc, char *argv[])
fclose(stdout);
fclose(stderr);
#else
- fprintf(stderr, "vdr: can't run in daemon mode with DEBUG_OSD or REMOTE_KBD on!\n");
+ fprintf(stderr, "vdr: can't run in daemon mode with DEBUG_OSD on!\n");
return 2;
#endif
}
@@ -378,8 +384,10 @@ int main(int argc, char *argv[])
new cRcuRemote("/dev/ttyS1");
#elif defined(REMOTE_LIRC)
new cLircRemote("/dev/lircd");
-#elif defined(REMOTE_KBD)
- new cKbdRemote;
+#endif
+#if defined(REMOTE_KBD)
+ if (!DaemonMode)
+ new cKbdRemote;
#endif
Interface->LearnKeys();
@@ -716,6 +724,7 @@ int main(int argc, char *argv[])
isyslog("exiting");
if (SysLogLevel > 0)
closelog();
+ tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
if (cThread::EmergencyExit()) {
esyslog("emergency exit!");
return 1;