diff options
-rw-r--r-- | CONTRIBUTORS | 24 | ||||
-rw-r--r-- | HISTORY | 43 | ||||
-rw-r--r-- | INSTALL | 17 | ||||
-rw-r--r-- | channels.conf | 23 | ||||
-rw-r--r-- | config.h | 6 | ||||
-rw-r--r-- | cutter.c | 4 | ||||
-rw-r--r-- | device.c | 7 | ||||
-rw-r--r-- | device.h | 8 | ||||
-rw-r--r-- | dvbdevice.c | 17 | ||||
-rw-r--r-- | dvbdevice.h | 3 | ||||
-rw-r--r-- | dvbosd.c | 16 | ||||
-rw-r--r-- | dvbosd.h | 16 | ||||
-rw-r--r-- | dvbplayer.c | 8 | ||||
-rw-r--r-- | dvbspu.h | 8 | ||||
-rw-r--r-- | menu.c | 61 | ||||
-rw-r--r-- | menu.h | 4 | ||||
-rw-r--r-- | menuitems.c | 4 | ||||
-rw-r--r-- | osd.c | 12 | ||||
-rw-r--r-- | osd.h | 6 | ||||
-rw-r--r-- | player.h | 3 | ||||
-rw-r--r-- | recording.c | 132 | ||||
-rw-r--r-- | recording.h | 15 | ||||
-rw-r--r-- | ringbuffer.c | 3 | ||||
-rw-r--r-- | ringbuffer.h | 4 | ||||
-rw-r--r-- | spu.h | 5 | ||||
-rw-r--r-- | svdrp.c | 6 | ||||
-rw-r--r-- | themes.c | 6 | ||||
-rw-r--r-- | tools.c | 10 | ||||
-rw-r--r-- | tools.h | 3 | ||||
-rw-r--r-- | vdr.1 | 6 | ||||
-rw-r--r-- | vdr.c | 27 |
31 files changed, 366 insertions, 141 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index d6f34f1..ace8e91 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -376,6 +376,7 @@ Ruben Nunez Francisco <ruben.nunez@tang-it.com> Mirko Dölle <mdoelle@linux-user.de> for reporting a bug when a timer records over midnight of a day that had a change in Daylight Saving Time + for suggesting to avoid the external 'find' command to scan the video directory Michael Rakowski <mrak@gmx.de> for translating OSD texts to the Polish language @@ -639,6 +640,7 @@ Sven Goethel <sgoethel@jausoft.com> for making switching audio channels work without stopping/restarting the DMX for fixing initializing the highlight area in cDvbSpuDecoder for suggesting to add cDevice::GetSTC() + for making some changes to the SPU decoder interface Jan Rieger <jan@ricomp.de> for suggestions and testing raw keyboard input @@ -718,6 +720,7 @@ Sascha Volkenandt <sascha@akv-soft.de> for suggesting to allow drawing "transparent" texts for suggesting to ignore unused "none" color entries in XPM files written by some broken graphics tools + for fixing a memory leak in theme description handling Malcolm Caldwell <malcolm.caldwell@ntu.edu.au> for modifying LOF handling to allow for C-band reception @@ -730,6 +733,9 @@ Ludwig Nussel <ludwig.nussel@web.de> for reporting a problem with the LIRC remote control trying to learn keys even if it couldn't connect to the LIRC daemon for making the plugin library directory configurable via Make.config + for reporting a problem on systems that have UTF-8 enabled + for pointing out a flaw in the the description of cRingBufferLinear + for reporting a bug in cRingBufferLinear::Get() in case the buffer wraps around Thomas Koch <tom@harhar.net> for his support in keeping the Premiere World channels up to date in 'channels.conf' @@ -850,6 +856,8 @@ Reinhard Nissl <rnissl@gmx.de> when using other libraries that also implement a function by that name for reporting a bug in handling ':' characters in channel names when reading channels.conf + for adding cDevice::Flush() to make sure that all data in the video card's buffers + has been processed Richard Robson <richard_robson@beeb.net> for reporting freezing replay if a timer starts while in Transfer Mode from the @@ -1024,3 +1032,19 @@ Jürgen Schmitz <j.schmitz@web.de> Philip Lawatsch <philip@lawatsch.at> for debugging a buffer overflow in eit.c + +Jouni Karvo <kex@netlab.hut.fi> + for suggesting to make the cOsd constructor 'protected' + +Olaf Henkel <olafhenkel@t-online.de> + for reporting a problem with long event texts in the "Classic VDR" skin + +Martin Dauskardt <md001@gmx.de> + for reporting a problem with switching channels while an encrypted channel is being + recorded + +Maynard Cedric <maynard.cedric@wanadoo.fr> + for reporting a problem in handling the color button texts in cMenuEditStrItem + +Jörg Knitter <joerg.knitter@gmx.de> + for reporting a problem in case the video partition is mounted with "iocharset=utf8" @@ -2892,3 +2892,46 @@ Video Disk Recorder Revision History - Modified 'libsi' to require callers to state the buffer sizes when getting strings in order to avoid buffer overflows (thanks to Philip Lawatsch for debugging a buffer overflow in eit.c). + +2004-06-19: Version 1.3.11 + +- In order to avoid problems on NPTL systems, VDR now checks for the presence + of NPTL at program start, and if it is, exits and tells the user to do + 'export LD_ASSUME_KERNEL=2.4.1' before starting VDR. +- Revisited the "Fixed missing audio after replaying a DVD" change because it + introduced a sound disturbance when switching between channels on the same + transponder (thanks to Marco Schlüßler). +- In order to avoid problems on UTF-8 systems, VDR now checks for the presence + of UTF-8 at program start, and if it is, exits and tells the user to turn off + UTF-8 before starting VDR (thanks to Ludwig Nussel for pointing out a problem + with systems that are set to use UTF-8). There are also problems in case the + video partition is mounted with "iocharset=utf8" (thanks to Jörg Knitter for + reporting this one). + Please also read the "IMPORTANT NOTES" section in the INSTALL file! +- Some changes to the SPU decoder interface (thanks to Sven Goethel). +- Some improvements in cOsd creation (thanks to some suggestions by Jouni Karvo). +- Fixed calculating the OSD width and height (thanks to Olaf Henkel for reporting + a problem with long event texts in the "Classic VDR" skin). +- Fixed switching channels while an encrypted channel is being recorded, because the + channel was switched if the new channel was on the same transponder and was + a radio channel or an unencrypted channel (thanks to Martin Dauskardt for reporting + this one). +- No longer using the external 'find' command to scan the video directory for + recordings (based on a suggestion by Mirko Dölle). +- The list of recordings is now kept statically in memory to avoid long delays + when opening the "Recordings" menu. As a side effect, external modifications to + the video directory are no longer immediately reflected in the "Recordings" menu. + If a plugin manipulates the video directory in any way, it can call the function + Recordings.TriggerUpdate() to trigger an update of the list of recordings. + If some external tool manipulates the video directory, it can touch the file + '.update' in the video directory to trigger an update of the list of recordings. +- Fixed a memory leak in theme description handling (thanks to Sascha Volkenandt). +- Added cDevice::Flush() to make sure that all data in the video card's buffers + has been processed (thanks to Reinhard Nissl). Currently this is not yet actually + implemented for FF DVB cards. +- Fixed handling the color button texts in cMenuEditStrItem (thanks to Maynard + Cedric for reporting this one). +- Fixed the description of cRingBufferLinear (thanks to Ludwig Nussel for pointing + out this one). +- Fixed cRingBufferLinear::Get() in case the buffer wraps around (thanks to Ludwig + Nussel for reporting this one). @@ -4,8 +4,8 @@ Installation of the Video Disk Recorder Version 1.3 ----------- -IMPORTANT NOTE: ---------------- +IMPORTANT NOTES: +---------------- VDR currently doesn't work with NPTL ("Native Posix Thread Library"). Either don't use NPTL, or set the environment variable @@ -14,6 +14,19 @@ Either don't use NPTL, or set the environment variable before running VDR. +Also, please make sure your environment is NOT set to use UTF-8 or +any other multibyte character representation. Check the value of your +$LANG or $LC_CTYPE environment variable, and if it contains something +like "de_DE.UTF-8", make sure you set it to something like "de_DE.iso8859-1" +or whatever single byte character mode you want. If you run VDR with +UTF-8 enabled, it may crash in case it encounters EPG or channel data +that contains non-7-bit ASCII characters. Another problem may occur if +you have mounted your video partition with "iocharset=utf8". In that case +recordings that contain umlauts or other non-seven-bit ASCII characters +may be displayed wrong, or not at all. Please make sure you mount your +video partition with "iocharset=iso8859-1" or whatever single byte character +mode you want. + Compiling and running the program: ---------------------------------- diff --git a/channels.conf b/channels.conf index 8ce6917..5a36b9e 100644 --- a/channels.conf +++ b/channels.conf @@ -28,7 +28,7 @@ HSE24:12480:vC34:S19.2E:27500:1279:1280:37:0:40:133:33:0 Bloomberg TV Germany:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:1108:0 EURONEWS:11817:vC34:S19.2E:27500:163:92=fra,93=eng,94=ita,95=esl,91=rus,98=por,99=deu:0:0:8004:1:1070:0 rbb Brandenburg:12109:hC34:S19.2E:27500:501:502=deu:504:0:28205:1:1073:0 -Sky News Intl:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0 +Sky News:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0 Veronica/FoxKids:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,602,100:5020:53:1109:0 BVN:12574:hC56:S19.2E:22000:515+8190:96=dut:36:0:5025:53:1109:0 CNBC Europe:12610:vC56:S19.2E:22000:944:945=eng:946:0:12200:1:1112:0 @@ -45,13 +45,13 @@ MDR FERNSEHEN:12109:hC34:S19.2E:27500:401:402=deu:404:0:28204:1:1073:0 rbb Berlin:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0 :Premiere World START,PREMIERE START:11797:hC34:S19.2E:27500:255:256=deu:32:1702,1801,1722:8:133:2:0 -PREM 1,PREMIERE 1:11797:hC34:S19.2E:27500:511:512=deu;515=deu:32:1801,1702,1722:10:133:2:0 +PREM 1,PREMIERE 1:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1722,1801,1702:10:133:2:0 PREM 2,PREMIERE 2:11797:hC34:S19.2E:27500:1791:1792=deu;1795=deu:32:1722,1801,1702:11:133:2:0 PREM 3,PREMIERE 3:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1801,1702:43:133:2:0 PREM 4,PREMIERE 4:11797:hC34:S19.2E:27500:767:768=deu:32:1801,1722,1702:9:133:2:0 -PREM 5,PREMIERE 5:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:32:1722,1702,1801:29:133:2:0 -PREM 6,PREMIERE 6:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1801,1722:41:133:2:0 -PREM 7,PREMIERE 7:11797:hC34:S19.2E:27500:1023:1024=deu:32:1722,1801,1702:20:133:2:0 +PREM 5,PREMIERE 5:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:32:1722,1801,1702:29:133:2:0 +PREM 6,PREMIERE 6:11797:hC34:S19.2E:27500:1535:1536=deu:32:1722,1801,1702:41:133:2:0 +PREM 7,PREMIERE 7:11797:hC34:S19.2E:27500:1023:1024=deu:32:1801,1722,1702:20:133:2:0 DISNEY,DISNEY CHANNEL:11758:hC34:S19.2E:27500:2559:2560=deu:0:1722,1702,1801:34:133:17:0 :Premiere Direkt DIREKT,PREMIERE DIREKT:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0:0:18:133:4:0 @@ -59,8 +59,8 @@ DIREKT,PREMIERE DIREKT:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0 B-UHSE,BEATE-UHSE.TV:12070:hC34:S19.2E:27500:1023:1024=deu:32:1801,1702,1722:21:133:1:0 EROTIK,PREMIERE EROTIK:12031:hC34:S19.2E:27500:1279:0:0:1722,1702,1801:513:133:4:0 :Sportsworld -SPORT 1,PREMIERE SPORT 1:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1702,1722,1801:17:133:3:0 -SPORT 2,PREMIERE SPORT 2:12031:hC34:S19.2E:27500:3839:3840=deu,3841=deu:32:1702,1722,1801:27:133:4:0 +F1-Portal:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1801,1702,1722:17:133:3:0 +SPORT 2,PREMIERE SPORT 2:12031:hC34:S19.2E:27500:3839:3840=deu:32:1702,1722,1801:27:133:4:0 :Beta Digital N24:12480:vC34:S19.2E:27500:2047:2048:36:0:47:133:33:0 Liberty TV.com:12610:vC56:S19.2E:22000:941:943=deu:0:0:12199:1:1112:0 @@ -95,14 +95,14 @@ ITV2:10906:vC56:S28.2E:22000:2348:2349=eng,2350=eng:2351:960,961:10240:2:2054:0 Sci-Fi:12148:hC23:S28.2E:27500:2314+2304:2315=eng:2316:960,961:4905:2:2023:0 Paramount:12187:hC23:S28.2E:27500:2313+2304:2314=eng:2315:960,961:5904:2:2025:0 Discovery:11875:hC23:S28.2E:27500:2304:2306=eng:2305:960,961:6201:2:2009:0 -Sky Movies 1:11836:hC23:S28.2E:27500:2309+2304:2310=eng,2311=NAR;2313=eng:2312:960,961:4303:2:2007:0 -Sky Movies 2:11836:hC23:S28.2E:27500:2305+2304:2306=eng,2307=NAR;2323=eng:2308:960,961:4302:2:2007:0 -Sky Movies 3:11836:hC23:S28.2E:27500:2314+2304:2315=eng,2316=NAR;2318=eng:2317:960,961:4403:2:2007:0 +Sky Movies 1:11836:hC23:S28.2E:27500:2310+2304:2311=eng,2312=NAR;2314=eng:2313:960,961:4303:2:2007:0 +Sky Movies 2:11836:hC23:S28.2E:27500:2305+2304:2306=eng,2307=NAR;2309=eng:2308:960,961:4302:2:2007:0 +Sky Movies 3:11836:hC23:S28.2E:27500:2315+2304:2316=eng,2317=NAR;2319=eng:2318:960,961:4403:2:2007:0 Sky Movies 4:11914:hC23:S28.2E:27500:2305+2304:2306=eng,2307=NAR:2308:960,961:4402:2:2011:0 Sky Movies 5:11914:hC23:S28.2E:27500:2313+2304:2314=eng,2315=NAR:2316:960,961:4503:2:2011:0 Sky Movies 6:11914:hC23:S28.2E:27500:2309+2304:2310=eng,2311=NAR:2312:960,961:4502:2:2011:0 Sky Movies 7:12090:vC23:S28.2E:27500:2312+2304:2313=eng,2314=NAR:2315:960,961:4603:2:2020:0 -Sky Movies 8:11836:hC23:S28.2E:27500:2319+2304:2320=eng,2321=NAR:2322:960,961:5502:2:2007:0 +Sky Movies 8:11836:hC23:S28.2E:27500:2320+2304:2321=eng,2322=NAR:2323:960,961:5502:2:2007:0 Sky Movies 9:12090:vC23:S28.2E:27500:2308+2304:2309=eng,2310=NAR:2311:960,961:4602:2:2020:0 Sky Cinema 1:12090:vC23:S28.2E:27500:2305+2304:2306=eng:2307:960,961:4809:2:2020:0 Sky Cinema 2:12090:vC23:S28.2E:27500:2316+2304:2317=eng:2318:960,961:4802:2:2020:0 @@ -116,4 +116,5 @@ CNN:12051:vC23:S28.2E:27500:2313:2315=eng:2314:0:7140:2:2018:0 BBC PARL'MNT:12129:vC23:S28.2E:27500:2304:2306=eng,2307=eng:2305:0:7300:2:2022:0 AL HAYAT:11200:vC56:S13.0E:27500:413:414:0:0:4733:318:13400:0 EURO1080:12168:vC34:S19.2E:27500:308:256:0:FF:21100:1:1088:0 +Astra HD:12441:vC34:S19.2E:27500:133+80:134:0:FF:29700:0:0:0 :@1000 New channels @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.197 2004/06/05 10:06:50 kls Exp $ + * $Id: config.h 1.198 2004/06/10 13:18:50 kls Exp $ */ #ifndef __CONFIG_H @@ -20,8 +20,8 @@ #include "i18n.h" #include "tools.h" -#define VDRVERSION "1.3.10" -#define VDRVERSNUM 10310 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.3.11" +#define VDRVERSNUM 10311 // Version * 10000 + Major * 100 + Minor #define MAXPRIORITY 99 #define MAXLIFETIME 99 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: cutter.c 1.6 2003/10/18 11:29:37 kls Exp $ + * $Id: cutter.c 1.7 2004/06/13 16:04:08 kls Exp $ */ #include "cutter.h" @@ -205,6 +205,7 @@ bool cCutter::Start(const char *FileName) // XXX editedVersionName = strdup(evn); Recording.WriteSummary(); + Recordings.AddByName(editedVersionName); cuttingThread = new cCuttingThread(FileName, editedVersionName); return true; } @@ -224,6 +225,7 @@ void cCutter::Stop(void) if (Error) esyslog("ERROR: '%s' during editing process", Error); RemoveVideoFile(editedVersionName); //XXX what if this file is currently being replayed? + Recordings.DelByName(editedVersionName); } } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 1.55 2004/05/16 12:14:47 kls Exp $ + * $Id: device.c 1.56 2004/06/19 08:51:05 kls Exp $ */ #include "device.h" @@ -619,6 +619,11 @@ bool cDevice::Poll(cPoller &Poller, int TimeoutMs) return false; } +bool cDevice::Flush(int TimeoutMs) +{ + return true; +} + int cDevice::PlayVideo(const uchar *Data, int Length) { return -1; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 1.43 2004/05/23 10:10:08 kls Exp $ + * $Id: device.h 1.44 2004/06/19 08:50:37 kls Exp $ */ #ifndef __DEVICE_H @@ -373,6 +373,12 @@ public: ///< If TimeoutMs is not zero, the device will wait up to the given number ///< of milleseconds before returning in case there is no immediate ///< need for data. + virtual bool Flush(int TimeoutMs = 0); + ///< Returns true if the device's output buffers are empty, i. e. any + ///< data which was bufferd so far has been processed. + ///< If TimeoutMs is not zero, the device will wait up to the given + ///< number of milliseconds before returning in case there is still + ///< data in the buffers.. virtual int PlayVideo(const uchar *Data, int Length); ///< Actually plays the given data block as video. The data must be ///< part of a PES (Packetized Elementary Stream) which can contain diff --git a/dvbdevice.c b/dvbdevice.c index e5b777d..8334801 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.89 2004/06/06 11:28:28 kls Exp $ + * $Id: dvbdevice.c 1.93 2004/06/19 09:33:42 kls Exp $ */ #include "dvbdevice.h" @@ -682,9 +682,9 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne result = hasPriority; if (Priority >= 0 && Receiving(true)) { if (dvbTuner->IsTunedTo(Channel)) { - if (!HasPid(Channel->Vpid())) { + if (Channel->Vpid() && !HasPid(Channel->Vpid()) || Channel->Apid1() && !HasPid(Channel->Apid1())) { #ifdef DO_MULTIPLE_RECORDINGS - if (Channel->Ca() > CACONFBASE) + if (Ca() > CACONFBASE || Channel->Ca() > CACONFBASE) needsDetachReceivers = !ciHandler // only LL-firmware can do non-live CA channels || Ca() != Channel->Ca(); else if (!IsPrimaryDevice()) @@ -766,9 +766,10 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) } if (IsPrimaryDevice()) AddPid(Channel->Tpid(), ptTeletext); + CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true)); // actually one would expect 'false' here, but according to Marco Schlüßler <marco@lordzodiac.de> this works + // to avoid missing audio after replaying a DVD; with 'false' there is an audio disturbance when switching + // between two channels on the same transponder on DVB-S CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true)); - CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false)); - CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false)); } else if (StartTransferMode) cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apid1(), Channel->Apid2(), Channel->Dpid1(), Channel->Dpid2())); @@ -1068,6 +1069,12 @@ bool cDvbDevice::Poll(cPoller &Poller, int TimeoutMs) return Poller.Poll(TimeoutMs); } +bool cDvbDevice::Flush(int TimeoutMs) +{ + //TODO actually this function should wait until all buffered data has been processed by the card, but how? + return true; +} + int cDvbDevice::PlayVideo(const uchar *Data, int Length) { int fd = (playMode == pmAudioOnly || playMode == pmAudioOnlyBlack) ? fd_audio : fd_video; diff --git a/dvbdevice.h b/dvbdevice.h index 2c5bd8e..f7a4b92 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.27 2004/04/17 11:56:22 kls Exp $ + * $Id: dvbdevice.h 1.28 2004/06/19 08:51:33 kls Exp $ */ #ifndef __DVBDEVICE_H @@ -115,6 +115,7 @@ public: virtual void Mute(void); virtual void StillPicture(const uchar *Data, int Length); virtual bool Poll(cPoller &Poller, int TimeoutMs = 0); + virtual bool Flush(int TimeoutMs = 0); virtual int PlayVideo(const uchar *Data, int Length); virtual void PlayAudio(const uchar *Data, int Length); @@ -4,13 +4,15 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbosd.c 1.22 2004/05/01 15:10:44 kls Exp $ + * $Id: dvbosd.c 1.23 2004/06/12 13:10:03 kls Exp $ */ #include "dvbosd.h" +#include <linux/dvb/osd.h> #include <signal.h> #include <sys/ioctl.h> #include <sys/unistd.h> +#include "dvbdevice.h" #include "tools.h" // --- cDvbOsd --------------------------------------------------------------- @@ -18,6 +20,18 @@ #define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 #define MAXOSDMEMORY 92000 // number of bytes available to the OSD (depends on firmware version, but there is no way of determining the actual value) +class cDvbOsd : public cOsd { +private: + int osdDev; + bool shown; + void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL); +public: + cDvbOsd(int Left, int Top, int OsdDev); + virtual ~cDvbOsd(); + virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas); + virtual void Flush(void); + }; + cDvbOsd::cDvbOsd(int Left, int Top, int OsdDev) :cOsd(Left, Top) { @@ -4,28 +4,14 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbosd.h 1.17 2004/04/30 13:44:16 kls Exp $ + * $Id: dvbosd.h 1.18 2004/06/12 13:09:52 kls Exp $ */ #ifndef __DVBOSD_H #define __DVBOSD_H -#include <linux/dvb/osd.h> -#include "dvbdevice.h" #include "osd.h" -class cDvbOsd : public cOsd { -private: - int osdDev; - bool shown; - void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL); -public: - cDvbOsd(int Left, int Top, int OsdDev); - virtual ~cDvbOsd(); - virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas); - virtual void Flush(void); - }; - class cDvbOsdProvider : public cOsdProvider { private: int osdDev; diff --git a/dvbplayer.c b/dvbplayer.c index c3bd542..8b60c2e 100644 --- a/dvbplayer.c +++ b/dvbplayer.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbplayer.c 1.23 2003/10/18 11:31:54 kls Exp $ + * $Id: dvbplayer.c 1.24 2004/06/19 08:55:49 kls Exp $ */ #include "dvbplayer.h" @@ -418,7 +418,7 @@ void cDvbPlayer::Action(void) int AudioTrack = 0; // -1 = any, 0 = none, >0 = audioTrack running = true; - while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available())) { + while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) { cPoller Poller; if (DevicePoll(Poller, 100)) { @@ -438,6 +438,10 @@ void cDvbPlayer::Action(void) continue; } else { + // hit begin of recording: wait for device buffers to drain + // before changing play mode: + if (!DeviceFlush(100)) + continue; // can't call Play() here, because those functions may only be // called from the foreground thread - and we also don't need // to empty the buffer here @@ -8,7 +8,7 @@ * * parts of this file are derived from the OMS program. * - * $Id: dvbspu.h 1.4 2004/05/31 08:49:20 kls Exp $ + * $Id: dvbspu.h 1.5 2004/06/12 12:57:55 kls Exp $ */ #ifndef __DVBSPU_H @@ -132,9 +132,6 @@ class cDvbSpuDecoder:public cSpuDecoder { int ScaleYres(int value); void DrawBmp(sDvbSpuRect & size, cBitmap * bmp); - void Draw(); - void Hide(); - public: cDvbSpuDecoder(); ~cDvbSpuDecoder(); @@ -147,6 +144,9 @@ class cDvbSpuDecoder:public cSpuDecoder { uint32_t palette); void clearHighlight(void); void Empty(void); + void Hide(void); + void Draw(void); + bool IsVisible(void) { return osd != NULL; } void processSPU(uint32_t pts, uint8_t * buf); }; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.308 2004/06/06 15:06:28 kls Exp $ + * $Id: menu.c 1.309 2004/06/13 20:26:51 kls Exp $ */ #include "menu.h" @@ -1410,7 +1410,6 @@ void cMenuRecordingItem::IncrementCounter(bool New) // --- cMenuRecordings ------------------------------------------------------- -cRecordings cMenuRecordings::Recordings; int cMenuRecordings::helpKeys = -1; cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus) @@ -1419,40 +1418,35 @@ cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus) base = Base ? strdup(Base) : NULL; level = Setup.RecordingDirs ? Level : -1; Display(); // this keeps the higher level menus from showing up briefly when pressing 'Back' during replay + const char *LastReplayed = cReplayControl::LastReplayed(); + cMenuRecordingItem *LastItem = NULL; + char *LastItemText = NULL; if (!Base) - Skins.Message(mtStatus, tr("scanning recordings...")); - bool Loaded = Base || Recordings.Load(); - if (!Base) - Skins.Message(mtStatus, NULL); - if (Loaded) { - const char *LastReplayed = cReplayControl::LastReplayed(); - cMenuRecordingItem *LastItem = NULL; - char *LastItemText = NULL; - for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { - if (!Base || (strstr(recording->Name(), Base) == recording->Name() && recording->Name()[strlen(Base)] == '~')) { - cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level); - if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) { - Add(Item); - LastItem = Item; - free(LastItemText); - LastItemText = strdup(LastItem->Text()); // must use a copy because of the counters! - } - else - delete Item; - if (LastItem) { - if (LastReplayed && strcmp(LastReplayed, recording->FileName()) == 0) - SetCurrent(LastItem); - if (LastItem->IsDirectory()) - LastItem->IncrementCounter(recording->IsNew()); - } + Recordings.Sort(); + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { + if (!Base || (strstr(recording->Name(), Base) == recording->Name() && recording->Name()[strlen(Base)] == '~')) { + cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level); + if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) { + Add(Item); + LastItem = Item; + free(LastItemText); + LastItemText = strdup(LastItem->Text()); // must use a copy because of the counters! + } + else + delete Item; + if (LastItem) { + if (LastReplayed && strcmp(LastReplayed, recording->FileName()) == 0) + SetCurrent(LastItem); + if (LastItem->IsDirectory()) + LastItem->IncrementCounter(recording->IsNew()); } } - free(LastItemText); - if (Current() < 0) - SetCurrent(First()); - else if (OpenSubMenus && Open(true)) - return; - } + } + free(LastItemText); + if (Current() < 0) + SetCurrent(First()); + else if (OpenSubMenus && Open(true)) + return; SetHelpKeys(); } @@ -2780,6 +2774,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) cStatus::MsgRecording(device, Recording.Name()); if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo() cReplayControl::SetRecording(fileName, Recording.Name()); + Recordings.AddByName(fileName); } else DELETENULL(recorder); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.63 2004/05/23 09:47:26 kls Exp $ + * $Id: menu.h 1.64 2004/06/13 11:46:03 kls Exp $ */ #ifndef __MENU_H @@ -16,7 +16,6 @@ #include "osdbase.h" #include "dvbplayer.h" #include "recorder.h" -#include "recording.h" #include "skins.h" class cMenuText : public cOsdMenu { @@ -107,7 +106,6 @@ class cMenuRecordingItem; class cMenuRecordings : public cOsdMenu { private: - static cRecordings Recordings; char *base; int level; static int helpKeys; diff --git a/menuitems.c b/menuitems.c index 3f83587..ee92dc9 100644 --- a/menuitems.c +++ b/menuitems.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menuitems.c 1.18 2004/05/16 12:47:02 kls Exp $ + * $Id: menuitems.c 1.19 2004/06/19 09:45:45 kls Exp $ */ #include "menuitems.h" @@ -331,8 +331,8 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key) if (pos >= 0) { insert = !insert; newchar = true; + SetHelpKeys(); } - SetHelpKeys(); break; case kYellow|k_Repeat: case kYellow: // Remove the character at current position; in insert mode it is the character to the right of cursor @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.52 2004/06/05 16:52:51 kls Exp $ + * $Id: osd.c 1.55 2004/06/15 20:29:42 kls Exp $ */ #include "osd.h" @@ -622,8 +622,8 @@ eOsdError cOsd::SetAreas(const tArea *Areas, int NumAreas) width = height = 0; for (int i = 0; i < NumAreas; i++) { bitmaps[numBitmaps++] = new cBitmap(Areas[i].Width(), Areas[i].Height(), Areas[i].bpp, Areas[i].x1, Areas[i].y1); - width = max(width, Areas[i].x2); - height = max(height, Areas[i].y2); + width = max(width, Areas[i].x2 + 1); + height = max(height, Areas[i].y2 + 1); } } } @@ -713,6 +713,10 @@ cOsdProvider::~cOsdProvider() cOsd *cOsdProvider::NewOsd(int Left, int Top) { + if (cOsd::IsOpen()) { + esyslog("ERROR: attempt to open OSD while it is already open!"); + return NULL; + } if (osdProvider) return osdProvider->CreateOsd(Left, Top); esyslog("ERROR: no OSD provider available - using dummy OSD!"); @@ -769,7 +773,7 @@ void cTextScroller::DrawText(void) { if (osd) { for (int i = 0; i < shown; i++) - osd->DrawText(left, top + i * font->Height(), textWrapper.GetLine(offset + i), colorFg, colorBg, font, width); + osd->DrawText(left, top + i * font->Height(), textWrapper.GetLine(offset + i), colorFg, colorBg, font, width); } } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.h 1.45 2004/06/05 12:38:44 kls Exp $ + * $Id: osd.h 1.46 2004/06/12 13:14:48 kls Exp $ */ #ifndef __OSD_H @@ -208,13 +208,14 @@ struct tArea { #define MAXOSDAREAS 16 class cOsd { + friend class cOsdProvider; private: static bool isOpen; cBitmap *savedRegion; cBitmap *bitmaps[MAXOSDAREAS]; int numBitmaps; int left, top, width, height; -public: +protected: cOsd(int Left, int Top); ///< Initializes the OSD with the given coordinates. ///< By default it is assumed that the full area will be able to display @@ -231,6 +232,7 @@ public: ///< and should require only the minimum necessary color depth. This is ///< because a derived cOsd class may or may not be able to handle more ///< than one area. +public: virtual ~cOsd(); ///< Shuts down the OSD. static bool IsOpen(void) { return isOpen; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: player.h 1.11 2004/04/30 13:45:59 kls Exp $ + * $Id: player.h 1.12 2004/06/19 08:53:07 kls Exp $ */ #ifndef __PLAYER_H @@ -20,6 +20,7 @@ private: ePlayMode playMode; protected: bool DevicePoll(cPoller &Poller, int TimeoutMs = 0) { return device ? device->Poll(Poller, TimeoutMs) : false; } + bool DeviceFlush(int TimeoutMs = 0) { return device ? device->Flush(TimeoutMs) : true; } void DeviceTrickSpeed(int Speed) { if (device) device->TrickSpeed(Speed); } void DeviceClear(void) { if (device) device->Clear(); } void DevicePlay(void) { if (device) device->Play(); } diff --git a/recording.c b/recording.c index 05efc44..cbc916a 100644 --- a/recording.c +++ b/recording.c @@ -4,10 +4,11 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.87 2004/05/07 14:24:18 kls Exp $ + * $Id: recording.c 1.88 2004/06/13 20:25:19 kls Exp $ */ #include "recording.h" +#include <dirent.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -25,7 +26,7 @@ #define RECEXT ".rec" #define DELEXT ".del" /* This was the original code, which works fine in a Linux only environment. - Unfortunately, because of windows and its brain dead file system, we have + Unfortunately, because of Windows and its brain dead file system, we have to use a more complicated approach, in order to allow users who have enabled the VFAT compile time option to see their recordings even if they forget to enable VFAT when compiling a new version of VDR... Gee, do I hate Windows. @@ -47,8 +48,6 @@ #define SUMMARYFILESUFFIX "/summary.vdr" #define MARKSFILESUFFIX "/marks.vdr" -#define FINDCMD "cd '%s' && find '%s' -follow -type d -name '%s' 2> /dev/null" - #define MINDISKSPACE 1024 // MB #define DELETEDLIFETIME 1 // hours after which a deleted recording will be actually removed @@ -70,14 +69,14 @@ void RemoveDeletedRecordings(void) if (!LockFile.Lock()) return; // Remove the oldest file that has been "deleted": - cRecordings Recordings; - if (Recordings.Load(true)) { - cRecording *r = Recordings.First(); + cRecordings DeletedRecordings(true); + if (DeletedRecordings.Load()) { + cRecording *r = DeletedRecordings.First(); cRecording *r0 = r; while (r) { if (r->start < r0->start) r0 = r; - r = Recordings.Next(r); + r = DeletedRecordings.Next(r); } if (r0 && time(NULL) - r0->start > DELETEDLIFETIME * 3600) { r0->Remove(); @@ -105,14 +104,14 @@ void AssertFreeDiskSpace(int Priority) return; // Remove the oldest file that has been "deleted": isyslog("low disk space while recording, trying to remove a deleted recording..."); - cRecordings Recordings; - if (Recordings.Load(true)) { - cRecording *r = Recordings.First(); + cRecordings DeletedRecordings(true); + if (DeletedRecordings.Load()) { + cRecording *r = DeletedRecordings.First(); cRecording *r0 = r; while (r) { if (r->start < r0->start) r0 = r; - r = Recordings.Next(r); + r = DeletedRecordings.Next(r); } if (r0 && r0->Remove()) { LastFreeDiskCheck += REMOVELATENCY / Factor; @@ -121,7 +120,7 @@ void AssertFreeDiskSpace(int Priority) } // No "deleted" files to remove, so let's see if we can delete a recording: isyslog("...no deleted recording found, trying to delete an old recording..."); - if (Recordings.Load(false)) { + if (Recordings.Load()) { cRecording *r = Recordings.First(); cRecording *r0 = NULL; while (r) { @@ -138,8 +137,10 @@ void AssertFreeDiskSpace(int Priority) } r = Recordings.Next(r); } - if (r0 && r0->Delete()) + if (r0 && r0->Delete()) { + Recordings.Del(r0); return; + } } // Unable to free disk space, but there's nothing we can do about that... isyslog("...no old recording found, giving up"); @@ -617,30 +618,75 @@ bool cRecording::Remove(void) // --- cRecordings ----------------------------------------------------------- -bool cRecordings::Load(bool Deleted) +cRecordings Recordings; + +cRecordings::cRecordings(bool Deleted) { - Clear(); - bool result = false; - char *cmd = NULL; - asprintf(&cmd, FINDCMD, VideoDirectory, VideoDirectory, Deleted ? "*" DELEXT : "*" RECEXT); - FILE *p = popen(cmd, "r"); - if (p) { - char *s; - while ((s = readline(p)) != NULL) { - cRecording *r = new cRecording(s); - if (r->Name()) - Add(r); - else - delete r; + deleted = Deleted; + lastUpdate = 0; +} + +bool cRecordings::ScanVideoDir(const char *DirName) +{ + DIR *d = opendir(DirName); + if (d) { + struct dirent *e; + while ((e = readdir(d)) != NULL) { + if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { + char *buffer; + asprintf(&buffer, "%s/%s", DirName, e->d_name); + struct stat st; + if (stat(buffer, &st) == 0) { + if (S_ISLNK(st.st_mode)) { + free(buffer); + buffer = ReadLink(buffer); + if (!buffer) + return false; + if (stat(buffer, &st) != 0) { + LOG_ERROR_STR(DirName); + return false; + } + } + if (S_ISDIR(st.st_mode)) { + if (endswith(buffer, deleted ? DELEXT : RECEXT)) { + cRecording *r = new cRecording(buffer); + if (r->Name()) + Add(r); + else + delete r; + } + else if (!ScanVideoDir(buffer)) + return false; + } + } + else { + LOG_ERROR_STR(DirName); + return false; + } + free(buffer); + } } - pclose(p); - Sort(); - result = Count() > 0; + closedir(d); } - else - Skins.Message(mtError, "Error while opening pipe!"); - free(cmd); - return result; + else { + LOG_ERROR_STR(DirName); + return false; + } + return true; +} + +bool cRecordings::NeedsUpdate(void) +{ + return lastUpdate <= LastModifiedTime(AddDirectory(VideoDirectory, ".update")); +} + +bool cRecordings::Load(void) +{ + lastUpdate = time(NULL); // doing this first to make sure we don't miss anything + Clear(); + ScanVideoDir(VideoDirectory); + Sort(); + return Count() > 0; } cRecording *cRecordings::GetByName(const char *FileName) @@ -652,6 +698,22 @@ cRecording *cRecordings::GetByName(const char *FileName) return NULL; } +void cRecordings::AddByName(const char *FileName) +{ + cRecording *recording = GetByName(FileName); + if (!recording) { + recording = new cRecording(FileName); + Add(recording); + } +} + +void cRecordings::DelByName(const char *FileName) +{ + cRecording *recording = GetByName(FileName); + if (recording) + Del(recording); +} + // --- cMark ----------------------------------------------------------------- char *cMark::buffer = NULL; diff --git a/recording.h b/recording.h index 01a25ab..04a1885 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.h 1.29 2004/05/07 14:24:22 kls Exp $ + * $Id: recording.h 1.30 2004/06/13 15:37:42 kls Exp $ */ #ifndef __RECORDING_H @@ -69,11 +69,22 @@ public: }; class cRecordings : public cList<cRecording> { +private: + bool deleted; + time_t lastUpdate; + bool ScanVideoDir(const char *DirName); public: - bool Load(bool Deleted = false); + cRecordings(bool Deleted = false); + bool Load(void); + void TriggerUpdate(void) { lastUpdate = 0; } + bool NeedsUpdate(void); cRecording *GetByName(const char *FileName); + void AddByName(const char *FileName); + void DelByName(const char *FileName); }; +extern cRecordings Recordings; + class cMark : public cListObject { private: static char *buffer; diff --git a/ringbuffer.c b/ringbuffer.c index 6f26748..b52c37e 100644 --- a/ringbuffer.c +++ b/ringbuffer.c @@ -7,7 +7,7 @@ * Parts of this file were inspired by the 'ringbuffy.c' from the * LinuxDVB driver (see linuxtv.org). * - * $Id: ringbuffer.c 1.19 2004/03/07 13:46:51 kls Exp $ + * $Id: ringbuffer.c 1.20 2004/06/19 12:27:56 kls Exp $ */ #include "ringbuffer.h" @@ -181,6 +181,7 @@ uchar *cRingBufferLinear::Get(int &Count) int t = margin - rest; memcpy(buffer + t, buffer + tail, rest); tail = t; + rest = head - tail; } int diff = head - tail; int cont = (diff >= 0) ? diff : Size() + diff - margin; diff --git a/ringbuffer.h b/ringbuffer.h index 349096f..f407488 100644 --- a/ringbuffer.h +++ b/ringbuffer.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ringbuffer.h 1.14 2004/03/07 13:40:45 kls Exp $ + * $Id: ringbuffer.h 1.15 2004/06/19 10:32:15 kls Exp $ */ #ifndef __RINGBUFFER_H @@ -54,7 +54,7 @@ private: public: cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false); ///< Creates a linear ring buffer. - ///< The buffer will be able to hold at most Size bytes of data, and will + ///< The buffer will be able to hold at most Size-Margin-1 bytes of data, and will ///< be guaranteed to return at least Margin bytes in one consecutive block. virtual ~cRingBufferLinear(); virtual int Available(void); @@ -6,7 +6,7 @@ * This code is distributed under the terms and conditions of the * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details. * - * $Id: spu.h 1.1 2002/09/08 14:17:51 kls Exp $ + * $Id: spu.h 1.2 2004/06/12 12:56:27 kls Exp $ */ #ifndef __SPU_VDR_H @@ -32,6 +32,9 @@ class cSpuDecoder { uint32_t palette) = 0; virtual void clearHighlight(void) = 0; virtual void Empty(void) = 0; + virtual void Hide(void) = 0; + virtual void Draw(void) = 0; + virtual bool IsVisible(void) = 0; virtual void processSPU(uint32_t pts, uint8_t * buf) = 0; }; @@ -10,7 +10,7 @@ * and interact with the Video Disk Recorder - or write a full featured * graphical interface that sits on top of an SVDRP connection. * - * $Id: svdrp.c 1.62 2004/03/25 17:00:23 kls Exp $ + * $Id: svdrp.c 1.63 2004/06/13 13:38:38 kls Exp $ */ #include "svdrp.h" @@ -504,8 +504,10 @@ void cSVDRP::CmdDELR(const char *Option) if (isnumber(Option)) { cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1); if (recording) { - if (recording->Delete()) + if (recording->Delete()) { Reply(250, "Recording \"%s\" deleted", Option); + ::Recordings.Load(); // must make sure the global recordings list is updated + } else Reply(554, "Error while deleting recording!"); } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: themes.c 1.2 2004/05/22 10:30:06 kls Exp $ + * $Id: themes.c 1.3 2004/06/18 15:05:07 kls Exp $ */ #include "themes.h" @@ -114,8 +114,10 @@ bool cTheme::Load(const char *FileName, bool OnlyDescriptions) char *l = strchr(n, '.'); if (l) lang = I18nLanguageIndex(++l); - if (lang >= 0) + if (lang >= 0) { + free(descriptions[lang]); descriptions[lang] = strdup(v); + } else error = "invalid language code"; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.79 2004/05/22 12:13:27 kls Exp $ + * $Id: tools.c 1.80 2004/06/13 14:36:41 kls Exp $ */ #include "tools.h" @@ -481,6 +481,14 @@ bool SpinUpDisk(const char *FileName) return false; } +time_t LastModifiedTime(const char *FileName) +{ + struct stat fs; + if (stat(FileName, &fs) == 0) + return fs.st_mtime; + return 0; +} + const char *WeekDayName(int WeekDay) { static char buffer[4]; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 1.56 2004/05/22 12:11:44 kls Exp $ + * $Id: tools.h 1.57 2004/06/13 14:13:26 kls Exp $ */ #ifndef __TOOLS_H @@ -83,6 +83,7 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks = false); bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis = false); char *ReadLink(const char *FileName); bool SpinUpDisk(const char *FileName); +time_t LastModifiedTime(const char *FileName); const char *WeekDayName(int WeekDay); ///< \warning returns a statically allocated string! const char *WeekDayName(time_t t); ///< \warning returns a statically allocated string! const char *DayDateTime(time_t t = 0); ///< \warning returns a statically allocated string! @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.1 1.10 2004/05/16 12:10:52 kls Exp $ +.\" $Id: vdr.1 1.11 2004/06/13 14:48:03 kls Exp $ .\" .TH vdr 1 "1 June 2003" "1.2.0" "Video Disk Recorder" .SH NAME @@ -176,6 +176,10 @@ The actual data files of a recording. .I epg.data Contains all current EPG data. Can be used for external processing and will also be read at program startup to have the full EPG data available immediately. +.TP +.I .update +If this file is present in the video directory, its last modification time will +be used to trigger an update of the list of recordings in the "Recordings" menu. .SH SEE ALSO .BR vdr (5) .SH AUTHOR @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/vdr * - * $Id: vdr.c 1.181 2004/05/16 10:12:43 kls Exp $ + * $Id: vdr.c 1.184 2004/06/13 13:52:09 kls Exp $ */ #include <getopt.h> @@ -84,6 +84,25 @@ static void Watchdog(int signum) int main(int argc, char *argv[]) { +#ifdef _CS_GNU_LIBPTHREAD_VERSION + // Check for NPTL and exit if present - VDR apparently doesn't run well with NPTL: + char LibPthreadVersion[128]; + if (confstr(_CS_GNU_LIBPTHREAD_VERSION, LibPthreadVersion, sizeof(LibPthreadVersion) > 0)) { + if (strstr(LibPthreadVersion, "NPTL")) { + fprintf(stderr, "vdr: please turn off NPTL by setting 'export LD_ASSUME_KERNEL=2.4.1' before starting VDR\n"); + return 2; + } + } +#endif + + // Check for UTF-8 and exit if present - asprintf() will fail if it encounters 8 bit ASCII codes + char *LangEnv; + if ((LangEnv = getenv("LANG")) != NULL && strcasestr(LangEnv, "utf") || + (LangEnv = getenv("LC_TYPE")) != NULL && strcasestr(LangEnv, "utf")) { + fprintf(stderr, "vdr: please turn off UTF-8 before starting VDR\n"); + return 2; + } + // Save terminal settings: struct termios savedTm; @@ -456,6 +475,10 @@ int main(int argc, char *argv[]) else cDevice::PrimaryDevice()->SetVolume(Setup.CurrentVolume, true); + // Recordings: + + Recordings.Load(); + // Signal handlers: if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN); @@ -587,6 +610,8 @@ int main(int argc, char *argv[]) TimerInVpsMargin = true; } } + if (!Menu && Recordings.NeedsUpdate()) + Recordings.Load(); // CAM control: if (!Menu && !cOsd::IsOpen()) Menu = CamControl(); |