]> git.vomp.tv Git - vompclient.git/blob - command.cc
NTSC support, needs testing
[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 #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   state = 0;
31 }
32
33 Command::~Command()
34 {
35   instance = NULL;
36 }
37
38 Command* Command::getInstance()
39 {
40   return instance;
41 }
42
43 int Command::init()
44 {
45   if (initted) return 0;
46   initted = 1;
47
48   logger = Log::getInstance();
49   viewman = ViewMan::getInstance();
50   remote = Remote::getInstance();
51
52   if (!logger || !viewman || !remote)
53   {
54     initted = 0;
55     return 0;
56   }
57
58   return 1;
59 }
60
61 int Command::shutdown()
62 {
63   if (!initted) return 0;
64   initted = 0;
65   return 1;
66 }
67
68 void Command::stop()
69 {
70   VDR::getInstance()->cancelFindingServer();
71   irun = 0;
72 }
73
74 void Command::run()
75 {
76   if (!initted) return;
77   irun = 1;
78
79   mainPid = getpid();
80
81   UCHAR screenSize = Osd::getInstance()->getScreenSize();
82
83   // moved from startup because surface delete doesn't work
84
85   // just in case
86   Video::getInstance()->signalOn();
87   Led::getInstance()->on();
88
89   // Blue background
90   View* v = new View();
91   v->setDimensions(Osd::getInstance()->getScreenHeight(), Osd::getInstance()->getScreenWidth());
92   v->setBackgroundColour(Colour::VIDEOBLUE);
93   v->draw();
94   v->show();
95   viewman->add(v);
96   viewman->removeView(v);
97
98   // Wallpaper
99   VWallpaper* w = new VWallpaper();
100   if (screenSize == Osd::PAL)
101   {
102     Log::getInstance()->log("Command", Log::DEBUG, "PAL wallpaper selected");
103     w->init("/wallpaperPAL.jpg");
104   }
105   else
106   {
107     Log::getInstance()->log("Command", Log::DEBUG, "NTSC wallpaper selected");
108     w->init("/wallpaperNTSC.jpg");
109   }
110   w->draw();
111   w->show();
112   viewman->add(w);
113
114
115 //  handleCommand(Remote::TWO);
116 //  handleCommand(Remote::UP);
117 //  handleCommand(Remote::PLAY);
118
119 //  handleCommand(Remote::DOWN);
120 //  handleCommand(Remote::OK);
121
122 //  handleCommand(Remote::DOWN);
123 //  handleCommand(Remote::DOWN);
124 //  handleCommand(Remote::DOWN);
125 //  handleCommand(Remote::OK);
126
127   // state values:
128   // 0 = not connected
129   // 1 = got servers
130   // 2 = multiple servers, showing select box
131   // 3 = a server has been selected
132   // 4 = connected
133   // 5 = standby
134
135   int selectServer;
136   UCHAR button = 0;
137   while(irun)
138   {
139     if (state != 4) // not really necessary, but chops out all the connecting rubbish if already connected
140     {
141       if (state == 0)
142       {
143         clearServerIPs();
144         broadcastForServers();
145         if (!irun) break;
146         state = 1;
147       }
148
149       if (state == 1)
150       {
151         if (serverIPs.size() == 1)
152         {
153           selectServer = 0;
154           state = 3;
155         }
156         else
157         {
158           selectServer = -1;
159           state = 2;
160           VServerSelect* vs = new VServerSelect(&serverIPs, &selectServer);
161           vs->draw();
162           vs->show();
163           viewman->add(vs);
164         }
165       }
166
167       if (state == 2)
168       {
169         // entering loop for 2nd time.. has a server been selected?
170         if (selectServer != -1) state = 3;
171       }
172
173       if (state == 3)
174       {
175         Log::getInstance()->log("Command", Log::DEBUG, "Server selected: %i", selectServer);
176
177         int success = connectToServer(selectServer);
178         clearServerIPs();
179
180         if (success)
181         {
182           VWelcome* vw = new VWelcome();
183           vw->draw();
184           vw->show();
185           viewman->add(vw);
186           state = 4;
187         }
188         else
189         {
190           state = 0;
191         }
192       }
193
194       if (state == 0) continue;
195       // state can't be 1
196       // if state == 2 then drop to remote handling below
197       // state can't be 3
198       // if state == 4 then drop through to main system, job done
199     }
200
201
202     button = remote->getButtonPress(2);  // FIXME why is this set to 2 and not 0? so it can quit
203     if ((button == Remote::NONE) || (button == Remote::UNKNOWN)) continue;
204
205     if (button != Remote::SIGNAL) handleCommand(button);
206     processMessageQueue();
207   }
208 }
209
210 void Command::postMessage(Message* m)
211 {
212   MessageQueue::postMessage(m);
213   kill(mainPid, SIGURG);
214 }
215
216 void Command::processMessage(Message* m)
217 {
218   Log::getInstance()->log("Command", Log::DEBUG, "processing message %i", m->message);
219
220   switch(m->message)
221   {
222     case Message::STANDBY:
223     {
224       doStandby();
225       break;
226     }
227     case Message::STOP_PLAYBACK:
228     {
229       handleCommand(Remote::STOP); // an odd way of doing it, but so simple
230       break;
231     }
232   }
233 }
234
235 void Command::clearServerIPs()
236 {
237   // Clear the serverIPs vector
238   for(UINT k = 0; k < serverIPs.size(); k++)
239   {
240     delete[] serverIPs[k];
241   }
242   serverIPs.clear();
243 }
244
245 void Command::handleCommand(int button)
246 {
247   if (state == 5 && (button != Remote::POWER)) return;
248
249   if (viewman->handleCommand(button)) return;
250
251   // command was not handled
252
253   switch(button)
254   {
255     case Remote::LEFT:
256     case Remote::RIGHT:
257     {
258       VVolume* v = new VVolume();
259       v->handleCommand(button); // this will draw+show
260       viewman->add(v);
261       viewman->timedDelete(v, 2, 1);
262       return;
263     }
264     case Remote::MUTE:
265     {
266       VMute* v = new VMute();
267       v->draw();
268       v->show();
269       viewman->add(v);
270       viewman->timedDelete(v, 2, 1);
271       return;
272     }
273     case Remote::POWER:
274     {
275       doStandby();
276       return;
277     }
278     case Remote::RECORD:
279     {
280       Osd::getInstance()->screenShot("/out.jpg");
281       return;
282     }
283   }
284 }
285
286 void Command::broadcastForServers()
287 {
288   VInfo* viewWait = new VInfo();
289   viewWait->setDimensions(200, 400);
290   if (Osd::getInstance()->getScreenSize() == Osd::PAL)
291   {
292     viewWait->setScreenPos(170, 200);
293   }
294   else
295   {
296     viewWait->setScreenPos(160, 150);
297   }
298   viewWait->setMainText("\n                        Locating server");
299   viewWait->draw();
300   viewWait->show();
301   viewman->add(viewWait);
302
303
304   VDR* vdr = VDR::getInstance();
305   vdr->findServers(serverIPs);
306   if (!irun) return;
307   viewman->removeView(viewWait);
308 }
309
310 int Command::connectToServer(int vectorIndex)
311 {
312   char a[60];
313   struct timespec ts;
314
315   VDR* vdr = VDR::getInstance();
316   vdr->setServerIP(serverIPs[vectorIndex]);
317
318   logger->log("Command", Log::NOTICE, "Connecting to server at %s", serverIPs[vectorIndex]);
319
320   VInfo* viewWait = new VInfo();
321   viewWait->setDimensions(200, 400);
322   if (Osd::getInstance()->getScreenSize() == Osd::PAL)
323   {
324     viewWait->setScreenPos(170, 200);
325   }
326   else
327   {
328     viewWait->setScreenPos(160, 150);
329   }
330   viewWait->setMainText("\n                     Connecting to VDR");
331   viewWait->draw();
332   viewWait->show();
333   viewman->add(viewWait);
334
335   int success = vdr->connect();
336
337   if (success)
338   {
339     Log::getInstance()->log("Command", Log::DEBUG, "Connected ok, doing login");
340     success = vdr->doLogin();
341
342     if (success)
343     {
344       strcpy(a, "\n                            Connected");
345       ts.tv_sec = 0;
346       ts.tv_nsec = 500000000;
347     }
348     else
349     {
350       strcpy(a, "\n                           Login failed");
351       ts.tv_sec = 3;
352       ts.tv_nsec = 0;
353     }
354   }
355   else
356   {
357     strcpy(a, "\n                      Connection failed");
358     ts.tv_sec = 3;
359     ts.tv_nsec = 0;
360   }
361
362   viewWait->setMainText(a);
363   viewWait->draw();
364   viewWait->show();
365
366   if (irun) nanosleep(&ts, NULL); // only do the wait if we aren't shutting down
367
368 /*
369   vdr->configSave("Section Name This Is blah blah blah 495834509725049375032end", "thekey with this space ", "1234value");
370   sleep(10);
371
372   char* conf = vdr->configLoad("fred", "bill");
373   if (conf)
374   {
375     //printf("And the config value returned is %s\n", conf);
376     delete[] conf;
377   }
378   else
379   {
380     //printf("Conf value return is NULL :(\n");
381   }
382 */
383
384   viewman->removeView(viewWait);
385
386   return success;
387 }
388
389 void Command::doStandby()
390 {
391   if (state == 5)
392   {
393     Video::getInstance()->signalOn();
394     Led::getInstance()->on();
395     state = 0;
396   }
397   else
398   {
399     ViewMan* viewman = ViewMan::getInstance();
400
401     viewman->removeAll();
402     viewman->redrawAll();
403
404
405     VDR::getInstance()->disconnect();
406     Video::getInstance()->signalOff();
407     Led::getInstance()->off();
408     state = 5;
409   }
410 }
411
412 void Command::doReboot()
413 {
414   VDR::getInstance()->disconnect();
415   // just kill it...
416   logger->log("Command", Log::NOTICE, "Reboot");
417   reboot(LINUX_REBOOT_CMD_RESTART);
418 }