2 Copyright 2007 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
21 #include "vvideolivetv.h"
23 #include "vchannellist.h"
25 //#include "playerlivetv.h"
34 #include "vaudioselector.h"
38 VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, VChannelList* tvchannelList)
40 vdr = VDR::getInstance();
41 boxstack = BoxStack::getInstance();
42 video = Video::getInstance();
45 vchannelList = tvchannelList;
46 numberWidth = (int)VDR::getInstance()->getChannelNumberWidth();
48 currentChannelIndex = 0;
49 previousChannelIndex = 0;
53 // Convert channel number to index
55 for(i = 0; i < chanList->size(); i++)
57 if ((*chanList)[i]->number == (UINT)initialChannelNumber)
59 currentChannelIndex = i;
67 videoMode = video->getMode();
68 // player = new PlayerLiveTV(Command::getInstance(), this);
69 // player->init(chanList);
71 setSize(video->getScreenWidth(), video->getScreenHeight());
73 Colour transparent(0, 0, 0, 0);
74 setBackgroundColour(transparent);
77 char* optionWSS = vdr->configLoad("General", "WSS");
80 if (strstr(optionWSS, "Yes")) dowss = true;
83 Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Do WSS: %u", dowss);
87 wss.setFormat(video->getFormat());
93 wssRegion.w = video->getScreenWidth();
97 Colour osdBack = Colour(50, 50, 50);
99 osd.setBackgroundColour(osdBack);
100 osd.setPosition(0, video->getScreenHeight() - 150);
101 osd.setSize(video->getScreenWidth(), 150);
102 osd.setVisible(false);
105 clock.setBackgroundColour(Colour::BLACK);
106 clock.setPosition(osd.getWidth() - 100, 4);
107 clock.setSize(90, 30);
108 clock.setText("00:00");
111 osdChanNum.setBackgroundColour(Colour::BLACK);
112 osdChanNum.setPosition(40, 4);
113 osdChanNum.setSize((numberWidth*10) + 22, 30); // 10 px = width of number chars in font
114 osd.add(&osdChanNum);
116 osdChanName.setBackgroundColour(Colour::BLACK);
117 osdChanName.setPosition(osdChanNum.getX2() + 10, 4);
118 osdChanName.setSize(300, 30);
119 osd.add(&osdChanName);
121 boxRed.setBackgroundColour(Colour::RED);
122 boxRed.setPosition(50, 104);
123 boxRed.setSize(18, 16);
126 boxGreen.setBackgroundColour(Colour::GREEN);
127 boxGreen.setPosition(220, 104);
128 boxGreen.setSize(18, 16);
131 boxYellow.setBackgroundColour(Colour::YELLOW);
132 boxYellow.setPosition(390, 104);
133 boxYellow.setSize(18, 16);
136 boxBlue.setBackgroundColour(Colour::BLUE);
137 boxBlue.setPosition(560, 104);
138 boxBlue.setSize(18, 16);
141 textRed.setBackgroundColour(Colour::BLACK);
142 textRed.setPosition(boxRed.getX()+18, 98);
143 textRed.setSize(120, 30);
144 textRed.setText("Summary");
147 textGreen.setBackgroundColour(Colour::BLACK);
148 textGreen.setPosition(boxGreen.getX()+18, 98);
149 textGreen.setSize(120, 30);
150 textGreen.setText("Audio");
153 textYellow.setBackgroundColour(Colour::BLACK);
154 textYellow.setPosition(boxYellow.getX()+18, 98);
155 textYellow.setSize(120, 30);
156 textYellow.setText("");
157 osd.add(&textYellow);
159 textBlue.setBackgroundColour(Colour::BLACK);
160 textBlue.setPosition(boxBlue.getX()+18, 98);
161 textBlue.setSize(90, 30);
162 textBlue.setText("EPG");
165 sl.setPosition(70, 36);
171 VVideoLiveTV::~VVideoLiveTV()
174 video->setDefaultAspect();
177 int VVideoLiveTV::handleCommand(int command)
186 vchannelList->highlightChannel((*chanList)[currentChannelIndex]);
195 boxstack->update(this, osd.getRegion());
204 boxstack->update(this, osd.getRegion());
222 case Remote::CHANNELUP:
227 case Remote::DF_DOWN:
228 case Remote::CHANNELDOWN:
233 case Remote::PREVCHANNEL:
235 channelChange(PREVIOUS, 0);
266 // key in channel number
274 VAudioSelector* vas = new VAudioSelector(this, (*chanList)[currentChannelIndex], ((Player*)player)->getCurrentAudioChannel());
275 vas->setBackgroundColour(Colour::VIEWBACKGROUND);
276 vas->setPosition(0, getHeight()-200);
278 BoxStack::getInstance()->add(vas);
279 BoxStack::getInstance()->update(vas);
295 void VVideoLiveTV::go()
298 osd.setVisible(true);
300 boxstack->update(this);
301 // set a timer for osd deletion
306 void VVideoLiveTV::stop()
310 void VVideoLiveTV::doNowNext()
315 Channel* currentChannel = (*chanList)[osdChannelIndex];
317 char formatChanNum[20];
318 SNPRINTF(formatChanNum, 19, "%0*lu", numberWidth, currentChannel->number);
319 osdChanNum.setText(formatChanNum);
320 osdChanName.setText(currentChannel->name);
322 eventList = VDR::getInstance()->getChannelSchedule(currentChannel->number);
326 sl.addOption(tr("No channel data available"), 0, 1);
330 sort(eventList->begin(), eventList->end(), EventSorter());
332 char tempString[300];
333 char tempString2[300];
336 int eventListSize = eventList->size();
337 for(int i = 0; i < eventListSize; i++)
339 event = (*eventList)[i];
341 //btime = localtime((time_t*)&event->time);
342 time_t etime = event->time;
343 btime = localtime(&etime);
345 strftime(tempString2, 299, "%0H:%0M ", btime);
347 strftime(tempString2, 299, "%H:%M ", btime);
349 SNPRINTF(tempString, 299, "%s %s", tempString2, event->title);
350 sl.addOption(tempString, (ULONG)event, (i==0));
355 void VVideoLiveTV::delData()
359 int eventListSize = eventList->size();
360 for(int i = 0; i < eventListSize; i++)
362 delete (*eventList)[i];
371 void VVideoLiveTV::doOK()
373 if (osd.getVisible())
375 if (osdChannelIndex == currentChannelIndex)
377 osd.setVisible(false);
379 boxstack->update(this, osd.getRegion());
383 channelChange(INDEX, osdChannelIndex);
386 boxstack->update(this, osd.getRegion());
391 osdChannelIndex = currentChannelIndex;
393 osd.setVisible(true);
395 boxstack->update(this, osd.getRegion());
396 // set a timer for deletion of osd
400 void VVideoLiveTV::doLeft()
402 if (osd.getVisible())
404 osdChannelIndex = downChannel(osdChannelIndex);
408 osdChannelIndex = currentChannelIndex;
409 osd.setVisible(true);
414 boxstack->update(this, osd.getRegion());
417 void VVideoLiveTV::doRight()
419 if (osd.getVisible())
421 osdChannelIndex = upChannel(osdChannelIndex);
425 osdChannelIndex = currentChannelIndex;
426 osd.setVisible(true);
431 boxstack->update(this, osd.getRegion());
434 void VVideoLiveTV::doChanUp()
436 channelChange(OFFSET, UP);
437 osdChannelIndex = currentChannelIndex;
440 boxstack->update(this, osd.getRegion());
443 void VVideoLiveTV::doChanDown()
445 channelChange(OFFSET, DOWN);
446 osdChannelIndex = currentChannelIndex;
449 boxstack->update(this, osd.getRegion());
452 void VVideoLiveTV::doKey(int command)
456 for (i = keying - 1; i >= 0; i--) keyingInput[i+1] = keyingInput[i];
457 keyingInput[0] = command;
460 char keyingString[numberWidth+1];
461 for (i = 0; i < numberWidth; i++) keyingString[i] = '_';
462 keyingString[numberWidth] = '\0';
464 for (i = 0; i < keying; i++) keyingString[i] = keyingInput[keying - 1 - i] + 48;
466 if (keying == numberWidth)
469 for(i = keying - 1; i >= 0; i--) newChannel += keyingInput[i] * (ULONG)pow(10, i);
471 channelChange(NUMBER, newChannel);
472 osdChannelIndex = currentChannelIndex;
475 boxstack->update(this, osd.getRegion());
479 osdChanNum.setText(keyingString);
481 boxstack->update(this, osd.getRegion());
485 bool VVideoLiveTV::channelChange(UCHAR changeType, UINT newData)
489 if (changeType == INDEX)
491 newChannel = newData;
493 else if (changeType == NUMBER)
496 for(i = 0; i < chanList->size(); i++)
498 if ((*chanList)[i]->number == (UINT)newData)
505 if (i == chanList->size())
511 else if (changeType == OFFSET)
513 if (newData == UP) newChannel = upChannel(currentChannelIndex);
514 else newChannel = downChannel(currentChannelIndex);
516 else if (changeType == PREVIOUS)
518 newChannel = previousChannelIndex;
522 return false; // bad input
525 if (newChannel == currentChannelIndex) return true;
527 previousChannelIndex = currentChannelIndex;
528 currentChannelIndex = newChannel;
530 Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Set player to channel %u", currentChannelIndex);
533 // player->setChannel(currentChannelIndex);
536 void VVideoLiveTV::processMessage(Message* m)
538 if (m->message == Message::MOUSE_LBDOWN)
540 BoxStack::getInstance()->handleCommand(Remote::OK); //simulate rok press
542 else if (m->message == Message::CHANNEL_CHANGE)
544 channelChange(NUMBER, m->parameter);
546 else if (m->message == Message::EPG_CLOSE)
548 video->setMode(videoMode);
550 else if (m->message == Message::AUDIO_CHANGE_CHANNEL)
552 Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change audio channel to %i", m->parameter);
553 // ((Player*)player)->setAudioChannel(m->parameter);
555 else if (m->message == Message::PLAYER_EVENT)
560 case Player::CONNECTION_LOST: // connection lost detected
562 Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received connection lost from player");
563 // I can't handle this, send it to command
564 Message* m2 = new Message();
565 m2->to = Command::getInstance();
566 m2->message = Message::CONNECTION_LOST;
567 Command::getInstance()->postMessageNoLock(m2);
570 case Player::STREAM_END:
572 // I can't handle this, send it to command - improve this
573 Message* m2 = new Message(); // Must be done after this thread finishes, and must break into master mutex
574 m2->to = Command::getInstance();
575 m2->message = Message::STREAM_END;
576 Command::getInstance()->postMessageNoLock(m2);
579 case Player::ASPECT43:
583 Log::getInstance()->log("VVideoRec", Log::DEBUG, "Received do WSS 43");
586 BoxStack::getInstance()->update(this, &wssRegion);
590 case Player::ASPECT169:
594 Log::getInstance()->log("VVideoRec", Log::DEBUG, "Received do WSS 169");
597 BoxStack::getInstance()->update(this, &wssRegion);
606 UINT VVideoLiveTV::upChannel(UINT index)
608 if (index == (chanList->size() - 1)) // at the end
609 return 0; // so go to start
614 UINT VVideoLiveTV::downChannel(UINT index)
616 if (index == 0) // at the start
617 return chanList->size() - 1; // so go to end
622 void VVideoLiveTV::toggleChopSides()
624 if (video->getTVsize() == Video::ASPECT16X9) return; // Means nothing for 16:9 TVs
626 if (videoMode == Video::NORMAL)
628 videoMode = Video::LETTERBOX;
629 video->setMode(Video::LETTERBOX);
633 videoMode = Video::NORMAL;
634 video->setMode(Video::NORMAL);