]> git.vomp.tv Git - vompclient.git/blob - vaudioselector.cc
Fix for possible crash when removing bar
[vompclient.git] / vaudioselector.cc
1 /*
2     Copyright 2006 Chris Tallon, Marten Richter
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 "vaudioselector.h"
22
23 VAudioSelector::VAudioSelector(void* tparent,bool* availableMpegAudioChannels,
24         bool* availableAc3AudioChannels,
25         int currentAudioChannel, RecInfo* recInfo)
26 {
27   Log::getInstance()->log("VAS", Log::DEBUG, "%i", currentAudioChannel);
28
29   parent = tparent;
30
31   create(200, 120);
32
33 //  setTitleText(tr("Audio"));
34 //  setTitleBarOn(1);
35 //  setTitleBarColour(Colour::TITLEBARBACKGROUND);
36
37   sl.setSurface(surface);
38   sl.setSurfaceOffset(40, 30);
39   sl.setDimensions(area.w - 45, area.h - 30);
40
41   // Load data from availableAudioChannels, currentAudioChannel and recInfo
42
43   int i;
44
45   for (i = 0; i < PES_AUDIO_MAXCHANNELS; i++)
46   {
47     if (availableMpegAudioChannels[i])
48     {
49       AudioChannel* ac = new AudioChannel();
50       ac->type = 0;
51       ac->name = NULL;
52       ac->pestype = PES_AUDIO_START + i;
53       acl.push_back(ac);
54     }
55   }
56   if (availableAc3AudioChannels != NULL)
57   {
58     for (i = 0; i < PES_AUDIO_AC3_MAXCHANNELS; i++)
59     {
60       if (availableAc3AudioChannels[i])
61       {
62         AudioChannel* ac = new AudioChannel();
63         ac->type = 1;//ac3
64         ac->name = NULL;
65         ac->pestype = PES_AUDIO_AC3_START + i;
66         acl.push_back(ac);
67       }
68     }
69   }
70
71   unsigned char numchan_recinfo = recInfo->numComponents;
72   unsigned char numchan_siz = acl.size();
73   int mp_audcounter = 0;
74   int ac3_counter = 0;
75   int ac3_offset = 0;
76
77   for (i = 0; i < numchan_siz; i++)
78   {
79     AudioChannel* ac = acl[i];
80     if (ac)
81     {
82       if (ac->type==0)
83       {
84         ac3_offset++;
85       }
86     }
87   }
88
89   unsigned char type;
90   char* lang;
91   char* description;
92   int type_int;
93
94   for (i = 0; i < numchan_recinfo; i++)
95   {
96     if (recInfo->streams[i] != 2) continue; //not an audio component
97     type = recInfo->types[i];
98     lang = recInfo->languages[i];
99     description = recInfo->descriptions[i];
100     AudioChannel* ac = NULL;
101     type_int = 0;
102
103     switch (type)
104     {
105       case 1: //mpaudio mono
106       case 3: //mpaudio stereo
107         if (mp_audcounter < numchan_siz) ac = acl[mp_audcounter];
108         type_int = 0;
109         break;
110       case 5: //ac3
111         if (ac3_counter + ac3_offset < numchan_siz) ac = acl[ac3_counter + ac3_offset];
112         type_int = 1;
113         break;
114     }
115
116     if (ac)
117     {
118       if (ac->type == type_int)
119       {
120         if (description && (strlen(description) > 0))
121         {
122           ac->name = new char[strlen(description)+1];
123           strcpy(ac->name, description);
124         }
125         else if (lang && (strlen(lang) > 0))
126         {
127           ac->name = new char[strlen(lang)+1];
128           strcpy(ac->name, lang);
129         }
130       }
131     }
132
133     switch (type_int)
134     {
135       case 0: //mpaudio
136         mp_audcounter++;
137         break;
138       case 1: //ac3
139         ac3_counter++;
140         break;
141     }
142   }
143
144   // Now do display
145
146   char tempString[300];
147   int audioChannelListSize = acl.size();
148
149   if (audioChannelListSize)
150   {
151     for(i = 0; i < audioChannelListSize; i++)
152     {
153       AudioChannel* ac = acl[i];
154
155       if (ac->name)
156       {
157         sl.addOption(ac->name, (ULONG)ac, (ac->pestype == currentAudioChannel));
158       }
159       else
160       {
161         if (ac->type==0)
162         {
163           SNPRINTF(tempString, 299, "%lu", (ULONG)(ac->pestype - PES_AUDIO_START));
164         }
165         else if (ac->type==1)
166         {
167           SNPRINTF(tempString, 299, "ac3 %lu", (ULONG)(ac->pestype - PES_AUDIO_AC3_START));
168         }
169         else
170         {
171           SNPRINTF(tempString, 299, "unknown");
172         }
173         sl.addOption(tempString, (ULONG)ac, (ac->pestype == currentAudioChannel));
174       }
175     }
176   }
177   else
178   {
179     sl.addOption(tr("No audio channel data available"), 0, 1);
180   }
181 }
182
183 VAudioSelector::~VAudioSelector()
184 {
185   int audioChannelListSize = acl.size();
186   for(int i = 0; i < audioChannelListSize; i++)
187   {
188     delete acl[i];
189   }
190   acl.clear();
191
192   sl.clear();
193
194   Message* m = new Message();
195   m->from = this;
196   m->to = parent;
197   m->message = Message::CHILD_CLOSE;
198   Command::getInstance()->postMessageNoLock(m);
199 }
200
201 void VAudioSelector::draw()
202 {
203   View::draw();
204   rectangle(0, 0, area.w, 30, Colour::TITLEBARBACKGROUND);
205   drawText(tr("Audio"), 45, 5, Colour::LIGHTTEXT);
206
207   sl.setBackgroundColour(backgroundColour);
208   sl.draw();
209 }
210
211 int VAudioSelector::handleCommand(int command)
212 {
213   switch (command)
214   {
215     case Remote::BACK:
216     case Remote::OK:
217     case Remote::GREEN:
218     {
219       return 4;
220     }
221     case Remote::DF_UP:
222     case Remote::UP:
223     {
224       sl.up();
225       sl.draw();
226
227       ViewMan::getInstance()->updateView(this);
228
229       Message* m = new Message();
230       m->from = this;
231       m->to = parent;
232       m->message = Message::AUDIO_CHANGE_CHANNEL;
233       m->parameter = ((AudioChannel*)sl.getCurrentOptionData())->pestype;
234       Command::getInstance()->postMessageNoLock(m);
235
236       return 2;
237     }
238     case Remote::DF_DOWN:
239     case Remote::DOWN:
240     {
241       sl.down();
242       sl.draw();
243
244       ViewMan::getInstance()->updateView(this);
245
246       Message* m = new Message();
247       m->from = this;
248       m->to = parent;
249       m->message = Message::AUDIO_CHANGE_CHANNEL;
250       m->parameter = ((AudioChannel*)sl.getCurrentOptionData())->pestype;
251       Command::getInstance()->postMessageNoLock(m);
252
253       return 2;
254     }
255   }
256
257   return 0;
258 }
259
260 void VAudioSelector::processMessage(Message* m)
261 {
262   if (m->message == Message::MOUSE_MOVE)
263   {
264     if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
265     {
266       sl.draw();
267       ViewMan::getInstance()->updateView(this);
268     }
269   }
270   else if (m->message == Message::MOUSE_LBDOWN)
271   {
272     if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
273     {
274       ViewMan::getInstance()->handleCommand(Remote::OK); //simulate OK press
275     }
276     else
277     { //check if press is outside this view! then simulate cancel
278       int x=(m->parameter>>16)-getScreenX();
279       int y=(m->parameter&0xFFFF)-getScreenY();
280       if (x<0 || y <0 || x>getWidth() || y>getHeight())
281       {
282         ViewMan::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
283       }
284     }
285   }
286 }