]> git.sesse.net Git - vlc/blob - modules/gui/macosx/VideoEffects.m
macosx: fixed conditionals for the different OS X release by adapting to the newly...
[vlc] / modules / gui / macosx / VideoEffects.m
1 /*****************************************************************************
2  * VideoEffects.m: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2011-2012 Felix Paul Kühne
5  * $Id$
6  *
7  * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- 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 #import "CompatibilityFixes.h"
25 #import "intf.h"
26 #import <vlc_common.h>
27 #import <vlc_modules.h>
28 #import <vlc_charset.h>
29 #import "VideoEffects.h"
30
31 #pragma mark -
32 #pragma mark Initialization & Generic code
33
34 @implementation VLCVideoEffects
35 static VLCVideoEffects *_o_sharedInstance = nil;
36
37 + (VLCVideoEffects *)sharedInstance
38 {
39     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
40 }
41
42 - (id)init
43 {
44     if (_o_sharedInstance) {
45         [self dealloc];
46     } else {
47         p_intf = VLCIntf;
48         _o_sharedInstance = [super init];
49     }
50
51     return _o_sharedInstance;
52 }
53
54 - (IBAction)toggleWindow:(id)sender
55 {
56     if( [o_window isVisible] )
57         [o_window orderOut:sender];
58     else
59         [o_window makeKeyAndOrderFront:sender];
60 }
61
62 - (void)awakeFromNib
63 {
64     [o_window setTitle: _NS("Video Effects")];
65     [o_window setExcludedFromWindowsMenu:YES];
66     if (!OSX_SNOW_LEOPARD)
67         [o_window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
68
69     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"basic"]] setLabel:_NS("Basic")];
70     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"crop"]] setLabel:_NS("Crop")];
71     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"geometry"]] setLabel:_NS("Geometry")];
72     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"color"]] setLabel:_NS("Color")];
73     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"misc"]] setLabel:_NS("Miscellaneous")];
74
75     [o_adjust_ckb setTitle:_NS("Image Adjust")];
76     [o_adjust_hue_lbl setStringValue:_NS("Hue")];
77     [o_adjust_contrast_lbl setStringValue:_NS("Contrast")];
78     [o_adjust_brightness_lbl setStringValue:_NS("Brightness")];
79     [o_adjust_brightness_ckb setTitle:_NS("Brightness Threshold")];
80     [o_adjust_saturation_lbl setStringValue:_NS("Saturation")];
81     [o_adjust_gamma_lbl setStringValue:_NS("Gamma")];
82     [o_adjust_reset_btn setTitle: _NS("Reset")];
83     [o_sharpen_ckb setTitle:_NS("Sharpen")];
84     [o_sharpen_lbl setStringValue:_NS("Sigma")];
85     [o_banding_ckb setTitle:_NS("Banding removal")];
86     [o_banding_lbl setStringValue:_NS("Radius")];
87     [o_grain_ckb setTitle:_NS("Film Grain")];
88     [o_grain_lbl setStringValue:_NS("Variance")];
89     [o_crop_top_lbl setStringValue:_NS("Top")];
90     [o_crop_left_lbl setStringValue:_NS("Left")];
91     [o_crop_right_lbl setStringValue:_NS("Right")];
92     [o_crop_bottom_lbl setStringValue:_NS("Bottom")];
93     [o_crop_sync_top_bottom_ckb setTitle:_NS("Synchronize top and bottom")];
94     [o_crop_sync_left_right_ckb setTitle:_NS("Synchronize left and right")];
95
96     [o_transform_ckb setTitle:_NS("Transform")];
97     [o_transform_pop removeAllItems];
98     [o_transform_pop addItemWithTitle: _NS("Rotate by 90 degrees")];
99     [[o_transform_pop lastItem] setTag: 90];
100     [o_transform_pop addItemWithTitle: _NS("Rotate by 180 degrees")];
101     [[o_transform_pop lastItem] setTag: 180];
102     [o_transform_pop addItemWithTitle: _NS("Rotate by 270 degrees")];
103     [[o_transform_pop lastItem] setTag: 270];
104     [o_transform_pop addItemWithTitle: _NS("Flip horizontally")];
105     [[o_transform_pop lastItem] setTag: 1];
106     [o_transform_pop addItemWithTitle: _NS("Flip vertically")];
107     [[o_transform_pop lastItem] setTag: 2];
108     [o_zoom_ckb setTitle:_NS("Magnification/Zoom")];
109     [o_puzzle_ckb setTitle:_NS("Puzzle game")];
110     [o_puzzle_rows_lbl setStringValue:_NS("Rows")];
111     [o_puzzle_columns_lbl setStringValue:_NS("Columns")];
112     [o_puzzle_blackslot_ckb setTitle:_NS("Black Slot")];
113
114     [o_threshold_ckb setTitle:_NS("Color threshold")];
115     [o_threshold_color_lbl setStringValue:_NS("Color")];
116     [o_threshold_saturation_lbl setStringValue:_NS("Saturation")];
117     [o_threshold_similarity_lbl setStringValue:_NS("Similarity")];
118     [o_sepia_ckb setTitle:_NS("Sepia")];
119     [o_sepia_lbl setStringValue:_NS("Intensity")];
120     [o_noise_ckb setTitle:_NS("Noise")];
121     [o_gradient_ckb setTitle:_NS("Gradient")];
122     [o_gradient_mode_lbl setStringValue:_NS("Mode")];
123     [o_gradient_mode_pop removeAllItems];
124     [o_gradient_mode_pop addItemWithTitle: _NS("Gradient")];
125     [[o_gradient_mode_pop lastItem] setTag: 1];
126     [o_gradient_mode_pop addItemWithTitle: _NS("Edge")];
127     [[o_gradient_mode_pop lastItem] setTag: 2];
128     [o_gradient_mode_pop addItemWithTitle: _NS("Hough")];
129     [[o_gradient_mode_pop lastItem] setTag: 3];
130     [o_gradient_color_ckb setTitle:_NS("Color")];
131     [o_gradient_cartoon_ckb setTitle:_NS("Cartoon")];
132     [o_extract_ckb setTitle:_NS("Color extraction")];
133     [o_extract_lbl setStringValue:_NS("Color")];
134     [o_invert_ckb setTitle:_NS("Invert colors")];
135     [o_posterize_ckb setTitle:_NS("Posterize")];
136     [o_posterize_lbl setStringValue:_NS("Posterize level")];
137     [o_blur_ckb setTitle:_NS("Motion blur")];
138     [o_blur_lbl setStringValue:_NS("Factor")];
139     [o_motiondetect_ckb setTitle:_NS("Motion Detect")];
140     [o_watereffect_ckb setTitle:_NS("Water effect")];
141     [o_waves_ckb setTitle:_NS("Waves")];
142     [o_psychedelic_ckb setTitle:_NS("Psychedelic")];
143     [o_anaglyph_ckb setTitle:_NS("Anaglyph 3D")];
144
145     [o_addtext_ckb setTitle:_NS("Add text")];
146     [o_addtext_text_lbl setStringValue:_NS("Text")];
147     [o_addtext_pos_lbl setStringValue:_NS("Position")];
148     [o_addtext_pos_pop removeAllItems];
149     [o_addtext_pos_pop addItemWithTitle: _NS("Center")];
150     [[o_addtext_pos_pop lastItem] setTag: 0];
151     [o_addtext_pos_pop addItemWithTitle: _NS("Left")];
152     [[o_addtext_pos_pop lastItem] setTag: 1];
153     [o_addtext_pos_pop addItemWithTitle: _NS("Right")];
154     [[o_addtext_pos_pop lastItem] setTag: 2];
155     [o_addtext_pos_pop addItemWithTitle: _NS("Top")];
156     [[o_addtext_pos_pop lastItem] setTag: 4];
157     [o_addtext_pos_pop addItemWithTitle: _NS("Bottom")];
158     [[o_addtext_pos_pop lastItem] setTag: 8];
159     [o_addtext_pos_pop addItemWithTitle: _NS("Top-Left")];
160     [[o_addtext_pos_pop lastItem] setTag: 5];
161     [o_addtext_pos_pop addItemWithTitle: _NS("Top-Right")];
162     [[o_addtext_pos_pop lastItem] setTag: 6];
163     [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Left")];
164     [[o_addtext_pos_pop lastItem] setTag: 9];
165     [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Right")];
166     [[o_addtext_pos_pop lastItem] setTag: 10];
167     [o_addlogo_ckb setTitle:_NS("Add logo")];
168     [o_addlogo_logo_lbl setStringValue:_NS("Logo")];
169     [o_addlogo_pos_lbl setStringValue:_NS("Position")];
170     [o_addlogo_pos_pop removeAllItems];
171     [o_addlogo_pos_pop addItemWithTitle: _NS("Center")];
172     [[o_addlogo_pos_pop lastItem] setTag: 0];
173     [o_addlogo_pos_pop addItemWithTitle: _NS("Left")];
174     [[o_addlogo_pos_pop lastItem] setTag: 1];
175     [o_addlogo_pos_pop addItemWithTitle: _NS("Right")];
176     [[o_addlogo_pos_pop lastItem] setTag: 2];
177     [o_addlogo_pos_pop addItemWithTitle: _NS("Top")];
178     [[o_addlogo_pos_pop lastItem] setTag: 4];
179     [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom")];
180     [[o_addlogo_pos_pop lastItem] setTag: 8];
181     [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Left")];
182     [[o_addlogo_pos_pop lastItem] setTag: 5];
183     [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Right")];
184     [[o_addlogo_pos_pop lastItem] setTag: 6];
185     [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Left")];
186     [[o_addlogo_pos_pop lastItem] setTag: 9];
187     [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Right")];
188     [[o_addlogo_pos_pop lastItem] setTag: 10];
189     [o_addlogo_transparency_lbl setStringValue:_NS("Transparency")];
190
191     [o_tableView selectFirstTabViewItem:self];
192
193     [self resetValues];
194 }
195
196 - (void)resetValues
197 {
198     NSString *tmpString;
199     char *tmpChar;
200     BOOL b_state;
201
202     /* do we have any filter enabled? if yes, show it. */
203     char * psz_vfilters;
204     psz_vfilters = config_GetPsz( p_intf, "video-filter" );
205     if( psz_vfilters ) {
206         [o_adjust_ckb setState: (NSInteger)strstr( psz_vfilters, "adjust")];
207         [o_sharpen_ckb setState: (NSInteger)strstr( psz_vfilters, "sharpen")];
208         [o_banding_ckb setState: (NSInteger)strstr( psz_vfilters, "gradfun")];
209         [o_grain_ckb setState: (NSInteger)strstr( psz_vfilters, "grain")];
210         [o_transform_ckb setState: (NSInteger)strstr( psz_vfilters, "transform")];
211         [o_zoom_ckb setState: (NSInteger)strstr( psz_vfilters, "magnify")];
212         [o_puzzle_ckb setState: (NSInteger)strstr( psz_vfilters, "puzzle")];
213         [o_threshold_ckb setState: (NSInteger)strstr( psz_vfilters, "colorthres")];
214         [o_sepia_ckb setState: (NSInteger)strstr( psz_vfilters, "sepia")];
215         [o_noise_ckb setState: (NSInteger)strstr( psz_vfilters, "noise")];
216         [o_gradient_ckb setState: (NSInteger)strstr( psz_vfilters, "gradient")];
217         [o_extract_ckb setState: (NSInteger)strstr( psz_vfilters, "extract")];
218         [o_invert_ckb setState: (NSInteger)strstr( psz_vfilters, "invert")];
219         [o_posterize_ckb setState: (NSInteger)strstr( psz_vfilters, "posterize")];
220         [o_blur_ckb setState: (NSInteger)strstr( psz_vfilters, "motionblur")];
221         [o_motiondetect_ckb setState: (NSInteger)strstr( psz_vfilters, "motiondetect")];
222         [o_watereffect_ckb setState: (NSInteger)strstr( psz_vfilters, "ripple")];
223         [o_waves_ckb setState: (NSInteger)strstr( psz_vfilters, "wave")];
224         [o_psychedelic_ckb setState: (NSInteger)strstr( psz_vfilters, "psychedelic")];
225         [o_anaglyph_ckb setState: (NSInteger)strstr( psz_vfilters, "anaglyph")];
226         free( psz_vfilters );
227     }
228     psz_vfilters = config_GetPsz( p_intf, "sub-source" );
229     if (psz_vfilters) {
230         [o_addtext_ckb setState: (NSInteger)strstr( psz_vfilters, "marq" )];
231         [o_addlogo_ckb setState: (NSInteger)strstr( psz_vfilters, "logo" )];
232         free( psz_vfilters );
233     }
234
235     /* fetch and show the various values */
236     [o_adjust_hue_sld setIntValue: config_GetInt( p_intf, "hue" )];
237     [o_adjust_contrast_sld setFloatValue: config_GetFloat( p_intf, "contrast" )];
238     [o_adjust_brightness_sld setFloatValue: config_GetFloat( p_intf, "brightness" )];
239     [o_adjust_saturation_sld setFloatValue: config_GetFloat( p_intf, "saturation" )];
240     [o_adjust_gamma_sld setFloatValue: config_GetFloat( p_intf, "gamma" )];
241     [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "brightness" )]];
242     [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "contrast" )]];
243     [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "gamma" )]];
244     [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "hue" )]];
245     [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "saturation" )]];
246     b_state = [o_adjust_ckb state];
247     [o_adjust_brightness_sld setEnabled: b_state];
248     [o_adjust_brightness_ckb setEnabled: b_state];
249     [o_adjust_contrast_sld setEnabled: b_state];
250     [o_adjust_gamma_sld setEnabled: b_state];
251     [o_adjust_hue_sld setEnabled: b_state];
252     [o_adjust_saturation_sld setEnabled: b_state];
253     [o_adjust_brightness_lbl setEnabled: b_state];
254     [o_adjust_contrast_lbl setEnabled: b_state];
255     [o_adjust_gamma_lbl setEnabled: b_state];
256     [o_adjust_hue_lbl setEnabled: b_state];
257     [o_adjust_saturation_lbl setEnabled: b_state];
258     [o_adjust_reset_btn setEnabled: b_state];
259     [o_sharpen_sld setFloatValue: config_GetFloat( p_intf, "sharpen-sigma" )];
260     [o_sharpen_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "sharpen-sigma" )]];
261     [o_sharpen_sld setEnabled: [o_sharpen_ckb state]];
262     [o_sharpen_lbl setEnabled: [o_sharpen_ckb state]];
263     [o_banding_sld setIntValue: config_GetInt( p_intf, "gradfun-radius" )];
264     [o_banding_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "gradfun-radius" )]];
265     [o_banding_sld setEnabled: [o_banding_ckb state]];
266     [o_banding_lbl setEnabled: [o_banding_ckb state]];
267     [o_grain_sld setFloatValue: config_GetFloat( p_intf, "grain-variance" )];
268     [o_grain_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat( p_intf, "grain-variance" )]];
269     [o_grain_sld setEnabled: [o_grain_ckb state]];
270     [o_grain_lbl setEnabled: [o_grain_ckb state]];
271
272     [o_crop_top_fld setIntValue: 0];
273     [o_crop_left_fld setIntValue: 0];
274     [o_crop_right_fld setIntValue: 0];
275     [o_crop_bottom_fld setIntValue: 0];
276     [o_crop_sync_top_bottom_ckb setState: NSOffState];
277     [o_crop_sync_left_right_ckb setState: NSOffState];
278
279     tmpChar = config_GetPsz( p_intf, "transform-type" );
280     tmpString = [NSString stringWithUTF8String: tmpChar];
281     if( [tmpString isEqualToString:@"hflip"] )
282         [o_transform_pop selectItemWithTag: 1];
283     else if( [tmpString isEqualToString:@"vflip"] )
284         [o_transform_pop selectItemWithTag: 2];
285     else
286         [o_transform_pop selectItemWithTag:[tmpString intValue]];
287     FREENULL( tmpChar );
288     [o_transform_pop setEnabled: [o_transform_ckb state]];
289     [o_puzzle_rows_fld setIntValue: config_GetInt( p_intf, "puzzle-rows" )];
290     [o_puzzle_columns_fld setIntValue: config_GetInt( p_intf, "puzzle-cols" )];
291     [o_puzzle_blackslot_ckb setState: config_GetInt( p_intf, "puzzle-black-slot" )];
292     b_state = [o_puzzle_ckb state];
293     [o_puzzle_rows_fld setEnabled: b_state];
294     [o_puzzle_rows_lbl setEnabled: b_state];
295     [o_puzzle_columns_fld setEnabled: b_state];
296     [o_puzzle_columns_lbl setEnabled: b_state];
297     [o_puzzle_blackslot_ckb setEnabled: b_state];
298
299     [o_threshold_color_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt( p_intf, "colorthres-color" )] uppercaseString]];
300     [o_threshold_saturation_sld setIntValue: config_GetInt( p_intf, "colorthres-saturationthres" )];
301     [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "colorthres-saturationthres" )]];
302     [o_threshold_similarity_sld setIntValue: config_GetInt( p_intf, "colorthres-similaritythres" )];
303     [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "colorthres-similaritythres" )]];
304     b_state = [o_threshold_ckb state];
305     [o_threshold_color_fld setEnabled: b_state];
306     [o_threshold_color_lbl setEnabled: b_state];
307     [o_threshold_saturation_sld setEnabled: b_state];
308     [o_threshold_saturation_lbl setEnabled: b_state];
309     [o_threshold_similarity_sld setEnabled: b_state];
310     [o_threshold_similarity_lbl setEnabled: b_state];
311     [o_sepia_fld setIntValue: config_GetInt( p_intf, "sepia-intensity" )];
312     [o_sepia_fld setEnabled: [o_sepia_ckb state]];
313     [o_sepia_lbl setEnabled: [o_sepia_ckb state]];
314     tmpChar = config_GetPsz( p_intf, "gradient-mode" );
315     tmpString = [NSString stringWithUTF8String: tmpChar];
316     if( [tmpString isEqualToString:@"hough"] )
317         [o_gradient_mode_pop selectItemWithTag: 3];
318     else if( [tmpString isEqualToString:@"edge"] )
319         [o_gradient_mode_pop selectItemWithTag: 2];
320     else
321         [o_gradient_mode_pop selectItemWithTag: 1];
322     FREENULL( tmpChar );
323     [o_gradient_cartoon_ckb setState: config_GetInt( p_intf, "gradient-cartoon" )];
324     [o_gradient_color_ckb setState: config_GetInt( p_intf, "gradient-type" )];
325     b_state = [o_gradient_ckb state];
326     [o_gradient_mode_pop setEnabled: b_state];
327     [o_gradient_mode_lbl setEnabled: b_state];
328     [o_gradient_cartoon_ckb setEnabled: b_state];
329     [o_gradient_color_ckb setEnabled: b_state];
330     [o_extract_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt( p_intf, "extract-component" )] uppercaseString]];
331     [o_extract_fld setEnabled: [o_extract_ckb state]];
332     [o_extract_lbl setEnabled: [o_extract_ckb state]];
333     [o_posterize_fld setIntValue: config_GetInt( p_intf, "posterize-level" )];
334     [o_posterize_fld setEnabled: [o_posterize_ckb state]];
335     [o_posterize_lbl setEnabled: [o_posterize_ckb state]];
336     [o_blur_sld setIntValue: config_GetInt( p_intf, "blur-factor" )];
337     [o_blur_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "blur-factor" )]];
338     [o_blur_sld setEnabled: [o_blur_ckb state]];
339     [o_blur_lbl setEnabled: [o_blur_ckb state]];
340
341     tmpChar = config_GetPsz( p_intf, "marq-marquee" );
342     if( tmpChar )
343     {
344         [o_addtext_text_fld setStringValue: [NSString stringWithUTF8String: tmpChar]];
345         FREENULL( tmpChar );
346     }
347     [o_addtext_pos_pop selectItemWithTag: config_GetInt( p_intf, "marq-position" )];
348     b_state = [o_addtext_ckb state];
349     [o_addtext_pos_pop setEnabled: b_state];
350     [o_addtext_pos_lbl setEnabled: b_state];
351     [o_addtext_text_lbl setEnabled: b_state];
352     [o_addtext_text_fld setEnabled: b_state];
353
354     tmpChar = config_GetPsz( p_intf, "logo-file" );
355     if( tmpChar )
356     {
357        [o_addlogo_logo_fld setStringValue: [NSString stringWithUTF8String: tmpChar]];
358         FREENULL( tmpChar );
359     }
360     [o_addlogo_pos_pop selectItemWithTag: config_GetInt( p_intf, "logo-position" )];
361     [o_addlogo_transparency_sld setIntValue: config_GetInt( p_intf, "logo-opacity" )];
362     [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt( p_intf, "logo-opacity" )]];
363     b_state = [o_addlogo_ckb state];
364     [o_addlogo_pos_pop setEnabled: b_state];
365     [o_addlogo_pos_lbl setEnabled: b_state];
366     [o_addlogo_logo_fld setEnabled: b_state];
367     [o_addlogo_logo_lbl setEnabled: b_state];
368     [o_addlogo_transparency_sld setEnabled: b_state];
369     [o_addlogo_transparency_lbl setEnabled: b_state];
370 }
371
372 - (void)setVideoFilter: (char *)psz_name on:(BOOL)b_on
373 {
374     char *psz_string, *psz_parser;
375     const char *psz_filter_type;
376
377     module_t *p_obj = module_find( psz_name );
378     if( !p_obj )
379     {
380         msg_Err( p_intf, "Unable to find filter module \"%s\".", psz_name );
381         return;
382     }
383     msg_Dbg( p_intf, "will set filter '%s'", psz_name );
384
385     if( module_provides( p_obj, "video splitter" ) )
386     {
387         psz_filter_type = "video-splitter";
388     }
389     else if( module_provides( p_obj, "video filter2" ) )
390     {
391         psz_filter_type = "video-filter";
392     }
393     else if( module_provides( p_obj, "sub source" ) )
394     {
395         psz_filter_type = "sub-source";
396     }
397     else if( module_provides( p_obj, "sub filter" ) )
398     {
399         psz_filter_type = "sub-filter";
400     }
401     else
402     {
403         msg_Err( p_intf, "Unknown video filter type." );
404         return;
405     }
406
407     psz_string = config_GetPsz( p_intf, psz_filter_type );
408
409     if (b_on) {
410         if(! psz_string)
411             psz_string = psz_name;
412         else if( (NSInteger)strstr( psz_string, psz_name ) == NO )
413             psz_string = (char *)[[NSString stringWithFormat: @"%s:%s", psz_string, psz_name] UTF8String];
414     } else {
415         if( !psz_string )
416             return;
417
418         psz_parser = strstr( psz_string, psz_name );
419         if( psz_parser )
420         {
421             if( *( psz_parser + strlen( psz_name ) ) == ':' )
422             {
423                 memmove( psz_parser, psz_parser + strlen( psz_name ) + 1,
424                         strlen( psz_parser + strlen( psz_name ) + 1 ) + 1 );
425             }
426             else
427             {
428                 *psz_parser = '\0';
429             }
430
431             /* Remove trailing : : */
432             if( strlen( psz_string ) > 0 &&
433                *( psz_string + strlen( psz_string ) -1 ) == ':' )
434             {
435                 *( psz_string + strlen( psz_string ) -1 ) = '\0';
436             }
437         }
438         else
439         {
440             free( psz_string );
441             return;
442         }
443     }
444     config_PutPsz( p_intf, psz_filter_type, psz_string );
445
446     /* Try to set on the fly */
447     if( !strcmp( psz_filter_type, "video-splitter" ) )
448     {
449         playlist_t *p_playlist = pl_Get( p_intf );
450         var_SetString( p_playlist, psz_filter_type, psz_string );
451     }
452     else
453     {
454         vout_thread_t *p_vout = getVout();
455         if( p_vout )
456         {
457             var_SetString( p_vout, psz_filter_type, psz_string );
458             vlc_object_release( p_vout );
459         }
460     }
461 }
462
463 - (void)restartFilterIfNeeded: (char *)psz_filter option: (char *)psz_name
464 {
465     vout_thread_t *p_vout = getVout();
466
467     if (p_vout == NULL)
468         return;
469     else
470         vlc_object_release( p_vout );
471
472     vlc_object_t *p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
473     int i_type;
474     i_type = var_Type( p_filter, psz_name );
475     if( i_type == 0 )
476         i_type = config_GetType( p_intf, psz_name );
477
478     if( !(i_type & VLC_VAR_ISCOMMAND) )
479     {
480         msg_Warn( p_intf, "Brute-restarting filter '%s', because the last changed option isn't a command", psz_name );
481         [self setVideoFilter: psz_filter on: NO];
482         [self setVideoFilter: psz_filter on: YES];
483     }
484     else
485         msg_Dbg( p_intf, "restart not needed" );
486
487     if( p_filter )
488         vlc_object_release( p_filter );
489 }
490
491 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter integer: (int)i_value
492 {
493     vout_thread_t *p_vout = getVout();
494     vlc_object_t *p_filter;
495
496     if( p_vout == NULL ) {
497         config_PutInt( p_intf , psz_name , i_value );
498     } else {
499         p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
500
501         if(! p_filter ) {
502             msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
503             vlc_object_release( p_vout );
504             return;
505         }
506         var_SetInteger( p_filter, psz_name, i_value );
507         config_PutInt( p_intf, psz_name, i_value );
508         vlc_object_release( p_vout );
509         vlc_object_release( p_filter );
510     }
511
512     [self restartFilterIfNeeded:psz_filter option: psz_name];
513 }
514
515 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter float: (float)f_value
516 {
517     vout_thread_t *p_vout = getVout();
518     vlc_object_t *p_filter;
519
520     if( p_vout == NULL ) {
521         config_PutFloat( p_intf , psz_name , f_value );
522     } else {
523         p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
524
525         if(! p_filter ) {
526             msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
527             vlc_object_release( p_vout );
528             return;
529         }
530         var_SetFloat( p_filter, psz_name, f_value );
531         config_PutFloat( p_intf, psz_name, f_value );
532         vlc_object_release( p_vout );
533         vlc_object_release( p_filter );
534
535         [self restartFilterIfNeeded:psz_filter option: psz_name];
536     }
537 }
538
539 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter string: (char *)psz_value
540 {
541     vout_thread_t *p_vout = getVout();
542     vlc_object_t *p_filter;
543
544     if( p_vout == NULL ) {
545         config_PutPsz( p_intf, psz_name, EnsureUTF8(psz_value) );
546     } else {
547         p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
548
549         if(! p_filter ) {
550             msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
551             vlc_object_release( p_vout );
552             return;
553         }
554         var_SetString( p_filter, psz_name, EnsureUTF8(psz_value) );
555         config_PutPsz( p_intf, psz_name, EnsureUTF8(psz_value) );
556         vlc_object_release( p_vout );
557         vlc_object_release( p_filter );
558
559         [self restartFilterIfNeeded:psz_filter option: psz_name];
560     }
561 }
562
563 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter boolean: (BOOL)b_value
564 {
565     vout_thread_t *p_vout = getVout();
566     vlc_object_t *p_filter;
567
568     if( p_vout == NULL ) {
569         config_PutInt( p_intf, psz_name, b_value );
570     } else {
571         p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
572
573         if(! p_filter ) {
574             msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
575             vlc_object_release( p_vout );
576             return;
577         }
578         var_SetBool( p_filter, psz_name, b_value );
579         config_PutInt( p_intf, psz_name, b_value );
580         vlc_object_release( p_vout );
581     }
582 }
583
584 #pragma mark -
585 #pragma mark basic
586 - (IBAction)enableAdjust:(id)sender
587 {
588     BOOL b_state = [o_adjust_ckb state];
589
590     [self setVideoFilter: "adjust" on: b_state];
591     [o_adjust_brightness_sld setEnabled: b_state];
592     [o_adjust_brightness_ckb setEnabled: b_state];
593     [o_adjust_brightness_lbl setEnabled: b_state];
594     [o_adjust_contrast_sld setEnabled: b_state];
595     [o_adjust_contrast_lbl setEnabled: b_state];
596     [o_adjust_gamma_sld setEnabled: b_state];
597     [o_adjust_gamma_lbl setEnabled: b_state];
598     [o_adjust_hue_sld setEnabled: b_state];
599     [o_adjust_hue_lbl setEnabled: b_state];
600     [o_adjust_saturation_sld setEnabled: b_state];
601     [o_adjust_saturation_lbl setEnabled: b_state];
602     [o_adjust_reset_btn setEnabled: b_state];
603 }
604
605 - (IBAction)adjustSliderChanged:(id)sender
606 {
607     if( sender == o_adjust_brightness_sld )
608         [self setVideoFilterProperty: "brightness" forFilter: "adjust" float: [o_adjust_brightness_sld floatValue]];
609     else if( sender == o_adjust_contrast_sld )
610         [self setVideoFilterProperty: "contrast" forFilter: "adjust" float: [o_adjust_contrast_sld floatValue]];
611     else if( sender == o_adjust_gamma_sld )
612         [self setVideoFilterProperty: "gamma" forFilter: "adjust" float: [o_adjust_gamma_sld floatValue]];
613     else if( sender == o_adjust_hue_sld )
614         [self setVideoFilterProperty: "hue" forFilter: "adjust" integer: [o_adjust_hue_sld intValue]];
615     else if( sender == o_adjust_saturation_sld )
616         [self setVideoFilterProperty: "saturation" forFilter: "adjust" float: [o_adjust_saturation_sld floatValue]];
617
618     if( sender == o_adjust_hue_sld )
619         [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%i", [o_adjust_hue_sld intValue]]];
620     else
621         [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
622 }
623
624 - (IBAction)enableAdjustBrightnessThreshold:(id)sender
625 {
626     if (sender == o_adjust_reset_btn)
627     {
628         [o_adjust_brightness_sld setFloatValue: 1.0];
629         [o_adjust_contrast_sld setFloatValue: 1.0];
630         [o_adjust_gamma_sld setFloatValue: 1.0];
631         [o_adjust_hue_sld setIntValue: 0];
632         [o_adjust_saturation_sld setFloatValue: 1.0];
633         [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
634         [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
635         [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
636         [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%i", 0]];
637         [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
638         [self setVideoFilterProperty: "brightness" forFilter: "adjust" float: 1.0];
639         [self setVideoFilterProperty: "contrast" forFilter: "adjust" float: 1.0];
640         [self setVideoFilterProperty: "gamma" forFilter: "adjust" float: 1.0];
641         [self setVideoFilterProperty: "hue" forFilter: "adjust" integer: 0.0];
642         [self setVideoFilterProperty: "saturation" forFilter: "adjust" float: 1.0];
643     }
644     else
645         config_PutInt( p_intf, "brightness-threshold", [o_adjust_brightness_ckb state] );
646 }
647
648 - (IBAction)enableSharpen:(id)sender
649 {
650     BOOL b_state = [o_sharpen_ckb state];
651
652     [self setVideoFilter: "sharpen" on: b_state];
653     [o_sharpen_sld setEnabled: b_state];
654     [o_sharpen_lbl setEnabled: b_state];
655 }
656
657 - (IBAction)sharpenSliderChanged:(id)sender
658 {
659     [self setVideoFilterProperty: "sharpen-sigma" forFilter: "sharpen" float: [sender floatValue]];
660     [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
661 }
662
663 - (IBAction)enableBanding:(id)sender
664 {
665     BOOL b_state = [o_banding_ckb state];
666
667     [self setVideoFilter: "gradfun" on: b_state];
668     [o_banding_sld setEnabled: b_state];
669     [o_banding_lbl setEnabled: b_state];
670 }
671
672 - (IBAction)bandingSliderChanged:(id)sender
673 {
674     [self setVideoFilterProperty: "gradfun-radius" forFilter: "gradfun" integer: [sender intValue]];
675     [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
676 }
677
678 - (IBAction)enableGrain:(id)sender
679 {
680     BOOL b_state = [o_grain_ckb state];
681
682     [self setVideoFilter: "grain" on: b_state];
683     [o_grain_sld setEnabled: b_state];
684     [o_grain_lbl setEnabled: b_state];
685 }
686
687 - (IBAction)grainSliderChanged:(id)sender
688 {
689     [self setVideoFilterProperty: "grain-variance" forFilter: "grain" float: [sender floatValue]];
690     [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
691 }
692
693
694 #pragma mark -
695 #pragma mark crop
696
697 #define updateopposite( giver, taker ) \
698     if (sender == giver) \
699         [taker setIntValue: [giver intValue]]
700
701 - (IBAction)cropObjectChanged:(id)sender
702 {
703     updateopposite( o_crop_top_fld, o_crop_top_stp );
704     updateopposite( o_crop_top_stp, o_crop_top_fld );
705     updateopposite( o_crop_left_fld, o_crop_left_stp );
706     updateopposite( o_crop_left_stp, o_crop_left_fld );
707     updateopposite( o_crop_right_fld, o_crop_right_stp );
708     updateopposite( o_crop_right_stp, o_crop_right_fld );
709     updateopposite( o_crop_bottom_fld, o_crop_bottom_stp );
710     updateopposite( o_crop_bottom_stp, o_crop_bottom_fld );
711
712     if( [o_crop_sync_top_bottom_ckb state] ) {
713         if (sender == o_crop_top_fld || sender == o_crop_top_stp ) {
714             [o_crop_bottom_fld setIntValue: [o_crop_top_fld intValue]];
715             [o_crop_bottom_stp setIntValue: [o_crop_top_fld intValue]];
716         }
717         else
718         {
719             [o_crop_top_fld setIntValue: [o_crop_bottom_fld intValue]];
720             [o_crop_top_stp setIntValue: [o_crop_bottom_fld intValue]];
721         }
722     }
723     if( [o_crop_sync_left_right_ckb state] ) {
724         if (sender == o_crop_left_fld || sender == o_crop_left_stp ) {
725             [o_crop_right_fld setIntValue: [o_crop_left_fld intValue]];
726             [o_crop_right_stp setIntValue: [o_crop_left_fld intValue]];
727         }
728         else
729         {
730             [o_crop_left_fld setIntValue: [o_crop_right_fld intValue]];
731             [o_crop_left_stp setIntValue: [o_crop_right_fld intValue]];
732         }
733     }
734
735     vout_thread_t *p_vout = getVout();
736     if( p_vout ) {
737         var_SetInteger( p_vout, "crop-top", [o_crop_top_fld intValue] );
738         var_SetInteger( p_vout, "crop-bottom", [o_crop_bottom_fld intValue] );
739         var_SetInteger( p_vout, "crop-left", [o_crop_left_fld intValue] );
740         var_SetInteger( p_vout, "crop-right", [o_crop_right_fld intValue] );
741         vlc_object_release( p_vout );
742     }
743 }
744
745 #undef updateopposite
746
747 #pragma mark -
748 #pragma mark geometry
749 - (IBAction)enableTransform:(id)sender
750 {
751     [self setVideoFilter: "transform" on: [o_transform_ckb state]];
752     [o_transform_pop setEnabled: [o_transform_ckb state]];
753 }
754
755 - (IBAction)transformModifierChanged:(id)sender
756 {
757     NSInteger tag = [[o_transform_pop selectedItem] tag];
758     char * psz_string = (char *)[[NSString stringWithFormat:@"%li", tag] UTF8String];
759     if( tag == 1 )
760         psz_string = (char *)"hflip";
761     else if( tag == 2 )
762         psz_string = (char *)"vflip";
763
764     [self setVideoFilterProperty: "transform-type" forFilter: "transform" string: psz_string];
765 }
766
767 - (IBAction)enableZoom:(id)sender
768 {
769     [self setVideoFilter: "magnify" on: [o_zoom_ckb state]];
770 }
771
772 - (IBAction)enablePuzzle:(id)sender
773 {
774     BOOL b_state = [o_puzzle_ckb state];
775
776     [self setVideoFilter: "puzzle" on: b_state];
777     [o_puzzle_columns_fld setEnabled: b_state];
778     [o_puzzle_columns_lbl setEnabled: b_state];
779     [o_puzzle_rows_fld setEnabled: b_state];
780     [o_puzzle_rows_lbl setEnabled: b_state];
781     [o_puzzle_blackslot_ckb setEnabled: b_state];
782 }
783
784 - (IBAction)puzzleModifierChanged:(id)sender
785 {
786     if( sender == o_puzzle_blackslot_ckb )
787         [self setVideoFilterProperty: "puzzle-black-slot" forFilter: "puzzle" boolean: [o_puzzle_blackslot_ckb state]];
788     else if( sender == o_puzzle_columns_fld )
789         [self setVideoFilterProperty: "puzzle-cols" forFilter: "puzzle" integer: [o_puzzle_columns_fld intValue]];
790     else
791         [self setVideoFilterProperty: "puzzle-rows" forFilter: "puzzle" integer: [o_puzzle_rows_fld intValue]];
792 }
793
794
795 #pragma mark -
796 #pragma mark color
797 - (IBAction)enableThreshold:(id)sender
798 {
799     BOOL b_state = [o_threshold_ckb state];
800
801     [self setVideoFilter: "colorthres" on: b_state];
802     [o_threshold_color_fld setEnabled: b_state];
803     [o_threshold_color_lbl setEnabled: b_state];
804     [o_threshold_saturation_sld setEnabled: b_state];
805     [o_threshold_saturation_lbl setEnabled: b_state];
806     [o_threshold_similarity_sld setEnabled: b_state];
807     [o_threshold_similarity_lbl setEnabled: b_state];
808 }
809
810 - (IBAction)thresholdModifierChanged:(id)sender
811 {
812     if( sender == o_threshold_color_fld )
813         [self setVideoFilterProperty: "colorthres-color" forFilter: "colorthres" integer: [o_threshold_color_fld intValue]];
814     else if( sender == o_threshold_saturation_sld )
815     {
816         [self setVideoFilterProperty: "colorthres-saturationthres" forFilter: "colorthres" integer: [o_threshold_saturation_sld intValue]];
817         [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_saturation_sld intValue]]];
818     }
819     else
820     {
821         [self setVideoFilterProperty: "colorthres-similaritythres" forFilter: "colorthres" integer: [o_threshold_similarity_sld intValue]];
822         [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_similarity_sld intValue]]];
823     }
824 }
825
826 - (IBAction)enableSepia:(id)sender
827 {
828     BOOL b_state = [o_sepia_ckb state];
829
830     [self setVideoFilter: "sepia" on: b_state];
831     [o_sepia_fld setEnabled: b_state];
832     [o_sepia_lbl setEnabled: b_state];
833 }
834
835 - (IBAction)sepiaModifierChanged:(id)sender
836 {
837     [self setVideoFilterProperty: "sepia-intensity" forFilter: "sepia" integer: [o_sepia_fld intValue]];
838 }
839
840 - (IBAction)enableNoise:(id)sender
841 {
842     [self setVideoFilter: "noise" on: [o_noise_ckb state]];
843 }
844
845 - (IBAction)enableGradient:(id)sender
846 {
847     BOOL b_state = [o_gradient_ckb state];
848
849     [self setVideoFilter: "gradient" on: b_state];
850     [o_gradient_mode_pop setEnabled: b_state];
851     [o_gradient_mode_lbl setEnabled: b_state];
852     [o_gradient_color_ckb setEnabled: b_state];
853     [o_gradient_cartoon_ckb setEnabled: b_state];
854 }
855
856 - (IBAction)gradientModifierChanged:(id)sender
857 {
858     if( sender == o_gradient_mode_pop ) {
859         if( [[o_gradient_mode_pop selectedItem] tag] == 3 )
860             [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "hough"];
861         else if( [[o_gradient_mode_pop selectedItem] tag] == 2 )
862             [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "edge"];
863         else
864             [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "gradient"];
865     }
866     else if( sender == o_gradient_color_ckb )
867         [self setVideoFilterProperty: "gradient-type" forFilter: "gradient" integer: [o_gradient_color_ckb state]];
868     else
869         [self setVideoFilterProperty: "gradient-cartoon" forFilter: "gradient" boolean: [o_gradient_cartoon_ckb state]];
870 }
871
872 - (IBAction)enableExtract:(id)sender
873 {
874     BOOL b_state = [o_extract_ckb state];
875     [self setVideoFilter: "extract" on: b_state];
876     [o_extract_fld setEnabled: b_state];
877     [o_extract_lbl setEnabled: b_state];
878 }
879
880 - (IBAction)extractModifierChanged:(id)sender
881 {
882     [self setVideoFilterProperty: "extract-component" forFilter: "extract" integer: [o_extract_fld intValue]];
883 }
884
885 - (IBAction)enableInvert:(id)sender
886 {
887     [self setVideoFilter: "invert" on: [o_invert_ckb state]];
888 }
889
890 - (IBAction)enablePosterize:(id)sender
891 {
892     BOOL b_state = [o_posterize_ckb state];
893
894     [self setVideoFilter: "posterize" on: b_state];
895     [o_posterize_fld setEnabled: b_state];
896     [o_posterize_lbl setEnabled: b_state];
897 }
898
899 - (IBAction)posterizeModifierChanged:(id)sender
900 {
901     [self setVideoFilterProperty: "posterize-level" forFilter: "posterize" integer: [o_posterize_fld intValue]];
902 }
903
904 - (IBAction)enableBlur:(id)sender
905 {
906     BOOL b_state = [o_blur_ckb state];
907
908     [self setVideoFilter: "motionblur" on: b_state];
909     [o_blur_sld setEnabled: b_state];
910     [o_blur_lbl setEnabled: b_state];
911 }
912
913 - (IBAction)blurModifierChanged:(id)sender
914 {
915     [self setVideoFilterProperty: "blur-factor" forFilter: "motionblur" integer: [sender intValue]];
916     [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
917 }
918
919 - (IBAction)enableMotionDetect:(id)sender
920 {
921     [self setVideoFilter: "motiondetect" on: [o_motiondetect_ckb state]];
922 }
923
924 - (IBAction)enableWaterEffect:(id)sender
925 {
926     [self setVideoFilter: "ripple" on: [o_watereffect_ckb state]];
927 }
928
929 - (IBAction)enableWaves:(id)sender
930 {
931     [self setVideoFilter: "wave" on: [o_waves_ckb state]];
932 }
933
934 - (IBAction)enablePsychedelic:(id)sender
935 {
936     [self setVideoFilter: "psychedelic" on: [o_psychedelic_ckb state]];
937 }
938
939 #pragma mark -
940 #pragma mark Miscellaneous
941 - (IBAction)enableAddText:(id)sender
942 {
943     BOOL b_state = [o_addtext_ckb state];
944
945     [o_addtext_pos_pop setEnabled: b_state];
946     [o_addtext_pos_lbl setEnabled: b_state];
947     [o_addtext_text_lbl setEnabled: b_state];
948     [o_addtext_text_fld setEnabled: b_state];
949     [self setVideoFilter: "marq" on: b_state];
950     [self setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: (char *)[[o_addtext_text_fld stringValue] UTF8String]];
951     [self setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
952 }
953
954 - (IBAction)addTextModifierChanged:(id)sender
955 {
956     if (sender == o_addtext_text_fld)
957         [self setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: (char *)[[o_addtext_text_fld stringValue] UTF8String]];
958     else
959         [self setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
960 }
961
962 - (IBAction)enableAddLogo:(id)sender
963 {
964     BOOL b_state = [o_addlogo_ckb state];
965
966     [o_addlogo_pos_pop setEnabled: b_state];
967     [o_addlogo_pos_lbl setEnabled: b_state];
968     [o_addlogo_logo_fld setEnabled: b_state];
969     [o_addlogo_logo_lbl setEnabled: b_state];
970     [o_addlogo_transparency_sld setEnabled: b_state];
971     [o_addlogo_transparency_lbl setEnabled: b_state];
972     [self setVideoFilter: "logo" on: b_state];
973 }
974
975 - (IBAction)addLogoModifierChanged:(id)sender
976 {
977     if (sender == o_addlogo_logo_fld)
978         [self setVideoFilterProperty: "logo-file" forFilter: "logo" string: (char *)[[o_addlogo_logo_fld stringValue] UTF8String]];
979     else if (sender == o_addlogo_pos_pop)
980         [self setVideoFilterProperty: "logo-position" forFilter: "logo" integer: [[o_addlogo_pos_pop selectedItem] tag]];
981     else
982     {
983         [self setVideoFilterProperty: "logo-opacity" forFilter: "logo" integer: [o_addlogo_transparency_sld intValue]];
984         [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%i", [o_addlogo_transparency_sld intValue]]];
985     }
986 }
987
988 - (IBAction)enableAnaglyph:(id)sender
989 {
990     [self setVideoFilter: "anaglyph" on: [o_anaglyph_ckb state]];
991 }
992
993 @end