]> git.vomp.tv Git - vompclient.git/blob - vvideolive.cc
New timers code
[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->add(v);
120       v->draw();
121       v->show();
122     }
123   }
124
125   return 1;
126 }
127
128 void VVideoLive::channelChange(UCHAR changeType, UINT newData)
129 {
130   UINT newChannel = 0;
131
132   if (changeType == INDEX)
133   {
134     newChannel = newData;
135   }
136   else if (changeType == NUMBER)
137   {
138     newChannel = channelIndexFromNumber(newData);
139   }
140   else if (changeType == OFFSET)
141   {
142     if (newData == UP) newChannel = upChannel();
143     else newChannel = downChannel();
144   }
145   else if (changeType == PREVIOUS)
146   {
147     newChannel = previousChannel;
148   }
149   else
150   {
151     return; // bad input!
152   }
153
154   previousChannel = currentChannel;
155   currentChannel = newChannel;
156
157   if (unavailable) showUnavailable(0);
158   else stop(1);
159   if(epgmode)
160     if(vepg)
161       vepg->setCurrentChannel((*chanList)[currentChannel]->name);
162   play();
163 }
164
165 void VVideoLive::processMessage(Message* m)
166 {
167   if (m->message == Message::CHANNEL_CHANGE)
168   {
169     channelChange(NUMBER, m->parameter);
170   }
171   else if (m->message == Message::CHANNEL_UP)
172   {
173     // this message is from vlivebanner
174     channelChange(OFFSET, UP);
175     if(!epgmode)
176     {
177       vlb->setChannel((*chanList)[currentChannel]);
178       vlb->draw();
179       vlb->show();
180     }
181   }
182   else if (m->message == Message::CHANNEL_DOWN)
183   {
184     // this message is from vlivebanner
185     channelChange(OFFSET, DOWN);
186     if(!epgmode)
187     {
188       vlb->setChannel((*chanList)[currentChannel]);
189       vlb->draw();
190       vlb->show();
191     }
192   }
193   else if (m->message == Message::STREAM_END)
194   {
195     Log::getInstance()->log("VVideoLive", Log::DEBUG, "streamEnd");
196     stop();
197     play(1);
198   }
199 }
200
201 void VVideoLive::doBanner(bool bannerTakesCommands)
202 {
203   if(epgmode)
204     return;
205   vlb = new VLiveBanner(this, (*chanList)[currentChannel], bannerTakesCommands);
206
207   Message* m = new Message();
208   m->from = this;
209   m->to = viewman;
210   m->message = Message::ADD_VIEW;
211   m->parameter = (ULONG)vlb;
212
213   viewman->postMessage(m);
214 }
215
216 void VVideoLive::showUnavailable(int active)
217 {
218   if (active == unavailable) return;
219
220   if (active)
221   {
222     unavailable = 1;
223
224     unavailableView = new VInfo();
225     unavailableView->create(400, 200);
226     if (Video::getInstance()->getFormat() == Video::PAL)
227     {
228       unavailableView->setScreenPos(170, 200);
229     }
230     else
231     {
232       unavailableView->setScreenPos(160, 150);
233     }
234     unavailableView->setTitleText((*chanList)[currentChannel]->name);
235     unavailableView->setOneLiner(tr("Channel unavailable"));
236     unavailableView->setDropThrough();
237
238     Message* m = new Message();
239     m->from = this;
240     m->to = viewman;
241     m->message = Message::ADD_VIEW;
242     m->parameter = (ULONG)unavailableView;
243
244     viewman->postMessage(m);
245   }
246   else
247   {
248     unavailable = 0;
249     ViewMan::getInstance()->removeView(unavailableView);
250     unavailableView = NULL;
251   }
252 }
253
254 void VVideoLive::play(int noShowVLB)
255 {
256   showUnavailable(0);
257
258   int available = vdr->streamChannel((*chanList)[currentChannel]->number);
259
260   if (!available)
261   {
262     showUnavailable(1);
263     if (!noShowVLB) doBanner(false);
264   }
265   else
266   {
267     if (!noShowVLB) doBanner(false);
268     player->play();
269   }
270 }
271
272 void VVideoLive::stop(int noRemoveVLB)
273 {
274 printf("1\n");
275   if (unavailable) return;
276 printf("2\n");
277   if (!noRemoveVLB) viewman->removeView(vlb); // if live banner is present, remove it. won't cause damage if its not present
278 printf("3\n");
279
280   player->stop();
281 printf("4\n");
282   vdr->stopStreaming();
283 printf("5\n");
284 }
285
286 UINT VVideoLive::upChannel()
287 {
288   if (currentChannel == (chanList->size() - 1)) // at the end
289     return 0; // so go to start
290   else
291     return currentChannel + 1;
292 }
293
294 UINT VVideoLive::downChannel()
295 {
296   if (currentChannel == 0) // at the start
297     return chanList->size() - 1; // so go to end
298   else
299     return currentChannel - 1;
300 }
301
302 UINT VVideoLive::channelIndexFromNumber(int number)
303 {
304   for(UINT i = 0; i < chanList->size(); i++)
305   {
306     if ((*chanList)[i]->number == (UINT)number) return i;
307   }
308   return 0;
309 }
310
311 UINT VVideoLive::getCurrentChannelIndex()
312 {
313   return channelIndexFromNumber(currentChannel);
314 }
315
316 void VVideoLive::showEPG()
317 {
318   if (unavailable) showUnavailable(0);
319   vepg = new VEpg(this, currentChannel);
320   ViewMan::getInstance()->add(vepg);
321   Video::getInstance()->setMode(Video::QUARTER);
322   Video::getInstance()->setPosition(170, 5); //TODO need to deal with 4:3 switching
323   vepg->draw();
324   vepg->show();
325 }
326
327 void VVideoLive::setEpgMode(bool mode)
328 {
329   epgmode = mode;
330 }
331