diff --git a/The-VDR-Plugin-System.md b/The-VDR-Plugin-System.md index 361a3b0..a228ffa 100644 --- a/The-VDR-Plugin-System.md +++ b/The-VDR-Plugin-System.md @@ -17,9 +17,9 @@ separate from the core VDR source, without the need of patching the original VDR code (and all the problems of correlating various patches).

This document is divided into two parts, the first one describing the -external interface +external interface of the plugin system, and the second one describing the -internal interface. +internal interface. The external interface handles everything necessary for a plugin to get hooked into the core VDR program and present itself to the user. The internal interface provides the plugin code access to VDR's internal data @@ -28,53 +28,53 @@ structures and allows it to hook itself into specific areas to perform special a


Table Of Contents

@@ -150,7 +150,7 @@ that there is a Makefile that provides the targets all, in loadable library file for that plugin (we'll get to the details later). The dynamically loadable library file for the plugin shall be located directly under the plugin's source directory. -See the section Initializing a new plugin directory +See the section Initializing a new plugin directory for how to generate an example Makefile.

The lib directory contains the dynamically loadable libraries of all @@ -177,7 +177,7 @@ The VDR Makefile contains the target plugins, which calls plus the target clean-plugins, which calls make clean in each of these directories.

-If you download a plugin package +If you download a plugin package from the web, it will typically have a name like

vdr-hello-0.0.1.tgz @@ -234,7 +234,7 @@ necessary. Don't forget to adapt the Makefile appropriately.

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 +If you load it into VDR you will find a new entry in the main menu, with the same name as your plugin (where the first character has been converted to uppercase). There will also be a new entry named "Plugins" in the "Setup" menu, which will bring up a list of all loaded plugins, through which you @@ -291,7 +291,7 @@ up to you. You could, for instance, prepend the macro with a 'P', as in P__I18N_H, or leave out the trailing _H, as in __I18N, or use a completely different way to make sure a header file is included only once.

-The 'hello' example that comes with VDR makes use of internationalization +The 'hello' example that comes with VDR makes use of internationalization and implements a file named i18n.h. To make sure it won't clash with VDR's i18n.h it uses the macro _I18N__H (one underline at the beginning and two replacing the dot). @@ -311,8 +311,8 @@ The constructor shall initialize any member variables the plugin defines, must not access any global structures of VDR. It also must not create any threads or other large data structures. These things are done in the -Initialize() or -Start() +Initialize() or +Start() function later. Constructing a plugin object shall not have any side effects or produce any output, since VDR, for instance, has to create the plugin objects in order to get their @@ -320,7 +320,7 @@ command line help - and after that immediately destroys them again.

The destructor has to clean up any data created by the plugin. Any threads the plugin may have created shall be stopped in the -Stop() function. +Stop() function.

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. @@ -393,7 +393,7 @@ virtual const char *Description(void) Note the tr() around the DESCRIPTION, which allows the description -to be internationalized. +to be internationalized.


Command line arguments

@@ -483,7 +483,7 @@ be shorter than 80 characters.
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, +thread of its own), or wants to make use of internationalization, it needs to implement one of the functions

@@ -529,9 +529,9 @@ virtual void Stop(void);
 in which it shall stop them.
 

The Stop() function will only be called if a previous call to the -Start() function of that plugin has +Start() function of that plugin has returned true. The Stop() functions are called in the reverse order -as the Start() functions were called. +as the Start() functions were called.


Logging

@@ -625,7 +625,7 @@ which can do one of three things: eventually start a custom player to replay a file other than a VDR recording.
  • Return a pointer to a cOsdObject object which will be displayed instead of the normal menu. The derived cOsdObject can open a - raw OSD from within its Show() + raw OSD from within its Show() function (it should not attempt to do so from within its constructor, since at that time the OSD is still in use by the main menu). See the 'osddemo' example that comes with VDR for a demonstration of how this @@ -670,7 +670,7 @@ the plugin should launch a separate thread to do this.
    Pushing in...

    Normally a plugin only reacts on user input if directly called through its -main menu entry, or performs some background +main menu entry, or performs some background 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 @@ -767,7 +767,7 @@ virtual cMenuSetupPage *SetupMenu(void); virtual bool SetupParse(const char *Name, const char *Value);

  • -The SetupMenu() function shall return the plugin's Setup menu +The SetupMenu() function shall return the plugin's Setup menu page, where the user can adjust all the parameters known to this plugin.

    SetupParse() will be called for each parameter the plugin has @@ -789,7 +789,7 @@ bool cPluginHello::SetupParse(const char *Name, const char *Value) It is important to make sure that the parameter names are exactly the same as -used in the Setup menu's Store() function. +used in the Setup menu's Store() function.

    The plugin's setup parameters are stored in the same file as VDR's parameters. In order to allow each plugin (and VDR itself) to have its own set of parameters, @@ -895,7 +895,7 @@ free to store such files anywhere it sees fit, it might be a good idea to put th place, preferably where such data already exists.

    configuration files, maybe for data that can't be stored in the simple -setup parameters of VDR, or maybe because it needs to +setup parameters of VDR, or maybe because it needs to launch other programs that simply need a separate configuration file.

    cache files, to store data so that future requests for that data can be served faster. The data @@ -1158,7 +1158,7 @@ when presenting them to the caller, and the continuation character ('-' will be set for all but the last one.

    The SVDRP functions are called from the separate "SVDRP server handler" thread. -Therefore the plugin needs to take care of proper locking if it accesses any +Therefore the plugin needs to take care of proper locking if it accesses any global data.


    Locking

    @@ -1248,7 +1248,7 @@ There can be any number of -L options, and each of them will app When started with the -h or -V option (for help or version information, respectively), VDR will automatically load all plugins in the default or given directory that match the VDR plugin -naming convention, +naming convention, and display their help and/or version information in addition to its own output.

    Building the distribution package

    @@ -1258,7 +1258,7 @@ and display their help and/or version information in addition to its own output. If you want to make your plugin available to other VDR users, you'll need to make a package that can be easily distributed. The Makefile that has been created by the call to -newplugin +newplugin provides the target dist, which does this for you.

    Simply change into your source directory and execute make dist: @@ -1769,7 +1769,7 @@ public: See the comments in VDR/skins.h for details. VDR/skinclassic.[hc] can be used as an example for how to implement all the necessary classes and -functions to compose a complete skin. See also the chapter about themes +functions to compose a complete skin. See also the chapter about themes 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, @@ -1779,7 +1779,7 @@ all you need to do is create a new object of your skin class, as in new cMySkin; -in the Start() function of your plugin. +in the Start() function of your plugin. Do not delete this object, it will be automatically deleted when the program ends.

    In order to be able to easily identify plugins that implement a skin it is recommended @@ -1795,7 +1795,7 @@ where xyz is the actual name of the skin.

    Eye of the beholder...

    -A theme is a collection of colors that can be used by a skin. +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 themed, and different skins may have completely different numbers of "themeable" parts, a particular theme can only be used with the skin it was designed @@ -1969,7 +1969,7 @@ StartSectionHandler(); from its constructor.

    -See Filters on how to set up actual filters that can +See Filters on how to set up actual filters that can handle section data.

    @@ -2029,9 +2029,9 @@ See VDR/dvbdevice.c for the implementation of the cDvbDevice initialize function.

    A plugin that adds devices to a VDR instance shall call this -function from its Initialize() function +function from its Initialize() function to make sure other plugins that may need to have access to all available devices -will see them in their Start() function. +will see them in their Start() function.

    Nothing needs to be done to shut down the devices. VDR will automatically shut down (delete) all devices when the program terminates. It is therefore @@ -2124,7 +2124,7 @@ public: See the implementation of cDiseqcPositioner in diseqc.c for details.

    You should create your derived positioner object in the -Start() function of your plugin. +Start() function of your plugin. Note that the object has to be created on the heap (using new), and you shall not delete it at any point (it will be deleted automatically when the program ends). @@ -2156,7 +2156,7 @@ public: You should create your derived audio object in the -Start() function of your plugin. +Start() function of your plugin. Note that the object has to be created on the heap (using new), and you shall not delete it at any point (it will be deleted automatically when the program ends). @@ -2214,7 +2214,7 @@ class to work, but typically you may want to have a separate thread running that collects the input and delivers it to the cRemote base class.

    You should create your derived remote control object in the -Start() function of your plugin. +Start() function of your plugin. Note that the object has to be created on the heap (using new), and you shall not delete it at any point (it will be deleted automatically when the program ends). @@ -2392,7 +2392,7 @@ public: See the description in videodir.h for details.

    You should create your derived video directory object in the -Start() function of your plugin. +Start() function of your plugin. Note that the object has to be created on the heap (using new), and you shall not delete it at any point (it will be deleted automatically when the program ends).