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