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