]> git.sesse.net Git - vlc/blob - modules/gui/macosx/extended.m
Removes trailing spaces. Removes tabs.
[vlc] / modules / gui / macosx / extended.m
1 /*****************************************************************************
2  * extended.m: MacOS X Extended interface panel
3  *****************************************************************************
4  * Copyright (C) 2005-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Felix Paul Kühne <fkuehne@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 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #import "extended.h"
30 #import "intf.h"
31 #import "vout.h"
32 #import <vlc_aout.h>
33 #import <vlc_vout.h>
34 #import <vlc_interface.h>
35
36 /*****************************************************************************
37  * VLCExtended implementation
38  *****************************************************************************/
39
40 @implementation VLCExtended
41
42 static VLCExtended *_o_sharedInstance = nil;
43
44 + (VLCExtended *)sharedInstance
45 {
46     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
47 }
48
49 - (id)init
50 {
51     if (_o_sharedInstance) {
52         [self dealloc];
53     } else {
54         _o_sharedInstance = [super init];
55     }
56
57     return _o_sharedInstance;
58 }
59
60 /*****************************************************************************
61  * GUI methods
62  *****************************************************************************/
63
64 - (void)initStrings
65 {
66     /* localise GUI-strings */
67     /* method is called from intf.m (in method showExtended) */
68     [o_extended_window setTitle: _NS("Extended controls")];
69     [o_lbl_video setStringValue: _NS("Video")];
70     [o_lbl_audio setStringValue: _NS("Audio")];
71     [o_lbl_audioFlts setStringValue: _NS("Audio filters")];
72     [o_lbl_videoFlts setStringValue: _NS("Video filters")];
73     [o_lbl_adjustImage setStringValue: _NS("Image adjustment")];
74     [o_btn_vidFlts_mrInfo setToolTip: _NS("Shows more information about the available video filters.")];
75     [o_ckb_wave setTitle: _NS("Wave")];
76     [o_ckb_ripple setTitle: _NS("Ripple")];
77     [o_ckb_psycho setTitle: _NS("Psychedelic")];
78     [o_ckb_gradient setTitle: _NS("Gradient")];
79     [o_lbl_general setStringValue: _NS("General editing filters")];
80     [o_lbl_distort setStringValue: _NS("Distortion filters")];
81     [o_ckb_blur setTitle: _NS("Blur")];
82     [o_ckb_blur setToolTip: _NS("Adds motion blurring to the image")];
83     [o_ckb_imgClone setTitle: _NS("Image clone")];
84     [o_ckb_imgClone setToolTip: _NS("Creates several copies of the Video "
85                                     "output window" )];
86     [o_ckb_imgCrop setTitle: _NS("Image cropping")];
87     [o_ckb_imgCrop setToolTip: _NS("Crops a defined part of the image")];
88     [o_ckb_imgInvers setTitle: _NS("Invert colors")];
89     [o_ckb_imgInvers setToolTip: _NS("Inverts the colors of the image")];
90     [o_ckb_trnsform setTitle: _NS("Transformation")];
91     [o_ckb_trnsform setToolTip: _NS("Rotates or flips the image")];
92     [o_ckb_intZoom setTitle: _NS("Interactive Zoom")];
93     [o_ckb_intZoom setToolTip: _NS("Enables an interactive Zoom feature")];
94     [o_ckb_vlme_norm setTitle: _NS("Volume normalization")];
95     [o_ckb_vlme_norm setToolTip: _NS("Prevents the audio output from going "
96         "over a predefined value.")];
97     [o_ckb_hdphnVirt setTitle: _NS("Headphone virtualization")];
98     [o_ckb_hdphnVirt setToolTip: _NS("Imitates the effect of surround sound "
99         "when using headphones.")];
100     [o_lbl_maxLevel setStringValue: _NS("Maximum level")];
101     [o_btn_rstrDefaults setTitle: _NS("Restore Defaults")];
102     [o_ckb_enblAdjustImg setTitle: _NS("Enable")];
103     [o_lbl_brightness setStringValue: _NS("Brightness")];
104     [o_lbl_contrast setStringValue: _NS("Contrast")];
105     [o_lbl_gamma setStringValue: _NS("Gamma")];
106     [o_lbl_hue setStringValue: _NS("Hue")];
107     [o_lbl_saturation setStringValue: _NS("Saturation")];
108     [o_lbl_opaque setStringValue: _NS("Opaqueness")];
109  
110 }
111
112 - (void)awakeFromNib
113 {
114     /* set the adjust-filter-sliders to the values from the prefs and enable
115      * them, if wanted */
116     char * psz_vfilters;
117     intf_thread_t * p_intf = VLCIntf;
118     psz_vfilters = config_GetPsz( p_intf, "vout-filter" );
119     /* set the video-filter-checkboxes to the correct values */
120     if( psz_vfilters )
121     {
122         [o_ckb_blur setState: (int)strstr( psz_vfilters, "motionblur")];
123         [o_ckb_imgClone setState: (int)strstr( psz_vfilters, "clone")];
124         [o_ckb_imgCrop setState: (int)strstr( psz_vfilters, "crop")];
125         [o_ckb_trnsform setState: (int)strstr( psz_vfilters, "transform")];
126
127         free( psz_vfilters );
128     }
129  
130     /* set the video-filter checkboxes to the correct values */
131     char * psz_vifilters;
132     psz_vifilters = config_GetPsz( p_intf, "video-filter" );
133     if( psz_vifilters && strstr( psz_vifilters, "adjust" ) )
134     {
135         [o_ckb_enblAdjustImg setState: NSOnState];
136         [o_btn_rstrDefaults setEnabled: YES];
137         [o_sld_brightness setEnabled: YES];
138         [o_sld_contrast setEnabled: YES];
139         [o_sld_gamma setEnabled: YES];
140         [o_sld_hue setEnabled: YES];
141         [o_sld_saturation setEnabled: YES];
142     }
143     else
144     {
145         [o_ckb_enblAdjustImg setState: NSOffState];
146         [o_btn_rstrDefaults setEnabled: NO];
147         [o_sld_brightness setEnabled: NO];
148         [o_sld_contrast setEnabled: NO];
149         [o_sld_gamma setEnabled: NO];
150         [o_sld_hue setEnabled: NO];
151         [o_sld_saturation setEnabled: NO];
152     }
153     if( psz_vifilters )
154     {
155         [o_ckb_wave setState: (int)strstr( psz_vifilters, "wave")];
156         [o_ckb_psycho setState: (int)strstr( psz_vifilters, "psychedelic")];
157         [o_ckb_ripple setState: (int)strstr( psz_vifilters, "ripple")];
158         [o_ckb_gradient setState: (int)strstr( psz_vifilters, "gradient")];
159         [o_ckb_imgInvers setState: (int)strstr( psz_vifilters, "invert")];
160
161         free( psz_vifilters );
162     }
163  
164     /* set the audio-filter-checkboxes to the values taken from the prefs */
165     char * psz_afilters;
166     psz_afilters = config_GetPsz( p_intf, "audio-filter" );
167     if( psz_afilters )
168     {
169         [o_ckb_hdphnVirt setState: (int)strstr( psz_afilters, "headphone" ) ];
170         [o_ckb_vlme_norm setState: (int)strstr( psz_afilters, "normvol" ) ];
171  
172         free( psz_afilters );
173     }
174 }
175
176 - (void)collapsAll
177 {
178     /* collaps all views so Cocoa saves the window position correctly */
179     if( o_adjImg_expanded )
180     {
181         [self expandAdjustImage: nil];
182     }
183     if( o_audFlts_expanded )
184     {
185         [self expandAudioFilters: nil];
186     }
187     if( o_vidFlts_expanded )
188     {
189         [self expandVideoFilters: nil];
190     }
191 }
192
193 - (BOOL)getConfigChanged
194 {
195     return o_config_changed;
196 }
197
198 - (void)showPanel
199 {
200     /* get the correct slider values from the prefs, in case they were changed
201      * elsewhere */
202     intf_thread_t * p_intf = VLCIntf;
203
204     int i_value = config_GetInt( p_intf, "hue" );
205     if( i_value > 0 && i_value < 360 )
206     {
207         [o_sld_hue setIntValue: i_value];
208     }
209
210     float f_value;
211  
212     f_value = config_GetFloat( p_intf, "saturation" );
213     if( f_value > 0 && f_value < 5 )
214     {
215         [o_sld_saturation setIntValue: (int)(100 * f_value) ];
216     }
217
218     f_value = config_GetFloat( p_intf, "contrast" );
219     if( f_value > 0 && f_value < 4 )
220     {
221         [o_sld_contrast setIntValue: (int)(100 * f_value) ];
222     }
223
224     f_value = config_GetFloat( p_intf, "brightness" );
225     if( f_value > 0 && f_value < 2 )
226     {
227         [o_sld_brightness setIntValue: (int)(100 * f_value) ];
228     }
229
230     f_value = config_GetFloat( p_intf, "gamma" );
231     if( f_value > 0 && f_value < 10 )
232     {
233         [o_sld_gamma setIntValue: (int)(10 * f_value) ];
234     }
235
236     f_value = config_GetFloat( p_intf, "norm-max-level" );
237     if( f_value > 0 && f_value < 10 )
238     {
239         [o_sld_maxLevel setFloatValue: f_value ];
240     }
241
242     [o_sld_opaque setFloatValue: (config_GetFloat( p_intf,
243         "macosx-opaqueness") * 100)];
244
245
246     /* show the window */
247     [o_extended_window displayIfNeeded];
248     [o_extended_window makeKeyAndOrderFront:nil];
249 }
250
251 - (IBAction)enableAdjustImage:(id)sender
252 {
253     /* en-/disable the sliders */
254     if ([o_ckb_enblAdjustImg state] == NSOnState)
255     {
256         [o_btn_rstrDefaults setEnabled: YES];
257         [o_sld_brightness setEnabled: YES];
258         [o_sld_contrast setEnabled: YES];
259         [o_sld_gamma setEnabled: YES];
260         [o_sld_hue setEnabled: YES];
261         [o_sld_saturation setEnabled: YES];
262         [self changeVideoFiltersString: "adjust" onOrOff: VLC_TRUE];
263     }else{
264         [o_btn_rstrDefaults setEnabled: NO];
265         [o_sld_brightness setEnabled: NO];
266         [o_sld_contrast setEnabled: NO];
267         [o_sld_gamma setEnabled: NO];
268         [o_sld_hue setEnabled: NO];
269         [o_sld_saturation setEnabled: NO];
270         [self changeVideoFiltersString: "adjust" onOrOff: VLC_FALSE];
271     }
272 }
273
274 - (IBAction)restoreDefaultsForAdjustImage:(id)sender
275 {
276     /* reset the sliders */
277     [o_sld_brightness setIntValue: 100];
278     [o_sld_contrast setIntValue: 100];
279     [o_sld_gamma setIntValue: 10];
280     [o_sld_hue setIntValue: 0];
281     [o_sld_saturation setIntValue: 100];
282     [o_sld_opaque setIntValue: 100];
283  
284     /* transmit the values */
285     [self sliderActionAdjustImage: o_sld_brightness];
286     [self sliderActionAdjustImage: o_sld_contrast];
287     [self sliderActionAdjustImage: o_sld_gamma];
288     [self sliderActionAdjustImage: o_sld_hue];
289     [self sliderActionAdjustImage: o_sld_saturation];
290     [self opaqueSliderAction: o_sld_opaque];
291 }
292
293 - (IBAction)sliderActionAdjustImage:(id)sender
294 {
295     /* read-out the sliders' values and apply them */
296     intf_thread_t * p_intf = VLCIntf;
297     vout_thread_t *p_vout = (vout_thread_t *)vlc_object_find(p_intf,
298                                  VLC_OBJECT_VOUT, FIND_ANYWHERE);
299     if( p_vout == NULL )
300     {
301         if (sender == o_sld_brightness)
302         {
303             config_PutFloat( p_intf , "brightness" , [o_sld_brightness floatValue] / 100);
304         } else if (sender == o_sld_contrast)
305         {
306             config_PutFloat( p_intf , "contrast" , [o_sld_contrast floatValue] / 100);
307         } else if (sender == o_sld_gamma)
308         {
309             config_PutFloat( p_intf , "gamma" , [o_sld_gamma floatValue] / 10);
310         } else if (sender == o_sld_hue)
311         {
312             config_PutInt( p_intf , "hue" , [o_sld_hue intValue]);
313         } else if (sender == o_sld_saturation)
314         {
315             config_PutFloat( p_intf , "saturation" , [o_sld_saturation floatValue] / 100);
316         } else {
317             msg_Warn( p_intf, "the corresponding subfilter coundn't be found" );
318         }
319     } else {
320         vlc_value_t val;
321         if (sender == o_sld_brightness)
322         {
323             val.f_float = [o_sld_brightness floatValue] / 100;
324             var_Set( p_vout, "brightness", val );
325             config_PutFloat( p_intf , "brightness" , [o_sld_brightness floatValue] / 100);
326         } else if (sender == o_sld_contrast)
327         {
328             val.f_float = [o_sld_contrast floatValue] / 100;
329             var_Set( p_vout, "contrast", val );
330             config_PutFloat( p_intf , "contrast" , [o_sld_contrast floatValue] / 100);
331         } else if (sender == o_sld_gamma)
332         {
333             val.f_float = [o_sld_gamma floatValue] / 10;
334             var_Set( p_vout, "gamma", val );
335             config_PutFloat( p_intf , "gamma" , [o_sld_gamma floatValue] / 10);
336         } else if (sender == o_sld_hue)
337         {
338             val.i_int = [o_sld_hue intValue];
339             var_Set( p_vout, "hue", val );
340             config_PutInt( p_intf , "hue" , [o_sld_hue intValue]);
341         } else if (sender == o_sld_saturation)
342         {
343             val.f_float = [o_sld_saturation floatValue] / 100;
344             var_Set( p_vout, "saturation", val );
345             config_PutFloat( p_intf , "saturation" , [o_sld_saturation floatValue] / 100);
346         } else {
347             msg_Warn( p_intf, "the corresponding subfilter coundn't be found" );
348         }
349         vlc_object_release( p_vout );
350     }
351
352     o_config_changed = YES;
353 }
354
355 /* change the opaqueness of the vouts */
356 - (IBAction)opaqueSliderAction:(id)sender
357 {
358     vlc_value_t val;
359     id o_window = [NSApp keyWindow];
360     NSArray *o_windows = [NSApp orderedWindows];
361     NSEnumerator *o_enumerator = [o_windows objectEnumerator];
362     playlist_t * p_playlist = pl_Yield( VLCIntf );
363     vout_thread_t *p_vout = vlc_object_find( VLCIntf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
364     vout_thread_t *p_real_vout;
365
366     val.f_float = [o_sld_opaque floatValue] / 100;
367
368
369     if( p_vout != NULL )
370     {
371         p_real_vout = [VLCVoutView getRealVout: p_vout];
372         var_Set( p_real_vout, "macosx-opaqueness", val );
373
374         while ((o_window = [o_enumerator nextObject]))
375         {
376             if( [[o_window className] isEqualToString: @"VLCVoutWindow"] ||
377                 [[[VLCMain sharedInstance] getEmbeddedList]
378                                     windowContainsEmbedded: o_window])
379             {
380                 [o_window setAlphaValue: val.f_float];
381             }
382             break;
383         }
384         vlc_object_release( p_vout );
385     }
386  
387     /* store to prefs */
388     config_PutFloat( p_playlist , "macosx-opaqueness" , val.f_float );
389  
390     vlc_object_release( p_playlist );
391
392     o_config_changed = YES;
393 }
394
395 - (IBAction)enableHeadphoneVirtualizer:(id)sender
396 {
397     /* en-/disable headphone virtualisation */
398     if ([o_ckb_hdphnVirt state] == NSOnState)
399     {
400         [self changeAFiltersString: "headphone_channel_mixer" onOrOff: VLC_TRUE ];
401     }else{
402         [self changeAFiltersString: "headphone_channel_mixer" onOrOff: VLC_FALSE ];
403     }
404 }
405
406 - (IBAction)sliderActionMaximumAudioLevel:(id)sender
407 {
408     /* read-out the slider's value and apply it */
409     intf_thread_t * p_intf = VLCIntf;
410     aout_instance_t * p_aout= (aout_instance_t *)vlc_object_find(p_intf,
411                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
412     if( p_aout != NULL )
413     {
414         var_SetFloat( p_aout, "norm-max-level", [o_sld_maxLevel floatValue] );
415         vlc_object_release( p_aout );
416     }
417     config_PutFloat( p_intf, "norm-max-level", [o_sld_maxLevel floatValue] );
418
419     o_config_changed = YES;
420 }
421
422 - (IBAction)enableVolumeNormalization:(id)sender
423 {
424     /* en-/disable volume normalisation */
425     if ([o_ckb_vlme_norm state] == NSOnState)
426     {
427         [self changeAFiltersString: "normvol" onOrOff: YES ];
428     }else{
429         [self changeAFiltersString: "normvol" onOrOff: NO ];
430     }
431 }
432
433 - (IBAction)expandAdjustImage:(id)sender
434 {
435     /* expand or collapse adjImg */
436     NSRect o_win_rect = [o_extended_window frame];
437     NSRect o_box_audFlts_rect = [o_box_audFlts frame];
438     NSRect o_box_vidFlts_rect = [o_box_vidFlts frame];
439     NSRect o_box_adjImg_rect = [o_box_adjImg frame];
440  
441     if (o_adjImg_expanded)
442     {
443         /* move the window contents upwards (partially done through settings
444          * inside the nib) and resize the window */
445         o_win_rect.size.height = o_win_rect.size.height - 193;
446         o_win_rect.origin.y = [o_extended_window frame].origin.y + 193;
447         o_box_audFlts_rect.origin.y = o_box_audFlts_rect.origin.y + 193;
448         o_box_vidFlts_rect.origin.y = o_box_vidFlts_rect.origin.y + 193;
449  
450         /* remove the inserted view */
451         [o_adjustImg_view removeFromSuperviewWithoutNeedingDisplay];
452     }else{
453  
454         /* move the window contents downwards and resize the window */
455         o_win_rect.size.height = o_win_rect.size.height + 193;
456         o_win_rect.origin.y = [o_extended_window frame].origin.y - 193;
457         o_box_audFlts_rect.origin.y = o_box_audFlts_rect.origin.y - 193;
458         o_box_vidFlts_rect.origin.y = o_box_vidFlts_rect.origin.y - 193;
459     }
460  
461     [o_box_audFlts setFrameFromContentFrame: o_box_audFlts_rect];
462     [o_box_vidFlts setFrameFromContentFrame: o_box_vidFlts_rect];
463     [o_extended_window displayIfNeeded];
464     [o_extended_window setFrame: o_win_rect display:YES animate: YES];
465  
466     if (o_adjImg_expanded)
467     {
468         o_box_adjImg_rect.size.height = [o_box_adjImg frame].size.height - 193;
469         o_adjImg_expanded = NO;
470     } else {
471         /* insert view */
472         o_box_adjImg_rect.size.height = [o_box_adjImg frame].size.height + 193;
473         [o_adjustImg_view setFrame: NSMakeRect( 20, -10, 370, 203)];
474         [o_adjustImg_view setNeedsDisplay:YES];
475         [o_adjustImg_view setAutoresizesSubviews: YES];
476         [[o_box_adjImg contentView] addSubview: o_adjustImg_view];
477         o_adjImg_expanded = YES;
478     }
479     [o_box_adjImg setFrameFromContentFrame: o_box_adjImg_rect];
480 }
481
482 - (IBAction)expandAudioFilters:(id)sender
483 {
484     /* expand or collapse audFlts */
485     NSRect o_win_rect = [o_extended_window frame];
486     NSRect o_box_audFlts_rect = [o_box_audFlts frame];
487  
488     if (o_audFlts_expanded)
489     {
490         /* move the window contents upwards (partially done through settings
491          * inside the nib) and resize the window */
492         o_win_rect.size.height = o_win_rect.size.height - 66;
493         o_win_rect.origin.y = [o_extended_window frame].origin.y + 66;
494  
495         /* remove the inserted view */
496         [o_audioFlts_view removeFromSuperviewWithoutNeedingDisplay];
497     }else{
498         /* move the window contents downwards and resize the window */
499         o_win_rect.size.height = o_win_rect.size.height + 66;
500         o_win_rect.origin.y = [o_extended_window frame].origin.y - 66;
501     }
502     [o_extended_window displayIfNeeded];
503     [o_extended_window setFrame: o_win_rect display:YES animate: YES];
504  
505  
506     if (o_audFlts_expanded)
507     {
508         o_box_audFlts_rect.size.height = [o_box_audFlts frame].size.height - 66;
509         o_audFlts_expanded = NO;
510     } else {
511         /* insert view */
512         o_box_audFlts_rect.size.height = [o_box_audFlts frame].size.height + 66;
513         [o_audioFlts_view setFrame: NSMakeRect( 20, -20, 370, 76)];
514         [o_audioFlts_view setNeedsDisplay:YES];
515         [o_audioFlts_view setAutoresizesSubviews: YES];
516         [[o_box_audFlts contentView] addSubview: o_audioFlts_view];
517         o_audFlts_expanded = YES;
518     }
519     [o_box_audFlts setFrameFromContentFrame: o_box_audFlts_rect];
520 }
521
522 - (IBAction)expandVideoFilters:(id)sender
523 {
524     /* expand or collapse vidFlts */
525     NSRect o_win_rect = [o_extended_window frame];
526     NSRect o_box_audFlts_rect = [o_box_audFlts frame];
527     NSRect o_box_vidFlts_rect = [o_box_vidFlts frame];
528  
529     if (o_vidFlts_expanded)
530     {
531         /* move the window contents upwards (partially done through settings
532          * inside the nib) and resize the window */
533         o_win_rect.size.height = o_win_rect.size.height - 172;
534         o_win_rect.origin.y = [o_extended_window frame].origin.y + 172;
535         o_box_audFlts_rect.origin.y = o_box_audFlts_rect.origin.y + 172;
536  
537         /* remove the inserted view */
538         [o_videoFilters_view removeFromSuperviewWithoutNeedingDisplay];
539     }else{
540  
541         /* move the window contents downwards and resize the window */
542         o_win_rect.size.height = o_win_rect.size.height + 172;
543         o_win_rect.origin.y = [o_extended_window frame].origin.y - 172;
544         o_box_audFlts_rect.origin.y = o_box_audFlts_rect.origin.y - 172;
545     }
546  
547     [o_box_audFlts setFrameFromContentFrame: o_box_audFlts_rect];
548     [o_extended_window displayIfNeeded];
549     [o_extended_window setFrame: o_win_rect display:YES animate: YES];
550  
551     if (o_vidFlts_expanded)
552     {
553         o_box_vidFlts_rect.size.height = [o_box_vidFlts frame].size.height - 172;
554         o_vidFlts_expanded = NO;
555     } else {
556         /* insert view */
557         o_box_vidFlts_rect.size.height = [o_box_vidFlts frame].size.height + 172;
558         [o_videoFilters_view setFrame: NSMakeRect( 20, -10, 370, 172)];
559         [o_videoFilters_view setNeedsDisplay:YES];
560         [o_videoFilters_view setAutoresizesSubviews: YES];
561         [[o_box_vidFlts contentView] addSubview: o_videoFilters_view];
562         o_vidFlts_expanded = YES;
563     }
564     [o_box_vidFlts setFrameFromContentFrame: o_box_vidFlts_rect];
565 }
566
567 - (IBAction)videoFilterAction:(id)sender
568 {
569     /* en-/disable video filters */
570     if (sender == o_ckb_blur)
571         [self changeVoutFiltersString: "motionblur" onOrOff: [o_ckb_blur state]];
572
573     else if (sender == o_ckb_imgClone)
574         [self changeVoutFiltersString: "clone" onOrOff: [o_ckb_imgClone state]];
575
576     else if (sender == o_ckb_imgCrop)
577         [self changeVoutFiltersString: "crop" onOrOff: [o_ckb_imgCrop state]];
578
579     else if (sender == o_ckb_imgInvers)
580         [self changeVideoFiltersString: "invert" onOrOff: [o_ckb_imgInvers state]];
581
582     else if (sender == o_ckb_trnsform)
583         [self changeVoutFiltersString: "transform" onOrOff: [o_ckb_trnsform state]];
584
585     else if (sender == o_ckb_intZoom )
586         [self changeVoutFiltersString: "magnify" onOrOff: [o_ckb_intZoom state]];
587
588     else if (sender == o_ckb_wave )
589         [self changeVideoFiltersString: "wave" onOrOff: [o_ckb_wave state]];
590
591     else if (sender == o_ckb_gradient )
592         [self changeVideoFiltersString: "gradient" onOrOff: [o_ckb_gradient state]];
593
594     else if (sender == o_ckb_psycho )
595         [self changeVideoFiltersString: "psychedelic" onOrOff: [o_ckb_psycho state]];
596
597     else if (sender == o_ckb_ripple )
598         [self changeVideoFiltersString: "ripple" onOrOff: [o_ckb_ripple state]];
599
600     else {
601         /* this shouldn't happen */
602         msg_Err( VLCIntf, "cannot find switched video-filter" );
603     }
604 }
605
606 - (IBAction)moreInfoVideoFilters:(id)sender
607 {
608     /* show info sheet */
609     NSBeginInformationalAlertSheet(_NS("About the video filters"), _NS("OK"), @"", @"",
610         o_extended_window, nil, nil, nil, nil, _NS("This panel allows "
611         "on-the-fly selection of various video effects.\n"
612         "These filters can be configured individually in the Preferences, in "
613         "the subsections of Video/Filters.\n"
614         "To choose the order in which the filter are applied, a filter "
615         "option string can be set in the Preferences, Video / Filters section."));
616 }
617
618
619 /*****************************************************************************
620  * methods to communicate changes to VLC's core
621  *****************************************************************************/
622
623 - (void)changeVoutFiltersString:(char *)psz_name onOrOff:(vlc_bool_t )b_add
624 {
625     /* copied from ../wxwidgets/extrapanel.cpp
626      * renamed to conform with Cocoa's rules */
627     /* this method only changes 1st generation video filters (the ones which
628      * can't be used for transcoding). Have a look at changeVideoFiltersString
629      * for the 2nd generation filters. */
630  
631     vout_thread_t *p_vout;
632     intf_thread_t * p_intf = VLCIntf;
633  
634     char *psz_parser, *psz_string;
635     psz_string = config_GetPsz( p_intf, "vout-filter" );
636  
637     if( !psz_string ) psz_string = strdup("");
638
639     psz_parser = strstr( psz_string, psz_name );
640
641     if( b_add )
642     {
643         if( !psz_parser )
644         {
645             psz_parser = psz_string;
646             asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
647                             psz_string, psz_name );
648             free( psz_parser );
649         }
650         else
651         {
652             return;
653         }
654     }
655     else
656     {
657         if( psz_parser )
658         {
659             memmove( psz_parser, psz_parser + strlen(psz_name) +
660                             (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
661                             strlen(psz_parser + strlen(psz_name)) + 1 );
662
663             /* Remove trailing : : */
664             if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
665             {
666                 *(psz_string+strlen(psz_string ) -1 ) = '\0';
667             }
668          }
669          else
670          {
671              free( psz_string );
672              return;
673          }
674     }
675     /* Vout is not kept, so put that in the config */
676     config_PutPsz( p_intf, "vout-filter", psz_string );
677
678     /* Try to set on the fly */
679     p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
680                                               FIND_ANYWHERE );
681     if( p_vout )
682     {
683         var_SetString( p_vout, "vout-filter", psz_string );
684         vlc_object_release( p_vout );
685     }
686
687     free( psz_string );
688
689     o_config_changed = YES;
690 }
691
692
693 - (void)changeVideoFiltersString:(char *)psz_name onOrOff:(vlc_bool_t )b_add
694 {
695     /* same as changeVoutFiltersString but addressing the "video-filter"
696      * variable which represents the video filter 2 modules */
697  
698     vout_thread_t *p_vout;
699     intf_thread_t * p_intf = VLCIntf;
700  
701     char *psz_parser, *psz_string;
702     psz_string = config_GetPsz( p_intf, "video-filter" );
703  
704     if( !psz_string ) psz_string = strdup("");
705
706     psz_parser = strstr( psz_string, psz_name );
707
708     if( b_add )
709     {
710         if( !psz_parser )
711         {
712             psz_parser = psz_string;
713             asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
714                             psz_string, psz_name );
715             free( psz_parser );
716         }
717         else
718         {
719             return;
720         }
721     }
722     else
723     {
724         if( psz_parser )
725         {
726             memmove( psz_parser, psz_parser + strlen(psz_name) +
727                             (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
728                             strlen(psz_parser + strlen(psz_name)) + 1 );
729
730             /* Remove trailing : : */
731             if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
732             {
733                 *(psz_string+strlen(psz_string ) -1 ) = '\0';
734             }
735          }
736          else
737          {
738              free( psz_string );
739              return;
740          }
741     }
742     /* Vout is not kept, so put that in the config */
743     config_PutPsz( p_intf, "video-filter", psz_string );
744
745     /* Try to set on the fly */
746     p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
747                                               FIND_ANYWHERE );
748     if( p_vout )
749     {
750         var_SetString( p_vout, "video-filter", psz_string );
751         vlc_object_release( p_vout );
752     }
753
754     free( psz_string );
755
756     o_config_changed = YES;
757 }
758
759 - (void)changeAFiltersString: (char *)psz_name onOrOff: (vlc_bool_t )b_add;
760 {
761     /* copied from ../wxwidgets/extrapanel.cpp
762      * renamed to conform with Cocoa's rules */
763
764     char *psz_parser, *psz_string;
765     intf_thread_t * p_intf = VLCIntf;
766     aout_instance_t * p_aout= (aout_instance_t *)vlc_object_find(p_intf,
767                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
768
769     if( p_aout )
770     {
771         psz_string = var_GetString( p_aout, "audio-filter" );
772     }
773     else
774     {
775         psz_string = config_GetPsz( p_intf, "audio-filter" );
776     }
777
778     if( !psz_string ) psz_string = strdup("");
779
780     psz_parser = strstr( psz_string, psz_name );
781
782     if( b_add )
783     {
784         if( !psz_parser )
785         {
786             psz_parser = psz_string;
787             asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
788                             psz_string, psz_name );
789             free( psz_parser );
790         }
791         else
792         {
793             return;
794         }
795     }
796     else
797     {
798         if( psz_parser )
799         {
800             memmove( psz_parser, psz_parser + strlen(psz_name) +
801                             (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
802                             strlen(psz_parser + strlen(psz_name)) + 1 );
803
804             if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
805             {
806                 *(psz_string+strlen(psz_string ) -1 ) = '\0';
807             }
808          }
809          else
810          {
811              free( psz_string );
812              return;
813          }
814     }
815
816     if( p_aout == NULL )
817     {
818         config_PutPsz( p_intf, "audio-filter", psz_string );
819     }
820     else
821     {
822         var_SetString( p_aout, "audio-filter", psz_string );
823         int i = 0;
824         while( i < p_aout->i_nb_inputs )
825         {
826             p_aout->pp_inputs[i]->b_restart = VLC_TRUE;
827             i = (i + 1);
828         }
829         vlc_object_release( p_aout );
830     }
831     free( psz_string );
832
833     o_config_changed = YES;
834 }
835
836 - (void)savePrefs
837 {
838     /* save the preferences to make sure that our module-changes will up on
839      * next launch again */
840     playlist_t * p_playlist = pl_Yield( VLCIntf );
841     int returnedValue;
842     NSArray * theModules;
843     theModules = [[NSArray alloc] initWithObjects: @"main", @"headphone",
844         @"transform", @"adjust", @"invert", @"motionblur", @"distort",
845         @"clone", @"crop", @"normvol", @"headphone_channel_mixer", @"macosx",
846         nil];
847     unsigned int x = 0;
848  
849     while ( x != [theModules count] )
850     {
851         returnedValue = config_SaveConfigFile( p_playlist, [[theModules
852             objectAtIndex: x] UTF8String] );
853
854         if (returnedValue != 0)
855         {
856             msg_Err(p_playlist, "unable to save the preferences of the "
857             "extended control attribute '%s' (%i)",
858             [[theModules objectAtIndex: x] UTF8String] , returnedValue);
859             [theModules release];
860             vlc_object_release( p_playlist );
861  
862             return;
863         }
864
865         x = ( x + 1 );
866     }
867  
868     msg_Dbg( p_playlist, "VLCExtended: saved certain preferences successfully" );
869  
870     [theModules release];
871     vlc_object_release( p_playlist );
872 }
873 @end