diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2006-01-15 18:00:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2006-01-15 18:00:00 +0100 |
commit | 78e3da813cb4345e57934a9a60f6316f1e257307 (patch) | |
tree | 2ce53c2872dd7451c0647ad50fe81306ad985bc0 | |
parent | da948a50d2318fd9c818a4b969b74555ce577b1e (diff) | |
download | vdr-patch-lnbsharing-78e3da813cb4345e57934a9a60f6316f1e257307.tar.gz vdr-patch-lnbsharing-78e3da813cb4345e57934a9a60f6316f1e257307.tar.bz2 |
Version 1.3.39vdr-1.3.39
- The SVDRP command LSTT now accepts the new option 'id' to have the channels
of the timers listed with their unique channel ids instead of their numbers
(suggested by Matthias Schniedermeyer).
- Added a missing #include <linux/unistd.h> to thread.c (thanks to Ville Skyttä).
- Fixed the "plugins-clean" and "plugins-install" targets in the Makefile (thanks
to Andreas Brachold).
- Fixed handling "more than 3 byte" key sequences in cKbdRemote::ReadKeySequence()
(thanks to Peter Bieringer). If you are using the PC keyboard as remote control
input you may need to make VDR newly learn the keys by removing the remote.conf
file.
- To avoid problems with access rights when VDR shall run as 'root' it now skips
all SetCaps() and SetUser() calls when it is started as 'root' and "-u root"
is given.
- Added missing i18n entry for the "Timer" button (thanks to Ville Skyttä)
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
- Making the "Menu" key behave consistently has not been well received by several
users, so the new option "Setup/OSD/Menu button closes" can be used to get the
old behavior back (which also is the default value of this option).
- Dropped the default vdr user. The program now always runs under the user id
it was started from, unless the '-u' option is given and it was started from
the 'root' user. If you want to have a default vdr user, you can activate and
adjust the "VDR_USER = vdr" line in your Make.config file (from the original
patch by Ludwig Nussel).
- Key macros can now be defined for all non-modeless keys (suggested by Mirko Dölle).
- Adjusted the "KEY MACROS" section of vdr.5 to the new plugin calling mechanism
introduced in version 1.3.32.
- Removed the now obsolete "ca.conf" section from vdr.1 (thanks to Ville Skyttä).
- Added missing description of L and R circular polarization to 'diseqc.conf'.
- Added a note about "modprobe capability" to INSTALL (suggested by Patrick Cernko).
- Fixed canonicalizing the file name in the SVDRP command GRAB to allow full path
names (thanks to Stefan Huelswitt).
- Added a missing '-' to the example for viewing a grabbed image on a remote host
(reported by Philippe Gramoullé).
- Made the "What's on now/next?" menus a lot faster by storing a pointer to each
channel's schedule in the cChannel data.
- Made the log messages regarding lost lock of devices "info" instead of "error"
(suggested by Andreas Brachold).
- The SVDRP command GRAB allows file names without extension again (suggested by
Stefan Huelswitt).
- Pressing '0' in the "Schedule" menu now rotates through displaying "This event on
this channel", "This event on all channels" and "All events on all channels".
This can be used to find reruns of a given show, or the episodes of a series.
Note that if there are many channels in your channels.conf, displaying the
"All events on all channels" page may take a while.
- The status markers in the "Schedule" menu are now only updated if a submenu is
closed in which a timer has been modified, which speeds up closing submenus.
- Now only writing Dolby Digital tracks into the 'info.vdr' file of a recording
if Setup.UseDolbyDigital is true (suggested by André Weidemann).
- Added a leading '0' to the day in the DayDateTime() function (thanks to Rolf
Ahrenberg).
- No longer displaying color buttons in the recording info menu if it has been
invoked from a player (reported by Jürgen Schilling).
-rw-r--r-- | CONTRIBUTORS | 30 | ||||
-rw-r--r-- | HISTORY | 57 | ||||
-rw-r--r-- | INSTALL | 14 | ||||
-rw-r--r-- | MANUAL | 14 | ||||
-rw-r--r-- | Make.config.template | 5 | ||||
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | README.vps | 1 | ||||
-rw-r--r-- | channels.c | 9 | ||||
-rw-r--r-- | channels.conf | 6 | ||||
-rw-r--r-- | channels.h | 6 | ||||
-rw-r--r-- | config.c | 5 | ||||
-rw-r--r-- | config.h | 7 | ||||
-rw-r--r-- | diseqc.conf | 2 | ||||
-rw-r--r-- | dvbdevice.c | 10 | ||||
-rw-r--r-- | eit.c | 8 | ||||
-rw-r--r-- | epg.c | 20 | ||||
-rw-r--r-- | epg.h | 3 | ||||
-rw-r--r-- | i18n.c | 119 | ||||
-rw-r--r-- | menu.c | 204 | ||||
-rw-r--r-- | remote.c | 15 | ||||
-rw-r--r-- | svdrp.c | 59 | ||||
-rw-r--r-- | thread.c | 3 | ||||
-rw-r--r-- | timers.c | 14 | ||||
-rw-r--r-- | timers.h | 11 | ||||
-rw-r--r-- | tools.c | 4 | ||||
-rw-r--r-- | vdr.1 | 9 | ||||
-rw-r--r-- | vdr.5 | 17 | ||||
-rw-r--r-- | vdr.c | 54 |
28 files changed, 558 insertions, 159 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index d524a30..dadcf8c 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -71,6 +71,8 @@ Matthias Schniedermeyer <ms@citd.de> and had their start time changed into the future for suggesting to give the timer status a bit that is set when that timer is currently recording + for suggesting to make the SVDRP command LSTT optionally list the channels + of the timers with their unique channel ids instead of their numbers Miha Setina <mihasetina@softhome.net> for translating OSD texts to the Slovenian language @@ -209,6 +211,10 @@ Stefan Huelswitt <huels@iname.com> live PIDs for reporting a problem in SetProgress() of the 'skincurses' plugin in case Total is 0 + for fixing canonicalizing the file name in the SVDRP command GRAB to allow full + path names + for suggesting that the SVDRP command GRAB should allow file names without extension + again Ulrich Röder <roeder@efr-net.de> for pointing out that there are channels that have a symbol rate higher than 27500 @@ -425,6 +431,7 @@ Mirko Dölle <mdoelle@linux-user.de> for suggesting to avoid the external 'find' command to scan the video directory for reporting a problem with inconsistent channel and timer lists for making the "Play" key in live viewing mode resume a previous replay session + for suggesting to allow defining key macros for all non-modeless keys Michael Rakowski <mrak@gmx.de> for translating OSD texts to the Polish language @@ -853,6 +860,9 @@ Andreas Brachold <vdr04@deltab.de> for reporting that there are empty info.vdr files created if there is no EPG info available for implementing the SVDRP command MOVC + for fixing the "plugins-clean" and "plugins-install" targets in the Makefile + for suggesting to make the log messages regarding lost lock of devices "info" + instead of "error" Manuel Hartl <icecep@gmx.net> for suggesting to extend the logging info when starting/stopping timers @@ -925,6 +935,7 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi> for changing the title of the recording info menu for reporting a bug in handling key macros with keys after @plugin for adding compiler options "-fPIC -g" to all plugins + for adding a leading '0' to the day in the DayDateTime() function Ralf Klueber <ralf.klueber@vodafone.com> for reporting a bug in cutting a recording if there is only a single editing mark @@ -940,6 +951,7 @@ Peter Bieringer <pb@bieringer.de> for suggesting to implement the command line option '--vfat' for reporting a leftover 'summary.vdr' in vdr.5 for adding more error messages and line numbers when reading EPG data and info.vdr + for fixing handling "more than 3 byte" key sequences in cKbdRemote::ReadKeySequence() Alexander Damhuis <ad@phonedation.de> for reporting problems when deleting a timer that is currently recording @@ -1459,6 +1471,9 @@ Ville Skyttä <ville.skytta@iki.fi> warnings with g++ 4.1.0 for reporting warnings with g++ 4.1.0 regarding incrementing the 'state' variables in the repacker classes in remux.c + for adding a missing #include <linux/unistd.h> to thread.c + for adding missing i18n entry for the "Timer" button + for removing the obsolete "ca.conf" section from vdr.1 Steffen Beyer <cpunk@reactor.de> for fixing setting the colored button help after deleting a recording in case the next @@ -1625,3 +1640,18 @@ Marcel Schaeben <mts280@gmx.de> Ingo Schneider <mail@ingo-schneider.de> for adding a SleepMs() in cRecorder::Action() to avoid a busy loop + +Patrick Cernko <errror@errror.org> + for suggesting to add a note about "modprobe capability" to INSTALL + +Philippe Gramoullé <philippe@gramoulle.com> + for reporting a a missing '-' in the example for viewing a grabbed image on a remote + host + +André Weidemann <Andre.Weidemann@web.de> + for suggesting to only write Dolby Digital tracks into the 'info.vdr' file of a + recording if Setup.UseDolbyDigital is true + +Jürgen Schilling <juergen_schilling@web.de> + for reporting that color buttons were displayed in the recording info menu if it + has been invoked from a player @@ -4029,7 +4029,7 @@ Video Disk Recorder Revision History name (based on a suggestion from Darren Salt). A simple way of viewing a grabbed image on a remote host is: - svdrpsend.pl -d <hostname> 'grab -' | sed -n -e 's/^216-//p' -e '1ibegin-base64 644 -' -e '$a====' | uudecode | display + svdrpsend.pl -d <hostname> 'grab -' | sed -n -e 's/^216-//p' -e '1ibegin-base64 644 -' -e '$a====' | uudecode | display - - The new command line option '-g' must be given if the SVDRP command GRAB shall be allowed to write image files to disk. The parameter to this option @@ -4134,3 +4134,58 @@ Video Disk Recorder Revision History - Added a SleepMs() in cRecorder::Action() to avoid a busy loop (thanks to Ingo Schneider). - Cleaned up some trailing white space. + +2006-01-15: Version 1.3.39 + +- The SVDRP command LSTT now accepts the new option 'id' to have the channels + of the timers listed with their unique channel ids instead of their numbers + (suggested by Matthias Schniedermeyer). +- Added a missing #include <linux/unistd.h> to thread.c (thanks to Ville Skyttä). +- Fixed the "plugins-clean" and "plugins-install" targets in the Makefile (thanks + to Andreas Brachold). +- Fixed handling "more than 3 byte" key sequences in cKbdRemote::ReadKeySequence() + (thanks to Peter Bieringer). If you are using the PC keyboard as remote control + input you may need to make VDR newly learn the keys by removing the remote.conf + file. +- To avoid problems with access rights when VDR shall run as 'root' it now skips + all SetCaps() and SetUser() calls when it is started as 'root' and "-u root" + is given. +- Added missing i18n entry for the "Timer" button (thanks to Ville Skyttä) +- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg). +- Making the "Menu" key behave consistently has not been well received by several + users, so the new option "Setup/OSD/Menu button closes" can be used to get the + old behavior back (which also is the default value of this option). +- Dropped the default vdr user. The program now always runs under the user id + it was started from, unless the '-u' option is given and it was started from + the 'root' user. If you want to have a default vdr user, you can activate and + adjust the "VDR_USER = vdr" line in your Make.config file (from the original + patch by Ludwig Nussel). +- Key macros can now be defined for all non-modeless keys (suggested by Mirko Dölle). +- Adjusted the "KEY MACROS" section of vdr.5 to the new plugin calling mechanism + introduced in version 1.3.32. +- Removed the now obsolete "ca.conf" section from vdr.1 (thanks to Ville Skyttä). +- Added missing description of L and R circular polarization to 'diseqc.conf'. +- Added a note about "modprobe capability" to INSTALL (suggested by Patrick Cernko). +- Fixed canonicalizing the file name in the SVDRP command GRAB to allow full path + names (thanks to Stefan Huelswitt). +- Added a missing '-' to the example for viewing a grabbed image on a remote host + (reported by Philippe Gramoullé). +- Made the "What's on now/next?" menus a lot faster by storing a pointer to each + channel's schedule in the cChannel data. +- Made the log messages regarding lost lock of devices "info" instead of "error" + (suggested by Andreas Brachold). +- The SVDRP command GRAB allows file names without extension again (suggested by + Stefan Huelswitt). +- Pressing '0' in the "Schedule" menu now rotates through displaying "This event on + this channel", "This event on all channels" and "All events on all channels". + This can be used to find reruns of a given show, or the episodes of a series. + Note that if there are many channels in your channels.conf, displaying the + "All events on all channels" page may take a while. +- The status markers in the "Schedule" menu are now only updated if a submenu is + closed in which a timer has been modified, which speeds up closing submenus. +- Now only writing Dolby Digital tracks into the 'info.vdr' file of a recording + if Setup.UseDolbyDigital is true (suggested by André Weidemann). +- Added a leading '0' to the day in the DayDateTime() function (thanks to Rolf + Ahrenberg). +- No longer displaying color buttons in the recording info menu if it has been + invoked from a player (reported by Jürgen Schilling). @@ -40,6 +40,12 @@ adjust the definition of DVBDIR in that file. VDR requires the Linux-DVB driver version dated 2003-08-23 or higher to work properly. +You will also need to install the "libjpeg" and "libcap" libraries, +as well as their "devel" packages to get the necessary header files +for compiling VDR. If the "capability" module is not compiled into +your kernel, you may need to do "modprobe capability" before running +VDR. + After extracting the package, change into the VDR directory and type 'make'. This should produce an executable file named 'vdr', which can be run after the DVB driver has been @@ -136,10 +142,10 @@ Setting the system time: ------------------------ If you want VDR to set the system time according to the data received -from the transponder, you need to start VDR as user 'root'. VDR will -then only keep the capability to set the system time, and set its -user id to a lesser privileged one ('vdr' by default, can be set -to a different value with the '-u' option). +from the transponder, you need to start VDR as user 'root'. For security +reasons you should then use the '-u' option to define a lesser privileged +user id under which VDR should actually run. It will then only keep the +capability to set the system time, and set its user id to the given one. You also need to enable the "EPG/Set system time" option in VDR's Setup menu, and select a transponder from which you want to receive the time in "Use time from transponder". Make sure you select a transponder @@ -72,6 +72,7 @@ Version 1.3 Red Recordings menu Green Schedule menu + Yellow Info Blue Timers menu (1) The "On/Off" button in the "Timers" menu only works if sorting the timers @@ -176,6 +177,12 @@ Version 1.3 whether there is currently a DVB card receiving the transponder this channel is on). + Pressing '0' in the "Schedule" menu rotates through displaying "This event on + this channel", "This event on all channels" and "All events on all channels". + This can be used to find reruns of a given show, or the episodes of a series. + Note that if there are many channels in your channels.conf, displaying the + "All events on all channels" page may take a while. + * Selecting a Channel There are four ways to select a channel: @@ -525,6 +532,13 @@ Version 1.3 (first) line of the list directly to the first (last) one. + Menu button closes = no + If set to "yes", pressing the "Menu" button while there is + anything displayed on the OSD will close the OSD. If set + to "no", the "Menu" button will open the main menu after + closing a temporary display, like, for instance, the channel + display. + Sort timers = yes Turns sorting the timers in the "Timers" menu on/off. Timers are sorted by ascending start times, with the first one being the next timer that will start. diff --git a/Make.config.template b/Make.config.template index 5cbf42b..fcf607c 100644 --- a/Make.config.template +++ b/Make.config.template @@ -6,7 +6,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Make.config.template 1.6 2005/09/02 14:24:31 kls Exp $ +# $Id: Make.config.template 1.7 2006/01/13 16:06:11 kls Exp $ ### The C compiler and options: @@ -30,3 +30,6 @@ VIDEODIR = /video LIRC_DEVICE = /dev/lircd RCU_DEVICE = /dev/ttyS1 + +## Define if you want vdr to not run as root +#VDR_USER = vdr @@ -4,7 +4,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 1.81 2006/01/01 15:12:05 kls Exp $ +# $Id: Makefile 1.83 2006/01/13 16:04:56 kls Exp $ .DELETE_ON_ERROR: @@ -77,6 +77,9 @@ endif ifdef REMOTE DEFINES += -DREMOTE_$(REMOTE) endif +ifdef VDR_USER +DEFINES += -DVDR_USER=\"$(VDR_USER)\" +endif LIRC_DEVICE ?= /dev/lircd RCU_DEVICE ?= /dev/ttyS1 @@ -192,7 +195,7 @@ plugins: include-dir plugins-clean: @for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do $(MAKE) -C "$(PLUGINDIR)/src/$$i" clean; done - @-rm -f $(PLUGINLIBDIR)/libvdr-*.so.$(VDRVERSION) + @-rm -f $(PLUGINDIR)/lib/libvdr-*.so.$(VDRVERSION) # Install the files: @@ -209,8 +212,8 @@ install: fi plugins-install: - @mkdir -p $(BINDIR)/$(PLUGINLIBDIR) - @cp $(PLUGINLIBDIR)/* $(BINDIR)/$(PLUGINLIBDIR) + @mkdir -p $(PLUGINLIBDIR) + @cp $(PLUGINDIR)/lib/libvdr-*.so.$(VDRVERSION) $(PLUGINLIBDIR) # Source documentation: @@ -134,3 +134,4 @@ Contact: ARD Digital: http://www.ard-digital.de/home/index.php?id=16&languageid=1 ZDF vision: http://www.zdf.de/ZDFde/inhalt/1/0,1872,1021601,00.html (select "zdfvision") + phone: 06131/706754 @@ -4,13 +4,14 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.c 1.47 2005/12/30 15:41:24 kls Exp $ + * $Id: channels.c 1.48 2006/01/14 15:51:02 kls Exp $ */ #include "channels.h" #include <linux/dvb/frontend.h> #include <ctype.h> #include "device.h" +#include "epg.h" // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d' // format characters in order to allow any number of blanks after a numeric @@ -174,6 +175,7 @@ cChannel::cChannel(void) guard = GUARD_INTERVAL_AUTO; hierarchy = HIERARCHY_AUTO; modification = CHANNELMOD_NONE; + schedule = NULL; linkChannels = NULL; refChannel = NULL; } @@ -184,6 +186,7 @@ cChannel::cChannel(const cChannel &Channel) shortName = NULL; provider = NULL; portalName = NULL; + schedule = NULL; linkChannels = NULL; refChannel = NULL; *this = Channel; @@ -293,6 +296,7 @@ bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarizatio srate = Srate; coderateH = CoderateH; modulation = QPSK; + schedule = NULL; } return true; } @@ -310,6 +314,7 @@ bool cChannel::SetCableTransponderData(int Source, int Frequency, int Modulation modulation = Modulation; srate = Srate; coderateH = CoderateH; + schedule = NULL; } return true; } @@ -331,6 +336,7 @@ bool cChannel::SetTerrTransponderData(int Source, int Frequency, int Bandwidth, coderateL = CoderateL; guard = Guard; transmission = Transmission; + schedule = NULL; } return true; } @@ -350,6 +356,7 @@ void cChannel::SetId(int Nid, int Tid, int Sid, int Rid) rid = Rid; if (Number()) Channels.HashChannel(this); + schedule = NULL; } } diff --git a/channels.conf b/channels.conf index e4f0fa4..c427628 100644 --- a/channels.conf +++ b/channels.conf @@ -45,11 +45,11 @@ MDR FERNSEHEN;ARD:12109:hC34:S19.2E:27500:401:402=deu:404:0:28204:1:1073:0 rbb Berlin;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0 :Premiere World PREMIERE START,START;PREMIERE:11797:hC34:S19.2E:27500:255:256=deu:32:1801,1722,1702:8:133:2:0 -PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1801,1722,1702:10:133:2:0 +PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu;515=deu:32:1801,1722,1702:10:133:2:0 PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1801,1722,1702:11:133:2:0 PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1702,1801:43:133:2:0 PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu,769=deu:32:1801,1722,1702:9:133:2:0 -PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:32:1722,1702,1801:29:133:2:0 +PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu:32:1722,1702,1801:29:133:2:0 PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1722,1801:41:133:2:0 PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1801,1702,1722:20:133:2:0 DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:32:1801,1702,1722:34:133:17:0 @@ -57,7 +57,7 @@ DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:32:1801,170 PREMIERE DIREKT,DIREKT;PREMIERE:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0:0:18:133:4:0 :PW Erotic BEATE-UHSE.TV,B-UHSE;PREMIERE:11758:hC34:S19.2E:27500:1791:1792=deu:32:1722,1702,1801:21:133:17:0 -EROTIK - AB 18!,AB 18!;PREMIERE:12031:hC34:S19.2E:27500:1279:1280=deu:0:1722,1801,1702,1810:513:133:4:0 +EROTIK - AB 18!,AB 18!;PREMIERE:12031:hC34:S19.2E:27500:1279:1280=deu:0:1801,1702,1722,1810:513:133:4:0 :Sportsworld PREMIERE SPORT PORTAL,SPORT PORTAL;PREMIERE:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1722,1801,1702:17:133:3:0 PREMIERE WIN,WIN;PREMIERE:12031:hC34:S19.2E:27500:3839:3840=deu:33:0:27:133:4:0 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.h 1.37 2006/01/07 13:00:43 kls Exp $ + * $Id: channels.h 1.38 2006/01/14 15:51:26 kls Exp $ */ #ifndef __CHANNELS_H @@ -103,7 +103,10 @@ public: class cLinkChannels : public cList<cLinkChannel> { }; +class cSchedule; + class cChannel : public cListObject { + friend class cSchedules; friend class cMenuEditChannel; private: static cString ToText(const cChannel *Channel); @@ -142,6 +145,7 @@ private: int hierarchy; int __EndData__; int modification; + mutable const cSchedule *schedule; cLinkChannels *linkChannels; cChannel *refChannel; cString ParametersToString(void) const; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.140 2006/01/07 12:28:49 kls Exp $ + * $Id: config.c 1.141 2006/01/13 15:19:37 kls Exp $ */ #include "config.h" @@ -220,6 +220,7 @@ cSetup::cSetup(void) TimeoutRequChInfo = 1; MenuScrollPage = 1; MenuScrollWrap = 0; + MenuButtonCloses = 0; MarkInstantRecord = 1; strcpy(NameInstantRecord, "TITLE EPISODE"); InstantRecordTime = 180; @@ -379,6 +380,7 @@ bool cSetup::Parse(const char *Name, const char *Value) else if (!strcasecmp(Name, "TimeoutRequChInfo")) TimeoutRequChInfo = atoi(Value); else if (!strcasecmp(Name, "MenuScrollPage")) MenuScrollPage = atoi(Value); else if (!strcasecmp(Name, "MenuScrollWrap")) MenuScrollWrap = atoi(Value); + else if (!strcasecmp(Name, "MenuButtonCloses")) MenuButtonCloses = atoi(Value); else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value); else if (!strcasecmp(Name, "NameInstantRecord")) strn0cpy(NameInstantRecord, Value, MaxFileName); else if (!strcasecmp(Name, "InstantRecordTime")) InstantRecordTime = atoi(Value); @@ -445,6 +447,7 @@ bool cSetup::Save(void) Store("TimeoutRequChInfo", TimeoutRequChInfo); Store("MenuScrollPage", MenuScrollPage); Store("MenuScrollWrap", MenuScrollWrap); + Store("MenuButtonCloses", MenuButtonCloses); Store("MarkInstantRecord", MarkInstantRecord); Store("NameInstantRecord", NameInstantRecord); Store("InstantRecordTime", InstantRecordTime); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.238 2006/01/07 12:57:42 kls Exp $ + * $Id: config.h 1.240 2006/01/13 15:17:19 kls Exp $ */ #ifndef __CONFIG_H @@ -19,8 +19,8 @@ #include "i18n.h" #include "tools.h" -#define VDRVERSION "1.3.38" -#define VDRVERSNUM 10338 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.3.39" +#define VDRVERSNUM 10339 // Version * 10000 + Major * 100 + Minor #define MAXPRIORITY 99 #define MAXLIFETIME 99 @@ -193,6 +193,7 @@ public: int TimeoutRequChInfo; int MenuScrollPage; int MenuScrollWrap; + int MenuButtonCloses; int MarkInstantRecord; char NameInstantRecord[MaxFileName]; int InstantRecordTime; diff --git a/diseqc.conf b/diseqc.conf index d4526d8..9708327 100644 --- a/diseqc.conf +++ b/diseqc.conf @@ -8,7 +8,7 @@ # slof: switch frequency of LNB; the first entry with # an slof greater than the actual transponder # frequency will be used -# polarization: V = vertical, H = horizontal +# polarization: V = vertical, H = horizontal, L = Left circular, R = Right circular # lof: the local oscillator frequency to subtract from # the actual transponder frequency # command: diff --git a/dvbdevice.c b/dvbdevice.c index 7fa39cc..fe32298 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.149 2006/01/07 15:15:01 kls Exp $ + * $Id: dvbdevice.c 1.150 2006/01/14 15:57:36 kls Exp $ */ #include "dvbdevice.h" @@ -314,7 +314,7 @@ void cDvbTuner::Action(void) tunerStatus = tsSet; diseqcCommands = NULL; if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these - esyslog("ERROR: frontend %d timed out while tuning to channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); + isyslog("frontend %d timed out while tuning to channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); lastTimeoutReport = time(NULL); } continue; @@ -323,13 +323,13 @@ void cDvbTuner::Action(void) if (Status & FE_REINIT) { tunerStatus = tsSet; diseqcCommands = NULL; - esyslog("ERROR: frontend %d was reinitialized", cardIndex); + isyslog("frontend %d was reinitialized", cardIndex); lastTimeoutReport = 0; continue; } else if (Status & FE_HAS_LOCK) { if (LostLock) { - esyslog("frontend %d regained lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); + isyslog("frontend %d regained lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); LostLock = false; } tunerStatus = tsLocked; @@ -338,7 +338,7 @@ void cDvbTuner::Action(void) } else if (tunerStatus == tsLocked) { LostLock = true; - esyslog("ERROR: frontend %d lost lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); + isyslog("frontend %d lost lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder()); tunerStatus = tsTuned; Timer.Set(lockTimeout); lastTimeoutReport = 0; @@ -8,7 +8,7 @@ * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>. * - * $Id: eit.c 1.113 2005/12/26 11:50:09 kls Exp $ + * $Id: eit.c 1.114 2006/01/14 15:41:21 kls Exp $ */ #include "eit.h" @@ -35,11 +35,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data) if (!channel) return; // only collect data for known channels - cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channelID); - if (!pSchedule) { - pSchedule = new cSchedule(channelID); - Schedules->Add(pSchedule); - } + cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channel, true); bool Empty = true; bool Modified = false; @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * - * $Id: epg.c 1.47 2005/12/30 15:41:59 kls Exp $ + * $Id: epg.c 1.49 2006/01/15 13:58:30 kls Exp $ */ #include "epg.h" @@ -247,6 +247,8 @@ void cEvent::Dump(FILE *f, const char *Prefix, bool InfoOnly) const if (components) { for (int i = 0; i < components->NumComponents(); i++) { tComponent *p = components->Component(i); + if (!Setup.UseDolbyDigital && p->stream == 0x02 && p->type == 0x05) + continue; fprintf(f, "%sX %s\n", Prefix, *p->ToString()); } } @@ -997,3 +999,19 @@ const cSchedule *cSchedules::GetSchedule(tChannelID ChannelID) const return NULL; } +const cSchedule *cSchedules::GetSchedule(const cChannel *Channel, bool AddIfMissing) const +{ + // This is not very beautiful, but it dramatically speeds up the + // "What's on now/next?" menus. + static cSchedule DummySchedule(tChannelID::InvalidID); + if (!Channel->schedule) + Channel->schedule = GetSchedule(Channel->GetChannelID()); + if (!Channel->schedule) + Channel->schedule = &DummySchedule; + if (Channel->schedule == &DummySchedule && AddIfMissing) { + cSchedule *Schedule = new cSchedule(Channel->GetChannelID()); + ((cSchedules *)this)->Add(Schedule); + Channel->schedule = Schedule; + } + return Channel->schedule != &DummySchedule? Channel->schedule : NULL; +} @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * - * $Id: epg.h 1.28 2005/12/27 14:31:24 kls Exp $ + * $Id: epg.h 1.29 2006/01/14 15:45:24 kls Exp $ */ #ifndef __EPG_H @@ -179,6 +179,7 @@ public: static bool Read(FILE *f = NULL); cSchedule *AddSchedule(tChannelID ChannelID); const cSchedule *GetSchedule(tChannelID ChannelID) const; + const cSchedule *GetSchedule(const cChannel *Channel, bool AddIfMissing = false) const; }; void ReportEpgBugFixStats(bool Reset = false); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.230 2006/01/08 11:56:31 kls Exp $ + * $Id: i18n.c 1.235 2006/01/15 12:22:15 kls Exp $ * * Translations provided by: * @@ -441,6 +441,69 @@ const tI18nPhrase Phrases[] = { "Programm - %s", "Program - %s", }, + { "This event - %s", + "Diese Sendung - %s", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + }, + { "This event - all channels", + "Diese Sendung - alle Kanäle", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + }, + { "All events - all channels", + "Alle Sendungen - alle Kanäle", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + }, { "What's on now?", "Was läuft jetzt?", "Kaj je na sporedu?", @@ -610,6 +673,27 @@ const tI18nPhrase Phrases[] = { "Sees/Väljas", "Til/Fra", }, + { "Timer", + "Timer", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "Ajastin", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + }, { "Button$Record", "Aufnehmen", "Posnemi", @@ -1200,7 +1284,7 @@ const tI18nPhrase Phrases[] = { "Optagelse om %d minutter - sluk alligevel?", }, { "Press any key to cancel shutdown", - "Taste drücken um Shutdown abzubrechen", + "Taste drücken, um Shutdown abzubrechen", "Pritisni katerikoli gumb za preklic izklopa", "Un tasto per annullare lo spegnimento", "Druk een toets om shutdown af te breken", @@ -2260,7 +2344,7 @@ const tI18nPhrase Phrases[] = { "Espaço em disco reduzido!", "Disque presque plein!", "Lite ledig diskplass!", - "Kovalevy lähes täynnä!", + "Tallennustila loppumassa!", "Dysk wkrotce pelny!", "¡Disco casi lleno", "Ï óêëçñüò êïíôåýåé íÜ ãåìßóåé!", @@ -2955,7 +3039,7 @@ const tI18nPhrase Phrases[] = { "Mostrar info ao mudar de Canal", "Affichage progr. en cours", "Info ved kanalskifte", - "Näytä kanavatieto", + "Näytä kanavatieto vaihdettaessa", "Informacja przy zmianie kanalu", "Información para cambio de canal", "Ðëçñïöïñßåò óôÞí áëëáãÞ êáíáëéïý", @@ -2976,7 +3060,7 @@ const tI18nPhrase Phrases[] = { "", // TODO "", // TODO "", // TODO - "", // TODO + "Sulje kanavatieto pyydettäessä", "", // TODO "", // TODO "", // TODO @@ -3031,6 +3115,27 @@ const tI18nPhrase Phrases[] = { "Ridade kerimine", "Scroll rundt", }, + { "Setup.OSD$Menu button closes", + "Menu-Taste schließt", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + }, { "Setup.OSD$Sort timers", "Timer sortieren", "Sortiraj termine", @@ -4155,7 +4260,7 @@ const tI18nPhrase Phrases[] = { "",//TODO "",//TODO "",//TODO - "",//TODO + " 0\t-.#~,/_@1\tabcäå2\tdef3\tghi4\tjkl5\tmnoö6\tpqrs7\ttuv8\twxyz9", "",//TODO "",//TODO "",//TODO @@ -5397,7 +5502,7 @@ const tI18nPhrase Phrases[] = { "",//TODO "",//TODO "",//TODO - "",//TODO + "Tallennus aloitettu", "",//TODO "",//TODO "",//TODO @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.390 2006/01/08 11:39:57 kls Exp $ + * $Id: menu.c 1.396 2006/01/15 15:02:36 kls Exp $ */ #include "menu.h" @@ -323,10 +323,10 @@ public: cMenuChannelItem(cChannel *Channel); static void SetSortMode(eChannelSortMode SortMode) { sortMode = SortMode; } static void IncSortMode(void) { sortMode = eChannelSortMode((sortMode == csmProvider) ? csmNumber : sortMode + 1); } + static eChannelSortMode SortMode(void) { return sortMode; } virtual int Compare(const cListObject &ListObject) const; virtual void Set(void); cChannel *Channel(void) { return channel; } - static eChannelSortMode SortMode(void) { return sortMode; } }; cMenuChannelItem::eChannelSortMode cMenuChannelItem::sortMode = csmNumber; @@ -916,7 +916,7 @@ cMenuEvent::cMenuEvent(const cEvent *Event, bool CanSwitch) SetTitle(channel->Name()); int TimerMatch = tmNone; Timers.GetMatch(event, &TimerMatch); - SetHelp(TimerMatch == tmFull ? tr("Timer") : tr("Button$Record"), NULL, NULL, CanSwitch ? tr("Button$Switch") : NULL); + SetHelp(TimerMatch == tmFull ? tr("Button$Timer") : tr("Button$Record"), NULL, NULL, CanSwitch ? tr("Button$Switch") : NULL); } } } @@ -962,21 +962,44 @@ eOSState cMenuEvent::ProcessKey(eKeys Key) class cMenuScheduleItem : public cOsdItem { public: + enum eScheduleSortMode { ssmAllThis, ssmThisThis, ssmThisAll, ssmAllAll }; // "which event(s) on which channel(s)" +private: + static eScheduleSortMode sortMode; +public: const cEvent *event; const cChannel *channel; + bool withDate; int timerMatch; - cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL); + cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL, bool WithDate = false); + static void SetSortMode(eScheduleSortMode SortMode) { sortMode = SortMode; } + static void IncSortMode(void) { sortMode = eScheduleSortMode((sortMode == ssmAllAll) ? ssmAllThis : sortMode + 1); } + static eScheduleSortMode SortMode(void) { return sortMode; } + virtual int Compare(const cListObject &ListObject) const; bool Update(bool Force = false); -}; + }; + +cMenuScheduleItem::eScheduleSortMode cMenuScheduleItem::sortMode = ssmAllThis; -cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel) +cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel, bool WithDate) { event = Event; channel = Channel; + withDate = WithDate; timerMatch = tmNone; Update(true); } +int cMenuScheduleItem::Compare(const cListObject &ListObject) const +{ + cMenuScheduleItem *p = (cMenuScheduleItem *)&ListObject; + int r = -1; + if (sortMode != ssmAllThis) + r = strcoll(event->Title(), p->event->Title()); + if (sortMode == ssmAllThis || r == 0) + r = event->StartTime() - p->event->StartTime(); + return r; +} + static char *TimerMatchChars = " tT"; bool cMenuScheduleItem::Update(bool Force) @@ -989,7 +1012,9 @@ bool cMenuScheduleItem::Update(bool Force) char t = TimerMatchChars[timerMatch]; char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' '; char r = event->IsRunning() ? '*' : ' '; - if (channel) + if (channel && withDate) + asprintf(&buffer, "%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), 6, *event->GetDateString(), *event->GetTimeString(), t, v, r, event->Title()); + else if (channel) 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()); else asprintf(&buffer, "%.*s\t%s\t%c%c%c\t%s", 6, *event->GetDateString(), *event->GetTimeString(), t, v, r, event->Title()); @@ -1005,6 +1030,7 @@ class cMenuWhatsOn : public cOsdMenu { private: bool now; int helpKeys; + int timerState; eOSState Record(void); eOSState Switch(void); static int currentChannel; @@ -1027,9 +1053,11 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha { now = Now; helpKeys = -1; + timerState = 0; + Timers.Modified(timerState); for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { if (!Channel->GroupSep()) { - const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (Schedule) { const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent(); if (Event) @@ -1044,10 +1072,12 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha bool cMenuWhatsOn::Update(void) { bool result = false; - for (cOsdItem *item = First(); item; item = Next(item)) { - if (((cMenuScheduleItem *)item)->Update()) - result = true; - } + if (Timers.Modified(timerState)) { + for (cOsdItem *item = First(); item; item = Next(item)) { + if (((cMenuScheduleItem *)item)->Update()) + result = true; + } + } return result; } @@ -1163,9 +1193,14 @@ private: bool now, next; int otherChannel; int helpKeys; + int timerState; + eOSState Number(void); eOSState Record(void); eOSState Switch(void); - void PrepareSchedule(cChannel *Channel); + void PrepareScheduleAllThis(const cEvent *Event, const cChannel *Channel); + void PrepareScheduleThisThis(const cEvent *Event, const cChannel *Channel); + void PrepareScheduleThisAll(const cEvent *Event, const cChannel *Channel); + void PrepareScheduleAllAll(const cEvent *Event, const cChannel *Channel); bool Update(void); void SetHelpKeys(void); public: @@ -1175,16 +1210,19 @@ public: }; cMenuSchedule::cMenuSchedule(void) -:cOsdMenu("", 7, 6, 4) +:cOsdMenu("") { now = next = false; otherChannel = 0; helpKeys = -1; + timerState = 0; + Timers.Modified(timerState); + cMenuScheduleItem::SetSortMode(cMenuScheduleItem::ssmAllThis); cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); if (channel) { cMenuWhatsOn::SetCurrentChannel(channel->Number()); schedules = cSchedules::Schedules(schedulesLock); - PrepareSchedule(channel); + PrepareScheduleAllThis(NULL, channel); SetHelpKeys(); } } @@ -1194,33 +1232,94 @@ cMenuSchedule::~cMenuSchedule() cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared } -void cMenuSchedule::PrepareSchedule(cChannel *Channel) +void cMenuSchedule::PrepareScheduleAllThis(const cEvent *Event, const cChannel *Channel) { Clear(); + SetCols(7, 6, 4); char *buffer = NULL; asprintf(&buffer, tr("Schedule - %s"), Channel->Name()); SetTitle(buffer); free(buffer); - if (schedules) { - const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID()); + if (schedules && Channel) { + const cSchedule *Schedule = schedules->GetSchedule(Channel); + if (Schedule) { + const cEvent *PresentEvent = Event ? Event : Schedule->GetPresentEvent(Channel->Number() == cDevice::CurrentChannel()); + time_t now = time(NULL) - Setup.EPGLinger * 60; + for (const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->Next(ev)) { + if (ev->EndTime() > now || ev == PresentEvent) + Add(new cMenuScheduleItem(ev), ev == PresentEvent); + } + } + } +} + +void cMenuSchedule::PrepareScheduleThisThis(const cEvent *Event, const cChannel *Channel) +{ + Clear(); + SetCols(7, 6, 4); + char *buffer = NULL; + asprintf(&buffer, tr("This event - %s"), Channel->Name()); + SetTitle(buffer); + free(buffer); + if (schedules && Channel && Event) { + const cSchedule *Schedule = schedules->GetSchedule(Channel); if (Schedule) { - const cEvent *PresentEvent = Schedule->GetPresentEvent(Channel->Number() == cDevice::CurrentChannel()); time_t now = time(NULL) - Setup.EPGLinger * 60; - for (const cEvent *Event = Schedule->Events()->First(); Event; Event = Schedule->Events()->Next(Event)) { - if (Event->EndTime() > now || Event == PresentEvent) - Add(new cMenuScheduleItem(Event), Event == PresentEvent); + for (const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->Next(ev)) { + if ((ev->EndTime() > now || ev == Event) && !strcmp(ev->Title(), Event->Title())) + Add(new cMenuScheduleItem(ev), ev == Event); } } } } +void cMenuSchedule::PrepareScheduleThisAll(const cEvent *Event, const cChannel *Channel) +{ + Clear(); + SetCols(CHNUMWIDTH, 7, 7, 6, 4); + SetTitle(tr("This event - all channels")); + if (schedules && Event) { + for (cChannel *ch = Channels.First(); ch; ch = Channels.Next(ch)) { + const cSchedule *Schedule = schedules->GetSchedule(ch); + if (Schedule) { + time_t now = time(NULL) - Setup.EPGLinger * 60; + for (const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->Next(ev)) { + if ((ev->EndTime() > now || ev == Event) && !strcmp(ev->Title(), Event->Title())) + Add(new cMenuScheduleItem(ev, ch, true), ev == Event && ch == Channel); + } + } + } + } +} + +void cMenuSchedule::PrepareScheduleAllAll(const cEvent *Event, const cChannel *Channel) +{ + Clear(); + SetCols(CHNUMWIDTH, 7, 7, 6, 4); + SetTitle(tr("All events - all channels")); + if (schedules) { + for (cChannel *ch = Channels.First(); ch; ch = Channels.Next(ch)) { + const cSchedule *Schedule = schedules->GetSchedule(ch); + if (Schedule) { + time_t now = time(NULL) - Setup.EPGLinger * 60; + for (const cEvent *ev = Schedule->Events()->First(); ev; ev = Schedule->Events()->Next(ev)) { + if (ev->EndTime() > now || ev == Event) + Add(new cMenuScheduleItem(ev, ch, true), ev == Event && ch == Channel); + } + } + } + } +} + bool cMenuSchedule::Update(void) { bool result = false; - for (cOsdItem *item = First(); item; item = Next(item)) { - if (((cMenuScheduleItem *)item)->Update()) - result = true; - } + if (Timers.Modified(timerState)) { + for (cOsdItem *item = First(); item; item = Next(item)) { + if (((cMenuScheduleItem *)item)->Update()) + result = true; + } + } return result; } @@ -1241,6 +1340,29 @@ void cMenuSchedule::SetHelpKeys(void) } } +eOSState cMenuSchedule::Number(void) +{ + cMenuScheduleItem::IncSortMode(); + cMenuScheduleItem *CurrentItem = (cMenuScheduleItem *)Get(Current()); + const cChannel *Channel = NULL; + const cEvent *Event = NULL; + if (CurrentItem) { + Event = CurrentItem->event; + Channel = Channels.GetByChannelID(Event->ChannelID(), true); + } + switch (cMenuScheduleItem::SortMode()) { + case cMenuScheduleItem::ssmAllThis: PrepareScheduleAllThis(Event, Channel); break; + case cMenuScheduleItem::ssmThisThis: PrepareScheduleThisThis(Event, Channel); break; + case cMenuScheduleItem::ssmThisAll: PrepareScheduleThisAll(Event, Channel); break; + case cMenuScheduleItem::ssmAllAll: PrepareScheduleAllAll(Event, Channel); break; + } + CurrentItem = (cMenuScheduleItem *)Get(Current()); + Sort(); + SetCurrent(CurrentItem); + Display(); + return osContinue; +} + eOSState cMenuSchedule::Record(void) { cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current()); @@ -1290,6 +1412,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) if (state == osUnknown) { switch (Key) { + case k0: return Number(); case kRecord: case kRed: return Record(); case kGreen: if (schedules) { @@ -1325,7 +1448,8 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) if (ei) { cChannel *channel = Channels.GetByChannelID(ei->ChannelID(), true); if (channel) { - PrepareSchedule(channel); + cMenuScheduleItem::SetSortMode(cMenuScheduleItem::ssmAllThis); + PrepareScheduleAllThis(NULL, channel); if (channel->Number() != cDevice::CurrentChannel()) { otherChannel = channel->Number(); SetHelp(Count() ? tr("Button$Record") : NULL, tr("Button$Now"), tr("Button$Next"), tr("Button$Switch")); @@ -1578,17 +1702,19 @@ cOsdObject *CamControl(void) class cMenuRecording : public cOsdMenu { private: const cRecording *recording; + bool withButtons; public: - cMenuRecording(const cRecording *Recording); + cMenuRecording(const cRecording *Recording, bool WithButtons = false); virtual void Display(void); virtual eOSState ProcessKey(eKeys Key); }; -cMenuRecording::cMenuRecording(const cRecording *Recording) +cMenuRecording::cMenuRecording(const cRecording *Recording, bool WithButtons) :cOsdMenu(tr("Recording info")) { recording = Recording; - if (recording) + withButtons = WithButtons; + if (withButtons) SetHelp(tr("Button$Play"), tr("Button$Rewind")); } @@ -1620,8 +1746,11 @@ eOSState cMenuRecording::ProcessKey(eKeys Key) if (state == osUnknown) { switch (Key) { - case kRed: Key = kOk; // will play the recording, even if recording commands are defined - case kGreen: cRemote::Put(Key, true); + case kRed: if (withButtons) + Key = kOk; // will play the recording, even if recording commands are defined + case kGreen: if (!withButtons) + break; + cRemote::Put(Key, true); // continue with osBack to close the info menu and process the key case kOk: return osBack; default: break; @@ -1869,7 +1998,7 @@ eOSState cMenuRecordings::Info(void) if (ri && !ri->IsDirectory()) { cRecording *recording = GetRecording(ri); if (recording && recording->Info()->Title()) - return AddSubMenu(new cMenuRecording(recording)); + return AddSubMenu(new cMenuRecording(recording, true)); } return osContinue; } @@ -2007,6 +2136,7 @@ void cMenuSetupOSD::Set(void) Add(new cMenuEditBoolItem(tr("Setup.OSD$Timeout requested channel info"), &data.TimeoutRequChInfo)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Scroll pages"), &data.MenuScrollPage)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Scroll wraps"), &data.MenuScrollWrap)); + Add(new cMenuEditBoolItem(tr("Setup.OSD$Menu button closes"), &data.MenuButtonCloses)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Sort timers"), &data.SortTimers)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs)); SetCurrent(Get(current)); @@ -2832,7 +2962,7 @@ static void SetTrackDescriptions(bool Live) if (Channel) { const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(Channel); if (Schedule) { const cEvent *Present = Schedule->GetPresentEvent(true); if (Present) @@ -2915,7 +3045,7 @@ void cDisplayChannel::DisplayInfo(void) cSchedulesLock SchedulesLock; const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(channel); if (Schedule) { const cEvent *Present = Schedule->GetPresentEvent(true); const cEvent *Following = Schedule->GetFollowingEvent(true); @@ -3345,7 +3475,7 @@ bool cRecordControl::GetEvent(void) cSchedulesLock SchedulesLock; const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(channel); if (Schedule) { event = Schedule->GetEventAround(Time); if (event) { @@ -3868,7 +3998,7 @@ cOsdObject *cReplayControl::GetInfo(void) { cRecording *Recording = Recordings.GetByName(cReplayControl::LastReplayed()); if (Recording) - return new cMenuRecording(Recording); + return new cMenuRecording(Recording, false); return NULL; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remote.c 1.46 2006/01/01 14:21:07 kls Exp $ + * $Id: remote.c 1.48 2006/01/15 15:17:40 kls Exp $ */ #include "remote.h" @@ -301,12 +301,13 @@ uint64 cKbdRemote::ReadKeySequence(void) k |= key1 & 0xFF; switch (key1) { case 0x31 ... 0x3F: // more-byte sequence - while (key1 != 0x7E) { - k <<= 8; - k |= key1 & 0xFF; - if ((key1 = ReadKey()) < 0) - break; // Sequence ends here - } + case 0x5B: // strange, may apparently occur + do { + if ((key1 = ReadKey()) < 0) + break; // Sequence ends here + k <<= 8; + k |= key1 & 0xFF; + } while (key1 != 0x7E); break; } } @@ -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.89 2005/12/30 15:42:29 kls Exp $ + * $Id: svdrp.c 1.93 2006/01/14 16:08:20 kls Exp $ */ #include "svdrp.h" @@ -229,9 +229,11 @@ const char *HelpPages[] = { "LSTR [ <number> ]\n" " List recordings. Without option, all recordings are listed. Otherwise\n" " the information for the given recording is listed.", - "LSTT [ <number> ]\n" + "LSTT [ <number> ] [ id ]\n" " List timers. Without option, all timers are listed. Otherwise\n" - " only the given timer is listed.", + " only the given timer is listed. If the keyword 'id' is given, the\n" + " channels will be listed with their unique channel ids instead of\n" + " their numbers.", "MESG <message>\n" " Displays the given message on the OSD. The message will be queued\n" " and displayed whenever this is suitable.\n", @@ -681,10 +683,6 @@ void cSVDRP::CmdGRAB(const char *Option) } else if (strcmp(FileName, "-") == 0) FileName = NULL; - else { - Reply(501, "Missing filename extension in \"%s\"", FileName); - return; - } // image quality (and obsolete type): if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) { if (strcasecmp(p, "JPEG") == 0 || strcasecmp(p, "PNM") == 0) { @@ -729,10 +727,13 @@ void cSVDRP::CmdGRAB(const char *Option) char RealFileName[PATH_MAX]; if (FileName) { if (grabImageDir) { - char *s; - asprintf(&s, "%s/%s", grabImageDir, FileName); - FileName = s; - char *slash = strrchr(FileName, '/'); // there definitely is one + char *s = 0; + char *slash = strrchr(FileName, '/'); + if (!slash) { + asprintf(&s, "%s/%s", grabImageDir, FileName); + FileName = s; + } + slash = strrchr(FileName, '/'); // there definitely is one *slash = 0; char *r = realpath(FileName, RealFileName); *slash = '/'; @@ -931,7 +932,7 @@ void cSVDRP::CmdLSTE(const char *Option) else Channel = Channels.GetByChannelID(tChannelID::FromString(Option)); if (Channel) { - Schedule = Schedules->GetSchedule(Channel->GetChannelID()); + Schedule = Schedules->GetSchedule(Channel); if (!Schedule) { Reply(550, "No schedule found"); return; @@ -1009,22 +1010,38 @@ void cSVDRP::CmdLSTR(const char *Option) void cSVDRP::CmdLSTT(const char *Option) { + int Number = 0; + bool Id = false; if (*Option) { - if (isnumber(Option)) { - cTimer *timer = Timers.Get(strtol(Option, NULL, 10) - 1); - if (timer) - Reply(250, "%d %s", timer->Index() + 1, *timer->ToText()); - else - Reply(501, "Timer \"%s\" not defined", Option); - } + char buf[strlen(Option) + 1]; + strcpy(buf, Option); + const char *delim = " \t"; + char *strtok_next; + char *p = strtok_r(buf, delim, &strtok_next); + while (p) { + if (isnumber(p)) + Number = strtol(p, NULL, 10); + else if (strcasecmp(p, "ID") == 0) + Id = true; + else { + Reply(501, "Unknown option: \"%s\"", p); + return; + } + p = strtok_r(NULL, delim, &strtok_next); + } + } + if (Number) { + cTimer *timer = Timers.Get(Number - 1); + if (timer) + Reply(250, "%d %s", timer->Index() + 1, *timer->ToText(Id)); else - Reply(501, "Error in timer number \"%s\"", Option); + Reply(501, "Timer \"%s\" not defined", Option); } else if (Timers.Count()) { for (int i = 0; i < Timers.Count(); i++) { cTimer *timer = Timers.Get(i); if (timer) - Reply(i < Timers.Count() - 1 ? -250 : 250, "%d %s", timer->Index() + 1, *timer->ToText()); + Reply(i < Timers.Count() - 1 ? -250 : 250, "%d %s", timer->Index() + 1, *timer->ToText(Id)); else Reply(501, "Timer \"%d\" not found", i + 1); } @@ -4,11 +4,12 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.c 1.50 2006/01/04 15:01:22 kls Exp $ + * $Id: thread.c 1.51 2006/01/08 16:03:56 kls Exp $ */ #include "thread.h" #include <errno.h> +#include <linux/unistd.h> #include <malloc.h> #include <stdarg.h> #include <sys/resource.h> @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.c 1.41 2006/01/08 11:40:29 kls Exp $ + * $Id: timers.c 1.43 2006/01/15 13:31:11 kls Exp $ */ #include "timers.h" @@ -515,7 +515,7 @@ cTimers Timers; cTimers::cTimers(void) { - modified = false; + state = 0; beingEdited = 0;; lastSetEvents = 0; } @@ -574,13 +574,13 @@ cTimer *cTimers::GetNextActiveTimer(void) void cTimers::SetModified(void) { - modified = true; + state++; } -bool cTimers::Modified(void) +bool cTimers::Modified(int &State) { - bool Result = modified; - modified = false; + bool Result = state != State; + State = state; return Result; } @@ -596,7 +596,7 @@ void cTimers::SetEvents(void) if (Schedules) { if (!lastSetEvents || Schedules->Modified() >= lastSetEvents) { for (cTimer *ti = First(); ti; ti = Next(ti)) { - const cSchedule *Schedule = Schedules->GetSchedule(ti->Channel()->GetChannelID()); + const cSchedule *Schedule = Schedules->GetSchedule(ti->Channel()); if (Schedule) { if (!lastSetEvents || Schedule->Modified() >= lastSetEvents) { const cEvent *Event = NULL; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.h 1.23 2006/01/06 14:13:17 kls Exp $ + * $Id: timers.h 1.24 2006/01/15 13:29:44 kls Exp $ */ #ifndef __TIMERS_H @@ -96,7 +96,7 @@ public: class cTimers : public cConfig<cTimer> { private: - bool modified; + int state; int beingEdited; time_t lastSetEvents; public: @@ -109,9 +109,10 @@ public: void IncBeingEdited(void) { beingEdited++; } void DecBeingEdited(void) { if (!--beingEdited) lastSetEvents = 0; } void SetModified(void); - bool Modified(void); - ///< Returns true if any of the timers have been modified. - ///< Calling this function resets the 'modified' flag to false. + bool Modified(int &State); + ///< Returns true if any of the timers have been modified, which + ///< is detected by State being different than the internal state. + ///< Upon return the internal state will be stored in State. void SetEvents(void); void DeleteExpired(void); }; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.109 2006/01/08 11:40:35 kls Exp $ + * $Id: tools.c 1.110 2006/01/15 14:31:45 kls Exp $ */ #include "tools.h" @@ -625,7 +625,7 @@ cString DayDateTime(time_t t) time(&t); struct tm tm_r; tm *tm = localtime_r(&t, &tm_r); - snprintf(buffer, sizeof(buffer), "%s %2d.%02d %02d:%02d", *WeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min); + snprintf(buffer, sizeof(buffer), "%s %02d.%02d %02d:%02d", *WeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min); return buffer; } @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.1 1.20 2006/01/08 11:51:36 kls Exp $ +.\" $Id: vdr.1 1.22 2006/01/14 11:09:08 kls Exp $ .\" .TH vdr 1 "08 Jan 2006" "1.3.38" "Video Disk Recorder" .SH NAME @@ -132,8 +132,8 @@ Set the controlling terminal. Run as user \fIuser\fR in case vdr was started as user 'root'. Starting vdr as 'root' is necessary if the system time shall be set from the transponder data, but for security reasons -during normal operation vdr switches to a lesser privileged -user id. By default the user 'vdr' is used. +vdr can switch to a lesser privileged user id during normal +operation. .TP .BI \-v\ dir ,\ \-\-video= dir Use \fIdir\fR as video directory. @@ -161,9 +161,6 @@ An non-recoverable error has been detected, \fBvdr\fR has given up. .I channels.conf Channel configuration. .TP -.I ca.conf -Conditional access configuration. -.TP .I timers.conf Timer configuration. .TP @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 1.45 2006/01/08 11:52:03 kls Exp $ +.\" $Id: vdr.5 1.47 2006/01/14 10:57:37 kls Exp $ .\" .TH vdr 5 "08 Jan 2006" "1.3.38" "Video Disk Recorder Files" .SH NAME @@ -407,16 +407,15 @@ whenever the given key is pressed. The format is \fBmacrokey [@plugin] key1 key2 key3...\fR where \fBmacrokey\fR is the key that shall initiate execution of this macro -and can be one of \fIRed\fR, \fIGreen\fR, \fIYellow\fR, \fIBlue\fR or -\fIUser1\fR...\fIUser9\fR. The rest of the line consists of a set of +and can be one of \fIUp\fR, \fIDown\fR, \fIOk\fR, \fIBack\fR, \fILeft\fR, +\fIRight\fR, \fIRed\fR, \fIGreen\fR, \fIYellow\fR, \fIBlue\fR, \fI0\fR...\fI9\fR +or \fIUser1\fR...\fIUser9\fR. The rest of the line consists of a set of keys, which will be executed just as if they had been pressed in the given sequence. The optional \fB@plugin\fR can be used to automatically select -the given plugin from the main menu (provided that plugin has a main menu -entry). \fBplugin\fR is the name of the plugin, exactly as given in the \-P -option when starting VDR. There can be only one \fB@plugin\fR per key macro, -and it implicitly adds an \fIOk\fR key to the macro definition (in order to -actually select the plugins main menu entry), which counts against the total -number of keys in the macro. For instance +the given plugin. +\fBplugin\fR is the name of the plugin, exactly as given in the \-P +option when starting VDR. There can be only one \fB@plugin\fR per key macro. +For instance \fBUser1 @abc Down Down Ok\fR @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/vdr * - * $Id: vdr.c 1.233 2006/01/08 11:49:03 kls Exp $ + * $Id: vdr.c 1.238 2006/01/15 13:31:57 kls Exp $ */ #include <getopt.h> @@ -157,14 +157,13 @@ int main(int argc, char *argv[]) // Command line options: -#define DEFAULTVDRUSER "vdr" #define DEFAULTSVDRPPORT 2001 #define DEFAULTWATCHDOG 0 // seconds #define DEFAULTPLUGINDIR PLUGINDIR #define DEFAULTEPGDATAFILENAME "epg.data" bool StartedAsRoot = false; - const char *VdrUser = DEFAULTVDRUSER; + const char *VdrUser = NULL; int SVDRPport = DEFAULTSVDRPPORT; const char *AudioCommand = NULL; const char *ConfigDirectory = NULL; @@ -192,6 +191,9 @@ int main(int argc, char *argv[]) #if defined(VFAT) VfatFileSystem = true; #endif +#if defined(VDR_USER) + VdrUser = VDR_USER; +#endif cPluginManager PluginManager(DEFAULTPLUGINDIR); int ExitCode = 0; @@ -337,16 +339,18 @@ int main(int argc, char *argv[]) // Set user id in case we were started as root: - if (getuid() == 0) { + if (VdrUser && getuid() == 0) { StartedAsRoot = true; - if (!SetKeepCaps(true)) - return 2; - if (!SetUser(VdrUser)) - return 2; - if (!SetKeepCaps(false)) - return 2; - if (!SetCapSysTime()) - return 2; + if (strcmp(VdrUser, "root")) { + if (!SetKeepCaps(true)) + return 2; + if (!SetUser(VdrUser)) + return 2; + if (!SetKeepCaps(false)) + return 2; + if (!SetCapSysTime()) + return 2; + } } // Help and version info: @@ -392,8 +396,8 @@ int main(int argc, char *argv[]) " -r CMD, --record=CMD call CMD before and after a recording\n" " -s CMD, --shutdown=CMD call CMD to shutdown the computer\n" " -t TTY, --terminal=TTY controlling tty\n" - " -u USER, --user=USER run as user USER (default: %s); only applicable\n" - " if started as root\n" + " -u USER, --user=USER run as user USER; only applicable if started as\n" + " root\n" " -v DIR, --video=DIR use DIR as video directory (default: %s)\n" " -V, --version print version information and exit\n" " --vfat encode special characters in recording names to\n" @@ -406,7 +410,6 @@ int main(int argc, char *argv[]) LIRC_DEVICE, DEFAULTSVDRPPORT, RCU_DEVICE, - DEFAULTVDRUSER, VideoDirectory, DEFAULTWATCHDOG ); @@ -471,7 +474,7 @@ int main(int argc, char *argv[]) } isyslog("VDR version %s started", VDRVERSION); - if (StartedAsRoot) + if (StartedAsRoot && VdrUser) isyslog("switched to user '%s'", VdrUser); if (DaemonMode) dsyslog("running as daemon (tid=%d)", cThread::ThreadId()); @@ -687,9 +690,10 @@ int main(int argc, char *argv[]) if (!Channels.BeingEdited() && !Timers.BeingEdited()) { int modified = Channels.Modified(); static time_t ChannelSaveTimeout = 0; + static int TimerState = 0; // Channels and timers need to be stored in a consistent manner, // therefore if one of them is changed, we save both. - if (modified == CHANNELSMOD_USER || Timers.Modified()) + if (modified == CHANNELSMOD_USER || Timers.Modified(TimerState)) ChannelSaveTimeout = 1; // triggers an immediate save else if (modified && !ChannelSaveTimeout) ChannelSaveTimeout = time(NULL) + CHANNELSAVEDELTA; @@ -785,14 +789,17 @@ int main(int argc, char *argv[]) // Keys that must work independent of any interactive mode: switch (key) { // Menu control: - case kMenu: + case kMenu: { key = kNone; // nobody else needs to see this key + bool WasOpen = Interact != NULL; + bool WasMenu = Interact && Interact->IsMenu(); if (Menu) DELETE_MENU; else if (cControl::Control() && cOsd::IsOpen()) cControl::Control()->Hide(); - else + if (!WasOpen || !WasMenu && !Setup.MenuButtonCloses) Menu = new cMenuMain; + } break; // Info: case kInfo: { @@ -978,6 +985,10 @@ int main(int argc, char *argv[]) } else { // Key functions in "normal" viewing mode: + if (KeyMacros.Get(key)) { + cRemote::PutMacro(key); + key = kNone; + } switch (key) { // Toggle channels: case k0: { @@ -1013,11 +1024,6 @@ int main(int argc, char *argv[]) cControl::Launch(new cReplayControl); } break; - // Key macros: - case kRed: - case kGreen: - case kYellow: - case kBlue: cRemote::PutMacro(key); break; default: break; } } |