diff --git a/HISTORY b/HISTORY index 29e9d600..cd8fdc72 100644 --- a/HISTORY +++ b/HISTORY @@ -1813,7 +1813,7 @@ Video Disk Recorder Revision History makes far jumps, so that a lock file might end up with a time stamp that lies in the distant future (thanks to Oliver Endriss). -2002-11-30: Version 1.1.18 +2002-12-01: Version 1.1.18 - Fixed missing initialization of 'number' in cChannel (thanks to Martin Hammerschmid for reporting this one). @@ -1832,3 +1832,5 @@ Video Disk Recorder Revision History for reporting this one). - Now taking an active SVDRP connection into account when doing shutdown or housekeeping (suggested by Emil Naepflein). +- Macros in 'keymacros.conf' can now use "@plugin" to directly access the main menu + function of a given plugin (see man vdr(5) for details). diff --git a/keymacros.conf b/keymacros.conf index 767d49d3..42cddc26 100644 --- a/keymacros.conf +++ b/keymacros.conf @@ -3,6 +3,7 @@ # Format: # # macrokey key1 key2 key3... +# macrokey @plugin key1 key2 key3... # # See man vdr(5) diff --git a/keys.c b/keys.c index 4647f3ae..381b3189 100644 --- a/keys.c +++ b/keys.c @@ -4,10 +4,11 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: keys.c 1.3 2002/10/27 15:19:40 kls Exp $ + * $Id: keys.c 1.4 2002/11/30 16:01:37 kls Exp $ */ #include "keys.h" +#include "plugin.h" static tKey keyTable[] = { // "Up" and "Down" must be the first two keys! { kUp, "Up" }, @@ -182,6 +183,12 @@ cKeyMacro::cKeyMacro(void) { for (int i = 0; i < MAXKEYSINMACRO; i++) macro[i] = kNone; + plugin = NULL; +} + +cKeyMacro::~cKeyMacro() +{ + free(plugin); } bool cKeyMacro::Parse(char *s) @@ -190,10 +197,35 @@ bool cKeyMacro::Parse(char *s) char *p; while ((p = strtok(s, " \t")) != NULL) { if (n < MAXKEYSINMACRO) { - macro[n] = cKey::FromString(p); - if (macro[n] == kNone) { - esyslog("ERROR: unknown key '%s'", p); - return false; + if (*p == '@') { + if (plugin) { + esyslog("ERROR: only one @plugin allowed per macro"); + return false; + } + if (!n) { + esyslog("ERROR: @plugin can't be first in macro"); + return false; + } + macro[n++] = k_Plugin; + if (n < MAXKEYSINMACRO) { + macro[n] = kOk; + plugin = strdup(p + 1); + if (!cPluginManager::GetPlugin(plugin)) { + esyslog("ERROR: unknown plugin '%s'", plugin); + return false; + } + } + else { + esyslog("ERROR: key macro too long"); + return false; + } + } + else { + macro[n] = cKey::FromString(p); + if (macro[n] == kNone) { + esyslog("ERROR: unknown key '%s'", p); + return false; + } } n++; s = NULL; diff --git a/keys.h b/keys.h index ceb2d1c8..02c513ae 100644 --- a/keys.h +++ b/keys.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: keys.h 1.3 2002/10/27 15:18:21 kls Exp $ + * $Id: keys.h 1.4 2002/12/01 10:43:26 kls Exp $ */ #ifndef __KEYS_H @@ -46,6 +46,8 @@ enum eKeys { // "Up" and "Down" must be the first two keys! kCommands, kUser1, kUser2, kUser3, kUser4, kUser5, kUser6, kUser7, kUser8, kUser9, kNone, + // The following codes are used internally: + k_Plugin, k_Setup, // The following flags are OR'd with the above codes: k_Repeat = 0x8000, @@ -105,10 +107,13 @@ extern cKeys Keys; class cKeyMacro : public cListObject { private: eKeys macro[MAXKEYSINMACRO]; + char *plugin; public: cKeyMacro(void); + ~cKeyMacro(); bool Parse(char *s); const eKeys *Macro(void) const { return macro; } + const char *Plugin(void) const { return plugin; } }; class cKeyMacros : public cConfig { diff --git a/menu.c b/menu.c index 25795fb8..a1c136fa 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.227 2002/11/29 14:06:38 kls Exp $ + * $Id: menu.c 1.228 2002/12/01 10:31:55 kls Exp $ */ #include "menu.h" @@ -2178,11 +2178,11 @@ cMenuPluginItem::cMenuPluginItem(const char *Name, int Index) cOsdObject *cMenuMain::pluginOsdObject = NULL; -cMenuMain::cMenuMain(bool Replaying, eOSState State) +cMenuMain::cMenuMain(bool Replaying, eOSState State, const char *Plugin) :cOsdMenu("") { replaying = Replaying; - Set(); + Set(Plugin); // Initial submenus: @@ -2193,6 +2193,7 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State) case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break; case osSetup: AddSubMenu(new cMenuSetup); break; case osCommands: AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); break; + case osPlugin: break; // the actual work is done in Set() default: break; } } @@ -2204,7 +2205,7 @@ cOsdObject *cMenuMain::PluginOsdObject(void) return o; } -void cMenuMain::Set(void) +void cMenuMain::Set(const char *Plugin) { Clear(); //SetTitle("VDR"); // this is done below, including disk usage @@ -2237,7 +2238,7 @@ void cMenuMain::Set(void) if (p) { const char *item = p->MainMenuEntry(); if (item) - Add(new cMenuPluginItem(hk(item), i)); + Add(new cMenuPluginItem(hk(item), i), Plugin && strcmp(Plugin, p->Name()) == 0); } else break; diff --git a/menu.h b/menu.h index ae7d0a91..7e7e4d66 100644 --- a/menu.h +++ b/menu.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.50 2002/11/23 14:51:32 kls Exp $ + * $Id: menu.h 1.51 2002/11/30 15:55:39 kls Exp $ */ #ifndef __MENU_H @@ -21,9 +21,9 @@ private: time_t lastActivity; bool replaying; static cOsdObject *pluginOsdObject; - void Set(void); + void Set(const char *Plugin = NULL); public: - cMenuMain(bool Replaying, eOSState State = osUnknown); + cMenuMain(bool Replaying, eOSState State = osUnknown, const char *Plugin = NULL); virtual eOSState ProcessKey(eKeys Key); static cOsdObject *PluginOsdObject(void); }; diff --git a/remote.c b/remote.c index 415e37ea..7157a5f5 100644 --- a/remote.c +++ b/remote.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remote.c 1.31 2002/11/01 10:50:13 kls Exp $ + * $Id: remote.c 1.32 2002/12/01 10:40:04 kls Exp $ */ #include "remote.h" @@ -31,6 +31,7 @@ cRemote *cRemote::learning = NULL; char *cRemote::unknownCode = NULL; cMutex cRemote::mutex; cCondVar cRemote::keyPressed; +const char *cRemote::plugin = NULL; cRemote::cRemote(const char *Name) { @@ -88,6 +89,7 @@ bool cRemote::PutMacro(eKeys Key) { const cKeyMacro *km = KeyMacros.Get(Key); if (km) { + plugin = km->Plugin(); for (int i = 1; i < MAXKEYSINMACRO; i++) { if (km->Macro()[i] != kNone) { if (!Put(km->Macro()[i])) diff --git a/remote.h b/remote.h index b23b9335..2aeec78c 100644 --- a/remote.h +++ b/remote.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remote.h 1.20 2002/11/09 11:07:33 kls Exp $ + * $Id: remote.h 1.21 2002/12/01 10:39:10 kls Exp $ */ #ifndef __REMOTE_H @@ -26,6 +26,7 @@ private: static char *unknownCode; static cMutex mutex; static cCondVar keyPressed; + static const char *plugin; char *name; protected: cRemote(const char *Name); @@ -41,6 +42,7 @@ public: static void Clear(void); static bool Put(eKeys Key); static bool PutMacro(eKeys Key); + static const char *GetPlugin(void) { return plugin; } static eKeys Get(int WaitMs = 1000, char **UnknownCode = NULL); }; diff --git a/vdr.5 b/vdr.5 index 66ce4a15..8a76fdd9 100644 --- a/vdr.5 +++ b/vdr.5 @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 1.15 2002/11/29 14:13:40 kls Exp $ +.\" $Id: vdr.5 1.16 2002/12/01 10:34:40 kls Exp $ .\" .TH vdr 5 "24 Nov 2002" "1.2.0" "Video Disk Recorder Files" .SH NAME @@ -363,13 +363,26 @@ this remote control delivers when the given key is pressed. The file \fIkeymacros.conf\fR contains user defined macros that will be executed whenever the given key is pressed. The format is -\fBmacrokey key1 key2 key3...\fR +\fBmacrokey [@plugin] key1 key2 key3...\fR where \fBmacrokey\fR is the key that shall initiate execution of this macro and can be one of \fIRed\fR, \fIGreen\fR, \fIYellow\fR, \fIBlue\fR or \fIUser1\fR...\fIUser9\fR. The rest of the line consists of a set of keys, which will be executed just as if they had been pressed in the given -sequence. Note that the color keys will only execute their macro function +sequence. The optional \fB@plugin\fR can be used to automatically select +the given plugin from the main menu (provided that plugin has a main menu +entry). \fBplugin\fR is the name of the plugin, exactly as given in the -P +option when starting VDR. There can be only one \fB@plugin\fR per key macro, +and it implicitly adds an \fIOk\fR key to the macro definition (in order to +actually select the plugins main menu entry), which counts against the total +number of keys in the macro. For instance + +\fBUser1 @abc Down Down Ok\fR + +would call the main menu function of the "abc" plugin and execute two "Down" +key presses, followed by "Ok". +.br +Note that the color keys will only execute their macro function in "normal viewing" mode (i.e. when no other menu or player is active). The \fIUser1\fR...\fIUser9\fR keys will always execute their macro function. There may be up to 15 keys in such a key sequence. diff --git a/vdr.c b/vdr.c index 214cdfd2..438f98fe 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.135 2002/11/30 14:37:45 kls Exp $ + * $Id: vdr.c 1.136 2002/12/01 10:44:48 kls Exp $ */ #include @@ -480,7 +480,7 @@ int main(int argc, char *argv[]) Menu = new cMenuMain(cControl::Control()); Temp = NULL; break; - #define DirectMainFunction(function)\ + #define DirectMainFunction(function...)\ DELETENULL(Menu);\ if (cControl::Control())\ cControl::Control()->Hide();\ @@ -493,6 +493,7 @@ int main(int argc, char *argv[]) case kSetup: DirectMainFunction(osSetup); break; case kCommands: DirectMainFunction(osCommands); break; case kUser1 ... kUser9: cRemote::PutMacro(key); break; + case k_Plugin: DirectMainFunction(osPlugin, cRemote::GetPlugin()); break; // Channel up/down: case kChanUp|k_Repeat: case kChanUp: