Updated The VDR Plugin System (markdown)

Manuel Reimer 2023-09-19 10:35:22 +02:00
parent 641cc4c634
commit 64bbb2f651

@ -78,9 +78,9 @@ structures and allows it to hook itself into specific areas to perform special a
</ul>
</ul>
<hr><h1><a name="Part I - The External Interface">Part I - The External Interface</a></h1>
<hr><h1>Part I - The External Interface</h1>
<hr><h2><a name="Quick start">Quick start</a></h2>
<hr><h2>Quick start</h2>
<div>Can't wait, can't wait!</div><p>
@ -102,7 +102,7 @@ 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.
<hr><h2><a name="The name of the plugin">The name of the plugin</a></h2>
<hr><h2>The name of the plugin</h2>
<div>Give me some I.D.!</div><p>
@ -126,7 +126,7 @@ const char *Name(void);
The actual name is derived from the plugin's library file name, as defined in the
next chapter.
<hr><h2><a name="The plugin directory structure">The plugin directory structure</a></h2>
<hr><h2>The plugin directory structure</h2>
<div>Where is everybody?</div><p>
@ -156,7 +156,7 @@ for how to generate an example Makefile.
The <tt>lib</tt> directory contains the dynamically loadable libraries of all
available plugins. Note that the names of these files are created by concatenating
<p>
<table border=2>
<table>
<tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>hello</tt></b></td><td align=center><b><tt>.so.</tt></b></td><td align=center><b><tt>1.1.0</tt></b></td></tr>
<tr><td align=center><small>VDR plugin<br>library prefix</small></td><td align=center><small>name of<br>the plugin</small></td><td align=center><small>shared object<br>indicator</small></td><td align=center><small>API version number<br>this plugin was<br>compiled for</small></td></tr>
</table>
@ -210,7 +210,7 @@ additional libraries <tt>foo</tt> and <tt>bar</tt>, the names would be
<tt>libhello-bar.so.0.0.1</tt>
<p>
<hr><h2><a name="Initializing a new plugin directory">Initializing a new plugin directory</a></h2>
<hr><h2>Initializing a new plugin directory</h2>
<div>A room with a view</div><p>
@ -229,7 +229,7 @@ have other plans.
Add further files and maybe subdirectories to your plugin source directory as
necessary. Don't forget to adapt the <tt>Makefile</tt> appropriately.
<hr><h2><a name="The actual implementation">The actual implementation</a></h2>
<hr><h2>The actual implementation</h2>
<div>Use the source, Luke!</div><p>
@ -296,7 +296,7 @@ and implements a file named <tt>i18n.h</tt>. To make sure it won't clash with VD
<tt>i18n.h</tt> it uses the macro <tt>_I18N__H</tt> (one underline at the beginning
and two replacing the dot).
<hr><h2><a name="Construction and Destruction">Construction and Destruction</a></h2>
<hr><h2>Construction and Destruction</h2>
<div>What goes up, must come down...</div><p>
@ -325,7 +325,7 @@ 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.
<hr><h2><a name="Version number">Version number</a></h2>
<hr><h2>Version number</h2>
<div>Which incarnation is this?</div><p>
@ -371,7 +371,7 @@ while those with <i>odd</i> release numbers (like <tt>1.1.x</tt>, <tt>1.3.x</tt>
a version number are not limited to single digits, so a version number of <tt>1.2.15</tt>
would be acceptable.
<hr><h2><a name="Description">Description</a></h2>
<hr><h2>Description</h2>
<div>What is it that you do?</div><p>
@ -395,7 +395,7 @@ virtual const char *Description(void)
Note the <tt>tr()</tt> around the <tt>DESCRIPTION</tt>, which allows the description
to be <a href="#Internationalization">internationalized</a>.
<hr><h2><a name="Command line arguments">Command line arguments</a></h2>
<hr><h2>Command line arguments</h2>
<div>Taking orders</div><p>
@ -449,7 +449,7 @@ correctly, or <i>false</i> in case of an error. The first plugin that returns
<i>false</i> from a call to its <tt>ProcessArgs()</tt> function will cause VDR
to exit.
<hr><h2><a name="Command line help">Command line help</a></h2>
<hr><h2>Command line help</h2>
<div>Tell me about it...</div><p>
@ -478,7 +478,7 @@ 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.
<hr><h2><a name="Getting started">Getting started</a></h2>
<hr><h2>Getting started</h2>
<div>Let's get ready to rumble!</div><p>
@ -516,7 +516,7 @@ 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.
<hr><h2><a name="Shutting down">Shutting down</a></h2>
<hr><h2>Shutting down</h2>
<div>Stop it, right there!</div><p>
@ -533,7 +533,7 @@ The <tt>Stop()</tt> function will only be called if a previous call to the
returned <i>true</i>. The <tt>Stop()</tt> functions are called in the reverse order
as the <a href="#Getting started"><tt>Start()</tt></a> functions were called.
<hr><h2><a name="Logging">Logging</a></h2>
<hr><h2>Logging</h2>
<div>Traces in the sand...</div><p>
@ -579,7 +579,7 @@ purpose of the plugin to display something on stdout, like for instance the
Please make any log messages in <b>ENGLISH</b>! Logs are usually sent to the developers
of a program, and they may not be able to read them if they are in an exotic language.
<hr><h2><a name="Main menu entry">Main menu entry</a></h2>
<hr><h2>Main menu entry</h2>
<div>Today's special is...</div><p>
@ -607,7 +607,7 @@ The menu entries of all plugins will be inserted into VDR's main menu right
after the <i>Recordings</i> item, in the same sequence as they were given
in the call to VDR.
<hr><h2><a name="User interaction">User interaction</a></h2>
<hr><h2>User interaction</h2>
<div>It's showtime!</div><p>
@ -640,7 +640,7 @@ interaction is possible. If a specific action takes longer than a few seconds,
the plugin should launch a separate thread to do this.
</b>
<hr><h2><a name="Housekeeping">Housekeeping</a></h2>
<hr><h2>Housekeeping</h2>
<div>Chores, chores...</div><p>
@ -665,7 +665,7 @@ interaction is possible. If a specific action takes longer than a few seconds,
the plugin should launch a separate thread to do this.
</b>
<hr><h2><a name="Main thread hook">Main thread hook</a></h2>
<hr><h2>Main thread hook</h2>
<div>Pushing in...</div><p>
@ -686,7 +686,7 @@ second.
as soon as possible! If you spend too much time in this function, the user
interface performance will become sluggish!</b>
<hr><h2><a name="Activity">Activity</a></h2>
<hr><h2>Activity</h2>
<div>Now is not a good time!</div><p>
@ -722,7 +722,7 @@ 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.
<hr><h2><a name="Wakeup">Wakeup</a></h2>
<hr><h2>Wakeup</h2>
<div>Wake me up before you go-go</div><p>
@ -755,7 +755,7 @@ return a string when <tt>Active()</tt> is called at that time, otherwise VDR may
again instantly. If <tt>WakeupTime()</tt> returns a time that is not in
the future, the time will be ignored.
<hr><h2><a name="Setup parameters">Setup parameters</a></h2>
<hr><h2>Setup parameters</h2>
<div>Remember me...</div><p>
@ -828,7 +828,7 @@ needs setup parameters that are not directly user adjustable. It can use
<tt>SetupStore()</tt> and <tt>SetupParse()</tt> without presenting these
parameters to the user.
<hr><h2><a name="The Setup menu">The Setup menu</a></h2>
<hr><h2>The Setup menu</h2>
<div>Have it your way!</div><p>
@ -886,7 +886,7 @@ 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).
<hr><h2><a name="Additional files">Additional files</a></h2>
<hr><h2>Additional files</h2>
<div>I want my own stuff!</div><p>
@ -952,7 +952,7 @@ called even from outside any member function of the derived plugin class, by wri
const char *MyConfigDir = cPlugin::ConfigDirectory();
</pre>
<hr><h2><a name="Internationalization">Internationalization</a></h2>
<hr><h2>Internationalization</h2>
<div>Welcome to Babylon!</div><p>
@ -998,7 +998,7 @@ and are defined in <tt>VDR/tools.h</tt>.
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.
<hr><h2><a name="Custom services">Custom services</a></h2>
<hr><h2>Custom services</h2>
<div>What can I do for you?</div><p>
@ -1066,7 +1066,7 @@ To send a message to all plugins, a plugin can call the function
<tt>cPluginManager::CallAllServices()</tt>. This function returns <tt>true</tt> if
any plugin handled the request, or <tt>false</tt> if no plugin handled the request.
<hr><h2><a name="SVDRP commands">SVDRP commands</a></h2>
<hr><h2>SVDRP commands</h2>
<div>Infinite Diversity in Infinite Combinations</div><p>
@ -1161,7 +1161,7 @@ will be set for all but the last one.
Therefore the plugin needs to take care of proper <a href="#Locking">locking</a> if it accesses any
global data.</b>
<hr><h2><a name="Locking">Locking</a></h2>
<hr><h2>Locking</h2>
<div>U can't touch this</div><p>
@ -1211,7 +1211,7 @@ See tools.h, class <tt>cListBase</tt> for more documentation and information on
to use locking with timeouts, and thread.h, classes <tt>cStateLock</tt> and
<tt>cStateKey</tt> on how to easily react to changes in such lists.
<hr><h2><a name="Loading plugins into VDR">Loading plugins into VDR</a></h2>
<hr><h2>Loading plugins into VDR</h2>
<div>Saddling up!</div><p>
@ -1251,7 +1251,7 @@ in the default or given directory that match the VDR plugin
<a href="#The plugin directory structure">naming convention</a>,
and display their help and/or version information in addition to its own output.
<hr><h2><a name="Building the distribution package">Building the distribution package</a></h2>
<hr><h2>Building the distribution package</h2>
<div>Let's get this show on the road!</div><p>
@ -1277,9 +1277,9 @@ vdr-hello-0.0.1.tgz
in your source directory, where <tt>hello</tt> will be replaced with your actual
plugin's name, and <tt>0.0.1</tt> will be your plugin's current version number.
<hr><h1><a name="Part II - The Internal Interface">Part II - The Internal Interface</a></h1>
<hr><h1>Part II - The Internal Interface</h1>
<hr><h2><a name="Status monitor">Status monitor</a></h2>
<hr><h2>Status monitor</h2>
<div>A piece of the action</div><p>
@ -1352,7 +1352,7 @@ See the file <tt>status.h</tt> for detailed information on which status monitor
member functions are available in <tt>cStatus</tt>. You only need to implement
the functions you actually want to use.
<hr><h2><a name="Players">Players</a></h2>
<hr><h2>Players</h2>
<div>Play it again, Sam!</div><p>
@ -1533,7 +1533,7 @@ 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...
<hr><h2><a name="Receivers">Receivers</a></h2>
<hr><h2>Receivers</h2>
<div>Tapping into the stream...</div><p>
@ -1599,7 +1599,7 @@ Mode</i>).
<p>
The <tt>cReceiver</tt> must be detached from its device before it is deleted.
<hr><h2><a name="Filters">Filters</a></h2>
<hr><h2>Filters</h2>
<div>A Fistful of Data</div><p>
@ -1643,7 +1643,7 @@ and will automatically detach itself from the <tt>cDevice</tt>.
<p>
See VDR/eit.c or VDR/pat.c to learn how to process filter data.
<hr><h2><a name="The On Screen Display">The On Screen Display</a></h2>
<hr><h2>The On Screen Display</h2>
<div>Window to the world</div><p>
@ -1734,7 +1734,7 @@ int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds = 0, int
to queue that message for display. See <tt>VDR/skins.h</tt> for details.
<hr><h2><a name="Skins">Skins</a></h2>
<hr><h2>Skins</h2>
<div>The emperor's new clothes</div><p>
@ -1791,7 +1791,7 @@ skinxyz
where <tt>xyz</tt> is the actual name of the skin.
<hr><h2><a name="Themes">Themes</a></h2>
<hr><h2>Themes</h2>
<div>Eye of the beholder...</div><p>
@ -1839,7 +1839,7 @@ By default this will use the colors that have been defined in the respective
<tt>THEME_CLR()</tt> line, but may be overwritten through user supplied theme
files (see <tt>man vdr(5)</tt> for information about the format of a theme file).
<hr><h2><a name="Devices">Devices</a></h2>
<hr><h2>Devices</h2>
<div>Expanding the possibilities</div><p>
@ -2090,7 +2090,7 @@ new cMyDeviceHook;
and shall not delete this object. It will be automatically deleted when the program ends.
<hr><h2><a name="Positioners">Positioners</a></h2>
<hr><h2>Positioners</h2>
<div>Now you see me - now you don't!</div><p>
@ -2129,7 +2129,7 @@ Note that the object has to be created on the heap (using <tt>new</tt>),
and you shall not delete it at any point (it will be deleted automatically
when the program ends).
<hr><h2><a name="Audio">Audio</a></h2>
<hr><h2>Audio</h2>
<div>"The stereo effect may only be experienced if stereo equipment is used!"</div><p>
@ -2172,7 +2172,7 @@ will need to copy it for later processing in your thread.
The <tt>Mute()</tt> and <tt>Clear()</tt> functions will be called whenever the audio shall
be muted, or any buffered data shall be cleared, respectively.
<hr><h2><a name="Remote Control">Remote Control</a></h2>
<hr><h2>Remote Control</h2>
<div>The joy of zapping!</div><p>
@ -2298,7 +2298,7 @@ if a key is held pressed down for a while, your derived class should use the glo
parameters <tt>Setup.RcRepeatDelay</tt> and <tt>Setup.RcRepeatDelta</tt> to allow
users to configure the behavior of this function.
<hr><h2><a name="Conditional Access">Conditional Access</a></h2>
<hr><h2>Conditional Access</h2>
<div>Members only!</div><p>
@ -2333,7 +2333,7 @@ virtual bool Assign(cDevice *Device, bool Query = false);
See the description of this function in <tt>ci.h</tt> for details.
<hr><h2><a name="Electronic Program Guide">Electronic Program Guide</a></h2>
<hr><h2>Electronic Program Guide</h2>
<div>The grass is always greener on the other side...</div><p>
@ -2363,7 +2363,7 @@ to signal VDR that no other EPG handlers shall be queried after this one.
<p>
See <tt>VDR/epg.h</tt> for details.
<hr><h2><a name="The video directory">The video directory</a></h2>
<hr><h2>The video directory</h2>
<div>Bits and pieces...</div><p>