]> git.vomp.tv Git - vompclient-marten.git/blob - command.cc
Network logging
[vompclient-marten.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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 "vconnect.h"
46 #include "message.h"
47 #include "remote.h"
48 #include "vinfo.h"
49 #include "boxx.h"
50 #include "boxstack.h"
51 #include "log.h"
52 #include "vsleeptimer.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       // << FIXME OBSELETE
357       case Message::STOP_PLAYBACK:
358       {
359         handleCommand(Remote::STOP); // an odd way of doing it, but so simple
360         break;
361       }
362       // Also connection_lost comes from player - anywhere else?
363       // FIXME OBSELETE >>
364
365
366       case Message::VDR_CONNECTED:
367       {
368         doJustConnected((VConnect*)m->from);
369         break;
370       }
371       case Message::SCREENSHOT:
372       {
373         Osd::getInstance()->screenShot("/out.jpg");
374         break;
375       }
376       case Message::CONNECTION_LOST:
377       {
378         doFromTheTop(true);
379         break;
380       }
381       case Message::UDP_BUTTON:
382       {
383         handleCommand(m->parameter);
384         break;
385       }
386       case Message::CHANGE_LANGUAGE:
387       {
388         boxstack->removeAll();
389         boxstack->update(wallpaper);
390         I18n::initialize();
391         if (!VDR::getInstance()->isConnected()) { connectionLost(); break; }
392         VWelcome* vw = new VWelcome();
393         vw->draw();
394         boxstack->add(vw);
395         boxstack->update(vw);
396         break;
397       }
398       case Message::LAST_VIEW_CLOSE:
399       {
400         // Shouldn't be done like this. Some generic message pass back from vinfo perhaps
401         if (crashed)
402         {
403           crashed = false;
404           doFromTheTop(false);        
405         }
406       
407 //        VWelcome* vw = new VWelcome();
408 //        vw->draw();
409 //        boxstack->add(vw);
410 //        boxstack->update(vw);
411
412         break;
413       }
414     }
415   }
416   else
417   {
418     /* FIXME
419     
420     Instead of sending through the boxstack, implement a more generic MessageReceiver interface
421     and have potential receivers register with something
422     When a message needs to be delivered, check if the receiver is still registered, if so, deliver the message
423     This could all be done using the existing big command mutex to keep it simple
424     */
425   
426     logger->log("Command", Log::DEBUG, "Sending message to boxstack");
427     boxstack->processMessage(m);
428   }
429 }
430
431 void Command::handleCommand(int button)
432 {
433   if (isStandby && (button != Remote::POWER)) return;
434   if (!connLost && boxstack->handleCommand(button)) return; // don't send to boxstack if connLost
435
436   // command was not handled
437
438   switch(button)
439   {
440     case Remote::DF_LEFT:
441     case Remote::DF_RIGHT:
442     case Remote::VOLUMEUP:
443     case Remote::VOLUMEDOWN:
444     {
445       VVolume* v = new VVolume();
446       boxstack->add(v);
447       v->handleCommand(button); // this will draw+show
448       return;
449     }
450     case Remote::MUTE:
451     {
452       VMute* v = new VMute();
453       v->draw();
454       boxstack->add(v);
455       boxstack->update(v);
456       return;
457     }
458     case Remote::POWER:
459     {
460       doStandby();
461       return;
462     }
463     case Remote::OK:
464     {
465       // FIXME
466       if (!connLost) return; // if connLost, handle Remote::OK
467       doFromTheTop(false);
468       return;
469     }
470     case Remote::GO:
471     {
472       VSleeptimer* sleep = new VSleeptimer();
473       boxstack->add(sleep);
474       sleep->handleCommand(button); // this will draw+show
475       return;
476     }
477   }
478 }
479
480 void Command::sig1()
481 {
482 #ifdef DEV
483   Message* m = new Message(); // break into master mutex
484   m->message = Message::SCREENSHOT;
485   m->to = this;
486   postMessage(m);
487 #endif
488 }
489
490 void Command::doStandby()
491 {
492   if (isStandby)
493   {
494     Video::getInstance()->signalOn();
495     Led::getInstance()->on();
496     isStandby = 0;
497
498
499     VConnect* vconnect = new VConnect(server);
500     boxstack->add(vconnect);
501     vconnect->run();
502   }
503   else
504   {
505     boxstack->removeAll();
506     Video::getInstance()->signalOff();
507     boxstack->update(wallpaper);
508
509     VDR::getInstance()->configSave("General", "Last Power State", "Off");
510     logger->netLogOff();
511     VDR::getInstance()->disconnect();
512     Led::getInstance()->off();
513     isStandby = 1;
514     Sleeptimer::getInstance()->shutdown();
515 #ifdef WIN32
516     stop(); //different behavoiur on windows, we exit
517 #endif
518   }
519 }
520
521 void Command::doFromTheTop(bool which)
522 {
523   if (which)
524   {
525     if (connLost)
526     {
527       logger->log("Command", Log::NOTICE, "Connection lost dialog already present");
528       return;
529     }
530   
531     logger->log("Command", Log::NOTICE, "Doing connection lost dialog");
532     connLost = new VInfo();
533     connLost->setSize(360, 200);
534     connLost->createBuffer();
535     if (Video::getInstance()->getFormat() == Video::PAL)
536       connLost->setPosition(190, 170);
537     else
538       connLost->setPosition(180, 120);
539     connLost->setOneLiner(tr("Connection lost"));
540     connLost->setDropThrough();
541     connLost->setBorderOn(1);
542     connLost->setTitleBarColour(Colour::DANGER);
543     connLost->okButton();
544     connLost->draw();
545     boxstack->add(connLost);
546     boxstack->update(connLost);
547     remote->clearBuffer();
548   }
549   else
550   {
551     logger->netLogOff();
552     VDR::getInstance()->disconnect();
553     boxstack->removeAll();
554     boxstack->update(wallpaper);
555     connLost = NULL;
556     
557     flushMessageQueue();
558     remote->clearBuffer();
559     
560     // at this point, everything should be reset to first-go
561     
562     VConnect* vconnect = new VConnect(server);
563     boxstack->add(vconnect);
564     vconnect->run();
565   }
566 }
567
568 void Command::doReboot()
569 {
570   logger->netLogOff();
571   VDR::getInstance()->disconnect();
572   // just kill it...
573   logger->log("Command", Log::NOTICE, "Reboot");
574 #ifndef WIN32
575   reboot(LINUX_REBOOT_CMD_RESTART);
576 #endif //Would we support this on windows?
577 }
578
579 void Command::connectionLost()
580 {
581   logger->netLogOff();
582   Message* m = new Message(); // break into master mutex
583   m->message = Message::CONNECTION_LOST;
584   m->to = this;
585   postMessageFromOuterSpace(m);
586 }
587
588 void Command::buildCrashedBox()
589 {
590   VInfo* crash = new VInfo();
591   crash->setSize(360, 250);
592   crash->createBuffer();
593   if (Video::getInstance()->getFormat() == Video::PAL)
594     crash->setPosition(190, 146);
595   else
596     crash->setPosition(180, 96);
597   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.");
598   crash->setBorderOn(1);
599   crash->setTitleBarColour(Colour::DANGER);
600   crash->okButton();
601   crash->setExitable();
602   crash->draw();
603   boxstack->add(crash);
604   boxstack->update(crash);
605 }
606
607 void Command::doJustConnected(VConnect* vconnect)
608 {
609   I18n::initialize();
610   if (!VDR::getInstance()->isConnected()) { connectionLost(); return; }
611   
612   Video* video = Video::getInstance();
613   Audio* audio = Audio::getInstance();  
614   boxstack->remove(vconnect);
615
616   VInfo* vi = new VInfo();
617   vi->setSize(400, 200);
618   vi->createBuffer();
619   if (video->getFormat() == Video::PAL)
620     vi->setPosition(170, 200);
621   else
622     vi->setPosition(160, 150);
623   vi->setOneLiner(tr("Connected, loading config"));
624   vi->draw();
625   boxstack->add(vi);
626   boxstack->update(vi);
627
628   VDR* vdr = VDR::getInstance();
629   char* config;
630
631   // See if we're supposed to do network logging
632   config = vdr->configLoad("Advanced", "Network logging");
633   if (config && !STRCASECMP(config, "On"))
634   {
635     logger->log("Command", Log::INFO, "Turning on network logging");
636     logger->netLogOn();
637   }  
638   else
639   {
640     logger->netLogOn();
641     logger->log("Command", Log::INFO, "Turned off network logging");
642   }
643   if (config) delete[] config;
644
645   // See if config says to override video format (PAL/NTSC)
646   config = vdr->configLoad("General", "Override Video Format");
647   if (config)
648   {
649     logger->log("Command", Log::DEBUG, "Override Video Format is present");
650
651     if (   (!strcmp(config, "PAL") && (video->getFormat() == Video::NTSC))
652         || (!strcmp(config, "NTSC") && (video->getFormat() == Video::PAL))  )
653     {
654       // Oh sheesh, need to switch format. Bye bye TV...
655
656       // Take everything down
657       boxstack->removeAll();
658       boxstack->remove(wallpaper);
659       Osd* osd = Osd::getInstance();
660       osd->shutdown();
661       video->shutdown();
662
663       // Get video and osd back up with the new mode
664       if (!strcmp(config, "PAL"))
665       {
666         logger->log("Command", Log::DEBUG, "Switching to PAL");
667         video->init(Video::PAL);
668       }
669       else if (!strcmp(config, "NTSC"))
670       {
671         logger->log("Command", Log::DEBUG, "Switching to NTSC");
672         video->init(Video::NTSC);
673       }
674       osd->init((char*)("/dev/stbgfx"));
675
676       // Put the wallpaper back
677       doWallpaper();
678
679       // Re add the vinfo
680       vi = new VInfo();
681       vi->setSize(400, 200);
682       vi->createBuffer();
683       if (video->getFormat() == Video::PAL)
684         vi->setPosition(170, 200);
685       else
686         vi->setPosition(160, 150);
687
688       vi->setOneLiner(tr("Connected, loading config"));
689       vi->draw();
690       boxstack->add(vi);
691       boxstack->update(vi);
692     }
693     else
694     {
695       logger->log("Command", Log::DEBUG, "Already in requested mode, or request was not 'PAL' or 'NTSC'");
696     }
697   }
698   else
699   {
700     logger->log("Command", Log::DEBUG, "Phew, no dangerous on-the-fly mode switching to do!");
701   }
702
703   // Power off if first boot and config says so
704   if (firstBoot)
705   {
706     firstBoot = 0;
707
708     logger->log("Command", Log::DEBUG, "Load power after boot");
709
710     config = vdr->configLoad("General", "Power After Boot");
711
712     if (config)
713     {
714       if (!STRCASECMP(config, "On"))
715       {
716         logger->log("Command", Log::INFO, "Config says Power After Boot = On");
717       }
718       else if (!STRCASECMP(config, "Off"))
719       {
720         logger->log("Command", Log::INFO, "Config says Power After Boot = Off");
721         doStandby();
722         delete[] config;
723         return; // quit here
724       }
725       else if (!STRCASECMP(config, "Last state"))
726       {
727         char* lastPowerState = vdr->configLoad("General", "Last Power State");
728         if (lastPowerState)
729         {
730           if (!STRCASECMP(lastPowerState, "On"))
731           {
732             logger->log("Command", Log::INFO, "Config says Last Power State = On");
733           }
734           else if (!STRCASECMP(lastPowerState, "Off"))
735           {
736             logger->log("Command", Log::INFO, "Config says Last Power State = Off");
737             doStandby();
738             delete[] config;
739             return; // quit here
740           }
741           else
742           {
743             logger->log("Command", Log::INFO, "Config General/Last Power State not understood");
744           }
745         }
746         else
747         {
748           logger->log("Command", Log::INFO, "Config General/Last Power State not found");
749         }
750       }
751       else
752       {
753         logger->log("Command", Log::INFO, "Config/Power After Boot not understood");
754       }
755       delete[] config;
756     }
757     else
758     {
759       logger->log("Command", Log::INFO, "Config General/Power After Boot not found");
760     }
761   }
762
763
764   // Go S-Video if config says so
765
766   config = vdr->configLoad("TV", "Connection");
767
768   if (config)
769   {
770     if (!STRCASECMP(config, "S-Video"))
771     {
772       logger->log("Command", Log::INFO, "Switching to S-Video as Connection=%s", config);
773       video->setConnection(Video::SVIDEO);
774     }
775     else
776     {
777       logger->log("Command", Log::INFO, "Switching to RGB/Composite as Connection=%s", config);
778       video->setConnection(Video::COMPOSITERGB);
779     }
780     delete[] config;
781   }
782   else
783   {
784     logger->log("Command", Log::INFO, "Config TV/S-Video not found");
785   }
786
787   // Set remote type
788
789   config = vdr->configLoad("General", "Remote type");
790
791   if (config)
792   {
793     if (!STRCASECMP(config, "New"))
794     {
795       logger->log("Command", Log::INFO, "Switching to New remote type");
796       remote->setRemoteType(Remote::NEWREMOTE);
797     }
798     else
799     {
800       logger->log("Command", Log::INFO, "Switching to Old remote type");
801       remote->setRemoteType(Remote::OLDREMOTE);
802     }
803     delete[] config;
804   }
805   else
806   {
807     logger->log("Command", Log::INFO, "Config General/Remote type not found");
808     remote->setRemoteType(Remote::OLDREMOTE);
809   }
810
811
812
813
814   // Get TV aspect ratio
815
816   config = vdr->configLoad("TV", "Aspect");
817   if (config)
818   {
819     if (!STRCASECMP(config, "16:9"))
820     {
821       logger->log("Command", Log::INFO, "/// Switching to TV aspect 16:9");
822       video->setTVsize(Video::ASPECT16X9);
823     }
824     else
825     {
826       logger->log("Command", Log::INFO, "/// Switching to TV aspect 4:3");
827       video->setTVsize(Video::ASPECT4X3);
828     }
829     delete[] config;
830   }
831   else
832   {
833     logger->log("Command", Log::INFO, "Config TV/Aspect type not found, going 4:3");
834     video->setTVsize(Video::ASPECT4X3);
835   }
836
837   config = vdr->configLoad("TV", "Widemode");
838   if (config)
839   {
840     if (!STRCASECMP(config, "Letterbox"))
841     {
842       logger->log("Command", Log::INFO, "Setting letterbox mode");
843       video->setMode(Video::LETTERBOX);
844     }
845     else
846     {
847       logger->log("Command", Log::INFO, "Setting chop-sides mode");
848       video->setMode(Video::NORMAL);
849     }
850     delete[] config;
851   }
852   else
853   {
854     logger->log("Command", Log::INFO, "Config TV/Widemode not found, Setting chop-sides mode");
855     video->setMode(Video::NORMAL);
856   }
857
858   config = vdr->configLoad("Advanced", "TCP receive window");
859   if (config)
860   {
861     size_t newTCPsize = atoi(config);
862     delete[] config;
863
864     logger->log("Command", Log::INFO, "Setting TCP window size %i", newTCPsize);
865     vdr->setReceiveWindow(newTCPsize);
866   }
867   else
868   {
869     logger->log("Command", Log::INFO, "TCP window size not found, setting 2048");
870     vdr->setReceiveWindow(2048); // Default
871   }
872
873   config = vdr->configLoad("Advanced", "Disable WOL");
874   if (config)
875   {
876     if (!STRCASECMP(config, "Yes"))
877     {
878       logger->log("Command", Log::INFO, "Config says disable WOL");
879       Wol::getInstance()->setEnabled(false);
880     }
881     else
882     {
883       logger->log("Command", Log::INFO, "Config says enable WOL");
884       Wol::getInstance()->setEnabled(true);
885     }
886
887     delete[] config;
888   }
889   else
890   {
891     logger->log("Command", Log::INFO, "By default, enable WOL");
892     Wol::getInstance()->setEnabled(true);
893   }
894   /* device dependend config */
895   audio->loadOptionsfromServer(vdr);
896   video->loadOptionsfromServer(vdr);
897   remote->loadOptionsfromServer(vdr);
898   // config done
899
900   // Save power state = on
901
902   vdr->configSave("General", "Last Power State", "On");
903
904   // Make sure connection didn't die
905   if (!vdr->isConnected())
906   {
907     Command::getInstance()->connectionLost();
908   }
909   else
910   {
911     boxstack->remove(vi);
912
913     VWelcome* vw = new VWelcome();
914     vw->draw();
915     boxstack->add(vw);
916     boxstack->update(vw);
917
918     // Enter pre-keys here
919 //    handleCommand(Remote::OK);
920 //    handleCommand(Remote::THREE);
921 //    handleCommand(Remote::SIX);
922 //    handleCommand(Remote::OK);
923 //    handleCommand(Remote::UP);
924 //    handleCommand(Remote::PLAY);
925 //    handleCommand(Remote::DOWN);
926 //    handleCommand(Remote::DOWN);
927 //    handleCommand(Remote::DOWN);
928  //   handleCommand(Remote::OK);
929 //    handleCommand(Remote::RED);
930   }
931 }