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"
44 #include "vserverselect.h"
60 #include "sleeptimer.h"
62 #include "osdvector.h"
64 #include "vvideolivetv.h"
66 #include "imageloader.h"
69 #ifdef VOMP_PLATFORM_RASPBERRY
70 #include "ledraspberry.h"
71 #include "osdopenvg.h"
77 #include "windowsosd.h"
79 #include "osdwinpixel.h"
81 #include "osdwinvector.h"
91 static const char* TAG = "Control";
93 Control* Control::instance = NULL;
107 Control* Control::getInstance()
112 bool Control::init(bool tcrashed)
114 if (initted) return false;
116 logger = LogNT::getInstance();
118 #if TELEM_ENABLED == 1
122 SkinFactory::InitSkin(0);
124 // FIXME All constructors first which do very little & don't rely on presence of other objects.
125 // Then all inits. Inits retrieve pointers to other objects.
129 led = new Led_TYPE(); if (!led) throw 10;
130 if (!led->init(-1)) throw 11; // FIXME init(0) on Win32
132 timers = new Timers(); if (!timers) throw 20;
133 if (!timers->init()) throw 21;
135 video = new Video_TYPE(); if (!video) throw 30;
136 if (!video->init(Video::PAL)) throw 31;
138 audio = new Audio_TYPE(); if (!audio) throw 40;
139 if (!audio->init(Audio::MPEG2_PES)) throw 41;
141 imageLoader = new ImageLoader(); if (!imageLoader) throw 50;
142 if (!imageLoader->init()) throw 51;
144 osd = new Osd_TYPE(); if (!osd) throw 60;
145 if (!osd->init()) throw 61;
147 vdr = new VDR(); if (!vdr) throw 70;
148 if (!vdr->init()) throw 71;
150 boxstack = new BoxStack(); if (!boxstack) throw 80;
151 if (!boxstack->init()) throw 81;
153 sleepTimer = new SleepTimer(); if (!sleepTimer) throw 90;
155 wol = new Wol(); if (!wol) throw 100;
157 inputMan = new InputMan(); if (!inputMan) throw 110;
158 if (!inputMan->init()) throw 111;
163 if (e == 10) logger->crit(TAG, "LED module failed to create");
164 else if (e == 11) logger->crit(TAG, "LED module failed to initialise");
165 else if (e == 20) logger->crit(TAG, "Timers module failed to create");
166 else if (e == 21) logger->crit(TAG, "Timers module failed to initialise");
167 else if (e == 30) logger->crit(TAG, "Video module failed to create");
168 else if (e == 31) logger->crit(TAG, "Video module failed to initialise");
169 else if (e == 40) logger->crit(TAG, "Audio module failed to create");
170 else if (e == 41) logger->crit(TAG, "Audio module failed to initialise");
171 else if (e == 50) logger->crit(TAG, "ImageLoader module failed to create");
172 else if (e == 51) logger->crit(TAG, "ImageLoader module failed to initialise");
173 else if (e == 60) logger->crit(TAG, "OSD module failed to create");
174 else if (e == 61) logger->crit(TAG, "OSD module failed to initialise");
175 else if (e == 70) logger->crit(TAG, "VDR module failed to create");
176 else if (e == 71) logger->crit(TAG, "VDR module failed to initialise");
177 else if (e == 80) logger->crit(TAG, "BoxStack module failed to create");
178 else if (e == 81) logger->crit(TAG, "BoxStack module failed to initialise");
179 else if (e == 90) logger->crit(TAG, "SleepTimer module failed to create");
180 else if (e == 100) logger->crit(TAG, "WOL module failed to create");
181 else if (e == 110) logger->crit(TAG, "InputMan module failed to create");
182 else if (e == 111) logger->crit(TAG, "InputMan module failed to initialise");
199 boxstack->shutdown();
220 imageLoader->shutdown();
265 void Control::shutdown()
267 if (!initted) return;
272 inputMan->shutdown();
275 logger->info(TAG, "InputMan module shut down");
281 logger->info(TAG, "WOL module shut down");
288 logger->info(TAG, "SleepTimer module shut down");
293 boxstack->shutdown();
296 logger->info(TAG, "BoxStack module shut down");
304 logger->info(TAG, "VDR module shut down");
312 logger->info(TAG, "OSD module shut down");
317 imageLoader->shutdown();
320 logger->info(TAG, "ImageLoader shut down");
328 logger->info(TAG, "Audio module shut down");
336 logger->info(TAG, "Video module shut down");
344 logger->info(TAG, "Timers module shut down");
352 logger->info(TAG, "LED module shut down");
358 logger->info(TAG, "Request stop");
360 Message* m = new Message(); // break master loop
361 m->message = Message::SHUTDOWN;
362 m->p_to = Message::CONTROL;
366 void Control::doWallpaper()
369 Boxx* bbg = new Boxx();
370 bbg->setSize(video->getScreenWidth(), video->getScreenHeight());
372 bbg->fillColour(DrawStyle::WALLPAPER);
374 boxstack->update(bbg);
375 boxstack->remove(bbg);
378 wallpaper = new Boxx();
379 wallpaper->setSize(video->getScreenWidth(), video->getScreenHeight());
380 wallpaper->createBuffer();
381 wallpaper->setBackgroundColour(DrawStyle::WALLPAPER);
383 wallpaper_pict = new WJpegTYPE();
384 wallpaper_pict->setSize(video->getScreenWidth(), video->getScreenHeight());
386 if (video->getFormat() == Video::PAL)
388 logger->debug(TAG, "PAL wallpaper selected");
390 wallpaper_pict->init("/wallpaperPAL.jpg");
392 wallpaper_pict->init("wallpaperPAL.jpg");
397 logger->debug(TAG, "NTSC wallpaper selected");
398 wallpaper_pict->init("/wallpaperNTSC.jpg");
401 if (DrawStyle::WALLPAPER.alpha)
402 wallpaper_pict->setVisible(true);
404 wallpaper_pict->setVisible(false);
406 wallpaper->add(wallpaper_pict);
409 boxstack->add(wallpaper);
410 boxstack->update(wallpaper);
412 OsdVector* osdv = dynamic_cast<OsdVector*>(Osd::getInstance());
413 if (osdv) osdv->updateBackgroundColor(DrawStyle::WALLPAPER);
418 if (!initted) return;
421 Video::getInstance()->signalOn();
422 Led::getInstance()->on();
432 VConnect* vconnect = new VConnect(); // Deleted when VConnect messages Control, and is boxstack->remove()'d
433 boxstack->add(vconnect);
439 //logger->debug(TAG, "Setting log trace only mode");
440 //logger->setTraceOnlyMode(false);
442 messageLoopRun = true;
447 boxstack->removeAllExceptWallpaper();
448 boxstack->remove(wallpaper);
449 delete wallpaper_pict; wallpaper_pict = NULL; wallpaper = NULL;
452 void Control::dispatchMessage(Message* m)
454 logger->debug(TAG, "processing message {}", m->message);
456 if (m->p_to == Message::CONTROL)
460 case Message::SHUTDOWN:
462 messageLoopRun = false;
465 case Message::STOP_PLAYBACK:
467 handleCommand(Input::STOP); // an odd way of doing it, but so simple
470 case Message::VDR_CONNECTED:
472 doJustConnected(static_cast<VConnect*>(m->from));
475 case Message::SCREENSHOT:
477 logger->info(TAG, "Screenshot Message arrived");
478 Osd::getInstance()->screenShot("out.jpg");
481 case Message::CONNECTION_LOST:
486 case Message::INPUT_EVENT:
488 logger->info(TAG, "INPUT_EVENT {}", m->parameter);
490 handleCommand(m->parameter);
493 case Message::CHANGE_LANGUAGE:
495 boxstack->removeAllExceptWallpaper();
496 boxstack->update(wallpaper);
498 if (!VDR::getInstance()->isConnected()) { connectionLost(); break; }
499 VWelcome* vw = new VWelcome();
502 boxstack->update(vw);
505 case Message::LAST_VIEW_CLOSE:
507 // Shouldn't be done like this. Some generic message pass back from vinfo perhaps
514 // VWelcome* vw = new VWelcome();
516 // boxstack->add(vw);
517 // boxstack->update(vw);
523 else if (m->p_to == Message::BOXSTACK)
525 boxstack->processMessage(m);
527 else if (m->p_to == Message::MOUSE_RECEIVER)
529 logger->debug(TAG, "Sending mouse message to boxstack for dispatch");
530 boxstack->processMessage(m);
535 m->to->processMessage(m);
538 logger->debug(TAG, "done processing message {}", m->message);
541 void Control::handleCommand(int button)
543 if (isStandby && (button != Input::POWER)
544 && (button != Input::POWERON)
545 && (button != Input::POWEROFF)) return;
547 if (!connLost && boxstack->handleCommand(button)) return; // don't send to boxstack if connLost
549 // command was not handled
553 case Input::VOLUMEUP:
554 case Input::VOLUMEDOWN:
556 if (inputMan->handlesVolume()) // CEC volume handler?
558 if (button == Input::VOLUMEDOWN)
559 inputMan->volumeDown();
561 inputMan->volumeUp();
565 VVolume* v = new VVolume();
567 v->handleCommand(button); // this will draw+show
573 if (inputMan->handlesVolume())
575 inputMan->volumeMute();
579 VMute* v = new VMute();
596 case Input::POWEROFF:
604 if (!connLost) return; // if connLost, handle Input::OK
610 logger->debug(TAG, "Handling sleeptimer go");
621 Message* m = new Message(); // break into master mutex
622 m->message = Message::SCREENSHOT;
623 m->p_to = Message::CONTROL;
629 void Control::doStandby()
642 void Control::doPowerOn()
646 Video::getInstance()->signalOn();
647 Led::getInstance()->on();
648 InputMan::getInstance()->changePowerState(true);
651 VConnect* vconnect = new VConnect();
652 boxstack->add(vconnect);
657 void Control::doPowerOff()
661 VDR::getInstance()->shutdownVDR();
662 boxstack->removeAllExceptWallpaper();
663 Video::getInstance()->signalOff();
664 boxstack->update(wallpaper);
666 VDR::getInstance()->configSave("General", "Last Power State", "Off");
667 logger->unsetExternLogger();
668 VDR::getInstance()->disconnect();
669 Led::getInstance()->off();
670 InputMan::getInstance()->changePowerState(false);
672 sleepTimer->shutdown();
676 void Control::doFromTheTop(bool which)
678 if (isStandby) return;
683 logger->info(TAG, "Connection lost dialog already present");
687 logger->info(TAG, "Doing connection lost dialog");
688 connLost = new VInfo();
689 connLost->setSize(360, 200);
690 connLost->createBuffer();
691 if (Video::getInstance()->getFormat() == Video::PAL)
692 connLost->setPosition(190, 170);
694 connLost->setPosition(180, 120);
695 connLost->setOneLiner(tr("Connection lost"));
696 connLost->setDropThrough();
697 connLost->setBorderOn(1);
698 connLost->setTitleBarColour(DrawStyle::DANGER);
699 connLost->okButton();
701 boxstack->add(connLost);
702 boxstack->update(connLost);
704 clearMQInputEvents();
708 logger->unsetExternLogger();
709 VDR::getInstance()->disconnect();
710 boxstack->removeAllExceptWallpaper();
711 boxstack->update(wallpaper);
716 // at this point, everything should be reset to first-go
718 VConnect* vconnect = new VConnect(); // deleted eventually in boxstack
719 boxstack->add(vconnect);
724 void Control::clearMQInputEvents()
726 std::lock_guard<std::mutex> lg(messageQueueMutex); // Get the lock
728 MQueueI i = messages.begin();
729 while(i != messages.end())
732 if (m->message == Message::INPUT_EVENT)
735 i = messages.erase(i);
744 void Control::doReboot()
747 logger->unsetExternLogger();
748 VDR::getInstance()->disconnect();
750 logger->info(TAG, "Reboot");
752 #ifndef VOMP_HAS_EXIT
753 // some plattforms, want a proper deinitialisation of their hardware before reboot
754 Osd::getInstance()->shutdown();
755 Audio::getInstance()->shutdown();
756 Video::getInstance()->shutdown();
757 InputMan::getInstance()->shutdown();
759 reboot(LINUX_REBOOT_CMD_RESTART);
760 // if reboot is not allowed -> stop
772 #endif //Would we support this on windows?
775 void Control::connectionLost()
777 logger->unsetExternLogger();
778 Message* m = new Message(); // break into master mutex
779 m->message = Message::CONNECTION_LOST;
780 m->p_to = Message::CONTROL;
784 void Control::buildCrashedBox()
786 VInfo* crash = new VInfo();
787 crash->setSize(360, 250);
788 crash->createBuffer();
789 if (Video::getInstance()->getFormat() == Video::PAL)
790 crash->setPosition(190, 146);
792 crash->setPosition(180, 96);
793 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.");
794 crash->setBorderOn(1);
795 crash->setTitleBarColour(DrawStyle::DANGER);
797 crash->setExitable();
799 boxstack->add(crash);
800 boxstack->update(crash);
803 int Control::getLangPref(bool subtitle, const char* langcode)
805 std::vector<struct ASLPref>::iterator itty=langcodes.begin();
806 char templangcode[4];
807 templangcode[0] = langcode[0];
808 templangcode[1] = langcode[1];
809 templangcode[2] = langcode[2];
810 templangcode[3] = '\0';
812 while (itty != langcodes.end())
814 size_t pos = (*itty).langcode.find(templangcode);
815 if (pos != std::string::npos)
817 //vector<struct ASLPref>::iterator itty2=langcodes.begin();
818 for (unsigned int i = 0; i < langcodes.size(); i++)
822 pref = langcodes[i].subtitlepref;
824 pref = langcodes[i].audiopref;
829 if (langcodes[i].subtitlepref==langpos) return i;
833 if (langcodes[i].audiopref==langpos) return i;
841 return langcodes.size(); //neutral
844 void Control::doJustConnected(VConnect* vconnect)
847 if (!VDR::getInstance()->isConnected()) { connectionLost(); return; }
848 logger->info(TAG, "Entering doJustConnected");
850 boxstack->remove(vconnect);
852 VInfo* vi = new VInfo();
853 vi->setSize(400, 200);
855 if (video->getFormat() == Video::PAL)
856 vi->setPosition(170, 200);
858 vi->setPosition(160, 150);
859 vi->setOneLiner(tr("Connected, loading config"));
862 boxstack->update(vi);
864 // FIXME make config system
868 // See if we're supposed to do network logging
869 config = vdr->configLoad("Advanced", "Network logging");
870 if (config && !STRCASECMP(config, "On"))
872 logger->info(TAG, "Turning on network logging");
873 logger->setExternLogger(vdr);
877 logger->unsetExternLogger();
878 logger->info(TAG, "Turned off network logging");
880 if (config) delete[] config;
882 config = vdr->configLoad("Advanced", "Skin Name");
885 const char **skinnames=SkinFactory::getSkinNames();
886 for (int i=0;i<SkinFactory::getNumberofSkins();i++)
888 if (!STRCASECMP(config, skinnames[i]))
890 SkinFactory::InitSkin(i);
896 if (wallpaper && wallpaper_pict)
898 if (DrawStyle::WALLPAPER.alpha)
899 wallpaper_pict->setVisible(true);
901 wallpaper_pict->setVisible(false);
904 boxstack->update(wallpaper);
909 SkinFactory::InitSkin(0);
912 // See if config says to override video format (PAL/NTSC)
913 config = vdr->configLoad("General", "Override Video Format");
916 logger->debug(TAG, "Override Video Format is present");
918 if ( (!strcmp(config, "PAL") && (video->getFormat() != Video::PAL))
919 || (!strcmp(config, "NTSC") && (video->getFormat() != Video::NTSC))
920 || (!strcmp(config, "PAL_M") && (video->getFormat() != Video::PAL_M))
921 || (!strcmp(config, "NTSC_J") && (video->getFormat() != Video::NTSC_J))
924 // Oh sheesh, need to switch format. Bye bye TV...
926 // Take everything down
927 boxstack->removeAllExceptWallpaper();
928 boxstack->remove(wallpaper);
929 delete wallpaper_pict; wallpaper_pict = NULL; wallpaper = NULL;
936 // FIXME FIXME FIXME why do this?
937 inputMan->shutdown(); // need on raspberry shut not do any harm, hopefully
940 // Get video and osd back up with the new mode
941 if (!strcmp(config, "PAL"))
943 logger->debug(TAG, "Switching to PAL");
944 video->init(Video::PAL);
946 else if (!strcmp(config, "NTSC"))
948 logger->debug(TAG, "Switching to NTSC");
949 video->init(Video::NTSC);
950 } else if (!strcmp(config, "PAL_M"))
952 logger->debug(TAG, "Switching to PAL_M");
953 video->init(Video::PAL_M);
954 } else if (!strcmp(config, "NTSC_J"))
956 logger->debug(TAG, "Switching to NTSC_J");
957 video->init(Video::NTSC_J);
962 //we do not init twice
966 // Put the wallpaper back
971 vi->setSize(400, 200);
973 if (video->getFormat() == Video::PAL)
974 vi->setPosition(170, 200);
976 vi->setPosition(160, 150);
978 vi->setOneLiner(tr("Connected, loading config"));
981 boxstack->update(vi);
985 logger->debug(TAG, "Already in requested mode, or request was not 'PAL' or 'NTSC'");
990 logger->debug(TAG, "Phew, no dangerous on-the-fly mode switching to do!");
993 // Power off if first boot and config says so
998 logger->debug(TAG, "Load power after boot");
1000 config = vdr->configLoad("General", "Power After Boot");
1004 if (!STRCASECMP(config, "On"))
1006 logger->info(TAG, "Config says Power After Boot = On");
1008 else if (!STRCASECMP(config, "Off"))
1010 logger->info(TAG, "Config says Power After Boot = Off");
1013 return; // quit here
1015 else if (!STRCASECMP(config, "Last state"))
1017 char* lastPowerState = vdr->configLoad("General", "Last Power State");
1020 if (!STRCASECMP(lastPowerState, "On"))
1022 logger->info(TAG, "Config says Last Power State = On");
1024 else if (!STRCASECMP(lastPowerState, "Off"))
1026 logger->info(TAG, "Config says Last Power State = Off");
1029 return; // quit here
1033 logger->info(TAG, "Config General/Last Power State not understood");
1038 logger->info(TAG, "Config General/Last Power State not found");
1043 logger->info(TAG, "Config/Power After Boot not understood");
1049 logger->info(TAG, "Config General/Power After Boot not found");
1054 // Go S-Video if config says so
1056 config = vdr->configLoad("TV", "Connection");
1060 if (!STRCASECMP(config, "S-Video"))
1062 logger->info(TAG, "Switching to S-Video as Connection={}", config);
1063 video->setConnection(Video::SVIDEO);
1064 } else if (!STRCASECMP(config, "HDMI"))
1066 logger->info(TAG, "Switching to HDMI as Connection={}", config);
1067 video->setConnection(Video::HDMI);
1068 } else if (!STRCASECMP(config, "HDMI3D"))
1070 logger->info(TAG, "Switching to HDMI3D as Connection={}", config);
1071 video->setConnection(Video::HDMI3D);
1075 logger->info(TAG, "Switching to RGB/Composite as Connection={}", config);
1076 video->setConnection(Video::COMPOSITERGB);
1082 logger->info(TAG, "Config TV/S-Video not found");
1085 // Set to shutdown VDR if config says
1087 config = vdr->configLoad("General", "VDR shutdown");
1090 if (!STRCASECMP(config, "On"))
1092 logger->info(TAG, "Shutdown VDR when shutting down vomp");
1093 vdr->setVDRShutdown(true);
1095 else if (!STRCASECMP(config, "Off"))
1097 logger->info(TAG, "Shutdown only vomp");
1098 vdr->setVDRShutdown(false);
1103 logger->info(TAG, "Default shutdown only vomp");
1104 vdr->setVDRShutdown(false); // Default
1107 // Get TV aspect ratio
1109 config = vdr->configLoad("TV", "Aspect");
1112 if (!STRCASECMP(config, "16:9"))
1114 logger->info(TAG, "/// Switching to TV aspect 16:9");
1115 video->setTVsize(Video::ASPECT16X9);
1119 logger->info(TAG, "/// Switching to TV aspect 4:3");
1120 video->setTVsize(Video::ASPECT4X3);
1126 logger->info(TAG, "Config TV/Aspect type not found, going 4:3");
1127 video->setTVsize(Video::ASPECT4X3);
1130 config = vdr->configLoad("TV", "Widemode");
1133 if (!STRCASECMP(config, "Letterbox"))
1135 logger->info(TAG, "Setting letterbox mode");
1136 video->setMode(Video::LETTERBOX);
1140 logger->info(TAG, "Setting chop-sides mode");
1141 video->setMode(Video::NORMAL);
1148 logger->info(TAG, "Config TV/Widemode not found, Setting letterbox mode");
1149 video->setMode(Video::LETTERBOX);
1151 logger->info(TAG, "Config TV/Widemode not found, Setting chop-sides mode");
1152 video->setMode(Video::NORMAL);
1156 config = vdr->configLoad("Advanced", "TCP receive window");
1159 size_t newTCPsize = atoi(config);
1162 logger->info(TAG, "Setting TCP window size %i", newTCPsize);
1163 vdr->setReceiveWindow(newTCPsize);
1167 logger->info(TAG, "TCP window size not found, setting 2048");
1168 if (DEFAULT_TCP_WINDOWSIZE) vdr->setReceiveWindow(2048); // Default
1171 config = vdr->configLoad("Advanced", "Font Name");
1174 Osd::getInstance()->setFont(config);
1175 logger->info(TAG, "Setting Font to %s", config);
1181 // Set recording list type
1183 #ifdef ADVANCED_MENUES
1184 config = vdr->configLoad("Advanced", "Menu type");
1188 if (!STRCASECMP(config, "Advanced"))
1190 logger->info(TAG, "Switching to Advanced menu");
1195 logger->info(TAG, "Switching to Classic menu");
1202 logger->info(TAG, "Config General/menu type not found");
1207 config = vdr->configLoad("Advanced", "Disable WOL");
1210 if (!STRCASECMP(config, "Yes"))
1212 logger->info(TAG, "Config says disable WOL");
1213 Wol::getInstance()->setEnabled(false);
1217 logger->info(TAG, "Config says enable WOL");
1218 Wol::getInstance()->setEnabled(true);
1225 logger->info(TAG, "By default, enable WOL");
1226 Wol::getInstance()->setEnabled(true);
1228 /* device dependend config */
1229 audio->loadOptionsFromServer(vdr);
1230 video->loadOptionsFromServer(vdr);
1231 inputMan->loadOptionsFromServer(vdr);
1233 video->executePendingModeChanges();
1236 // Save power state = on
1238 vdr->configSave("General", "Last Power State", "On");
1240 // Make sure connection didn't die
1241 if (!vdr->isConnected())
1243 Control::getInstance()->connectionLost();
1247 boxstack->remove(vi);
1249 VWelcome* vw = new VWelcome();
1252 // No boxstack->update yet
1254 Config* localConfig = Config::getInstance();
1255 int startToLiveTV{};
1256 localConfig->getInt("main", "start_to_live_tv", startToLiveTV);
1259 std::shared_ptr<ChannelList> chanList = VDR::getInstance()->getChannelsList(VDR::VIDEO);
1260 if (chanList && chanList->size())
1262 Channel* chan = NULL;
1263 for (u4 i = 0; i < chanList->size(); i++)
1265 if ((*chanList)[i]->number == static_cast<u4>(startToLiveTV))
1267 chan = (*chanList)[i];
1273 VVideoLiveTV* v = new VVideoLiveTV(chanList, chan->number, NULL);
1279 // Could not find channel, no VVideoLiveTV was made, update vw instead
1280 boxstack->update(vw);
1285 Control::getInstance()->connectionLost();
1288 else // Not starting to live TV
1290 boxstack->update(vw);
1293 // Enter pre-keys here
1294 // handleCommand(Input::OK);
1295 // handleCommand(Input::THREE);
1296 // handleCommand(Input::SIX);
1297 // handleCommand(Input::UP);
1298 // handleCommand(Input::OK);
1299 // handleCommand(Input::OK);
1300 // handleCommand(Input::PLAY);
1301 // handleCommand(Input::DOWN);
1302 // handleCommand(Input::DOWN);
1303 // handleCommand(Input::DOWN);
1304 // handleCommand(Input::RIGHT);
1305 // handleCommand(Input::RED);