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