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