2 Copyright 2004-2005 Chris Tallon
4 This file is part of VOMP.
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.
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.
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
23 Command* Command::instance = NULL;
39 Command* Command::getInstance()
46 if (initted) return 0;
49 logger = Log::getInstance();
50 viewman = ViewMan::getInstance();
51 remote = Remote::getInstance();
53 if (!logger || !viewman || !remote)
59 pthread_mutex_init(&masterLock, NULL);
64 int Command::shutdown()
66 if (!initted) return 0;
73 // VDR::getInstance()->cancelFindingServer();
77 void Command::doWallpaper()
79 Video* video = Video::getInstance();
83 v->create(video->getScreenWidth(), video->getScreenHeight());
84 v->setBackgroundColour(Colour::VIDEOBLUE);
87 viewman->updateView(v);
88 viewman->removeView(v);
91 wallpaper = new VWallpaper();
92 if (video->getFormat() == Video::PAL)
94 logger->log("Command", Log::DEBUG, "PAL wallpaper selected");
95 wallpaper->init("/wallpaperPAL.jpg");
99 logger->log("Command", Log::DEBUG, "NTSC wallpaper selected");
100 wallpaper->init("/wallpaperNTSC.jpg");
103 viewman->add(wallpaper);
104 viewman->updateView(wallpaper);
109 if (!initted) return;
115 Video::getInstance()->signalOn();
116 Led::getInstance()->on();
120 // End of startup. Lock the mutex and put the first view up
122 pthread_mutex_lock(&masterLock);
125 VConnect* vconnect = new VConnect();
126 viewman->add(vconnect);
134 pthread_mutex_unlock(&masterLock);
136 button = remote->getButtonPress(2); // FIXME why is this set to 2 and not 0? so it can quit
137 // something happened, lock and process
139 pthread_mutex_lock(&masterLock);
141 if ((button == Remote::NA_NONE) || (button == Remote::NA_UNKNOWN)) continue;
143 if (button != Remote::NA_SIGNAL) handleCommand(button);
144 processMessageQueue();
147 pthread_mutex_unlock(&masterLock);
150 void Command::postMessage(Message* m)
152 // This is locked here in case the main loop is not waiting for an event, but is processing one
153 // it could be killed but then not react to it because the signal wouldn't cause
154 // remote->getButtonPress to break
155 // locking the mutex ensures that the master thread is waiting on getButtonPress
158 pthread_mutex_lock(&masterLock);
159 MessageQueue::postMessage(m);
160 kill(mainPid, SIGURG);
161 pthread_mutex_unlock(&masterLock);
164 void Command::postMessageNoLock(Message* m)
166 // As above but use this one if this message is being posted because of a button press
167 // the mutex is already locked, locking around postMessage is not needed as the
168 // queue is guaranteed to be run when the button has been processed
169 MessageQueue::postMessage(m);
172 bool Command::postMessageIfNotBusy(Message* m)
174 // This is for the timers module
175 // If the masterlock is locked then the timers module wants to
178 if (pthread_mutex_trylock(&masterLock) != EBUSY)
180 MessageQueue::postMessage(m);
181 kill(mainPid, SIGURG);
182 pthread_mutex_unlock(&masterLock);
191 void Command::processMessage(Message* m)
193 logger->log("Command", Log::DEBUG, "processing message %i", m->message);
197 case Message::STANDBY:
202 case Message::STOP_PLAYBACK:
204 handleCommand(Remote::STOP); // an odd way of doing it, but so simple
207 case Message::STREAM_END:
209 VVideoLive::getInstance()->streamEnd();
212 case Message::VDR_CONNECTED:
214 doJustConnected((VConnect*)m->from);
219 // FIXME - go to one message queue only - then instead of having
220 // objects deriving from messagequeues, make them derive from
221 // messagereceiver - then one messagequeue can deliver any message to anywhere
225 ((TimerReceiver*)m->to)->timercall(m->parameter);
226 handleCommand(Remote::NA_NONE); // in case any timer has posted messages to viewman,
227 // run viewman message queue here. FIXME improve this!
230 case Message::SCREENSHOT:
232 Osd::getInstance()->screenShot("/out.jpg");
237 void Command::handleCommand(int button)
239 if (isStandby && (button != Remote::POWER)) return;
241 if (viewman->handleCommand(button)) return;
243 // command was not handled
247 case Remote::DF_LEFT:
248 case Remote::DF_RIGHT:
249 case Remote::VOLUMEUP:
250 case Remote::VOLUMEDOWN:
252 VVolume* v = new VVolume();
254 v->handleCommand(button); // this will draw+show
259 VMute* v = new VMute();
262 viewman->updateView(v);
276 Message* m = new Message(); // break into master mutex
277 m->message = Message::SCREENSHOT;
283 void Command::doStandby()
287 Video::getInstance()->signalOn();
288 Led::getInstance()->on();
292 VConnect* vconnect = new VConnect();
293 viewman->add(vconnect);
298 viewman->removeAll();
299 Video::getInstance()->signalOff();
300 viewman->updateView(wallpaper);
302 VDR::getInstance()->configSave("General", "Last Power State", "Off");
303 VDR::getInstance()->disconnect();
304 Led::getInstance()->off();
309 void Command::doReboot()
311 VDR::getInstance()->disconnect();
313 logger->log("Command", Log::NOTICE, "Reboot");
314 reboot(LINUX_REBOOT_CMD_RESTART);
317 void Command::doJustConnected(VConnect* vconnect)
320 Video* video = Video::getInstance();
321 viewman->removeView(vconnect);
323 VInfo* vi = new VInfo();
324 vi->create(400, 200);
325 if (video->getFormat() == Video::PAL)
326 vi->setScreenPos(170, 200);
328 vi->setScreenPos(160, 150);
330 vi->setOneLiner(tr("Connected, loading config"));
333 viewman->updateView(vi);
335 VDR* vdr = VDR::getInstance();
338 // See if config says to override video format (PAL/NTSC)
339 config = vdr->configLoad("General", "Override Video Format");
342 logger->log("Command", Log::DEBUG, "Override Video Format is present");
344 if ( (!strcmp(config, "PAL") && (video->getFormat() == Video::NTSC))
345 || (!strcmp(config, "NTSC") && (video->getFormat() == Video::PAL)) )
347 // Oh sheesh, need to switch format. Bye bye TV...
349 // Take everything down
350 viewman->removeAll();
351 viewman->removeView(wallpaper);
352 Osd* osd = Osd::getInstance();
356 // Get video and osd back up with the new mode
357 if (!strcmp(config, "PAL"))
359 logger->log("Command", Log::DEBUG, "Switching to PAL");
360 video->init(Video::PAL);
362 else if (!strcmp(config, "NTSC"))
364 logger->log("Command", Log::DEBUG, "Switching to NTSC");
365 video->init(Video::NTSC);
367 osd->init("/dev/stbgfx");
369 // Put the wallpaper back
374 vi->create(400, 200);
375 if (video->getFormat() == Video::PAL)
376 vi->setScreenPos(170, 200);
378 vi->setScreenPos(160, 150);
380 vi->setOneLiner(tr("Connected, loading config"));
383 viewman->updateView(vi);
387 logger->log("Command", Log::DEBUG, "Already in requested mode, or request was not 'PAL' or 'NTSC'");
392 logger->log("Command", Log::DEBUG, "Phew, no dangerous on-the-fly mode switching to do!");
395 // Power off if first boot and config says so
400 logger->log("Command", Log::DEBUG, "Load power after boot");
402 config = vdr->configLoad("General", "Power After Boot");
406 if (!strcasecmp(config, "On"))
408 logger->log("Command", Log::INFO, "Config says Power After Boot = On");
410 else if (!strcasecmp(config, "Off"))
412 logger->log("Command", Log::INFO, "Config says Power After Boot = Off");
417 else if (!strcasecmp(config, "Last state"))
419 char* lastPowerState = vdr->configLoad("General", "Last Power State");
422 if (!strcasecmp(lastPowerState, "On"))
424 logger->log("Command", Log::INFO, "Config says Last Power State = On");
426 else if (!strcasecmp(lastPowerState, "Off"))
428 logger->log("Command", Log::INFO, "Config says Last Power State = Off");
435 logger->log("Command", Log::INFO, "Config General/Last Power State not understood");
440 logger->log("Command", Log::INFO, "Config General/Last Power State not found");
445 logger->log("Command", Log::INFO, "Config/Power After Boot not understood");
451 logger->log("Command", Log::INFO, "Config General/Power After Boot not found");
456 // Go S-Video if config says so
458 config = vdr->configLoad("TV", "Connection");
462 if (!strcasecmp(config, "S-Video"))
464 logger->log("Command", Log::INFO, "Switching to S-Video as Connection=%s", config);
465 video->setConnection(Video::SVIDEO);
469 logger->log("Command", Log::INFO, "Switching to RGB/Composite as Connection=%s", config);
470 video->setConnection(Video::COMPOSITERGB);
476 logger->log("Command", Log::INFO, "Config TV/S-Video not found");
481 config = vdr->configLoad("General", "Remote type");
485 if (!strcasecmp(config, "New"))
487 logger->log("Command", Log::INFO, "Switching to New remote type");
488 remote->setRemoteType(Remote::NEWREMOTE);
492 logger->log("Command", Log::INFO, "Switching to Old remote type");
493 remote->setRemoteType(Remote::OLDREMOTE);
499 logger->log("Command", Log::INFO, "Config General/Remote type not found");
500 remote->setRemoteType(Remote::OLDREMOTE);
503 // Get TV aspect ratio
505 config = vdr->configLoad("TV", "Aspect");
508 if (!strcasecmp(config, "16:9"))
510 logger->log("Command", Log::INFO, "/// Switching to TV aspect 16:9");
511 video->setTVsize(Video::ASPECT16X9);
515 logger->log("Command", Log::INFO, "/// Switching to TV aspect 4:3");
516 video->setTVsize(Video::ASPECT4X3);
522 logger->log("Command", Log::INFO, "Config TV/Aspect type not found, going 4:3");
523 video->setTVsize(Video::ASPECT4X3);
526 config = vdr->configLoad("TV", "Widemode");
529 if (!strcasecmp(config, "Letterbox"))
531 logger->log("Command", Log::INFO, "Setting letterbox mode");
532 video->setMode(Video::LETTERBOX);
536 logger->log("Command", Log::INFO, "Setting chop-sides mode");
537 video->setMode(Video::NORMAL);
543 logger->log("Command", Log::INFO, "Config TV/Widemode not found, Setting chop-sides mode");
544 video->setMode(Video::NORMAL);
547 config = vdr->configLoad("Advanced", "TCP receive window");
550 size_t newTCPsize = atoi(config);
553 logger->log("Command", Log::INFO, "Setting TCP window size %i", newTCPsize);
554 vdr->setReceiveWindow(newTCPsize);
558 logger->log("Command", Log::INFO, "TCP window size not found, setting 2048");
559 vdr->setReceiveWindow(2048); // Default
565 // Save power state = on
567 vdr->configSave("General", "Last Power State", "On");
570 viewman->removeView(vi);
572 VWelcome* vw = new VWelcome();
575 viewman->updateView(vw);
577 // Enter pre-keys here
578 // handleCommand(Remote::THREE);
579 // handleCommand(Remote::DOWN);
580 // handleCommand(Remote::OK);
581 // handleCommand(Remote::PLAY);