48af1e28888eafe27ef74fc5679f0cd7affa1c54
[vlc.git] / modules / gui / macosx / controls.m
1 /*****************************************************************************
2  * controls.m: MacOS X interface plugin
3  *****************************************************************************
4  * Copyright (C) 2002 VideoLAN
5  * $Id: controls.m,v 1.26 2003/02/10 00:16:51 hartman Exp $
6  *
7  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8  *          Christophe Massiot <massiot@via.ecp.fr>
9  *          Derk-Jan Hartman <thedj@users.sourceforge.net>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdlib.h>                                      /* malloc(), free() */
30 #include <sys/param.h>                                    /* for MAXPATHLEN */
31 #include <string.h>
32
33 #include "intf.h"
34 #include "vout.h"
35
36 /*****************************************************************************
37  * VLCControls interface 
38  *****************************************************************************/
39 @interface VLCControls : NSObject
40 {
41     IBOutlet id o_open;
42     IBOutlet id o_main;
43
44     IBOutlet id o_volumeslider;
45 }
46
47 - (IBAction)play:(id)sender;
48 - (IBAction)stop:(id)sender;
49 - (IBAction)faster:(id)sender;
50 - (IBAction)slower:(id)sender;
51
52 - (IBAction)prev:(id)sender;
53 - (IBAction)next:(id)sender;
54 - (IBAction)loop:(id)sender;
55
56 - (IBAction)forward:(id)sender;
57 - (IBAction)backward:(id)sender;
58
59 - (IBAction)volumeUp:(id)sender;
60 - (IBAction)volumeDown:(id)sender;
61 - (IBAction)mute:(id)sender;
62 - (IBAction)volumeSliderUpdated:(id)sender;
63 - (void)updateVolumeSlider;
64
65 - (IBAction)halfWindow:(id)sender;
66 - (IBAction)normalWindow:(id)sender;
67 - (IBAction)doubleWindow:(id)sender;
68 - (IBAction)fullscreen:(id)sender;
69 - (IBAction)deinterlace:(id)sender;
70
71 - (IBAction)toggleProgram:(id)sender;
72 - (IBAction)toggleTitle:(id)sender;
73 - (IBAction)toggleChapter:(id)sender;
74 - (IBAction)toggleLanguage:(id)sender;
75 - (IBAction)toggleVar:(id)sender;
76
77 @end
78
79 /*****************************************************************************
80  * VLCControls implementation 
81  *****************************************************************************/
82 @implementation VLCControls
83
84 - (IBAction)play:(id)sender
85 {
86     intf_thread_t * p_intf = [NSApp getIntf];
87
88     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
89                                                        FIND_ANYWHERE );
90     if( p_playlist == NULL )
91     {
92         return;
93     }
94
95     if( playlist_IsPlaying( p_playlist ) )
96     {
97         playlist_Pause( p_playlist );
98         vlc_object_release( p_playlist );
99     }
100     else
101     {
102         if( !playlist_IsEmpty( p_playlist ) )
103         {
104             playlist_Play( p_playlist );
105             vlc_object_release( p_playlist );
106         }
107         else
108         {
109             vlc_object_release( p_playlist );
110             [o_open openFile: nil];
111         }
112     }
113 }
114
115 - (IBAction)stop:(id)sender
116 {
117     intf_thread_t * p_intf = [NSApp getIntf];
118
119     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
120                                                        FIND_ANYWHERE );
121     if( p_playlist == NULL )
122     {
123         return;
124     }
125
126     playlist_Stop( p_playlist );
127     vlc_object_release( p_playlist );
128 }
129
130 - (IBAction)faster:(id)sender
131 {
132     intf_thread_t * p_intf = [NSApp getIntf];
133
134     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
135                                                        FIND_ANYWHERE );
136     if( p_playlist == NULL )
137     {
138         return;
139     }
140
141     vlc_mutex_lock( &p_playlist->object_lock );
142     if( p_playlist->p_input != NULL )
143     {
144         input_SetStatus( p_playlist->p_input, INPUT_STATUS_FASTER );
145     } 
146     vlc_mutex_unlock( &p_playlist->object_lock );
147
148     vlc_object_release( p_playlist );
149 }
150
151 - (IBAction)slower:(id)sender
152 {
153     intf_thread_t * p_intf = [NSApp getIntf];
154
155     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
156                                                        FIND_ANYWHERE );
157     if( p_playlist == NULL )
158     {
159         return;
160     }
161
162     vlc_mutex_lock( &p_playlist->object_lock );
163     if( p_playlist->p_input != NULL )
164     {
165         input_SetStatus( p_playlist->p_input, INPUT_STATUS_SLOWER );
166     }
167     vlc_mutex_unlock( &p_playlist->object_lock );
168
169     vlc_object_release( p_playlist );
170 }
171
172 - (IBAction)prev:(id)sender
173 {
174     intf_thread_t * p_intf = [NSApp getIntf];
175
176     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
177                                                        FIND_ANYWHERE );
178     if( p_playlist == NULL )
179     {
180         return;
181     }
182
183     vlc_mutex_lock( &p_playlist->object_lock );
184
185     if( p_playlist->p_input == NULL )
186     {
187         vlc_mutex_unlock( &p_playlist->object_lock );
188         vlc_object_release( p_playlist );  
189         return;
190     }
191
192     vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
193
194 #define p_area p_playlist->p_input->stream.p_selected_area
195
196     if( p_area->i_part_nb > 1 && p_area->i_part > 1 )
197     {
198         p_area->i_part--;
199
200         vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
201         input_ChangeArea( p_playlist->p_input, p_area );
202         vlc_mutex_unlock( &p_playlist->object_lock );
203
204         p_intf->p_sys->b_chapter_update = VLC_TRUE;
205     }
206     else
207     {
208         vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
209         vlc_mutex_unlock( &p_playlist->object_lock );
210         playlist_Prev( p_playlist );
211     }
212
213 #undef p_area
214
215     vlc_object_release( p_playlist );
216 }
217
218 - (IBAction)next:(id)sender
219 {
220     intf_thread_t * p_intf = [NSApp getIntf];
221
222     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
223                                                        FIND_ANYWHERE );
224     if( p_playlist == NULL )
225     {
226         return;
227     }
228
229     vlc_mutex_lock( &p_playlist->object_lock );
230
231     if( p_playlist->p_input == NULL )
232     {
233         vlc_mutex_unlock( &p_playlist->object_lock );
234         vlc_object_release( p_playlist );  
235         return;
236     }
237
238     vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
239
240 #define p_area p_playlist->p_input->stream.p_selected_area
241
242     if( p_area->i_part_nb > 1 && p_area->i_part + 1 < p_area->i_part_nb )
243     {
244         p_area->i_part++;
245
246         vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
247         input_ChangeArea( p_playlist->p_input, p_area );
248         vlc_mutex_unlock( &p_playlist->object_lock );
249
250         p_intf->p_sys->b_chapter_update = VLC_TRUE;
251     }
252     else
253     {
254         vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
255         vlc_mutex_unlock( &p_playlist->object_lock );
256         playlist_Next( p_playlist );
257     }
258
259 #undef p_area
260
261     vlc_object_release( p_playlist );
262 }
263
264 - (IBAction)loop:(id)sender
265 {
266     intf_thread_t * p_intf = [NSApp getIntf];
267
268     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
269                                                        FIND_ANYWHERE );
270     if( p_playlist == NULL )
271     {
272         return;
273     }
274
275     config_PutInt( p_playlist, "loop",
276                    !config_GetInt( p_playlist, "loop" ) );
277
278     vlc_object_release( p_playlist );
279 }
280
281 - (IBAction)forward:(id)sender
282 {
283     intf_thread_t * p_intf = [NSApp getIntf];
284     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
285                                                        FIND_ANYWHERE );
286     if( p_playlist == NULL || p_playlist->p_input == NULL )
287     {
288         if ( p_playlist != NULL ) vlc_object_release( p_playlist );
289         return;
290     }
291
292     input_Seek( p_playlist->p_input, 5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
293     vlc_object_release( p_playlist );
294 }
295
296 - (IBAction)backward:(id)sender
297 {
298     intf_thread_t * p_intf = [NSApp getIntf];
299     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
300                                                        FIND_ANYWHERE );
301     if( p_playlist == NULL || p_playlist->p_input == NULL )
302     {
303         if ( p_playlist != NULL ) vlc_object_release( p_playlist );
304         return;
305     }
306
307     input_Seek( p_playlist->p_input, -5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
308     vlc_object_release( p_playlist );
309 }
310
311 - (IBAction)volumeUp:(id)sender
312 {
313     intf_thread_t * p_intf = [NSApp getIntf];
314
315     aout_VolumeUp( p_intf, 1, NULL );
316
317     if( p_intf->p_sys->b_mute )
318     {
319         [self mute: nil];
320     }
321
322     [self updateVolumeSlider];
323 }
324
325 - (IBAction)volumeDown:(id)sender
326 {
327     intf_thread_t * p_intf = [NSApp getIntf];
328
329     aout_VolumeDown( p_intf, 1, NULL );
330
331     if( p_intf->p_sys->b_mute )
332     {
333         [self mute: nil];
334     }
335
336     [self updateVolumeSlider];
337 }
338
339 - (IBAction)mute:(id)sender
340 {
341     intf_thread_t * p_intf = [NSApp getIntf];
342     audio_volume_t i_volume;
343
344     aout_VolumeMute( p_intf, &i_volume );
345     p_intf->p_sys->b_mute = ( i_volume == 0 );
346
347     [self updateVolumeSlider];
348 }
349
350 - (IBAction)volumeSliderUpdated:(id)sender
351 {
352     intf_thread_t * p_intf = [NSApp getIntf];
353     audio_volume_t i_volume = (audio_volume_t)[sender intValue];
354
355     aout_VolumeSet( p_intf, i_volume * AOUT_VOLUME_STEP );
356 }
357
358 - (void)updateVolumeSlider
359 {
360     intf_thread_t * p_intf = [NSApp getIntf];
361     audio_volume_t i_volume;
362
363     aout_VolumeGet( p_intf, &i_volume );
364
365     [o_volumeslider setFloatValue: (float)(i_volume / AOUT_VOLUME_STEP)]; 
366 }
367
368 - (IBAction)halfWindow:(id)sender
369 {
370     id o_window = [NSApp keyWindow];
371     NSArray *o_windows = [NSApp windows];
372     NSEnumerator *o_enumerator = [o_windows objectEnumerator];
373     
374     while ((o_window = [o_enumerator nextObject]))
375     {
376         if( [[o_window className] isEqualToString: @"VLCWindow"] )
377         {
378             [o_window scaleWindowWithFactor: 0.5];
379         }
380     }
381 }
382
383 - (IBAction)normalWindow:(id)sender
384 {
385     id o_window = [NSApp keyWindow];
386     NSArray *o_windows = [NSApp windows];
387     NSEnumerator *o_enumerator = [o_windows objectEnumerator];
388     
389     while ((o_window = [o_enumerator nextObject]))
390     {
391         if( [[o_window className] isEqualToString: @"VLCWindow"] )
392         {
393             [o_window scaleWindowWithFactor: 1];
394         }
395     }
396 }
397
398 - (IBAction)doubleWindow:(id)sender
399 {
400     id o_window = [NSApp keyWindow];
401     NSArray *o_windows = [NSApp windows];
402     NSEnumerator *o_enumerator = [o_windows objectEnumerator];
403     
404     while ((o_window = [o_enumerator nextObject]))
405     {
406         if( [[o_window className] isEqualToString: @"VLCWindow"] )
407         {
408             [o_window scaleWindowWithFactor: 2];
409         }
410     }
411 }
412
413
414 - (IBAction)fullscreen:(id)sender
415 {
416     id o_window = [NSApp keyWindow];
417     NSArray *o_windows = [NSApp windows];
418     NSEnumerator *o_enumerator = [o_windows objectEnumerator];
419     
420     while ((o_window = [o_enumerator nextObject]))
421     {
422         if( [[o_window className] isEqualToString: @"VLCWindow"] )
423         {
424             [o_window toggleFullscreen];
425         }
426     }
427 }
428
429 - (IBAction)deinterlace:(id)sender
430 {
431     intf_thread_t * p_intf = [NSApp getIntf];
432     BOOL bEnable = [sender state] == NSOffState;
433     
434     if( bEnable )
435     {
436         config_PutPsz( p_intf, "filter", "deinterlace" );
437         config_PutPsz( p_intf, "deinterlace-mode",
438                     [[sender title] lossyCString] );    Ê
439     }
440     else
441     {
442         config_PutPsz( p_intf, "filter", NULL );
443     }
444 }
445
446 - (IBAction)toggleProgram:(id)sender
447 {
448     NSMenuItem * o_mi = (NSMenuItem *)sender;
449     intf_thread_t * p_intf = [NSApp getIntf];
450
451     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
452                                                        FIND_ANYWHERE );
453     if( p_playlist == NULL )
454     {
455         return;
456     }
457
458     vlc_mutex_lock( &p_playlist->object_lock );
459
460     if( p_playlist->p_input == NULL )
461     {
462         vlc_mutex_unlock( &p_playlist->object_lock );
463         vlc_object_release( p_playlist );
464         return;
465     }
466
467     if( [o_mi state] == NSOffState )
468     {
469         u16 i_program_id = [o_mi tag];
470
471         input_ChangeProgram( p_playlist->p_input, i_program_id );
472         input_SetStatus( p_playlist->p_input, INPUT_STATUS_PLAY );
473     }
474
475     vlc_mutex_unlock( &p_playlist->object_lock );
476     vlc_object_release( p_playlist );
477 }
478
479 - (IBAction)toggleTitle:(id)sender
480 {
481     NSMenuItem * o_mi = (NSMenuItem *)sender;
482     intf_thread_t * p_intf = [NSApp getIntf];
483
484     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
485                                                        FIND_ANYWHERE );
486     if( p_playlist == NULL )
487     {
488         return;
489     }
490
491     vlc_mutex_lock( &p_playlist->object_lock );
492
493     if( p_playlist->p_input == NULL )
494     {
495         vlc_mutex_unlock( &p_playlist->object_lock );
496         vlc_object_release( p_playlist );
497         return;
498     }
499
500     if( [o_mi state] == NSOffState )
501     {
502         int i_title = [o_mi tag];
503
504 #define p_input p_playlist->p_input
505         input_ChangeArea( p_input, p_input->stream.pp_areas[i_title] );
506         input_SetStatus( p_input, INPUT_STATUS_PLAY );
507 #undef p_input
508     }
509
510     vlc_mutex_unlock( &p_playlist->object_lock );
511     vlc_object_release( p_playlist );
512 }
513
514 - (IBAction)toggleChapter:(id)sender
515 {
516     NSMenuItem * o_mi = (NSMenuItem *)sender;
517     intf_thread_t * p_intf = [NSApp getIntf];
518
519     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
520                                                        FIND_ANYWHERE );
521     if( p_playlist == NULL )
522     {
523         return;
524     }
525
526     vlc_mutex_lock( &p_playlist->object_lock );
527
528     if( p_playlist->p_input == NULL )
529     {
530         vlc_mutex_unlock( &p_playlist->object_lock );
531         vlc_object_release( p_playlist );
532         return;
533     }
534
535     if( [o_mi state] == NSOffState )
536     {
537         int i_chapter = [o_mi tag];
538
539 #define p_input p_playlist->p_input
540         p_input->stream.p_selected_area->i_part = i_chapter;
541         input_ChangeArea( p_input, p_input->stream.p_selected_area );
542         input_SetStatus( p_input, INPUT_STATUS_PLAY );
543 #undef p_input
544     }
545
546     vlc_mutex_unlock( &p_playlist->object_lock );
547     vlc_object_release( p_playlist );
548 }
549
550 - (IBAction)toggleLanguage:(id)sender
551 {
552     NSMenuItem * o_mi = (NSMenuItem *)sender;
553     intf_thread_t * p_intf = [NSApp getIntf];
554
555     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
556                                                        FIND_ANYWHERE );
557     if( p_playlist == NULL )
558     {
559         return;
560     }
561
562     vlc_mutex_lock( &p_playlist->object_lock );
563
564     if( p_playlist->p_input == NULL )
565     {
566         vlc_mutex_unlock( &p_playlist->object_lock );
567         vlc_object_release( p_playlist );
568         return;
569     }
570
571 #if 0
572     /* We do not use this code, because you need to start stop .avi for
573      * it to work, so not very useful now  --hartman */
574     if ( [o_mi state] == NSOffState && [o_mi tag] == 2000 )
575     {
576         NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
577         
578         [o_open_panel setAllowsMultipleSelection: NO];
579         [o_open_panel setTitle: _NS("Open subtitle file")];
580         [o_open_panel setPrompt: _NS("Open")];
581     
582         if( [o_open_panel runModalForDirectory: nil 
583                 file: nil types: nil] == NSOKButton )
584         {
585             NSString *o_filename = [[o_open_panel filenames] objectAtIndex: 0];
586             config_PutPsz( p_intf, "sub-file", strdup( [o_filename cString] ));
587         }
588     }
589 #endif
590
591 #define p_input p_playlist->p_input
592
593     if( !p_intf->p_sys->b_audio_update )
594     {
595         NSValue * o_value = [o_mi representedObject];
596         es_descriptor_t * p_es = [o_value pointerValue];
597
598         if( [o_mi state] == NSOnState )
599         {
600             /* we just have one ES to disable */
601             input_ToggleES( p_input, p_es, 0 );
602         }
603         else
604         {
605             unsigned int i;
606             int i_cat = [o_mi tag];
607
608             vlc_mutex_lock( &p_input->stream.stream_lock );
609
610 #define ES p_input->stream.pp_selected_es[i]
611
612             /* unselect the selected ES in the same class */
613             for( i = 0; i < p_input->stream.i_selected_es_number; i++ )
614             {
615                 if( ES->i_cat == i_cat )
616                 {
617                     vlc_mutex_unlock( &p_input->stream.stream_lock );
618                     input_ToggleES( p_input, ES, 0 );
619                     vlc_mutex_lock( &p_input->stream.stream_lock );
620                     break;
621                 }
622             }
623
624 #undef ES
625
626             vlc_mutex_unlock( &p_input->stream.stream_lock );
627
628             input_ToggleES( p_input, p_es, 1 );
629         }
630     }
631
632 #undef p_input
633
634     vlc_mutex_unlock( &p_playlist->object_lock );
635     vlc_object_release( p_playlist );
636 }
637
638 - (IBAction)toggleVar:(id)sender
639 {
640     NSMenuItem * o_mi = (NSMenuItem *)sender;
641     
642     if( [o_mi state] == NSOffState )
643     {
644         const char * psz_variable = (const char *)[o_mi tag];
645         char * psz_value = [NSApp delocalizeString: [o_mi title]];
646         vlc_object_t * p_object = (vlc_object_t *)
647             [[o_mi representedObject] pointerValue];
648         vlc_value_t val;
649         /* psz_string sucks */
650         val.psz_string = (char *)psz_value;
651
652         if ( var_Set( p_object, psz_variable, val ) < 0 )
653         {
654             msg_Warn( p_object, "cannot set variable (%s)", psz_value );
655         }
656
657         free( psz_value );
658     }
659 }
660
661 @end
662
663 @implementation VLCControls (NSMenuValidation)
664  
665 - (BOOL)validateMenuItem:(NSMenuItem *)o_mi
666 {
667     BOOL bEnabled = TRUE;
668     NSMenu * o_menu = [o_mi menu];
669     intf_thread_t * p_intf = [NSApp getIntf];
670
671     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
672                                                        FIND_ANYWHERE );
673
674     if( p_playlist != NULL )
675     {
676         vlc_mutex_lock( &p_playlist->object_lock );
677     }
678
679 #define p_input p_playlist->p_input
680
681     if( [[o_mi title] isEqualToString: _NS("Faster")] ||
682         [[o_mi title] isEqualToString: _NS("Slower")] )
683     {
684         if( p_playlist != NULL && p_input != NULL )
685         {
686             vlc_mutex_lock( &p_input->stream.stream_lock );
687             bEnabled = p_input->stream.b_pace_control;
688             vlc_mutex_unlock( &p_input->stream.stream_lock );
689         }
690         else
691         {
692             bEnabled = FALSE;
693         }
694     }
695     else if( [[o_mi title] isEqualToString: _NS("Stop")] )
696     {
697         if( p_playlist == NULL || p_input == NULL )
698         {
699             bEnabled = FALSE;
700         }
701     }
702     else if( [[o_mi title] isEqualToString: _NS("Previous")] ||
703              [[o_mi title] isEqualToString: _NS("Next")] )
704     {
705         if( p_playlist == NULL )
706         {
707             bEnabled = FALSE;
708         }
709         else
710         {
711             bEnabled = p_playlist->i_size > 1;
712
713             if( p_input != NULL )
714             {
715                 vlc_mutex_lock( &p_input->stream.stream_lock );
716                 bEnabled |= p_input->stream.p_selected_area->i_part_nb > 1;
717                 vlc_mutex_unlock( &p_input->stream.stream_lock );
718             }
719         }
720     }
721     else if( [[o_mi title] isEqualToString: _NS("Loop")] )
722     {
723         int i_state = config_GetInt( p_playlist, "loop" ) ?
724                       NSOnState : NSOffState;
725
726         [o_mi setState: i_state];
727     }
728     else if( [[o_mi title] isEqualToString: _NS("Step Forward")] ||
729              [[o_mi title] isEqualToString: _NS("Step Backward")] )
730     {
731         if( p_playlist != NULL && p_input != NULL )
732         {
733             vlc_mutex_lock( &p_input->stream.stream_lock );
734             bEnabled = p_input->stream.b_seekable;
735             vlc_mutex_unlock( &p_input->stream.stream_lock );
736         }
737         else
738         {
739             bEnabled = FALSE;
740         }
741     }
742     else if( [[o_mi title] isEqualToString: _NS("Mute")] ) 
743     {
744         [o_mi setState: p_intf->p_sys->b_mute ? NSOnState : NSOffState];
745     }
746     else if( [[o_mi title] isEqualToString: _NS("Fullscreen")] ||
747                 [[o_mi title] isEqualToString: _NS("Half Size")] ||
748                 [[o_mi title] isEqualToString: _NS("Normal Size")] ||
749                 [[o_mi title] isEqualToString: _NS("Double Size")])    
750     {
751         id o_window;
752         NSArray *o_windows = [NSApp windows];
753         NSEnumerator *o_enumerator = [o_windows objectEnumerator];
754         bEnabled = FALSE;
755         
756         while ((o_window = [o_enumerator nextObject]))
757         {
758             if( [[o_window className] isEqualToString: @"VLCWindow"] )
759             {
760                 bEnabled = TRUE;
761                 break;
762             }
763         }
764     }
765     else if( o_menu != nil && 
766              [[o_menu title] isEqualToString: _NS("Deinterlace")] )
767     {
768         char * psz_filter = config_GetPsz( p_intf, "filter" );  Ê
769         
770         if( psz_filter != NULL )        Ê
771         {       Ê
772             free( psz_filter ); Ê
773             
774             psz_filter = config_GetPsz( p_intf, "deinterlace-mode" );   Ê
775         }       Ê
776         Ê       Ê
777         if( psz_filter != NULL )        Ê
778         {       Ê
779             if( strcmp( psz_filter, [[o_mi title] lossyCString] ) == 0 )        Ê
780             {   Ê
781                 [o_mi setState: NSOnState];     Ê
782             }   Ê
783             else        Ê
784             {   Ê
785                 [o_mi setState: NSOffState];    Ê
786             }   Ê
787             
788             free( psz_filter ); Ê
789         }       Ê
790         else    Ê
791         {       Ê
792             [o_mi setState: NSOffState];        Ê
793         }
794     } 
795
796     if( p_playlist != NULL )
797     {
798         vlc_mutex_unlock( &p_playlist->object_lock );
799         vlc_object_release( p_playlist );
800     }
801
802     return( bEnabled );
803 }
804
805 @end