*: a new mouse gestures interface, currently supporting back, forward, quit
[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.25 2003/02/09 01:50:35 massiot 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
432 }
433
434 - (IBAction)toggleProgram:(id)sender
435 {
436     NSMenuItem * o_mi = (NSMenuItem *)sender;
437     intf_thread_t * p_intf = [NSApp getIntf];
438
439     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
440                                                        FIND_ANYWHERE );
441     if( p_playlist == NULL )
442     {
443         return;
444     }
445
446     vlc_mutex_lock( &p_playlist->object_lock );
447
448     if( p_playlist->p_input == NULL )
449     {
450         vlc_mutex_unlock( &p_playlist->object_lock );
451         vlc_object_release( p_playlist );
452         return;
453     }
454
455     if( [o_mi state] == NSOffState )
456     {
457         u16 i_program_id = [o_mi tag];
458
459         input_ChangeProgram( p_playlist->p_input, i_program_id );
460         input_SetStatus( p_playlist->p_input, INPUT_STATUS_PLAY );
461     }
462
463     vlc_mutex_unlock( &p_playlist->object_lock );
464     vlc_object_release( p_playlist );
465 }
466
467 - (IBAction)toggleTitle:(id)sender
468 {
469     NSMenuItem * o_mi = (NSMenuItem *)sender;
470     intf_thread_t * p_intf = [NSApp getIntf];
471
472     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
473                                                        FIND_ANYWHERE );
474     if( p_playlist == NULL )
475     {
476         return;
477     }
478
479     vlc_mutex_lock( &p_playlist->object_lock );
480
481     if( p_playlist->p_input == NULL )
482     {
483         vlc_mutex_unlock( &p_playlist->object_lock );
484         vlc_object_release( p_playlist );
485         return;
486     }
487
488     if( [o_mi state] == NSOffState )
489     {
490         int i_title = [o_mi tag];
491
492 #define p_input p_playlist->p_input
493         input_ChangeArea( p_input, p_input->stream.pp_areas[i_title] );
494         input_SetStatus( p_input, INPUT_STATUS_PLAY );
495 #undef p_input
496     }
497
498     vlc_mutex_unlock( &p_playlist->object_lock );
499     vlc_object_release( p_playlist );
500 }
501
502 - (IBAction)toggleChapter:(id)sender
503 {
504     NSMenuItem * o_mi = (NSMenuItem *)sender;
505     intf_thread_t * p_intf = [NSApp getIntf];
506
507     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
508                                                        FIND_ANYWHERE );
509     if( p_playlist == NULL )
510     {
511         return;
512     }
513
514     vlc_mutex_lock( &p_playlist->object_lock );
515
516     if( p_playlist->p_input == NULL )
517     {
518         vlc_mutex_unlock( &p_playlist->object_lock );
519         vlc_object_release( p_playlist );
520         return;
521     }
522
523     if( [o_mi state] == NSOffState )
524     {
525         int i_chapter = [o_mi tag];
526
527 #define p_input p_playlist->p_input
528         p_input->stream.p_selected_area->i_part = i_chapter;
529         input_ChangeArea( p_input, p_input->stream.p_selected_area );
530         input_SetStatus( p_input, INPUT_STATUS_PLAY );
531 #undef p_input
532     }
533
534     vlc_mutex_unlock( &p_playlist->object_lock );
535     vlc_object_release( p_playlist );
536 }
537
538 - (IBAction)toggleLanguage:(id)sender
539 {
540     NSMenuItem * o_mi = (NSMenuItem *)sender;
541     intf_thread_t * p_intf = [NSApp getIntf];
542
543     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
544                                                        FIND_ANYWHERE );
545     if( p_playlist == NULL )
546     {
547         return;
548     }
549
550     vlc_mutex_lock( &p_playlist->object_lock );
551
552     if( p_playlist->p_input == NULL )
553     {
554         vlc_mutex_unlock( &p_playlist->object_lock );
555         vlc_object_release( p_playlist );
556         return;
557     }
558
559 #if 0
560     /* We do not use this code, because you need to start stop .avi for
561      * it to work, so not very useful now  --hartman */
562     if ( [o_mi state] == NSOffState && [o_mi tag] == 2000 )
563     {
564         NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
565         
566         [o_open_panel setAllowsMultipleSelection: NO];
567         [o_open_panel setTitle: _NS("Open subtitle file")];
568         [o_open_panel setPrompt: _NS("Open")];
569     
570         if( [o_open_panel runModalForDirectory: nil 
571                 file: nil types: nil] == NSOKButton )
572         {
573             NSString *o_filename = [[o_open_panel filenames] objectAtIndex: 0];
574             config_PutPsz( p_intf, "sub-file", strdup( [o_filename cString] ));
575         }
576     }
577 #endif
578
579 #define p_input p_playlist->p_input
580
581     if( !p_intf->p_sys->b_audio_update )
582     {
583         NSValue * o_value = [o_mi representedObject];
584         es_descriptor_t * p_es = [o_value pointerValue];
585
586         if( [o_mi state] == NSOnState )
587         {
588             /* we just have one ES to disable */
589             input_ToggleES( p_input, p_es, 0 );
590         }
591         else
592         {
593             unsigned int i;
594             int i_cat = [o_mi tag];
595
596             vlc_mutex_lock( &p_input->stream.stream_lock );
597
598 #define ES p_input->stream.pp_selected_es[i]
599
600             /* unselect the selected ES in the same class */
601             for( i = 0; i < p_input->stream.i_selected_es_number; i++ )
602             {
603                 if( ES->i_cat == i_cat )
604                 {
605                     vlc_mutex_unlock( &p_input->stream.stream_lock );
606                     input_ToggleES( p_input, ES, 0 );
607                     vlc_mutex_lock( &p_input->stream.stream_lock );
608                     break;
609                 }
610             }
611
612 #undef ES
613
614             vlc_mutex_unlock( &p_input->stream.stream_lock );
615
616             input_ToggleES( p_input, p_es, 1 );
617         }
618     }
619
620 #undef p_input
621
622     vlc_mutex_unlock( &p_playlist->object_lock );
623     vlc_object_release( p_playlist );
624 }
625
626 - (IBAction)toggleVar:(id)sender
627 {
628     NSMenuItem * o_mi = (NSMenuItem *)sender;
629     
630     if( [o_mi state] == NSOffState )
631     {
632         const char * psz_variable = (const char *)[o_mi tag];
633         char * psz_value = [NSApp delocalizeString: [o_mi title]];
634         vlc_object_t * p_object = (vlc_object_t *)
635             [[o_mi representedObject] pointerValue];
636         vlc_value_t val;
637         /* psz_string sucks */
638         val.psz_string = (char *)psz_value;
639
640         if ( var_Set( p_object, psz_variable, val ) < 0 )
641         {
642             msg_Warn( p_object, "cannot set variable (%s)", psz_value );
643         }
644
645         free( psz_value );
646     }
647 }
648
649 @end
650
651 @implementation VLCControls (NSMenuValidation)
652  
653 - (BOOL)validateMenuItem:(NSMenuItem *)o_mi
654 {
655     BOOL bEnabled = TRUE;
656     NSMenu * o_menu = [o_mi menu];
657     intf_thread_t * p_intf = [NSApp getIntf];
658
659     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
660                                                        FIND_ANYWHERE );
661
662     if( p_playlist != NULL )
663     {
664         vlc_mutex_lock( &p_playlist->object_lock );
665     }
666
667 #define p_input p_playlist->p_input
668
669     if( [[o_mi title] isEqualToString: _NS("Faster")] ||
670         [[o_mi title] isEqualToString: _NS("Slower")] )
671     {
672         if( p_playlist != NULL && p_input != NULL )
673         {
674             vlc_mutex_lock( &p_input->stream.stream_lock );
675             bEnabled = p_input->stream.b_pace_control;
676             vlc_mutex_unlock( &p_input->stream.stream_lock );
677         }
678         else
679         {
680             bEnabled = FALSE;
681         }
682     }
683     else if( [[o_mi title] isEqualToString: _NS("Stop")] )
684     {
685         if( p_playlist == NULL || p_input == NULL )
686         {
687             bEnabled = FALSE;
688         }
689     }
690     else if( [[o_mi title] isEqualToString: _NS("Previous")] ||
691              [[o_mi title] isEqualToString: _NS("Next")] )
692     {
693         if( p_playlist == NULL )
694         {
695             bEnabled = FALSE;
696         }
697         else
698         {
699             bEnabled = p_playlist->i_size > 1;
700
701             if( p_input != NULL )
702             {
703                 vlc_mutex_lock( &p_input->stream.stream_lock );
704                 bEnabled |= p_input->stream.p_selected_area->i_part_nb > 1;
705                 vlc_mutex_unlock( &p_input->stream.stream_lock );
706             }
707         }
708     }
709     else if( [[o_mi title] isEqualToString: _NS("Loop")] )
710     {
711         int i_state = config_GetInt( p_playlist, "loop" ) ?
712                       NSOnState : NSOffState;
713
714         [o_mi setState: i_state];
715     }
716     else if( [[o_mi title] isEqualToString: _NS("Step Forward")] ||
717              [[o_mi title] isEqualToString: _NS("Step Backward")] )
718     {
719         if( p_playlist != NULL && p_input != NULL )
720         {
721             vlc_mutex_lock( &p_input->stream.stream_lock );
722             bEnabled = p_input->stream.b_seekable;
723             vlc_mutex_unlock( &p_input->stream.stream_lock );
724         }
725         else
726         {
727             bEnabled = FALSE;
728         }
729     }
730     else if( [[o_mi title] isEqualToString: _NS("Mute")] ) 
731     {
732         [o_mi setState: p_intf->p_sys->b_mute ? NSOnState : NSOffState];
733     }
734     else if( [[o_mi title] isEqualToString: _NS("Fullscreen")] ||
735                 [[o_mi title] isEqualToString: _NS("Half Size")] ||
736                 [[o_mi title] isEqualToString: _NS("Normal Size")] ||
737                 [[o_mi title] isEqualToString: _NS("Double Size")])    
738     {
739         id o_window;
740         NSArray *o_windows = [NSApp windows];
741         NSEnumerator *o_enumerator = [o_windows objectEnumerator];
742         bEnabled = FALSE;
743         
744         while ((o_window = [o_enumerator nextObject]))
745         {
746             if( [[o_window className] isEqualToString: @"VLCWindow"] )
747             {
748                 bEnabled = TRUE;
749                 break;
750             }
751         }
752     }
753     else if( o_menu != nil && 
754              [[o_menu title] isEqualToString: _NS("Deinterlace")] )
755     { 
756
757     } 
758
759     if( p_playlist != NULL )
760     {
761         vlc_mutex_unlock( &p_playlist->object_lock );
762         vlc_object_release( p_playlist );
763     }
764
765     return( bEnabled );
766 }
767
768 @end