]> git.vomp.tv Git - vompclient.git/blob - command.cc
Rename TCP class to TCPOld
[vompclient.git] / command.cc
1 /*
2     Copyright 2004-2020 Chris Tallon
3
4     This file is part of VOMP.
5
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.
10
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.
15
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/>.
18 */
19
20 // FIXME rename to Control and move stuff from main to here
21
22
23 #include "command.h"
24
25 #ifdef WIN32
26 #include "inputwin.h"
27 #endif
28
29 #ifdef __ANDROID__
30 #include "inputandroid.h"
31 #endif
32
33 #include "led.h"
34 #include "video.h"
35 #include "audio.h"
36 #include "vdr.h"
37 #include "vvolume.h"
38 #include "vserverselect.h"
39 #include "vwelcome.h"
40 #include "vmute.h"
41 #include "colour.h"
42 #include "osd.h"
43 #include "i18n.h"
44 #include "timers.h"
45 #include "wol.h"
46 #include "vconnect.h"
47 #include "message.h"
48 #include "inputman.h"
49 #include "input.h"
50 #include "vinfo.h"
51 #include "boxx.h"
52 #include "boxstack.h"
53 #include "log.h"
54 #include "vsleeptimer.h"
55 #include "wjpeg.h"
56 #include "osdvector.h"
57
58
59 Command* Command::instance = NULL;
60
61 Command::Command()
62 {
63   if (instance) return;
64   instance = this;
65 }
66
67 Command::~Command()
68 {
69   flushMessageQueue();
70   instance = NULL;
71 }
72
73 Command* Command::getInstance()
74 {
75   return instance;
76 }
77
78 int Command::init(bool tcrashed)
79 {
80   if (initted) return 0;
81   initted = true;
82   crashed = tcrashed;
83
84   logger = Log::getInstance();
85   boxstack = BoxStack::getInstance();
86   inputMan = InputMan::getInstance();
87   
88   if (!logger || !boxstack || !inputMan)
89   {
90     initted = false;
91     return 0;
92   }
93
94   SkinFactory::InitSkin(0);
95
96   return 1;
97 }
98
99 int Command::shutdown()
100 {
101   if (!initted) return 0;
102   initted = false;
103   return 1;
104 }
105
106 void Command::stop()
107 {
108   logger->log("Command", Log::NOTICE, "Request stop");
109
110   Message* m = new Message(); // break master loop
111   m->message = Message::SHUTDOWN;
112   m->to = this;
113   postMessage(m);
114 }
115
116 void Command::doWallpaper()
117 {
118   Video* video = Video::getInstance();
119
120   // Blue background
121   Boxx* bbg = new Boxx();
122   bbg->setSize(video->getScreenWidth(), video->getScreenHeight());
123   bbg->createBuffer();
124   bbg->fillColour(DrawStyle::WALLPAPER);
125   boxstack->add(bbg);
126   boxstack->update(bbg);
127   boxstack->remove(bbg);
128
129   // Wallpaper
130   wallpaper = new Boxx();
131   wallpaper->setSize(video->getScreenWidth(), video->getScreenHeight());
132   wallpaper->createBuffer();
133   wallpaper->setBackgroundColour(DrawStyle::WALLPAPER);
134
135   wallpaper_pict = new WJpegTYPE();
136   wallpaper_pict->setSize(video->getScreenWidth(), video->getScreenHeight());
137
138   if (video->getFormat() == Video::PAL)
139   {
140     logger->log("Command", Log::DEBUG, "PAL wallpaper selected");
141 #ifndef _MIPS_ARCH    
142     wallpaper_pict->init("/wallpaperPAL.jpg");
143 #else
144     wallpaper_pict->init("wallpaperPAL.jpg");
145 #endif
146   }
147   else
148   {
149     logger->log("Command", Log::DEBUG, "NTSC wallpaper selected");
150     wallpaper_pict->init("/wallpaperNTSC.jpg");
151   }
152
153   if (DrawStyle::WALLPAPER.alpha)
154     wallpaper_pict->setVisible(true);
155   else
156     wallpaper_pict->setVisible(false);
157
158   wallpaper->add(wallpaper_pict);
159   wallpaper->draw();
160
161   boxstack->add(wallpaper);
162   boxstack->update(wallpaper);
163
164   OsdVector* osdv = dynamic_cast<OsdVector*>(Osd::getInstance());
165   if (osdv) osdv->updateBackgroundColor(DrawStyle::WALLPAPER);
166 }
167
168 void Command::run()
169 {
170   if (!initted) return;
171   irun = true;
172
173   // just in case
174   Video::getInstance()->signalOn();
175   Led::getInstance()->on();
176
177   doWallpaper();
178
179   if (crashed)
180   {
181     buildCrashedBox();
182   }
183   else
184   {
185     VConnect* vconnect = new VConnect();
186     boxstack->add(vconnect);
187     vconnect->run();
188   }
189
190
191   // FIXME Input::NA_SIGNAL is possibly obsolete now
192
193   std::unique_lock<std::mutex> lockWrapper(messageQueueMutex);  // locks. unlocks on out-of-scope
194
195   inputMan->start();
196
197   while(irun)
198   {
199     messageQueueCond.wait(lockWrapper, [&] { return !irun || !messages.empty(); });
200     logger->log("Command", Log::DEBUG, "woke");
201
202     if (!irun) break;
203
204     while(!messages.empty())
205     {
206       Message* m = messages.front();
207       messages.pop_front();
208
209       lockWrapper.unlock();
210
211       processMessage(m);
212       delete m;
213
214       lockWrapper.lock();
215     }
216   }
217
218   inputMan->stop();
219
220   boxstack->removeAllExceptWallpaper();
221   boxstack->remove(wallpaper);
222   delete wallpaper_pict; wallpaper_pict = NULL; wallpaper = NULL;
223 }
224
225 void Command::processMessage(Message* m)
226 {
227     // FIXME - a slight modification - how if messagereceivers were to register
228     // themselves as receivers to avoid the calling-a-deleted-object problem
229     // then only deliver/register/unregister would have to be protected
230
231   logger->log("Command", Log::DEBUG, "processing message %i", m->message);
232
233
234   if (m->to == this)
235   {
236     switch(m->message)
237     {
238       case Message::SHUTDOWN:
239       {
240         irun = false;
241         break;
242       }
243       // << FIXME OBSELETE
244       case Message::STOP_PLAYBACK:
245       {
246         handleCommand(Input::STOP); // an odd way of doing it, but so simple
247         break;
248       }
249       // Also connection_lost comes from player - anywhere else?
250       // FIXME OBSELETE >>
251
252
253       case Message::VDR_CONNECTED:
254       {
255         doJustConnected(static_cast<VConnect*>(m->from));
256         break;
257       }
258       case Message::SCREENSHOT:
259       {
260         logger->log("Osd", Log::NOTICE, "Screenshot Message arrived");
261         Osd::getInstance()->screenShot("out.jpg");
262         break;
263       }
264       case Message::CONNECTION_LOST:
265       {
266         doFromTheTop(true);
267         break;
268       }
269       case Message::INPUT_EVENT:
270       {
271         logger->log("Command", Log::NOTICE, "INPUT_EVENT %i", m->parameter);
272
273         handleCommand(m->parameter);
274         break;
275       }
276       case Message::CHANGE_LANGUAGE:
277       {
278         boxstack->removeAllExceptWallpaper();
279         boxstack->update(wallpaper);
280         I18n::initialize();
281         if (!VDR::getInstance()->isConnected()) { connectionLost(); break; }
282         VWelcome* vw = new VWelcome();
283         vw->draw();
284         boxstack->add(vw);
285         boxstack->update(vw);
286         break;
287       }
288       case Message::LAST_VIEW_CLOSE:
289       {
290         // Shouldn't be done like this. Some generic message pass back from vinfo perhaps
291         if (crashed)
292         {
293           crashed = false;
294           doFromTheTop(false);        
295         }
296       
297 //        VWelcome* vw = new VWelcome();
298 //        vw->draw();
299 //        boxstack->add(vw);
300 //        boxstack->update(vw);
301
302         break;
303       }
304       case Message::NEW_PICTURE:
305       {
306         //Log::getInstance()->log("Command", Log::DEBUG, "TVMedia NEW_PICTURE");
307         OsdVector* osdv = dynamic_cast<OsdVector*>(Osd::getInstance());
308         if (osdv) osdv->informPicture(m->tag, reinterpret_cast<ImageIndex>(m->data));
309         break;
310       }
311       case Message::NEW_PICTURE_STATIC:
312       {
313         //Log::getInstance()->log("Command", Log::DEBUG, "TVMedia NEW_PICTURE %x %x",m->tag,m->parameter);
314         OsdVector* osdv = dynamic_cast<OsdVector*>(Osd::getInstance());
315         if (osdv) osdv->informPicture(static_cast<unsigned long long>(m->tag) << 32LL, reinterpret_cast<ImageIndex>(m->data));
316         break;
317       }
318     }
319   }
320   else
321   {
322     /* FIXME
323     
324     Instead of sending through the boxstack, implement a more generic MessageReceiver interface
325     and have potential receivers register with something
326     When a message needs to be delivered, check if the receiver is still registered, if so, deliver the message
327     This could all be done using the existing big command mutex to keep it simple
328     */
329   
330     logger->log("Command", Log::DEBUG, "Sending message to boxstack");
331     boxstack->processMessage(m);
332   }
333 }
334
335 void Command::handleCommand(int button)
336 {
337   if (isStandby && (button != Input::POWER)
338                 && (button != Input::POWERON)
339                 && (button != Input::POWEROFF))  return;
340
341   if (!connLost && boxstack->handleCommand(button)) return; // don't send to boxstack if connLost
342
343   // command was not handled
344
345   switch(button)
346   {
347     case Input::VOLUMEUP:
348     case Input::VOLUMEDOWN:
349     {
350       if (inputMan->handlesVolume()) // CEC volume handler?
351       {
352         if (button == Input::VOLUMEDOWN)
353           inputMan->volumeDown();
354         else
355           inputMan->volumeUp();
356       }
357       else
358       {
359         VVolume* v = new VVolume();
360         boxstack->add(v);
361         v->handleCommand(button); // this will draw+show
362       }
363       return;
364     }
365     case Input::MUTE:
366     {
367       if (inputMan->handlesVolume())
368       {
369         inputMan->volumeMute();
370       }
371       else
372       {
373         VMute* v = new VMute();
374         v->draw();
375         boxstack->add(v);
376         boxstack->update(v);
377       }
378       return;
379     }
380     case Input::POWER:
381     {
382       doStandby();
383       return;
384     }
385     case Input::POWERON:
386     {
387       doPowerOn();
388       return;
389     }
390     case Input::POWEROFF:
391     {
392       doPowerOff();
393       return;
394     }
395     case Input::OK:
396     {
397       // FIXME
398       if (!connLost) return; // if connLost, handle Input::OK
399       doFromTheTop(false);
400       return;
401     }
402     case Input::GO:
403     {
404       VSleeptimer* sleep = new VSleeptimer();
405       boxstack->add(sleep);
406       sleep->handleCommand(button); // this will draw+show
407       return;
408     }
409   }
410 }
411
412 void Command::sig1()
413 {
414 #ifdef DEV
415   Message* m = new Message(); // break into master mutex
416   m->message = Message::SCREENSHOT;
417   m->to = this;
418   postMessage(m);
419 #endif
420 }
421
422 void Command::doStandby()
423 {
424   if (isStandby)
425   {
426     doPowerOn();
427   }
428   else
429   {
430     doPowerOff();
431   }
432 }
433
434
435 void Command::doPowerOn()
436 {
437   if (isStandby)
438   {
439     Video::getInstance()->signalOn();
440     Led::getInstance()->on();
441     InputMan::getInstance()->changePowerState(true);
442     isStandby = false;
443
444     VConnect* vconnect = new VConnect();
445     boxstack->add(vconnect);
446     vconnect->run();
447   }
448 }
449
450 void Command::doPowerOff()
451 {
452   if (!isStandby)
453   {
454     VDR::getInstance()->shutdownVDR();
455     boxstack->removeAllExceptWallpaper();
456     Video::getInstance()->signalOff();
457     boxstack->update(wallpaper);
458
459     VDR::getInstance()->configSave("General", "Last Power State", "Off");
460     logger->unsetExternLogger();
461     VDR::getInstance()->disconnect();
462     Led::getInstance()->off();
463     InputMan::getInstance()->changePowerState(false);
464     isStandby = true;
465     Sleeptimer::getInstance()->shutdown();
466   }
467 }
468
469 void Command::doFromTheTop(bool which)
470 {
471   if (isStandby) return;
472   if (which)
473   {
474     if (connLost)
475     {
476       logger->log("Command", Log::NOTICE, "Connection lost dialog already present");
477       return;
478     }
479   
480     logger->log("Command", Log::NOTICE, "Doing connection lost dialog");
481     connLost = new VInfo();
482     connLost->setSize(360, 200);
483     connLost->createBuffer();
484     if (Video::getInstance()->getFormat() == Video::PAL)
485       connLost->setPosition(190, 170);
486     else
487       connLost->setPosition(180, 120);
488     connLost->setOneLiner(tr("Connection lost"));
489     connLost->setDropThrough();
490     connLost->setBorderOn(1);
491     connLost->setTitleBarColour(DrawStyle::DANGER);
492     connLost->okButton();
493     connLost->draw();
494     boxstack->add(connLost);
495     boxstack->update(connLost);
496
497     clearMQInputEvents();
498   }
499   else
500   {
501     logger->unsetExternLogger();
502     VDR::getInstance()->disconnect();
503     boxstack->removeAllExceptWallpaper();
504     boxstack->update(wallpaper);
505     connLost = NULL;
506     
507     flushMessageQueue();
508     
509     // at this point, everything should be reset to first-go
510     
511     VConnect* vconnect = new VConnect();
512     boxstack->add(vconnect);
513     vconnect->run();
514   }
515 }
516
517 void Command::clearMQInputEvents()
518 {
519   std::lock_guard<std::mutex> lg(messageQueueMutex); // Get the lock
520
521   MQueueI i = messages.begin();
522   while(i != messages.end())
523   {
524     Message* m = *i;
525     if (m->message == Message::INPUT_EVENT)
526     {
527       delete m;
528       i = messages.erase(i);
529     }
530     else
531     {
532       ++i;
533     }
534   }
535 }
536
537 void Command::doReboot()
538 {
539
540   logger->unsetExternLogger();
541   VDR::getInstance()->disconnect();
542   // just kill it...
543   logger->log("Command", Log::NOTICE, "Reboot");
544 #ifndef WIN32
545 #ifndef VOMP_HAS_EXIT
546   // some plattforms, want a proper deinitialisation of their hardware before reboot
547   Osd::getInstance()->shutdown();
548   Audio::getInstance()->shutdown();
549   Video::getInstance()->shutdown();
550   InputMan::getInstance()->shutdown();
551
552   reboot(LINUX_REBOOT_CMD_RESTART);
553   // if  reboot is not allowed -> stop
554   stop();
555
556
557 #else
558   stop();
559
560 #ifdef __ANDROID__
561   exit(0);
562 #endif
563
564 #endif
565 #endif //Would we support this on windows?
566 }
567
568 void Command::connectionLost()
569 {
570   logger->unsetExternLogger();
571   Message* m = new Message(); // break into master mutex
572   m->message = Message::CONNECTION_LOST;
573   m->to = this;
574   postMessage(m);
575 }
576
577 void Command::buildCrashedBox()
578 {
579   VInfo* crash = new VInfo();
580   crash->setSize(360, 250);
581   crash->createBuffer();
582   if (Video::getInstance()->getFormat() == Video::PAL)
583     crash->setPosition(190, 146);
584   else
585     crash->setPosition(180, 96);
586   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.");
587   crash->setBorderOn(1);
588   crash->setTitleBarColour(DrawStyle::DANGER);
589   crash->okButton();
590   crash->setExitable();
591   crash->draw();
592   boxstack->add(crash);
593   boxstack->update(crash);
594 }
595
596 int Command::getLangPref(bool subtitle, const char* langcode)
597 {
598   std::vector<struct ASLPref>::iterator itty=langcodes.begin();
599   char templangcode[4];
600   templangcode[0] = langcode[0];
601   templangcode[1] = langcode[1];
602   templangcode[2] = langcode[2];
603   templangcode[3] = '\0';
604   int langpos = 0;
605   while (itty != langcodes.end())
606   {
607     size_t pos = (*itty).langcode.find(templangcode);
608     if (pos != std::string::npos)
609     {
610       //vector<struct ASLPref>::iterator itty2=langcodes.begin();
611       for (unsigned int i = 0; i < langcodes.size(); i++)
612       {
613         int pref = 0;
614         if (subtitle)
615           pref = langcodes[i].subtitlepref;
616         else
617           pref = langcodes[i].audiopref;
618         if (pref < 0) break;
619
620         if (subtitle)
621         {
622           if (langcodes[i].subtitlepref==langpos) return i;
623         }
624         else
625         {
626           if (langcodes[i].audiopref==langpos) return i;
627         }
628       }
629       break;
630     }
631     itty++;
632     langpos++;
633   }
634   return langcodes.size(); //neutral
635 }
636
637 void Command::doJustConnected(VConnect* vconnect)
638 {
639   I18n::initialize();
640   if (!VDR::getInstance()->isConnected()) { connectionLost(); return; }
641   logger->log("Command", Log::INFO, "Entering doJustConnected");
642   
643   Video* video = Video::getInstance();
644   Audio* audio = Audio::getInstance();  
645   boxstack->remove(vconnect);
646
647   VInfo* vi = new VInfo();
648   vi->setSize(400, 200);
649   vi->createBuffer();
650   if (video->getFormat() == Video::PAL)
651     vi->setPosition(170, 200);
652   else
653     vi->setPosition(160, 150);
654   vi->setOneLiner(tr("Connected, loading config"));
655   vi->draw();
656   boxstack->add(vi);
657   boxstack->update(vi);
658
659   // FIXME make config system
660
661   VDR* vdr = VDR::getInstance();
662   char* config;
663
664   // See if we're supposed to do network logging
665   config = vdr->configLoad("Advanced", "Network logging");
666   if (config && !STRCASECMP(config, "On"))
667   {
668     logger->log("Command", Log::INFO, "Turning on network logging");
669     logger->setExternLogger(vdr);
670   }  
671   else
672   {
673           logger->unsetExternLogger();
674     logger->log("Command", Log::INFO, "Turned off network logging");
675   }
676   if (config) delete[] config;
677
678   config = vdr->configLoad("Advanced", "Skin Name");
679   if (config)
680   {
681     const char **skinnames=SkinFactory::getSkinNames();
682     for (int i=0;i<SkinFactory::getNumberofSkins();i++)
683     {
684       if (!STRCASECMP(config, skinnames[i]))
685       {
686         SkinFactory::InitSkin(i);
687         break;
688       }
689     }
690     delete[] config;
691
692     if (wallpaper && wallpaper_pict)
693     {
694       if (DrawStyle::WALLPAPER.alpha)
695         wallpaper_pict->setVisible(true);
696       else
697         wallpaper_pict->setVisible(false);
698
699       wallpaper->draw();
700       boxstack->update(wallpaper);
701     }
702   }
703   else
704   {
705     SkinFactory::InitSkin(0);
706   }
707
708   // See if config says to override video format (PAL/NTSC)
709   config = vdr->configLoad("General", "Override Video Format");
710   if (config)
711   {
712     logger->log("Command", Log::DEBUG, "Override Video Format is present");
713
714     if (   (!strcmp(config, "PAL") && (video->getFormat() != Video::PAL))
715         || (!strcmp(config, "NTSC") && (video->getFormat() != Video::NTSC))
716         || (!strcmp(config, "PAL_M") && (video->getFormat() != Video::PAL_M))
717         || (!strcmp(config, "NTSC_J") && (video->getFormat() != Video::NTSC_J))
718         )
719     {
720       // Oh sheesh, need to switch format. Bye bye TV...
721
722       // Take everything down
723       boxstack->removeAllExceptWallpaper();
724       boxstack->remove(wallpaper);
725       delete wallpaper_pict; wallpaper_pict = NULL; wallpaper = NULL;
726
727       Osd* osd = Osd::getInstance();
728 #ifndef __ANDROID__
729       osd->shutdown();
730 #endif
731       video->shutdown();
732
733       inputMan->shutdown(); // need on raspberry shut not do any harm, hopefully
734       inputMan->init(); // FIXME this breaks badly now
735
736       // Get video and osd back up with the new mode
737       if (!strcmp(config, "PAL"))
738       {
739         logger->log("Command", Log::DEBUG, "Switching to PAL");
740         video->init(Video::PAL);
741       }
742       else if (!strcmp(config, "NTSC"))
743       {
744         logger->log("Command", Log::DEBUG, "Switching to NTSC");
745         video->init(Video::NTSC);
746       } else if (!strcmp(config, "PAL_M"))
747       {
748         logger->log("Command", Log::DEBUG, "Switching to PAL_M");
749         video->init(Video::PAL_M);
750       } else if (!strcmp(config, "NTSC_J"))
751       {
752         logger->log("Command", Log::DEBUG, "Switching to NTSC_J");
753         video->init(Video::NTSC_J);
754       }
755       delete[] config;
756
757 #ifndef __ANDROID__
758       //we do not init twice
759       osd->init();
760 #endif
761
762       // Put the wallpaper back
763       doWallpaper();
764
765       // Re add the vinfo
766       vi = new VInfo();
767       vi->setSize(400, 200);
768       vi->createBuffer();
769       if (video->getFormat() == Video::PAL)
770         vi->setPosition(170, 200);
771       else
772         vi->setPosition(160, 150);
773
774       vi->setOneLiner(tr("Connected, loading config"));
775       vi->draw();
776       boxstack->add(vi);
777       boxstack->update(vi);
778     }
779     else
780     {
781       logger->log("Command", Log::DEBUG, "Already in requested mode, or request was not 'PAL' or 'NTSC'");
782     }
783   }
784   else
785   {
786     logger->log("Command", Log::DEBUG, "Phew, no dangerous on-the-fly mode switching to do!");
787   }
788
789   // Power off if first boot and config says so
790   if (firstBoot)
791   {
792     firstBoot = false;
793
794     logger->log("Command", Log::DEBUG, "Load power after boot");
795
796     config = vdr->configLoad("General", "Power After Boot");
797
798     if (config)
799     {
800       if (!STRCASECMP(config, "On"))
801       {
802         logger->log("Command", Log::INFO, "Config says Power After Boot = On");
803       }
804       else if (!STRCASECMP(config, "Off"))
805       {
806         logger->log("Command", Log::INFO, "Config says Power After Boot = Off");
807         doStandby();
808         delete[] config;
809         return; // quit here
810       }
811       else if (!STRCASECMP(config, "Last state"))
812       {
813         char* lastPowerState = vdr->configLoad("General", "Last Power State");
814         if (lastPowerState)
815         {
816           if (!STRCASECMP(lastPowerState, "On"))
817           {
818             logger->log("Command", Log::INFO, "Config says Last Power State = On");
819           }
820           else if (!STRCASECMP(lastPowerState, "Off"))
821           {
822             logger->log("Command", Log::INFO, "Config says Last Power State = Off");
823             doStandby();
824             delete[] config;
825             return; // quit here
826           }
827           else
828           {
829             logger->log("Command", Log::INFO, "Config General/Last Power State not understood");
830           }
831         }
832         else
833         {
834           logger->log("Command", Log::INFO, "Config General/Last Power State not found");
835         }
836       }
837       else
838       {
839         logger->log("Command", Log::INFO, "Config/Power After Boot not understood");
840       }
841       delete[] config;
842     }
843     else
844     {
845       logger->log("Command", Log::INFO, "Config General/Power After Boot not found");
846     }
847   }
848
849
850   // Go S-Video if config says so
851
852   config = vdr->configLoad("TV", "Connection");
853
854   if (config)
855   {
856     if (!STRCASECMP(config, "S-Video"))
857     {
858       logger->log("Command", Log::INFO, "Switching to S-Video as Connection=%s", config);
859       video->setConnection(Video::SVIDEO);
860     } else  if (!STRCASECMP(config, "HDMI"))
861     {
862       logger->log("Command", Log::INFO, "Switching to HDMI as Connection=%s", config);
863       video->setConnection(Video::HDMI);
864     } else  if (!STRCASECMP(config, "HDMI3D"))
865     {
866       logger->log("Command", Log::INFO, "Switching to HDMI3D as Connection=%s", config);
867       video->setConnection(Video::HDMI3D);
868     }
869     else
870     {
871       logger->log("Command", Log::INFO, "Switching to RGB/Composite as Connection=%s", config);
872       video->setConnection(Video::COMPOSITERGB);
873     }
874     delete[] config;
875   }
876   else
877   {
878     logger->log("Command", Log::INFO, "Config TV/S-Video not found");
879   }
880
881   // Set to shutdown VDR if config says
882   
883   config = vdr->configLoad("General", "VDR shutdown");
884   if (config)
885   {
886     if (!STRCASECMP(config, "On"))
887     {
888       logger->log("Command", Log::INFO, "Shutdown VDR when shutting down vomp");
889       vdr->setVDRShutdown(true);
890     }
891     else if (!STRCASECMP(config, "Off"))
892     {
893       logger->log("Command", Log::INFO, "Shutdown only vomp");
894       vdr->setVDRShutdown(false);
895     }
896   }
897   else
898   {
899     logger->log("Command", Log::INFO, "Default shutdown only vomp");
900     vdr->setVDRShutdown(false); // Default
901   }
902           
903   // Get TV aspect ratio
904
905   config = vdr->configLoad("TV", "Aspect");
906   if (config)
907   {
908     if (!STRCASECMP(config, "16:9"))
909     {
910       logger->log("Command", Log::INFO, "/// Switching to TV aspect 16:9");
911       video->setTVsize(Video::ASPECT16X9);
912     }
913     else
914     {
915       logger->log("Command", Log::INFO, "/// Switching to TV aspect 4:3");
916       video->setTVsize(Video::ASPECT4X3);
917     }
918     delete[] config;
919   }
920   else
921   {
922     logger->log("Command", Log::INFO, "Config TV/Aspect type not found, going 4:3");
923     video->setTVsize(Video::ASPECT4X3);
924   }
925
926   config = vdr->configLoad("TV", "Widemode");
927   if (config)
928   {
929     if (!STRCASECMP(config, "Letterbox"))
930     {
931       logger->log("Command", Log::INFO, "Setting letterbox mode");
932       video->setMode(Video::LETTERBOX);
933     }
934     else
935     {
936       logger->log("Command", Log::INFO, "Setting chop-sides mode");
937       video->setMode(Video::NORMAL);
938     }
939     delete[] config;
940   }
941   else
942   {
943 #ifdef __ANDROID__
944          logger->log("Command", Log::INFO, "Config TV/Widemode not found, Setting letterbox mode");
945          video->setMode(Video::LETTERBOX);
946 #else
947     logger->log("Command", Log::INFO, "Config TV/Widemode not found, Setting chop-sides mode");
948     video->setMode(Video::NORMAL);
949 #endif
950   }
951
952   config = vdr->configLoad("Advanced", "TCP receive window");
953   if (config)
954   {
955     size_t newTCPsize = atoi(config);
956     delete[] config;
957
958     logger->log("Command", Log::INFO, "Setting TCP window size %i", newTCPsize);
959     vdr->setReceiveWindow(newTCPsize);
960   }
961   else
962   {
963     logger->log("Command", Log::INFO, "TCP window size not found, setting 2048");
964     if (DEFAULT_TCP_WINDOWSIZE) vdr->setReceiveWindow(2048); // Default
965   }
966
967   config = vdr->configLoad("Advanced", "Font Name");
968   if (config)
969   {
970         Osd::getInstance()->setFont(config);
971     logger->log("Command", Log::INFO, "Setting Font to %s", config);
972     delete[] config;
973
974   }
975
976
977   // Set recording list type
978
979 #ifdef ADVANCED_MENUES
980   config = vdr->configLoad("Advanced", "Menu type");
981
982   if (config)
983   {
984     if (!STRCASECMP(config, "Advanced"))
985     {
986       logger->log("Command", Log::INFO, "Switching to Advanced menu");
987       advMenus = true;
988     }
989     else
990     {
991       logger->log("Command", Log::INFO, "Switching to Classic menu");
992       advMenus = false;
993     }
994     delete[] config;
995   }
996   else
997   {
998     logger->log("Command", Log::INFO, "Config General/menu type not found");
999     advMenus = true;
1000   }
1001 #endif
1002
1003   config = vdr->configLoad("Advanced", "Disable WOL");
1004   if (config)
1005   {
1006     if (!STRCASECMP(config, "Yes"))
1007     {
1008       logger->log("Command", Log::INFO, "Config says disable WOL");
1009       Wol::getInstance()->setEnabled(false);
1010     }
1011     else
1012     {
1013       logger->log("Command", Log::INFO, "Config says enable WOL");
1014       Wol::getInstance()->setEnabled(true);
1015     }
1016
1017     delete[] config;
1018   }
1019   else
1020   {
1021     logger->log("Command", Log::INFO, "By default, enable WOL");
1022     Wol::getInstance()->setEnabled(true);
1023   }
1024   /* device dependend config */
1025   audio->loadOptionsFromServer(vdr);
1026   video->loadOptionsFromServer(vdr);
1027   inputMan->loadOptionsFromServer(vdr);
1028
1029   video->executePendingModeChanges();
1030   // config done
1031
1032   // Save power state = on
1033
1034   vdr->configSave("General", "Last Power State", "On");
1035
1036   // Make sure connection didn't die
1037   if (!vdr->isConnected())
1038   {
1039     Command::getInstance()->connectionLost();
1040   }
1041   else
1042   {
1043     boxstack->remove(vi);
1044
1045     VWelcome* vw = new VWelcome();
1046     vw->draw();
1047     boxstack->add(vw);
1048     boxstack->update(vw);
1049
1050     // Enter pre-keys here
1051 //    handleCommand(Input::OK);
1052 //    handleCommand(Input::THREE);
1053 //    handleCommand(Input::SIX);
1054 //    handleCommand(Input::OK);
1055 //    handleCommand(Input::UP);
1056 //    handleCommand(Input::PLAY);
1057 //    handleCommand(Input::DOWN);
1058 //    handleCommand(Input::DOWN);
1059 //    handleCommand(Input::DOWN);
1060 //    handleCommand(Input::RIGHT);
1061 //    handleCommand(Input::RED);
1062   }
1063 }