diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 3648e7a6..8345303e 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1827,3 +1827,6 @@ Richard Lithvall Tobias Grimm for suggesting to use geteuid() to check whether VDR is running as user 'root' + +Peter Dittmann + for a patch that was used as a base to implement cPlugin::Active() diff --git a/HISTORY b/HISTORY index 7a97612f..facf7f1b 100644 --- a/HISTORY +++ b/HISTORY @@ -4523,3 +4523,6 @@ Video Disk Recorder Revision History - Fixed the vdr.1 man page (a single DVB card can record and do live tv). - The preferred audio language is now automatically selected when starting replay. - Updated the Danish OSD texts (thanks to Mogens Elneff). +- The new function cPlugin::Active() can be used by a plugin to indicate that it + is still busy and the system should not shut down or restart (based on a patch + from Peter Dittmann). See PLUGINS.html for details. diff --git a/PLUGINS.html b/PLUGINS.html index 9515174f..8f0e12ef 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -14,18 +14,18 @@ Copyright © 2006 Klaus Schmidinger
www.cadsoft.de/vdr

-
  -Important modifications introduced in version 1.3.30 are marked like this. -
-
  +
  Important modifications introduced in version 1.3.31 are marked like this.
-
  +
  Important modifications introduced in version 1.3.37 are marked like this.
-
  +
  Important modifications introduced in version 1.3.38 are marked like this.
+
  +Important modifications introduced in version 1.3.46 are marked like this. +

VDR provides an easy to use plugin interface that allows additional functionality to be added to the program by implementing a dynamically loadable library file. @@ -62,14 +62,15 @@ structures and allows it to hook itself into specific areas to perform special a

  • Main menu entry
  • User interaction
  • Housekeeping +
      +
  • Activity +
  • Setup parameters
  • The Setup menu
  • Configuration files
  • Internationalization -
     
  • Custom services -
  • -
      +
     
  • SVDRP commands
  • Loading plugins into VDR @@ -609,6 +610,44 @@ interaction is possible. If a specific action takes longer than a few seconds, the plugin should launch a separate thread to do this. +
      +

    Activity

    + +
    Now is not a good time!

    + +If a plugin is running a background task that should be finished before shutting +down the system, it can implement the function + +

    +virtual cString Active(void);
    +

    + +which shall return an empty string if it is ok to shut down, and a proper message +if not: + +

    +cString cDoSomethingPlugin::Active(void)
    +{
    +  if (busy)
    +     return tr("Doing something");
    +  return NULL;
    +}
    +

    + +The message should be short and should indicate what is currently going on. +It will be presented to the user as a confirmation message, followed by a +hyphen and a "shut down anyway?" prompt, as in +

    +Doing something - shut down anyway? +

    +All plugins will be queried, and the first one that returns a non empty +string will cause the confirmation message to be shown. If the user confirms +the prompt by pressing the "Ok" button, the rest of the plugins will also +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. +

    +

    Setup parameters

    Remember me...

    @@ -864,7 +903,6 @@ Texts are first searched for in the Phrases registered for this plugin (i and then in the global VDR texts. So a plugin can make use of texts defined by the core VDR code. -
     

    Custom services

    What can I do for you?

    @@ -933,9 +971,7 @@ To send a message to all plugins, a plugin can call the function cPluginManager::CallAllServices(). This function returns true if any plugin handled the request, or false if no plugin handled the request. -

    - -
      +
     

    SVDRP commands

    Infinite Diversity in Infinite Combinations

    @@ -1262,7 +1298,7 @@ public: cMyControl(void); virtual ~cMyControl(); virtual void Hide(void); -
      +
      virtual cOsdObject *GetInfo(void);
    virtual eOSState ProcessKey(eKeys Key); @@ -1294,7 +1330,7 @@ A derived cControl must implement the Hide() function, it has to hide itself from the OSD, in case it uses it. Hide() may be called at any time, and it may be called even if the cControl is not visible at the moment.

    -
      +
      The GetInfo() function is called when the user presses the Info button, and shall return a pointer to a cOsdObject that contains information about the currently played programme. The caller takes ownership of the returned @@ -1522,7 +1558,7 @@ with the full required resolution. Only if this fails shall it use alternate areas. Drawing areas are always rectangular and may not overlap (but do not need to be adjacent). -
      +
     

    Directly accessing the OSD is only allowed from the foreground thread, which restricts this to a cOsdObject returned from the plugin's MainMenuAction() diff --git a/i18n.c b/i18n.c index 249440b2..70c37802 100644 --- a/i18n.c +++ b/i18n.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.257 2006/04/15 09:22:37 kls Exp $ + * $Id: i18n.c 1.258 2006/04/15 11:05:27 kls Exp $ * * Translations provided by: * @@ -1275,6 +1275,28 @@ const tI18nPhrase Phrases[] = { "Vil du virkelig genstarte?", "Opravdu restartovat?", }, + { "shut down anyway?", + "trotzdem ausschalten?", + "zares izklopi?", + "spengo comunque?", + "toch uitschakelen?", + "quer mesmo desligar?", + "confirmez l'arrêt", + "slå av likevel?", + "sammutetaanko?", + "wy³±czyæ mimo to?", + "¿apagar igualmente?", + "ÔåëéêÜ íá ãßíåé ôåñìáôéóìüò?", + "vill du ändå avbryta?", + "închid, totuºi?", + "mégis kikapcsolni?", + "Apagar de totes maneres?", + "ÔÕÙáâÒØâÕÛìÝÞ ÒëÚÛîçØâì?", + "svejedno iskljuèiti?", + "lülitan välja?", + "sluk alligevel?", + "pøesto vypnout?", + }, { "Recording - restart anyway?", "Aufnahme läuft - trotzdem neu starten?", "Snemanje - zares ponoven zagon?", diff --git a/menu.c b/menu.c index bb72d9fa..56eb0685 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.429 2006/04/14 14:28:34 kls Exp $ + * $Id: menu.c 1.430 2006/04/15 10:30:52 kls Exp $ */ #include "menu.h" @@ -2696,7 +2696,9 @@ void cMenuSetup::Set(void) eOSState cMenuSetup::Restart(void) { - if (Interface->Confirm(cRecordControls::Active() ? tr("Recording - restart anyway?") : tr("Really restart?"))) { + if (Interface->Confirm(tr("Really restart?")) + && (!cRecordControls::Active() || Interface->Confirm(tr("Recording - restart anyway?"))) + && !cPluginManager::Active(tr("Really restart?"))) { cThread::EmergencyExit(true); return osEnd; } diff --git a/newplugin b/newplugin index 1800b7f4..e1d32f0c 100755 --- a/newplugin +++ b/newplugin @@ -12,7 +12,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: newplugin 1.22 2005/11/11 13:20:14 kls Exp $ +# $Id: newplugin 1.23 2006/04/15 11:18:36 kls Exp $ $PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin \n"; @@ -166,6 +166,7 @@ public: virtual bool Start(void); virtual void Stop(void); virtual void Housekeeping(void); + virtual cString Active(void); virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; } virtual cOsdObject *MainMenuAction(void); virtual cMenuSetupPage *SetupMenu(void); @@ -221,6 +222,12 @@ void cPlugin${PLUGIN_CLASS}::Housekeeping(void) // Perform any cleanup or other regular tasks. } +cString cPlugin${PLUGIN_CLASS}::Active(void) +{ + // Return a message string if shutdown should be postponed + return NULL; +} + cOsdObject *cPlugin${PLUGIN_CLASS}::MainMenuAction(void) { // Perform the action when selected from the main VDR menu. diff --git a/plugin.c b/plugin.c index fc1a25ac..4f673f76 100644 --- a/plugin.c +++ b/plugin.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: plugin.c 1.19 2006/04/14 11:45:43 kls Exp $ + * $Id: plugin.c 1.20 2006/04/15 11:17:03 kls Exp $ */ #include "plugin.h" @@ -14,6 +14,7 @@ #include #include #include "config.h" +#include "interface.h" #define LIBVDR_PREFIX "libvdr-" #define SO_INDICATOR ".so." @@ -69,6 +70,11 @@ void cPlugin::Housekeeping(void) { } +cString cPlugin::Active(void) +{ + return NULL; +} + const char *cPlugin::MainMenuEntry(void) { return NULL; @@ -364,6 +370,23 @@ void cPluginManager::Housekeeping(void) } } +bool cPluginManager::Active(const char *Prompt) +{ + if (pluginManager) { + for (cDll *dll = pluginManager->dlls.First(); dll; dll = pluginManager->dlls.Next(dll)) { + cPlugin *p = dll->Plugin(); + if (p) { + cString s = p->Active(); + if (!isempty(*s)) { + if (!Prompt || !Interface->Confirm(cString::sprintf("%s - %s", *s, Prompt))) + return true; + } + } + } + } + return false; +} + bool cPluginManager::HasPlugins(void) { return pluginManager && pluginManager->dlls.Count(); diff --git a/plugin.h b/plugin.h index 285d0dc2..d113c8eb 100644 --- a/plugin.h +++ b/plugin.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: plugin.h 1.11 2006/04/14 11:42:48 kls Exp $ + * $Id: plugin.h 1.12 2006/04/15 10:30:33 kls Exp $ */ #ifndef __PLUGIN_H @@ -39,6 +39,7 @@ public: virtual bool Start(void); virtual void Stop(void); virtual void Housekeeping(void); + virtual cString Active(void); virtual const char *MainMenuEntry(void); virtual cOsdObject *MainMenuAction(void); @@ -89,6 +90,7 @@ public: bool InitializePlugins(void); bool StartPlugins(void); void Housekeeping(void); + static bool Active(const char *Prompt = NULL); static bool HasPlugins(void); static cPlugin *GetPlugin(int Index); static cPlugin *GetPlugin(const char *Name); diff --git a/vdr.c b/vdr.c index ec82bedb..1583f9da 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/vdr * - * $Id: vdr.c 1.256 2006/04/14 11:45:05 kls Exp $ + * $Id: vdr.c 1.257 2006/04/15 11:05:49 kls Exp $ */ #include @@ -980,6 +980,8 @@ int main(int argc, char *argv[]) if (Interface->Confirm(tr("Recording - shut down anyway?"))) ForceShutdown = true; } + if (cPluginManager::Active(tr("shut down anyway?"))) + ForceShutdown = true; LastActivity = 1; // not 0, see below! UserShutdown = true; break; @@ -1093,7 +1095,7 @@ int main(int argc, char *argv[]) Skins.Message(mtInfo, tr("Editing process finished")); } } - if (!Interact && ((!cRecordControls::Active() && !cCutter::Active() && (!Interface->HasSVDRPConnection() || UserShutdown)) || ForceShutdown)) { + if (!Interact && ((!cRecordControls::Active() && !cCutter::Active() && !cPluginManager::Active() && (!Interface->HasSVDRPConnection() || UserShutdown)) || ForceShutdown)) { time_t Now = time(NULL); if (Now - LastActivity > ACTIVITYTIMEOUT) { // Shutdown: