diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2007-02-25 18:00:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2007-02-25 18:00:00 +0100 |
commit | 9f42c33ef6793482a5c2515f9a87c13c0d189c60 (patch) | |
tree | 45025e95c0774761760c9bc6a44f4e69a1baf43b | |
parent | 66ab78a40f5b57e20142a33484e32c785a0c4017 (diff) | |
download | vdr-patch-lnbsharing-9f42c33ef6793482a5c2515f9a87c13c0d189c60.tar.gz vdr-patch-lnbsharing-9f42c33ef6793482a5c2515f9a87c13c0d189c60.tar.bz2 |
Version 1.5.1vdr-1.5.1
- Added cDevice::HasCi() so that devices with Common Interface can be avoided
when tuning to an FTA channel, thus preserving the CAM resources even on budget
DVB cards (suggested by Petri Helin).
- Fixed i18n characters for the Hungarian texts (thanks to Thomas Günther).
- Now using cPipe instead of popen() in cCommand::Execute() to avoid problems
with open file handles when starting background commands (thanks to Reinhard
Nissl).
- Removed 'assert(0)' from cDvbSpuDecoder::setTime() (thanks to Marco Schlüßler).
- Fixed a possible crash when loading an invalid XPM file (thanks to Martin Wache).
- Updated satellite names in 'sources.conf' (thanks to Thilo Wunderlich).
- Adapted 'libsi' to DVB-S2 (thanks to Marco Schlüßler).
- Fixed handling error status in cDvbTuner::GetFrontendStatus() (thanks to
Reinhard Nissl).
- Shutdown handling has been rewritten (thanks to Udo Richter).
- Plugins can now implement the new function WakeupTime() to request VDR to wake
up at a particular time (thanks to Udo Richter).
- The HUP signal now forces a restart of VDR (thanks to Udo Richter).
- cThread::EmergencyExit() has been replaced by ShutdownHandler.RequestEmergencyExit().
- Several references to "button" in a remote control context have been changed
to "key" (based on a report from Marko Mäkelä regarding the "Menu button closes"
text). The "MenuButtonCloses" parameter in 'setup.conf' has therefore been
renamed to "MenuKeyCloses", accordingly. This will result in an "unknown config
parameter: MenuButtonCloses" error message in the log file, so you may want to
remove that entry from your 'setup.conf' file.
- Simplified the error handling in cDvbTuner::GetFrontendStatus() (based on a
discussion with Reinhard Nissl).
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
- Increased the maximum number of DVB devices to 8 (thanks to Rolf Ahrenberg).
- The new Setup parameter "Channel entry timeout" can be used to customize the time
since the last keypress until a numerically entered channel number is considered
complete, and the channel is switched (suggested by Helmut Auer). Setting this
parameter to 0 turns off the automatic channel switching, and the user will
have to confirm the entry by pressing the "Ok" key.
-rw-r--r-- | CONTRIBUTORS | 21 | ||||
-rw-r--r-- | HISTORY | 53 | ||||
-rw-r--r-- | INSTALL | 51 | ||||
-rw-r--r-- | MANUAL | 87 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | PLUGINS.html | 49 | ||||
-rw-r--r-- | config.c | 20 | ||||
-rw-r--r-- | config.h | 14 | ||||
-rw-r--r-- | device.c | 8 | ||||
-rw-r--r-- | device.h | 4 | ||||
-rw-r--r-- | dvbdevice.c | 20 | ||||
-rw-r--r-- | dvbdevice.h | 9 | ||||
-rw-r--r-- | dvbspu.c | 7 | ||||
-rw-r--r-- | i18n.c | 240 | ||||
-rw-r--r-- | keys.h | 3 | ||||
-rw-r--r-- | libsi/descriptor.c | 61 | ||||
-rw-r--r-- | libsi/descriptor.h | 33 | ||||
-rw-r--r-- | libsi/headers.h | 209 | ||||
-rw-r--r-- | libsi/si.c | 21 | ||||
-rw-r--r-- | libsi/si.h | 17 | ||||
-rw-r--r-- | menu.c | 18 | ||||
-rwxr-xr-x | newplugin | 9 | ||||
-rw-r--r-- | osd.c | 22 | ||||
-rw-r--r-- | plugin.c | 27 | ||||
-rw-r--r-- | plugin.h | 4 | ||||
-rw-r--r-- | recorder.c | 5 | ||||
-rw-r--r-- | remote.c | 4 | ||||
-rw-r--r-- | remote.h | 5 | ||||
-rw-r--r-- | remux.c | 8 | ||||
-rw-r--r-- | shutdown.c | 250 | ||||
-rw-r--r-- | shutdown.h | 112 | ||||
-rw-r--r-- | sources.conf | 26 | ||||
-rw-r--r-- | thread.c | 27 | ||||
-rw-r--r-- | thread.h | 8 | ||||
-rw-r--r-- | vdr.1 | 10 | ||||
-rw-r--r-- | vdr.c | 223 |
36 files changed, 1348 insertions, 341 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 79c6e18..d1c492f 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -360,6 +360,7 @@ Norbert Schmidt <nschmidt-nrw@t-online.de> Thilo Wunderlich <wunderlich@speedway.org> for his help in keeping 'channels.conf' up to date for reporting a problem with accessing the epg.data file before it is fully written + for updating satellite names in 'sources.conf' Stephan Schreiber <stephan@sschreiber.de> for his support in keeping the Premiere World channels up to date in 'channels.conf.cable' @@ -583,6 +584,7 @@ Helmut Auer <vdr@helmutauer.de> for suggesting to reduce the logging for the SVDRP GRAB command for reporting that the shutdown script is given a reboot time in the past if there is a recording going on or about to start, and the user insists in shutting down now + for suggesting to make the channel entry timeout configurable Jeremy Hall <jhall@UU.NET> for fixing an incomplete initialization of the filter parameters in eit.c @@ -1008,13 +1010,14 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi> cPluginManager::Active() in menu.c to "restart anyway?" for adding --remove-destination to the 'cp' command for binaries in the Makefiles of the plugins + for increasing the maximum number of DVB devices to 8 Ralf Klueber <ralf.klueber@vodafone.com> for reporting a bug in cutting a recording if there is only a single editing mark for reporting a bug in handling a channels.conf that contains a ":@nnn" line as its last entry -Hermann Gausterer <mrq1@gmx.net> +Hermann Gausterer <vdr@mrq1.org> for suggesting to switch to the recording channel in case the current channel becomes unavailable @@ -1114,6 +1117,9 @@ Reinhard Nissl <rnissl@gmx.de> for changing the behaviour when hitting the end of a recording in fast forward mode for suggesting to give the cRemote::CallPlugin() function a boolean return value for fixing a possible crash in remux.c on 64-bit machines + for making cCommand::Execute() use cPipe instead of popen() to avoid problems + with open file handles when starting background commands + for fixing handling error status in cDvbTuner::GetFrontendStatus() Richard Robson <richard_robson@beeb.net> for reporting freezing replay if a timer starts while in Transfer Mode from the @@ -1387,6 +1393,8 @@ Marco Schlüßler <marco@lordzodiac.de> replay has been stopped for reporting a problem with displaying the replay mode symbol in case of "Multi speed mode" + for removing 'assert(0)' from cDvbSpuDecoder::setTime() + for adapting 'libsi' to DVB-S2 Jürgen Schmitz <j.schmitz@web.de> for reporting a bug in displaying the current channel when switching via the SVDRP @@ -1479,6 +1487,10 @@ Udo Richter <udo_richter@gmx.de> for some hints on how to improve handling cPluginManager::Active() for fixing a possible segfault if VDR gets terminated while a message is displayed for reporting an error in the INSTALL section on retrying shutdown later + for rewriting shutdown handling + for implementing cPlugin::WakeupTime() to allow plugins to request VDR to wake + up at a particular time + for making the HUP signal force a restart of VDR Sven Kreiensen <svenk@kammer.uni-hannover.de> for his help in keeping 'channels.conf.terr' up to date @@ -1692,6 +1704,7 @@ Henrik Niehaus <henrik.niehaus@gmx.de> Martin Wache <M.Wache@gmx.net> for adding a sleep in cDvbPlayer::Action() in case there is no data to send to the device, which avoids a busy loop on very fast machines + for fixing a possible crash when loading an invalid XPM file Matthias Lenk <matthias.lenk@amd.com> for reporting an out-of-bounds memory access with audio language ids @@ -1720,6 +1733,7 @@ Thomas Günther <tom1@toms-cafe.de> for reporting a bug in the initial setting of the time transponder setup parameter for suggesting to extend the version number reported with the '-V' option to also show the current APIVERSION + for fixing i18n characters for the Hungarian texts David Woodhouse <dwmw2@infradead.org> for his help in replacing the get/put_unaligned() macros from asm/unaligned.h with @@ -1744,6 +1758,7 @@ Marko Mäkelä <marko.makela@hut.fi> for suggesting to ignore k_Repeat when deciding whether the same key has been pressed in string input fields for fixing missing ',' in the Italian and Polish OSD texts + for pointing out that "Menu button closes" should actually be "Menu key closes" Patrick Rother <krd-vdr@gulu.net> for reporting a bug in defining timers that only differ in the day of week @@ -2050,3 +2065,7 @@ Jörg Wendel <vdr-ml@jwendel.de> Peter Pinnau <vdr@unterbrecher.de> for reporting that 'uint32_t' requires uncluding stdint.h in font.h on some systems + +Petri Helin <phelin@googlemail.com> + for suggesting to avoid budget DVB cards with Common Interface when tuning to an + FTA channel @@ -5081,3 +5081,56 @@ Video Disk Recorder Revision History without valid CA ids VDR can't decide which CAM slot to use. However, since VDR now automatically determines which CAM can decrypt which channel, setting fixed channel/device relations should no longer be necessary. + IF AN ENCRYPTED CHANNEL CAN'T BE DECRYPTED AND YOU HAVE A CA VALUE IN THE RANGE + 0...F FOR THAT CHANNEL, SET IT TO 0 (FTA) AND TUNE TO THE CHANNEL AGAIN. + +2007-01-28: Version 1.4.5-1 + +- Fixed i18n characters for the Hungarian texts (thanks to Thomas Günther). +- Now using cPipe instead of popen() in cCommand::Execute() to avoid problems + with open file handles when starting background commands (thanks to Reinhard + Nissl). + +2007-02-24: Version 1.4.5-2 + +- Removed 'assert(0)' from cDvbSpuDecoder::setTime() (thanks to Marco Schlüßler). +- Fixed a possible crash when loading an invalid XPM file (thanks to Martin Wache). +- Updated satellite names in 'sources.conf' (thanks to Thilo Wunderlich). +- Fixed handling error status in cDvbTuner::GetFrontendStatus() (thanks to + Reinhard Nissl). + +2007-02-25: Version 1.5.1 + +- Added cDevice::HasCi() so that devices with Common Interface can be avoided + when tuning to an FTA channel, thus preserving the CAM resources even on budget + DVB cards (suggested by Petri Helin). +- Fixed i18n characters for the Hungarian texts (thanks to Thomas Günther). +- Now using cPipe instead of popen() in cCommand::Execute() to avoid problems + with open file handles when starting background commands (thanks to Reinhard + Nissl). +- Removed 'assert(0)' from cDvbSpuDecoder::setTime() (thanks to Marco Schlüßler). +- Fixed a possible crash when loading an invalid XPM file (thanks to Martin Wache). +- Updated satellite names in 'sources.conf' (thanks to Thilo Wunderlich). +- Adapted 'libsi' to DVB-S2 (thanks to Marco Schlüßler). +- Fixed handling error status in cDvbTuner::GetFrontendStatus() (thanks to + Reinhard Nissl). +- Shutdown handling has been rewritten (thanks to Udo Richter). +- Plugins can now implement the new function WakeupTime() to request VDR to wake + up at a particular time (thanks to Udo Richter). +- The HUP signal now forces a restart of VDR (thanks to Udo Richter). +- cThread::EmergencyExit() has been replaced by ShutdownHandler.RequestEmergencyExit(). +- Several references to "button" in a remote control context have been changed + to "key" (based on a report from Marko Mäkelä regarding the "Menu button closes" + text). The "MenuButtonCloses" parameter in 'setup.conf' has therefore been + renamed to "MenuKeyCloses", accordingly. This will result in an "unknown config + parameter: MenuButtonCloses" error message in the log file, so you may want to + remove that entry from your 'setup.conf' file. +- Simplified the error handling in cDvbTuner::GetFrontendStatus() (based on a + discussion with Reinhard Nissl). +- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg). +- Increased the maximum number of DVB devices to 8 (thanks to Rolf Ahrenberg). +- The new Setup parameter "Channel entry timeout" can be used to customize the time + since the last keypress until a numerically entered channel number is considered + complete, and the channel is switched (suggested by Helmut Auer). Setting this + parameter to 0 turns off the automatic channel switching, and the user will + have to confirm the entry by pressing the "Ok" key. @@ -160,30 +160,33 @@ and the next timer event is at least MinEventTimeout minutes in the future (see the Setup parameters in MANUAL). The command given in the '-s' option will be called with five parameters. -The first one is the time (in UTC) of the next timer event (as a time_t -type number), and the second one is the number of seconds from the current -time until the next timer event. Your program can choose which one to use -for programming some sort of hardware device that makes sure the computer -will be restarted in time before the next timer event. Your program must -also initiate the actual shutdown procedure of the computer. After this -your program should return to VDR. VDR will not automatically exit after -calling the shutdown program, but will rather continue normally until it -receives a SIGTERM when the computer is actually shut down. So in case -the shutdown fails, or the shutdown program for some reason decides not to -perform a shutdown, VDR will stay up and running and will call the shutdown -program again after another five minutes. - -If there are currently no timers active, both parameters will be '0'. -In that case the program shall not set the hardware for automatic restart -and only perform the system shutdown. A program that uses the second parameter -to set the hardware for restart must therefore also check whether the first -parameter is '0'. - -The third parameter contains the number of the channel that will be recorded -by the next timer (or 0 if no timer is present), and the fourth parameter -contains the file name of the recording as defined in the timer (or an empty -string if no timer is present). These can be used by the shutdown program to -show that information on some display interface etc. + +The first one is the time (in UTC) of the next timer event or plugin wakeup +time (as a time_t type number), and the second one is the number of +seconds from the current time until the next timer event. Your program can +choose which one to use for programming some sort of hardware device that +makes sure the computer will be restarted in time before the next timer +event. Your program must also initiate the actual shutdown procedure of the +computer. VDR will not automatically exit after calling the shutdown +program, but will rather continue normally until it receives a SIGTERM when +the computer is actually shut down. So in case the shutdown fails, or the +shutdown program for some reason decides not to perform a shutdown, VDR +will stay up and running and will call the shutdown program again after a +while. The command will be started in a separate background session, so it +can continue to run even after VDR has terminated. + +If there are currently no timers active and there is no plugin wakeup +time, both parameters will be '0'. In that case the program shall not set +the hardware for automatic restart and only perform the system shutdown. +A program that uses the second parameter to set the hardware for restart +must therefore also check whether the first parameter is '0'. + +If the wakeup time is given by a timer, the third parameter will be the +number of the channel that will be recorded, otherwise it will be 0. The +fourth parameter contains the file name of the recording as defined in the +timer, the name of the plugin that requested the wakeup time, or an empty +string if no wakeup time is present. These can be used by the shutdown +program to show that information on some display interface etc. The fifth parameter indicates the reason why the shutdown was requested. '0' means this is an automatic shutdown due to some timeout, while '1' means @@ -112,7 +112,7 @@ Version 1.4 "Ok" here opens the "Edit timer" menu. Textual options, like channel names or recording file names, can be edited - by pressing the "Right" button (which puts brackets around the current + by pressing the "Right" key (which puts brackets around the current character as in "[R]TL"), selecting the desired character position with "Left" and "Right", and changing the character with the "Up" and "Down" keys. "Ok" then confirms the changes. The "Red" key toggles between @@ -120,7 +120,7 @@ Version 1.4 insert and overwrite mode. The "Yellow" key deletes the current character (or the one to the right of the cursor in insert mode). - The "Red", "Green", "Yellow" and "Blue" buttons have special meanings + The "Red", "Green", "Yellow" and "Blue" keys have special meanings in various menus and are listed at the bottom of the on-screen-display. At any point in the menu system, pressing the "Menu" key again will @@ -137,22 +137,22 @@ Version 1.4 displays detailed information about the selected programme. Pressing "Ok" again (or pressing "Back") gets you back into the "Schedule" menu. - From the "Schedule" menu, the "Green" button opens the "What's on now?" + From the "Schedule" menu, the "Green" key opens the "What's on now?" menu, which displays all programmes that are currently running on all channels that broadcast their programme information on the current transponder, or from channels that have been current lately (VDR stores all information it gathers in an internal list). The more channels you have been switching through lately, the longer this list will be. - The "Yellow" button opens the "What's on next?" menu, which lists all + The "Yellow" key opens the "What's on next?" menu, which lists all programmes that will start next on all channels. - Inside the "What's on now/next?" menus the "Green" button toggles between - the "Now" and "Next" display, and the "Yellow" button takes you to the + Inside the "What's on now/next?" menus the "Green" key toggles between + the "Now" and "Next" display, and the "Yellow" key takes you to the "Schedule" menu of the current channel in the list. - The "Red" button allows you to instantly program a timer to record the - selected programme. After pressing this button, the current event will - be marked with 'T', and the function of the "Red" button will change from + The "Red" key allows you to instantly program a timer to record the + selected programme. After pressing this key, the current event will + be marked with 'T', and the function of the "Red" key will change from "Record" to "Timer". Pressing "Red" on an event marked with 'T' will open the "Edit timer" menu for this timer, where you can make any modifications you may want to apply. Note that the Start and Stop time are offset by the @@ -167,7 +167,7 @@ Version 1.4 directly into the "Edit timer" menu in order to allow the user to make further changes to timer parameters before the actual recording starts. - The "Blue" button can be pressed to switch to the channel with the selected + The "Blue" key can be pressed to switch to the channel with the selected programme. The following markers in these menus give additional information about the @@ -192,14 +192,14 @@ Version 1.4 1. With no On Screen Menu displayed press the "Up" or "Down" key to switch to the next higher or lower channel. - 2. Press the "Menu" button to bring up the On Screen Menu, select "Channels" + 2. Press the "Menu" key to bring up the On Screen Menu, select "Channels" and browse through the list with the "Up" and "Down" key; to switch to the selected channel press "Ok". 3. Directly type in the channel number with the numeric keys ('0'..'9'); if no key is pressed for about one second, the digits collected so far will define the channel number. 4. From the "Now", "Next" and "Event" menus (accessible through the "Schedule" - menu) by pressing the "Blue" button. + menu) by pressing the "Blue" key. Pressing the '0' key in normal viewing mode toggles between the current and the previous channel. A channel is considered "previous" if it has been @@ -210,15 +210,15 @@ Version 1.4 'current/next' information will be displayed below this line. This display automatically goes away after about five seconds, or if any key is pressed. To bring up the channel display without switching channels you can press - the "Ok" button. + the "Ok" key. * Selecting audio tracks If the current channel or recording provides different audio tracks (for - different languages or Dolby Digital), the "Green" button in the "VDR" menu can + different languages or Dolby Digital), the "Green" key in the "VDR" menu can be pressed to bring up the "Audio" menu. Within this menu, the "Up" and "Down" keys can be used to switch between the audio tracks. If your remote control has - a dedicated "Audio" button, the first press of that button brings up the "Audio" + a dedicated "Audio" key, the first press of that key brings up the "Audio" menu, and every further press switches to the next available audio track. The "Left" and "Right" keys can be used to switch between "mono left", "stereo" @@ -242,7 +242,7 @@ Version 1.4 If the 'channels.conf' file contains "group separators" you can switch through these groups by pressing the "Left" and "Right" key while no menu is being displayed. The channel display will show the name of the - group, and if you press the "Ok" button while the group name is being + group, and if you press the "Ok" key while the group name is being displayed, you will switch to the first channel of that group. Channel groups can be whatever you decide them to be. You can either @@ -251,11 +251,11 @@ Version 1.4 * Instant Recording - You can start recording the current channel by pressing the "Red" button + You can start recording the current channel by pressing the "Red" key in the "VDR" menu. This will create a timer event named "@channelname" that starts at the current time and by default records for 3 hours. If you want to modify the recording time you need to edit the timer. - Stop instant recording by pressing the "Menu" button and selecting + Stop instant recording by pressing the "Menu" key and selecting "Stop Recording", or by disabling the timer. The default priority, lifetime and recording time can be defined in the "Setup/Recording" menu. @@ -267,7 +267,7 @@ Version 1.4 "Record") and immediately begin replaying that recording. Replay will be put into "pause" mode, so you can attend to whatever it was that disturbed your live viewing session. Once you're back, simply press the "Up" or "Play" - button and you'll be watching the current channel in time shift mode, right + key and you'll be watching the current channel in time shift mode, right from the point where you left off. The instant recording VDR has started will use the parameters for "Pause priority" and "Pause lifetime" as defined in the "Setup/Recording" menu. Recording time will be the same as for @@ -277,12 +277,12 @@ Version 1.4 * Replaying a Recording All recordings are listed in the "Recordings" menu. Browse through the - list with the "Up" and "Down" button and press "Ok" (or the "Red" button) + list with the "Up" and "Down" key and press "Ok" (or the "Red" key) to start playback. New recordings are marked with an '*'. If the Setup parameter RecordingDirs has been set and there are recordings from repeating timers organized in a subdirectory structure, only the directory is displayed and it can be opened by pressing "Ok" (or the "Red" - button). A directory entry displays the total number of recordings within + key). A directory entry displays the total number of recordings within that directory (and any possible subdirectory thereof) as well as the total number of new recordings (as opposed to a recording's entry, which displays the date and time of the recording). @@ -295,15 +295,15 @@ Version 1.4 the order in which they were broadcast. Playback can be stopped via the "VDR" menu by selecting "Stop replaying", - or by pressing the "Blue" button outside the menu. + or by pressing the "Blue" key outside the menu. A previously stopped playback session can be resumed by pressing the "Blue" - button in the "VDR" menu. + key in the "VDR" menu. * Processing Recordings The configuration file 'reccmds.conf' can be used to define system commands that can be applied to the recording that is currently highlighted in the - "Recordings" menu. The "Red" button in the "Recordings" menu opens the "Recording + "Recordings" menu. The "Red" key in the "Recordings" menu opens the "Recording commands" menu if there are commands defined in the file 'reccmds.conf'. Pressing one of the keys '1'..'9' in the "Recordings" menu executes the corresponding command from 'reccmds.conf' (see also "Executing system commands" below). @@ -322,20 +322,20 @@ Version 1.4 Right Runs playback forward or backward at a higher speed; press again to resume normal speed. If in Pause mode, runs forward or backward at a slower speed; press again to return to pause mode. - Pressing and holding down the button performs the function until - the button is released again. + Pressing and holding down the key performs the function until + the key is released again. If "Multi Speed Mode" has been enabled in the "Setup" menu, the - function of these buttons changes in a way that gives you three + function of these keys changes in a way that gives you three fast and slow speeds, through which you can switch by pressing - the respective button several times. + the respective key several times. - Red Jump to a specific location. Enter the time you want to jump to and then press "Left" or "Right" to jump relative to the current position, "Up" to jump to an absolute position, and "Down" to jump and pause at an absolute position. - Green Yellow Skips about 60 seconds back or forward. - Pressing and holding down the button performs the function until - the button is released again. + Pressing and holding down the key performs the function until + the key is released again. - Ok Brings up the replay progress display, which shows the date, time and title of the recording, a progress bar and the current and total time of the recording. @@ -469,7 +469,7 @@ Version 1.4 First day: The date of the first day when this timer shall start recording (only available for repeating timers). - A timer can also be programmed by pressing the "Red" button on the "Schedule", + A timer can also be programmed by pressing the "Red" key on the "Schedule", "Now", "Next" or "Event" menus. * Parameters in the "Setup" menu @@ -513,7 +513,7 @@ Version 1.4 Info on channel switch = yes Turns the display of the current/next information on or off when switching the channel. The information is - always displayed when pressing the "Ok" button in + always displayed when pressing the "Ok" key in normal viewing mode. Timeout requested channel info = yes @@ -535,10 +535,10 @@ Version 1.4 (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 + Menu key closes = no + If set to "yes", pressing the "Menu" key 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 + to "no", the "Menu" key will open the main menu after closing a temporary display, like, for instance, the channel display. @@ -607,7 +607,7 @@ Version 1.4 different languages, the preferred languages are checked in the given order to decide which one to take. - Scan The "Red" button in the "Setup/EPG" menu can be used to + Scan The "Red" key in the "Setup/EPG" menu can be used to force an EPG scan on a single DVB card system. If pressed, and the primary DVB device is currently not recording or replaying, it will loop through the transponders once and @@ -711,7 +711,7 @@ Version 1.4 yes = use it (and create subdirectories) Use VPS = 0 Defines whether a timer that is created from an EPG entry - (by pressing the "Record" (red) button in the "Schedules" + (by pressing the "Record" (red) key in the "Schedules" or "What's on now/next?" menu) will automatically use VPS if the event it is created for has a VPS time. @@ -723,7 +723,7 @@ Version 1.4 Mark instant recording = yes Defines whether an "instant recording" (started by - pressing the "Red" button in the "VDR" menu) will be + pressing the "Red" key in the "VDR" menu) will be marked with a '@' character to make it distinguishable from timer recordings in the "Recordings" menu. @@ -786,9 +786,18 @@ Version 1.4 connection after which the connection is automatically closed. Default is 300, a value of 0 means no timeout. - Zap Timeout = 3 The time (in seconds) until a channel counts as "previous" + Zap timeout = 3 The time (in seconds) until a channel counts as "previous" for switching with '0' + Channel entry timeout = 1000 + The time (in milliseconds) after the last keypress until + a numerically entered channel number is considered + complete, and the channel is switched. Default is 1000, + a value of 0 turns this off, so a numerically entered + channel number then needs to be confirmed with the "Ok" + key. Note that the total maximum is also limited by + the "OSD/Channel info time" parameter. + Initial channel = 0 The number of the channel that shall be tuned to when VDR starts. Default is 0, which means that it will tune to the channel that was on before VDR was stopped. @@ -4,7 +4,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 1.96 2006/11/11 13:55:32 kls Exp $ +# $Id: Makefile 1.97 2007/02/24 13:23:12 kls Exp $ .DELETE_ON_ERROR: @@ -35,7 +35,7 @@ SILIB = $(LSIDIR)/libsi.a OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o dvbosd.o\ dvbplayer.o dvbspu.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\ lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o rcu.o\ - receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o\ + receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\ skinclassic.o skins.o skinsttng.o sources.o spu.o status.o svdrp.o themes.o thread.o\ timers.o tools.o transfer.o vdr.o videodir.o diff --git a/PLUGINS.html b/PLUGINS.html index 71c1b77..6403453 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -6,7 +6,7 @@ <center><h1>The VDR Plugin System</h1></center> -<center><b>Version 1.5.0</b></center> +<center><b>Version 1.5.1</b></center> <p> <center> Copyright © 2006 Klaus Schmidinger<br> @@ -14,9 +14,12 @@ Copyright © 2006 Klaus Schmidinger<br> <a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a> </center> <p> -<!--X1.5.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<!--X1.5.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> Important modifications introduced in version 1.5.0 are marked like this. <!--X1.5.0--></td></tr></table> +<!--X1.5.1--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +Important modifications introduced in version 1.5.1 are marked like this. +<!--X1.5.1--></td></tr></table> <p> VDR provides an easy to use plugin interface that allows additional functionality to be added to the program by implementing a dynamically loadable library file. @@ -55,6 +58,9 @@ structures and allows it to hook itself into specific areas to perform special a <li><a href="#Housekeeping">Housekeeping</a> <li><a href="#Main thread hook">Main thread hook</a> <li><a href="#Activity">Activity</a> +<!--X1.5.1--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<li><a href="#Wakeup">Wakeup</a> +<!--X1.5.1--></td></tr></table> <li><a href="#Setup parameters">Setup parameters</a> <li><a href="#The Setup menu">The Setup menu</a> <li><a href="#Configuration files">Configuration files</a> @@ -76,7 +82,7 @@ structures and allows it to hook itself into specific areas to perform special a <li><a href="#Devices">Devices</a> <li><a href="#Audio">Audio</a> <li><a href="#Remote Control">Remote Control</a> -<!--X1.5.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<!--X1.5.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> <li><a href="#Conditional Access">Conditional Access</a> <!--X1.5.0--></td></tr></table> </ul> @@ -675,6 +681,41 @@ be queried, and further prompts may show up. If all prompts have been confirmed, the shutdown will take place. As soon as one prompt is not confirmed, no further plugins will be queried and no shutdown will be done. +<!--X1.5.1--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<a name="Wakeup"><hr><h2>Wakeup</h2> + +<center><i><b>Wake me up before you go-go</b></i></center><p> + +If a plugin wants to schedule activity for a later time, or wants to perform +periodic activity at a certain time at night, and if VDR shall wake up from +shutdown at that time, the plugin can implement the function + +<p><table><tr><td bgcolor=#F0F0F0><pre> +virtual time_t WakeupTime(void); +</pre></td></tr></table><p> + +which shall return the time of the next custom wakeup time, or 0 if no wakeup +is planned. VDR will pass the most recent wakeup time of all plugins, or the next +timer time, whichever comes first, to the shutdown script. The following sample +will wake up VDR every night at 1:00: + +<p><table><tr><td bgcolor=#F0F0F0><pre> +time_t MyPlugin::WakeupTime(void) +{ + time_t Now = time(NULL); + time_t Time = cTimer::SetTime(Now, cTimer::TimeToInt(100)); + if (Time <= Now) + Time = cTimer::IncDay(Time, 1); + return Time; +} +</pre></td></tr></table><p> + +After wakeup, the plugin shall continue to return the wakeup time and shall +return a string when <tt>Active()</tt> is called at that time, otherwise VDR may shut down +again instantly. If <tt>WakeupTime()</tt> returns a time that is not in +the future, the time will be ignored. +<!--X1.5.1--></td></tr></table> + <a name="Setup parameters"><hr><h2>Setup parameters</h2> <center><i><b>Remember me...</b></i></center><p> @@ -2046,7 +2087,7 @@ Put(uint64 Code, bool Repeat = false, bool Release = false); The other parameters have the same meaning as in the first version of this function. -<!--X1.5.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<!--X1.5.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> <a name="Conditional Access"><hr><h2>Conditional Access</h2> <center><i><b>Members only!</b></i></center><p> @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.146 2006/07/22 11:57:51 kls Exp $ + * $Id: config.c 1.150 2007/02/25 13:58:45 kls Exp $ */ #include "config.h" @@ -67,8 +67,8 @@ const char *cCommand::Execute(const char *Parameters) asprintf(&cmdbuf, "%s %s", command, Parameters); const char *cmd = cmdbuf ? cmdbuf : command; dsyslog("executing command '%s'", cmd); - FILE *p = popen(cmd, "r"); - if (p) { + cPipe p; + if (p.Open(cmd, "r")) { int l = 0; int c; while ((c = fgetc(p)) != EOF) { @@ -78,7 +78,7 @@ const char *cCommand::Execute(const char *Parameters) } if (result) result[l] = 0; - pclose(p); + p.Close(); } else esyslog("ERROR: can't open pipe for command '%s'", cmd); @@ -222,7 +222,7 @@ cSetup::cSetup(void) TimeoutRequChInfo = 1; MenuScrollPage = 1; MenuScrollWrap = 0; - MenuButtonCloses = 0; + MenuKeyCloses = 0; MarkInstantRecord = 1; strcpy(NameInstantRecord, "TITLE EPISODE"); InstantRecordTime = 180; @@ -242,6 +242,7 @@ cSetup::cSetup(void) EPGLinger = 0; SVDRPTimeout = 300; ZapTimeout = 3; + ChannelEntryTimeout = 1000; PrimaryLimit = 0; DefaultPriority = 50; DefaultLifetime = 99; @@ -267,6 +268,7 @@ cSetup::cSetup(void) SplitEditedFiles = 0; MinEventTimeout = 30; MinUserInactivity = 300; + NextWakeupTime = 0; MultiSpeedMode = 0; ShowReplayMode = 0; ResumeID = 0; @@ -383,7 +385,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, "MenuKeyCloses")) MenuKeyCloses = 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); @@ -403,6 +405,7 @@ bool cSetup::Parse(const char *Name, const char *Value) else if (!strcasecmp(Name, "EPGLinger")) EPGLinger = atoi(Value); else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value); else if (!strcasecmp(Name, "ZapTimeout")) ZapTimeout = atoi(Value); + else if (!strcasecmp(Name, "ChannelEntryTimeout")) ChannelEntryTimeout= atoi(Value); else if (!strcasecmp(Name, "PrimaryLimit")) PrimaryLimit = atoi(Value); else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value); else if (!strcasecmp(Name, "DefaultLifetime")) DefaultLifetime = atoi(Value); @@ -428,6 +431,7 @@ bool cSetup::Parse(const char *Name, const char *Value) else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value); else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value); else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value); + else if (!strcasecmp(Name, "NextWakeupTime")) NextWakeupTime = atoi(Value); else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value); else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value); else if (!strcasecmp(Name, "ResumeID")) ResumeID = atoi(Value); @@ -451,7 +455,7 @@ bool cSetup::Save(void) Store("TimeoutRequChInfo", TimeoutRequChInfo); Store("MenuScrollPage", MenuScrollPage); Store("MenuScrollWrap", MenuScrollWrap); - Store("MenuButtonCloses", MenuButtonCloses); + Store("MenuKeyCloses", MenuKeyCloses); Store("MarkInstantRecord", MarkInstantRecord); Store("NameInstantRecord", NameInstantRecord); Store("InstantRecordTime", InstantRecordTime); @@ -471,6 +475,7 @@ bool cSetup::Save(void) Store("EPGLinger", EPGLinger); Store("SVDRPTimeout", SVDRPTimeout); Store("ZapTimeout", ZapTimeout); + Store("ChannelEntryTimeout",ChannelEntryTimeout); Store("PrimaryLimit", PrimaryLimit); Store("DefaultPriority", DefaultPriority); Store("DefaultLifetime", DefaultLifetime); @@ -496,6 +501,7 @@ bool cSetup::Save(void) Store("SplitEditedFiles", SplitEditedFiles); Store("MinEventTimeout", MinEventTimeout); Store("MinUserInactivity", MinUserInactivity); + Store("NextWakeupTime", NextWakeupTime); Store("MultiSpeedMode", MultiSpeedMode); Store("ShowReplayMode", ShowReplayMode); Store("ResumeID", ResumeID); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.283 2007/01/07 14:09:31 kls Exp $ + * $Id: config.h 1.287 2007/02/25 13:58:59 kls Exp $ */ #ifndef __CONFIG_H @@ -21,13 +21,13 @@ // VDR's own version number: -#define VDRVERSION "1.5.0" -#define VDRVERSNUM 10500 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.5.1" +#define VDRVERSNUM 10501 // Version * 10000 + Major * 100 + Minor // The plugin API's version number: -#define APIVERSION "1.5.0" -#define APIVERSNUM 10500 // Version * 10000 + Major * 100 + Minor +#define APIVERSION "1.5.1" +#define APIVERSNUM 10501 // Version * 10000 + Major * 100 + Minor // When loading plugins, VDR searches them by their APIVERSION, which // may be smaller than VDRVERSION in case there have been no changes to @@ -206,7 +206,7 @@ public: int TimeoutRequChInfo; int MenuScrollPage; int MenuScrollWrap; - int MenuButtonCloses; + int MenuKeyCloses; int MarkInstantRecord; char NameInstantRecord[MaxFileName]; int InstantRecordTime; @@ -225,6 +225,7 @@ public: int EPGLinger; int SVDRPTimeout; int ZapTimeout; + int ChannelEntryTimeout; int PrimaryLimit; int DefaultPriority, DefaultLifetime; int PausePriority, PauseLifetime; @@ -244,6 +245,7 @@ public: int MaxVideoFileSize; int SplitEditedFiles; int MinEventTimeout, MinUserInactivity; + time_t NextWakeupTime; int MultiSpeedMode; int ShowReplayMode; int ResumeID; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 1.138 2007/01/07 13:41:07 kls Exp $ + * $Id: device.c 1.139 2007/01/13 12:05:00 kls Exp $ */ #include "device.h" @@ -334,6 +334,7 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView imp <<= 8; imp |= min(max((NumUsableSlots ? SlotPriority[j] : 0) + MAXPRIORITY, 0), 0xFF); // use the CAM slot with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) imp <<= 1; imp |= ndr; // avoid devices if we need to detach existing receivers imp <<= 1; imp |= device[i]->IsPrimaryDevice(); // avoid the primary device + imp <<= 1; imp |= NumUsableSlots ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards imp <<= 1; imp |= NumUsableSlots ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel if (imp < Impact) { @@ -367,6 +368,11 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView return d; } +bool cDevice::HasCi(void) +{ + return false; +} + void cDevice::SetCamSlot(cCamSlot *CamSlot) { camSlot = CamSlot; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 1.80 2007/01/03 14:14:29 kls Exp $ + * $Id: device.h 1.81 2007/01/13 11:33:57 kls Exp $ */ #ifndef __DEVICE_H @@ -314,6 +314,8 @@ private: time_t startScrambleDetection; cCamSlot *camSlot; public: + virtual bool HasCi(void); + ///< Returns true if this device has a Common Interface. void SetCamSlot(cCamSlot *CamSlot); ///< Sets the given CamSlot to be used with this device. cCamSlot *CamSlot(void) const { return camSlot; } diff --git a/dvbdevice.c b/dvbdevice.c index 487aec5..8757710 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.161 2007/01/05 11:09:51 kls Exp $ + * $Id: dvbdevice.c 1.164 2007/02/25 11:46:52 kls Exp $ */ #include "dvbdevice.h" @@ -155,15 +155,12 @@ bool cDvbTuner::GetFrontendStatus(fe_status_t &Status, int TimeoutMs) ; // just to clear the event queue - we'll read the actual status below } } - do { - int stat = ioctl(fd_frontend, FE_READ_STATUS, &Status); - if (stat == 0) - return true; - if (stat < 0) { - if (errno == EINTR) - continue; + while (1) { + if (ioctl(fd_frontend, FE_READ_STATUS, &Status) != -1) + return true; + if (errno != EINTR) + break; } - } while (0); return false; } @@ -509,6 +506,11 @@ cSpuDecoder *cDvbDevice::GetSpuDecoder(void) return spuDecoder; } +bool cDvbDevice::HasCi(void) +{ + return ciAdapter; +} + uchar *cDvbDevice::GrabImage(int &Size, bool Jpeg, int Quality, int SizeX, int SizeY) { if (devVideoIndex < 0) diff --git a/dvbdevice.h b/dvbdevice.h index 670421f..63c38d1 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.42 2007/01/05 10:39:52 kls Exp $ + * $Id: dvbdevice.h 1.44 2007/02/25 12:23:57 kls Exp $ */ #ifndef __DVBDEVICE_H @@ -19,7 +19,7 @@ #error VDR requires Linux DVB driver API version 3! #endif -#define MAXDVBDEVICES 4 +#define MAXDVBDEVICES 8 class cDvbTuner; @@ -84,6 +84,11 @@ protected: protected: virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask); +// Common Interface facilities: + +public: + virtual bool HasCi(void); + // Image Grab facilities private: @@ -8,7 +8,7 @@ * * parts of this file are derived from the OMS program. * - * $Id: dvbspu.c 1.21 2006/04/17 12:45:05 kls Exp $ + * $Id: dvbspu.c 1.22 2007/02/03 10:13:18 kls Exp $ */ #include "dvbspu.h" @@ -504,9 +504,8 @@ int cDvbSpuDecoder::setTime(uint32_t pts) default: esyslog("invalid sequence in control header (%.2x)", spu[i]); - assert(0); - i++; - break; + Empty(); + return 0; } } if (fodd != 0 && feven != 0) { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.286 2007/01/07 12:19:15 kls Exp $ + * $Id: i18n.c 1.291 2007/02/25 13:59:28 kls Exp $ * * Translations provided by: * @@ -119,7 +119,7 @@ const tI18nPhrase Phrases[] = { "iso8859-7", "iso8859-1", "iso8859-2", - "iso8859-1", + "iso8859-2", "iso8859-1", "iso8859-5", "iso8859-2", @@ -231,7 +231,7 @@ const tI18nPhrase Phrases[] = { "×ñïíïðñïãñáììáôéóìïß", "Timers", "Timer-e", - "Idözítö", + "Idõzítõ", "Temporitzadors", "ÂÐÙÜÕàë", "Termini", @@ -385,7 +385,7 @@ const tI18nPhrase Phrases[] = { "Ôñïðïðïßçóç ÷ñïíïðñïãñáììáôéóìïý", "Ändra timer", "Modificare timer", - "Idözítö megváltoztatása", + "Idõzítõ megváltoztatása", "Editar temporitzador", "ÃáâÐÝÞÒÚÐ âÐÙÜÕàÐ", "Ureðivanje termina", @@ -694,7 +694,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "Timer", "Timer", - "Idözítö", + "Idõzítõ", "",// TODO "ÂÐÙÜÕà", "",// TODO @@ -936,7 +936,7 @@ const tI18nPhrase Phrases[] = { "Åðüìåíï", "Nästa", "Urmãtor", - "Következö", + "Következõ", "Següent", "´ÐÛÕÕ", "Slijedi", @@ -1157,7 +1157,7 @@ const tI18nPhrase Phrases[] = { "ÄéáãñáöÞ ÷ñïíïðñïãñáììáôéóìïý;?", "Ta bort timern?", "ªterg timer-ul?", - "Idözítö törlése?", + "Idõzítõ törlése?", "Esborrar el temporitzador?", "ÃÔÐÛØâì âÐÙÜÕà?", "Obrisati termin?", @@ -1341,6 +1341,28 @@ const tI18nPhrase Phrases[] = { "Optagelse igang - genstart alligevel?", "Systém je zaneprázdnìn - pøesto restartovat?", }, + { "Editing - restart anyway?", + "Schnitt läuft - trotzdem neu starten?", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + }, { "Recording - shut down anyway?", "Aufnahme läuft - trotzdem ausschalten?", "Snemanje - zares izklopi?", @@ -1377,7 +1399,7 @@ const tI18nPhrase Phrases[] = { "ÁíáìÝíåôáé åããñáöÞ óÝ %ld ëåðôÜ - ÔåëéêÜ íá ôåñìáôéóôåß?", "Inspelning startar om %ld minuter, vill du avsluta?", "Înregistrez peste %ld minute - închid, totuºi?", - "Felvétel %ld perc mulva kezdödik - mégis kikapcsolni?", + "Felvétel %ld perc mulva kezdõdik - mégis kikapcsolni?", "Hi ha una gravació en %ld minuts - Apagar de totes maneres?", "ÇÕàÕ× %ld ÜØÝãâ ÝÐçÝñâáï ×ÐßØáì - ÔÕÙáâÒØâÕÛìÝÞ ÒëÚÛîçØâì?", "Snimanje za %ld minuta - svejedno iskljuèiti?", @@ -1407,6 +1429,116 @@ const tI18nPhrase Phrases[] = { "Tryk vilkårlig tast for at annullere sluk", "Jakákoliv klávesa zru¹í vypnutí", }, + { "Press any key to cancel restart", + "Taste drücken, um Neustart abzubrechen", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + }, + { "VDR will shut down later - press Power to force", + "VDR schaltet später aus - Power zum erzwingen", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "VDR sammuu myöhemmin - pakota virtakytkimellä", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + }, + { "VDR will shut down in %s minutes", + "VDR wird in %s Minuten ausschalten", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "VDR sammuu %s minuutin kuluttua", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + }, + { "Editing - shut down anyway?", + "Schnitt läuft - trotzdem ausschalten?", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "Leikkaus kesken - sammutetaanko?", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + }, + { "Plugin %s wakes up in %ld min, continue?", + "Plugin %s wacht in %ld Min auf, weiter?", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "Laajennos %s herää %ld minuutin kuluttua - sammutetaanko?", + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + "",//TODO + }, // Channel parameters: { "Name", "Name", @@ -2149,7 +2281,7 @@ const tI18nPhrase Phrases[] = { "Ðñþôç ìÝñá", "Första dag", "Prima zi", - "Elsö nap", + "Elsõ nap", "Primer dia", "¿ÕàÒëÙ ÔÕÝì", "Prvi dan", @@ -2172,7 +2304,7 @@ const tI18nPhrase Phrases[] = { "Ôï êáíÜëç ÷ñéóéìïðïéåßôáé áðü ÷ñïíïðñïãñáììáôéóìü!", "Kanalen används av en timer!", "Canalul este utilizat de un timer!", - "Az adót az idözítö használja!", + "Az adót az idõzítõ használja!", "Canal en ús per un temporitzador!", "ºÐÝÐÛ ×ÐÝïâ âÐÙÜÕàÞÜ!", "Program je trenutno zauzet terminom za snimanje", @@ -2304,7 +2436,7 @@ const tI18nPhrase Phrases[] = { "",//TODO "strax VPS inspelning...", "Urmeazã o înregistrare VPS!", - "VPS-felvétel rögtön kezdödik!", + "VPS-felvétel rögtön kezdõdik!", "",//TODO "VPS-·ÐßØáì áÚÞàÞ ÝÐçÝÕâáï", "",//TODO @@ -2348,7 +2480,7 @@ const tI18nPhrase Phrases[] = { "Ôï êáíÜëç äÝí åßíáé äéáèÝóéìï!", "Kanalen är inte tillgänglig!", "Canal indisponibil", - "Az adó nem elérhetö", + "Az adó nem elérhetõ", "Canal no disponible!", "ºÐÝÐÛ ÝÕÔÞáâãßÕÝ!", "Program nije dostupan!", @@ -2370,7 +2502,7 @@ const tI18nPhrase Phrases[] = { "Ïé ñéèìýóåéò ôïí êáíáëéþí áëëõëïóõìðßðôïõí!", "Kanalinställningarna är ej unika!", "Parametrii canalului nu sunt univoci!", - "Az adóbeállítások nem egyértelmüek", + "Az adóbeállítások nem egyértelmûek", "Propietats del canal duplicades!", "½ÐáâàÞÙÚØ ÚÐÝÐÛÐ ÝÕ ãÝØÚÐÛìÝë!", "Parametri programa nisu jednoznaèni!", @@ -2524,7 +2656,7 @@ const tI18nPhrase Phrases[] = { "",//TODO "Otillräcklingt diskutrymme för inspelning!", "Insuficient spaþiul pe disc pentru înregistrare!", - "Nincs elegendö hely a felvételre", + "Nincs elegendõ hely a felvételre", "",//TODO "½ÕÔÞáâÐâÞçÝÞ ÜÕáâÐ ÝÐ ÔØáÚÕ ÔÛï ÝÐçÐÛÐ ×ÐßØáØ", "",//TODO @@ -3186,7 +3318,7 @@ const tI18nPhrase Phrases[] = { "×ñüíïò Ýíäåéîçò ìõíçìÜôùí (ä)", "Tid för meddelanden (sek)", "Timp afiºare mesaje (sec)", - "Információ feltüntetésének idötartama", + "Információ feltûntetésének idõtartama", "Durada dels missatges (s)", "´ÛØâÕÛìÝÞáâì ßÞÚÐ×Ð áÞÞÑéÕÝØÙ (áÕÚ)", "Vrijeme prikaza poruka (s)", @@ -3208,7 +3340,7 @@ const tI18nPhrase Phrases[] = { "×ñéóçìïðïßçóç ìéêñüí ãñáììáôïóåéñþí", "Använd liten font", "Utilizare fonturi mici", - "Kisbetüt használni", + "Kisbetût használni", "",// TODO "¸áßÞÛì×ÞÒÐâì ÜÕÛÚØÙ èàØäâ", "Koristi mala slova", @@ -3252,7 +3384,7 @@ const tI18nPhrase Phrases[] = { "ÅîáñôÜôå áðü ôÞí åðéöÜíåéá", "skin beroende", "dep. de skin", - "Menü nézetétöl függöen", + "Menü nézetétõl függõen", "",// TODO "áÞÓÛÐáÝÞ âÕÜÕ", "ovisno o povr¹ini", @@ -3318,7 +3450,7 @@ const tI18nPhrase Phrases[] = { "÷ñüíïò Ýíäåéêóçò ðëçñïöïñßùí êáíáëéïý óå (ä)", "Kanal information (s)", "Durata afiºãrii info-canal (s)", - "Adásinformáció feltüntetésének idötartama (s)", + "Adásinformáció feltûntetésének idõtartama (s)", "",// TODO "¿ÞÚÐ× ØÝäÞàÜÐæØØ Þ ÚÐÝÐÛÕ (áÕÚ)", "Vrijeme prikaza informacije o programu (s)", @@ -3414,7 +3546,7 @@ const tI18nPhrase Phrases[] = { "Scroll rundt", "Z konce na zaèátek", }, - { "Setup.OSD$Menu button closes", + { "Setup.OSD$Menu key closes", "Menu-Taste schließt", "Meni gumb zapre meni", "Usare il bottone Menu per chiudere", @@ -3472,7 +3604,7 @@ const tI18nPhrase Phrases[] = { "×ñüíïò äéÜñêåéáò åîÝôáóçò EPG óå þñåò", "EPG sökning timeout", "Interval achiziþie EPG (h)", - "Fennmaradt idö az EPG-újításig (h)", + "Fennmaradt idõ az EPG-újításig (h)", "Màxim d'Hores a cercar per la Guia", "·ÐÔÕàÖÚÐ áÚÐÝØàÞÒÐÝØï âÕÛÕÓØÔÐ (ç)", "Vrijeme do EPG pregleda (h)", @@ -3538,7 +3670,7 @@ const tI18nPhrase Phrases[] = { "Óõíôïíéóìüò þñáò õðïëïãéóôÞ", "Ställ in systemtid", "Potriveºte ceasul sistem", - "Az idö beállítása", + "Az idõ beállítása", "Ajustar l'hora del sistema", "ÃáâÐÝÞÒØâì áØáâÕÜÝÞÕ ÒàÕÜï", "Podesi vrijeme sistema", @@ -3560,7 +3692,7 @@ const tI18nPhrase Phrases[] = { "Áíáìåôáäüôçò óõíôïíéóìïý þñáò", "Använd klockan från transponder", "Preia ora din transponder", - "Idöhöz tartozó Transponder", + "Idõhöz tartozó Transponder", "Usar el temps del múltiplex", "¸áßÞÛì×ÞÒÐâì ÒàÕÜï âàÐÝáßÞÝÔÕàÐ", "Transponder za pode¹avanje sata", @@ -3626,7 +3758,7 @@ const tI18nPhrase Phrases[] = { "Êýñéá DVB êÜñôá", "Primär DVB enhet", "Dispozitiv DVB primar", - "Elsö DVB interface", + "Elsõ DVB interface", "Tarja DVB primària", "¾áÝÞÒÝÞÕ DVB-ãáâàÞÙáâÒÞ", "Primarni DVB ureðaj", @@ -4000,7 +4132,7 @@ const tI18nPhrase Phrases[] = { "¢íù LNB-Óõ÷íüôçôá (MHz)", "Övre LNB frekvens (MHz)", "Frecvnþã LNB superioarã (MHz)", - "Felsö LNB-frekvencia (MHZ)", + "Felsõ LNB-frekvencia (MHZ)", "Freqüència LNB alta (MHz)", "²ÕàåÝïï çÐáâÞâÐ ÚÞÝÒÕàâÕàÐ (¼³æ)", "Gornja LNB frekv. (MHz)", @@ -4044,7 +4176,7 @@ const tI18nPhrase Phrases[] = { "Ðñüóèåôïò ÷ñüíïò óôçí áñ÷Þ (ëåðôÜ)", "Marginal för start (min)", "Marjã la pornire (min)", - "Idöeltolódás a kezdésnél (perc)", + "Idõeltolódás a kezdésnél (perc)", "Marge d'inici de gravació (min)", "¾ßÕàÕÖÕÝØÕ ÝÐçÐÛÐ ×ÐßØáØ (ÜØÝ)", "Rezerva na poèetku snimanja (min)", @@ -4066,7 +4198,7 @@ const tI18nPhrase Phrases[] = { "Ðñüóèåôïò ÷ñüíïò óôü ôÝëïò (ëåðôÜ)", "Marginal för stopp (min)", "Marjã la oprire (min)", - "Idöeltolódás a befejezésnél (perc)", + "Idõeltolódás a befejezésnél (perc)", "Marge de fi de gravació (min)", "·ÐßÐ×ÔëÒÐÝØÕ ÞáâÐÝÞÒÚØ ×ÐßØáØ (ÜØÝ)", "Rezerva na kraju (min)", @@ -4242,7 +4374,7 @@ const tI18nPhrase Phrases[] = { "Ðåñéèþñéï VPS (ä)", "VPS marginal (s)", "Marjã de timp la utilizare VPS (s)", - "Idöeltolódás VPS-nél (s)", + "Idõeltolódás VPS-nél (s)", "",// TODO "±ãäÕàÝÞÕ ÒàÕÜï VPS (áÕÚ)", "Vremenska rezerva kod VPS (s)", @@ -4308,7 +4440,7 @@ const tI18nPhrase Phrases[] = { "ÄéÜñêåéá óôãìéáßáò åããñáöÞò (ëåðôÜ)", "Direktinspelning längd (min)", "Timpul de înregistare imediatã (min)", - "Felvétel idötartama (perc)", + "Felvétel idõtartama (perc)", "Temps de gravació instantània (min)", "´ÛØâÕÛìÝÞáâì àãçÝÞÙ ×ÐßØáØ (ÜØÝ)", "Trajanje direktnog snimanja (min)", @@ -4440,7 +4572,7 @@ const tI18nPhrase Phrases[] = { "ÅëÜ÷éóôïò ÷ñÜíïò ðáñåìâïëÞò (ëåðôÜ)", "Minsta händelse-pause (min)", "Duratã minimã emisiuni (min)", - "Idözitések közötti idötartam (perc)", + "Idõzitések közötti idõtartam (perc)", "Temps mínim en pausa (min)", "¼ØÝ. ÒàÕÜï ÞÖØÔÐÝØï áÞÑëâØï (ÜØÝ)", "Minimalno vrijeme pauze", @@ -4514,6 +4646,28 @@ const tI18nPhrase Phrases[] = { "Zap timeout (s)", "Èasový limit Zap (s)", }, + { "Setup.Miscellaneous$Channel entry timeout (ms)", + "Zeitlimit für Kanaleingabe (ms)", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + }, { "Setup.Miscellaneous$Initial channel", "Kanal beim Einschalten", "Privzeti kanal", @@ -4550,7 +4704,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "Ljudstyrka vid uppstart", "Volumul la pornire", - "Hangerö a bekapcsolásnál", + "Hangerõ a bekapcsolásnál", "",// TODO "³àÞÜÚÞáâì ßàØ ÒÚÛîçÕÝØØ", "",// TODO @@ -4572,7 +4726,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "som förut", "ca mai înainte", - "ahogy az elöbb", + "ahogy az elõbb", "",// TODO "ÚÐÚ àÐÝìèÕ", "",// TODO @@ -4640,7 +4794,7 @@ const tI18nPhrase Phrases[] = { " áÜâãäåÝæçÞèéßêëìíîïüðñóòôõýö÷øùþ0123456789-.#~,/_@abcdefghijklmnopqrstuvwxyz", " abcdefghijklmnopqrstuvwxyzåäö0123456789-.#~,/_@", " aãâbcdefghiîjklmnopqrsºtþuvwxyz0123456789-.#~,/_@", - " aábcdeéfghiíjklmnoóö¿pqrstuúü¿vwxyz0123456789-.,#~,/_@", + " aábcdeéfghiíjklmnoóöõpqrstuúüûvwxyz0123456789-.,#~,/_@", " aàbcçdeéèfghiíjklmnoòpqrstuúvwxyz0123456789-.,#~,/_@·", " abcdefghijklmnopqrstuvwxyzÐÑÒÓÔÕñÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìîï0123456789-.#~,/_@", " abcèædðefghijklmnopqrs¹tuvwxyz¾0123456789-.#~,/_@", // hrv @@ -4663,7 +4817,7 @@ const tI18nPhrase Phrases[] = { "",//TODO " 0\t-.#~,/_@1\tabcåä2\tdef3\tghi4\tjkl5\tmnoö6\tpqrs7\ttuv8\twxyz", " 0\t-.#~,/_@1\taãâbc2\tdef3\tghiî4\tjkl5\tmno6\tpqrsº7\ttþuv8\twxyz9", - " 0\t-.#~,/_@1\taábc2\tdeé3\tghií4\tjkl5\tmnoóö¿6\tpqrs7\ttuúü¿v8\twxyz9", + " 0\t-.#~,/_@1\taábc2\tdeéf3\tghií4\tjkl5\tmnoóöõ6\tpqrs7\ttuúüûv8\twxyz9", "",//TODO "",//TODO "",//TODO @@ -4708,7 +4862,7 @@ const tI18nPhrase Phrases[] = { "ÖÜóç 1: Áíß÷íåõóç êþäéêá RC", "Steg1: identifiering av kod", "Faza 1: Detecþia tipului telecomenzii", - "Elsö lépés: távirányító kódjának meghatározása", + "Elsõ lépés: távirányító kódjának meghatározása", "Fase 1: Detectant el tipus de receptor", "ÈÐÓ 1: ¾ßàÕÔÕÛÕÝØÕ âØßÐ ÚÞÔÐ ßãÛìâÐ", "Faza 1: detektiranje kôda daljinskog upravljaèa.", @@ -5347,7 +5501,7 @@ const tI18nPhrase Phrases[] = { "Ðñïþèçóç åìðñüò", "Snabbspolning framåt", "Derulare înainte", - "Elöre pörgetni", + "Elõre pörgetni", "Endavant ràpidament", "¿àÞÚàãâÚÐ ÒßÕàñÔ", "Naprijed", @@ -5391,7 +5545,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "Nästa", "Urmãtor", - "Elöre", + "Elõre", "",// TODO "²ßÕàÕÔ", "",// TODO @@ -5429,7 +5583,7 @@ const tI18nPhrase Phrases[] = { "Ligar", "Arrêt", "Power", - "Virtakytkin", + "Virta", "Wy³±cz", "Apagar", "Këåßóéìï", @@ -5501,7 +5655,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "Förra kanalen", "Canal anterior", - "Az elözö adás", + "Az elõzõ adás", "",// TODO "¿àÕÔëÔãéØÙ ÚÐÝÐÛ", "",// TODO @@ -5523,7 +5677,7 @@ const tI18nPhrase Phrases[] = { "¸íôáóç+", "Volym+", "Volum+", - "Hangerö+", + "Hangerõ+", "Volum +", "³àÞÜÚÞáâì +", "Glasnije", // hrv "Glasnocca +" @@ -5545,7 +5699,7 @@ const tI18nPhrase Phrases[] = { "¸íôáóç-", "Volym-", "Volum-", - "Hangerö-", + "Hangerõ-", "Volum -", "³àÞÜÚÞáâì -", "Ti¹e", // hrv Glasnocca -" @@ -5561,7 +5715,7 @@ const tI18nPhrase Phrases[] = { "Sem som", "Coupure du son", "Lyd av", - "Äänetön", + "Mykistys", "Wycisz", "Mudo", "Óéùðçëü", @@ -5832,7 +5986,7 @@ const tI18nPhrase Phrases[] = { "¸íôáóç ", "Volym ", "Volum ", - "Hangerö", + "Hangerõ", "Volum ", "³àÞÜÚÞáâì ", "Glasnoæa ", @@ -6052,7 +6206,7 @@ const tI18nPhrase Phrases[] = { "ÐÜãùìá æùíôáíïý óÞìáôïò", "Pausar direktinspelningen", "Trec în pauzã emisiunea transmisã...", - "Az élö adás megállítva...", + "Az élõ adás megállítva...", "Pausa d'emissió en directe...", "ÀÕÖØÜ ÞâÛÞÖÕÝÝÞÓÞ ßàÞáÜÞâàÐ...", "Zaustavljanje ¾ivog signala...", @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: keys.h 1.10 2006/10/14 10:41:20 kls Exp $ + * $Id: keys.h 1.11 2007/02/25 10:49:35 kls Exp $ */ #ifndef __KEYS_H @@ -74,6 +74,7 @@ enum eKeys { // "Up" and "Down" must be the first two keys! #define ISRAWKEY(k) ((k) != kNone && ((k) & k_Flags) == 0) #define NORMALKEY(k) (eKeys((k) & ~k_Repeat)) #define ISMODELESSKEY(k) (RAWKEY(k) > k9) +#define ISREALKEY(k) (k != kNone && k != k_Plugin) #define BASICKEY(k) (eKeys((k) & 0xFFFF)) #define KBDKEY(k) (eKeys(((k) << 16) | kKbd)) diff --git a/libsi/descriptor.c b/libsi/descriptor.c index 1654a33..f3bb344 100644 --- a/libsi/descriptor.c +++ b/libsi/descriptor.c @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: descriptor.c 1.21 2006/05/28 14:25:30 kls Exp $ + * $Id: descriptor.c 1.22 2007/02/03 11:45:58 kls Exp $ * * ***************************************************************************/ @@ -418,8 +418,16 @@ int SatelliteDeliverySystemDescriptor::getPolarization() const { return s->polarization; } -int SatelliteDeliverySystemDescriptor::getModulation() const { - return s->modulation; +int SatelliteDeliverySystemDescriptor::getModulationSystem() const { + return s->modulation_system; +} + +int SatelliteDeliverySystemDescriptor::getModulationType() const { + return s->modulation_type; +} + +int SatelliteDeliverySystemDescriptor::getRollOff() const { + return s->roll_off; } int SatelliteDeliverySystemDescriptor::getSymbolRate() const { @@ -462,6 +470,18 @@ int TerrestrialDeliverySystemDescriptor::getFrequency() const { return (HILO(s->frequency_hi) << 16) | HILO(s->frequency_lo); } +int TerrestrialDeliverySystemDescriptor::getPriority() const { + return s->priority; +} + +int TerrestrialDeliverySystemDescriptor::getTimeSlicingIndicator() const { + return s->time_slicing_indicator; +} + +int TerrestrialDeliverySystemDescriptor::getMpeFecIndicator() const { + return s->mpe_fec_indicator; +} + int TerrestrialDeliverySystemDescriptor::getBandwidth() const { return s->bandwidth; } @@ -794,6 +814,41 @@ int AncillaryDataDescriptor::getAncillaryDataIdentifier() const { return s->ancillary_data_identifier; } +void S2SatelliteDeliverySystemDescriptor::Parse() { + int offset=0; + input_stream_identifier=0; + data.setPointerAndOffset<const descr_s2_satellite_delivery_system>(s, offset); + if (s->scrambling_sequence_selector) + data.setPointerAndOffset<const descr_scrambling_sequence_selector>(sss, offset); + if (s->multiple_input_stream_flag) + input_stream_identifier = *data.getData(offset++); +} + +int S2SatelliteDeliverySystemDescriptor::getScramblingSequenceSelector() const { + return s->scrambling_sequence_selector; +} + +int S2SatelliteDeliverySystemDescriptor::getMultipleInputStreamFlag() const { + return s->multiple_input_stream_flag; +} + +int S2SatelliteDeliverySystemDescriptor::getBackwardsCompatibilityIndicator() const { + return s->backwards_compatibility_indicator; +} + +int S2SatelliteDeliverySystemDescriptor::getScramblingSequenceIndex() const { + return sss == NULL ? 0 : (sss->scrambling_sequence_index_hi_lo << 16) | HILO(sss->scrambling_sequence_index_lo); +} + +void ExtensionDescriptor::Parse() { + int offset=0; + data.setPointerAndOffset<const descr_extension>(s, offset); +} + +int ExtensionDescriptor::getExtensionDescriptorTag() const { + return s->descriptor_tag_extension; +} + int PremiereContentTransmissionDescriptor::getOriginalNetworkId() const { return HILO(s->original_network_id); } diff --git a/libsi/descriptor.h b/libsi/descriptor.h index c0c884f..161793e 100644 --- a/libsi/descriptor.h +++ b/libsi/descriptor.h @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: descriptor.h 1.15 2006/05/28 14:25:30 kls Exp $ + * $Id: descriptor.h 1.16 2007/02/03 11:45:58 kls Exp $ * * ***************************************************************************/ @@ -210,7 +210,9 @@ public: int getOrbitalPosition() const; int getWestEastFlag() const; int getPolarization() const; - int getModulation() const; + int getModulationSystem() const; + int getModulationType() const; + int getRollOff() const; int getSymbolRate() const; int getFecInner() const; protected: @@ -236,6 +238,9 @@ class TerrestrialDeliverySystemDescriptor : public Descriptor { public: int getFrequency() const; int getBandwidth() const; + int getPriority() const; + int getTimeSlicingIndicator() const; + int getMpeFecIndicator() const; int getConstellation() const; int getHierarchy() const; int getCodeRateHP() const; @@ -484,6 +489,30 @@ private: const descr_ancillary_data *s; }; +class S2SatelliteDeliverySystemDescriptor : public Descriptor { +public: + int getScramblingSequenceSelector() const; + int getMultipleInputStreamFlag() const; + int getBackwardsCompatibilityIndicator() const; + int getScramblingSequenceIndex() const; + int getInputStreamIdentifier() const { return input_stream_identifier; } +protected: + virtual void Parse(); +private: + const descr_s2_satellite_delivery_system *s; + const descr_scrambling_sequence_selector *sss; + int input_stream_identifier; +}; + +class ExtensionDescriptor : public Descriptor { +public: + int getExtensionDescriptorTag() const; +protected: + virtual void Parse(); +private: + const descr_extension *s; +}; + // Private DVB Descriptor Premiere.de // 0xF2 Content Transmission Descriptor // http://dvbsnoop.sourceforge.net/examples/example-private-section.html diff --git a/libsi/headers.h b/libsi/headers.h index ea7824b..db1e261 100644 --- a/libsi/headers.h +++ b/libsi/headers.h @@ -10,7 +10,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: headers.h 1.8 2006/09/02 20:25:16 kls Exp $ + * $Id: headers.h 1.9 2007/02/03 11:45:58 kls Exp $ * * ***************************************************************************/ @@ -942,9 +942,13 @@ struct descr_satellite_delivery_system { #if BYTE_ORDER == BIG_ENDIAN u_char west_east_flag :1; u_char polarization :2; - u_char modulation :5; + u_char roll_off :2; + u_char modulation_system :1; + u_char modulation_type :2; #else - u_char modulation :5; + u_char modulation_type :2; + u_char modulation_system :1; + u_char roll_off :2; u_char polarization :2; u_char west_east_flag :1; #endif @@ -1349,9 +1353,15 @@ struct descr_terrestrial_delivery { u_char frequency_lo_lo :8; #if BYTE_ORDER == BIG_ENDIAN u_char bandwidth :3; - u_char reserved1 :5; + u_char priority :1; + u_char time_slicing_indicator :1; + u_char mpe_fec_indicator :1; + u_char reserved1 :2; #else - u_char reserved1 :5; + u_char reserved1 :2; + u_char mpe_fec_indicator :1; + u_char time_slicing_indicator :1; + u_char priority :1; u_char bandwidth :3; #endif #if BYTE_ORDER == BIG_ENDIAN @@ -1492,10 +1502,10 @@ struct descr_data_broadcast { /* TBD */ }; -/* 0x65 ca_system_descriptor */ +/* 0x65 scrambling_descriptor */ -#define DESCR_CA_SYSTEM_LEN XX -struct descr_ca_system { +#define DESCR_SCRAMBLING_LEN XX +struct descr_scrambling { u_char descriptor_tag :8; u_char descriptor_length :8; /* TBD */ @@ -1628,6 +1638,189 @@ struct descr_service_identifier { u_char descriptor_length :8; }; +/* 0x72 service_availbility_descriptor */ + +struct descr_service_availbility { + u_char descriptor_tag :8; + u_char descriptor_length :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char availability_flag :1; + u_char reserved :7; +#else + u_char reserved :7; + u_char availability_flag :1; +#endif +}; + +/* 0x73 default_authority_descriptor (ETSI TS 102 323) */ + +struct descr_default_authority { + u_char descriptor_tag :8; + u_char descriptor_length :8; +}; + +/* 0x74 related_content_descriptor (ETSI TS 102 323) */ + +struct descr_related_content { + u_char descriptor_tag :8; + u_char descriptor_length :8; +}; + +/* 0x75 tva_id_descriptor (ETSI TS 102 323) */ + +struct descr_tva_id { + u_char descriptor_tag :8; + u_char descriptor_length :8; +}; + +/* 0x76 content_identifier_descriptor (ETSI TS 102 323) */ + +struct descr_content_identifier { + u_char descriptor_tag :8; + u_char descriptor_length :8; +}; + +/* 0x77 time_slice_fec_identifier_descriptor (ETSI EN 301 192) */ + +struct descr_time_slice_fec_identifier { + u_char descriptor_tag :8; + u_char descriptor_length :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char time_slicing :1; + u_char mpe_fec :2; + u_char reserved :2; + u_char frame_size :3; +#else + u_char frame_size :3; + u_char reserved :2; + u_char mpe_fec :2; + u_char time_slicing :1; +#endif + u_char max_burst_duration :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char max_average_rate :4; + u_char time_slice_fec_id :4; +#else + u_char time_slice_fec_id :4; + u_char max_average_rate :4; +#endif +}; + +/* 0x78 ecm_repetition_rate_descriptor (ETSI EN 301 192) */ + +struct descr_ecm_repetition_rate { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char ca_system_id_hi :8; + u_char ca_system_id_lo :8; + u_char ecm_repetition_rate_hi :8; + u_char ecm_repetition_rate_lo :8; +}; + +/* 0x79 s2_satellite_delivery_system_descriptor */ + +struct descr_s2_satellite_delivery_system { + u_char descriptor_tag :8; + u_char descriptor_length :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char scrambling_sequence_selector :1; + u_char multiple_input_stream_flag :1; + u_char backwards_compatibility_indicator :1; + u_char reserved :5; +#else + u_char reserved :5; + u_char backwards_compatibility_indicator :1; + u_char multiple_input_stream_flag :1; + u_char scrambling_sequence_selector :1; +#endif +}; + +struct descr_scrambling_sequence_selector { +#if BYTE_ORDER == BIG_ENDIAN + u_char reserved :6; + u_char scrambling_sequence_index_hi_lo :2; +#else + u_char scrambling_sequence_index_hi_lo :2; + u_char reserved :6; +#endif + u_char scrambling_sequence_index_lo_hi :8; + u_char scrambling_sequence_index_lo_lo :8; +}; + +/* 0x7A enhanced_ac3_descriptor */ + +struct descr_enhanced_ac3 { + u_char descriptor_tag :8; + u_char descriptor_length :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char component_type_flag :1; + u_char bsid_flag :1; + u_char mainid_flag :1; + u_char asvc_flag :1; + u_char mixinfoexists :1; + u_char substream1_flag :1; + u_char substream2_flag :1; + u_char substream3_flag :1; +#else + u_char substream3_flag :1; + u_char substream2_flag :1; + u_char substream1_flag :1; + u_char mixinfoexists :1; + u_char asvc_flag :1; + u_char mainid_flag :1; + u_char bsid_flag :1; + u_char component_type_flag :1; +#endif +}; + +/* 0x7B dts_descriptor */ + +struct descr_dts { + u_char descriptor_tag :8; + u_char descriptor_length :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char sample_rate_code :4; + u_char bit_rate_code :6; + u_char nblks :7; + u_char fsize_hi :6; + u_char fsize_lo :8; + u_char surround_mode :6; + u_char lfe_flag :1; + u_char extended_surround_flag :2; +#else + u_char extended_surround_flag :2; + u_char lfe_flag :1; + u_char surround_mode :6; + u_char fsize_lo :8; + u_char fsize_hi :6; + u_char nblks :7; + u_char bit_rate_code :6; + u_char sample_rate_code :4; +#endif +}; + +/* 0x7C aac_descriptor */ + +struct descr_aac { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char profile_and_level :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char aac_type_flag :1; + u_char reserved :7; +#else + u_char reserved :7; + u_char aac_type_flag :1; +#endif +}; +/* 0x7F extension_descriptor */ + +struct descr_extension { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char descriptor_tag_extension :8; +}; + /* MHP 0x00 application_descriptor */ #define DESCR_APPLICATION_LEN 3 @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.c 1.16 2006/04/14 10:53:44 kls Exp $ + * $Id: si.c 1.17 2007/02/03 11:45:58 kls Exp $ * * ***************************************************************************/ @@ -425,6 +425,12 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, case AncillaryDataDescriptorTag: d=new AncillaryDataDescriptor(); break; + case S2SatelliteDeliverySystemDescriptorTag: + d=new S2SatelliteDeliverySystemDescriptor(); + break; + case ExtensionDescriptorTag: + d=new ExtensionDescriptor(); + break; //note that it is no problem to implement one //of the unimplemented descriptors. @@ -459,12 +465,23 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, case PartialTransportStreamDescriptorTag: case DataBroadcastDescriptorTag: case DataBroadcastIdDescriptorTag: - case CaSystemDescriptorTag: + case ScramblingDescriptorTag: case AC3DescriptorTag: case DSNGDescriptorTag: case AnnouncementSupportDescriptorTag: case AdaptationFieldDataDescriptorTag: case TransportStreamDescriptorTag: + + //defined in ETSI EN 300 468 v 1.7.1 + case DefaultAuthorityDescriptorTag: + case RelatedContentDescriptorTag: + case TVAIdDescriptorTag: + case ContentIdentifierDescriptorTag: + case TimeSliceFecIdentifierDescriptorTag: + case ECMRepetitionRateDescriptorTag: + case EnhancedAC3DescriptorTag: + case DTSDescriptorTag: + case AACDescriptorTag: default: if (!returnUnimplemetedDescriptor) return 0; @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.h 1.15 2006/05/27 13:07:20 kls Exp $ + * $Id: si.h 1.16 2007/02/03 11:47:25 kls Exp $ * * ***************************************************************************/ @@ -108,7 +108,7 @@ enum DescriptorTag { FrequencyListDescriptorTag = 0x62, PartialTransportStreamDescriptorTag = 0x63, DataBroadcastDescriptorTag = 0x64, - CaSystemDescriptorTag = 0x65, + ScramblingDescriptorTag = 0x65, DataBroadcastIdDescriptorTag = 0x66, TransportStreamDescriptorTag = 0x67, DSNGDescriptorTag = 0x68, @@ -122,6 +122,19 @@ enum DescriptorTag { AdaptationFieldDataDescriptorTag = 0x70, ServiceIdentifierDescriptorTag = 0x71, ServiceAvailabilityDescriptorTag = 0x72, + // defined by ETSI (EN 300 468) v 1.7.1 + DefaultAuthorityDescriptorTag = 0x73, + RelatedContentDescriptorTag = 0x74, + TVAIdDescriptorTag = 0x75, + ContentIdentifierDescriptorTag = 0x76, + TimeSliceFecIdentifierDescriptorTag = 0x77, + ECMRepetitionRateDescriptorTag = 0x78, + S2SatelliteDeliverySystemDescriptorTag = 0x79, + EnhancedAC3DescriptorTag = 0x7A, + DTSDescriptorTag = 0x7B, + AACDescriptorTag = 0x7C, + ExtensionDescriptorTag = 0x7F, + // Defined by ETSI TS 102 812 (MHP) // They once again start with 0x00 (see page 234, MHP specification) MHP_ApplicationDescriptorTag = 0x00, @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.447 2007/01/07 12:19:48 kls Exp $ + * $Id: menu.c 1.450 2007/02/25 14:04:33 kls Exp $ */ #include "menu.h" @@ -22,6 +22,7 @@ #include "plugin.h" #include "recording.h" #include "remote.h" +#include "shutdown.h" #include "sources.h" #include "status.h" #include "themes.h" @@ -2206,7 +2207,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$Menu key closes"), &data.MenuKeyCloses)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs)); SetCurrent(Get(current)); Display(); @@ -2661,6 +2662,7 @@ cMenuSetupMisc::cMenuSetupMisc(void) Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. user inactivity (min)"), &data.MinUserInactivity)); Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"), &data.SVDRPTimeout)); Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Zap timeout (s)"), &data.ZapTimeout)); + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Channel entry timeout (ms)"), &data.ChannelEntryTimeout, 0)); Add(new cMenuEditChanItem(tr("Setup.Miscellaneous$Initial channel"), &data.InitialChannel, tr("Setup.Miscellaneous$as before"))); Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Initial volume"), &data.InitialVolume, -1, 255, tr("Setup.Miscellaneous$as before"))); } @@ -2770,10 +2772,8 @@ void cMenuSetup::Set(void) eOSState cMenuSetup::Restart(void) { - if (Interface->Confirm(tr("Really restart?")) - && (!cRecordControls::Active() || Interface->Confirm(tr("Recording - restart anyway?"))) - && !cPluginManager::Active(tr("restart anyway?"))) { - cThread::EmergencyExit(true); + if (Interface->Confirm(tr("Really restart?")) && ShutdownHandler.ConfirmRestart(true)) { + ShutdownHandler.Exit(1); return osEnd; } return osContinue; @@ -3090,8 +3090,6 @@ static void SetTrackDescriptions(int LiveChannel) // --- cDisplayChannel ------------------------------------------------------- -#define DIRECTCHANNELTIMEOUT 1000 //ms - cDisplayChannel *cDisplayChannel::currentDisplayChannel = NULL; cDisplayChannel::cDisplayChannel(int Number, bool Switched) @@ -3290,7 +3288,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) Refresh(); break; case kNone: - if (number && lastTime.Elapsed() > DIRECTCHANNELTIMEOUT) { + if (number && Setup.ChannelEntryTimeout && int(lastTime.Elapsed()) > Setup.ChannelEntryTimeout) { channel = Channels.GetByNumber(number); if (channel) NewChannel = channel; @@ -3699,7 +3697,7 @@ bool cRecordControls::Start(cTimer *Timer, bool Pause) if (device) { dsyslog("switching device %d to channel %d", device->DeviceNumber() + 1, channel->Number()); if (!device->SwitchChannel(channel, false)) { - cThread::EmergencyExit(true); + ShutdownHandler.RequestEmergencyExit(); return false; } if (!Timer || Timer->Matches()) { @@ -12,7 +12,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: newplugin 1.30 2006/09/09 12:38:35 kls Exp $ +# $Id: newplugin 1.31 2007/02/24 13:23:08 kls Exp $ $PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin <name>\n"; @@ -169,6 +169,7 @@ public: virtual void Housekeeping(void); virtual void MainThreadHook(void); virtual cString Active(void); + virtual time_t WakeupTime(void); virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; } virtual cOsdObject *MainMenuAction(void); virtual cMenuSetupPage *SetupMenu(void); @@ -236,6 +237,12 @@ cString cPlugin${PLUGIN_CLASS}::Active(void) return NULL; } +time_t cPlugin${PLUGIN_CLASS}::WakeupTime(void) +{ + // Return custom wakeup time for shutdown script + return 0; +} + cOsdObject *cPlugin${PLUGIN_CLASS}::MainMenuAction(void) { // Perform the action when selected from the main VDR menu. @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.67 2006/02/26 14:31:31 kls Exp $ + * $Id: osd.c 1.68 2007/02/17 16:05:52 kls Exp $ */ #include "osd.h" @@ -218,14 +218,17 @@ bool cBitmap::LoadXpm(const char *FileName) int w, h, n, c; if (4 != sscanf(s, "%d %d %d %d", &w, &h, &n, &c)) { esyslog("ERROR: faulty 'values' line in XPM file '%s'", FileName); + isXpm = false; break; } lines = h + n + 1; Xpm = MALLOC(char *, lines); + memset(Xpm, 0, lines * sizeof(char*)); } char *q = strchr(s, '"'); if (!q) { esyslog("ERROR: missing quotes in XPM file '%s'", FileName); + isXpm = false; break; } *q = 0; @@ -233,16 +236,21 @@ bool cBitmap::LoadXpm(const char *FileName) Xpm[index++] = strdup(s); else { esyslog("ERROR: too many lines in XPM file '%s'", FileName); + isXpm = false; break; } } } - if (index == lines) - Result = SetXpm(Xpm); - else - esyslog("ERROR: too few lines in XPM file '%s'", FileName); - for (int i = 0; i < index; i++) - free(Xpm[i]); + if (isXpm) { + if (index == lines) + Result = SetXpm(Xpm); + else + esyslog("ERROR: too few lines in XPM file '%s'", FileName); + } + if (Xpm) { + for (int i = 0; i < index; i++) + free(Xpm[i]); + } free(Xpm); fclose(f); } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: plugin.c 1.24 2006/10/14 09:49:16 kls Exp $ + * $Id: plugin.c 1.25 2007/02/24 13:44:23 kls Exp $ */ #include "plugin.h" @@ -80,6 +80,11 @@ cString cPlugin::Active(void) return NULL; } +time_t cPlugin::WakeupTime(void) +{ + return 0; +} + const char *cPlugin::MainMenuEntry(void) { return NULL; @@ -403,6 +408,26 @@ bool cPluginManager::Active(const char *Prompt) return false; } +cPlugin *cPluginManager::GetNextWakeupPlugin(void) +{ + cPlugin *NextPlugin = NULL; + if (pluginManager) { + time_t Now = time(NULL); + time_t Next = 0; + for (cDll *dll = pluginManager->dlls.First(); dll; dll = pluginManager->dlls.Next(dll)) { + cPlugin *p = dll->Plugin(); + if (p) { + time_t t = p->WakeupTime(); + if (t > Now && (!Next || t < Next)) { + Next = t; + NextPlugin = p; + } + } + } + } + return NextPlugin; +} + bool cPluginManager::HasPlugins(void) { return pluginManager && pluginManager->dlls.Count(); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: plugin.h 1.13 2006/04/17 09:18:16 kls Exp $ + * $Id: plugin.h 1.14 2007/02/24 13:45:28 kls Exp $ */ #ifndef __PLUGIN_H @@ -41,6 +41,7 @@ public: virtual void Housekeeping(void); virtual void MainThreadHook(void); virtual cString Active(void); + virtual time_t WakeupTime(void); virtual const char *MainMenuEntry(void); virtual cOsdObject *MainMenuAction(void); @@ -93,6 +94,7 @@ public: void Housekeeping(void); void MainThreadHook(void); static bool Active(const char *Prompt = NULL); + static cPlugin *GetNextWakeupPlugin(void); static bool HasPlugins(void); static cPlugin *GetPlugin(int Index); static cPlugin *GetPlugin(const char *Name); @@ -4,13 +4,14 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recorder.c 1.18 2007/01/05 10:43:09 kls Exp $ + * $Id: recorder.c 1.19 2007/02/24 16:36:24 kls Exp $ */ #include "recorder.h" #include <stdarg.h> #include <stdio.h> #include <unistd.h> +#include "shutdown.h" #define RECORDERBUFSIZE MEGABYTE(5) @@ -117,7 +118,7 @@ void cFileWriter::Action(void) } else if (time(NULL) - t > MAXBROKENTIMEOUT) { esyslog("ERROR: video data stream broken"); - cThread::EmergencyExit(true); + ShutdownHandler.RequestEmergencyExit(); t = time(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.55 2006/12/02 11:12:42 kls Exp $ + * $Id: remote.c 1.56 2007/02/24 13:23:12 kls Exp $ */ #include "remote.h" @@ -31,6 +31,7 @@ cMutex cRemote::mutex; cCondVar cRemote::keyPressed; const char *cRemote::keyMacroPlugin = NULL; const char *cRemote::callPlugin = NULL; +time_t cRemote::lastActivity = 0; cRemote::cRemote(const char *Name) { @@ -183,6 +184,7 @@ eKeys cRemote::Get(int WaitMs, char **UnknownCode) out = 0; if ((k & k_Repeat) != 0) repeatTimeout.Set(REPEATTIMEOUT); + lastActivity = time(NULL); return k; } else if (!WaitMs || !keyPressed.TimedWait(mutex, WaitMs) && repeatTimeout.TimedOut()) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remote.h 1.38 2006/12/02 11:12:49 kls Exp $ + * $Id: remote.h 1.39 2007/02/24 15:53:00 kls Exp $ */ #ifndef __REMOTE_H @@ -28,6 +28,7 @@ private: static char *unknownCode; static cMutex mutex; static cCondVar keyPressed; + static time_t lastActivity; static const char *keyMacroPlugin; static const char *callPlugin; char *name; @@ -61,6 +62,8 @@ public: ///< plugin name will be reset to NULL by this call. static bool HasKeys(void); static eKeys Get(int WaitMs = 1000, char **UnknownCode = NULL); + static time_t LastActivity(void) { return lastActivity; } + ///< Absolute time when last key was delivered by Get(). }; class cRemotes : public cList<cRemote> {}; @@ -11,13 +11,13 @@ * The cRepacker family's code was originally written by Reinhard Nissl <rnissl@gmx.de>, * and adapted to the VDR coding style by Klaus.Schmidinger@cadsoft.de. * - * $Id: remux.c 1.57 2006/12/01 14:46:25 kls Exp $ + * $Id: remux.c 1.58 2007/02/24 16:36:10 kls Exp $ */ #include "remux.h" #include <stdlib.h> #include "channels.h" -#include "thread.h" +#include "shutdown.h" #include "tools.h" ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader) @@ -2011,7 +2011,7 @@ int cRemux::Put(const uchar *Data, int Count) esyslog("ERROR: no useful data seen within %d byte of video stream", skipped); skipped = -1; if (exitOnFailure) - cThread::EmergencyExit(true); + ShutdownHandler.RequestEmergencyExit(); } else skipped += used; @@ -2059,7 +2059,7 @@ uchar *cRemux::Get(int &Count, uchar *PictureType) if (pt < I_FRAME || B_FRAME < pt) { esyslog("ERROR: unknown picture type '%d'", pt); if (++numUPTerrors > MAXNUMUPTERRORS && exitOnFailure) - cThread::EmergencyExit(true); + ShutdownHandler.RequestEmergencyExit(); } else if (!synced) { if (pt == I_FRAME) { diff --git a/shutdown.c b/shutdown.c new file mode 100644 index 0000000..4029a78 --- /dev/null +++ b/shutdown.c @@ -0,0 +1,250 @@ +/* + * shutdown.c: Handling of shutdown and inactivity + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * Original version written by Udo Richter <udo_richter@gmx.de>. + * + * $Id: shutdown.c 1.1 2007/02/24 17:24:11 kls Exp $ + */ + +#include "shutdown.h" +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include "channels.h" +#include "config.h" +#include "cutter.h" +#include "i18n.h" +#include "interface.h" +#include "menu.h" +#include "plugin.h" +#include "timers.h" +#include "tools.h" + +cShutdownHandler ShutdownHandler; + +cCountdown::cCountdown(void) +{ + timeout = 0; + counter = 0; + timedOut = false; + message = NULL; +} + +void cCountdown::Start(const char *Message, int Seconds) +{ + timeout = time(NULL) + Seconds; + counter = -1; + timedOut = false; + message = Message; + Update(); +} + +void cCountdown::Cancel(void) +{ + if (timeout) { + timeout = 0; + timedOut = false; + Skins.Message(mtStatus, NULL); + } +} + +bool cCountdown::Done(void) +{ + if (timedOut) { + Cancel(); + return true; + } + return false; +} + +bool cCountdown::Update(void) +{ + if (timeout) { + int NewCounter = (timeout - time(NULL) + 9) / 10; + if (NewCounter <= 0) + timedOut = true; + if (counter != NewCounter) { + counter = NewCounter; + char time[10]; + snprintf(time, sizeof(time), "%d:%d0", counter > 0 ? counter / 6 : 0, counter > 0 ? counter % 6 : 0); + cString Message = cString::sprintf(message, time); + Skins.Message(mtStatus, Message); + return true; + } + } + return false; +} + +cShutdownHandler::cShutdownHandler(void) +{ + activeTimeout = 0; + retry = 0; + shutdownCommand = NULL; + exitCode = -1; + emergencyExitRequested = false; +} + +cShutdownHandler::~cShutdownHandler() +{ + free(shutdownCommand); +} + +void cShutdownHandler::RequestEmergencyExit(void) +{ + esyslog("initiating emergency exit"); + emergencyExitRequested = true; + Exit(1); +} + +void cShutdownHandler::CheckManualStart(int ManualStart) +{ + time_t Delta = Setup.NextWakeupTime ? Setup.NextWakeupTime - time(NULL) : 0; + + if (!Setup.NextWakeupTime || abs(Delta) > ManualStart) { + // Apparently the user started VDR manually + dsyslog("assuming manual start of VDR"); + // Set inactive after MinUserInactivity + SetUserInactiveTimeout(); + } + else + // Set inactive from now on + SetUserInactive(); +} + +void cShutdownHandler::SetShutdownCommand(const char *ShutdownCommand) +{ + free(shutdownCommand); + shutdownCommand = ShutdownCommand ? strdup(ShutdownCommand) : NULL; +} + +void cShutdownHandler::CallShutdownCommand(time_t WakeupTime, int Channel, const char *File, bool UserShutdown) +{ + time_t Delta = WakeupTime ? WakeupTime - time(NULL) : 0; + cString cmd = cString::sprintf("%s %ld %ld %d \"%s\" %d", shutdownCommand, WakeupTime, Delta, Channel, *strescape(File, "\"$"), UserShutdown); + isyslog("executing '%s'", *cmd); + if (SystemExec(cmd, true) == 0) + Setup.NextWakeupTime = WakeupTime; // Remember this wakeup time for comparison on reboot +} + +void cShutdownHandler::SetUserInactiveTimeout(int Seconds, bool Force) +{ + if (!Setup.MinUserInactivity && !Force) { + activeTimeout = 0; + return; + } + if (Seconds < 0) + Seconds = Setup.MinUserInactivity * 60; + activeTimeout = time(NULL) + Seconds; +} + +bool cShutdownHandler::ConfirmShutdown(bool Interactive) +{ + if (!shutdownCommand) { + if (Interactive) + Skins.Message(mtError, tr("Can't shutdown - option '-s' not given!")); + return false; + } + if (cCutter::Active()) { + if (!Interactive || !Interface->Confirm(tr("Editing - shut down anyway?"))) + return false; + } + + cTimer *timer = Timers.GetNextActiveTimer(); + time_t Next = timer ? timer->StartTime() : 0; + time_t Delta = timer ? Next - time(NULL) : 0; + + if (cRecordControls::Active() || (Next && Delta <= 0)) { + // VPS recordings in timer end margin may cause Delta <= 0 + if (!Interactive || !Interface->Confirm(tr("Recording - shut down anyway?"))) + return false; + } + else if (Next && Delta <= Setup.MinEventTimeout * 60) { + // Timer within Min Event Timeout + if (!Interactive) + return false; + cString buf = cString::sprintf(tr("Recording in %ld minutes, shut down anyway?"), Delta / 60); + if (!Interface->Confirm(buf)) + return false; + } + + if (cPluginManager::Active(Interactive ? tr("shut down anyway?") : NULL)) + return false; + + cPlugin *Plugin = cPluginManager::GetNextWakeupPlugin(); + Next = Plugin ? Plugin->WakeupTime() : 0; + Delta = Next ? Next - time(NULL) : 0; + if (Next && Delta <= Setup.MinEventTimeout * 60) { + // Plugin wakeup within Min Event Timeout + if (!Interactive) + return false; + cString buf = cString::sprintf(tr("Plugin %s wakes up in %ld min, continue?"), Plugin->Name(), Delta / 60); + if (!Interface->Confirm(buf)) + return false; + } + + return true; +} + +bool cShutdownHandler::ConfirmRestart(bool Interactive) +{ + if (cCutter::Active()) { + if (!Interactive || !Interface->Confirm(tr("Editing - restart anyway?"))) + return false; + } + + cTimer *timer = Timers.GetNextActiveTimer(); + time_t Next = timer ? timer->StartTime() : 0; + time_t Delta = timer ? Next - time(NULL) : 0; + + if (cRecordControls::Active() || (Next && Delta <= 0)) { + // VPS recordings in timer end margin may cause Delta <= 0 + if (!Interactive || !Interface->Confirm(tr("Recording - restart anyway?"))) + return false; + } + + if (cPluginManager::Active(Interactive ? tr("restart anyway?") : NULL)) + return false; + + return true; +} + +bool cShutdownHandler::DoShutdown(bool Force) +{ + time_t Now = time(NULL); + cTimer *timer = Timers.GetNextActiveTimer(); + cPlugin *Plugin = cPluginManager::GetNextWakeupPlugin(); + + time_t Next = timer ? timer->StartTime() : 0; + time_t NextPlugin = Plugin ? Plugin->WakeupTime() : 0; + if (NextPlugin && (!Next || Next > NextPlugin)) { + Next = NextPlugin; + timer = NULL; + } + time_t Delta = Next ? Next - Now : 0; + + if (Next && Delta < Setup.MinEventTimeout * 60) { + if (!Force) + return false; + Delta = Setup.MinEventTimeout * 60; + Next = Now + Delta; + timer = NULL; + dsyslog("reboot at %s", *TimeToString(Next)); + } + + if (Next && timer) { + dsyslog("next timer event at %s", *TimeToString(Next)); + CallShutdownCommand(Next, timer->Channel()->Number(), timer->File(), Force); + } + else if (Next && Plugin) { + CallShutdownCommand(Next, 0, Plugin->Name(), Force); + dsyslog("next plugin wakeup at %s", *TimeToString(Next)); + } + else + CallShutdownCommand(Next, 0, "", Force); // Next should always be 0 here. Just for safety, pass it. + + return true; +} diff --git a/shutdown.h b/shutdown.h new file mode 100644 index 0000000..4dff8ea --- /dev/null +++ b/shutdown.h @@ -0,0 +1,112 @@ +/* + * shutdown.h: Handling of shutdown and inactivity + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * Original version written by Udo Richter <udo_richter@gmx.de>. + * + * $Id: shutdown.h 1.1 2007/02/24 17:23:59 kls Exp $ + */ + +#ifndef __SHUTDOWN_H +#define __SHUTDOWN_H + +#include <time.h> + +class cCountdown { +private: + time_t timeout; ///< 5-minute countdown timer + int counter; ///< last shown time in 10s units + bool timedOut; ///< countdown did run down to 0 and was not canceled + const char *message; ///< message to display, %s is placeholder for time +public: + cCountdown(void); + void Start(const char *Message, int Seconds); + ///< Start the 5 minute shutdown warning countdown. + void Cancel(void); + ///< Cancel the 5 minute shutdown warning countdown. + bool Done(void); + ///< Check if countdown timer has run out without canceling. + operator bool(void) const { return timeout != 0; } + ///< Check if countdown is running. + bool Update(void); + ///< Update status display of the countdown. + ///< Returns true on actual update. + }; + +class cShutdownHandler { +private: + time_t activeTimeout; + ///< Time when VDR will become non-interactive. 0 means never. + time_t retry; + ///< Time for retrying the shutdown. + char *shutdownCommand; + ///< Command for shutting down VDR. + int exitCode; + ///< Exit code, if VDR exit was requested, or -1 if not requested. + bool emergencyExitRequested; + ///< The requested exit is an emergency exit. +public: + cCountdown countdown; + cShutdownHandler(void); + ~cShutdownHandler(); + void Exit(int ExitCode) { exitCode = ExitCode; } + ///< Set VDR exit code and initiate end of VDR main loop. + ///< This will exit VDR without any confirmation. + bool DoExit(void) { return exitCode >= 0; } + ///< Check if an exit code was set, and VDR should exit. + int GetExitCode(void) { return exitCode >= 0 ? exitCode : 0; } + ///< Get the currently set exit code of VDR. + bool EmergencyExitRequested(void) { return emergencyExitRequested; } + ///< Returns true if an emergency exit was requested. + void RequestEmergencyExit(void); + ///< Requests an emergency exit of the VDR main loop. + void CheckManualStart(int ManualStart); + ///< Check whether the next timer is in ManualStart time window. + ///< If yes, assume non-interactive use. + void SetShutdownCommand(const char *ShutdownCommand); + ///< Set the command string for shutdown command. + void CallShutdownCommand(time_t WakeupTime, int Channel, const char *File, bool UserShutdown); + ///< Call the shutdown command with the given parameters. + bool IsUserInactive(time_t AtTime = 0) { return activeTimeout && activeTimeout <= (AtTime ? AtTime : time(NULL)); } + ///< Check whether VDR is in interactive mode or non-interactive mode (waiting for shutdown). + ///< AtTime checks whether VDR will probably be inactive at that time. + time_t GetUserInactiveTime(void) { return activeTimeout; } + ///< Time when user will become non-inactive, or 0 if never. + void SetUserInactiveTimeout(int Seconds = -1, bool Force = false); + ///< Set the time when VDR will switch into non-interactive mode or power down. + ///< -1 means Setup.MinUserInactivity in the future. + ///< Otherwise, seconds in the future. + ///< If MinUserInactivity = 0 and Force = false, Seconds is ignored and VDR will + ///< stay interactive forever. + void SetUserInactive(void) { SetUserInactiveTimeout(0, true); } + ///< Set VDR manually into non-interactive mode. + bool Retry(time_t AtTime = 0) { return retry <= (AtTime ? AtTime : time(NULL)); } + ///< Check whether its time to re-try the shutdown. + ///< AtTime checks whether VDR will probably be inactive at that time. + time_t GetRetry(void) { return retry; } + ///< Time when shutdown retry block ends. + void SetRetry(int Seconds) { retry = time(NULL) + Seconds; } + ///< Set shutdown retry so that VDR will not try to automatically shut down + ///< within Seconds. + bool ConfirmShutdown(bool Ask); + ///< Check for background activity that blocks shutdown. + ///< Returns immediately and without user interaction if Ask = false. + ///< Asks for confirmation if Ask = true. + ///< Returns true if ready for shutdown. + bool ConfirmRestart(bool Ask); + ///< Check for background activity that blocks restart. + ///< Returns immediately and without user interaction if Ask = false. + ///< Asks for confirmation if Ask = true. + ///< Returns true if ready for restart. + bool DoShutdown(bool Force); + ///< Call the shutdown script with data of the next pending timer. + ///< Fails if Force = false and a timer is running or within MinEventTimeout. + ///< Always calls shutdown on Force = true. + ///< Returns true on success. + }; + +extern cShutdownHandler ShutdownHandler; + +#endif diff --git a/sources.conf b/sources.conf index 81e5171..7cc105e 100644 --- a/sources.conf +++ b/sources.conf @@ -38,7 +38,7 @@ S38E Paksat 1 S39E Hellas Sat 2 S40E Express AM1 S42E Turksat 1C/2A -S45E PAS 12 +S45E Intelsat 12 S49E Yamal 202 S53E Express AM 22 S55E Insat 3E & Intelsat 702 @@ -48,9 +48,9 @@ S60E Intelsat 904 S62E Intelsat 902 S64E Intelsat 906 S66E Intelsat 704 -S68.5E PAS 7/10 +S68.5E Intelsat 7/10 S70.5E Eutelsat W5 -S72E PAS 4 +S72E Intelsat 4 # Asia @@ -98,8 +98,8 @@ S158E Superbird A S160E Optus B1 S162E Superbird B2 S164E Optus A3 -S166E PAS 8 -S169E PAS 2 +S166E Intelsat 8 +S169E Intelsat 2 S172E AMC 23 S180E Intelsat 701 S177W NSS 5 @@ -125,12 +125,12 @@ S31.5W Intelsat 801 S34.5W Intelsat 903 S37.5W Telstar 11 & AMC 12 S40.5W NSS 806 -S43W PAS 3R/6B -S45W PAS 1R +S43W Intelsat 3R/6B +S45W Intelsat 1R S50W Intelsat 705 S53W Intelsat 707 S55.5W Intelsat 805 -S58W PAS 9 +S58W Intelsat 9 S61W Amazonas # America @@ -151,13 +151,13 @@ S84W Brasilsat B3 S85W AMC 2 S85.1W XM 3 S87W AMC3 -S89W Intelsat Americas 8 +S89W Galaxy 28 S91W Galaxy 11 & Nimiq 1 S91.5W DirecTV 2 S92W Brasilsat B4 -S93W Intelsat Americas 6 +S93W Galaxy 26 S95W Galaxy 3C -S97W Intelsat Americas 5 +S97W Galaxy 25 S99W Galaxy 4R S99.2W Spaceway 2 S101W DirecTV 1R/4S/8 & AMC4 @@ -168,11 +168,11 @@ S110W DirecTV 5 & Echostar 6/8/10 S111.1W Anik F2 S113W Solidaridad 2 S119W Echostar 7 & DirecTV 7S -S121W Echostar 9 & Intelsat Americas 13 +S121W Echostar 9 & Galaxy 23 S123W Galaxy 10R S125W Galaxy 14 S127W Galaxy 13/Horizons 1 -S129W Echostar 5 & Intelsat Americas 7 +S129W Echostar 5 & Galaxy 27 S131W AMC 11 S133W Galaxy15/1R S135W AMC 10 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.c 1.59 2007/01/05 10:44:22 kls Exp $ + * $Id: thread.c 1.60 2007/02/24 16:13:33 kls Exp $ */ #include "thread.h" @@ -200,7 +200,6 @@ void cMutex::Unlock(void) // --- cThread --------------------------------------------------------------- tThreadId cThread::mainThreadId = 0; -bool cThread::emergencyExitRequested = false; cThread::cThread(const char *Description) { @@ -320,14 +319,6 @@ void cThread::Cancel(int WaitSeconds) } } -bool cThread::EmergencyExit(bool Request) -{ - if (!Request) - return emergencyExitRequested; - esyslog("initiating emergency exit"); - return emergencyExitRequested = true; // yes, it's an assignment, not a comparison! -} - tThreadId cThread::ThreadId(void) { return syscall(__NR_gettid); @@ -505,7 +496,7 @@ int cPipe::Close(void) // --- SystemExec ------------------------------------------------------------ -int SystemExec(const char *Command) +int SystemExec(const char *Command, bool Detached) { pid_t pid; @@ -515,14 +506,24 @@ int SystemExec(const char *Command) } if (pid > 0) { // parent process - int status; - if (waitpid(pid, &status, 0) < 0) { + int status = 0; + if (!Detached && waitpid(pid, &status, 0) < 0) { LOG_ERROR; return -1; } return status; } else { // child process + if (Detached) { + // Start a new session + pid_t sid = setsid(); + if (sid < 0) + LOG_ERROR; + // close STDIN and re-open as /dev/null + int devnull = open("/dev/null", O_RDONLY); + if (devnull < 0 || dup2(devnull, 0) < 0) + LOG_ERROR; + } int MaxPossibleFileDescriptors = getdtablesize(); for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++) close(i); //close all dup'ed filedescriptors @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.h 1.38 2007/01/05 10:44:38 kls Exp $ + * $Id: thread.h 1.39 2007/02/24 16:13:28 kls Exp $ */ #ifndef __THREAD_H @@ -84,7 +84,6 @@ private: cMutex mutex; char *description; static tThreadId mainThreadId; - static bool emergencyExitRequested; static void *StartThread(cThread *Thread); protected: void SetPriority(int Priority); @@ -118,7 +117,6 @@ public: ///< If the thread is already running, nothing happens. bool Active(void); ///< Checks whether the thread is still alive. - static bool EmergencyExit(bool Request = false); static tThreadId ThreadId(void); static tThreadId IsMainThread(void) { return ThreadId() == mainThreadId; } static void SetMainThreadId(void); @@ -175,7 +173,9 @@ public: // SystemExec() implements a 'system()' call that closes all unnecessary file // descriptors in the child process. +// With Detached=true, calls command in background and in a separate session, +// with stdin connected to /dev/null. -int SystemExec(const char *Command); +int SystemExec(const char *Command, bool Detached = false); #endif //__THREAD_H @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.1 1.28 2007/01/07 14:03:56 kls Exp $ +.\" $Id: vdr.1 1.29 2007/02/24 17:40:20 kls Exp $ .\" .TH vdr 1 "07 Jan 2007" "1.4.5" "Video Disk Recorder" .SH NAME @@ -153,6 +153,14 @@ Print version information and exit. .BI \-w\ sec ,\ \-\-watchdog= sec Activate the watchdog timer with a timeout of \fIsec\fR seconds. A value of \fB0\fR (default) disables the watchdog. +.SH SIGNALS +.TP +.B SIGINT, SIGTERM +Program exits with status 0. +.TP +.B SIGHUP +Program exits with status 1. This can be used to force a reload, for example +if an update has been installed. .SH EXIT STATUS .TP .B 0 @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/vdr * - * $Id: vdr.c 1.283 2007/01/05 10:46:14 kls Exp $ + * $Id: vdr.c 1.285 2007/02/25 11:27:36 kls Exp $ */ #include <getopt.h> @@ -54,6 +54,7 @@ #include "plugin.h" #include "rcu.h" #include "recording.h" +#include "shutdown.h" #include "skinclassic.h" #include "skinsttng.h" #include "sources.h" @@ -66,20 +67,23 @@ #define MINCHANNELWAIT 10 // seconds to wait between failed channel switchings #define ACTIVITYTIMEOUT 60 // seconds before starting housekeeping #define SHUTDOWNWAIT 300 // seconds to wait in user prompt before automatic shutdown +#define SHUTDOWNRETRY 360 // seconds before trying again to shut down +#define SHUTDOWNFORCEPROMPT 5 // seconds to wait in user prompt to allow forcing shutdown +#define SHUTDOWNCANCELROMPT 5 // seconds to wait in user prompt to allow canceling shutdown +#define RESTARTCANCELPROMPT 5 // seconds to wait in user prompt before restarting on SIGHUP #define MANUALSTART 600 // seconds the next timer must be in the future to assume manual start #define CHANNELSAVEDELTA 600 // seconds before saving channels.conf after automatic modifications #define DEVICEREADYTIMEOUT 30 // seconds to wait until all devices are ready #define MENUTIMEOUT 120 // seconds of user inactivity after which an OSD display is closed -#define SHUTDOWNRETRY 300 // seconds before trying again to shut down #define TIMERCHECKDELTA 10 // seconds between checks for timers that need to see their channel #define TIMERDEVICETIMEOUT 8 // seconds before a device used for timer check may be reused #define TIMERLOOKAHEADTIME 60 // seconds before a non-VPS timer starts and the channel is switched if possible #define VPSLOOKAHEADTIME 24 // hours within which VPS timers will make sure their events are up to date #define VPSUPTODATETIME 3600 // seconds before the event or schedule of a VPS timer needs to be refreshed -#define EXIT(v) { ExitCode = (v); goto Exit; } +#define EXIT(v) { ShutdownHandler.Exit(v); goto Exit; } -static int Interrupted = 0; +static int LastSignal = 0; static bool SetUser(const char *UserName) { @@ -138,10 +142,18 @@ static bool SetKeepCaps(bool On) static void SignalHandler(int signum) { - if (signum != SIGPIPE) { - Interrupted = signum; - Interface->Interrupt(); - } + isyslog("caught signal %d", signum); + switch (signum) { + case SIGPIPE: + break; + case SIGHUP: + LastSignal = signum; + break; + default: + LastSignal = signum; + Interface->Interrupt(); + ShutdownHandler.Exit(0); + } signal(signum, SignalHandler); } @@ -184,7 +196,6 @@ int main(int argc, char *argv[]) bool MuteAudio = false; int WatchdogTimeout = DEFAULTWATCHDOG; const char *Terminal = NULL; - const char *Shutdown = NULL; bool UseKbd = true; const char *LircDevice = NULL; @@ -205,7 +216,6 @@ int main(int argc, char *argv[]) #endif cPluginManager PluginManager(DEFAULTPLUGINDIR); - int ExitCode = 0; static struct option long_options[] = { { "audio", required_argument, NULL, 'a' }, @@ -313,7 +323,7 @@ int main(int argc, char *argv[]) break; case 'r': cRecordingUserCommand::SetCommand(optarg); break; - case 's': Shutdown = optarg; + case 's': ShutdownHandler.SetShutdownCommand(optarg); break; case 't': Terminal = optarg; if (access(Terminal, R_OK | W_OK) < 0) { @@ -498,10 +508,7 @@ int main(int argc, char *argv[]) int PreviousChannel[2] = { 1, 1 }; int PreviousChannelIndex = 0; time_t LastChannelChanged = time(NULL); - time_t LastActivity = 0; int MaxLatencyTime = 0; - bool ForceShutdown = false; - bool UserShutdown = false; bool InhibitEpgScan = false; bool IsInfoMenu = false; cSkin *CurrentSkin = NULL; @@ -596,6 +603,10 @@ int main(int argc, char *argv[]) } } + // Check for timers in automatic start time window: + + ShutdownHandler.CheckManualStart(MANUALSTART); + // User interface: Interface = new cInterface(SVDRPport); @@ -668,12 +679,7 @@ int main(int argc, char *argv[]) #define DELETE_MENU ((IsInfoMenu &= (Menu == NULL)), delete Menu, Menu = NULL) - while (!Interrupted) { - // Handle emergency exits: - if (cThread::EmergencyExit()) { - esyslog("emergency exit requested - shutting down"); - break; - } + while (!ShutdownHandler.DoExit()) { #ifdef DEBUGRINGBUFFERS cRingBufferLinear::PrintDebugRBL(); #endif @@ -856,9 +862,13 @@ int main(int argc, char *argv[]) // User Input: cOsdObject *Interact = Menu ? Menu : cControl::Control(); eKeys key = Interface->GetKey(!Interact || !Interact->NeedsFastResponse()); - if (NORMALKEY(key) != kNone) { + if (ISREALKEY(key)) { EITScanner.Activity(); - LastActivity = time(NULL); + // Cancel shutdown countdown: + if (ShutdownHandler.countdown) + ShutdownHandler.countdown.Cancel(); + // Set user active for MinUserInactivity time in the future: + ShutdownHandler.SetUserInactiveTimeout(); } // Keys that must work independent of any interactive mode: switch (key) { @@ -875,7 +885,7 @@ int main(int argc, char *argv[]) else WasOpen = false; } - if (!WasOpen || !WasMenu && !Setup.MenuButtonCloses) + if (!WasOpen || !WasMenu && !Setup.MenuKeyCloses) Menu = new cMenuMain; } break; @@ -996,37 +1006,32 @@ int main(int argc, char *argv[]) } break; // Power off: - case kPower: { + case kPower: isyslog("Power button pressed"); DELETE_MENU; - if (!Shutdown) { - Skins.Message(mtError, tr("Can't shutdown - option '-s' not given!")); + // Check for activity, request power button again if active: + if (!ShutdownHandler.ConfirmShutdown(false) && Skins.Message(mtWarning, tr("VDR will shut down later - press Power to force"), SHUTDOWNFORCEPROMPT) != kPower) { + // Not pressed power - set VDR to be non-interactive and power down later: + ShutdownHandler.SetUserInactive(); break; } - LastActivity = 1; // not 0, see below! - UserShutdown = true; - if (cRecordControls::Active()) { - if (!Interface->Confirm(tr("Recording - shut down anyway?"))) - break; - } - if (cPluginManager::Active(tr("shut down anyway?"))) + // No activity or power button pressed twice - ask for confirmation: + if (!ShutdownHandler.ConfirmShutdown(true)) { + // Non-confirmed background activity - set VDR to be non-interactive and power down later: + ShutdownHandler.SetUserInactive(); break; - if (!cRecordControls::Active()) { - cTimer *timer = Timers.GetNextActiveTimer(); - time_t Next = timer ? timer->StartTime() : 0; - time_t Delta = timer ? Next - time(NULL) : 0; - if (Next && Delta <= Setup.MinEventTimeout * 60) { - char *buf; - asprintf(&buf, tr("Recording in %ld minutes, shut down anyway?"), Delta / 60); - bool confirm = Interface->Confirm(buf); - free(buf); - if (!confirm) - break; - } } - ForceShutdown = true; + // Ask the final question: + if (!Interface->Confirm(tr("Press any key to cancel shutdown"), SHUTDOWNCANCELROMPT, true)) + // If final question was canceled, continue to be active: + break; + // Ok, now call the shutdown script: + ShutdownHandler.DoShutdown(true); + // Set VDR to be non-interactive and power down again later: + ShutdownHandler.SetUserInactive(); + // Do not attempt to automatically shut down for a while: + ShutdownHandler.SetRetry(SHUTDOWNRETRY); break; - } default: break; } Interact = Menu ? Menu : cControl::Control(); // might have been closed in the mean time @@ -1041,7 +1046,7 @@ int main(int argc, char *argv[]) continue; } } - else if (time(NULL) - LastActivity > MENUTIMEOUT) + else if (time(NULL) - cRemote::LastActivity() > MENUTIMEOUT) state = osEnd; } switch (state) { @@ -1143,77 +1148,55 @@ int main(int argc, char *argv[]) Skins.Message(mtInfo, tr("Editing process finished")); } } - if (!Interact && ((!cRecordControls::Active() && !cCutter::Active() && (!Interface->HasSVDRPConnection() || UserShutdown)) || ForceShutdown)) { - time_t Now = time(NULL); - if (Now - LastActivity > ACTIVITYTIMEOUT) { - // Shutdown: - if (Shutdown && (Setup.MinUserInactivity || LastActivity == 1) && Now - LastActivity > Setup.MinUserInactivity * 60) { - cTimer *timer = Timers.GetNextActiveTimer(); - time_t Next = timer ? timer->StartTime() : 0; - time_t Delta = timer ? Next - Now : 0; - if (!LastActivity) { - if (!timer || Delta > MANUALSTART) { - // Apparently the user started VDR manually - dsyslog("assuming manual start of VDR"); - LastActivity = Now; - continue; // don't run into the actual shutdown procedure below - } - else - LastActivity = 1; - } - if (timer && Delta < Setup.MinEventTimeout * 60 && ForceShutdown) { - Delta = Setup.MinEventTimeout * 60; - Next = Now + Delta; - timer = NULL; - dsyslog("reboot at %s", *TimeToString(Next)); - } - if (!ForceShutdown && cPluginManager::Active()) { - LastActivity = Now - Setup.MinUserInactivity * 60 + SHUTDOWNRETRY; // try again later - continue; - } - if (!Next || Delta > Setup.MinEventTimeout * 60 || ForceShutdown) { - ForceShutdown = false; - if (timer) - dsyslog("next timer event at %s", *TimeToString(Next)); - if (WatchdogTimeout > 0) - signal(SIGALRM, SIG_IGN); - if (Interface->Confirm(tr("Press any key to cancel shutdown"), UserShutdown ? 5 : SHUTDOWNWAIT, true)) { - cControl::Shutdown(); - int Channel = timer ? timer->Channel()->Number() : 0; - const char *File = timer ? timer->File() : ""; - if (timer) - Delta = Next - time(NULL); // compensates for Confirm() timeout - char *cmd; - asprintf(&cmd, "%s %ld %ld %d \"%s\" %d", Shutdown, Next, Delta, Channel, *strescape(File, "\"$"), UserShutdown); - isyslog("executing '%s'", cmd); - SystemExec(cmd); - free(cmd); - LastActivity = time(NULL) - Setup.MinUserInactivity * 60 + SHUTDOWNRETRY; // try again later - } - else { - LastActivity = Now; - if (WatchdogTimeout > 0) { - alarm(WatchdogTimeout); - if (signal(SIGALRM, Watchdog) == SIG_IGN) - signal(SIGALRM, SIG_IGN); - } - } - UserShutdown = false; - continue; // skip the rest of the housekeeping for now - } - } - // Disk housekeeping: - RemoveDeletedRecordings(); - cSchedules::Cleanup(); - // Plugins housekeeping: - PluginManager.Housekeeping(); + + // SIGHUP shall cause a restart: + if (LastSignal == SIGHUP) { + if (ShutdownHandler.ConfirmRestart(true) && Interface->Confirm(tr("Press any key to cancel restart"), RESTARTCANCELPROMPT, true)) + EXIT(1); + LastSignal = 0; + } + + // Update the shutdown countdown: + if (ShutdownHandler.countdown && ShutdownHandler.countdown.Update()) { + if (!ShutdownHandler.ConfirmShutdown(false)) + ShutdownHandler.countdown.Cancel(); + } + + if (!Interact && !cRecordControls::Active() && !cCutter::Active() && !Interface->HasSVDRPConnection() && cRemote::LastActivity() > ACTIVITYTIMEOUT) { + // Handle housekeeping tasks + + // Shutdown: + // Check whether VDR will be ready for shutdown in SHUTDOWNWAIT seconds: + time_t Soon = time(NULL) + SHUTDOWNWAIT; + if (ShutdownHandler.IsUserInactive(Soon) && ShutdownHandler.Retry(Soon) && !ShutdownHandler.countdown) { + if (ShutdownHandler.ConfirmShutdown(false)) + // Time to shut down - start final countdown: + ShutdownHandler.countdown.Start(tr("VDR will shut down in %s minutes"), SHUTDOWNWAIT); // the placeholder is really %s! + // Dont try to shut down again for a while: + ShutdownHandler.SetRetry(SHUTDOWNRETRY); } + // Countdown run down to 0? + if (ShutdownHandler.countdown.Done()) { + // Timed out, now do a final check: + if (ShutdownHandler.IsUserInactive() && ShutdownHandler.ConfirmShutdown(false)) + ShutdownHandler.DoShutdown(false); + // Do this again a bit later: + ShutdownHandler.SetRetry(SHUTDOWNRETRY); + } + + // Disk housekeeping: + RemoveDeletedRecordings(); + cSchedules::Cleanup(); + // Plugins housekeeping: + PluginManager.Housekeeping(); } + // Main thread hooks of plugins: PluginManager.MainThreadHook(); } - if (Interrupted) - isyslog("caught signal %d", Interrupted); + + if (ShutdownHandler.EmergencyExitRequested()) + esyslog("emergency exit requested - shutting down"); Exit: @@ -1227,7 +1210,7 @@ Exit: Remotes.Clear(); Audios.Clear(); Skins.Clear(); - if (ExitCode != 2) { + if (ShutdownHandler.GetExitCode() != 2) { Setup.CurrentChannel = cDevice::CurrentChannel(); Setup.CurrentVolume = cDevice::CurrentVolume(); Setup.Save(); @@ -1238,14 +1221,12 @@ Exit: ReportEpgBugFixStats(); if (WatchdogTimeout > 0) dsyslog("max. latency time %d seconds", MaxLatencyTime); - isyslog("exiting"); + isyslog("exiting, exit code %d", ShutdownHandler.GetExitCode()); + if (ShutdownHandler.EmergencyExitRequested()) + esyslog("emergency exit!"); if (SysLogLevel > 0) closelog(); if (HasStdin) tcsetattr(STDIN_FILENO, TCSANOW, &savedTm); - if (cThread::EmergencyExit()) { - esyslog("emergency exit!"); - return 1; - } - return ExitCode; + return ShutdownHandler.GetExitCode(); } |