]> git.sesse.net Git - vlc/blob - modules/gui/wxwidgets/extrapanel.cpp
playlist: Make sure we don't pl_Release(p_playlist).
[vlc] / modules / gui / wxwidgets / extrapanel.cpp
1 /*****************************************************************************
2  * extrapanel.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2004, 2003 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_aout.h>
33 #include <vlc_vout.h>
34 #include <vlc_interface.h>
35
36 #include <math.h>
37
38 #include "extrapanel.hpp"
39
40 /*****************************************************************************
41  * Local class declarations.
42  *****************************************************************************/
43
44 #define SMOOTH_TIP N_( "Controls the blending of equalizer bands. The higher" \
45             " this value is, the more correlated their movement will be." )
46
47 static int IntfBandsCallback( vlc_object_t *, char const *,
48                               vlc_value_t, vlc_value_t, void * );
49 static int IntfPreampCallback( vlc_object_t *, char const *,
50                                vlc_value_t, vlc_value_t, void * );
51 static void ChangeFiltersString( intf_thread_t *, aout_instance_t *,
52                                  char *, bool );
53 static void ChangeVFiltersString( intf_thread_t *, char *, bool );
54 static void ChangeVFilters2String( intf_thread_t *, char *, bool );
55
56 /* IDs for the controls and the menu commands */
57 enum
58 {
59     Notebook_Event,
60
61     Adjust_Event,
62     RestoreDefaults_Event,
63
64     Hue_Event,
65     Contrast_Event,
66     Brightness_Event,
67     Saturation_Event,
68     Gamma_Event,
69     Ratio_Event,
70
71     FiltersInfo_Event,
72
73     Filter0_Event, Filter1_Event, Filter2_Event, Filter3_Event, Filter4_Event,
74     Filter5_Event, Filter6_Event, Filter7_Event, Filter8_Event, Filter9_Event,
75
76     EqEnable_Event,
77     Eq2Pass_Event,
78     EqRestore_Event,
79
80     Smooth_Event,
81
82     Preamp_Event,
83
84     Band0_Event,Band1_Event,Band2_Event,Band3_Event,Band4_Event,
85     Band5_Event,Band6_Event,Band7_Event,Band8_Event,Band9_Event,
86
87     NormVol_Event, NVSlider_Event, HeadPhone_Event
88 };
89
90 BEGIN_EVENT_TABLE( ExtraPanel, wxPanel )
91     EVT_IDLE( ExtraPanel::OnIdle )
92
93     /* Equalizer */
94     EVT_CHECKBOX( EqEnable_Event, ExtraPanel::OnEnableEqualizer )
95     EVT_CHECKBOX( Eq2Pass_Event, ExtraPanel::OnEq2Pass )
96     EVT_BUTTON( EqRestore_Event, ExtraPanel::OnEqRestore )
97
98     EVT_COMMAND_SCROLL( Preamp_Event, ExtraPanel::OnPreamp )
99     EVT_COMMAND_SCROLL( Smooth_Event, ExtraPanel::OnEqSmooth )
100
101     EVT_COMMAND_SCROLL(Band0_Event, ExtraPanel::OnChangeEqualizer)
102     EVT_COMMAND_SCROLL(Band1_Event, ExtraPanel::OnChangeEqualizer)
103     EVT_COMMAND_SCROLL(Band2_Event, ExtraPanel::OnChangeEqualizer)
104     EVT_COMMAND_SCROLL(Band3_Event, ExtraPanel::OnChangeEqualizer)
105     EVT_COMMAND_SCROLL(Band4_Event, ExtraPanel::OnChangeEqualizer)
106     EVT_COMMAND_SCROLL(Band5_Event, ExtraPanel::OnChangeEqualizer)
107     EVT_COMMAND_SCROLL(Band6_Event, ExtraPanel::OnChangeEqualizer)
108     EVT_COMMAND_SCROLL(Band7_Event, ExtraPanel::OnChangeEqualizer)
109     EVT_COMMAND_SCROLL(Band8_Event, ExtraPanel::OnChangeEqualizer)
110     EVT_COMMAND_SCROLL(Band9_Event, ExtraPanel::OnChangeEqualizer)
111
112     /* Video */
113     EVT_CHECKBOX( Adjust_Event, ExtraPanel::OnEnableAdjust )
114     EVT_BUTTON( RestoreDefaults_Event, ExtraPanel::OnRestoreDefaults )
115
116     EVT_COMMAND_SCROLL(Hue_Event, ExtraPanel::OnAdjustUpdate)
117     EVT_COMMAND_SCROLL(Contrast_Event, ExtraPanel::OnAdjustUpdate)
118     EVT_COMMAND_SCROLL(Brightness_Event, ExtraPanel::OnAdjustUpdate)
119     EVT_COMMAND_SCROLL(Saturation_Event, ExtraPanel::OnAdjustUpdate)
120     EVT_COMMAND_SCROLL(Gamma_Event, ExtraPanel::OnAdjustUpdate)
121
122     EVT_BUTTON( FiltersInfo_Event, ExtraPanel::OnFiltersInfo )
123
124     EVT_CHECKBOX( Filter0_Event, ExtraPanel::OnSelectFilter )
125     EVT_CHECKBOX( Filter1_Event, ExtraPanel::OnSelectFilter )
126     EVT_CHECKBOX( Filter2_Event, ExtraPanel::OnSelectFilter )
127     EVT_CHECKBOX( Filter3_Event, ExtraPanel::OnSelectFilter )
128     EVT_CHECKBOX( Filter4_Event, ExtraPanel::OnSelectFilter )
129     EVT_CHECKBOX( Filter5_Event, ExtraPanel::OnSelectFilter )
130     EVT_CHECKBOX( Filter6_Event, ExtraPanel::OnSelectFilter )
131     EVT_CHECKBOX( Filter7_Event, ExtraPanel::OnSelectFilter )
132     EVT_CHECKBOX( Filter8_Event, ExtraPanel::OnSelectFilter )
133     EVT_CHECKBOX( Filter9_Event, ExtraPanel::OnSelectFilter )
134
135     /* Audio */
136     EVT_CHECKBOX( NormVol_Event, ExtraPanel::OnNormvol )
137     EVT_CHECKBOX( HeadPhone_Event, ExtraPanel::OnHeadphone )
138
139     EVT_COMMAND_SCROLL( NVSlider_Event, ExtraPanel::OnNormvolSlider )
140
141 END_EVENT_TABLE()
142
143 struct filter {
144     char *psz_filter;
145     char *psz_name;
146     char *psz_help;
147     bool  b_vfilter2;
148 };
149
150 static const struct filter vfilters[] =
151 {
152     { "clone", N_("Image clone"), N_("Creates several clones of the image"), false },
153     { "gradient", N_("Cartoon effect"), N_("Gradient effects (cartoon) on the image"), true },
154     { "invert", N_("Image inversion") , N_("Inverts the colors of the image"), true },
155     { "motionblur", N_("Blurring"), N_("Adds motion blurring to the image"), true },
156     { "ripple", N_("Water effect"), N_("Adds water effect to the image"), true },
157     { "wave", N_("Wave effect"), N_("Adds wave effect to the image"), true },
158     { "transform",  N_("Transformation"), N_("Rotates or flips the image"), false },
159     { "magnify",  N_("Magnify"), N_("Magnifies part of the image"), false },
160     { "puzzle",  N_("Puzzle"), N_("Turns the image into a puzzle"), false },
161     { NULL, NULL, NULL } /* Do not remove this line */
162 };
163
164 /*****************************************************************************
165  * Constructor.
166  *****************************************************************************/
167 ExtraPanel::ExtraPanel( intf_thread_t *_p_intf, wxWindow *_p_parent ):
168         wxPanel( _p_parent , -1, wxDefaultPosition, wxDefaultSize )
169 {
170
171     p_intf = _p_intf;
172     p_parent = _p_parent;
173     SetAutoLayout( TRUE );
174
175     wxBoxSizer *extra_sizer = new wxBoxSizer( wxHORIZONTAL );
176
177     notebook = new wxNotebook( this, Notebook_Event );
178
179 #if (!wxCHECK_VERSION(2,5,2))
180     wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
181 #endif
182
183     notebook->AddPage( VideoPanel( notebook ), wxU(_("Video")) );
184     notebook->AddPage( EqzPanel( notebook ), wxU(_("Equalizer")) );
185     notebook->AddPage( AudioPanel( notebook ), wxU(_("Audio")) );
186
187 #if (!wxCHECK_VERSION(2,5,2))
188     extra_sizer->Add( notebook_sizer, 1, wxEXPAND, 0 );
189 #else
190     extra_sizer->Add( notebook, 1, wxEXPAND, 0 );
191 #endif
192
193     SetSizerAndFit( extra_sizer );
194     extra_sizer->Layout();
195 }
196
197 ExtraPanel::~ExtraPanel()
198 {
199 }
200
201 /* Video Panel constructor */
202 wxPanel *ExtraPanel::VideoPanel( wxWindow *parent )
203 {
204     char *psz_filters;
205
206     wxPanel *panel = new wxPanel( parent, -1 );
207     wxBoxSizer *panel_sizer = new wxBoxSizer( wxHORIZONTAL );
208
209     /* Create static box to surround the adjust controls */
210     wxStaticBox *adjust_box =
211            new wxStaticBox( panel, -1, wxU(_("Image adjustment" )) );
212     wxStaticBoxSizer *adjust_sizer =
213         new wxStaticBoxSizer( adjust_box, wxVERTICAL );
214     adjust_sizer->SetMinSize( -1, 50 );
215
216     /* Create flex grid */
217     wxFlexGridSizer *adjust_gridsizer =
218         new wxFlexGridSizer( 6, 2, 0, 0);
219     adjust_gridsizer->AddGrowableCol(1);
220
221     /* Create the adjust button */
222     wxCheckBox * adjust_check = new wxCheckBox( panel, Adjust_Event,
223                                                  wxU(_("Enable")));
224
225     /* Create the restore to defaults button */
226     restoredefaults_button =
227         new wxButton( panel, RestoreDefaults_Event,
228         wxU(_("Restore Defaults")), wxDefaultPosition);
229
230     wxStaticText *hue_text = new wxStaticText( panel, -1,
231                                        wxU(_("Hue")) );
232     hue_slider = new wxSlider ( panel, Hue_Event, 0, 0,
233                                 360, wxDefaultPosition, wxDefaultSize );
234
235     wxStaticText *contrast_text = new wxStaticText( panel, -1,
236                                        wxU(_("Contrast")) );
237     contrast_slider = new wxSlider ( panel, Contrast_Event, 0, 0,
238                                 200, wxDefaultPosition, wxDefaultSize);
239
240     wxStaticText *brightness_text = new wxStaticText( panel, -1,
241                                        wxU(_("Brightness")) );
242     brightness_slider = new wxSlider ( panel, Brightness_Event, 0, 0,
243                            200, wxDefaultPosition, wxDefaultSize) ;
244
245     wxStaticText *saturation_text = new wxStaticText( panel, -1,
246                                           wxU(_("Saturation")) );
247     saturation_slider = new wxSlider ( panel, Saturation_Event, 0, 0,
248                            300, wxDefaultPosition, wxDefaultSize );
249
250     wxStaticText *gamma_text = new wxStaticText( panel, -1,
251                                           wxU(_("Gamma")) );
252     gamma_slider = new wxSlider ( panel, Gamma_Event, 0, 0,
253                            100, wxDefaultPosition, wxDefaultSize );
254
255     adjust_gridsizer->Add( adjust_check, 1, wxEXPAND|wxALL, 2 );
256     adjust_gridsizer->Add( restoredefaults_button, 1, wxEXPAND|wxALL, 2 );
257     adjust_gridsizer->Add( hue_text, 1, wxEXPAND|wxALL, 2 );
258     adjust_gridsizer->Add( hue_slider, 1, wxEXPAND|wxALL, 2 );
259     adjust_gridsizer->Add( contrast_text, 1, wxEXPAND|wxALL, 2 );
260     adjust_gridsizer->Add( contrast_slider, 1, wxEXPAND|wxALL, 2 );
261     adjust_gridsizer->Add( brightness_text, 1, wxEXPAND|wxALL, 2 );
262     adjust_gridsizer->Add( brightness_slider, 1, wxEXPAND|wxALL, 2 );
263     adjust_gridsizer->Add( saturation_text, 1, wxEXPAND|wxALL, 2 );
264     adjust_gridsizer->Add( saturation_slider, 1, wxEXPAND|wxALL, 2 );
265     adjust_gridsizer->Add( gamma_text, 1, wxEXPAND|wxALL, 2 );
266     adjust_gridsizer->Add( gamma_slider, 1, wxEXPAND|wxALL, 2 );
267
268     adjust_sizer->Add( adjust_gridsizer, 1, wxEXPAND|wxALL, 2);
269
270     panel_sizer->Add( adjust_sizer , 1, wxTOP, 2 );
271
272 #if 0
273     /* Create sizer to surround the other controls */
274     wxBoxSizer *other_sizer = new wxBoxSizer( wxVERTICAL );
275
276     wxStaticBox *video_box =
277             new wxStaticBox( panel, -1, wxU(_("Video Options")) );
278     /* Create the sizer for the frame */
279     wxStaticBoxSizer *video_sizer =
280        new wxStaticBoxSizer( video_box, wxVERTICAL );
281     video_sizer->SetMinSize( -1, 50 );
282
283     static const wxString ratio_array[] =
284     {
285         wxT("4:3"),
286         wxT("16:9"),
287     };
288
289     wxBoxSizer *ratio_sizer = new wxBoxSizer( wxHORIZONTAL );
290     wxStaticText *ratio_text = new wxStaticText( panel, -1,
291                                           wxU(_("Aspect Ratio")) );
292
293     ratio_combo = new wxComboBox( panel, Ratio_Event, wxT(""),
294                                   wxDefaultPosition, wxSize( 80 , -1),
295                                   WXSIZEOF(ratio_array), ratio_array,
296                                   0 );
297
298     ratio_sizer->Add( ratio_text, 0, wxALL, 2 );
299     ratio_sizer->Add( ratio_combo, 0, wxALL, 2 );
300     ratio_sizer->Layout();
301
302     video_sizer->Add( ratio_sizer  , 0 , wxALL , 2 );
303     video_sizer->Layout();
304 #endif
305
306     wxStaticBox *filter_box =
307                   new wxStaticBox( panel, -1, wxU(_("Video filters")) );
308     wxStaticBoxSizer *filter_sizer =
309                    new wxStaticBoxSizer( filter_box, wxHORIZONTAL );
310
311     wxBoxSizer *t_col_sizer = new wxBoxSizer( wxVERTICAL );
312
313
314     for( int i = 0 ; vfilters[i].psz_filter != NULL ; i++ )
315     {
316         wxCheckBox *box = new wxCheckBox( panel, Filter0_Event + i,
317                                           wxU( _( vfilters[i].psz_name ) ) );
318         t_col_sizer->Add( box, 0, wxALL, 2 );
319         box->SetToolTip( wxU( _( vfilters[i].psz_help ) ) );
320     }
321
322     filter_sizer->Add( t_col_sizer );
323     filter_sizer->Add( new wxButton( panel, FiltersInfo_Event,
324                             wxU(_("More Info" ) ) ), 0, wxALL, 4 );
325 #if 0
326     other_sizer->Add( video_sizer, 0, wxALL | wxEXPAND , 0);
327     other_sizer->Add( filter_sizer, 0, wxALL | wxEXPAND , 0);
328     other_sizer->Layout();
329     panel_sizer->Add(other_sizer , 1 );
330 #endif
331
332     panel_sizer->Add( filter_sizer, 1, wxTOP|wxLEFT, 2 );
333
334     panel->SetSizerAndFit( panel_sizer );
335
336     /* Layout the whole panel */
337     panel_sizer->Layout();
338
339     panel_sizer->SetSizeHints( panel );
340
341     /* Write down initial values */
342     psz_filters = config_GetPsz( p_intf, "vout-filter" );
343     if( psz_filters && strstr( psz_filters, "adjust" ) )
344     {
345         adjust_check->SetValue( 1 );
346         restoredefaults_button->Enable();
347         saturation_slider->Enable();
348         contrast_slider->Enable();
349         brightness_slider->Enable();
350         hue_slider->Enable();
351         gamma_slider->Enable();
352     }
353     else
354     {
355         adjust_check->SetValue( 0 );
356         restoredefaults_button->Disable();
357         saturation_slider->Disable();
358         contrast_slider->Disable();
359         brightness_slider->Disable();
360         hue_slider->Disable();
361         gamma_slider->Disable();
362     }
363     free( psz_filters );
364
365     int i_value = config_GetInt( p_intf, "hue" );
366     if( i_value > 0 && i_value < 360 )
367         hue_slider->SetValue( i_value );
368     float f_value;
369     f_value = config_GetFloat( p_intf, "saturation" );
370     if( f_value > 0 && f_value < 5 )
371         saturation_slider->SetValue( (int)(100 * f_value) );
372     f_value = config_GetFloat( p_intf, "contrast" );
373     if( f_value > 0 && f_value < 4 )
374         contrast_slider->SetValue( (int)(100 * f_value) );
375     f_value = config_GetFloat( p_intf, "brightness" );
376     if( f_value > 0 && f_value < 2 )
377         brightness_slider->SetValue( (int)(100 * f_value) );
378     f_value = config_GetFloat( p_intf, "gamma" );
379     if( f_value > 0 && f_value < 10 )
380         gamma_slider->SetValue( (int)(10 * f_value) );
381
382     b_update = false;
383
384     return panel;
385 }
386
387 /* Audio panel constructor */
388 wxPanel *ExtraPanel::AudioPanel( wxWindow *parent )
389 {
390     char *psz_filters;
391
392     wxPanel *panel = new wxPanel( parent, -1 );
393     wxBoxSizer *panel_sizer = new wxBoxSizer( wxHORIZONTAL );
394
395     /* Create static box to surround the adjust controls */
396     wxStaticBox *filter_box =
397            new wxStaticBox( panel, -1, wxU(_("Audio filters")) );
398     wxStaticBoxSizer *filter_sizer =
399         new wxStaticBoxSizer( filter_box, wxVERTICAL );
400     filter_sizer->SetMinSize( -1, 50 );
401
402     wxCheckBox * headphone_check = new wxCheckBox( panel, HeadPhone_Event,
403                                     wxU(_("Headphone virtualization")));
404     headphone_check->SetToolTip( wxU(_("Imitates the effect of "
405              "surround sound when using headphones." ) ) );
406
407     wxCheckBox * normvol_check = new wxCheckBox( panel, NormVol_Event,
408                                     wxU(_("Volume normalization")));
409     normvol_check->SetToolTip( wxU(_("Prevents the audio output "
410                          "level from going over a predefined value." ) ) );
411
412     wxStaticText *normvol_label = new wxStaticText( panel, -1,
413                                    wxU( _("Maximum level") ) );
414
415     wxSlider *normvol_slider = new wxSlider ( panel, NVSlider_Event, 20, 5,
416                            100, wxDefaultPosition, wxSize( 100, -1 ) );
417
418     filter_sizer->Add( headphone_check, 0, wxALL, 4 );
419     filter_sizer->Add( normvol_check, 0, wxALL, 4 );
420     filter_sizer->Add( normvol_label, 0, wxALL, 4 );
421     filter_sizer->Add( normvol_slider, 0, wxALL, 4 );
422
423     panel_sizer->Add( filter_sizer, 1, wxTOP, 2 );
424     panel->SetSizerAndFit( panel_sizer );
425     panel_sizer->Layout();
426     panel_sizer->SetSizeHints( panel );
427
428     /* Write down initial values */
429     psz_filters = config_GetPsz( p_intf, "audio-filter" );
430     if( psz_filters )
431     {
432         headphone_check->SetValue( strstr( psz_filters, "headphone" ) );
433         normvol_check->SetValue( strstr( psz_filters, "normvol" ) );
434         free( psz_filters );
435     }
436     else
437     {
438         headphone_check->SetValue( 0 );
439         normvol_check->SetValue( 0 );
440     }
441
442     return panel;
443 }
444
445
446 static const wxString band_frequencies[] =
447 {
448     wxT(" 60 Hz"),
449     wxT("170 Hz"),
450     wxT("310 Hz"),
451     wxT("600 Hz"),
452     wxT(" 1 kHz"),
453     wxT(" 3 kHz"),
454     wxT(" 6 kHz"),
455     wxT("12 kHz"),
456     wxT("14 kHz"),
457     wxT("16 kHz")
458 };
459
460 /* Equalizer Panel constructor */
461 wxPanel *ExtraPanel::EqzPanel( wxWindow *parent )
462 {
463     wxPanel *panel = new wxPanel( parent, -1 );
464     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
465
466     /* Create static box to surround the adjust controls */
467     wxBoxSizer *top_sizer =
468         new wxBoxSizer( wxHORIZONTAL );
469
470     /* Create the enable button */
471     eq_chkbox =  new wxCheckBox( panel, EqEnable_Event,
472                             wxU(_("Enable") ) );
473     eq_chkbox->SetToolTip( wxU(_("Enable the equalizer. You can either "
474     "manually adjust the bands or use a preset (Audio Menu->Equalizer)." ) ) );
475     top_sizer->Add( eq_chkbox, 0, wxALL, 2 );
476
477     eq_2p_chkbox =  new wxCheckBox( panel, Eq2Pass_Event,
478                             wxU(_("2 Pass") ) );
479
480     eq_2p_chkbox->SetToolTip( wxU(_("Apply the equalizer twice. "
481                "The resulting effect will be sharper.") ) );
482
483     top_sizer->Add( eq_2p_chkbox, 0, wxALL, 2 );
484
485     top_sizer->Add( 0, 0, 1, wxALL, 2 );
486
487     eq_restoredefaults_button = new wxButton( panel, EqRestore_Event,
488                                   wxU( _("Restore Defaults") ) );
489     top_sizer->Add( eq_restoredefaults_button, 0, wxALL, 2 );
490     top_sizer->Add( 0, 0, 1, wxALL, 2 );
491
492     smooth_text = new wxStaticText( panel, -1, wxU( _("Smooth :") ));
493     smooth_text->SetToolTip( wxU( _(SMOOTH_TIP) ) );
494     top_sizer->Add( smooth_text, 0, wxALL, 2 );
495
496     smooth_slider =new wxSlider( panel, Smooth_Event, 0, 0, 10 ,
497                     wxDefaultPosition, wxSize( 100, -1 ) );
498     smooth_slider->SetToolTip( wxU( _(SMOOTH_TIP) ) );
499     top_sizer->Add( smooth_slider, 0, wxALL, 2 );
500     i_smooth = 0;
501
502     /* Create flex grid */
503     wxFlexGridSizer *eq_gridsizer =
504         new wxFlexGridSizer( 2, 12, 0, 0);
505     eq_gridsizer->AddGrowableRow( 0 );
506     eq_gridsizer->AddGrowableCol( 1 );
507
508     preamp_slider = new wxSlider( panel, Preamp_Event, 80, 0, 400,
509                     wxDefaultPosition, wxSize( -1 , 90 ) , wxSL_VERTICAL );
510     eq_gridsizer->Add( preamp_slider, 1, wxEXPAND|wxALL, 2 );
511
512     eq_gridsizer->Add( 0, 0, 1, wxALL, 2 );
513
514     for( int i = 0 ; i < 10 ; i++ )
515     {
516         band_sliders[i] = new wxSlider( panel, Band0_Event + i, 200, 0, 400,
517                     wxDefaultPosition, wxSize( -1 , 90 ) , wxSL_VERTICAL );
518
519         i_values[i] = 200;
520         eq_gridsizer->Add( band_sliders[i], 1, wxEXPAND|wxALL, 2 );
521     }
522
523     preamp_text = new wxStaticText( panel, -1, wxU( _("Preamp\n12.0dB") ) );
524     wxFont font= preamp_text->GetFont();
525     font.SetPointSize(7);
526     preamp_text->SetFont( font );
527     eq_gridsizer->Add( preamp_text, wxALL, 2 );
528
529     eq_gridsizer->Add( 0, 0, 1 );
530
531     for( int i = 0 ; i < 10 ; i++ )
532     {
533         band_texts[i] = new wxStaticText( panel, -1,
534                                 band_frequencies[i] + wxU("\n0.0dB" ) ) ;
535         eq_gridsizer->Add( band_texts[i], 1, wxEXPAND|wxALL, 2 );
536         wxFont font= band_texts[i]->GetFont();
537         font.SetPointSize(7);
538         band_texts[i]->SetFont( font );
539     }
540
541     panel_sizer->Add( top_sizer , 0 , wxTOP | wxEXPAND, 5 );
542     panel_sizer->Add( eq_gridsizer , 0 , wxEXPAND, 0 );
543
544     panel->SetSizer( panel_sizer );
545
546     panel_sizer->Layout();
547
548     panel_sizer->SetSizeHints( panel );
549
550     CheckAout();
551
552     aout_instance_t *p_aout = (aout_instance_t *)vlc_object_find(p_intf,
553                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
554     char *psz_af;
555     if( p_aout )
556     {
557         psz_af = var_GetNonEmptyString( p_aout, "audio-filter" );
558         if( var_GetBool( p_aout, "equalizer-2pass" ) )
559             eq_2p_chkbox->SetValue( true );
560         vlc_object_release( p_aout );
561     }
562     else
563     {
564         psz_af = config_GetPsz( p_intf, "audio-filter" );
565         if( config_GetInt( p_intf, "equalizer-2pass" ) )
566             eq_2p_chkbox->SetValue( true );
567     }
568     if( psz_af != NULL && strstr( psz_af, "equalizer" ) )
569     {
570         eq_chkbox->SetValue( true );
571     } else {
572         eq_2p_chkbox->Disable();
573         eq_restoredefaults_button->Disable();
574         smooth_slider->Disable();
575         smooth_text->Disable();
576         preamp_slider->Disable();
577         preamp_text->Disable();
578         for( int i_index=0; i_index < 10; i_index++ )
579         {
580             band_sliders[i_index]->Disable();
581             band_texts[i_index]->Disable();
582         }
583     }
584     free( psz_af );
585
586     return panel;
587 }
588
589 /*******************************************************
590  * Event handlers
591  *******************************************************/
592
593 /* Keep aout up to date and update the bands if needed */
594 void ExtraPanel::OnIdle( wxIdleEvent &event )
595 {
596     CheckAout();
597     if( b_update == true )
598     {
599         if( b_my_update == true )
600         {
601             b_update = b_my_update = false;
602             return;
603         }
604         char *p = psz_bands;
605         for( int i = 0; i < 10; i++ )
606         {
607                 float f;
608                 char psz_val[5];
609                 int i_val;
610                 /* Read dB -20/20*/
611                 f = strtof( p, &p );
612                 i_val= (int)( ( f + 20 ) * 10 );
613                 band_sliders[i]->SetValue( 400 - i_val );
614                 i_values[i] = 400 - i_val;
615                 sprintf( psz_val, "%.1f", f );
616                 band_texts[i]->SetLabel( band_frequencies[i] + wxT("\n") +
617                                                 wxU( psz_val ) + wxT("dB") );
618                 if( p == NULL )
619                 {
620                     break;
621                 }
622                 p++;
623                 if( *p == 0 )
624                     break;
625         }
626         char psz_val[5];
627         int i_val = (int)( ( f_preamp + 20 ) * 10 );
628         sprintf( psz_val, "%.1f", f_preamp );
629         preamp_slider->SetValue( 400 - i_val );
630         const wxString preamp = wxT("Preamp\n");
631         preamp_text->SetLabel( preamp + wxU( psz_val ) + wxT( "dB" ) );
632         eq_chkbox->SetValue( TRUE );
633         b_update = false;
634     }
635 }
636
637 /*************************
638  *  Equalizer Panel events
639  *************************/
640 void ExtraPanel::OnEnableEqualizer( wxCommandEvent &event )
641 {
642     int i_index;
643     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
644                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
645     ChangeFiltersString( p_intf,p_aout, "equalizer",
646                          event.IsChecked() ? true : false );
647
648     if( event.IsChecked() )
649     {
650         eq_2p_chkbox->Enable();
651         eq_restoredefaults_button->Enable();
652         smooth_slider->Enable();
653         smooth_text->Enable();
654         preamp_slider->Enable();
655         preamp_text->Enable();
656         for( i_index=0; i_index < 10; i_index++ )
657         {
658             band_sliders[i_index]->Enable();
659             band_texts[i_index]->Enable();
660         }
661     } else {
662         eq_2p_chkbox->Disable();
663         eq_restoredefaults_button->Disable();
664         smooth_slider->Disable();
665         smooth_text->Disable();
666         preamp_slider->Disable();
667         preamp_text->Disable();
668         for( i_index=0; i_index < 10; i_index++ )
669         {
670             band_sliders[i_index]->Disable();
671             band_texts[i_index]->Disable();
672         }
673     }
674
675     if( p_aout != NULL )
676         vlc_object_release( p_aout );
677 }
678
679 void ExtraPanel::OnEqRestore( wxCommandEvent &event )
680 {
681     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
682                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
683     if( p_aout == NULL )
684     {
685         vlc_value_t val;
686         bool b_previous = eq_chkbox->IsChecked();
687         val.f_float = 12.0;
688         IntfPreampCallback( NULL, NULL, val,val, this );
689         config_PutFloat( p_intf, "equalizer-preamp", 12.0 );
690         val.psz_string = strdup( "0 0 0 0 0 0 0 0 0 0" );
691         IntfBandsCallback( NULL, NULL, val,val, this );
692         config_PutPsz( p_intf, "equalizer-bands",
693                                 "0 0 0 0 0 0 0 0 0 0");
694         config_PutPsz( p_intf, "equalizer-preset","flat" );
695         eq_chkbox->SetValue( b_previous );
696     }
697     else
698     {
699         var_SetFloat( p_aout, "equalizer-preamp", 12.0 );
700         config_PutFloat( p_intf, "equalizer-preamp", 12.0 );
701         var_SetString( p_aout, "equalizer-bands",
702                                 "0 0 0 0 0 0 0 0 0 0");
703         config_PutPsz( p_intf, "equalizer-bands",
704                                 "0 0 0 0 0 0 0 0 0 0");
705         var_SetString( p_aout , "equalizer-preset" , "flat" );
706         config_PutPsz( p_intf, "equalizer-preset","flat" );
707         vlc_object_release( p_aout );
708     }
709 }
710
711 void ExtraPanel::OnEq2Pass( wxCommandEvent &event )
712 {
713     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
714                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
715
716     bool b_2p = event.IsChecked() ? true : false;
717
718     if( p_aout == NULL )
719     {
720         config_PutInt( p_intf, "equalizer-2pass", b_2p );
721     }
722     else
723     {
724         var_SetBool( p_aout, "equalizer-2pass", b_2p );
725         config_PutInt( p_intf, "equalizer-2pass", b_2p );
726         if( eq_chkbox->IsChecked() )
727         {
728             for( int i = 0; i < p_aout->i_nb_inputs; i++ )
729             {
730                 p_aout->pp_inputs[i]->b_restart = true;
731             }
732         }
733         vlc_object_release( p_aout );
734     }
735 }
736
737 void ExtraPanel::OnEqSmooth( wxScrollEvent &event )
738 {
739     /* Max smoothing : 70% */
740     i_smooth = event.GetPosition() * 7;
741 }
742
743 void ExtraPanel::OnPreamp( wxScrollEvent &event )
744 {
745     float f= (float)( 400 - event.GetPosition() ) / 10 - 20 ;
746     char psz_val[5];
747
748     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
749                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
750
751     sprintf( psz_val, "%.1f", f );
752     const wxString preamp = wxT("Preamp\n");
753     preamp_text->SetLabel( preamp + wxU( psz_val ) + wxT( "dB" ) );
754
755     if( p_aout == NULL )
756     {
757         config_PutFloat( p_intf, "equalizer-preamp", f );
758     }
759     else
760     {
761         var_SetFloat( p_aout, "equalizer-preamp", f );
762         config_PutFloat( p_intf, "equalizer-preamp", f );
763         b_my_update = true;
764         vlc_object_release( p_aout );
765     }
766 }
767
768 void ExtraPanel::OnChangeEqualizer( wxScrollEvent &event )
769 {
770     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
771                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
772     char psz_values[102];
773     memset( psz_values, 0, 102 );
774
775
776     /* Smoothing */
777     int i_diff = event.GetPosition() - i_values[  event.GetId() - Band0_Event ];
778     i_values[ event.GetId() - Band0_Event] = event.GetPosition();
779
780     for( int i = event.GetId() + 1 ; i <= Band9_Event ; i++ )
781     {
782         int i_new = band_sliders[ i-Band0_Event ]->GetValue() +
783            (int)( i_diff * pow( (float)i_smooth / 100 , i- event.GetId() ) ) ;
784         if( i_new < 0 ) i_new = 0;
785         if( i_new > 400 ) i_new = 400;
786         band_sliders[ i-Band0_Event ]->SetValue( i_new );
787     }
788     for( int i = Band0_Event ; i < event.GetId() ; i++ )
789     {
790         int i_new =   band_sliders[ i-Band0_Event ]->GetValue() +
791            (int)( i_diff * pow( (float)i_smooth / 100 , event.GetId() - i  ) );
792         if( i_new < 0 ) i_new = 0;
793         if( i_new > 400 ) i_new = 400;
794         band_sliders[ i-Band0_Event ]->SetValue( i_new );
795     }
796
797     /* Write the new bands values */
798     for( int i = 0 ; i < 10 ; i++ )
799     {
800         char psz_val[5];
801         float f_val = (float)( 400 - band_sliders[i]->GetValue() ) / 10- 20 ;
802         sprintf( psz_values, "%s %f", psz_values, f_val );
803         sprintf( psz_val, "%.1f", f_val );
804         band_texts[i]->SetLabel( band_frequencies[i] + wxT("\n") +
805                         wxU( psz_val ) + wxT("dB" ) );
806     }
807     if( p_aout == NULL )
808     {
809         config_PutPsz( p_intf, "equalizer-bands", psz_values );
810     }
811     else
812     {
813         var_SetString( p_aout, "equalizer-bands", psz_values );
814         config_PutPsz( p_intf, "equalizer-bands", psz_values );
815         b_my_update = true;
816         vlc_object_release( p_aout );
817     }
818 }
819
820 /***********************
821  * Audio Panel events
822  ***********************/
823 void ExtraPanel::OnHeadphone( wxCommandEvent &event )
824 {
825     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
826                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
827     ChangeFiltersString( p_intf , p_aout, "headphone_channel_mixer",
828                          event.IsChecked() ? true : false );
829     if( p_aout != NULL )
830         vlc_object_release( p_aout );
831 }
832
833 void ExtraPanel::OnNormvol( wxCommandEvent &event )
834 {
835     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
836                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
837     ChangeFiltersString( p_intf , p_aout, "normvol",
838                          event.IsChecked() ? true : false );
839     if( p_aout != NULL )
840         vlc_object_release( p_aout );
841 }
842
843 void ExtraPanel::OnNormvolSlider( wxScrollEvent &event )
844 {
845     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
846                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
847     if( p_aout != NULL )
848     {
849         var_SetFloat( p_aout, "norm-max-level", (float)event.GetPosition()/10 );
850         vlc_object_release( p_aout );
851     }
852     else
853     {
854         config_PutFloat( p_intf, "norm-max-level",
855                         (float)event.GetPosition()/10 );
856     }
857 }
858 /***********************
859  *  Video Panel events
860  ***********************/
861 void ExtraPanel::OnEnableAdjust(wxCommandEvent& event)
862 {
863     ChangeVFiltersString( p_intf,  "adjust",
864                           event.IsChecked() ? true : false );
865
866     if( event.IsChecked() )
867     {
868         restoredefaults_button->Enable();
869         brightness_slider->Enable();
870         saturation_slider->Enable();
871         contrast_slider->Enable();
872         hue_slider->Enable();
873         gamma_slider->Enable();
874     }
875     else
876     {
877         restoredefaults_button->Disable();
878         brightness_slider->Disable();
879         saturation_slider->Disable();
880         contrast_slider->Disable();
881         hue_slider->Disable();
882         gamma_slider->Disable();
883     }
884 }
885
886 void ExtraPanel::OnRestoreDefaults( wxCommandEvent &event)
887 {
888     hue_slider->SetValue(0);
889     saturation_slider->SetValue(100);
890     brightness_slider->SetValue(100);
891     contrast_slider->SetValue(100),
892     gamma_slider->SetValue(10);
893
894     wxScrollEvent *hscroll_event = new wxScrollEvent(0, Hue_Event, 0);
895     OnAdjustUpdate(*hscroll_event);
896
897     wxScrollEvent *sscroll_event = new wxScrollEvent(0, Saturation_Event, 100);
898     OnAdjustUpdate(*sscroll_event);
899
900     wxScrollEvent *bscroll_event = new wxScrollEvent(0, Brightness_Event, 100);
901     OnAdjustUpdate(*bscroll_event);
902
903     wxScrollEvent *cscroll_event = new wxScrollEvent(0, Contrast_Event, 100);
904     OnAdjustUpdate(*cscroll_event);
905
906     wxScrollEvent *gscroll_event = new wxScrollEvent(0, Gamma_Event, 10);
907     OnAdjustUpdate(*gscroll_event);
908
909 }
910
911 void ExtraPanel::OnAdjustUpdate( wxScrollEvent &event)
912 {
913     vout_thread_t *p_vout = (vout_thread_t *)vlc_object_find(p_intf,
914                                  VLC_OBJECT_VOUT, FIND_ANYWHERE);
915     if( p_vout == NULL )
916     {
917         switch( event.GetId() )
918         {
919             case Hue_Event:
920                 config_PutInt( p_intf , "hue" , event.GetPosition() );
921                 break;
922
923             case Saturation_Event:
924                 config_PutFloat( p_intf , "saturation" ,
925                                 (float)event.GetPosition()/100 );
926                 break;
927
928             case Brightness_Event:
929                 config_PutFloat( p_intf , "brightness" ,
930                                 (float)event.GetPosition()/100 );
931                 break;
932
933             case Contrast_Event:
934                 config_PutFloat( p_intf , "contrast" ,
935                                 (float)event.GetPosition()/100 );
936                 break;
937
938             case Gamma_Event:
939                 config_PutFloat( p_intf , "gamma" ,
940                                 (float)event.GetPosition()/10 );
941                 break;
942         }
943     }
944     else
945     {
946         vlc_value_t val;
947         switch( event.GetId() )
948         {
949             case Hue_Event:
950                 val.i_int = event.GetPosition();
951                 var_Set( p_vout, "hue", val );
952                 config_PutInt( p_intf , "hue" , event.GetPosition() );
953                 break;
954
955             case Saturation_Event:
956                 val.f_float = (float)event.GetPosition() / 100;
957                 var_Set( p_vout, "saturation", val );
958                 config_PutFloat( p_intf , "saturation" ,
959                                 (float)event.GetPosition()/100 );
960                 break;
961
962             case Brightness_Event:
963                 val.f_float = (float)event.GetPosition() / 100;
964                 var_Set( p_vout, "brightness", val );
965                 config_PutFloat( p_intf , "brightness" ,
966                                 (float)event.GetPosition()/100 );
967                 break;
968
969             case Contrast_Event:
970                 val.f_float = (float)event.GetPosition() / 100;
971                 var_Set( p_vout, "contrast", val );
972                 config_PutFloat( p_intf , "contrast" ,
973                                 (float)event.GetPosition()/100 );
974                 break;
975
976             case Gamma_Event:
977                 val.f_float = (float)event.GetPosition() / 10;
978                 var_Set( p_vout, "gamma", val );
979                 config_PutFloat( p_intf , "gamma" ,
980                                 (float)event.GetPosition()/10 );
981                 break;
982         }
983         vlc_object_release(p_vout);
984     }
985 }
986
987 /* FIXME */
988 void ExtraPanel::OnRatio( wxCommandEvent& event )
989 {
990    config_PutPsz( p_intf, "aspect-ratio", ratio_combo->GetValue().mb_str(wxConvUTF8) );
991 }
992
993
994 void ExtraPanel::OnSelectFilter(wxCommandEvent& event)
995 {
996     int i_filter = event.GetId() - Filter0_Event ;
997     if( vfilters[i_filter].psz_filter  )
998     {
999         if( vfilters[i_filter].b_vfilter2 )
1000             ChangeVFilters2String( p_intf, vfilters[i_filter].psz_filter ,
1001                                 event.IsChecked() ? true : false );
1002         else
1003             ChangeVFiltersString( p_intf, vfilters[i_filter].psz_filter ,
1004                                   event.IsChecked() ? true : false );
1005     }
1006 }
1007
1008 void ExtraPanel::OnFiltersInfo(wxCommandEvent& event)
1009 {
1010     wxMessageBox( wxU( _("Filtering effects to apply to the video. "
1011                   "You must restart the stream for these settings to "
1012                   "take effect.\n\n"
1013                   "To configure these filters, go to Preferences / Video / "
1014                   "Filters. In order to control the order in which they "
1015                   "are applied, enter a filters string in the Video Filter "
1016                   "Module inside the preferences."
1017                   ) ),
1018                     wxU( _("More Information" ) ), wxOK | wxICON_INFORMATION,
1019                     this->p_parent );
1020 }
1021 /**********************************
1022  * Other functions
1023  **********************************/
1024 void ExtraPanel::CheckAout()
1025 {
1026     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
1027                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
1028     if( p_aout != NULL )
1029     {
1030         if( p_aout != p_intf->p_sys->p_aout )
1031         {
1032             /* We want to know if someone changes the bands */
1033             if( var_AddCallback( p_aout, "equalizer-bands",
1034                                     IntfBandsCallback, this ) )
1035             {
1036                 /* The variable does not exist yet, wait */
1037                 vlc_object_release( p_aout );
1038                 return;
1039             }
1040             if( var_AddCallback( p_aout, "equalizer-preamp",
1041                                     IntfPreampCallback, this )  )
1042             {
1043                 vlc_object_release( p_aout );
1044                 return;
1045             }
1046             /* Ok, we have our variables, make a first update round */
1047             p_intf->p_sys->p_aout = p_aout;
1048
1049             f_preamp = var_GetFloat( p_aout, "equalizer-preamp" );
1050             psz_bands = var_GetNonEmptyString( p_aout, "equalizer-bands" );
1051             if( psz_bands == NULL )
1052                 psz_bands = strdup("");
1053             b_update = true;
1054         }
1055         vlc_object_release( p_aout );
1056     }
1057 }
1058
1059 static void ChangeVFiltersString( intf_thread_t *p_intf,
1060                                   char *psz_name, bool b_add )
1061 {
1062     vout_thread_t *p_vout;
1063     char *psz_parser, *psz_string;
1064
1065     psz_string = config_GetPsz( p_intf, "vout-filter" );
1066
1067     if( !psz_string ) psz_string = strdup("");
1068
1069     psz_parser = strstr( psz_string, psz_name );
1070
1071     if( b_add )
1072     {
1073         if( !psz_parser )
1074         {
1075             psz_parser = psz_string;
1076             asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
1077                             psz_string, psz_name );
1078             free( psz_parser );
1079         }
1080         else
1081         {
1082             return;
1083         }
1084     }
1085     else
1086     {
1087         if( psz_parser )
1088         {
1089             memmove( psz_parser, psz_parser + strlen(psz_name) +
1090                             (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
1091                             strlen(psz_parser + strlen(psz_name)) + 1 );
1092
1093             /* Remove trailing : : */
1094             if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
1095             {
1096                 *(psz_string+strlen(psz_string ) -1 ) = '\0';
1097             }
1098          }
1099          else
1100          {
1101              free( psz_string );
1102              return;
1103          }
1104     }
1105     /* Vout is not kept, so put that in the config */
1106     config_PutPsz( p_intf, "vout-filter", psz_string );
1107
1108     /* Try to set on the fly */
1109     p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
1110                                               FIND_ANYWHERE );
1111     if( p_vout )
1112     {
1113         var_SetString( p_vout, "vout-filter", psz_string );
1114         vlc_object_release( p_vout );
1115     }
1116
1117     free( psz_string );
1118 }
1119
1120 static void ChangeVFilters2String( intf_thread_t *p_intf,
1121                                   char *psz_name, bool b_add )
1122 {
1123     vout_thread_t *p_vout;
1124     char *psz_parser, *psz_string;
1125
1126     psz_string = config_GetPsz( p_intf, "video-filter" );
1127
1128     if( !psz_string ) psz_string = strdup("");
1129
1130     psz_parser = strstr( psz_string, psz_name );
1131
1132     if( b_add )
1133     {
1134         if( !psz_parser )
1135         {
1136             psz_parser = psz_string;
1137             asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
1138                             psz_string, psz_name );
1139             free( psz_parser );
1140         }
1141         else
1142         {
1143             return;
1144         }
1145     }
1146     else
1147     {
1148         if( psz_parser )
1149         {
1150             memmove( psz_parser, psz_parser + strlen(psz_name) +
1151                             (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
1152                             strlen(psz_parser + strlen(psz_name)) + 1 );
1153
1154             /* Remove trailing : : */
1155             if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
1156             {
1157                 *(psz_string+strlen(psz_string ) -1 ) = '\0';
1158             }
1159          }
1160          else
1161          {
1162              free( psz_string );
1163              return;
1164          }
1165     }
1166     /* Vout is not kept, so put that in the config */
1167     config_PutPsz( p_intf, "video-filter", psz_string );
1168
1169     /* Try to set on the fly */
1170     p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
1171                                               FIND_ANYWHERE );
1172     if( p_vout )
1173     {
1174         var_SetString( p_vout, "video-filter", psz_string );
1175         vlc_object_release( p_vout );
1176     }
1177     free( psz_string );
1178 }
1179
1180
1181 static void ChangeFiltersString( intf_thread_t *p_intf,
1182                                  aout_instance_t * p_aout,
1183                                  char *psz_name, bool b_add )
1184 {
1185     char *psz_parser, *psz_string;
1186
1187     if( p_aout )
1188     {
1189         psz_string = var_GetNonEmptyString( p_aout, "audio-filter" );
1190     }
1191     else
1192     {
1193         psz_string = config_GetPsz( p_intf, "audio-filter" );
1194     }
1195
1196     if( !psz_string ) psz_string = strdup("");
1197
1198     psz_parser = strstr( psz_string, psz_name );
1199
1200     if( b_add )
1201     {
1202         if( !psz_parser )
1203         {
1204             psz_parser = psz_string;
1205             asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
1206                             psz_string, psz_name );
1207             free( psz_parser );
1208         }
1209         else
1210         {
1211             return;
1212         }
1213     }
1214     else
1215     {
1216         if( psz_parser )
1217         {
1218             memmove( psz_parser, psz_parser + strlen(psz_name) +
1219                             (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
1220                             strlen(psz_parser + strlen(psz_name)) + 1 );
1221
1222             if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
1223             {
1224                 *(psz_string+strlen(psz_string ) -1 ) = '\0';
1225             }
1226          }
1227          else
1228          {
1229              free( psz_string );
1230              return;
1231          }
1232     }
1233
1234     if( p_aout == NULL )
1235     {
1236         config_PutPsz( p_intf, "audio-filter", psz_string );
1237     }
1238     else
1239     {
1240         var_SetString( p_aout, "audio-filter", psz_string );
1241         for( int i = 0; i < p_aout->i_nb_inputs; i++ )
1242         {
1243             p_aout->pp_inputs[i]->b_restart = true;
1244         }
1245     }
1246     free( psz_string );
1247 }
1248
1249
1250 static int IntfBandsCallback( vlc_object_t *p_this, char const *psz_cmd,
1251                           vlc_value_t oldval, vlc_value_t newval, void *param )
1252 {
1253     ExtraPanel *p_panel = (ExtraPanel *)param;
1254
1255     p_panel->psz_bands = strdup( newval.psz_string );
1256     p_panel->b_update = true;
1257
1258     return VLC_SUCCESS;
1259 }
1260
1261 static int IntfPreampCallback( vlc_object_t *p_this, char const *psz_cmd,
1262                           vlc_value_t oldval, vlc_value_t newval, void *param )
1263 {
1264     ExtraPanel *p_panel = (ExtraPanel *)param;
1265
1266     p_panel->f_preamp = newval.f_float;
1267     p_panel->b_update = true;
1268
1269     return VLC_SUCCESS;
1270 }
1271
1272 #if 0
1273 /**********************************************************************
1274  * A small window to contain the extrapanel in its undocked state
1275  **********************************************************************/
1276 BEGIN_EVENT_TABLE(ExtraWindow, wxFrame)
1277 END_EVENT_TABLE()
1278
1279
1280 ExtraWindow::ExtraWindow( intf_thread_t *_p_intf, wxWindow *p_parent,
1281                           wxPanel *_extra_panel ):
1282        wxFrame( p_parent, -1, wxU(_("Extended controls")), wxDefaultPosition,
1283                  wxDefaultSize, wxDEFAULT_FRAME_STYLE )
1284 {
1285     p_intf = _p_intf;
1286     SetIcon( *p_intf->p_sys->p_icon );
1287
1288     wxBoxSizer *window_sizer = new wxBoxSizer( wxVERTICAL );
1289     SetSizer( window_sizer );
1290
1291     panel = _extra_panel;
1292     window_sizer->Add( panel );
1293
1294     window_sizer->Layout();
1295     window_sizer->Fit( this );
1296
1297     Show();
1298 }
1299
1300 ExtraWindow::~ExtraWindow()
1301 {
1302     delete panel;
1303 }
1304 #endif