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