mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Improved implementation of setup menus for plugins
This commit is contained in:
parent
0fac78954c
commit
51eb880da0
169
PLUGINS.html
169
PLUGINS.html
@ -15,7 +15,10 @@ VDR code (and all the problems of correlating various patches).
|
|||||||
This document describes the "outside" interface of the plugin system.
|
This document describes the "outside" interface of the plugin system.
|
||||||
It handles everything necessary for a plugin to get hooked into the core
|
It handles everything necessary for a plugin to get hooked into the core
|
||||||
VDR program and present itself to the user.
|
VDR program and present itself to the user.
|
||||||
|
<p>
|
||||||
|
<!--X1.1.1--><table width=100%><tr><td bgcolor=red> </td><td width=100%>
|
||||||
|
Important modifications introduced in version 1.1.1 are marked like this.
|
||||||
|
<!--X1.1.1--></td></tr></table>
|
||||||
<!--<p>TODO: Link to the document about VDR base classes to use when implementing actual functionality (yet to be written).-->
|
<!--<p>TODO: Link to the document about VDR base classes to use when implementing actual functionality (yet to be written).-->
|
||||||
|
|
||||||
<hr><h2>Quick start</h2>
|
<hr><h2>Quick start</h2>
|
||||||
@ -25,12 +28,12 @@ VDR program and present itself to the user.
|
|||||||
Actually you should read this entire document before starting to work with VDR plugins,
|
Actually you should read this entire document before starting to work with VDR plugins,
|
||||||
but you probably want to see something happening right away <tt>;-)</tt>
|
but you probably want to see something happening right away <tt>;-)</tt>
|
||||||
<p>
|
<p>
|
||||||
So, for a quick demonstration of the plugin system, there is a demo plugin called
|
So, for a quick demonstration of the plugin system, there is a sample plugin called
|
||||||
"hello" that comes with the VDR source. To test drive this one, do the following:
|
"hello" that comes with the VDR source. To test drive this one, do the following:
|
||||||
<ul>
|
<ul>
|
||||||
<li>change into the VDR source directory
|
<li>change into the VDR source directory
|
||||||
<li><b><tt>make</tt></b> the VDR program with your usual <tt>REMOTE=...</tt> (and maybe other) options
|
<li><b><tt>make</tt></b> the VDR program with your usual <tt>REMOTE=...</tt> (and maybe other) options
|
||||||
<li>do <b><tt>make plugins</tt></b> to build the demo plugin
|
<li>do <b><tt>make plugins</tt></b> to build the plugin
|
||||||
<li>run VDR with <b><tt>vdr -V</tt></b> to see the version information
|
<li>run VDR with <b><tt>vdr -V</tt></b> to see the version information
|
||||||
<li>run VDR with <b><tt>vdr -h</tt></b> to see the command line options
|
<li>run VDR with <b><tt>vdr -h</tt></b> to see the command line options
|
||||||
<li>run VDR with <b><tt>vdr -Phello</tt></b>
|
<li>run VDR with <b><tt>vdr -Phello</tt></b>
|
||||||
@ -74,16 +77,14 @@ is used:
|
|||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
VDR/PLUGINS/src
|
VDR/PLUGINS/src
|
||||||
VDR/PLUGINS/src/demo
|
|
||||||
VDR/PLUGINS/src/hello
|
VDR/PLUGINS/src/hello
|
||||||
VDR/PLUGINS/lib
|
VDR/PLUGINS/lib
|
||||||
VDR/PLUGINS/lib/libvdr-demo.so.1.1.0
|
|
||||||
VDR/PLUGINS/lib/libvdr-hello.so.1.1.0
|
VDR/PLUGINS/lib/libvdr-hello.so.1.1.0
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
The <tt>src</tt> directory contains one subdirectory for each plugin, which carries
|
The <tt>src</tt> directory contains one subdirectory for each plugin, which carries
|
||||||
the name of that plugin (in the above example that would be <tt>demo</tt> and
|
the name of that plugin (in the above example that would be <tt>hello</tt>).
|
||||||
<tt>hello</tt>, respectively). What's inside the individual source directory of a
|
What's inside the individual source directory of a
|
||||||
plugin is entirely up to the author of that plugin. The only prerequisites are
|
plugin is entirely up to the author of that plugin. The only prerequisites are
|
||||||
that there is a <tt>Makefile</tt> that provides the targets <tt>all</tt> and
|
that there is a <tt>Makefile</tt> that provides the targets <tt>all</tt> and
|
||||||
<tt>clean</tt>, and that a call to <tt>make all</tt> actually produces a dynamically
|
<tt>clean</tt>, and that a call to <tt>make all</tt> actually produces a dynamically
|
||||||
@ -93,7 +94,7 @@ 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
|
available plugins. Note that the names of these files are created by concatenating
|
||||||
<p>
|
<p>
|
||||||
<table border=2>
|
<table border=2>
|
||||||
<tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>demo</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><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><font size=-1>VDR plugin<br>library prefix</font></td><td align=center><font size=-1>name of<br>the plugin</font></td><td align=center><font size=-1>shared object<br>indicator</font></td><td align=center><font size=-1>VDR version number<br>this plugin was<br>compiled for</font></td></tr>
|
<tr><td align=center><font size=-1>VDR plugin<br>library prefix</font></td><td align=center><font size=-1>name of<br>the plugin</font></td><td align=center><font size=-1>shared object<br>indicator</font></td><td align=center><font size=-1>VDR version number<br>this plugin was<br>compiled for</font></td></tr>
|
||||||
</table>
|
</table>
|
||||||
<p>
|
<p>
|
||||||
@ -109,25 +110,25 @@ each of these directories.
|
|||||||
If you download a plugin <a href="#Building the distribution package">package</a>
|
If you download a plugin <a href="#Building the distribution package">package</a>
|
||||||
from the web, it will typically have a name like
|
from the web, it will typically have a name like
|
||||||
<p>
|
<p>
|
||||||
<tt>vdr-demo-0.0.1.tgz</tt>
|
<tt>vdr-hello-0.0.1.tgz</tt>
|
||||||
<p>
|
<p>
|
||||||
and will unpack into a directory named
|
and will unpack into a directory named
|
||||||
<p>
|
<p>
|
||||||
<tt>vdr-demo-0.0.1</tt>
|
<tt>vdr-hello-0.0.1</tt>
|
||||||
<p>
|
<p>
|
||||||
To use the <tt>plugins</tt> and <tt>plugins-clean</tt> targets from the VDR <tt>Makefile</tt>
|
To use the <tt>plugins</tt> and <tt>plugins-clean</tt> targets from the VDR <tt>Makefile</tt>
|
||||||
you need to unpack such an archive into the <tt>VDR/PLUGINS/src</tt> directory and
|
you need to unpack such an archive into the <tt>VDR/PLUGINS/src</tt> directory and
|
||||||
create a symbolic link with the basic plugin name, as in
|
create a symbolic link with the basic plugin name, as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
ln -s vdr-demo-0.0.1 demo
|
ln -s vdr-hello-0.0.1 hello
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
Since the VDR <tt>Makefile</tt> only searches for directories with names consisting
|
Since the VDR <tt>Makefile</tt> only searches for directories with names consisting
|
||||||
of only lowercase characters and digits, it will only follow the symbolic links, which
|
of only lowercase characters and digits, it will only follow the symbolic links, which
|
||||||
should lead to the current version of the plugin you want to use. This way you can
|
should lead to the current version of the plugin you want to use. This way you can
|
||||||
have several different versions of a plugin source (like <tt>vdr-demo-0.0.1</tt> and
|
have several different versions of a plugin source (like <tt>vdr-hello-0.0.1</tt> and
|
||||||
<tt>vdr-demo-0.0.2</tt>) and define which one to actually use through the symbolic link.
|
<tt>vdr-hello-0.0.2</tt>) and define which one to actually use through the symbolic link.
|
||||||
|
|
||||||
<a name="Initializing a new plugin directory"><hr><h2>Initializing a new plugin directory</h2>
|
<a name="Initializing a new plugin directory"><hr><h2>Initializing a new plugin directory</h2>
|
||||||
|
|
||||||
@ -174,7 +175,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:
|
At the end of the plugin's source file you will find a line that looks like this:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
VDRPLUGINCREATOR(cPluginDemo);
|
VDRPLUGINCREATOR(cPluginHello);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
This is the "magic" hook that allows VDR to actually load the plugin into
|
This is the "magic" hook that allows VDR to actually load the plugin into
|
||||||
@ -230,9 +231,7 @@ Here's an example:
|
|||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
static const char *VERSION = "0.0.1";
|
static const char *VERSION = "0.0.1";
|
||||||
|
|
||||||
...
|
const char *cPluginHello::Version(void)
|
||||||
|
|
||||||
const char *cPluginDemo::Version(void)
|
|
||||||
{
|
{
|
||||||
return VERSION;
|
return VERSION;
|
||||||
}
|
}
|
||||||
@ -265,15 +264,20 @@ In order to tell the user what exactly a plugin does, it must implement the func
|
|||||||
virtual const char *Description(void) = 0;
|
virtual const char *Description(void) = 0;
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
which returns a short, one line description of the plugin's purpose.
|
which returns a short, one line description of the plugin's purpose:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
|
static const char *DESCRIPTION = "A friendly greeting";
|
||||||
|
|
||||||
virtual const char *Description(void)
|
virtual const char *Description(void)
|
||||||
{
|
{
|
||||||
return "A simple demo plugin";
|
return tr(DESCRIPTION);
|
||||||
}
|
}
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
Note the <tt>tr()</tt> around the <tt>DESCRIPTION</tt>, which allows the description
|
||||||
|
to be <a href="#Internationalization">internationalized</a>.
|
||||||
|
|
||||||
<hr><h2>Command line arguments</h2>
|
<hr><h2>Command line arguments</h2>
|
||||||
|
|
||||||
<center><i><b>Taking orders</b></i></center><p>
|
<center><i><b>Taking orders</b></i></center><p>
|
||||||
@ -300,20 +304,21 @@ will survive the entire lifetime of the plugin, so it is safe to store pointers
|
|||||||
these values inside the plugin. Here's an example:
|
these values inside the plugin. Here's an example:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
bool cPluginDemo::ProcessArgs(int argc, char *argv[])
|
bool cPluginHello::ProcessArgs(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
// Implement command line argument processing here if applicable.
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{ "aaa", required_argument, NULL, 'a' },
|
{ "aaa", required_argument, NULL, 'a' },
|
||||||
{ "bbb", no_argument, NULL, 'b' },
|
{ "bbb", no_argument, NULL, 'b' },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
while ((c = getopt_long(argc, argv, "a:b", long_options, NULL)) != -1) {
|
while ((c = getopt_long(argc, argv, "a:b", long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a': fprintf(stderr, "option -a = %s\n", optarg);
|
case 'a': option_a = optarg;
|
||||||
break;
|
break;
|
||||||
case 'b': fprintf(stderr, "option -b\n");
|
case 'b': option_b = true;
|
||||||
break;
|
break;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
@ -342,8 +347,9 @@ The returned string should contain the command line help for this plugin, format
|
|||||||
in the same way as done by VDR itself:
|
in the same way as done by VDR itself:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
const char *cPluginDemo::CommandLineHelp(void)
|
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"
|
return " -a ABC, --aaa=ABC do something nice with ABC\n"
|
||||||
" -b, --bbb activate 'plan B'\n";
|
" -b, --bbb activate 'plan B'\n";
|
||||||
}
|
}
|
||||||
@ -392,9 +398,11 @@ 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:
|
plugin that will have a main menu item:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
const char *cPluginDemo::MainMenuEntry(void)
|
static const char *MAINMENUENTRY = "Hello";
|
||||||
|
|
||||||
|
const char *cPluginHello::MainMenuEntry(void)
|
||||||
{
|
{
|
||||||
return "Demo";
|
return tr(MAINMENUENTRY);
|
||||||
}
|
}
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -440,7 +448,7 @@ virtual cMenuSetupPage *SetupMenu(void);
|
|||||||
virtual bool SetupParse(const char *Name, const char *Value);
|
virtual bool SetupParse(const char *Name, const char *Value);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
The <tt>SetupMenu()</tt> function shall return the plugin's "Setup" menu
|
The <tt>SetupMenu()</tt> function shall return the plugin's <a href="#The Setup menu"><i>Setup</i> menu</a>
|
||||||
page, where the user can adjust all the parameters known to this plugin.
|
page, where the user can adjust all the parameters known to this plugin.
|
||||||
<p>
|
<p>
|
||||||
<tt>SetupParse()</tt> will be called for each parameter the plugin has
|
<tt>SetupParse()</tt> will be called for each parameter the plugin has
|
||||||
@ -448,13 +456,30 @@ previously stored in the global setup data (see below). It shall return
|
|||||||
<i>true</i> if the parameter was parsed correctly, <i>false</i> in case of
|
<i>true</i> if the parameter was parsed correctly, <i>false</i> in case of
|
||||||
an error. If <i>false</i> is returned, an error message will be written to
|
an error. If <i>false</i> is returned, an error message will be written to
|
||||||
the log file (and program execution will continue).
|
the log file (and program execution will continue).
|
||||||
|
<!--X1.1.1--><table width=100%><tr><td bgcolor=red> </td><td width=100%>
|
||||||
|
A possible implementation of <tt>SetupParse()</tt> could look like this:
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
|
bool cPluginHello::SetupParse(const char *Name, const char *Value)
|
||||||
|
{
|
||||||
|
// Parse your own setup parameters and store their values.
|
||||||
|
if (!strcasecmp(Name, "GreetingTime")) GreetingTime = atoi(Value);
|
||||||
|
else if (!strcasecmp(Name, "UseAlternateGreeting")) UseAlternateGreeting = atoi(Value);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
It is important to make sure that the parameter names are exactly the same as
|
||||||
|
used in the <a href="#The Setup menu"><i>Setup</i> menu</a>'s <tt>Store()</tt> function.
|
||||||
|
<!--X1.1.1--></td></tr></table>
|
||||||
<p>
|
<p>
|
||||||
The plugin's setup parameters are stored in the same file as VDR's parameters.
|
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,
|
In order to allow each plugin (and VDR itself) to have its own set of parameters,
|
||||||
the <tt>Name</tt> of each parameter will be preceeded with the plugin's
|
the <tt>Name</tt> of each parameter will be preceeded with the plugin's
|
||||||
name, as in
|
name, as in
|
||||||
<p>
|
<p>
|
||||||
<tt>demo.SomeParameter = 123</tt>
|
<tt>hello.GreetingTime = 3</tt>
|
||||||
<p>
|
<p>
|
||||||
The prefix will be handled by the core VDR setup code, so the individual
|
The prefix will be handled by the core VDR setup code, so the individual
|
||||||
plugins need not worry about this.
|
plugins need not worry about this.
|
||||||
@ -465,8 +490,8 @@ To store its values in the global setup, a plugin has to call the function
|
|||||||
void SetupStore(const char *Name, <i>type</i> Value);
|
void SetupStore(const char *Name, <i>type</i> Value);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
where <tt>Name</tt> is the name of the parameter (<tt>"SomeParameter"</tt> in the above
|
where <tt>Name</tt> is the name of the parameter (<tt>"GreetingTime"</tt> in the above
|
||||||
example, without the prefix <tt>"demo."</tt>) and <tt>Value</tt> is a simple data type (like
|
example, without the prefix <tt>"hello."</tt>) and <tt>Value</tt> is a simple data type (like
|
||||||
<tt>char *</tt>, <tt>int</tt> etc).
|
<tt>char *</tt>, <tt>int</tt> etc).
|
||||||
Note that this is not a function that the individual plugin class needs to implement!
|
Note that this is not a function that the individual plugin class needs to implement!
|
||||||
<tt>SetupStore()</tt> is a non-virtual member function of the <tt>cPlugin</tt> class.
|
<tt>SetupStore()</tt> is a non-virtual member function of the <tt>cPlugin</tt> class.
|
||||||
@ -474,7 +499,7 @@ Note that this is not a function that the individual plugin class needs to imple
|
|||||||
To remove a parameter from the setup data, call <tt>SetupStore()</tt> with the appropriate
|
To remove a parameter from the setup data, call <tt>SetupStore()</tt> with the appropriate
|
||||||
name and without any value, as in
|
name and without any value, as in
|
||||||
<p>
|
<p>
|
||||||
<tt>SetupStore("SomeParameter");</tt>
|
<tt>SetupStore("GreetingTime");</tt>
|
||||||
<p>
|
<p>
|
||||||
The VDR menu "Setup/Plugins" will list all loaded plugins with their name,
|
The VDR menu "Setup/Plugins" will list all loaded plugins with their name,
|
||||||
version number and description. Selecting an item in this list will bring up
|
version number and description. Selecting an item in this list will bring up
|
||||||
@ -486,6 +511,66 @@ needs setup parameters that are not directly user adjustable. It can use
|
|||||||
<tt>SetupStore()</tt> and <tt>SetupParse()</tt> without presenting these
|
<tt>SetupStore()</tt> and <tt>SetupParse()</tt> without presenting these
|
||||||
parameters to the user.
|
parameters to the user.
|
||||||
|
|
||||||
|
<!--X1.1.1--><table width=100%><tr><td bgcolor=red> </td><td width=100%>
|
||||||
|
<a name="The Setup menu"><hr><h2>The Setup menu</h2>
|
||||||
|
|
||||||
|
<center><i><b>Have it your way!</b></i></center><p>
|
||||||
|
|
||||||
|
To implement a <i>Setup</i> menu, a plugin needs to derive a class from
|
||||||
|
<tt>cMenuSetupPage</tt> and implement its constructor and the pure virtual
|
||||||
|
<tt>Store()</tt> member function:
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
|
int GreetingTime = 3;
|
||||||
|
int UseAlternateGreeting = false;
|
||||||
|
|
||||||
|
class cMenuSetupHello : public cMenuSetupPage {
|
||||||
|
private:
|
||||||
|
int newGreetingTime;
|
||||||
|
int newUseAlternateGreeting;
|
||||||
|
protected:
|
||||||
|
virtual void Store(void);
|
||||||
|
public:
|
||||||
|
cMenuSetupHello(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cMenuSetupHello::cMenuSetupHello(void)
|
||||||
|
{
|
||||||
|
newGreetingTime = GreetingTime;
|
||||||
|
newUseAlternateGreeting = UseAlternateGreeting;
|
||||||
|
Add(new cMenuEditIntItem( tr("Greeting time (s)"), &newGreetingTime));
|
||||||
|
Add(new cMenuEditBoolItem(tr("Use alternate greeting"), &newUseAlternateGreeting));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuSetupHello::Store(void)
|
||||||
|
{
|
||||||
|
SetupStore("GreetingTime", GreetingTime = newGreetingTime);
|
||||||
|
SetupStore("UseAlternateGreeting", UseAlternateGreeting = newUseAlternateGreeting);
|
||||||
|
}
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
In this example we have two global setup parameters (<tt>GreetingTime</tt> and <tt>UseAlternateGreeting</tt>).
|
||||||
|
The constructor initializes two private members with the values of these parameters, so
|
||||||
|
that the <i>Setup</i> menu can work with temporary copies (in order to discard any changes
|
||||||
|
if the user doesn't confirm them by pressing the "Ok" button).
|
||||||
|
After this the constructor adds the appropriate menu items, using internationalized texts
|
||||||
|
and the addresses of the temporary variables. That's all there is to inizialize a <i>Setup</i>
|
||||||
|
menu - the rest will be done by the core VDR code.
|
||||||
|
<p>
|
||||||
|
Once the user has pressed the "Ok" button to confirm the changes, the <tt>Store()</tt> function will
|
||||||
|
be called, in which all setup parameters must be actually stored in VDR's global setup data.
|
||||||
|
This is done by calling the <tt>SetupStore()</tt> function for each of the parameters.
|
||||||
|
The <i>Name</i> string given here will be used to identify the parameter in VDR's
|
||||||
|
<tt>setup.conf</tt> file, and will be automatically prepended with the plugin's name.
|
||||||
|
<p>
|
||||||
|
Note that in this small example the new values of the parameters are copied into the
|
||||||
|
global variables within each <tt>SetupStore()</tt> call. This is not mandatory, however.
|
||||||
|
You can first assign the temporary values to the global variables and then do the
|
||||||
|
<tt>SetupStore()</tt> calls, or you can define a class or struct that contains all
|
||||||
|
your setup parameters and use that one to copy all parameters with one single statement
|
||||||
|
(like VDR does with its cSetup class).
|
||||||
|
<!--X1.1.1--></td></tr></table>
|
||||||
|
|
||||||
<a name="Internationalization"><hr><h2>Internationalization</h2>
|
<a name="Internationalization"><hr><h2>Internationalization</h2>
|
||||||
|
|
||||||
<center><i><b>Welcome to Babylon!</b></i></center><p>
|
<center><i><b>Welcome to Babylon!</b></i></center><p>
|
||||||
@ -519,7 +604,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
void cPluginDemo::Start(void)
|
void cPluginHello::Start(void)
|
||||||
{
|
{
|
||||||
RegisterI18n(Phrases);
|
RegisterI18n(Phrases);
|
||||||
}
|
}
|
||||||
@ -557,20 +642,20 @@ core VDR code.
|
|||||||
Plugins are loaded into VDR using the command line option <b><tt>-P</tt></b>, as in
|
Plugins are loaded into VDR using the command line option <b><tt>-P</tt></b>, as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
vdr -Pdemo
|
vdr -Phello
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
If the plugin accepts command line options, they are given as part of the argument
|
If the plugin accepts command line options, they are given as part of the argument
|
||||||
to the <b><tt>-P</tt></b> option, which then has to be enclosed in quotes:
|
to the <b><tt>-P</tt></b> option, which then has to be enclosed in quotes:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
vdr -P"demo -a abc -b"
|
vdr -P"hello -a abc -b"
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
Any number of plugins can be loaded this way, each with its own <b><tt>-P</tt></b> option:
|
Any number of plugins can be loaded this way, each with its own <b><tt>-P</tt></b> option:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
vdr -P"demo -a abc -b" -Pdvd -Pmp3
|
vdr -P"hello -a abc -b" -Pdvd -Pmp3
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
If you are not starting VDR from the VDR source directory (and thus your plugins
|
If you are not starting VDR from the VDR source directory (and thus your plugins
|
||||||
@ -578,7 +663,7 @@ cannot be found at their default location) you need to tell VDR the location of
|
|||||||
the plugins through the <b><tt>-L</tt></b> option:
|
the plugins through the <b><tt>-L</tt></b> option:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
vdr -L/usr/lib/vdr -Pdemo
|
vdr -L/usr/lib/vdr -Phello
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
There can be any number of <b><tt>-L</tt></b> options, and each of them will apply to the
|
There can be any number of <b><tt>-L</tt></b> options, and each of them will apply to the
|
||||||
@ -603,17 +688,17 @@ provides the target <tt>package</tt>, which does this for you.
|
|||||||
Simply change into your source directory and execute <tt>make package</tt>:
|
Simply change into your source directory and execute <tt>make package</tt>:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
cd VDR/PLUGINS/src/demo
|
cd VDR/PLUGINS/src/hello
|
||||||
make package
|
make package
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
After this you should find a file named like
|
After this you should find a file named like
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
||||||
vdr-demo-0.0.1.tgz
|
vdr-hello-0.0.1.tgz
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
in your source directory, where <tt>demo</tt> will be replaced with your actual
|
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.
|
plugin's name, and <tt>0.0.1</tt> will be your plugin's current version number.
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
11
config.c
11
config.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.c 1.99 2002/05/05 12:00:00 kls Exp $
|
* $Id: config.c 1.100 2002/05/11 12:05:22 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -1073,14 +1073,19 @@ bool cSetup::Load(const char *FileName)
|
|||||||
if (cConfig<cSetupLine>::Load(FileName, true)) {
|
if (cConfig<cSetupLine>::Load(FileName, true)) {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
for (cSetupLine *l = First(); l; l = Next(l)) {
|
for (cSetupLine *l = First(); l; l = Next(l)) {
|
||||||
|
bool error = false;
|
||||||
if (l->Plugin()) {
|
if (l->Plugin()) {
|
||||||
cPlugin *p = cPluginManager::GetPlugin(l->Plugin());
|
cPlugin *p = cPluginManager::GetPlugin(l->Plugin());
|
||||||
if (p && !p->SetupParse(l->Name(), l->Value()))
|
if (p && !p->SetupParse(l->Name(), l->Value()))
|
||||||
result = false;
|
error = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!Parse(l->Name(), l->Value()))
|
if (!Parse(l->Name(), l->Value()))
|
||||||
result = false;
|
error = true;
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
esyslog(LOG_ERR, "ERROR: unknown config parameter: %s%s%s = %s", l->Plugin() ? l->Plugin() : "", l->Plugin() ? "." : "", l->Name(), l->Value());
|
||||||
|
result = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
15
i18n.c
15
i18n.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: i18n.c 1.87 2002/05/09 13:40:51 kls Exp $
|
* $Id: i18n.c 1.88 2002/05/11 11:43:38 kls Exp $
|
||||||
*
|
*
|
||||||
* Translations provided by:
|
* Translations provided by:
|
||||||
*
|
*
|
||||||
@ -1270,6 +1270,19 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Plugins",
|
"Plugins",
|
||||||
"Plugins",
|
"Plugins",
|
||||||
},
|
},
|
||||||
|
{ "Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
"Plugin",
|
||||||
|
},
|
||||||
{ "Restart",
|
{ "Restart",
|
||||||
"Neustart",
|
"Neustart",
|
||||||
"Ponoven zagon",
|
"Ponoven zagon",
|
||||||
|
192
menu.c
192
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 1.190 2002/05/09 10:13:47 kls Exp $
|
* $Id: menu.c 1.191 2002/05/11 11:16:32 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -1525,19 +1525,41 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- cMenuSetupBase --------------------------------------------------------
|
||||||
|
|
||||||
|
class cMenuSetupBase : public cMenuSetupPage {
|
||||||
|
protected:
|
||||||
|
cSetup data;
|
||||||
|
virtual void Store(void);
|
||||||
|
public:
|
||||||
|
cMenuSetupBase(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cMenuSetupBase::cMenuSetupBase(void)
|
||||||
|
{
|
||||||
|
data = Setup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuSetupBase::Store(void)
|
||||||
|
{
|
||||||
|
Setup = data;
|
||||||
|
Setup.Save();
|
||||||
|
}
|
||||||
|
|
||||||
// --- cMenuSetupOSD ---------------------------------------------------------
|
// --- cMenuSetupOSD ---------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetupOSD : public cMenuSetupPage {
|
class cMenuSetupOSD : public cMenuSetupBase {
|
||||||
private:
|
private:
|
||||||
virtual void Set(void);
|
virtual void Set(void);
|
||||||
public:
|
public:
|
||||||
cMenuSetupOSD(void) { Set(); }
|
cMenuSetupOSD(void) { Set(); }
|
||||||
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cMenuSetupOSD::Set(void)
|
void cMenuSetupOSD::Set(void)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
SetupTitle("OSD");
|
SetSection(tr("OSD"));
|
||||||
Add(new cMenuEditStraItem(tr("Setup.OSD$Language"), &data.OSDLanguage, I18nNumLanguages, I18nLanguages()));
|
Add(new cMenuEditStraItem(tr("Setup.OSD$Language"), &data.OSDLanguage, I18nNumLanguages, I18nLanguages()));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.OSD$Width"), &data.OSDwidth, MINOSDWIDTH, MAXOSDWIDTH));
|
Add(new cMenuEditIntItem( tr("Setup.OSD$Width"), &data.OSDwidth, MINOSDWIDTH, MAXOSDWIDTH));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.OSD$Height"), &data.OSDheight, MINOSDHEIGHT, MAXOSDHEIGHT));
|
Add(new cMenuEditIntItem( tr("Setup.OSD$Height"), &data.OSDheight, MINOSDHEIGHT, MAXOSDHEIGHT));
|
||||||
@ -1549,19 +1571,31 @@ void cMenuSetupOSD::Set(void)
|
|||||||
Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs));
|
Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eOSState cMenuSetupOSD::ProcessKey(eKeys Key)
|
||||||
|
{
|
||||||
|
int osdLanguage = data.OSDLanguage;
|
||||||
|
eOSState state = cMenuSetupBase::ProcessKey(Key);
|
||||||
|
|
||||||
|
if (data.OSDLanguage != osdLanguage) {
|
||||||
|
int OriginalOSDLanguage = Setup.OSDLanguage;
|
||||||
|
Setup.OSDLanguage = data.OSDLanguage;
|
||||||
|
Set();
|
||||||
|
Display();
|
||||||
|
Setup.OSDLanguage = OriginalOSDLanguage;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cMenuSetupEPG ---------------------------------------------------------
|
// --- cMenuSetupEPG ---------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetupEPG : public cMenuSetupPage {
|
class cMenuSetupEPG : public cMenuSetupBase {
|
||||||
private:
|
|
||||||
virtual void Set(void);
|
|
||||||
public:
|
public:
|
||||||
cMenuSetupEPG(void) { Set(); }
|
cMenuSetupEPG(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cMenuSetupEPG::Set(void)
|
cMenuSetupEPG::cMenuSetupEPG(void)
|
||||||
{
|
{
|
||||||
Clear();
|
SetSection(tr("EPG"));
|
||||||
SetupTitle("EPG");
|
|
||||||
Add(new cMenuEditIntItem( tr("Setup.EPG$EPG scan timeout (h)"), &data.EPGScanTimeout));
|
Add(new cMenuEditIntItem( tr("Setup.EPG$EPG scan timeout (h)"), &data.EPGScanTimeout));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.EPG$EPG bugfix level"), &data.EPGBugfixLevel, 0, MAXEPGBUGFIXLEVEL));
|
Add(new cMenuEditIntItem( tr("Setup.EPG$EPG bugfix level"), &data.EPGBugfixLevel, 0, MAXEPGBUGFIXLEVEL));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.EPG$Set system time"), &data.SetSystemTime));
|
Add(new cMenuEditBoolItem(tr("Setup.EPG$Set system time"), &data.SetSystemTime));
|
||||||
@ -1570,34 +1604,43 @@ void cMenuSetupEPG::Set(void)
|
|||||||
|
|
||||||
// --- cMenuSetupDVB ---------------------------------------------------------
|
// --- cMenuSetupDVB ---------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetupDVB : public cMenuSetupPage {
|
class cMenuSetupDVB : public cMenuSetupBase {
|
||||||
private:
|
|
||||||
virtual void Set(void);
|
|
||||||
public:
|
public:
|
||||||
cMenuSetupDVB(void) { Set(); }
|
cMenuSetupDVB(void);
|
||||||
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cMenuSetupDVB::Set(void)
|
cMenuSetupDVB::cMenuSetupDVB(void)
|
||||||
{
|
{
|
||||||
Clear();
|
SetSection(tr("DVB"));
|
||||||
SetupTitle("DVB");
|
|
||||||
Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDvbApi::NumDvbApis));
|
Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDvbApi::NumDvbApis));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.DVB$Video format"), &data.VideoFormat, "4:3", "16:9"));
|
Add(new cMenuEditBoolItem(tr("Setup.DVB$Video format"), &data.VideoFormat, "4:3", "16:9"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eOSState cMenuSetupDVB::ProcessKey(eKeys Key)
|
||||||
|
{
|
||||||
|
int oldPrimaryDVB = Setup.PrimaryDVB;
|
||||||
|
eOSState state = cMenuSetupBase::ProcessKey(Key);
|
||||||
|
|
||||||
|
if (state == osBack && Key == kOk) {
|
||||||
|
if (Setup.PrimaryDVB != oldPrimaryDVB) {
|
||||||
|
state = osSwitchDvb;
|
||||||
|
cDvbApi::PrimaryDvbApi->SetVideoFormat(Setup.VideoFormat ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cMenuSetupLNB ---------------------------------------------------------
|
// --- cMenuSetupLNB ---------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetupLNB : public cMenuSetupPage {
|
class cMenuSetupLNB : public cMenuSetupBase {
|
||||||
private:
|
|
||||||
virtual void Set(void);
|
|
||||||
public:
|
public:
|
||||||
cMenuSetupLNB(void) { Set(); }
|
cMenuSetupLNB(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cMenuSetupLNB::Set(void)
|
cMenuSetupLNB::cMenuSetupLNB(void)
|
||||||
{
|
{
|
||||||
Clear();
|
SetSection(tr("LNB"));
|
||||||
SetupTitle("LNB");
|
|
||||||
Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"), &data.LnbSLOF));
|
Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"), &data.LnbSLOF));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.LNB$Low LNB frequency (MHz)"), &data.LnbFrequLo));
|
Add(new cMenuEditIntItem( tr("Setup.LNB$Low LNB frequency (MHz)"), &data.LnbFrequLo));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi));
|
Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi));
|
||||||
@ -1606,17 +1649,15 @@ void cMenuSetupLNB::Set(void)
|
|||||||
|
|
||||||
// --- cMenuSetupCICAM -------------------------------------------------------
|
// --- cMenuSetupCICAM -------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetupCICAM : public cMenuSetupPage {
|
class cMenuSetupCICAM : public cMenuSetupBase {
|
||||||
private:
|
|
||||||
virtual void Set(void);
|
|
||||||
public:
|
public:
|
||||||
cMenuSetupCICAM(void) { Set(); }
|
cMenuSetupCICAM(void);
|
||||||
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cMenuSetupCICAM::Set(void)
|
cMenuSetupCICAM::cMenuSetupCICAM(void)
|
||||||
{
|
{
|
||||||
Clear();
|
SetSection(tr("CICAM"));
|
||||||
SetupTitle("CICAM");
|
|
||||||
for (int d = 0; d < cDvbApi::NumDvbApis; d++) {
|
for (int d = 0; d < cDvbApi::NumDvbApis; d++) {
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
@ -1626,19 +1667,25 @@ void cMenuSetupCICAM::Set(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eOSState cMenuSetupCICAM::ProcessKey(eKeys Key)
|
||||||
|
{
|
||||||
|
eOSState state = cMenuSetupBase::ProcessKey(Key);
|
||||||
|
|
||||||
|
if (state == osBack && Key == kOk)
|
||||||
|
cDvbApi::SetCaCaps();
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cMenuSetupRecord ------------------------------------------------------
|
// --- cMenuSetupRecord ------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetupRecord : public cMenuSetupPage {
|
class cMenuSetupRecord : public cMenuSetupBase {
|
||||||
private:
|
|
||||||
virtual void Set(void);
|
|
||||||
public:
|
public:
|
||||||
cMenuSetupRecord(void) { Set(); }
|
cMenuSetupRecord(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cMenuSetupRecord::Set(void)
|
cMenuSetupRecord::cMenuSetupRecord(void)
|
||||||
{
|
{
|
||||||
Clear();
|
SetSection(tr("Recording"));
|
||||||
SetupTitle("Recording");
|
|
||||||
Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at start (min)"), &data.MarginStart));
|
Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at start (min)"), &data.MarginStart));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at stop (min)"), &data.MarginStop));
|
Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at stop (min)"), &data.MarginStop));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.Recording$Primary limit"), &data.PrimaryLimit, 0, MAXPRIORITY));
|
Add(new cMenuEditIntItem( tr("Setup.Recording$Primary limit"), &data.PrimaryLimit, 0, MAXPRIORITY));
|
||||||
@ -1655,34 +1702,28 @@ void cMenuSetupRecord::Set(void)
|
|||||||
|
|
||||||
// --- cMenuSetupReplay ------------------------------------------------------
|
// --- cMenuSetupReplay ------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetupReplay : public cMenuSetupPage {
|
class cMenuSetupReplay : public cMenuSetupBase {
|
||||||
private:
|
|
||||||
virtual void Set(void);
|
|
||||||
public:
|
public:
|
||||||
cMenuSetupReplay(void) { Set(); }
|
cMenuSetupReplay(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cMenuSetupReplay::Set(void)
|
cMenuSetupReplay::cMenuSetupReplay(void)
|
||||||
{
|
{
|
||||||
Clear();
|
SetSection(tr("Replay"));
|
||||||
SetupTitle("Replay");
|
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.Replay$Multi speed mode"), &data.MultiSpeedMode));
|
Add(new cMenuEditBoolItem(tr("Setup.Replay$Multi speed mode"), &data.MultiSpeedMode));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.Replay$Show replay mode"), &data.ShowReplayMode));
|
Add(new cMenuEditBoolItem(tr("Setup.Replay$Show replay mode"), &data.ShowReplayMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cMenuSetupMisc --------------------------------------------------------
|
// --- cMenuSetupMisc --------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetupMisc : public cMenuSetupPage {
|
class cMenuSetupMisc : public cMenuSetupBase {
|
||||||
private:
|
|
||||||
virtual void Set(void);
|
|
||||||
public:
|
public:
|
||||||
cMenuSetupMisc(void) { Set(); }
|
cMenuSetupMisc(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cMenuSetupMisc::Set(void)
|
cMenuSetupMisc::cMenuSetupMisc(void)
|
||||||
{
|
{
|
||||||
Clear();
|
SetSection(tr("Miscellaneous"));
|
||||||
SetupTitle("Miscellaneous");
|
|
||||||
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. event timeout (min)"), &data.MinEventTimeout));
|
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. event timeout (min)"), &data.MinEventTimeout));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. user inactivity (min)"), &data.MinUserInactivity));
|
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. user inactivity (min)"), &data.MinUserInactivity));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"), &data.SVDRPTimeout));
|
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"), &data.SVDRPTimeout));
|
||||||
@ -1706,18 +1747,15 @@ cMenuSetupPluginItem::cMenuSetupPluginItem(const char *Name, int Index)
|
|||||||
|
|
||||||
// --- cMenuSetupPlugins -----------------------------------------------------
|
// --- cMenuSetupPlugins -----------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetupPlugins : public cMenuSetupPage {
|
class cMenuSetupPlugins : public cMenuSetupBase {
|
||||||
private:
|
|
||||||
virtual void Set(void);
|
|
||||||
public:
|
public:
|
||||||
cMenuSetupPlugins(void) { Set(); }
|
cMenuSetupPlugins(void);
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cMenuSetupPlugins::Set(void)
|
cMenuSetupPlugins::cMenuSetupPlugins(void)
|
||||||
{
|
{
|
||||||
Clear();
|
SetSection(tr("Plugins"));
|
||||||
SetupTitle("Plugins");
|
|
||||||
SetHasHotkeys();
|
SetHasHotkeys();
|
||||||
for (int i = 0; ; i++) {
|
for (int i = 0; ; i++) {
|
||||||
cPlugin *p = cPluginManager::GetPlugin(i);
|
cPlugin *p = cPluginManager::GetPlugin(i);
|
||||||
@ -1734,25 +1772,25 @@ void cMenuSetupPlugins::Set(void)
|
|||||||
|
|
||||||
eOSState cMenuSetupPlugins::ProcessKey(eKeys Key)
|
eOSState cMenuSetupPlugins::ProcessKey(eKeys Key)
|
||||||
{
|
{
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key); // not cMenuSetupPage::ProcessKey()!
|
eOSState state = HasSubMenu() ? cMenuSetupBase::ProcessKey(Key) : cOsdMenu::ProcessKey(Key);
|
||||||
|
|
||||||
if (state == osUnknown) {
|
if (Key == kOk) {
|
||||||
switch (Key) {
|
if (state == osUnknown) {
|
||||||
case kOk: {
|
cMenuSetupPluginItem *item = (cMenuSetupPluginItem *)Get(Current());
|
||||||
cMenuSetupPluginItem *item = (cMenuSetupPluginItem *)Get(Current());
|
if (item) {
|
||||||
if (item) {
|
cPlugin *p = cPluginManager::GetPlugin(item->PluginIndex());
|
||||||
cPlugin *p = cPluginManager::GetPlugin(item->PluginIndex());
|
if (p) {
|
||||||
if (p) {
|
cMenuSetupPage *menu = p->SetupMenu();
|
||||||
cOsdMenu *menu = p->SetupMenu();
|
if (menu) {
|
||||||
if (menu)
|
menu->SetPlugin(p);
|
||||||
return AddSubMenu(menu);
|
return AddSubMenu(menu);
|
||||||
Interface->Info(tr("This plugin has no setup parameters!"));
|
}
|
||||||
}
|
Interface->Info(tr("This plugin has no setup parameters!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
default: break;
|
else if (state == osContinue)
|
||||||
}
|
Store();
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
48
menuitems.c
48
menuitems.c
@ -4,12 +4,13 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menuitems.c 1.1 2002/05/09 10:10:12 kls Exp $
|
* $Id: menuitems.c 1.2 2002/05/11 10:49:45 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menuitems.h"
|
#include "menuitems.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
#include "plugin.h"
|
||||||
|
|
||||||
// --- cMenuEditItem ---------------------------------------------------------
|
// --- cMenuEditItem ---------------------------------------------------------
|
||||||
|
|
||||||
@ -437,15 +438,13 @@ eOSState cMenuTextItem::ProcessKey(eKeys Key)
|
|||||||
cMenuSetupPage::cMenuSetupPage(void)
|
cMenuSetupPage::cMenuSetupPage(void)
|
||||||
:cOsdMenu("", 33)
|
:cOsdMenu("", 33)
|
||||||
{
|
{
|
||||||
data = Setup;
|
plugin = NULL;
|
||||||
osdLanguage = Setup.OSDLanguage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cMenuSetupPage::SetupTitle(const char *s)
|
void cMenuSetupPage::SetSection(const char *Section)
|
||||||
{
|
{
|
||||||
char buf[40]; // can't call tr() for more than one string at a time!
|
char buf[40];
|
||||||
char *q = buf + snprintf(buf, sizeof(buf), "%s - ", tr("Setup"));
|
snprintf(buf, sizeof(buf), "%s - %s", tr("Setup"), Section);
|
||||||
snprintf(q, sizeof(buf) - strlen(buf), "%s", tr(s));
|
|
||||||
SetTitle(buf);
|
SetTitle(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,22 +454,31 @@ eOSState cMenuSetupPage::ProcessKey(eKeys Key)
|
|||||||
|
|
||||||
if (state == osUnknown) {
|
if (state == osUnknown) {
|
||||||
switch (Key) {
|
switch (Key) {
|
||||||
case kOk: state = (Setup.PrimaryDVB != data.PrimaryDVB) ? osSwitchDvb : osBack;
|
case kOk: Store();
|
||||||
cDvbApi::PrimaryDvbApi->SetVideoFormat(data.VideoFormat ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3);
|
state = osBack;
|
||||||
Setup = data;
|
|
||||||
Setup.Save();
|
|
||||||
cDvbApi::SetCaCaps();
|
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.OSDLanguage != osdLanguage) {
|
|
||||||
int OriginalOSDLanguage = Setup.OSDLanguage;
|
|
||||||
Setup.OSDLanguage = data.OSDLanguage;
|
|
||||||
Set();
|
|
||||||
Display();
|
|
||||||
osdLanguage = data.OSDLanguage;
|
|
||||||
Setup.OSDLanguage = OriginalOSDLanguage;
|
|
||||||
}
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cMenuSetupPage::SetPlugin(cPlugin *Plugin)
|
||||||
|
{
|
||||||
|
plugin = Plugin;
|
||||||
|
char buf[40];
|
||||||
|
snprintf(buf, sizeof(buf), "%s '%s'", tr("Plugin"), plugin->Name());
|
||||||
|
SetSection(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuSetupPage::SetupStore(const char *Name, const char *Value = NULL)
|
||||||
|
{
|
||||||
|
if (plugin)
|
||||||
|
plugin->SetupStore(Name, Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuSetupPage::SetupStore(const char *Name, int Value)
|
||||||
|
{
|
||||||
|
if (plugin)
|
||||||
|
plugin->SetupStore(Name, Value);
|
||||||
|
}
|
||||||
|
15
menuitems.h
15
menuitems.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menuitems.h 1.1 2002/05/09 09:41:06 kls Exp $
|
* $Id: menuitems.h 1.2 2002/05/11 10:48:28 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MENUITEMS_H
|
#ifndef __MENUITEMS_H
|
||||||
@ -96,15 +96,20 @@ public:
|
|||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cPlugin;
|
||||||
|
|
||||||
class cMenuSetupPage : public cOsdMenu {
|
class cMenuSetupPage : public cOsdMenu {
|
||||||
|
private:
|
||||||
|
cPlugin *plugin;
|
||||||
protected:
|
protected:
|
||||||
cSetup data;
|
void SetSection(const char *Section);
|
||||||
int osdLanguage;
|
virtual void Store(void) = 0;
|
||||||
void SetupTitle(const char *s);
|
void SetupStore(const char *Name, const char *Value = NULL);
|
||||||
virtual void Set(void) = 0;
|
void SetupStore(const char *Name, int Value);
|
||||||
public:
|
public:
|
||||||
cMenuSetupPage(void);
|
cMenuSetupPage(void);
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
|
void SetPlugin(cPlugin *Plugin);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__MENUITEMS_H
|
#endif //__MENUITEMS_H
|
||||||
|
10
vdr.c
10
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
||||||
*
|
*
|
||||||
* $Id: vdr.c 1.104 2002/05/05 12:00:00 kls Exp $
|
* $Id: vdr.c 1.105 2002/05/11 11:46:40 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -578,14 +578,14 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (Interrupted)
|
if (Interrupted)
|
||||||
isyslog(LOG_INFO, "caught signal %d", Interrupted);
|
isyslog(LOG_INFO, "caught signal %d", Interrupted);
|
||||||
Setup.CurrentChannel = cDvbApi::CurrentChannel();
|
|
||||||
Setup.CurrentVolume = cDvbApi::CurrentVolume();
|
|
||||||
Setup.Save();
|
|
||||||
PluginManager.Shutdown(true);
|
|
||||||
cVideoCutter::Stop();
|
cVideoCutter::Stop();
|
||||||
delete Menu;
|
delete Menu;
|
||||||
delete ReplayControl;
|
delete ReplayControl;
|
||||||
delete Interface;
|
delete Interface;
|
||||||
|
PluginManager.Shutdown(true);
|
||||||
|
Setup.CurrentChannel = cDvbApi::CurrentChannel();
|
||||||
|
Setup.CurrentVolume = cDvbApi::CurrentVolume();
|
||||||
|
Setup.Save();
|
||||||
cDvbApi::Cleanup();
|
cDvbApi::Cleanup();
|
||||||
if (WatchdogTimeout > 0)
|
if (WatchdogTimeout > 0)
|
||||||
dsyslog(LOG_INFO, "max. latency time %d seconds", MaxLatencyTime);
|
dsyslog(LOG_INFO, "max. latency time %d seconds", MaxLatencyTime);
|
||||||
|
Loading…
Reference in New Issue
Block a user