]> git.vomp.tv Git - vompclient.git/blob - vvideolive.cc
Half way to saying no such channel if there isnt.
[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   epgmode=false;
37   videoMode = Video::getInstance()->getMode();
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     case Remote::PAUSE:
76     {
77       if (!unavailable) player->resyncAudio(); // do resync2
78       return 2;
79     }
80
81     case Remote::STOP:
82     case Remote::BACK:
83     case Remote::MENU:
84     {
85       if (unavailable) showUnavailable(0);
86       else stop();
87       return 4;
88     }
89     // Take up and down from new remote and do live banner
90     case Remote::UP:
91     case Remote::DOWN:
92     {
93       doBanner(true);
94       return 2;
95     }
96     case Remote::DF_UP:
97     case Remote::CHANNELUP:
98     {
99       if (unavailable) showUnavailable(0);
100       else stop();
101       channelChange(OFFSET, UP);
102       return 2;
103     }
104     case Remote::DF_DOWN:
105     case Remote::CHANNELDOWN:
106     {
107       if (unavailable) showUnavailable(0);
108       else stop();
109       channelChange(OFFSET, DOWN);
110       return 2;
111     }
112     case Remote::PREVCHANNEL:
113     {
114       if (unavailable) showUnavailable(0);
115       else stop();
116       channelChange(PREVIOUS, 0);
117       return 2;
118     }
119     case Remote::OK:
120     {
121       doBanner(true);
122       return 2;
123     }
124     case Remote::GUIDE:
125     case Remote::RED:
126     {
127       if (!epgmode)
128       {
129         showEPG();
130       }
131       epgmode=!epgmode;
132       return 2;
133     }
134
135     case Remote::ZERO ... Remote::NINE:
136     {
137       VChannelSelect* v = new VChannelSelect(this, command);
138       v->draw();
139       viewman->add(v);
140       viewman->updateView(v);
141     }
142   }
143
144   return 1;
145 }
146
147 void VVideoLive::channelChange(UCHAR changeType, UINT newData)
148 {
149   UINT newChannel = 0;
150
151   if (changeType == INDEX)
152   {
153     newChannel = newData;
154   }
155   else if (changeType == NUMBER)
156   {
157     UINT i;
158     for(i = 0; i < chanList->size(); i++)
159     {
160       if ((*chanList)[i]->number == (UINT)newData)
161       {
162         newChannel = i;
163         break;
164       }
165     }
166
167     if (i == chanList->size())
168     {
169       doNoSuchChannel();
170       return;
171     }
172   }
173   else if (changeType == OFFSET)
174   {
175     if (newData == UP) newChannel = upChannel();
176     else newChannel = downChannel();
177   }
178   else if (changeType == PREVIOUS)
179   {
180     newChannel = previousChannel;
181   }
182   else
183   {
184     return; // bad input!
185   }
186
187   previousChannel = currentChannel;
188   currentChannel = newChannel;
189
190   if (unavailable) showUnavailable(0);
191   else stop(1);
192   if(epgmode)
193     if(vepg)
194       vepg->setCurrentChannel((*chanList)[currentChannel]->name);
195   play();
196 }
197
198 void VVideoLive::processMessage(Message* m)
199 {
200   if (m->message == Message::CHANNEL_CHANGE)
201   {
202     channelChange(NUMBER, m->parameter);
203   }
204   else if (m->message == Message::CHANNEL_UP)
205   {
206     // this message is from vlivebanner
207     channelChange(OFFSET, UP);
208     if(!epgmode)
209     {
210       VLiveBanner* vlb = VLiveBanner::getInstance(); // guaranteed to be one
211       vlb->setChannel((*chanList)[currentChannel]);
212       vlb->draw();
213       viewman->updateView(vlb);
214     }
215   }
216   else if (m->message == Message::CHANNEL_DOWN)
217   {
218     // this message is from vlivebanner
219     channelChange(OFFSET, DOWN);
220     if(!epgmode)
221     {
222       VLiveBanner* vlb = VLiveBanner::getInstance(); // guaranteed to be one
223       vlb->setChannel((*chanList)[currentChannel]);
224       vlb->draw();
225       viewman->updateView(vlb);
226     }
227   }
228   else if (m->message == Message::STREAM_END)
229   {
230     Log::getInstance()->log("VVideoLive", Log::DEBUG, "streamEnd");
231     stop();
232     showUnavailable(1);
233   }
234   else if (m->message == Message::EPG)
235   {
236     Log::getInstance()->log("VVideoLive", Log::DEBUG, "EPG requested from live banner");
237
238     if (!epgmode)
239     {
240       showEPG();
241       epgmode=!epgmode; // shouldn't this be within the braces? // same for above in handleCommand, ask Brian FIXME
242     }
243   }
244 }
245
246 void VVideoLive::doBanner(bool bannerTakesCommands)
247 {
248   if(epgmode)
249     return;
250
251   if (VLiveBanner::getInstance()) return; // there already is one
252
253   VLiveBanner* vlb = new VLiveBanner(this, (*chanList)[currentChannel], bannerTakesCommands);
254
255   Message* m = new Message();
256   m->from = this;
257   m->to = viewman;
258   m->message = Message::ADD_VIEW;
259   m->parameter = (ULONG)vlb;
260
261   viewman->postMessage(m);
262 }
263
264 void VVideoLive::doNoSuchChannel()
265 {
266   Log::getInstance()->log("VVideoLive", Log::ERR, "No such channel");
267   // FIXME do gui for this
268 }
269
270 void VVideoLive::showUnavailable(int active)
271 {
272   if (active == unavailable) return;
273
274   if (active)
275   {
276     unavailable = 1;
277
278     unavailableView = new VInfo();
279     unavailableView->create(400, 200);
280     if (Video::getInstance()->getFormat() == Video::PAL)
281     {
282       unavailableView->setScreenPos(170, 200);
283     }
284     else
285     {
286       unavailableView->setScreenPos(160, 150);
287     }
288     unavailableView->setTitleText((*chanList)[currentChannel]->name);
289     unavailableView->setOneLiner(tr("Channel unavailable"));
290     unavailableView->setDropThrough();
291
292     Message* m = new Message();
293     m->from = this;
294     m->to = viewman;
295     m->message = Message::ADD_VIEW;
296     m->parameter = (ULONG)unavailableView;
297
298     viewman->postMessage(m);
299   }
300   else
301   {
302     unavailable = 0;
303     viewman->removeView(unavailableView);
304     unavailableView = NULL;
305   }
306 }
307
308 void VVideoLive::play(int noShowVLB)
309 {
310   showUnavailable(0);
311
312   int available = vdr->streamChannel((*chanList)[currentChannel]->number);
313
314   if (!available)
315   {
316     showUnavailable(1);
317     if (!noShowVLB) doBanner(false);
318   }
319   else
320   {
321     if (!noShowVLB) doBanner(false);
322     player->play();
323   }
324 }
325
326 void VVideoLive::stop(int noRemoveVLB)
327 {
328   if (unavailable) return;
329   if (!noRemoveVLB && VLiveBanner::getInstance()) viewman->removeView(VLiveBanner::getInstance()); // if live banner is present, remove it. won't cause damage if its not present
330
331   player->stop();
332   Log::getInstance()->log("VVideoLive", Log::DEBUG, "Delay starts here due to time taken by plugin to stop");
333   vdr->stopStreaming();
334   Log::getInstance()->log("VVideoLive", Log::DEBUG, "Delay ends here due to time taken by plugin to stop");
335 }
336
337 UINT VVideoLive::upChannel()
338 {
339   if (currentChannel == (chanList->size() - 1)) // at the end
340     return 0; // so go to start
341   else
342     return currentChannel + 1;
343 }
344
345 UINT VVideoLive::downChannel()
346 {
347   if (currentChannel == 0) // at the start
348     return chanList->size() - 1; // so go to end
349   else
350     return currentChannel - 1;
351 }
352
353 void VVideoLive::showEPG()
354 {
355   if (unavailable) showUnavailable(0);
356
357   Video::getInstance()->setMode(Video::QUARTER);
358   Video::getInstance()->setPosition(170, 5); //TODO need to deal with 4:3 switching
359
360   vepg = new VEpg(this, currentChannel);
361   vepg->draw();
362
363   viewman->add(vepg);
364   viewman->updateView(vepg);
365 }
366
367 void VVideoLive::setEpgMode(bool mode)
368 {
369   epgmode = mode;
370
371   // Ok so we do need this function
372   // but FIXME improve this, integrate with live mode switching from remote
373   if (mode == FALSE)
374   {
375     Video::getInstance()->setMode(videoMode);
376   }
377 }