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