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