1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Implemented the "Info" key

This commit is contained in:
Klaus Schmidinger 2006-01-06 12:53:28 +01:00
parent c0f1fc817e
commit 700b88bc4d
12 changed files with 117 additions and 39 deletions

View File

@ -4104,3 +4104,12 @@ Video Disk Recorder Revision History
sort modes. sort modes.
- The default cOsdObject::Show() now automatically calls cOsdMenu::Display() if - The default cOsdObject::Show() now automatically calls cOsdMenu::Display() if
this is a menu. this is a menu.
- The new "Info" key brings up information on the currently viewed programme
or recording. For a live programme this is the same as "Schedule/Ok", i.e. the
description of the current EPG event. For a recording this is the same as shown
by the "Info" button in the "Recordings" menu. Plugins that implement players
can overwrite their cControl::GetInfo() function to show their own info (see
PLUGINS.html for details). Pressing the "Info" key again while the info is
displayed will close the OSD. In order to assign this new key to an existing
remote control setup, the remote.conf file needs to be deleted and VDR has
to be restarted to go through the process of learning the remote control keys.

1
MANUAL
View File

@ -33,6 +33,7 @@ Version 1.2
If your remote control provides additional keys, they can be used for the If your remote control provides additional keys, they can be used for the
following functions: following functions:
Info display information on the currently viewed programme or recording
Play resume normal replay Play resume normal replay
Pause pause replay or live video Pause pause replay or live video
Stop stop replay Stop stop replay

View File

@ -14,18 +14,18 @@ Copyright &copy; 2005 Klaus Schmidinger<br>
<a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a> <a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
</center> </center>
<p> <p>
<!--X1.3.21--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%> <!--X1.3.30--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.3.21 are marked like this.
<!--X1.3.21--></td></tr></table>
<!--X1.3.30--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.3.30 are marked like this. Important modifications introduced in version 1.3.30 are marked like this.
<!--X1.3.30--></td></tr></table> <!--X1.3.30--></td></tr></table>
<!--X1.3.31--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%> <!--X1.3.31--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.3.31 are marked like this. Important modifications introduced in version 1.3.31 are marked like this.
<!--X1.3.31--></td></tr></table> <!--X1.3.31--></td></tr></table>
<!--X1.3.37--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%> <!--X1.3.37--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.3.37 are marked like this. Important modifications introduced in version 1.3.37 are marked like this.
<!--X1.3.37--></td></tr></table> <!--X1.3.37--></td></tr></table>
<!--X1.3.38--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.3.38 are marked like this.
<!--X1.3.38--></td></tr></table>
<p> <p>
VDR provides an easy to use plugin interface that allows additional functionality 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. to be added to the program by implementing a dynamically loadable library file.
@ -66,10 +66,10 @@ structures and allows it to hook itself into specific areas to perform special a
<li><a href="#The Setup menu">The Setup menu</a> <li><a href="#The Setup menu">The Setup menu</a>
<li><a href="#Configuration files">Configuration files</a> <li><a href="#Configuration files">Configuration files</a>
<li><a href="#Internationalization">Internationalization</a> <li><a href="#Internationalization">Internationalization</a>
<!--X1.3.30--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%> <!--X1.3.30--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<li><a href="#Custom services">Custom services</a> <li><a href="#Custom services">Custom services</a>
<!--X1.3.30--></td></tr></table> <!--X1.3.30--></td></tr></table>
<!--X1.3.31--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%> <!--X1.3.31--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<li><a href="#SVDRP commands">SVDRP commands</a> <li><a href="#SVDRP commands">SVDRP commands</a>
<!--X1.3.31--></td></tr></table> <!--X1.3.31--></td></tr></table>
<li><a href="#Loading plugins into VDR">Loading plugins into VDR</a> <li><a href="#Loading plugins into VDR">Loading plugins into VDR</a>
@ -85,9 +85,7 @@ structures and allows it to hook itself into specific areas to perform special a
<li><a href="#Skins">Skins</a> <li><a href="#Skins">Skins</a>
<li><a href="#Themes">Themes</a> <li><a href="#Themes">Themes</a>
<li><a href="#Devices">Devices</a> <li><a href="#Devices">Devices</a>
<!--X1.3.21--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<li><a href="#Audio">Audio</a> <li><a href="#Audio">Audio</a>
<!--X1.3.21--></td></tr></table>
<li><a href="#Remote Control">Remote Control</a> <li><a href="#Remote Control">Remote Control</a>
</ul> </ul>
</ul> </ul>
@ -866,7 +864,7 @@ Texts are first searched for in the <i>Phrases</i> registered for this plugin (i
and then in the global VDR texts. So a plugin can make use of texts defined by the and then in the global VDR texts. So a plugin can make use of texts defined by the
core VDR code. core VDR code.
<!--X1.3.30--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%> <!--X1.3.30--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<a name="Custom services"><hr><h2>Custom services</h2> <a name="Custom services"><hr><h2>Custom services</h2>
<center><i><b>What can I do for you?</b></i></center><p> <center><i><b>What can I do for you?</b></i></center><p>
@ -937,7 +935,7 @@ any plugin handled the request, or <tt>false</tt> if no plugin handled the reque
<!--X1.3.30--></td></tr></table> <!--X1.3.30--></td></tr></table>
<!--X1.3.31--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%> <!--X1.3.31--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<a name="SVDRP commands"><hr><h2>SVDRP commands</h2> <a name="SVDRP commands"><hr><h2>SVDRP commands</h2>
<center><i><b>Infinite Diversity in Infinite Combinations</b></i></center><p> <center><i><b>Infinite Diversity in Infinite Combinations</b></i></center><p>
@ -1264,6 +1262,9 @@ public:
cMyControl(void); cMyControl(void);
virtual ~cMyControl(); virtual ~cMyControl();
virtual void Hide(void); virtual void Hide(void);
<!--X1.3.38--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
virtual cOsdObject *GetInfo(void);
<!--X1.3.38--></td></tr></table>
virtual eOSState ProcessKey(eKeys Key); virtual eOSState ProcessKey(eKeys Key);
}; };
</pre></td></tr></table><p> </pre></td></tr></table><p>
@ -1292,8 +1293,14 @@ to make the main program loop shut down the player control.
A derived <tt>cControl</tt> <b>must</b> implement the <tt>Hide()</tt> function, in which A derived <tt>cControl</tt> <b>must</b> implement the <tt>Hide()</tt> function, in which
it has to hide itself from the OSD, in case it uses it. <tt>Hide()</tt> may be called at it has to hide itself from the OSD, in case it uses it. <tt>Hide()</tt> may be called at
any time, and it may be called even if the <tt>cControl</tt> is not visible at the moment. any time, and it may be called even if the <tt>cControl</tt> is not visible at the moment.
The reason for this is that the <tt>Menu</tt> button shall always bring up the main VDR <p>
menu, so any active <tt>cControl</tt> needs to be hidden when that button is pressed. <!--X1.3.38--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
The <tt>GetInfo()</tt> function is called when the user presses the <tt>Info</tt> button,
and shall return a pointer to a <tt>cOsdObject</tt> that contains information
about the currently played programme. The caller takes ownership of the returned
pointer and will delete it when it is no longer used. If no information is available,
<tt>NULL</tt> shall be returned.
<!--X1.3.38--></td></tr></table>
<p> <p>
Finally, to get things going, a plugin that implements a player (and the surrounding Finally, to get things going, a plugin that implements a player (and the surrounding
infrastructure like displaying a list of playable stuff etc) simply has to call the infrastructure like displaying a list of playable stuff etc) simply has to call the
@ -1515,7 +1522,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 areas. Drawing areas are always rectangular and may not overlap (but do not need
to be adjacent). to be adjacent).
<!--X1.3.37--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%> <!--X1.3.37--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
<p> <p>
Directly accessing the OSD is only allowed from the foreground thread, which Directly accessing the OSD is only allowed from the foreground thread, which
restricts this to a <tt>cOsdObject</tt> returned from the plugin's <tt>MainMenuAction()</tt> restricts this to a <tt>cOsdObject</tt> returned from the plugin's <tt>MainMenuAction()</tt>
@ -1840,9 +1847,7 @@ private:
virtual void Action(void); virtual void Action(void);
public: public:
cMyAudio(void); cMyAudio(void);
<!--X1.3.21--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
virtual void Play(const uchar *Data, int Length, uchar Id); virtual void Play(const uchar *Data, int Length, uchar Id);
<!--X1.3.21--></td></tr></table>
virtual void Mute(bool On); virtual void Mute(bool On);
virtual void Clear(void); virtual void Clear(void);
}; };

23
i18n.c
View File

@ -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.225 2006/01/04 15:50:19 kls Exp $ * $Id: i18n.c 1.226 2006/01/05 15:39:56 kls Exp $
* *
* Translations provided by: * Translations provided by:
* *
@ -4631,6 +4631,27 @@ const tI18nPhrase Phrases[] = {
"Sinine", "Sinine",
"Blå", "Blå",
}, },
{ "Key$Info",
"Info",
"Info",
"",//TODO
"Info",
"",//TODO
"Info",
"",//TODO
"Tiedot",
"",//TODO
"",//TODO
"Ðëçñïöïñßåò",
"Info",
"Info",
"",//TODO
"",//TODO
"¸ÝäÞ",
"Info",
"Info",
"Info",
},
{ "Key$Play", { "Key$Play",
"Wiedergabe", "Wiedergabe",
"Predvajaj", "Predvajaj",

View File

@ -9,4 +9,5 @@
Red Recordings Red Recordings
Green Schedule Green Schedule
Yellow Info
Blue Timers Blue Timers

3
keys.c
View File

@ -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: keys.c 1.9 2005/09/17 11:27:40 kls Exp $ * $Id: keys.c 1.10 2006/01/05 15:39:26 kls Exp $
*/ */
#include "keys.h" #include "keys.h"
@ -32,6 +32,7 @@ static tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
{ k7, "7" }, { k7, "7" },
{ k8, "8" }, { k8, "8" },
{ k9, "9" }, { k9, "9" },
{ kInfo, "Info" },
{ kPlay, "Play" }, { kPlay, "Play" },
{ kPause, "Pause" }, { kPause, "Pause" },
{ kStop, "Stop" }, { kStop, "Stop" },

3
keys.h
View File

@ -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: keys.h 1.6 2004/12/27 11:10:59 kls Exp $ * $Id: keys.h 1.7 2006/01/05 15:39:06 kls Exp $
*/ */
#ifndef __KEYS_H #ifndef __KEYS_H
@ -26,6 +26,7 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
kYellow, kYellow,
kBlue, kBlue,
k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k0, k1, k2, k3, k4, k5, k6, k7, k8, k9,
kInfo,
kPlay, kPlay,
kPause, kPause,
kStop, kStop,

10
menu.c
View File

@ -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.386 2006/01/05 14:02:45 kls Exp $ * $Id: menu.c 1.387 2006/01/06 11:44:25 kls Exp $
*/ */
#include "menu.h" #include "menu.h"
@ -3877,6 +3877,14 @@ void cReplayControl::EditTest(void)
} }
} }
cOsdObject *cReplayControl::GetInfo(void)
{
cRecording *Recording = Recordings.GetByName(cReplayControl::LastReplayed());
if (Recording)
return new cMenuRecording(Recording);
return NULL;
}
eOSState cReplayControl::ProcessKey(eKeys Key) eOSState cReplayControl::ProcessKey(eKeys Key)
{ {
if (!Active()) if (!Active())

3
menu.h
View File

@ -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.h 1.80 2006/01/04 13:47:00 kls Exp $ * $Id: menu.h 1.81 2006/01/06 11:30:38 kls Exp $
*/ */
#ifndef __MENU_H #ifndef __MENU_H
@ -240,6 +240,7 @@ private:
public: public:
cReplayControl(void); cReplayControl(void);
virtual ~cReplayControl(); virtual ~cReplayControl();
virtual cOsdObject *GetInfo(void);
virtual eOSState ProcessKey(eKeys Key); virtual eOSState ProcessKey(eKeys Key);
virtual void Show(void); virtual void Show(void);
virtual void Hide(void); virtual void Hide(void);

View File

@ -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: player.c 1.10 2006/01/01 14:45:36 kls Exp $ * $Id: player.c 1.11 2006/01/06 11:30:07 kls Exp $
*/ */
#include "player.h" #include "player.h"
@ -55,6 +55,11 @@ cControl::~cControl()
control = NULL; control = NULL;
} }
cOsdObject *cControl::GetInfo(void)
{
return NULL;
}
cControl *cControl::Control(void) cControl *cControl::Control(void)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);

View File

@ -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: player.h 1.18 2006/01/01 14:43:10 kls Exp $ * $Id: player.h 1.19 2006/01/06 11:29:27 kls Exp $
*/ */
#ifndef __PLAYER_H #ifndef __PLAYER_H
@ -71,6 +71,7 @@ public:
cControl(cPlayer *Player, bool Hidden = false); cControl(cPlayer *Player, bool Hidden = false);
virtual ~cControl(); virtual ~cControl();
virtual void Hide(void) = 0; virtual void Hide(void) = 0;
virtual cOsdObject *GetInfo(void);
bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false) { return player->GetIndex(Current, Total, SnapToIFrame); } bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false) { return player->GetIndex(Current, Total, SnapToIFrame); }
bool GetReplayMode(bool &Play, bool &Forward, int &Speed) { return player->GetReplayMode(Play, Forward, Speed); } bool GetReplayMode(bool &Play, bool &Forward, int &Speed) { return player->GetReplayMode(Play, Forward, Speed); }
static void Launch(cControl *Control); static void Launch(cControl *Control);

54
vdr.c
View File

@ -22,7 +22,7 @@
* *
* The project's page is at http://www.cadsoft.de/vdr * The project's page is at http://www.cadsoft.de/vdr
* *
* $Id: vdr.c 1.229 2006/01/05 15:35:06 kls Exp $ * $Id: vdr.c 1.230 2006/01/06 12:47:16 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
@ -491,6 +491,7 @@ int main(int argc, char *argv[])
bool ForceShutdown = false; bool ForceShutdown = false;
bool UserShutdown = false; bool UserShutdown = false;
bool TimerInVpsMargin = false; bool TimerInVpsMargin = false;
bool IsInfoMenu = false;
// Load plugins: // Load plugins:
@ -646,6 +647,8 @@ int main(int argc, char *argv[])
// Main program loop: // Main program loop:
#define DELETE_MENU ((IsInfoMenu &= (Menu == NULL)), delete Menu, Menu = NULL)
while (!Interrupted) { while (!Interrupted) {
// Handle emergency exits: // Handle emergency exits:
if (cThread::EmergencyExit()) { if (cThread::EmergencyExit()) {
@ -786,14 +789,35 @@ int main(int argc, char *argv[])
case kMenu: case kMenu:
key = kNone; // nobody else needs to see this key key = kNone; // nobody else needs to see this key
if (Menu) if (Menu)
DELETENULL(Menu); DELETE_MENU;
else if (cControl::Control() && cOsd::IsOpen()) else if (cControl::Control() && cOsd::IsOpen())
cControl::Control()->Hide(); cControl::Control()->Hide();
else else
Menu = new cMenuMain; Menu = new cMenuMain;
break; break;
// Info:
case kInfo: {
bool WasInfoMenu = IsInfoMenu;
DELETE_MENU;
if (!WasInfoMenu) {
IsInfoMenu = true;
if (cControl::Control()) {
cControl::Control()->Hide();
Menu = cControl::Control()->GetInfo();
if (Menu)
Menu->Show();
else
IsInfoMenu = false;
}
else {
cRemote::Put(kOk, true);
cRemote::Put(kSchedule, true);
}
}
}
break;
#define DirectMainFunction(function)\ #define DirectMainFunction(function)\
DELETENULL(Menu);\ DELETE_MENU;\
if (cControl::Control())\ if (cControl::Control())\
cControl::Control()->Hide();\ cControl::Control()->Hide();\
Menu = new cMenuMain(function);\ Menu = new cMenuMain(function);\
@ -806,7 +830,7 @@ int main(int argc, char *argv[])
case kCommands: DirectMainFunction(osCommands); break; case kCommands: DirectMainFunction(osCommands); break;
case kUser1 ... kUser9: cRemote::PutMacro(key); key = kNone; break; case kUser1 ... kUser9: cRemote::PutMacro(key); key = kNone; break;
case k_Plugin: { case k_Plugin: {
DELETENULL(Menu); DELETE_MENU;
if (cControl::Control()) if (cControl::Control())
cControl::Control()->Hide(); cControl::Control()->Hide();
cPlugin *plugin = cPluginManager::GetPlugin(cRemote::GetPlugin()); cPlugin *plugin = cPluginManager::GetPlugin(cRemote::GetPlugin());
@ -851,7 +875,7 @@ int main(int argc, char *argv[])
if (cControl::Control()) if (cControl::Control())
cControl::Control()->Hide(); cControl::Control()->Hide();
if (!cDisplayTracks::IsOpen()) { if (!cDisplayTracks::IsOpen()) {
DELETENULL(Menu); DELETE_MENU;
Menu = cDisplayTracks::Create(); Menu = cDisplayTracks::Create();
} }
else else
@ -861,7 +885,7 @@ int main(int argc, char *argv[])
// Pausing live video: // Pausing live video:
case kPause: case kPause:
if (!cControl::Control()) { if (!cControl::Control()) {
DELETENULL(Menu); DELETE_MENU;
if (!cRecordControls::PauseLiveVideo()) if (!cRecordControls::PauseLiveVideo())
Skins.Message(mtError, tr("No free DVB device to record!")); Skins.Message(mtError, tr("No free DVB device to record!"));
key = kNone; // nobody else needs to see this key key = kNone; // nobody else needs to see this key
@ -879,7 +903,7 @@ int main(int argc, char *argv[])
break; break;
// Power off: // Power off:
case kPower: isyslog("Power button pressed"); case kPower: isyslog("Power button pressed");
DELETENULL(Menu); DELETE_MENU;
if (!Shutdown) { if (!Shutdown) {
Skins.Message(mtError, tr("Can't shutdown - option '-s' not given!")); Skins.Message(mtError, tr("Can't shutdown - option '-s' not given!"));
break; break;
@ -909,44 +933,44 @@ int main(int argc, char *argv[])
state = osEnd; state = osEnd;
} }
switch (state) { switch (state) {
case osPause: DELETENULL(Menu); case osPause: DELETE_MENU;
cControl::Shutdown(); // just in case cControl::Shutdown(); // just in case
if (!cRecordControls::PauseLiveVideo()) if (!cRecordControls::PauseLiveVideo())
Skins.Message(mtError, tr("No free DVB device to record!")); Skins.Message(mtError, tr("No free DVB device to record!"));
break; break;
case osRecord: DELETENULL(Menu); case osRecord: DELETE_MENU;
if (cRecordControls::Start()) if (cRecordControls::Start())
Skins.Message(mtInfo, tr("Recording started")); Skins.Message(mtInfo, tr("Recording started"));
else else
Skins.Message(mtError, tr("No free DVB device to record!")); Skins.Message(mtError, tr("No free DVB device to record!"));
break; break;
case osRecordings: case osRecordings:
DELETENULL(Menu); DELETE_MENU;
cControl::Shutdown(); cControl::Shutdown();
Menu = new cMenuMain(osRecordings); Menu = new cMenuMain(osRecordings);
break; break;
case osReplay: DELETENULL(Menu); case osReplay: DELETE_MENU;
cControl::Shutdown(); cControl::Shutdown();
cControl::Launch(new cReplayControl); cControl::Launch(new cReplayControl);
break; break;
case osStopReplay: case osStopReplay:
DELETENULL(Menu); DELETE_MENU;
cControl::Shutdown(); cControl::Shutdown();
break; break;
case osSwitchDvb: case osSwitchDvb:
DELETENULL(Menu); DELETE_MENU;
cControl::Shutdown(); cControl::Shutdown();
Skins.Message(mtInfo, tr("Switching primary DVB...")); Skins.Message(mtInfo, tr("Switching primary DVB..."));
cDevice::SetPrimaryDevice(Setup.PrimaryDVB); cDevice::SetPrimaryDevice(Setup.PrimaryDVB);
break; break;
case osPlugin: DELETENULL(Menu); case osPlugin: DELETE_MENU;
Menu = cMenuMain::PluginOsdObject(); Menu = cMenuMain::PluginOsdObject();
if (Menu) if (Menu)
Menu->Show(); Menu->Show();
break; break;
case osBack: case osBack:
case osEnd: if (Interact == Menu) case osEnd: if (Interact == Menu)
DELETENULL(Menu); DELETE_MENU;
else else
cControl::Shutdown(); cControl::Shutdown();
break; break;