]> git.vomp.tv Git - vompclient.git/blob - vvideolive.cc
EPG & vvideolive clean up (inc new bugs!)
[vompclient.git] / vvideolive.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 "vvideolive.h"
22
23 VVideoLive* VVideoLive::instance = NULL;
24
25 VVideoLive::VVideoLive(ChannelList* tchanList, ULONG tstreamType)
26 {
27   instance = this;
28   vdr = VDR::getInstance();
29   viewman = ViewMan::getInstance();
30   chanList = tchanList;
31   currentChannel = 0;
32   previousChannel = 0;
33   unavailable = 0;
34   unavailableView = NULL;
35   streamType = tstreamType;
36   vlb = (VLiveBanner*)1; // Can't be NULL because then that is sent to ViewMan::remove and it takes the top view off .. FIXME!
37   epgmode=false;
38   if (streamType == VDR::RADIO) player = new PlayerVideo(Command::getInstance(), 0, 1);
39   else                          player = new PlayerVideo(Command::getInstance(), 0, 0);
40
41   player->init();
42
43   Video* video = Video::getInstance();
44   create(video->getScreenWidth(), video->getScreenHeight());
45   Colour transparent(0, 0, 0, 0);
46   setBackgroundColour(transparent);
47 }
48
49 VVideoLive::~VVideoLive()
50 {
51   delete player;
52   instance = NULL;
53   Video::getInstance()->setDefaultAspect();
54 }
55
56 VVideoLive* VVideoLive::getInstance()
57 {
58   return instance;
59 }
60
61 void VVideoLive::draw()
62 {
63   View::draw();
64 }
65
66 int VVideoLive::handleCommand(int command)
67 {
68   switch(command)
69   {
70     case Remote::PLAY:
71     {
72       if (!unavailable) player->play(); // do resync
73       return 2;
74     }
75
76     case Remote::STOP:
77     case Remote::BACK:
78     case Remote::MENU:
79     {
80       if (unavailable) showUnavailable(0);
81       else stop();
82       return 4;
83     }
84     case Remote::DF_UP:
85     case Remote::CHANNELUP:
86     {
87       if (unavailable) showUnavailable(0);
88       else stop();
89       channelChange(OFFSET, UP);
90       return 2;
91     }
92     case Remote::DF_DOWN:
93     case Remote::CHANNELDOWN:
94     {
95       if (unavailable) showUnavailable(0);
96       else stop();
97       channelChange(OFFSET, DOWN);
98       return 2;
99     }
100     case Remote::OK:
101     {
102       doBanner(true);
103       return 2;
104     }
105     case Remote::GUIDE:
106     case Remote::RED:
107     {
108       if (!epgmode)
109       {
110         showEPG();
111       }
112       epgmode=!epgmode;
113       return 2;
114     }
115
116     case Remote::ZERO ... Remote::NINE:
117     {
118       VChannelSelect* v = new VChannelSelect(this, command);
119       viewman->addNoLock(v);
120 //      ViewMan::getInstance()->timedDelete(v, 4, 0);
121       v->draw();
122       v->show();
123     }
124   }
125
126   return 1;
127 }
128
129 void VVideoLive::channelChange(UCHAR changeType, UINT newData)
130 {
131   UINT newChannel = 0;
132
133   if (changeType == INDEX)
134   {
135     newChannel = newData;
136   }
137   else if (changeType == NUMBER)
138   {
139     newChannel = channelIndexFromNumber(newData);
140   }
141   else if (changeType == OFFSET)
142   {
143     if (newData == UP) newChannel = upChannel();
144     else newChannel = downChannel();
145   }
146   else if (changeType == PREVIOUS)
147   {
148     newChannel = previousChannel;
149   }
150   else
151   {
152     return; // bad input!
153   }
154
155   previousChannel = currentChannel;
156   currentChannel = newChannel;
157
158   if (unavailable) showUnavailable(0);
159   else stop(1);
160   if(epgmode)
161     if(vepg)
162       vepg->setCurrentChannel((*chanList)[currentChannel]->name);
163   play();
164 }
165
166 void VVideoLive::processMessage(Message* m)
167 {
168   if (m->message == Message::CHANNEL_CHANGE)
169   {
170     channelChange(NUMBER, m->parameter);
171   }
172   else if (m->message == Message::CHANNEL_UP)
173   {
174     // this message is from vlivebanner
175     channelChange(OFFSET, UP);
176     if(!epgmode)
177     {
178       vlb->setChannel((*chanList)[currentChannel]);
179       vlb->draw();
180       vlb->show();
181     }
182   }
183   else if (m->message == Message::CHANNEL_DOWN)
184   {
185     // this message is from vlivebanner
186     channelChange(OFFSET, DOWN);
187     if(!epgmode)
188     {
189       vlb->setChannel((*chanList)[currentChannel]);
190       vlb->draw();
191       vlb->show();
192     }
193   }
194   else if (m->message == Message::STREAM_END)
195   {
196     Log::getInstance()->log("VVideoLive", Log::DEBUG, "streamEnd");
197     stop();
198     play(1);
199   }
200 }
201
202 void VVideoLive::doBanner(bool bannerTakesCommands)
203 {
204   if(epgmode)
205     return;
206   vlb = new VLiveBanner(this, (*chanList)[currentChannel], bannerTakesCommands);
207   viewman->timedDelete(vlb, 4, 0);
208
209   Message* m = new Message();
210   m->from = this;
211   m->to = viewman;
212   m->message = Message::ADD_VIEW;
213   m->parameter = (ULONG)vlb;
214
215   viewman->postMessage(m);
216 }
217
218 void VVideoLive::showUnavailable(int active)
219 {
220   if (active == unavailable) return;
221
222   if (active)
223   {
224     unavailable = 1;
225
226     unavailableView = new VInfo();
227     unavailableView->create(400, 200);
228     if (Video::getInstance()->getFormat() == Video::PAL)
229     {
230       unavailableView->setScreenPos(170, 200);
231     }
232     else
233     {
234       unavailableView->setScreenPos(160, 150);
235     }
236     unavailableView->setTitleText((*chanList)[currentChannel]->name);
237     unavailableView->setOneLiner(tr("Channel unavailable"));
238     unavailableView->setDropThrough();
239
240     Message* m = new Message();
241     m->from = this;
242     m->to = viewman;
243     m->message = Message::ADD_VIEW;
244     m->parameter = (ULONG)unavailableView;
245
246     viewman->postMessage(m);
247   }
248   else
249   {
250     unavailable = 0;
251     ViewMan::getInstance()->removeView(unavailableView, 1);
252     unavailableView = NULL;
253   }
254 }
255
256 void VVideoLive::play(int noShowVLB)
257 {
258   showUnavailable(0);
259
260   int available = vdr->streamChannel((*chanList)[currentChannel]->number);
261
262   if (!available)
263   {
264     showUnavailable(1);
265     if (!noShowVLB) doBanner(false);
266   }
267   else
268   {
269     if (!noShowVLB) doBanner(false);
270     player->play();
271   }
272 }
273
274 void VVideoLive::stop(int noRemoveVLB)
275 {
276 printf("1\n");
277   if (unavailable) return;
278 printf("2\n");
279   if (!noRemoveVLB) viewman->removeView(vlb, 1); // if live banner is present, remove it. won't cause damage if its not present
280 printf("3\n");
281
282   player->stop();
283 printf("4\n");
284   vdr->stopStreaming();
285 printf("5\n");
286 }
287
288 UINT VVideoLive::upChannel()
289 {
290   if (currentChannel == (chanList->size() - 1)) // at the end
291     return 0; // so go to start
292   else
293     return currentChannel + 1;
294 }
295
296 UINT VVideoLive::downChannel()
297 {
298   if (currentChannel == 0) // at the start
299     return chanList->size() - 1; // so go to end
300   else
301     return currentChannel - 1;
302 }
303
304 UINT VVideoLive::channelIndexFromNumber(int number)
305 {
306   for(UINT i = 0; i < chanList->size(); i++)
307   {
308     if ((*chanList)[i]->number == (UINT)number) return i;
309   }
310   return 0;
311 }
312
313 UINT VVideoLive::getCurrentChannelIndex()
314 {
315   return channelIndexFromNumber(currentChannel);
316 }
317
318 void VVideoLive::showEPG()
319 {
320   if (unavailable) showUnavailable(0);
321   vepg = new VEpg(this, currentChannel);
322   ViewMan::getInstance()->addNoLock(vepg);
323   Video::getInstance()->setMode(Video::QUARTER);
324   Video::getInstance()->setPosition(170, 5); //TODO need to deal with 4:3 switching
325   vepg->draw();
326   vepg->show();
327 }
328
329 void VVideoLive::setEpgMode(bool mode)
330 {
331   epgmode = mode;
332 }
333