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();
261 void Control::shutdown()
263 if (!initted) return;
268 inputMan->shutdown();
271 logger->info(TAG, "InputMan module shut down");
277 logger->info(TAG, "WOL module shut down");
284 logger->info(TAG, "SleepTimer module shut down");
289 boxstack->shutdown();
292 logger->info(TAG, "BoxStack module shut down");
300 logger->info(TAG, "VDR module shut down");
308 logger->info(TAG, "OSD module shut down");
313 imageLoader->shutdown();
316 logger->info(TAG, "ImageLoader shut down");
324 logger->info(TAG, "Audio module shut down");
332 logger->info(TAG, "Video module shut down");
340 logger->info(TAG, "Timers module shut down");
348 logger->info(TAG, "LED module shut down");
354 logger->info(TAG, "Request stop");
356 Message* m = new Message(); // break master loop
357 m->message = Message::SHUTDOWN;
358 m->p_to = Message::CONTROL;
362 void Control::doWallpaper()
365 Boxx* bbg = new Boxx();
366 bbg->setSize(video->getScreenWidth(), video->getScreenHeight());
368 bbg->fillColour(DrawStyle::WALLPAPER);
370 boxstack->update(bbg);
371 boxstack->remove(bbg);
374 wallpaper = new Boxx();
375 wallpaper->setSize(video->getScreenWidth(), video->getScreenHeight());
376 wallpaper->createBuffer();
377 wallpaper->setBackgroundColour(DrawStyle::WALLPAPER);
379 wallpaper_pict = new WJpegTYPE();
380 wallpaper_pict->setSize(video->getScreenWidth(), video->getScreenHeight());
382 if (video->getFormat() == Video::PAL)
384 logger->debug(TAG, "PAL wallpaper selected");
386 wallpaper_pict->init("/wallpaperPAL.jpg");
388 wallpaper_pict->init("wallpaperPAL.jpg");
393 logger->debug(TAG, "NTSC wallpaper selected");
394 wallpaper_pict->init("/wallpaperNTSC.jpg");
397 if (DrawStyle::WALLPAPER.alpha)
398 wallpaper_pict->setVisible(true);
400 wallpaper_pict->setVisible(false);
402 wallpaper->add(wallpaper_pict);
405 boxstack->add(wallpaper);
406 boxstack->update(wallpaper);
408 OsdVector* osdv = dynamic_cast<OsdVector*>(Osd::getInstance());
409 if (osdv) osdv->updateBackgroundColor(DrawStyle::WALLPAPER);
414 if (!initted) return;
417 Video::getInstance()->signalOn();
418 Led::getInstance()->on();
428 VConnect* vconnect = new VConnect(); // Deleted when VConnect messages Control, and is boxstack->remove()'d
429 boxstack->add(vconnect);
435 //logger->debug(TAG, "Setting log trace only mode");
436 //logger->setTraceOnlyMode(false);
438 messageLoopRun = true;
443 boxstack->removeAllExceptWallpaper();
444 boxstack->remove(wallpaper);
445 delete wallpaper_pict; wallpaper_pict = NULL; wallpaper = NULL;
448 void Control::dispatchMessage(Message* m)
450 logger->debug(TAG, "processing message {}", m->message);
452 if (m->p_to == Message::CONTROL)
456 case Message::SHUTDOWN:
458 messageLoopRun = false;
461 case Message::STOP_PLAYBACK:
463 handleCommand(Input::STOP); // an odd way of doing it, but so simple
466 case Message::VDR_CONNECTED:
468 doJustConnected(static_cast<VConnect*>(m->from));
471 case Message::SCREENSHOT:
473 logger->info(TAG, "Screenshot Message arrived");
474 Osd::getInstance()->screenShot("out.jpg");
477 case Message::CONNECTION_LOST:
482 case Message::INPUT_EVENT:
484 logger->info(TAG, "INPUT_EVENT {}", m->parameter);
486 handleCommand(m->parameter);
489 case Message::CHANGE_LANGUAGE:
491 boxstack->removeAllExceptWallpaper();
492 boxstack->update(wallpaper);
494 if (!VDR::getInstance()->isConnected()) { connectionLost(); break; }
495 VWelcome* vw = new VWelcome();
498 boxstack->update(vw);
501 case Message::LAST_VIEW_CLOSE:
503 // Shouldn't be done like this. Some generic message pass back from vinfo perhaps
510 // VWelcome* vw = new VWelcome();
512 // boxstack->add(vw);
513 // boxstack->update(vw);
519 else if (m->p_to == Message::BOXSTACK)
521 boxstack->processMessage(m);
523 else if (m->p_to == Message::MOUSE_RECEIVER)
525 logger->debug(TAG, "Sending mouse message to boxstack for dispatch");
526 boxstack->processMessage(m);
531 m->to->processMessage(m);
534 logger->debug(TAG, "done processing message {}", m->message);
537 void Control::handleCommand(int button)
539 if (isStandby && (button != Input::POWER)
540 && (button != Input::POWERON)
541 && (button != Input::POWEROFF)) return;
543 if (!connLost && boxstack->handleCommand(button)) return; // don't send to boxstack if connLost
545 // command was not handled
549 case Input::VOLUMEUP:
550 case Input::VOLUMEDOWN:
552 if (inputMan->handlesVolume()) // CEC volume handler?
554 if (button == Input::VOLUMEDOWN)
555 inputMan->volumeDown();
557 inputMan->volumeUp();
561 VVolume* v = new VVolume();
563 v->handleCommand(button); // this will draw+show
569 if (inputMan->handlesVolume())
571 inputMan->volumeMute();
575 VMute* v = new VMute();
592 case Input::POWEROFF:
600 if (!connLost) return; // if connLost, handle Input::OK
606 logger->debug(TAG, "Handling sleeptimer go");
617 Message* m = new Message(); // break into master mutex
618 m->message = Message::SCREENSHOT;
619 m->p_to = Message::CONTROL;
625 void Control::doStandby()
638 void Control::doPowerOn()
642 Video::getInstance()->signalOn();
643 Led::getInstance()->on();
644 InputMan::getInstance()->changePowerState(true);
647 VConnect* vconnect = new VConnect();
648 boxstack->add(vconnect);
653 void Control::doPowerOff()
657 VDR::getInstance()->shutdownVDR();
658 boxstack->removeAllExceptWallpaper();
659 Video::getInstance()->signalOff();
660 boxstack->update(wallpaper);
662 VDR::getInstance()->configSave("General", "Last Power State", "Off");
663 logger->unsetExternLogger();
664 VDR::getInstance()->disconnect();
665 Led::getInstance()->off();
666 InputMan::getInstance()->changePowerState(false);
668 sleepTimer->shutdown();
672 void Control::doFromTheTop(bool which)
674 if (isStandby) return;
679 logger->info(TAG, "Connection lost dialog already present");
683 logger->info(TAG, "Doing connection lost dialog");
684 connLost = new VInfo();
685 connLost->setSize(360, 200);
686 connLost->createBuffer();
687 if (Video::getInstance()->getFormat() == Video::PAL)
688 connLost->setPosition(190, 170);
690 connLost->setPosition(180, 120);
691 connLost->setOneLiner(tr("Connection lost"));
692 connLost->setDropThrough();
693 connLost->setBorderOn(1);
694 connLost->setTitleBarColour(DrawStyle::DANGER);
695 connLost->okButton();
697 boxstack->add(connLost);
698 boxstack->update(connLost);
700 clearMQInputEvents();
704 logger->unsetExternLogger();
705 VDR::getInstance()->disconnect();
706 boxstack->removeAllExceptWallpaper();
707 boxstack->update(wallpaper);
712 // at this point, everything should be reset to first-go
714 VConnect* vconnect = new VConnect(); // deleted eventually in boxstack
715 boxstack->add(vconnect);
720 void Control::clearMQInputEvents()
722 std::lock_guard<std::mutex> lg(messageQueueMutex); // Get the lock
724 MQueueI i = messages.begin();
725 while(i != messages.end())
728 if (m->message == Message::INPUT_EVENT)
731 i = messages.erase(i);
740 void Control::doReboot()
743 logger->unsetExternLogger();
744 VDR::getInstance()->disconnect();
746 logger->info(TAG, "Reboot");
748 #ifndef VOMP_HAS_EXIT
749 // some plattforms, want a proper deinitialisation of their hardware before reboot
750 Osd::getInstance()->shutdown();
751 Audio::getInstance()->shutdown();
752 Video::getInstance()->shutdown();
753 InputMan::getInstance()->shutdown();
755 reboot(LINUX_REBOOT_CMD_RESTART);
756 // if reboot is not allowed -> stop
768 #endif //Would we support this on windows?
771 void Control::connectionLost()
773 logger->unsetExternLogger();
774 Message* m = new Message(); // break into master mutex
775 m->message = Message::CONNECTION_LOST;
776 m->p_to = Message::CONTROL;
780 void Control::buildCrashedBox()
782 VInfo* crash = new VInfo();
783 crash->setSize(360, 250);
784 crash->createBuffer();
785 if (Video::getInstance()->getFormat() == Video::PAL)
786 crash->setPosition(190, 146);
788 crash->setPosition(180, 96);
789 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.");
790 crash->setBorderOn(1);
791 crash->setTitleBarColour(DrawStyle::DANGER);
793 crash->setExitable();
795 boxstack->add(crash);
796 boxstack->update(crash);
799 int Control::getLangPref(bool subtitle, const char* langcode)
801 std::vector<struct ASLPref>::iterator itty=langcodes.begin();
802 char templangcode[4];
803 templangcode[0] = langcode[0];
804 templangcode[1] = langcode[1];
805 templangcode[2] = langcode[2];
806 templangcode[3] = '\0';
808 while (itty != langcodes.end())
810 size_t pos = (*itty).langcode.find(templangcode);
811 if (pos != std::string::npos)
813 //vector<struct ASLPref>::iterator itty2=langcodes.begin();
814 for (unsigned int i = 0; i < langcodes.size(); i++)
818 pref = langcodes[i].subtitlepref;
820 pref = langcodes[i].audiopref;
825 if (langcodes[i].subtitlepref==langpos) return i;
829 if (langcodes[i].audiopref==langpos) return i;
837 return langcodes.size(); //neutral
840 void Control::doJustConnected(VConnect* vconnect)
843 if (!VDR::getInstance()->isConnected()) { connectionLost(); return; }
844 logger->info(TAG, "Entering doJustConnected");
846 boxstack->remove(vconnect);
848 VInfo* vi = new VInfo();
849 vi->setSize(400, 200);
851 if (video->getFormat() == Video::PAL)
852 vi->setPosition(170, 200);
854 vi->setPosition(160, 150);
855 vi->setOneLiner(tr("Connected, loading config"));
858 boxstack->update(vi);
860 // FIXME make config system
864 // See if we're supposed to do network logging
865 config = vdr->configLoad("Advanced", "Network logging");
866 if (config && !STRCASECMP(config, "On"))
868 logger->info(TAG, "Turning on network logging");
869 logger->setExternLogger(vdr);
873 logger->unsetExternLogger();
874 logger->info(TAG, "Turned off network logging");
876 if (config) delete[] config;
878 config = vdr->configLoad("Advanced", "Skin Name");
881 const char **skinnames=SkinFactory::getSkinNames();
882 for (int i=0;i<SkinFactory::getNumberofSkins();i++)
884 if (!STRCASECMP(config, skinnames[i]))
886 SkinFactory::InitSkin(i);
892 if (wallpaper && wallpaper_pict)
894 if (DrawStyle::WALLPAPER.alpha)
895 wallpaper_pict->setVisible(true);
897 wallpaper_pict->setVisible(false);
900 boxstack->update(wallpaper);
905 SkinFactory::InitSkin(0);
908 // See if config says to override video format (PAL/NTSC)
909 config = vdr->configLoad("General", "Override Video Format");
912 logger->debug(TAG, "Override Video Format is present");
914 if ( (!strcmp(config, "PAL") && (video->getFormat() != Video::PAL))
915 || (!strcmp(config, "NTSC") && (video->getFormat() != Video::NTSC))
916 || (!strcmp(config, "PAL_M") && (video->getFormat() != Video::PAL_M))
917 || (!strcmp(config, "NTSC_J") && (video->getFormat() != Video::NTSC_J))
920 // Oh sheesh, need to switch format. Bye bye TV...
922 // Take everything down
923 boxstack->removeAllExceptWallpaper();
924 boxstack->remove(wallpaper);
925 delete wallpaper_pict; wallpaper_pict = NULL; wallpaper = NULL;
932 // FIXME FIXME FIXME why do this?
933 inputMan->shutdown(); // need on raspberry shut not do any harm, hopefully
936 // Get video and osd back up with the new mode
937 if (!strcmp(config, "PAL"))
939 logger->debug(TAG, "Switching to PAL");
940 video->init(Video::PAL);
942 else if (!strcmp(config, "NTSC"))
944 logger->debug(TAG, "Switching to NTSC");
945 video->init(Video::NTSC);
946 } else if (!strcmp(config, "PAL_M"))
948 logger->debug(TAG, "Switching to PAL_M");
949 video->init(Video::PAL_M);
950 } else if (!strcmp(config, "NTSC_J"))
952 logger->debug(TAG, "Switching to NTSC_J");
953 video->init(Video::NTSC_J);
958 //we do not init twice
962 // Put the wallpaper back
967 vi->setSize(400, 200);
969 if (video->getFormat() == Video::PAL)
970 vi->setPosition(170, 200);
972 vi->setPosition(160, 150);
974 vi->setOneLiner(tr("Connected, loading config"));
977 boxstack->update(vi);
981 logger->debug(TAG, "Already in requested mode, or request was not 'PAL' or 'NTSC'");
986 logger->debug(TAG, "Phew, no dangerous on-the-fly mode switching to do!");
989 // Power off if first boot and config says so
994 logger->debug(TAG, "Load power after boot");
996 config = vdr->configLoad("General", "Power After Boot");
1000 if (!STRCASECMP(config, "On"))
1002 logger->info(TAG, "Config says Power After Boot = On");
1004 else if (!STRCASECMP(config, "Off"))
1006 logger->info(TAG, "Config says Power After Boot = Off");
1009 return; // quit here
1011 else if (!STRCASECMP(config, "Last state"))
1013 char* lastPowerState = vdr->configLoad("General", "Last Power State");
1016 if (!STRCASECMP(lastPowerState, "On"))
1018 logger->info(TAG, "Config says Last Power State = On");
1020 else if (!STRCASECMP(lastPowerState, "Off"))
1022 logger->info(TAG, "Config says Last Power State = Off");
1025 return; // quit here
1029 logger->info(TAG, "Config General/Last Power State not understood");
1034 logger->info(TAG, "Config General/Last Power State not found");
1039 logger->info(TAG, "Config/Power After Boot not understood");
1045 logger->info(TAG, "Config General/Power After Boot not found");
1050 // Go S-Video if config says so
1052 config = vdr->configLoad("TV", "Connection");
1056 if (!STRCASECMP(config, "S-Video"))
1058 logger->info(TAG, "Switching to S-Video as Connection={}", config);
1059 video->setConnection(Video::SVIDEO);
1060 } else if (!STRCASECMP(config, "HDMI"))
1062 logger->info(TAG, "Switching to HDMI as Connection={}", config);
1063 video->setConnection(Video::HDMI);
1064 } else if (!STRCASECMP(config, "HDMI3D"))
1066 logger->info(TAG, "Switching to HDMI3D as Connection={}", config);
1067 video->setConnection(Video::HDMI3D);
1071 logger->info(TAG, "Switching to RGB/Composite as Connection={}", config);
1072 video->setConnection(Video::COMPOSITERGB);
1078 logger->info(TAG, "Config TV/S-Video not found");
1081 // Set to shutdown VDR if config says
1083 config = vdr->configLoad("General", "VDR shutdown");
1086 if (!STRCASECMP(config, "On"))
1088 logger->info(TAG, "Shutdown VDR when shutting down vomp");
1089 vdr->setVDRShutdown(true);
1091 else if (!STRCASECMP(config, "Off"))
1093 logger->info(TAG, "Shutdown only vomp");
1094 vdr->setVDRShutdown(false);
1099 logger->info(TAG, "Default shutdown only vomp");
1100 vdr->setVDRShutdown(false); // Default
1103 // Get TV aspect ratio
1105 config = vdr->configLoad("TV", "Aspect");
1108 if (!STRCASECMP(config, "16:9"))
1110 logger->info(TAG, "/// Switching to TV aspect 16:9");
1111 video->setTVsize(Video::ASPECT16X9);
1115 logger->info(TAG, "/// Switching to TV aspect 4:3");
1116 video->setTVsize(Video::ASPECT4X3);
1122 logger->info(TAG, "Config TV/Aspect type not found, going 4:3");
1123 video->setTVsize(Video::ASPECT4X3);
1126 config = vdr->configLoad("TV", "Widemode");
1129 if (!STRCASECMP(config, "Letterbox"))
1131 logger->info(TAG, "Setting letterbox mode");
1132 video->setMode(Video::LETTERBOX);
1136 logger->info(TAG, "Setting chop-sides mode");
1137 video->setMode(Video::NORMAL);
1144 logger->info(TAG, "Config TV/Widemode not found, Setting letterbox mode");
1145 video->setMode(Video::LETTERBOX);
1147 logger->info(TAG, "Config TV/Widemode not found, Setting chop-sides mode");
1148 video->setMode(Video::NORMAL);
1152 config = vdr->configLoad("Advanced", "TCP receive window");
1155 size_t newTCPsize = atoi(config);
1158 logger->info(TAG, "Setting TCP window size %i", newTCPsize);
1159 vdr->setReceiveWindow(newTCPsize);
1163 logger->info(TAG, "TCP window size not found, setting 2048");
1164 if (DEFAULT_TCP_WINDOWSIZE) vdr->setReceiveWindow(2048); // Default
1167 config = vdr->configLoad("Advanced", "Font Name");
1170 Osd::getInstance()->setFont(config);
1171 logger->info(TAG, "Setting Font to %s", config);
1177 // Set recording list type
1179 #ifdef ADVANCED_MENUES
1180 config = vdr->configLoad("Advanced", "Menu type");
1184 if (!STRCASECMP(config, "Advanced"))
1186 logger->info(TAG, "Switching to Advanced menu");
1191 logger->info(TAG, "Switching to Classic menu");
1198 logger->info(TAG, "Config General/menu type not found");
1203 config = vdr->configLoad("Advanced", "Disable WOL");
1206 if (!STRCASECMP(config, "Yes"))
1208 logger->info(TAG, "Config says disable WOL");
1209 Wol::getInstance()->setEnabled(false);
1213 logger->info(TAG, "Config says enable WOL");
1214 Wol::getInstance()->setEnabled(true);
1221 logger->info(TAG, "By default, enable WOL");
1222 Wol::getInstance()->setEnabled(true);
1224 /* device dependend config */
1225 audio->loadOptionsFromServer(vdr);
1226 video->loadOptionsFromServer(vdr);
1227 inputMan->loadOptionsFromServer(vdr);
1229 video->executePendingModeChanges();
1232 // Save power state = on
1234 vdr->configSave("General", "Last Power State", "On");
1236 // Make sure connection didn't die
1237 if (!vdr->isConnected())
1239 Control::getInstance()->connectionLost();
1243 boxstack->remove(vi);
1245 VWelcome* vw = new VWelcome();
1248 // No boxstack->update yet
1250 Config* localConfig = Config::getInstance();
1251 int startToLiveTV{};
1252 localConfig->getInt("main", "start_to_live_tv", startToLiveTV);
1255 std::shared_ptr<ChannelList> chanList = VDR::getInstance()->getChannelsList(VDR::VIDEO);
1256 if (chanList && chanList->size())
1258 Channel* chan = NULL;
1259 for (UINT i = 0; i < chanList->size(); i++)
1261 if ((*chanList)[i]->number == static_cast<ULONG>(startToLiveTV))
1263 chan = (*chanList)[i];
1269 VVideoLiveTV* v = new VVideoLiveTV(chanList, chan->number, NULL);
1275 // Could not find channel, no VVideoLiveTV was made, update vw instead
1276 boxstack->update(vw);
1281 Control::getInstance()->connectionLost();
1284 else // Not starting to live TV
1286 boxstack->update(vw);
1289 // Enter pre-keys here
1290 // handleCommand(Input::OK);
1291 // handleCommand(Input::THREE);
1292 // handleCommand(Input::SIX);
1293 // handleCommand(Input::UP);
1294 // handleCommand(Input::OK);
1295 // handleCommand(Input::OK);
1296 // handleCommand(Input::PLAY);
1297 // handleCommand(Input::DOWN);
1298 // handleCommand(Input::DOWN);
1299 // handleCommand(Input::DOWN);
1300 // handleCommand(Input::RIGHT);
1301 // handleCommand(Input::RED);