]> git.vomp.tv Git - vompclient.git/blob - command.cc
German updates
[vompclient.git] / command.cc
1 /*
2     Copyright 2004-2005 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, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #ifndef WIN32
22 #include <linux/errno.h>
23 #endif
24
25 #include "command.h"
26
27 #ifdef WIN32
28 #include "remotewin.h"
29 #endif
30
31 #include "led.h"
32 #include "video.h"
33 #include "audio.h"
34 #include "vdr.h"
35 #include "vvolume.h"
36 #include "vserverselect.h"
37 #include "vwelcome.h"
38 #include "vmute.h"
39 #include "colour.h"
40 #include "osd.h"
41 #include "i18n.h"
42 #include "timerreceiver.h"
43 #include "timers.h"
44 #include "wol.h"
45 #include "vvideolive.h"
46 #include "vconnect.h"
47 #include "message.h"
48 #include "remote.h"
49 #include "vinfo.h"
50 #include "boxx.h"
51 #include "boxstack.h"
52 #include "log.h"
53
54
55 Command* Command::instance = NULL;
56
57 Command::Command()
58 {
59   if (instance) return;
60   instance = this;
61   initted = 0;
62   isStandby = 0;
63   firstBoot = 1;
64   connLost = NULL;
65   crashed = false;
66 }
67
68 Command::~Command()
69 {
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 = 1;
82   crashed = tcrashed;
83
84   logger = Log::getInstance();
85   boxstack = BoxStack::getInstance();
86   remote = Remote::getInstance();
87   
88   remote->InitHWCListwithDefaults();
89   
90   if (!logger || !boxstack || !remote)
91   {
92     initted = 0;
93     return 0;
94   }
95 #ifndef WIN32
96   pthread_mutex_init(&masterLock, NULL);
97 #else
98   masterLock=CreateMutex(NULL,FALSE,NULL);
99 #endif
100
101   return 1;
102 }
103
104 int Command::shutdown()
105 {
106   if (!initted) return 0;
107   initted = 0;
108   return 1;
109 }
110
111 void Command::stop()
112 {
113 //  VDR::getInstance()->cancelFindingServer();
114   udp.shutdown();
115   irun = 0;
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(Colour::VIDEOBLUE);
127   boxstack->add(bbg);
128   boxstack->update(bbg);
129   boxstack->remove(bbg);
130
131   // Wallpaper
132   WJpeg* wallpaperj = new WJpeg();
133   wallpaperj->setSize(video->getScreenWidth(), video->getScreenHeight());
134   wallpaperj->createBuffer();
135
136   if (video->getFormat() == Video::PAL)
137   {
138     logger->log("Command", Log::DEBUG, "PAL wallpaper selected");
139     wallpaperj->init("/wallpaperPAL.jpg");
140   }
141   else
142   {
143     logger->log("Command", Log::DEBUG, "NTSC wallpaper selected");
144     wallpaperj->init("/wallpaperNTSC.jpg");
145   }
146   wallpaperj->draw();
147
148   boxstack->add(wallpaperj);
149   boxstack->update(wallpaperj);
150
151   wallpaper = wallpaperj;
152 }
153
154 void Command::run()
155 {
156   if (!initted) return;
157   irun = 1;
158 #ifndef WIN32
159   mainPid = getpid();
160 #endif
161
162   // just in case
163   Video::getInstance()->signalOn();
164   Led::getInstance()->on();
165
166   doWallpaper();
167
168   // End of startup. Lock the mutex and put the first view up
169 //  logger->log("Command", Log::DEBUG, "WANT LOCK");
170 #ifndef WIN32
171   pthread_mutex_lock(&masterLock);
172 #else
173   WaitForSingleObject(masterLock, INFINITE );
174 #endif
175   //logger->log("Command", Log::DEBUG, "LOCKED");
176
177   if (crashed)
178   {
179     buildCrashedBox();
180   }
181   else
182   {
183     VConnect* vconnect = new VConnect();
184     boxstack->add(vconnect);
185     vconnect->run();
186   }
187
188   // Start method 2 of getting commands in...
189   udp.run(this);
190
191   UCHAR button = 0;
192   while(irun)
193   {
194     // unlock and wait
195     //logger->log("Command", Log::DEBUG, "UNLOCK");
196 #ifndef WIN32
197     pthread_mutex_unlock(&masterLock);
198 #else
199     ReleaseMutex(masterLock);
200 #endif
201     button = remote->getButtonPress(2);  // FIXME why is this set to 2 and not 0? so it can quit
202     // something happened, lock and process
203
204     //  logger->log("Command", Log::DEBUG, "WANT LOCK");
205 #ifndef WIN32
206     pthread_mutex_lock(&masterLock);
207 #else
208     WaitForSingleObject(masterLock, INFINITE );
209 #endif
210     // logger->log("Command", Log::DEBUG, "LOCK");
211
212     if ((button == Remote::NA_NONE) /*|| (button == Remote::NA_UNKNOWN)*/) continue;
213
214     if (button != Remote::NA_SIGNAL) handleCommand(button);
215     processMessageQueue();
216   }
217
218   //logger->log("Command", Log::DEBUG, "UNLOCK");
219 #ifndef WIN32
220   pthread_mutex_unlock(&masterLock);
221 #else
222   ReleaseMutex(masterLock);
223 #endif
224 }
225
226 void Command::postMessage(Message* m)
227 {
228   // This is locked here in case the main loop is not waiting for an event, but is processing one
229   // it could be killed but then not react to it because the signal wouldn't cause
230   // remote->getButtonPress to break
231   // locking the mutex ensures that the master thread is waiting on getButtonPress
232
233
234   //logger->log("Command", Log::DEBUG, "WANT LOCK");
235 #ifndef WIN32
236   pthread_mutex_lock(&masterLock);
237 #else
238   WaitForSingleObject(masterLock, INFINITE );
239 #endif
240   //logger->log("Command", Log::DEBUG, "LOCK");
241   MessageQueue::postMessage(m);
242
243 #ifndef WIN32
244   kill(mainPid, SIGURG);
245   pthread_mutex_unlock(&masterLock);
246 #else
247   ((RemoteWin*)Remote::getInstance())->Signal();
248   ReleaseMutex(masterLock);
249 #endif
250   //logger->log("Command", Log::DEBUG, "UNLOCK");
251 }
252
253 void Command::postMessageNoLock(Message* m)
254 {
255   // As above but use this one if this message is being posted because of a button press
256   // the mutex is already locked, locking around postMessage is not needed as the
257   // queue is guaranteed to be run when the button has been processed
258   MessageQueue::postMessage(m);
259 }
260
261 bool Command::postMessageIfNotBusy(Message* m)
262 {
263   // Used for Windows mouse events
264
265   //logger->log("Command", Log::DEBUG, "TRY LOCK");
266 #ifndef WIN32
267   if (pthread_mutex_trylock(&masterLock) != EBUSY)
268   {
269     //logger->log("Command", Log::DEBUG, "LOCK");
270     MessageQueue::postMessage(m);
271     kill(mainPid, SIGURG);
272     pthread_mutex_unlock(&masterLock);
273     //logger->log("Command", Log::DEBUG, "UNLOCK");
274     return true;
275   }
276   else
277   {
278     return false;
279   }
280 #else
281   switch (WaitForSingleObject(masterLock, 0 ))
282   { //FIXME this is not "if not busy" check
283     case WAIT_OBJECT_0: //but with proper argument 0 this did not work
284     // case WAIT_ABANDONED:
285     MessageQueue::postMessage(m);
286     ((RemoteWin*)Remote::getInstance())->Signal();
287     ReleaseMutex(masterLock);
288     return true;
289
290     case WAIT_ABANDONED: return false;
291     case WAIT_TIMEOUT: return false;
292   }
293     return false;
294 #endif
295 }
296
297 void Command::postMessageFromOuterSpace(Message* m)
298 {
299   /*
300   Yet another way of getting messages into Command. This one is for events that
301   are not standard button presses (or UDP generated buttons). It is also not for
302   events that are generated as a result of other events (events that can safely
303   call postMessageNoLock and be guaranteed that the message will be processed
304   because it is known that the queue is currently being processed).
305   This is for events that come from outer space and can occur when the master
306   mutex is locked or not, they need to be queued and executed but it doesn't
307   matter when.
308   Actually so far it is for events caused by the video stream - aspect ratio
309   changes. These can occur when the master mutex is locked and so postMessage
310   doesn't work. postMessageNoLock doesn't work because if the mutex *isn't*
311   locked at the time then the message could be sat around a while before
312   being noticed.
313   The whole message system was at first supposed to prevent the problem of
314   calling a function on an object that had just been deleted, by ordering
315   messages such that all calls are done before object deletion. However,
316   because of the new centralised messaging system and the fact that BoxStack
317   locates the destination object before calling it, the messaging system now
318   allows the kind of sloppy calls it was supposed to stop. Weird huh. This
319   is mentioned here because the video stream might generate an event just as
320   the user hits stop. The mutex is locked, and by the time the message
321   is examined the vvideorec/live has been deleted. This doesn't matter because
322   boxstack will drop the message if it can't find the matching object to
323   deliver it to.
324   Finally, all this is fine and dandy, except that I'm not 100% sure that
325   this sloppy postMessage and hope a queued signal will force it to be processed
326   thingy will actually work. Hmmm.
327   Lastly <g>, I will consider making the naming system a little more sane
328   if this works.
329   */
330
331   logger->log("Command", Log::DEBUG, "PMFOS called");
332   MessageQueue::postMessage(m);
333
334 #ifndef WIN32
335   kill(mainPid, SIGURG);
336 #else
337   ((RemoteWin*)Remote::getInstance())->Signal();
338 #endif
339 }
340
341 void Command::processMessage(Message* m)
342 {
343     // FIXME - a slight modification - how if messagereceivers were to register
344     // themselves as receivers to avoid the calling-a-deleted-object problem
345     // then only deliver/register/unregister would have to be protected
346
347   logger->log("Command", Log::DEBUG, "processing message %i", m->message);
348
349
350   if (m->to == this)
351   {
352     switch(m->message)
353     {
354       case Message::STANDBY:
355       {
356         doStandby();
357         break;
358       }
359
360
361       // << FIXME OBSELETE
362       case Message::STOP_PLAYBACK:
363       {
364         handleCommand(Remote::STOP); // an odd way of doing it, but so simple
365         break;
366       }
367       case Message::STREAM_END:
368       {
369         VVideoLive::getInstance()->streamEnd();
370         break;
371       }
372
373       // Also connection_lost comes from player - anywhere else?
374       // FIXME OBSELETE >>
375
376
377       case Message::VDR_CONNECTED:
378       {
379         doJustConnected((VConnect*)m->from);
380         break;
381       }
382       case Message::SCREENSHOT:
383       {
384         Osd::getInstance()->screenShot("/out.jpg");
385         break;
386       }
387       case Message::CONNECTION_LOST:
388       {
389         doFromTheTop(true);
390         break;
391       }
392       case Message::UDP_BUTTON:
393       {
394         handleCommand(m->parameter);
395         break;
396       }
397       case Message::CHANGE_LANGUAGE:
398       {
399         boxstack->removeAll();
400         boxstack->update(wallpaper);
401         I18n::initialize();
402         VWelcome* vw = new VWelcome();
403         vw->draw();
404         boxstack->add(vw);
405         boxstack->update(vw);
406         break;
407       }
408       case Message::LAST_VIEW_CLOSE:
409       {
410         // Shouldn't be done like this. Some generic message pass back from vinfo perhaps
411         if (crashed)
412         {
413           crashed = false;
414           doFromTheTop(false);        
415         }
416       
417 //        VWelcome* vw = new VWelcome();
418 //        vw->draw();
419 //        boxstack->add(vw);
420 //        boxstack->update(vw);
421
422         break;
423       }
424     }
425   }
426   else
427   {
428     logger->log("Command", Log::DEBUG, "Sending message to boxstack");
429     boxstack->processMessage(m);
430   }
431 }
432
433 void Command::handleCommand(int button)
434 {
435   if (isStandby && (button != Remote::POWER)) return;
436   if (!connLost && boxstack->handleCommand(button)) return; // don't send to boxstack if connLost
437
438   // command was not handled
439
440   switch(button)
441   {
442     case Remote::DF_LEFT:
443     case Remote::DF_RIGHT:
444     case Remote::VOLUMEUP:
445     case Remote::VOLUMEDOWN:
446     {
447       VVolume* v = new VVolume();
448       boxstack->add(v);
449       v->handleCommand(button); // this will draw+show
450       return;
451     }
452     case Remote::MUTE:
453     {
454       VMute* v = new VMute();
455       v->draw();
456       boxstack->add(v);
457       boxstack->update(v);
458       return;
459     }
460     case Remote::POWER:
461     {
462       doStandby();
463       return;
464     }
465     case Remote::OK:
466     {
467       // FIXME
468       if (!connLost) return; // if connLost, handle Remote::OK
469       doFromTheTop(false);
470       return;
471     }
472   }
473 }
474
475 void Command::sig1()
476 {
477 #ifdef DEV
478   Message* m = new Message(); // break into master mutex
479   m->message = Message::SCREENSHOT;
480   m->to = this;
481   postMessage(m);
482 #endif
483 }
484
485 void Command::doStandby()
486 {
487   if (isStandby)
488   {
489     Video::getInstance()->signalOn();
490     Led::getInstance()->on();
491     isStandby = 0;
492
493
494     VConnect* vconnect = new VConnect();
495     boxstack->add(vconnect);
496     vconnect->run();
497   }
498   else
499   {
500     boxstack->removeAll();
501     Video::getInstance()->signalOff();
502     boxstack->update(wallpaper);
503
504     VDR::getInstance()->configSave("General", "Last Power State", "Off");
505     VDR::getInstance()->disconnect();
506     Led::getInstance()->off();
507     isStandby = 1;
508 #ifdef WIN32
509     stop(); //different behavoiur on windows, we exit
510 #endif
511   }
512 }
513
514 void Command::doFromTheTop(bool which)
515 {
516   if (which)
517   {
518     connLost = new VInfo();
519     connLost->setSize(360, 200);
520     connLost->createBuffer();
521     if (Video::getInstance()->getFormat() == Video::PAL)
522       connLost->setPosition(190, 170);
523     else
524       connLost->setPosition(180, 120);
525     connLost->setOneLiner(tr("Connection lost"));
526     connLost->setDropThrough();
527     connLost->setBorderOn(1);
528     connLost->setTitleBarColour(Colour::DANGER);
529     connLost->okButton();
530     connLost->draw();
531     boxstack->add(connLost);
532     boxstack->update(connLost);
533     remote->clearBuffer();
534   }
535   else
536   {
537     VDR::getInstance()->disconnect();
538     boxstack->removeAll();
539     boxstack->update(wallpaper);
540     connLost = NULL;
541     VConnect* vconnect = new VConnect();
542     boxstack->add(vconnect);
543     vconnect->run();
544   }
545 }
546
547 void Command::doReboot()
548 {
549   VDR::getInstance()->disconnect();
550   // just kill it...
551   logger->log("Command", Log::NOTICE, "Reboot");
552 #ifndef WIN32
553   reboot(LINUX_REBOOT_CMD_RESTART);
554 #endif //Would we support this on windows?
555 }
556
557 void Command::connectionLost()
558 {
559   Message* m = new Message(); // break into master mutex
560   m->message = Message::CONNECTION_LOST;
561   m->to = this;
562   postMessageNoLock(m);
563 }
564
565 void Command::buildCrashedBox()
566 {
567   VInfo* crash = new VInfo();
568   crash->setSize(360, 250);
569   crash->createBuffer();
570   if (Video::getInstance()->getFormat() == Video::PAL)
571     crash->setPosition(190, 146);
572   else
573     crash->setPosition(180, 96);
574   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.");
575   crash->setBorderOn(1);
576   crash->setTitleBarColour(Colour::DANGER);
577   crash->okButton();
578   crash->setExitable();
579   crash->draw();
580   boxstack->add(crash);
581   boxstack->update(crash);
582 }
583
584 void Command::doJustConnected(VConnect* vconnect)
585 {
586   I18n::initialize();
587   Video* video = Video::getInstance();
588   Audio* audio = Audio::getInstance();  
589   boxstack->remove(vconnect);
590
591   VInfo* vi = new VInfo();
592   vi->setSize(400, 200);
593   vi->createBuffer();
594   if (video->getFormat() == Video::PAL)
595     vi->setPosition(170, 200);
596   else
597     vi->setPosition(160, 150);
598   vi->setOneLiner(tr("Connected, loading config"));
599   vi->draw();
600   boxstack->add(vi);
601   boxstack->update(vi);
602
603   VDR* vdr = VDR::getInstance();
604   char* config;
605
606   // See if config says to override video format (PAL/NTSC)
607   config = vdr->configLoad("General", "Override Video Format");
608   if (config)
609   {
610     logger->log("Command", Log::DEBUG, "Override Video Format is present");
611
612     if (   (!strcmp(config, "PAL") && (video->getFormat() == Video::NTSC))
613         || (!strcmp(config, "NTSC") && (video->getFormat() == Video::PAL))  )
614     {
615       // Oh sheesh, need to switch format. Bye bye TV...
616
617       // Take everything down
618       boxstack->removeAll();
619       boxstack->remove(wallpaper);
620       Osd* osd = Osd::getInstance();
621       osd->shutdown();
622       video->shutdown();
623
624       // Get video and osd back up with the new mode
625       if (!strcmp(config, "PAL"))
626       {
627         logger->log("Command", Log::DEBUG, "Switching to PAL");
628         video->init(Video::PAL);
629       }
630       else if (!strcmp(config, "NTSC"))
631       {
632         logger->log("Command", Log::DEBUG, "Switching to NTSC");
633         video->init(Video::NTSC);
634       }
635       osd->init((char*)("/dev/stbgfx"));
636
637       // Put the wallpaper back
638       doWallpaper();
639
640       // Re add the vinfo
641       vi = new VInfo();
642       vi->setSize(400, 200);
643       vi->createBuffer();
644       if (video->getFormat() == Video::PAL)
645         vi->setPosition(170, 200);
646       else
647         vi->setPosition(160, 150);
648
649       vi->setOneLiner(tr("Connected, loading config"));
650       vi->draw();
651       boxstack->add(vi);
652       boxstack->update(vi);
653     }
654     else
655     {
656       logger->log("Command", Log::DEBUG, "Already in requested mode, or request was not 'PAL' or 'NTSC'");
657     }
658   }
659   else
660   {
661     logger->log("Command", Log::DEBUG, "Phew, no dangerous on-the-fly mode switching to do!");
662   }
663
664   // Power off if first boot and config says so
665   if (firstBoot)
666   {
667     firstBoot = 0;
668
669     logger->log("Command", Log::DEBUG, "Load power after boot");
670
671     config = vdr->configLoad("General", "Power After Boot");
672
673     if (config)
674     {
675       if (!STRCASECMP(config, "On"))
676       {
677         logger->log("Command", Log::INFO, "Config says Power After Boot = On");
678       }
679       else if (!STRCASECMP(config, "Off"))
680       {
681         logger->log("Command", Log::INFO, "Config says Power After Boot = Off");
682         doStandby();
683         delete[] config;
684         return; // quit here
685       }
686       else if (!STRCASECMP(config, "Last state"))
687       {
688         char* lastPowerState = vdr->configLoad("General", "Last Power State");
689         if (lastPowerState)
690         {
691           if (!STRCASECMP(lastPowerState, "On"))
692           {
693             logger->log("Command", Log::INFO, "Config says Last Power State = On");
694           }
695           else if (!STRCASECMP(lastPowerState, "Off"))
696           {
697             logger->log("Command", Log::INFO, "Config says Last Power State = Off");
698             doStandby();
699             delete[] config;
700             return; // quit here
701           }
702           else
703           {
704             logger->log("Command", Log::INFO, "Config General/Last Power State not understood");
705           }
706         }
707         else
708         {
709           logger->log("Command", Log::INFO, "Config General/Last Power State not found");
710         }
711       }
712       else
713       {
714         logger->log("Command", Log::INFO, "Config/Power After Boot not understood");
715       }
716       delete[] config;
717     }
718     else
719     {
720       logger->log("Command", Log::INFO, "Config General/Power After Boot not found");
721     }
722   }
723
724
725   // Go S-Video if config says so
726
727   config = vdr->configLoad("TV", "Connection");
728
729   if (config)
730   {
731     if (!STRCASECMP(config, "S-Video"))
732     {
733       logger->log("Command", Log::INFO, "Switching to S-Video as Connection=%s", config);
734       video->setConnection(Video::SVIDEO);
735     }
736     else
737     {
738       logger->log("Command", Log::INFO, "Switching to RGB/Composite as Connection=%s", config);
739       video->setConnection(Video::COMPOSITERGB);
740     }
741     delete[] config;
742   }
743   else
744   {
745     logger->log("Command", Log::INFO, "Config TV/S-Video not found");
746   }
747
748   // Set remote type
749
750   config = vdr->configLoad("General", "Remote type");
751
752   if (config)
753   {
754     if (!STRCASECMP(config, "New"))
755     {
756       logger->log("Command", Log::INFO, "Switching to New remote type");
757       remote->setRemoteType(Remote::NEWREMOTE);
758     }
759     else
760     {
761       logger->log("Command", Log::INFO, "Switching to Old remote type");
762       remote->setRemoteType(Remote::OLDREMOTE);
763     }
764     delete[] config;
765   }
766   else
767   {
768     logger->log("Command", Log::INFO, "Config General/Remote type not found");
769     remote->setRemoteType(Remote::OLDREMOTE);
770   }
771
772
773
774
775   // Get TV aspect ratio
776
777   config = vdr->configLoad("TV", "Aspect");
778   if (config)
779   {
780     if (!STRCASECMP(config, "16:9"))
781     {
782       logger->log("Command", Log::INFO, "/// Switching to TV aspect 16:9");
783       video->setTVsize(Video::ASPECT16X9);
784     }
785     else
786     {
787       logger->log("Command", Log::INFO, "/// Switching to TV aspect 4:3");
788       video->setTVsize(Video::ASPECT4X3);
789     }
790     delete[] config;
791   }
792   else
793   {
794     logger->log("Command", Log::INFO, "Config TV/Aspect type not found, going 4:3");
795     video->setTVsize(Video::ASPECT4X3);
796   }
797
798   config = vdr->configLoad("TV", "Widemode");
799   if (config)
800   {
801     if (!STRCASECMP(config, "Letterbox"))
802     {
803       logger->log("Command", Log::INFO, "Setting letterbox mode");
804       video->setMode(Video::LETTERBOX);
805     }
806     else
807     {
808       logger->log("Command", Log::INFO, "Setting chop-sides mode");
809       video->setMode(Video::NORMAL);
810     }
811     delete[] config;
812   }
813   else
814   {
815     logger->log("Command", Log::INFO, "Config TV/Widemode not found, Setting chop-sides mode");
816     video->setMode(Video::NORMAL);
817   }
818
819   config = vdr->configLoad("Advanced", "TCP receive window");
820   if (config)
821   {
822     size_t newTCPsize = atoi(config);
823     delete[] config;
824
825     logger->log("Command", Log::INFO, "Setting TCP window size %i", newTCPsize);
826     vdr->setReceiveWindow(newTCPsize);
827   }
828   else
829   {
830     logger->log("Command", Log::INFO, "TCP window size not found, setting 2048");
831     vdr->setReceiveWindow(2048); // Default
832   }
833
834   config = vdr->configLoad("Advanced", "Disable WOL");
835   if (config)
836   {
837     if (!STRCASECMP(config, "Yes"))
838     {
839       logger->log("Command", Log::INFO, "Config says disable WOL");
840       Wol::getInstance()->setEnabled(false);
841     }
842     else
843     {
844       logger->log("Command", Log::INFO, "Config says enable WOL");
845       Wol::getInstance()->setEnabled(true);
846     }
847
848     delete[] config;
849   }
850   else
851   {
852     logger->log("Command", Log::INFO, "By default, enable WOL");
853     Wol::getInstance()->setEnabled(true);
854   }
855   /* device dependend config */
856   audio->loadOptionsfromServer(vdr);
857   video->loadOptionsfromServer(vdr);
858   remote->loadOptionsfromServer(vdr);
859   // config done
860
861   // Save power state = on
862
863   vdr->configSave("General", "Last Power State", "On");
864
865   // Make sure connection didn't die
866   if (!vdr->isConnected())
867   {
868     Command::getInstance()->connectionLost();
869   }
870   else
871   {
872     boxstack->remove(vi);
873
874     VWelcome* vw = new VWelcome();
875     vw->draw();
876     boxstack->add(vw);
877     boxstack->update(vw);
878
879     // Enter pre-keys here
880 //    handleCommand(Remote::SIX);
881 //    handleCommand(Remote::UP);
882 //    handleCommand(Remote::PLAY);
883 //    handleCommand(Remote::DOWN);
884 //    handleCommand(Remote::DOWN);
885 //    handleCommand(Remote::DOWN);
886 //    handleCommand(Remote::OK);
887 //    handleCommand(Remote::OK);
888 //    handleCommand(Remote::RED);
889   }
890 }