]> git.vomp.tv Git - vompclient-marten.git/blob - command.cc
Widescreen support, segfault fix on livetv interrupt
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "command.h"
22
23 Command* Command::instance = NULL;
24
25 Command::Command()
26 {
27   if (instance) return;
28   instance = this;
29   initted = 0;
30   isStandby = 0;
31   firstBoot = 1;
32 }
33
34 Command::~Command()
35 {
36   instance = NULL;
37 }
38
39 Command* Command::getInstance()
40 {
41   return instance;
42 }
43
44 int Command::init()
45 {
46   if (initted) return 0;
47   initted = 1;
48
49   logger = Log::getInstance();
50   viewman = ViewMan::getInstance();
51   remote = Remote::getInstance();
52
53   if (!logger || !viewman || !remote)
54   {
55     initted = 0;
56     return 0;
57   }
58
59   logger->log("Command", Log::DEBUG, "%p", this);
60
61   return 1;
62 }
63
64 int Command::shutdown()
65 {
66   if (!initted) return 0;
67   initted = 0;
68   return 1;
69 }
70
71 void Command::stop()
72 {
73 //  VDR::getInstance()->cancelFindingServer();
74   irun = 0;
75 }
76
77 void Command::run()
78 {
79   if (!initted) return;
80   irun = 1;
81
82   mainPid = getpid();
83
84   Video* video = Video::getInstance();
85
86   UCHAR screenSize = video->getFormat();
87
88   // moved from startup because surface delete doesn't work
89
90   // just in case
91   video->signalOn();
92   Led::getInstance()->on();
93
94   // Blue background
95   View* v = new View();
96   v->setDimensions(video->getScreenWidth(), video->getScreenHeight());
97   v->setBackgroundColour(Colour::VIDEOBLUE);
98   v->draw();
99   v->show();
100   viewman->add(v);
101   viewman->removeView(v);
102
103   // Wallpaper
104   VWallpaper* w = new VWallpaper();
105   if (screenSize == Video::PAL)
106   {
107     logger->log("Command", Log::DEBUG, "PAL wallpaper selected");
108     w->init("/wallpaperPAL.jpg");
109   }
110   else
111   {
112     logger->log("Command", Log::DEBUG, "NTSC wallpaper selected");
113     w->init("/wallpaperNTSC.jpg");
114   }
115   w->draw();
116   w->show();
117   viewman->add(w);
118
119   VConnect* vconnect = new VConnect();
120   viewman->add(vconnect);
121   vconnect->run();
122
123
124   UCHAR button = 0;
125   while(irun)
126   {
127     button = remote->getButtonPress(2);  // FIXME why is this set to 2 and not 0? so it can quit
128     if ((button == Remote::NA_NONE) || (button == Remote::NA_UNKNOWN)) continue;
129
130     if (button != Remote::NA_SIGNAL) handleCommand(button);
131     processMessageQueue();
132   }
133 }
134
135 void Command::postMessage(Message* m)
136 {
137   MessageQueue::postMessage(m);
138   kill(mainPid, SIGURG);
139 }
140
141 void Command::processMessage(Message* m)
142 {
143   logger->log("Command", Log::DEBUG, "processing message %i", m->message);
144
145   switch(m->message)
146   {
147     case Message::STANDBY:
148     {
149       doStandby();
150       break;
151     }
152     case Message::STOP_PLAYBACK:
153     {
154       handleCommand(Remote::STOP); // an odd way of doing it, but so simple
155       break;
156     }
157     case Message::STREAM_END:
158     {
159       // post a message to ViewMan and then run the viewman message queue
160       Message* m = new Message();
161       m->message = Message::STREAM_END;
162       m->to = VVideoLive::getInstance();
163       viewman->postMessage(m);
164       handleCommand(Remote::NA_NONE);
165       break;
166     }
167     case Message::VDR_CONNECTED:
168     {
169       doJustConnected((VConnect*)m->from);
170       break;
171     }
172   }
173 }
174
175 void Command::handleCommand(int button)
176 {
177   if (isStandby && (button != Remote::POWER)) return;
178
179   if (viewman->handleCommand(button)) return;
180
181   // command was not handled
182
183   switch(button)
184   {
185     case Remote::DF_LEFT:
186     case Remote::DF_RIGHT:
187     case Remote::VOLUMEUP:
188     case Remote::VOLUMEDOWN:
189     {
190       VVolume* v = new VVolume();
191       v->handleCommand(button); // this will draw+show
192       viewman->add(v);
193       viewman->timedDelete(v, 2, 1);
194       return;
195     }
196     case Remote::MUTE:
197     {
198       VMute* v = new VMute();
199       v->draw();
200       v->show();
201       viewman->add(v);
202       viewman->timedDelete(v, 2, 1);
203       return;
204     }
205     case Remote::POWER:
206     {
207       doStandby();
208       return;
209     }
210 #ifdef DEV
211     case Remote::RECORD:
212     {
213       Osd::getInstance()->screenShot("/out.jpg");
214       return;
215     }
216 #endif
217   }
218 }
219
220 void Command::doStandby()
221 {
222   if (isStandby)
223   {
224     Video::getInstance()->signalOn();
225     Led::getInstance()->on();
226     isStandby = 0;
227
228
229     VConnect* vconnect = new VConnect();
230     viewman->add(vconnect);
231     vconnect->run();
232   }
233   else
234   {
235     ViewMan* viewman = ViewMan::getInstance();
236
237     viewman->removeAll();
238     viewman->redrawAll();
239
240     VDR::getInstance()->configSave("General", "Last Power State", "Off");
241     VDR::getInstance()->disconnect();
242     Video::getInstance()->signalOff();
243     Led::getInstance()->off();
244     isStandby = 1;
245   }
246 }
247
248 void Command::doReboot()
249 {
250   VDR::getInstance()->disconnect();
251   // just kill it...
252   logger->log("Command", Log::NOTICE, "Reboot");
253   reboot(LINUX_REBOOT_CMD_RESTART);
254 }
255
256 void Command::doJustConnected(VConnect* vconnect)
257 {
258   Video* video = Video::getInstance();
259   ViewMan* viewman = ViewMan::getInstance();
260   viewman->removeView(vconnect, 0, 1);
261
262   VInfo* vi = new VInfo();
263   vi->setDimensions(400, 200);
264   if (video->getFormat() == Video::PAL)
265     vi->setScreenPos(170, 200);
266   else
267     vi->setScreenPos(160, 150);
268
269   vi->setMainText("\n               Connected, loading config");
270   vi->draw();
271   vi->show();
272   viewman->add(vi);
273
274
275   VDR* vdr = VDR::getInstance();
276
277   // Power off if first boot and config says so
278   if (firstBoot)
279   {
280     firstBoot = 0;
281
282     char* powerAfterBoot = vdr->configLoad("General", "Power After Boot");
283
284     if (powerAfterBoot)
285     {
286       if (!strcasecmp(powerAfterBoot, "On"))
287       {
288         logger->log("Command", Log::INFO, "Config says Power After Boot = On");
289       }
290       else if (!strcasecmp(powerAfterBoot, "Off"))
291       {
292         logger->log("Command", Log::INFO, "Config says Power After Boot = Off");
293         doStandby();
294         return; // quit here
295       }
296       else if (!strcasecmp(powerAfterBoot, "Last state"))
297       {
298         char* lastPowerState = vdr->configLoad("General", "Last Power State");
299         if (lastPowerState)
300         {
301           if (!strcasecmp(lastPowerState, "On"))
302           {
303             logger->log("Command", Log::INFO, "Config says Last Power State = On");
304           }
305           else if (!strcasecmp(lastPowerState, "Off"))
306           {
307             logger->log("Command", Log::INFO, "Config says Last Power State = Off");
308             doStandby();
309             return; // quit here
310           }
311           else
312           {
313             logger->log("Command", Log::INFO, "Config General/Last Power State not understood");
314           }
315         }
316         else
317         {
318           logger->log("Command", Log::INFO, "Config General/Last Power State not found");
319         }
320       }
321       else
322       {
323         logger->log("Command", Log::INFO, "Config/Power After Boot not understood");
324       }
325     }
326     else
327     {
328       logger->log("Command", Log::INFO, "Config General/Power After Boot not found");
329     }
330   }
331
332
333   // Go S-Video if config says so
334
335   char* svideo = vdr->configLoad("TV", "S-Video");
336
337   if (svideo)
338   {
339     if (!strcasecmp(svideo, "Yes"))
340     {
341       logger->log("Command", Log::INFO, "Switching to S-Video as S-Video=%s", svideo);
342       video->setConnection(Video::SVIDEO);
343     }
344     else
345     {
346       logger->log("Command", Log::INFO, "Leaving video output as S-Video=%s", svideo);
347       video->setConnection(Video::COMPOSITERGB);
348     }
349   }
350   else
351   {
352     logger->log("Command", Log::INFO, "Config TV/S-Video not found");
353   }
354
355   // Set remote type
356
357   char* remoteType = vdr->configLoad("General", "Remote type");
358
359   if (remoteType)
360   {
361     if (!strcasecmp(remoteType, "New"))
362     {
363       logger->log("Command", Log::INFO, "Switching to New remote type");
364       remote->setRemoteType(Remote::NEWREMOTE);
365     }
366     else
367     {
368       logger->log("Command", Log::INFO, "Switching to Old remote type");
369       remote->setRemoteType(Remote::OLDREMOTE);
370     }
371   }
372   else
373   {
374     logger->log("Command", Log::INFO, "Config General/Remote type not found");
375     remote->setRemoteType(Remote::OLDREMOTE);
376   }
377
378   // Save power state = on
379
380   vdr->configSave("General", "Last Power State", "On");
381
382   // Get TV aspect ratio
383
384   char* aspect = vdr->configLoad("TV", "Aspect");
385
386   if (aspect)
387   {
388     if (!strcasecmp(aspect, "16:9"))
389     {
390       logger->log("Command", Log::INFO, "Switching to TV aspect 16:9");
391       video->setAspectRatio(Video::ASPECT16X9);
392     }
393     else
394     {
395       logger->log("Command", Log::INFO, "Switching to TV aspect 4:3");
396       video->setAspectRatio(Video::ASPECT4X3);
397     }
398   }
399   else
400   {
401     logger->log("Command", Log::INFO, "Config TV/Aspect type not found, going 4:3");
402     video->setAspectRatio(Video::ASPECT4X3);
403   }
404
405   video->reinit();
406
407   // config done
408
409   viewman->removeView(vi);
410
411   VWelcome* vw = new VWelcome();
412   viewman->add(vw);
413   viewman->redrawAll();
414
415 /*
416   handleCommand(Remote::DOWN);
417   handleCommand(Remote::DOWN);
418   handleCommand(Remote::DOWN);
419   handleCommand(Remote::OK);
420 */
421 }