From 046b7f062e016a50ba3aa98a41c914cea05cf93a Mon Sep 17 00:00:00 2001 From: Manuel Reimer Date: Tue, 19 Sep 2023 10:21:33 +0200 Subject: [PATCH] Updated The VDR Plugin System (markdown) --- The-VDR-Plugin-System.md | 408 +++++++++++++++++++-------------------- 1 file changed, 204 insertions(+), 204 deletions(-) diff --git a/The-VDR-Plugin-System.md b/The-VDR-Plugin-System.md index 4834be8..ee0f211 100644 --- a/The-VDR-Plugin-System.md +++ b/The-VDR-Plugin-System.md @@ -119,9 +119,9 @@ 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. @@ -134,12 +134,12 @@ 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
 VDR/PLUGINS/lib/libvdr-hello.so.1.1.0
-

+

The src directory contains one subdirectory for each plugin, which carries the name of that plugin (in the above example that would be hello). @@ -190,9 +190,9 @@ 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
-

+

Since the VDR Makefile only searches for directories with names consisting of only lowercase characters and digits, it will only follow the symbolic links, which @@ -254,9 +254,9 @@ 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);
-

+

This is the "magic" hook that allows VDR to actually load the plugin into its memory. You don't need to worry about the details behind all this. @@ -267,14 +267,14 @@ 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
 
 ...
 
 #endif //__I18N_H
-

+

The example shown here is the way VDR does this in its core source files. It takes the header file's name, converts it to all uppercase, replaces the @@ -302,10 +302,10 @@ and two replacing the dot). The constructor and destructor of a plugin are defined as -

+

 cPlugin(void);
 virtual ~cPlugin();
-

+

The constructor shall initialize any member variables the plugin defines, but must not access any global structures of VDR. @@ -333,9 +333,9 @@ 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;
-

+

Since this is a "pure" virtual function, any derived plugin class must implement it. The returned string should identify this version of the plugin. @@ -344,14 +344,14 @@ 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)
 {
   return VERSION;
 }
-

+

Note that the definition of the version number is expected to be located in the main source file, and must be written as @@ -377,20 +377,20 @@ would be acceptable. 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)
 {
   return tr(DESCRIPTION);
 }
-

+

Note the tr() around the DESCRIPTION, which allows the description to be internationalized. @@ -403,9 +403,9 @@ 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[]);
-

+

The parameters argc and argv have exactly the same meaning as in a normal C program's main() function. @@ -420,7 +420,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.
@@ -442,7 +442,7 @@ bool cPluginHello::ProcessArgs(int argc, char *argv[])
         }
   return true;
 }
-

+

The return value must be true if all options have been processed correctly, or false in case of an error. The first plugin that returns @@ -455,22 +455,22 @@ to exit. If a plugin accepts command line options, it should implement the function -

+

 virtual const char *CommandLineHelp(void);
-

+

which will be called if the user enters the -h option when starting VDR. 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.
   return "  -a ABC,   --aaa=ABC      do something nice with ABC\n"
          "  -b,       --bbb          activate 'plan B'\n";
 }
-

+

This command line help will be printed directly below VDR's help texts (separated by a line indicating the plugin's name, version and description), so if you use the @@ -486,10 +486,10 @@ 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);
-

+

which are called once for each plugin at program startup. The difference between these two functions is that Initialize() is @@ -522,9 +522,9 @@ texts, it doesn't need to implement either of these functions. If a plugin performs any background tasks, it shall implement the function -

+

 virtual void Stop(void);
-

+

in which it shall stop them.

@@ -547,9 +547,9 @@ 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 log message 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 sure your log messages are obvious enough. @@ -586,22 +586,22 @@ of a program, and they may not be able to read them if they are in an exotic lan 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);
-

+

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)
 {
   return tr(MAINMENUENTRY);
 }
-

+

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 @@ -613,9 +613,9 @@ in the call to VDR. If the user selects the main menu entry of a plugin, VDR calls the function -

+

 virtual cOsdObject *MainMenuAction(void);
-

+

which can do one of three things: