2 Copyright 2004-2020 Chris Tallon
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
20 // FIXME rename to Control and move stuff from main to here
23 #include <unistd.h> // for reboot
24 #include <linux/reboot.h>
25 #include <sys/reboot.h>
35 #include "inputandroid.h"
43 #include "vserverselect.h"
59 #include "sleeptimer.h"
61 #include "osdvector.h"
63 #include "vvideolivetv.h"
65 #include "imageloader.h"
68 #ifdef VOMP_PLATFORM_RASPBERRY
69 #include "ledraspberry.h"
70 #include "osdopenvg.h"
76 #include "windowsosd.h"
78 #include "osdwinpixel.h"
80 #include "osdwinvector.h"
90 static const char* TAG = "Control";
92 Control* Control::instance = NULL;
106 Control* Control::getInstance()
111 bool Control::init(bool tcrashed)
113 if (initted) return false;
115 logger = LogNT::getInstance();
117 SkinFactory::InitSkin(0);
119 // FIXME All constructors first which do very little & don't rely on presence of other objects.
120 // Then all inits. Inits retrieve pointers to other objects.
124 led = new Led_TYPE(); if (!led) throw 10;
125 if (!led->init(-1)) throw 11; // FIXME init(0) on Win32
127 timers = new Timers(); if (!timers) throw 20;
128 if (!timers->init()) throw 21;
130 video = new Video_TYPE(); if (!video) throw 30;
131 if (!video->init(Video::PAL)) throw 31;
133 audio = new Audio_TYPE(); if (!audio) throw 40;
134 if (!audio->init(Audio::MPEG2_PES)) throw 41;
136 imageLoader = new ImageLoader(); if (!imageLoader) throw 50;
137 if (!imageLoader->init()) throw 51;
139 osd = new Osd_TYPE(); if (!osd) throw 60;
140 if (!osd->init()) throw 61;
142 vdr = new VDR(); if (!vdr) throw 70;
143 if (!vdr->init()) throw 71;
145 boxstack = new BoxStack(); if (!boxstack) throw 80;
146 if (!boxstack->init()) throw 81;
148 sleepTimer = new SleepTimer(); if (!sleepTimer) throw 90;
150 wol = new Wol(); if (!wol) throw 100;
152 inputMan = new InputMan(); if (!inputMan) throw 110;
153 if (!inputMan->init()) throw 111;
158 if (e == 10) logger->crit(TAG, "LED module failed to create");
159 else if (e == 11) logger->crit(TAG, "LED module failed to initialise");
160 else if (e == 20) logger->crit(TAG, "Timers module failed to create");
161 else if (e == 21) logger->crit(TAG, "Timers module failed to initialise");
162 else if (e == 30) logger->crit(TAG, "Video module failed to create");
163 else if (e == 31) logger->crit(TAG, "Video module failed to initialise");
164 else if (e == 40) logger->crit(TAG, "Audio module failed to create");
165 else if (e == 41) logger->crit(TAG, "Audio module failed to initialise");
166 else if (e == 50) logger->crit(TAG, "ImageLoader module failed to create");
167 else if (e == 51) logger->crit(TAG, "ImageLoader module failed to initialise");
168 else if (e == 60) logger->crit(TAG, "OSD module failed to create");
169 else if (e == 61) logger->crit(TAG, "OSD module failed to initialise");
170 else if (e == 70) logger->crit(TAG, "VDR module failed to create");
171 else if (e == 71) logger->crit(TAG, "VDR module failed to initialise");
172 else if (e == 80) logger->crit(TAG, "BoxStack module failed to create");
173 else if (e == 81) logger->crit(TAG, "BoxStack module failed to initialise");
174 else if (e == 90) logger->crit(TAG, "SleepTimer module failed to create");
175 else if (e == 100) logger->crit(TAG, "WOL module failed to create");
176 else if (e == 110) logger->crit(TAG, "InputMan module failed to create");
177 else if (e == 111) logger->crit(TAG, "InputMan module failed to initialise");
194 boxstack->shutdown();
215 imageLoader->shutdown();
260 void Control::shutdown()
262 if (!initted) return;
267 inputMan->shutdown();
270 logger->info(TAG, "InputMan module shut down");
276 logger->info(TAG, "WOL module shut down");
283 logger->info(TAG, "SleepTimer module shut down");
288 boxstack->shutdown();
291 logger->info(TAG, "BoxStack module shut down");
299 logger->info(TAG, "VDR module shut down");
307 logger->info(TAG, "OSD module shut down");
312 imageLoader->shutdown();
315 logger->info(TAG, "ImageLoader shut down");
323 logger->info(TAG, "Audio module shut down");
331 logger->info(TAG, "Video module shut down");
339 logger->info(TAG, "Timers module shut down");
347 logger->info(TAG, "LED module shut down");
353 logger->info(TAG, "Request stop");
355 Message* m = new Message(); // break master loop
356 m->message = Message::SHUTDOWN;
357 m->p_to = Message::CONTROL;
361 void Control::doWallpaper()
364 Boxx* bbg = new Boxx();
365 bbg->setSize(video->getScreenWidth(), video->getScreenHeight());
367 bbg->fillColour(DrawStyle::WALLPAPER);
369 boxstack->update(bbg);
370 boxstack->remove(bbg);
373 wallpaper = new Boxx();
374 wallpaper->setSize(video->getScreenWidth(), video->getScreenHeight());
375 wallpaper->createBuffer();
376 wallpaper->setBackgroundColour(DrawStyle::WALLPAPER);
378 wallpaper_pict = new WJpegTYPE();
379 wallpaper_pict->setSize(video->getScreenWidth(), video->getScreenHeight());
381 if (video->getFormat() == Video::PAL)
383 logger->debug(TAG, "PAL wallpaper selected");
385 wallpaper_pict->init("/wallpaperPAL.jpg");
387 wallpaper_pict->init("wallpaperPAL.jpg");
392 logger->debug(TAG, "NTSC wallpaper selected");
393 wallpaper_pict->init("/wallpaperNTSC.jpg");
396 if (DrawStyle::WALLPAPER.alpha)
397 wallpaper_pict->setVisible(true);
399 wallpaper_pict->setVisible(false);
401 wallpaper->add(wallpaper_pict);
404 boxstack->add(wallpaper);
405 boxstack->update(wallpaper);
407 OsdVector* osdv = dynamic_cast<OsdVector*>(Osd::getInstance());
408 if (osdv) osdv->updateBackgroundColor(DrawStyle::WALLPAPER);
413 if (!initted) return;
416 Video::getInstance()->signalOn();
417 Led::getInstance()->on();
427 VConnect* vconnect = new VConnect(); // Deleted when VConnect messages Control, and is boxstack->remove()'d
428 boxstack->add(vconnect);
434 //logger->debug(TAG, "Setting log trace only mode");
435 //logger->setTraceOnlyMode(false);
437 messageLoopRun = true;
442 boxstack->removeAllExceptWallpaper();
443 boxstack->remove(wallpaper);
444 delete wallpaper_pict; wallpaper_pict = NULL; wallpaper = NULL;
447 void Control::dispatchMessage(Message* m)
449 logger->debug(TAG, "processing message {}", m->message);
451 if (m->p_to == Message::CONTROL)
455 case Message::SHUTDOWN:
457 messageLoopRun = false;
460 case Message::STOP_PLAYBACK:
462 handleCommand(Input::STOP); // an odd way of doing it, but so simple
465 case Message::VDR_CONNECTED:
467 doJustConnected(static_cast<VConnect*>(m->from));
470 case Message::SCREENSHOT:
472 logger->info(TAG, "Screenshot Message arrived");
473 Osd::getInstance()->screenShot("out.jpg");
476 case Message::CONNECTION_LOST:
481 case Message::INPUT_EVENT:
483 logger->info(TAG, "INPUT_EVENT {}", m->parameter);
485 handleCommand(m->parameter);
488 case Message::CHANGE_LANGUAGE:
490 boxstack->removeAllExceptWallpaper();
491 boxstack->update(wallpaper);
493 if (!VDR::getInstance()->isConnected()) { connectionLost(); break; }
494 VWelcome* vw = new VWelcome();
497 boxstack->update(vw);
500 case Message::LAST_VIEW_CLOSE:
502 // Shouldn't be done like this. Some generic message pass back from vinfo perhaps
509 // VWelcome* vw = new VWelcome();
511 // boxstack->add(vw);
512 // boxstack->update(vw);
518 else if (m->p_to == Message::BOXSTACK)
520 boxstack->processMessage(m);
522 else if (m->p_to == Message::MOUSE_RECEIVER)
524 logger->debug(TAG, "Sending mouse message to boxstack for dispatch");
525 boxstack->processMessage(m);
530 m->to->processMessage(m);
533 logger->debug(TAG, "done processing message {}", m->message);
536 void Control::handleCommand(int button)
538 if (isStandby && (button != Input::POWER)
539 && (button != Input::POWERON)
540 && (button != Input::POWEROFF)) return;
542 if (!connLost && boxstack->handleCommand(button)) return; // don't send to boxstack if connLost
544 // command was not handled
548 case Input::VOLUMEUP:
549 case Input::VOLUMEDOWN:
551 if (inputMan->handlesVolume()) // CEC volume handler?
553 if (button == Input::VOLUMEDOWN)
554 inputMan->volumeDown();
556 inputMan->volumeUp();
560 VVolume* v = new VVolume();
562 v->handleCommand(button); // this will draw+show
568 if (inputMan->handlesVolume())
570 inputMan->volumeMute();
574 VMute* v = new VMute();
591 case Input::POWEROFF:
599 if (!connLost) return; // if connLost, handle Input::OK
605 logger->debug(TAG, "Handling sleeptimer go");
616 Message* m = new Message(); // break into master mutex
617 m->message = Message::SCREENSHOT;
618 m->p_to = Message::CONTROL;
624 void Control::doStandby()
637 void Control::doPowerOn()
641 Video::getInstance()->signalOn();
642 Led::getInstance()->on();
643 InputMan::getInstance()->changePowerState(true);
646 VConnect* vconnect = new VConnect();
647 boxstack->add(vconnect);
652 void Control::doPowerOff()
656 VDR::getInstance()->shutdownVDR();
657 boxstack->removeAllExceptWallpaper();
658 Video::getInstance()->signalOff();
659 boxstack->update(wallpaper);
661 VDR::getInstance()->configSave("General", "Last Power State", "Off");
662 logger->unsetExternLogger();
663 VDR::getInstance()->disconnect();
664 Led::getInstance()->off();
665 InputMan::getInstance()->changePowerState(false);
667 sleepTimer->shutdown();
671 void Control::doFromTheTop(bool which)
673 if (isStandby) return;
678 logger->info(TAG, "Connection lost dialog already present");
682 logger->info(TAG, "Doing connection lost dialog");
683 connLost = new VInfo();
684 connLost->setSize(360, 200);
685 connLost->createBuffer();
686 if (Video::getInstance()->getFormat() == Video::PAL)
687 connLost->setPosition(190, 170);
689 connLost->setPosition(180, 120);
690 connLost->setOneLiner(tr("Connection lost"));
691 connLost->setDropThrough();
692 connLost->setBorderOn(1);
693 connLost->setTitleBarColour(DrawStyle::DANGER);
694 connLost->okButton();
696 boxstack->add(connLost);
697 boxstack->update(connLost);
699 clearMQInputEvents();
703 logger->unsetExternLogger();
704 VDR::getInstance()->disconnect();
705 boxstack->removeAllExceptWallpaper();
706 boxstack->update(wallpaper);
711 // at this point, everything should be reset to first-go
713 VConnect* vconnect = new VConnect(); // deleted eventually in boxstack
714 boxstack->add(vconnect);
719 void Control::clearMQInputEvents()
721 std::lock_guard<std::mutex> lg(messageQueueMutex); // Get the lock
723 MQueueI i = messages.begin();
724 while(i != messages.end())
727 if (m->message == Message::INPUT_EVENT)
730 i = messages.erase(i);
739 void Control::doReboot()
742 logger->unsetExternLogger();
743 VDR::getInstance()->disconnect();
745 logger->info(TAG, "Reboot");
747 #ifndef VOMP_HAS_EXIT
748 // some plattforms, want a proper deinitialisation of their hardware before reboot
749 Osd::getInstance()->shutdown();
750 Audio::getInstance()->shutdown();
751 Video::getInstance()->shutdown();
752 InputMan::getInstance()->shutdown();
754 reboot(LINUX_REBOOT_CMD_RESTART);
755 // if reboot is not allowed -> stop
767 #endif //Would we support this on windows?
770 void Control::connectionLost()
772 logger->unsetExternLogger();
773 Message* m = new Message(); // break into master mutex
774 m->message = Message::CONNECTION_LOST;
775 m->p_to = Message::CONTROL;
779 void Control::buildCrashedBox()
781 VInfo* crash = new VInfo();
782 crash->setSize(360, 250);
783 crash->createBuffer();
784 if (Video::getInstance()->getFormat() == Video::PAL)
785 crash->setPosition(190, 146);
787 crash->setPosition(180, 96);
788 crash->setMainText("Oops, vomp crashed.. :(\nPlease report this crash to the author, with as much detail as possible about what you were doing at the time that might have caused the crash.");
789 crash->setBorderOn(1);
790 crash->setTitleBarColour(DrawStyle::DANGER);
792 crash->setExitable();
794 boxstack->add(crash);
795 boxstack->update(crash);
798 int Control::getLangPref(bool subtitle, const char* langcode)
800 std::vector<struct ASLPref>::iterator itty=langcodes.begin();
801 char templangcode[4];
802 templangcode[0] = langcode[0];
803 templangcode[1] = langcode[1];
804 templangcode[2] = langcode[2];
805 templangcode[3] = '\0';
807 while (itty != langcodes.end())
809 size_t pos = (*itty).langcode.find(templangcode);
810 if (pos != std::string::npos)
812 //vector<struct ASLPref>::iterator itty2=langcodes.begin();
813 for (unsigned int i = 0; i < langcodes.size(); i++)
817 pref = langcodes[i].subtitlepref;
819 pref = langcodes[i].audiopref;
824 if (langcodes[i].subtitlepref==langpos) return i;
828 if (langcodes[i].audiopref==langpos) return i;
836 return langcodes.size(); //neutral
839 void Control::doJustConnected(VConnect* vconnect)
842 if (!VDR::getInstance()->isConnected()) { connectionLost(); return; }
843 logger->info(TAG, "Entering doJustConnected");
845 boxstack->remove(vconnect);
847 VInfo* vi = new VInfo();
848 vi->setSize(400, 200);
850 if (video->getFormat() == Video::PAL)
851 vi->setPosition(170, 200);
853 vi->setPosition(160, 150);
854 vi->setOneLiner(tr("Connected, loading config"));
857 boxstack->update(vi);
859 // FIXME make config system
863 // See if we're supposed to do network logging
864 config = vdr->configLoad("Advanced", "Network logging");
865 if (config && !STRCASECMP(config, "On"))
867 logger->info(TAG, "Turning on network logging");
868 logger->setExternLogger(vdr);
872 logger->unsetExternLogger();
873 logger->info(TAG, "Turned off network logging");
875 if (config) delete[] config;
877 config = vdr->configLoad("Advanced", "Skin Name");
880 const char **skinnames=SkinFactory::getSkinNames();
881 for (int i=0;i<SkinFactory::getNumberofSkins();i++)
883 if (!STRCASECMP(config, skinnames[i]))
885 SkinFactory::InitSkin(i);
891 if (wallpaper && wallpaper_pict)
893 if (DrawStyle::WALLPAPER.alpha)
894 wallpaper_pict->setVisible(true);
896 wallpaper_pict->setVisible(false);
899 boxstack->update(wallpaper);
904 SkinFactory::InitSkin(0);
907 // See if config says to override video format (PAL/NTSC)
908 config = vdr->configLoad("General", "Override Video Format");
911 logger->debug(TAG, "Override Video Format is present");
913 if ( (!strcmp(config, "PAL") && (video->getFormat() != Video::PAL))
914 || (!strcmp(config, "NTSC") && (video->getFormat() != Video::NTSC))
915 || (!strcmp(config, "PAL_M") && (video->getFormat() != Video::PAL_M))
916 || (!strcmp(config, "NTSC_J") && (video->getFormat() != Video::NTSC_J))
919 // Oh sheesh, need to switch format. Bye bye TV...
921 // Take everything down
922 boxstack->removeAllExceptWallpaper();
923 boxstack->remove(wallpaper);
924 delete wallpaper_pict; wallpaper_pict = NULL; wallpaper = NULL;
931 // FIXME FIXME FIXME why do this?
932 inputMan->shutdown(); // need on raspberry shut not do any harm, hopefully
935 // Get video and osd back up with the new mode
936 if (!strcmp(config, "PAL"))
938 logger->debug(TAG, "Switching to PAL");
939 video->init(Video::PAL);
941 else if (!strcmp(config, "NTSC"))
943 logger->debug(TAG, "Switching to NTSC");
944 video->init(Video::NTSC);
945 } else if (!strcmp(config, "PAL_M"))
947 logger->debug(TAG, "Switching to PAL_M");
948 video->init(Video::PAL_M);
949 } else if (!strcmp(config, "NTSC_J"))
951 logger->debug(TAG, "Switching to NTSC_J");
952 video->init(Video::NTSC_J);
957 //we do not init twice
961 // Put the wallpaper back
966 vi->setSize(400, 200);
968 if (video->getFormat() == Video::PAL)
969 vi->setPosition(170, 200);
971 vi->setPosition(160, 150);
973 vi->setOneLiner(tr("Connected, loading config"));
976 boxstack->update(vi);
980 logger->debug(TAG, "Already in requested mode, or request was not 'PAL' or 'NTSC'");
985 logger->debug(TAG, "Phew, no dangerous on-the-fly mode switching to do!");
988 // Power off if first boot and config says so
993 logger->debug(TAG, "Load power after boot");
995 config = vdr->configLoad("General", "Power After Boot");
999 if (!STRCASECMP(config, "On"))
1001 logger->info(TAG, "Config says Power After Boot = On");
1003 else if (!STRCASECMP(config, "Off"))
1005 logger->info(TAG, "Config says Power After Boot = Off");
1008 return; // quit here
1010 else if (!STRCASECMP(config, "Last state"))
1012 char* lastPowerState = vdr->configLoad("General", "Last Power State");
1015 if (!STRCASECMP(lastPowerState, "On"))
1017 logger->info(TAG, "Config says Last Power State = On");
1019 else if (!STRCASECMP(lastPowerState, "Off"))
1021 logger->info(TAG, "Config says Last Power State = Off");
1024 return; // quit here
1028 logger->info(TAG, "Config General/Last Power State not understood");
1033 logger->info(TAG, "Config General/Last Power State not found");
1038 logger->info(TAG, "Config/Power After Boot not understood");
1044 logger->info(TAG, "Config General/Power After Boot not found");
1049 // Go S-Video if config says so
1051 config = vdr->configLoad("TV", "Connection");
1055 if (!STRCASECMP(config, "S-Video"))
1057 logger->info(TAG, "Switching to S-Video as Connection={}", config);
1058 video->setConnection(Video::SVIDEO);
1059 } else if (!STRCASECMP(config, "HDMI"))
1061 logger->info(TAG, "Switching to HDMI as Connection={}", config);
1062 video->setConnection(Video::HDMI);
1063 } else if (!STRCASECMP(config, "HDMI3D"))
1065 logger->info(TAG, "Switching to HDMI3D as Connection={}", config);
1066 video->setConnection(Video::HDMI3D);
1070 logger->info(TAG, "Switching to RGB/Composite as Connection={}", config);
1071 video->setConnection(Video::COMPOSITERGB);
1077 logger->info(TAG, "Config TV/S-Video not found");
1080 // Set to shutdown VDR if config says
1082 config = vdr->configLoad("General", "VDR shutdown");
1085 if (!STRCASECMP(config, "On"))
1087 logger->info(TAG, "Shutdown VDR when shutting down vomp");
1088 vdr->setVDRShutdown(true);
1090 else if (!STRCASECMP(config, "Off"))
1092 logger->info(TAG, "Shutdown only vomp");
1093 vdr->setVDRShutdown(false);
1098 logger->info(TAG, "Default shutdown only vomp");
1099 vdr->setVDRShutdown(false); // Default
1102 // Get TV aspect ratio
1104 config = vdr->configLoad("TV", "Aspect");
1107 if (!STRCASECMP(config, "16:9"))
1109 logger->info(TAG, "/// Switching to TV aspect 16:9");
1110 video->setTVsize(Video::ASPECT16X9);
1114 logger->info(TAG, "/// Switching to TV aspect 4:3");
1115 video->setTVsize(Video::ASPECT4X3);
1121 logger->info(TAG, "Config TV/Aspect type not found, going 4:3");
1122 video->setTVsize(Video::ASPECT4X3);
1125 config = vdr->configLoad("TV", "Widemode");
1128 if (!STRCASECMP(config, "Letterbox"))
1130 logger->info(TAG, "Setting letterbox mode");
1131 video->setMode(Video::LETTERBOX);
1135 logger->info(TAG, "Setting chop-sides mode");
1136 video->setMode(Video::NORMAL);
1143 logger->info(TAG, "Config TV/Widemode not found, Setting letterbox mode");
1144 video->setMode(Video::LETTERBOX);
1146 logger->info(TAG, "Config TV/Widemode not found, Setting chop-sides mode");
1147 video->setMode(Video::NORMAL);
1151 config = vdr->configLoad("Advanced", "TCP receive window");
1154 size_t newTCPsize = atoi(config);
1157 logger->info(TAG, "Setting TCP window size %i", newTCPsize);
1158 vdr->setReceiveWindow(newTCPsize);
1162 logger->info(TAG, "TCP window size not found, setting 2048");
1163 if (DEFAULT_TCP_WINDOWSIZE) vdr->setReceiveWindow(2048); // Default
1166 config = vdr->configLoad("Advanced", "Font Name");
1169 Osd::getInstance()->setFont(config);
1170 logger->info(TAG, "Setting Font to %s", config);
1176 // Set recording list type
1178 #ifdef ADVANCED_MENUES
1179 config = vdr->configLoad("Advanced", "Menu type");
1183 if (!STRCASECMP(config, "Advanced"))
1185 logger->info(TAG, "Switching to Advanced menu");
1190 logger->info(TAG, "Switching to Classic menu");
1197 logger->info(TAG, "Config General/menu type not found");
1202 config = vdr->configLoad("Advanced", "Disable WOL");
1205 if (!STRCASECMP(config, "Yes"))
1207 logger->info(TAG, "Config says disable WOL");
1208 Wol::getInstance()->setEnabled(false);
1212 logger->info(TAG, "Config says enable WOL");
1213 Wol::getInstance()->setEnabled(true);
1220 logger->info(TAG, "By default, enable WOL");
1221 Wol::getInstance()->setEnabled(true);
1223 /* device dependend config */
1224 audio->loadOptionsFromServer(vdr);
1225 video->loadOptionsFromServer(vdr);
1226 inputMan->loadOptionsFromServer(vdr);
1228 video->executePendingModeChanges();
1231 // Save power state = on
1233 vdr->configSave("General", "Last Power State", "On");
1235 // Make sure connection didn't die
1236 if (!vdr->isConnected())
1238 Control::getInstance()->connectionLost();
1242 boxstack->remove(vi);
1244 VWelcome* vw = new VWelcome();
1247 // No boxstack->update yet
1249 Config* localConfig = Config::getInstance();
1250 int startToLiveTV{};
1251 localConfig->getInt("main", "start_to_live_tv", startToLiveTV);
1254 std::shared_ptr<ChannelList> chanList = VDR::getInstance()->getChannelsList(VDR::VIDEO);
1255 if (chanList && chanList->size())
1257 Channel* chan = NULL;
1258 for (u4 i = 0; i < chanList->size(); i++)
1260 if ((*chanList)[i]->number == static_cast<u4>(startToLiveTV))
1262 chan = (*chanList)[i];
1268 VVideoLiveTV* v = new VVideoLiveTV(chanList, chan->number, NULL);
1274 // Could not find channel, no VVideoLiveTV was made, update vw instead
1275 boxstack->update(vw);
1280 Control::getInstance()->connectionLost();
1283 else // Not starting to live TV
1285 boxstack->update(vw);
1288 // Enter pre-keys here
1289 // handleCommand(Input::OK);
1290 // handleCommand(Input::THREE);
1291 // handleCommand(Input::SIX);
1292 // handleCommand(Input::UP);
1293 // handleCommand(Input::OK);
1294 // handleCommand(Input::OK);
1295 // handleCommand(Input::PLAY);
1296 // handleCommand(Input::DOWN);
1297 // handleCommand(Input::DOWN);
1298 // handleCommand(Input::DOWN);
1299 // handleCommand(Input::RIGHT);
1300 // handleCommand(Input::RED);