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