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