From f10368dddbb89f74141f7c36f95dd369ecc8dd74 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Mon, 18 Feb 2008 20:40:08 +0100 Subject: [PATCH] Fixed various spelling errors and improved PLUGINS.html --- CONTRIBUTORS | 17 +-- HISTORY | 59 ++++---- PLUGINS.html | 378 +++++++++++++++++++++++++++------------------------ 3 files changed, 238 insertions(+), 216 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index bb50c01a..96fd1ce7 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -122,7 +122,7 @@ Henning Holtschneider for pointing out a possible hangup when reading a broken epg.data file Paulo Lopes - for translating OSD texts to the Portugese language + for translating OSD texts to the Portuguese language Markus Lang and Ulrich Röder for making DiSEqC support configurable @@ -186,7 +186,7 @@ Stefan Huelswitt for reporting a bug in handling of Ca parameters with values <= MAXDEVICES, which don't indicate an actual encrypted channel for implementing setting the "broken link" flag for GOPs at the beginning of a new - video sequence, which avoids artefacts when cutting + video sequence, which avoids artifacts when cutting for suggesting to add VDRVERSNUM to config.h for fixing a memory leak in cNonBlockingFileReader for fixing an uninitialized variable in cDisplayChannel @@ -1082,7 +1082,7 @@ Thomas Schmidt for reporting a crash when canceling a newly created timer for making 'diseqc.conf' a required file only if Setup.DiSEqC is activated for making VDR use the default configuration directory as defined in the CONFDIR - varable in the Makefile + variable in the Makefile Michael Walle for reporting a bug in channel switching after Left/Right has been pressed @@ -1352,7 +1352,7 @@ Wayne Keer for reporting a spelling error in 'canceling' for adding some 'mkdir -p' to the Makefile's 'install' target for reporting some missing braces in remux.c - for suggesting to modifiy the Makefile to copy and clean up additional libraries + for suggesting to modify the Makefile to copy and clean up additional libraries a plugin might provide Marco Schlüßler @@ -1451,7 +1451,7 @@ Marco Schl for fixing selecting the audio track when pressing Ok in the Audio menu for implementing handling DVB subtitles for fixing the description of DeviceSetAvailableTrack() and cReceiver(), and adding - an example ~cMyReceiver() in PLUGINS.html (thanks to Marco Schlüßler). + an example ~cMyReceiver() in PLUGINS.html for fixing checking compatibility mode for old subtitles plugin for a patch that was used to implement handling of DVB-S2 for fixing setting the date in the channel display of the classic and sttng skins, @@ -1752,6 +1752,7 @@ Ville Skytt for making the "Play" key start replay of the selected recording in the Recordings menu for adding missing #include to epg.c and menuitems.h + for fixing various spelling errors and improving PLUGINS.html Steffen Beyer for fixing setting the colored button help after deleting a recording in case the next @@ -1886,7 +1887,7 @@ Philip Prindeville Enrico Scholz for making VDR use use daemon() instead of fork() to run in daemon mode for fixing a possible endless loop in a menu with no selectable items if - Setup.MenuScrollWrap is true (thanks to Enrico Scholz) + Setup.MenuScrollWrap is true Nicolas Huillard for translating OSD texts to the French language @@ -2134,7 +2135,7 @@ Prakash Punnoor Anssi Hannula for a patch that was used to implement processing the "frequency list descriptor" for suggesting that cDevice::GetDevice() should prefer any device that's already - receiving and doesn't require detatching receivers + receiving and doesn't require detaching receivers for improving handling Transfer Mode devices when selecting a device to receive for fixing handling frequencies in NitFilter::Process() for making non-primary devices in Transfer mode be also used for recording @@ -2204,7 +2205,7 @@ J for reporting that cPlugin::Active() was called too often Peter Pinnau - for reporting that 'uint32_t' requires uncluding stdint.h in font.h on some systems + for reporting that 'uint32_t' requires including stdint.h in font.h on some systems Petri Helin for suggesting to avoid budget DVB cards with Common Interface when tuning to an diff --git a/HISTORY b/HISTORY index 52890622..3ef8b667 100644 --- a/HISTORY +++ b/HISTORY @@ -247,10 +247,10 @@ Video Disk Recorder Revision History 2000-11-01: Version 0.67 - The EIT information is now gathered in a separate thread. -- The sytem time can now be synchronized to the time broadcast in the DVB data +- The system time can now be synchronized to the time broadcast in the DVB data stream. This can be enabled in the "Setup" menu by setting "SetSystemTime" to 1. Note that this works only if VDR is running under a user ID that has - permisson to set the system time. + permission to set the system time. - The new item "Schedule" in the "Main" menu opens VDR's EPG (thanks to Robert Schneider). See the MANUAL file for a detailed description. - The new setup parameters MarginStart and MarginStop define how long (in @@ -640,7 +640,7 @@ Video Disk Recorder Revision History - The new command line option '-E' can be used to define where the EPG data shall be written to. This is especially useful if VDR runs in a system that turns off the video disk when it is not used, and therefore needs - to write the EPG file to a ramdisk (or turn off writing it alltogether). + to write the EPG file to a ramdisk (or turn off writing it altogether). See 'vdr --help' for details. - Making sure the disk is up and running before starting recording (this is important for systems that turn off the video disk when it is not used). @@ -776,7 +776,7 @@ Video Disk Recorder Revision History set to INVERSION_AUTO, which should work with all channels on Astra). - Removing unnecessary double quotes from EPG Subtitle in EPGBugfixLevel >=1. - EPG info is now updated if the contents changes but the ID remains the same. -- Fixed handling SVDRP commands whith more than one blank between the command +- Fixed handling SVDRP commands with more than one blank between the command word and the options. - The current volume setting is now saved to setup.conf and restored at the next program start. @@ -907,7 +907,7 @@ Video Disk Recorder Revision History in the call to the shutdown command (option '-s') and the recording command (option '-r'). - Improved error handling in the editing process; the resulting file will be - deleted if an error occured. + deleted if an error occurred. - A message is now prompted at the end of the editing process, indicating whether the process succeeded or failed. - Fixed setting the LastActivity timestamp after a shutdown prompt (thanks to @@ -1058,7 +1058,7 @@ Video Disk Recorder Revision History - Changed the meaning of the 'Ca' parameter in 'channels.conf'. Each channel can now define which decryption method it needs in order to be accessed. The new configuration file 'ca.conf' contains the defined values, and the default - 'channels.conf' has been modifed to contain the new values for 'Premiere World' + 'channels.conf' has been modified to contain the new values for 'Premiere World' and 'ORF'. If you use the default 'channels.conf' and have the conditional access hardware to receive encrypted channels, please make sure you copy the file 'ca.conf' into your /video directory (or wherever your configuration files @@ -1369,7 +1369,7 @@ Video Disk Recorder Revision History cPlayer and cControl have been given the functions GetIndex() and GetReplayMode() to allow access to the player's status. - Added cOsd::OpenRaw() to create a raw OSD (needed for displaying SPUs). -- Changed the symantics of the Name parameter in cStatus::Recording() and +- Changed the semantics of the Name parameter in cStatus::Recording() and cStatus::Replaying(). It is no longer the full directory name of the recording, but rather just the basic name. This has been changed to allow players that can't provide a name to simply use a string that describes the player type (like, e.g., @@ -1661,7 +1661,7 @@ Video Disk Recorder Revision History - Implemented new keys to directly access the VDR main menu functions "Schedule", "Channels", "Timers", "Recordings", "Setup" and "Commands". If your remote control provides keys you want to assign these functions to, you can delete - your 'remote.cof' file and restart VDR to go through the key learning procedure + your 'remote.conf' file and restart VDR to go through the key learning procedure again in order to assign these new keys. See MANUAL for more information. - The new configuration file 'keymacros.conf' can be used to assign macros to the color buttons in normal viewing mode, as well as to up to 9 user defined @@ -1905,7 +1905,7 @@ Video Disk Recorder Revision History - Fixed handling channels in the "Channels" menu in case there are ':@nnn' group separators without names (thanks to Guy Roussin for reporting this one). - The SVDRP command CHAN now also accepts channel IDs. -- Increased the timeout until an index file is considerd no longer to be written +- Increased the timeout until an index file is considered no longer to be written (sometimes in time shift with heavy system load the index file was closed too early by the replay thread). - Implemented "Link Layer" based CAM support, which hopefully will solve the @@ -2006,7 +2006,7 @@ Video Disk Recorder Revision History - Added some missing cAudio handling calls (thanks to Werner Fink). - Replaced the 'for' loops in StripAudioPackets() with memset() calls (thanks to Werner Fink). -- Further increased the timeout until an index file is considerd no longer to be +- Further increased the timeout until an index file is considered no longer to be written. - Fixed a crash in case the index file can't be accessed any more during replay (thanks to Stefan Huelswitt for reporting this one). @@ -2068,7 +2068,7 @@ Video Disk Recorder Revision History - Fixed deleting the last recording in the "Recordings" menu, which started pausing live video (thanks to Christoph Friederich for reporting this one). - Now setting the "broken link" flag for GOPs at the beginning of a new video - sequence, which avoids artefacts when cutting (thanks to Stefan Huelswitt). + sequence, which avoids artifacts when cutting (thanks to Stefan Huelswitt). - Removed the Mute() call from cDvbDevice::StillPicture() (suggested by Andreas Schultz). - Updated 'channels.conf.terr' for Berlin (thanks to Andreas Brachold). @@ -2136,7 +2136,7 @@ Video Disk Recorder Revision History - Updated 'channels.conf.terr' for Berlin (thanks to Juri Haberland). - Avoiding short display of the "Main" menu when pressing the "Recordings" button or the "Back" button during replay. -- Further increased the timeout until an index file is considerd no longer to be +- Further increased the timeout until an index file is considered no longer to be written. - Implemented separate PausePriority and PauseLifetime parameters for the recordings created when pausing live video (suggested by Alfred Zastrow). @@ -2168,7 +2168,7 @@ Video Disk Recorder Revision History - Updated 'channels.conf.cable' (thanks to Stefan Hußfeldt). - Fixed reading 'epg.data' for channels with non-zero RID (thanks to Oliver Endriss for reporting this one). -- Fixed EPG bugfix statistics to avoid log entires for undefined channels (thanks +- Fixed EPG bugfix statistics to avoid log entries for undefined channels (thanks to Lars Bläser for reporting this one). - No longer waiting inside cIndexFile::CatchUp() to avoid shortly blocking replay at the end of a recording. @@ -2218,7 +2218,7 @@ Video Disk Recorder Revision History Ahrenberg). - Completed the Italian OSD texts (thanks to Antonio Ospite). - Fixed breaking off replay in case the user hits "Play" or "Pause" too soon after - going into "Pause live video" mode (thanks to Karim Afifi for reporting ths one). + going into "Pause live video" mode (thanks to Karim Afifi for reporting this one). - Some corrections to the Catalanian OSD texts (thanks to Jordi Vilà). - Single event timers are now deleted if the recording they are doing is deleted before the timer ends. @@ -2247,7 +2247,7 @@ Video Disk Recorder Revision History Josten). - Fixed device handling in the CICAM menu in case a VDR instance was started with a specific device using the -D option (thanks to Gerald Raaf for reporting - ths one). + this one). - Initializing the current channel to '1' to avoid a crash in creating a new timer in case there is no device in the system that can actually receive any channel (thanks to Malcolm Caldwell for reporting this one). @@ -2448,7 +2448,7 @@ Video Disk Recorder Revision History 2003-10-26: Version 1.2.6pre4 - Fixed handling CAM menus in case the CAM connection fails while the menu - is being presented (thanks to Thomas v. Keller for reportign this one). + is being presented (thanks to Thomas v. Keller for reporting this one). - Added missing 'const' to some cChannel member functions (thanks to Torsten Herz). @@ -2668,7 +2668,7 @@ Video Disk Recorder Revision History recording exceeds 10 (suggested by Gregoire Favre). Since the UPT error doesn't happen on my system, this has not been explicitly tested. The "preliminary fix" for the UPT error in VDR/dvbdevice.c has been disabled - by default, since it makes channel switching unpleasently slow. If you want + by default, since it makes channel switching unpleasantly slow. If you want to have that workaround back, you can uncomment the line //#define WAIT_FOR_LOCK_AFTER_TUNING 1 in VDR/dvbdevice.c. @@ -2815,7 +2815,7 @@ Video Disk Recorder Revision History - Added a hint to PLUGINS.html about how to name a plugin that implements a skin. - Completed the Finnish OSD texts (thanks to Rolf Ahrenberg). - Single shot timers and events now show the day of week (adopted with some changes - from the "elchi" patch, orginally introduced by Oskar Signell). Plugins that use + from the "elchi" patch, originally introduced by Oskar Signell). Plugins that use cEvent::GetDateString() should note that this function now returns a longer string, including the day of week. The new function const char *WeekDayName(time_t t) can be called with a time_t value to get the day of week for that time. @@ -3267,7 +3267,7 @@ Video Disk Recorder Revision History - Skins need to implement the new cSkinDisplayTrack class to display the audio track menu. - The ST:TNG skin now displays the current audio track description (if any) at the - botton left side. + bottom left side. - The new setup option "DVB/Audio languages" can be used to control which audio language shall be selected in case a channel broadcasts in different languages (see MANUAL for details). @@ -3959,7 +3959,7 @@ Video Disk Recorder Revision History (thanks to Holger Brunn). - The new function Skins.QueueMessage() can be called from a background thread to queue a message for display. See VDR/skins.h for details. -- The SVDRP command MESG uses the new message queueing facility, so MESG +- The SVDRP command MESG uses the new message queuing facility, so MESG commands may now be executed at any time, and the message will be displayed (no more "pending message"). @@ -4483,7 +4483,7 @@ Video Disk Recorder Revision History - Fixed a typo in skins.h (thanks to Alexander Rieger). - cSkins::QueueMessage() called from a background thread with an empty message now clears all messages that have been previously queued by that thread and have - not yet beed displayed (thanks to Alexander Rieger). + not yet been displayed (thanks to Alexander Rieger). - Fixed handling the color button texts when switching from the 'Schedule' menu of a channel without EPG info to the 'What's on now' menu (reported by Rolf Ahrenberg). @@ -4736,7 +4736,7 @@ Video Disk Recorder Revision History - Fixed handling VPS timers in case the EPG event hasn't been 'seen' in a while. - Fixed calculating the cache size in cUnbufferedFile::Read() (thanks to Artur Skawina). - Removed -fPIC from VDR's and libsi's Makefile (suggested by Prakash Punnoor). -- Modifed the device selection to better handle timer conflicts (reported by +- Modified the device selection to better handle timer conflicts (reported by Christian Wieninger). - Avoiding a compiler warning in libsi's TypeLoop::operator[]. - Now processing the "frequency list descriptor" (based on a patch from Anssi Hannula). @@ -4827,7 +4827,7 @@ Video Disk Recorder Revision History - Fixed handling client side termination of SVDRP connections (thanks to Frank Schmirler). - cDevice::GetDevice() now prefers any device that's already receiving and doesn't - require detatching receivers (suggested by Anssi Hannula). + require detaching receivers (suggested by Anssi Hannula). - Fixed handling numeric keys in the channel display after switching channel groups (thanks to Andreas Regel). - Menu items derived from cMenuEditIntItem now loop though their values if they @@ -4893,7 +4893,7 @@ Video Disk Recorder Revision History - Revoked the change to cDevice::GetDevice() that was introduced in version 1.4.1-2, which made it prefer any device that's already receiving and doesn't require - detatching receivers. This change has caused some unwanted behavior, so further + detaching receivers. This change has caused some unwanted behavior, so further testing is necessary. 2006-09-03: Version 1.4.2-1 @@ -5041,7 +5041,7 @@ Video Disk Recorder Revision History decrypting the current channel again. - The Setup/CAM menu now dynamically refreshes its items and displays whether a CAM is present or ready. The 'Reset' function no longer leaves the menu. -- The CAM menu will now be openend when pressing the Ok key on a slot entry. +- The CAM menu will now be opened when pressing the Ok key on a slot entry. - The CAM menu now stays within the current menu context and doesn't close and reopen the menu every time an option is selected. - When an encrypted channel is switched to for the first time, VDR now checks @@ -5400,7 +5400,7 @@ Video Disk Recorder Revision History texts they want to reuse from VDR's core translations (suggested by Matthias Becker). - VDR now uses the default configuration directory as defined in the CONFDIR - varable in the Makefile (thanks to Thomas Schmidt). + variable in the Makefile (thanks to Thomas Schmidt). - The SVDRP command LSTC can now list the channels with group separators if the option ':groups' is given (thanks to Andreas Mair). - Added a missing error report to cCuttingThread::Action() (thanks to Udo @@ -5479,7 +5479,7 @@ Video Disk Recorder Revision History i18n: $(I18Npot) $(I18Nmo) (based on a suggestion by Torsten Kunkel). - Removed a duplicate ',' from the ca_ES.po file (thanks to Thomas Günther). -- Added the 'ß' character to the "allowed charcaters" in the de_DE.po file +- Added the 'ß' character to the "allowed characters" in the de_DE.po file (suggested by Thomas Günther). - Made the default copy ctor of cRecording private (thanks to Markus Hahn). Same for the assign operator. @@ -5550,7 +5550,7 @@ Video Disk Recorder Revision History - Added a missing setting of lastFreeMB in cMenuMain::Update() (reported by Andreas Brugger). - Added '-Wno-parentheses' to the compiler options in order to avoid silly compiler - warnings for expessions like 'a || b && c', where GCC 4.3 wants to force the + warnings for expressions like 'a || b && c', where GCC 4.3 wants to force the programmer to write 'a || (b && c)', while everybody knows that '&&' links stronger than '||' (reported by Tobias Grimm). - Updated the Hungarian language texts (thanks to István Füley). @@ -5572,7 +5572,7 @@ Video Disk Recorder Revision History - The new option --localedir can be used to set the locale directory at runtime (based on a patch from Stefan Huelswitt). - Fixed finding new transponders (thanks to Winfried Köhler). -- Implemented handling of DVB-S2 (thanks to Marco Schlüßler and Reinhald Nissl +- Implemented handling of DVB-S2 (thanks to Marco Schlüßler and Reinhard Nissl for a patch that was used to implement this). VDR now requires the "multiproto" DVB driver, e.g. from http://jusst.de/hg/multiproto. - Removed switching to the next higher or lower channel if the current channel @@ -5651,3 +5651,4 @@ Video Disk Recorder Revision History return the right value in the early stage of channel switching). - Updated the Danish OSD texts (thanks to Mogens Elneff). - Updated the Dutch OSD texts (thanks to Carel Willemse). +- Fixed various spelling errors and improved PLUGINS.html (thanks to Ville Skyttä). diff --git a/PLUGINS.html b/PLUGINS.html index 71286b3b..9dc48e7f 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -1,18 +1,36 @@ + + The VDR Plugin System + - + -

The VDR Plugin System

+
+

The VDR Plugin System

-
Version 1.6
+Version 1.6

-

Copyright © 2008 Klaus Schmidinger
kls@cadsoft.de
www.cadsoft.de/vdr -
+

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. @@ -78,11 +96,11 @@ structures and allows it to hook itself into specific areas to perform special a -


Part I - The External Interface

+

Part I - The External Interface

-

Quick start

+

Quick start

-
Can't wait, can't wait!

+

Can't wait, can't wait!

Actually you should read this entire document before starting to work with VDR plugins, but you probably want to see something happening right away ;-) @@ -102,9 +120,9 @@ So, for a quick demonstration of the plugin system, there is a sample plugin cal If you enjoyed this brief glimpse into VDR plugin handling, read through the rest of this document and eventually write your own VDR plugin. -


The name of the plugin

+

The name of the plugin

-
Give me some I.D.!

+

Give me some I.D.!

One of the first things to consider when writing a VDR plugin is giving the thing a proper name. This name will be used in the VDR command line in order to load @@ -119,22 +137,22 @@ No other characters should be used here.

A plugin can access its name through the (non virtual) member function -

+

 const char *Name(void);
 

The actual name is derived from the plugin's library file name, as defined in the next chapter. -


The plugin directory structure

+

The plugin directory structure

-
Where is everybody?

+

Where is everybody?

By default plugins are located in a directory named PLUGINS below the VDR source directory. Inside this directory the following subdirectory structure is used: -

+

 VDR/PLUGINS/src
 VDR/PLUGINS/src/hello
 VDR/PLUGINS/lib
@@ -154,7 +172,7 @@ available plugins. Note that the names of these files are created by concatenati
 

- +
libvdr-hello.so.1.1.0
VDR plugin
library prefix
name of
the plugin
shared object
indicator
API version number
this plugin was
compiled for
VDR plugin
library prefix
name of
the plugin
shared object
indicator
API version number
this plugin was
compiled for

The API version number refers to the plugin API version number of the VDR @@ -186,7 +204,7 @@ To use the plugins and clean-plugins targets from the VDR you need to unpack such an archive into the VDR/PLUGINS/src directory and create a symbolic link with the basic plugin name, as in -

+

 ln -s hello-0.0.1 hello
 

@@ -206,9 +224,9 @@ additional libraries foo and bar, the names would be libhello-bar.so.0.0.1

-


Initializing a new plugin directory

+

Initializing a new plugin directory

-
A room with a view

+

A room with a view

Call the Perl script newplugin from the VDR source directory to create a new plugin directory with a Makefile and a main source file implementing @@ -225,9 +243,9 @@ have other plans. Add further files and maybe subdirectories to your plugin source directory as necessary. Don't forget to adapt the Makefile appropriately. -


The actual implementation

+

The actual implementation

-
Use the source, Luke!

+

Use the source, Luke!

A newly initialized plugin doesn't really do very much yet. If you load it into VDR you will find a new @@ -250,7 +268,7 @@ If your plugin shall not be accessible through VDR's main menu, simply remove

At the end of the plugin's source file you will find a line that looks like this: -

+

 VDRPLUGINCREATOR(cPluginHello);
 

@@ -263,7 +281,7 @@ source directory and adjust the Makefile accordingly. Header files usually contain preprocessor statements that prevent the same file (or rather its contents, to be precise) from being included more than once, like -

+

 #ifndef __I18N_H
 #define __I18N_H
 
@@ -292,13 +310,13 @@ and implements a file named i18n.h. To make sure it won't clash with VD
 i18n.h it uses the macro _I18N__H (one underline at the beginning
 and two replacing the dot).
 
-

Construction and Destruction

+

Construction and Destruction

-
What goes up, must come down...

+

What goes up, must come down...

The constructor and destructor of a plugin are defined as -

+

 cPlugin(void);
 virtual ~cPlugin();
 

@@ -321,15 +339,15 @@ Any threads the plugin may have created shall be stopped in the Of course, if your plugin doesn't define any member variables that need to be initialized (and deleted), you don't need to implement either of these functions. -


Version number

+

Version number

-
Which incarnation is this?

+

Which incarnation is this?

Every plugin must have a version number of its own, which does not necessarily have to be in any way related to the VDR version number. VDR requests a plugin's version number through a call to the function -

+

 virtual const char *Version(void) = 0;
 

@@ -340,7 +358,7 @@ information, like for instance "0.0.1pre2" or the like. The string should only be as long as really necessary, and shall not contain the plugin's name itself. Here's an example: -

+

 static const char *VERSION = "0.0.1";
 
 const char *cPluginHello::Version(void)
@@ -354,6 +372,7 @@ main source file, and must be written as
 
 static const char *VERSION = ...
 
+

just like shown in the above example. This is a convention that allows the Makefile to extract the version number when generating the file name for the distribution archive.

@@ -366,19 +385,19 @@ while those with odd release numbers (like 1.1.x, 1.3.x a version number are not limited to single digits, so a version number of 1.2.15 would be acceptable. -


Description

+

Description

-
What is it that you do?

+

What is it that you do?

In order to tell the user what exactly a plugin does, it must implement the function -

+

 virtual const char *Description(void) = 0;
 

which returns a short, one line description of the plugin's purpose: -

+

 static const char *DESCRIPTION = "A friendly greeting";
 
 virtual const char *Description(void)
@@ -390,15 +409,15 @@ virtual const char *Description(void)
 Note the tr() around the DESCRIPTION, which allows the description
 to be internationalized.
 
-

Command line arguments

+

Command line arguments

-
Taking orders

+

Taking orders

A VDR plugin can have command line arguments just like any normal program. If a plugin wants to react on command line arguments, it needs to implement the function -

+

 virtual bool ProcessArgs(int argc, char *argv[]);
 

@@ -415,7 +434,7 @@ these arguments. As with any normal C program, the strings pointed to by arg will survive the entire lifetime of the plugin, so it is safe to store pointers to these values inside the plugin. Here's an example: -

+

 bool cPluginHello::ProcessArgs(int argc, char *argv[])
 {
   // Implement command line argument processing here if applicable.
@@ -444,13 +463,13 @@ correctly, or false in case of an error. The first plugin that returns
 false from a call to its ProcessArgs() function will cause VDR
 to exit.
 
-

Command line help

+

Command line help

-
Tell me about it...

+

Tell me about it...

If a plugin accepts command line options, it should implement the function -

+

 virtual const char *CommandLineHelp(void);
 

@@ -458,7 +477,7 @@ which will be called if the user enters the -h option when start The returned string should contain the command line help for this plugin, formatted in the same way as done by VDR itself: -

+

 const char *cPluginHello::CommandLineHelp(void)
 {
   // Return a string that describes all known command line options.
@@ -473,15 +492,15 @@ same formatting as shown here it will line up nicely.
 Note that all lines should be terminated with a newline character, and should
 be shorter than 80 characters.
 
-

Getting started

+

Getting started

-
Let's get ready to rumble!

+

Let's get ready to rumble!

If a plugin implements a function that runs in the background (presumably in a thread of its own), or wants to make use of internationalization, it needs to implement one of the functions -

+

 virtual bool Initialize(void);
 virtual bool Start(void);
 

@@ -511,13 +530,13 @@ VDR to exit. If the plugin doesn't implement any background functionality or internationalized texts, it doesn't need to implement either of these functions. -


Shutting down

+

Shutting down

-
Stop it, right there!

+

Stop it, right there!

If a plugin performs any background tasks, it shall implement the function -

+

 virtual void Stop(void);
 

@@ -528,8 +547,9 @@ The Stop() function will only be called if a previous call to the returned true. The Stop() functions are called in the reverse order as the Start() functions were called. -


Logging

+

Logging

+

If the plugin should print log messages, you can use dsyslog(), isyslog() or esyslog().

  • dsyslog() prints the log message only if the log level of vdr is set to 3. @@ -539,21 +559,21 @@ If the plugin should print log messages, you can use dsyslog(), isy The output of this log is the syslog of the system vdr is running on. The logmessage can be formatted like printf(), as in -

    +

     esyslog("pluginname: error #%d has occurred", ErrorNumber);
     

    Note that the log messages will be given as provided, the plugin's name will not -automatically be added, so make shure your log messages are obvious enough. +automatically be added, so make sure your log messages are obvious enough. -


    Main menu entry

    +

    Main menu entry

    -
    Today's special is...

    +

    Today's special is...

    If the plugin implements a feature that the user shall be able to access from VDR's main menu, it needs to implement the function -

    +

     virtual const char *MainMenuEntry(void);
     

    @@ -561,7 +581,7 @@ The default implementation returns a NULL pointer, which means that this plugin will not have an item in the main menu. Here's an example of a plugin that will have a main menu item: -

    +

     static const char *MAINMENUENTRY = "Hello";
     
     const char *cPluginHello::MainMenuEntry(void)
    @@ -574,13 +594,13 @@ The menu entries of all plugins will be inserted into VDR's main menu right
     after the Recordings item, in the same sequence as they were given
     in the call to VDR.
     
    -

    User interaction

    +

    User interaction

    -
    It's showtime!

    +

    It's showtime!

    If the user selects the main menu entry of a plugin, VDR calls the function -

    +

     virtual cOsdObject *MainMenuAction(void);
     

    @@ -607,14 +627,14 @@ interaction is possible. If a specific action takes longer than a few seconds, the plugin should launch a separate thread to do this. -


    Housekeeping

    +

    Housekeeping

    -
    Chores, chores...

    +

    Chores, chores...

    From time to time a plugin may want to do some regular tasks, like cleaning up some files or other things. In order to do this it can implement the function -

    +

     virtual void Housekeeping(void);
     

    @@ -632,9 +652,9 @@ interaction is possible. If a specific action takes longer than a few seconds, the plugin should launch a separate thread to do this. -


    Main thread hook

    +

    Main thread hook

    -
    Pushing in...

    +

    Pushing in...

    Normally a plugin only reacts on user input if directly called through its main menu entry, or performs some background @@ -642,7 +662,7 @@ activity in a separate thread. However, sometimes a plugin may need to do something in the context of the main program thread, without being explicitly called up by the user. In such a case it can implement the function -

    +

     virtual void MainThreadHook(void);
     

    @@ -653,21 +673,21 @@ second. as soon as possible! If you spend too much time in this function, the user interface performance will become sluggish! -


    Activity

    +

    Activity

    -
    Now is not a good time!

    +

    Now is not a good time!

    If a plugin is running a background task that should be finished before shutting down the system, it can implement the function -

    +

     virtual cString Active(void);
     

    which shall return an empty string if it is ok to shut down, and a proper message if not: -

    +

     cString cDoSomethingPlugin::Active(void)
     {
       if (busy)
    @@ -689,15 +709,15 @@ 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.
     
    -

    Wakeup

    +

    Wakeup

    -
    Wake me up before you go-go

    +

    Wake me up before you go-go

    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 -

    +

     virtual time_t WakeupTime(void);
     

    @@ -706,7 +726,7 @@ is planned. VDR will pass the most recent wakeup time of all plugins, or the nex timer time, whichever comes first, to the shutdown script. The following sample will wake up VDR every night at 1:00: -

    +

     time_t MyPlugin::WakeupTime(void)
     {
       time_t Now = time(NULL);
    @@ -722,14 +742,14 @@ return a string when Active() is called at that time, otherwise VDR may
     again instantly. If WakeupTime() returns a time that is not in
     the future, the time will be ignored.
     
    -

    Setup parameters

    +

    Setup parameters

    -
    Remember me...

    +

    Remember me...

    If a plugin requires its own setup parameters, it needs to implement the following functions to handle these parameters: -

    +

     virtual cMenuSetupPage *SetupMenu(void);
     virtual bool SetupParse(const char *Name, const char *Value);
     

    @@ -744,7 +764,7 @@ an error. If false is returned, an error message will be written to the log file (and program execution will continue). A possible implementation of SetupParse() could look like this: -

    +

     bool cPluginHello::SetupParse(const char *Name, const char *Value)
     {
       // Parse your own setup parameters and store their values.
    @@ -770,7 +790,7 @@ plugins need not worry about this.
     

    To store its values in the global setup, a plugin has to call the function -

    +

     void SetupStore(const char *Name, type Value);
     

    @@ -795,15 +815,15 @@ needs setup parameters that are not directly user adjustable. It can use SetupStore() and SetupParse() without presenting these parameters to the user. -


    The Setup menu

    +

    The Setup menu

    -
    Have it your way!

    +

    Have it your way!

    To implement a Setup menu, a plugin needs to derive a class from cMenuSetupPage and implement its constructor and the pure virtual Store() member function: -

    +

     int GreetingTime = 3;
     int UseAlternateGreeting = false;
     
    @@ -853,9 +873,9 @@ You can first assign the temporary values to the global variables and then do th
     your setup parameters and use that one to copy all parameters with one single statement
     (like VDR does with its cSetup class).
     
    -

    Configuration files

    +

    Configuration files

    -
    I want my own stuff!

    +

    I want my own stuff!

    There may be situations where a plugin requires configuration files of its own, maybe for data that can't be stored in the simple setup parameters @@ -864,7 +884,7 @@ configuration file. While the plugin is free to store such files anywhere it sees fit, it might be a good idea to put them in a common place, preferably where other configuration data already exists. VDR provides the function -

    +

     const char *ConfigDirectory(const char *PluginName = NULL);
     

    @@ -887,7 +907,7 @@ these in a subdirectory of its own, named after the plugin. To easily get such a the ConfigDirectory() function can be given an additional string that will be appended to the returned directory name, as in -

    +

     const char *MyConfigDir = ConfigDirectory(Name());
     

    @@ -904,19 +924,19 @@ The ConfigDirectory() function is a static member function of the c class. This allows it to be called even from outside any member function of the derived plugin class, by writing -

    +

     const char *MyConfigDir = cPlugin::ConfigDirectory();
     

    -


    Internationalization

    +

    Internationalization

    -
    Welcome to Babylon!

    +

    Welcome to Babylon!

    If a plugin displays texts to the user, it should prepare for internationalization of these texts. All that is necessary for this is to mark every text that is presented to the user as translatable, as in -

    +

     const char *s = tr("Hello world!");
     

    @@ -931,7 +951,7 @@ Sometimes texts are stored in an array, in which case they need to be marked differently, using the trNOOP() macro. The actual translation is then done when such a text is used, as in -

    +

     const char *Texts = {
       trNOOP("First text"),
       trNOOP("Second text"),
    @@ -954,9 +974,9 @@ and are defined in VDR/tools.h.
     Most of the time a plugin doesn't need to care about this, but when it comes to
     handling individual characters these functions may come in handy.
     
    -

    Custom services

    +

    Custom services

    -
    What can I do for you?

    +

    What can I do for you?

    In some situations, two plugins may want to communicate directly, talking about things that VDR doesn't handle itself. For example, a plugin may want to use features @@ -964,7 +984,7 @@ that some other plugin offers, or it may want to inform other plugins about impo things it does. To receive requests or messages, a plugin can implement the following function: -

    +

     virtual bool Service(const char *Id, void *Data = NULL);
     

    @@ -981,7 +1001,7 @@ otherwise. The plugins have to agree in which situations the service may be called, for example whether the service may be called from every thread, or just from the main thread. A possible implementation could look like this: -

    +

     struct Hello_SetGreetingTime_v1_0 {
       int NewGreetingTime;
       };
    @@ -1004,7 +1024,7 @@ this as a 'service supported' check without performing any actions.
     To send messages to, or request services from a specific plugin, one plugin can directly
     call another plugin's service function:
     
    -

    +

     Hello_SetGreetingTime_v1_0 hellodata;
     hellodata.NewGreetingTime = 3;
     cPlugin *Plugin = cPluginManager::GetPlugin("hello");
    @@ -1022,21 +1042,21 @@ To send a message to all plugins, a plugin can call the function
     cPluginManager::CallAllServices(). This function returns true if
     any plugin handled the request, or false if no plugin handled the request.
     
    -

    SVDRP commands

    +

    SVDRP commands

    -
    Infinite Diversity in Infinite Combinations

    +

    Infinite Diversity in Infinite Combinations

    A plugin can implement its own SVDRP commands through the two functions -

    +

     virtual const char **SVDRPHelpPages(void);
    -virtual cString SVDRPCommand(const char *Cmd, const char *Option, int &ReplyCode);
    +virtual cString SVDRPCommand(const char *Cmd, const char *Option, int &ReplyCode);
     

    The SVDRPHelpPages() function must return a pointer to a list of help strings for all of the plugin's SVDRP commands, like this -

    +

     const char **cPluginSvdrpdemo::SVDRPHelpPages(void)
     {
       static const char *HelpPages[] = {
    @@ -1067,8 +1087,8 @@ The actual processing of SVDRP commands for a plugin is done in its
     Here's an example of such a function, which implements the commands advertised in
     the above help texts:
     
    -

    -cString cPluginSvdrpdemo::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
    +

    +cString cPluginSvdrpdemo::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
     {
       if (strcasecmp(Command, "DATE") == 0) {
          // we use the default reply code here
    @@ -1113,26 +1133,26 @@ The returned string may consist of several lines, separated by the newline chara
     when presenting them to the caller, and the continuation character ('-')
     will be set for all but the last one.
     
    -

    Loading plugins into VDR

    +

    Loading plugins into VDR

    -
    Saddling up!

    +

    Saddling up!

    Plugins are loaded into VDR using the command line option -P, as in -

    +

     vdr -Phello
     

    If the plugin accepts command line options, they are given as part of the argument to the -P option, which then has to be enclosed in quotes: -

    +

     vdr -P"hello -a abc -b"
     

    Any number of plugins can be loaded this way, each with its own -P option: -

    +

     vdr -P"hello -a abc -b" -Pdvd -Pmp3
     

    @@ -1140,7 +1160,7 @@ If you are not starting VDR from the VDR source directory (and thus your plugins cannot be found at their default location) you need to tell VDR the location of the plugins through the -L option: -

    +

     vdr -L/usr/lib/vdr -Phello
     

    @@ -1153,9 +1173,9 @@ in the default or given directory that match the VDR plugin naming convention, and display their help and/or version information in addition to its own output. -


    Building the distribution package

    +

    Building the distribution package

    -
    Let's get this show on the road!

    +

    Let's get this show on the road!

    If you want to make your plugin available to other VDR users, you'll need to make a package that can be easily distributed. @@ -1165,30 +1185,30 @@ provides the target dist, which does this for you.

    Simply change into your source directory and execute make dist: -

    +

     cd VDR/PLUGINS/src/hello
     make dist
     

    After this you should find a file named like -

    +

     vdr-hello-0.0.1.tgz
     

    in your source directory, where hello will be replaced with your actual plugin's name, and 0.0.1 will be your plugin's current version number. -


    Part II - The Internal Interface

    +

    Part II - The Internal Interface

    -

    Status monitor

    +

    Status monitor

    -
    A piece of the action

    +

    A piece of the action

    If a plugin wants to get informed on various events in VDR, it can derive a class from cStatus, as in -

    +

     #include <vdr/status.h>
     
     class cMyStatusMonitor : public cStatus {
    @@ -1208,7 +1228,7 @@ void cMyStatusMonitor::ChannelSwitch(const cDevice *Device, int ChannelNumber)
     An object of this class will be informed whenever the channel is switched on one of
     the DVB devices. It could be used in a plugin like this:
     
    -

    +

     #include <vdr/plugin.h>
     
     class cPluginStatus : public cPlugin {
    @@ -1254,14 +1274,14 @@ See the file status.h for detailed information on which status monitor
     member functions are available in cStatus. You only need to implement
     the functions you actually want to use.
     
    -

    Players

    +

    Players

    -
    Play it again, Sam!

    +

    Play it again, Sam!

    Implementing a player is a two step process. First you need the actual player class, which is derived from the abstract cPlayer: -

    +

     #include <vdr/player.h>
     
     class cMyPlayer : public cPlayer {
    @@ -1277,7 +1297,7 @@ What exactly you do in this class is entirely up to you. If you want to run a se
     thread which, e.g.,  reads data from a file, you can additionally derive your class from
     cThread and implement the necessary functionality:
     
    -

    +

     #include <vdr/player.h>
     
     class cMyPlayer : public cPlayer, cThread {
    @@ -1295,7 +1315,7 @@ its own player for the VDR recordings.
     

    To play the actual data, the player needs to call its member function -

    +

     int PlayPes(const uchar *Data, int Length, bool VideoOnly);
     

    @@ -1308,7 +1328,7 @@ desired data stream, and it must be delivered fast enough so that the DVB device doesn't run out of data. To avoid busy loops the player should call its member function -

    +

     bool DevicePoll(cPoller &Poller, int TimeoutMs = 0);
     

    @@ -1320,14 +1340,14 @@ If the player can provide more than a single audio track, and has special requirements in order to set a given track, it can implement the following function to allow the device to set a specific track: -

    +

     virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId)
     

    A player that has special requirements about audio tracks should announce its available audio tracks by calling -

    +

     bool DeviceSetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, const char *Description = NULL)
     

    @@ -1336,7 +1356,7 @@ See device.h for details about the parameters for track handling. The second part needed here is a control object that receives user input from the main program loop and reacts on this by telling the player what to do: -

    +

     #include <vdr/player.h>
     
     class cMyControl : public cControl {
    @@ -1355,7 +1375,7 @@ public:
     hand over a pointer to it to the cControl base class, so that it
     can be later attached to the primary DVB device:
     
    -

    +

     cMyControl::cMyControl(void)
     :cControl(player = new cMyPlayer)
     {
    @@ -1386,7 +1406,7 @@ Finally, to get things going, a plugin that implements a player (and the surroun
     infrastructure like displaying a list of playable stuff etc) simply has to call the
     static function cControl::Launch() with the player control object, as in
     
    -

    +

     cControl::Launch(new cMyControl);
     

    @@ -1397,7 +1417,7 @@ use the primary DVB device, or the user decides to start a different replay).

    The cPlayer class has a member function -

    +

     void DeviceStillPicture(const uchar *Data, int Length);
     

    @@ -1435,14 +1455,14 @@ enjoy additional players, since they will be able to control them with actions that they already know. If you absolutely want to do things differently, just go ahead - it's your show... -


    Receivers

    +

    Receivers

    -
    Tapping into the stream...

    +

    Tapping into the stream...

    In order to receive any kind of data from a cDevice, a plugin must set up an object derived from the cReceiver class: -

    +

     #include <vdr/receiver.h>
     
     class cMyReceiver : public cReceiver, cThread {
    @@ -1486,7 +1506,7 @@ a cReceiver to be detached from its cDevice at any time.
     Once a cReceiver has been created, it needs to be attached to
     a cDevice:
     
    -

    +

     cMyReceiver *Receiver = new cMyReceiver(123);
     
     cDevice::ActualDevice()->AttachReceiver(Receiver);
    @@ -1500,15 +1520,15 @@ Mode).
     If the cReceiver isn't needed any more, it may simply be deleted
     and will automatically detach itself from the cDevice.
     
    -

    Filters

    +

    Filters

    -
    A Fistful of Data

    +

    A Fistful of Data

    If you want to receive section data you have to implement a derived cFilter class which at least implements the Process() function and a constructor that sets the (initial) filter parameters: -

    +

     #include <vdr/filter.h>
     
     class cMyFilter : public cFilter {
    @@ -1533,7 +1553,7 @@ void cMyFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
     An instance of such a filter needs to be attached to the device from
     which it shall receive data, as in
     
    -

    +

     cMyFilter *Filter = new cMyFilter();
     
     cDevice::ActualDevice()->AttachFilter(Filter);
    @@ -1544,14 +1564,14 @@ and will automatically detach itself from the cDevice.
     

    See VDR/eit.c or VDR/pat.c to learn how to process filter data. -


    The On Screen Display

    +

    The On Screen Display

    -
    Window to the world

    +

    Window to the world

    If a plugin needs to have total control over the OSD, it can call the static function -

    +

     #include <vdr/osd.h>
     
     cOsd *MyOsd = cOsdProvider::NewOsd(x, y);
    @@ -1561,7 +1581,7 @@ where x and y are the coordinates of the upper left corner
     of the OSD area on the screen. Such an OSD doesn't display anything
     yet, so you need to at least call the function
     
    -

    +

     tArea Area = { 0, 0, 100, 100, 4 };
     MyOsd->SetAreas(&Area, 1);
     

    @@ -1580,7 +1600,7 @@ Since it is often not really necessary to have hundreds or thousands of colors all over the OSD area, a plugin can divide the total drawing area into several sub-areas with different color depths and separate color palettes, as in -

    +

     tArea Area = { 0, 0, 99, 99, 4 };
     if (osd->CanHandleAreas(Area, 1) == oeOk)
        osd->SetAreas(&Area, 1);
    @@ -1615,7 +1635,7 @@ color. In order to not use up the whole color palette for a single color
     combination (and thus be unable to draw any other colors at all), it may be
     useful to call
     
    -

    +

     osd->SetAntiAliasGranularity();
     

    @@ -1629,15 +1649,15 @@ function, or any of the skin classes a plugin might implement. If a plugin runs a separate thread and wants to issue a message directly from within that tread, it can call -

    +

     int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds = 0, int Timeout = 0);
     

    to queue that message for display. See VDR/skins.h for details. -


    Skins

    +

    Skins

    -
    The emperor's new clothes

    +

    The emperor's new clothes

    The way VDR displays its menus to the user is implemented through skins. A particular skin provides several functions that return objects to be used @@ -1652,7 +1672,7 @@ arbitrary skin of its own by doing something similar to what's done in The first step in implementing a new skin is to derive a class from cSkin that provides the handling objects necessary to do the actual work: -

    +

     #include "skins.h"
     
     class cMySkin : public cSkin {
    @@ -1676,7 +1696,7 @@ if you want to make the colors used by your skin configurable.
     To add your new skin to the list of skins available to the user in Setup/OSD/Skin,
     all you need to do is create a new object of your skin class, as in
     
    -

    +

     new cMySkin;
     

    @@ -1686,15 +1706,15 @@ Do not delete this object, it will be automatically deleted when the program end In order to be able to easily identify plugins that implement a skin it is recommended that the name of such a plugin should be -

    +

     skinxyz
     

    where xyz is the actual name of the skin. -


    Themes

    +

    Themes

    -
    Eye of the beholder...

    +

    Eye of the beholder...

    A theme is a collection of colors that can be used by a skin. Since every skin most likely has its own idea about what parts of it can be @@ -1705,13 +1725,13 @@ will be actually used can be defined in Setup/OSD/Theme.

    In order to make a skin "themeable" is shall create an object of type cTheme, as in -

    +

     static cTheme Theme;
     

    The next step is to define the colors that shall be provided by this theme, as in -

    +

     THEME_CLR(Theme, clrTitle,        0xFFBC8024);
     THEME_CLR(Theme, clrButtonRedFg,  clrWhite);
     THEME_CLR(Theme, clrButtonRedBg,  clrRed);
    @@ -1732,7 +1752,7 @@ and Blue component, respectively), or one of the predefined color names from
     In the actual drawing code of a skin, the color names defined with the THEME_CLR()
     macros can be used to fetch the actual color values from the theme, as in
     
    -

    +

     osd->DrawText(x, y, s, Theme.Color(clrButtonRedFg), Theme.Color(clrButtonRedBg), font);
     

    @@ -1740,9 +1760,9 @@ By default this will use the colors that have been defined in the respective THEME_CLR() line, but may be overwritten through user supplied theme files (see man vdr(5) for information about the format of a theme file). -


    Devices

    +

    Devices

    -
    Expanding the possibilities

    +

    Expanding the possibilities

    By default VDR is based on using DVB PCI cards that are supported by the LinuxDVB driver. However, a plugin can implement additional devices that @@ -1756,7 +1776,7 @@ stream and displays it, for instance, on an existing graphics adapter.

    To implement an additional device, a plugin must derive a class from cDevice: -

    +

     #include <vdr/device.h>
     
     class cMyDevice : public cDevice {
    @@ -1775,7 +1795,7 @@ the cDvbDevice, which is used to access the DVB PCI cards.
     If the new device can receive, it most likely needs to provide a way of
     selecting which channel it shall tune to:
     
    -

    +

     virtual bool ProvidesSource(int Source) const;
     virtual bool ProvidesTransponder(const cChannel *Channel) const;
     virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
    @@ -1791,7 +1811,7 @@ respectively.
     If the device can provide more than a single audio track, it can implement the
     following function to make them available:
     
    -

    +

     virtual void SetAudioTrackDevice(eTrackType Type);
     virtual int GetAudioChannelDevice(void);
     virtual void SetAudioChannelDevice(int AudioChannel);
    @@ -1802,7 +1822,7 @@ virtual void SetAudioChannelDevice(int AudioChannel);
     

    A device that can be used for recording must implement the functions -

    +

     virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
     virtual bool OpenDvr(void);
     virtual void CloseDvr(void);
    @@ -1819,7 +1839,7 @@ must deliver exactly one such packet (if one is currently available).
     

    The functions to implement replaying capabilities are -

    +

     virtual bool HasDecoder(void) const;
     virtual bool CanReplay(void) const;
     virtual bool SetPlayMode(ePlayMode PlayMode);
    @@ -1838,7 +1858,7 @@ virtual int PlayVideo(const uchar *Data, int Length);
     In addition, the following functions may be implemented to provide further
     functionality:
     
    -

    +

     virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
     virtual void SetVideoFormat(bool VideoFormat16_9);
     virtual void SetVolumeDevice(int Volume);
    @@ -1850,7 +1870,7 @@ virtual void SetVolumeDevice(int Volume);
     If your device provides section filtering capabilities it can implement
     the functions
     
    -

    +

     virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
     virtual void CloseFilter(int Handle);
     

    @@ -1861,7 +1881,7 @@ filter parameters. In order to actually start section handling, the device also needs to call the function -

    +

     StartSectionHandler();
     

    @@ -1879,7 +1899,7 @@ an "OSD provider" class, derived from cOsdProvider, which, when its cOsd, which can be used to access the device's OSD: -

    +

     class cMyOsdProvider : public cOsdProvider {
     public:
       cMyOsdProvider(void);
    @@ -1890,7 +1910,7 @@ public:
     In its MakePrimaryDevice() function the device shall create an object
     of this class, as in
     
    -

    +

     void cMyDevice::MakePrimaryDevice(bool On)
     {
       new cMyOsdProvider;
    @@ -1927,9 +1947,9 @@ shut down (delete) all devices when the program terminates. It is therefore
     important that the devices are created on the heap, using the new
     operator!
     
    -

    Audio

    +

    Audio

    -
    "The stereo effect may only be experienced if stereo equipment is used!"

    +

    "The stereo effect may only be experienced if stereo equipment is used!"

    There are many different ways to replay additional audio tracks, like Dolby Digital. So VDR offers a plugin interface that allows for the implementation of any kind of @@ -1938,7 +1958,7 @@ audio replay facility. To implement a new audio output facility, simply derive a class from cAudio, as in -

    +

     #include <vdr/audio.h>
     #include <vdr/thread.h>
     
    @@ -1970,9 +1990,9 @@ will need to copy it for later processing in your thread.
     The Mute() and Clear() functions will be called whenever the audio shall
     be muted, or any buffered data shall be cleared, respectively.
     
    -

    Remote Control

    +

    Remote Control

    -
    The joy of zapping!

    +

    The joy of zapping!

    There are several ways to control the operation of VDR. The builtin methods are using the PC keyboard, a homebuilt RCU unit or the LIRC interface. @@ -1982,7 +2002,7 @@ remote control, so a plugin can use the cRemote class to do that. The simplest method for a plugin to issue commands to VDR is to call the static function cRemote::Put(eKeys Key), as in -

    +

     cRemote::Put(kUp);
     

    @@ -1994,7 +2014,7 @@ In cases where the incoming codes are not known, or not all available keys may be supported by the actual remote control in use, you may want to derive your own remote control class from cRemote, as in -

    +

     #include <vdr/remote.h>
     #include <vdr/thread.h>
     
    @@ -2019,7 +2039,7 @@ when the program ends).
     

    The constructor of your remote control class should look like this -

    +

     cMyRemote::cMyRemote(const char *Name)
     :cRemote(Name)
     {
    @@ -2039,7 +2059,7 @@ member variables, you should do so before calling Start().
     If your remote control for some reason can't work (maybe because it was unable to
     open some file handle it requires) it can implement the virtual function
     
    -

    +

     virtual bool Ready(void);
     

    @@ -2060,7 +2080,7 @@ If your remote control class needs some setup data that shall be readily available next time VDR starts (without having to go through the initialization procedure again) it can use the cRemote member functions -

    +

     void PutSetup(const char *Setup);
     const char *GetSetup(void);
     

    @@ -2074,7 +2094,7 @@ The cRemote class assumes that any incoming remote control code can be expressed as a character string. So whatever data your remote control provides needs to be given to the base class by calling -

    +

     Put(const char *Code, bool Repeat = false, bool Release = false);
     

    @@ -2085,15 +2105,15 @@ Since a common case for remote control data is to be given as a numerical value, there is another Put() function available for your convenience, which takes a 64 bit unsigned integer value instead of a character string: -

    +

     Put(uint64 Code, bool Repeat = false, bool Release = false);
     

    The other parameters have the same meaning as in the first version of this function. -


    Conditional Access

    +

    Conditional Access

    -
    Members only!

    +

    Members only!

    Pay TV providers usually encrypt their broadcasts, so that only viewers who have the proper smart card can watch them. Such a smart card needs to be inserted @@ -2120,7 +2140,7 @@ several low level functions that handle the actual data transfer (see dvbci. for example). The decision whether the adapter can actually be assigned to different devices is made in the function -

    +

     virtual bool Assign(cDevice *Device, bool Query = false);