]> git.sesse.net Git - vlc/blob - src/control/video.c
286ae181761ee541628db40f5a913d83a9f3a361
[vlc] / src / control / video.c
1 /*****************************************************************************
2  * video.c: libvlc new API video functions
3  *****************************************************************************
4  * Copyright (C) 2005-2010 the VideoLAN team
5  *
6  * $Id$
7  *
8  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
9  *          Filippo Carone <littlejohn@videolan.org>
10  *          Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
11  *          Damien Fouilleul <damienf a_t videolan dot org>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc/libvlc.h>
33 #include <vlc/libvlc_media.h>
34 #include <vlc/libvlc_media_player.h>
35
36 #include <vlc_common.h>
37 #include <vlc_input.h>
38 #include <vlc_vout.h>
39
40 #include "media_player_internal.h"
41 #include <vlc_osd.h>
42 #include <assert.h>
43
44 /*
45  * Remember to release the returned vout_thread_t.
46  */
47 static vout_thread_t **GetVouts( libvlc_media_player_t *p_mi, size_t *n )
48 {
49     input_thread_t *p_input = libvlc_get_input_thread( p_mi );
50     if( !p_input )
51         return NULL;
52
53     vout_thread_t **pp_vouts;
54     if (input_Control( p_input, INPUT_GET_VOUTS, &pp_vouts, n))
55     {
56         *n = 0;
57         pp_vouts = NULL;
58     }
59     vlc_object_release (p_input);
60     return pp_vouts;
61 }
62
63 static vout_thread_t *GetVout (libvlc_media_player_t *mp, size_t num)
64 {
65     vout_thread_t *p_vout = NULL;
66     size_t n;
67     vout_thread_t **pp_vouts = GetVouts (mp, &n);
68     if (pp_vouts == NULL)
69         goto err;
70
71     if (num < n)
72         p_vout = pp_vouts[num];
73
74     for (size_t i = 0; i < n; i++)
75         if (i != num)
76             vlc_object_release (pp_vouts[i]);
77     free (pp_vouts);
78
79     if (p_vout == NULL)
80 err:
81         libvlc_printerr ("Video output not active");
82     return p_vout;
83 }
84
85 /**********************************************************************
86  * Exported functions
87  **********************************************************************/
88
89 void libvlc_set_fullscreen( libvlc_media_player_t *p_mi, int b_fullscreen )
90 {
91     /* This will work even if the video is not currently active */
92     var_SetBool (p_mi, "fullscreen", !!b_fullscreen);
93
94     /* Apply to current video outputs (if any) */
95     size_t n;
96     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
97     for (size_t i = 0; i < n; i++)
98     {
99         var_SetBool (pp_vouts[i], "fullscreen", b_fullscreen);
100         vlc_object_release (pp_vouts[i]);
101     }
102     free (pp_vouts);
103 }
104
105 int libvlc_get_fullscreen( libvlc_media_player_t *p_mi )
106 {
107     return var_GetBool (p_mi, "fullscreen");
108 }
109
110 void libvlc_toggle_fullscreen( libvlc_media_player_t *p_mi )
111 {
112     var_ToggleBool (p_mi, "fullscreen");
113     bool b_fullscreen = var_GetBool (p_mi, "fullscreen");
114
115     /* Apply to current video outputs (if any) */
116     size_t n;
117     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
118     for (size_t i = 0; i < n; i++)
119     {
120         vout_thread_t *p_vout = pp_vouts[i];
121
122         var_SetBool (p_vout, "fullscreen", b_fullscreen);
123         vlc_object_release (p_vout);
124     }
125     free (pp_vouts);
126 }
127
128 void libvlc_video_set_key_input( libvlc_media_player_t *p_mi, unsigned on )
129 {
130     var_SetBool (p_mi, "keyboard-events", !!on);
131 }
132
133 void libvlc_video_set_mouse_input( libvlc_media_player_t *p_mi, unsigned on )
134 {
135     var_SetBool (p_mi, "mouse-events", !!on);
136 }
137
138 int
139 libvlc_video_take_snapshot( libvlc_media_player_t *p_mi, unsigned num,
140                             const char *psz_filepath,
141                             unsigned int i_width, unsigned int i_height )
142 {
143     assert( psz_filepath );
144
145     vout_thread_t *p_vout = GetVout (p_mi, num);
146     if (p_vout == NULL)
147         return -1;
148
149     /* FIXME: This is not atomic. Someone else could change the values,
150      * at least in theory. */
151     var_SetInteger( p_vout, "snapshot-width", i_width);
152     var_SetInteger( p_vout, "snapshot-height", i_height );
153     var_SetString( p_vout, "snapshot-path", psz_filepath );
154     var_SetString( p_vout, "snapshot-format", "png" );
155     var_TriggerCallback (p_vout, "video-snapshot" );
156     return 0;
157 }
158
159 int libvlc_video_get_size( libvlc_media_player_t *p_mi, unsigned num,
160                            unsigned *restrict px, unsigned *restrict py )
161 {
162     vout_thread_t *p_vout = GetVout (p_mi, num);
163     if (p_vout == NULL)
164         return -1;
165
166     *px = p_vout->i_window_height;
167     *py = p_vout->i_window_width;
168     vlc_object_release (p_vout);
169     return 0;
170 }
171
172 int libvlc_video_get_height( libvlc_media_player_t *p_mi )
173 {
174     unsigned height, width;
175
176     if (libvlc_video_get_size (p_mi, 0, &height, &width))
177         return 0;
178     return height;
179 }
180
181 int libvlc_video_get_width( libvlc_media_player_t *p_mi )
182 {
183     unsigned height, width;
184
185     if (libvlc_video_get_size (p_mi, 0, &height, &width))
186         return 0;
187     return width;
188 }
189
190 unsigned libvlc_media_player_has_vout( libvlc_media_player_t *p_mi )
191 {
192     size_t n;
193     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
194     for (size_t i = 0; i < n; i++)
195         vlc_object_release (pp_vouts[i]);
196     free (pp_vouts);
197     return n;
198 }
199
200 float libvlc_video_get_scale( libvlc_media_player_t *mp )
201 {
202     float f_scale = var_GetFloat (mp, "scale");
203     if (var_GetBool (mp, "autoscale"))
204         f_scale = 0.;
205     return f_scale;
206 }
207
208 void libvlc_video_set_scale( libvlc_media_player_t *p_mp, float f_scale )
209 {
210     if (f_scale != 0.)
211         var_SetFloat (p_mp, "scale", f_scale);
212     var_SetBool (p_mp, "autoscale", f_scale != 0.);
213
214     /* Apply to current video outputs (if any) */
215     size_t n;
216     vout_thread_t **pp_vouts = GetVouts (p_mp, &n);
217     for (size_t i = 0; i < n; i++)
218     {
219         vout_thread_t *p_vout = pp_vouts[i];
220
221         if (f_scale != 0.)
222             var_SetFloat (p_vout, "scale", f_scale);
223         var_SetBool (p_mp, "autoscale", f_scale != 0.);
224         vlc_object_release (p_vout);
225     }
226     free (pp_vouts);
227 }
228
229 char *libvlc_video_get_aspect_ratio( libvlc_media_player_t *p_mi )
230 {
231     return var_GetNonEmptyString (p_mi, "aspect-ratio");
232 }
233
234 void libvlc_video_set_aspect_ratio( libvlc_media_player_t *p_mi,
235                                     const char *psz_aspect )
236 {
237     if (psz_aspect == NULL)
238         psz_aspect = "";
239     var_SetString (p_mi, "aspect-ratio", psz_aspect);
240
241     size_t n;
242     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
243     for (size_t i = 0; i < n; i++)
244     {
245         vout_thread_t *p_vout = pp_vouts[i];
246
247         var_SetString (p_vout, "aspect-ratio", psz_aspect);
248         vlc_object_release (p_vout);
249     }
250     free (pp_vouts);
251 }
252
253 int libvlc_video_get_spu( libvlc_media_player_t *p_mi )
254 {
255     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
256     vlc_value_t val_list;
257     vlc_value_t val;
258     int i_spu = -1;
259     int i_ret = -1;
260     int i;
261
262     if( !p_input_thread )
263     {
264         libvlc_printerr( "No active input" );
265         return -1;
266     }
267
268     i_ret = var_Get( p_input_thread, "spu-es", &val );
269     if( i_ret < 0 )
270     {
271         vlc_object_release( p_input_thread );
272         libvlc_printerr( "Subtitle informations not found" );
273         return -1;
274     }
275
276     var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
277     for( i = 0; i < val_list.p_list->i_count; i++ )
278     {
279         if( val.i_int == val_list.p_list->p_values[i].i_int )
280         {
281             i_spu = i;
282             break;
283         }
284     }
285     var_FreeList( &val_list, NULL );
286     vlc_object_release( p_input_thread );
287     return i_spu;
288 }
289
290 int libvlc_video_get_spu_count( libvlc_media_player_t *p_mi )
291 {
292     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
293     int i_spu_count;
294
295     if( !p_input_thread )
296         return 0;
297
298     i_spu_count = var_CountChoices( p_input_thread, "spu-es" );
299     vlc_object_release( p_input_thread );
300     return i_spu_count;
301 }
302
303 libvlc_track_description_t *
304         libvlc_video_get_spu_description( libvlc_media_player_t *p_mi )
305 {
306     return libvlc_get_track_description( p_mi, "spu-es" );
307 }
308
309 int libvlc_video_set_spu( libvlc_media_player_t *p_mi, unsigned i_spu )
310 {
311     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
312     vlc_value_t list;
313     int i_ret = 0;
314
315     if( !p_input_thread )
316         return -1;
317
318     var_Change (p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &list, NULL);
319
320     if (i_spu > (unsigned)list.p_list->i_count)
321     {
322         libvlc_printerr( "Subtitle number out of range (%u/%u)",
323                          i_spu, list.p_list->i_count );
324         i_ret = -1;
325         goto end;
326     }
327     var_SetInteger (p_input_thread, "spu-es",
328                     list.p_list->p_values[i_spu].i_int);
329 end:
330     vlc_object_release (p_input_thread);
331     var_FreeList (&list, NULL);
332     return i_ret;
333 }
334
335 int libvlc_video_set_subtitle_file( libvlc_media_player_t *p_mi,
336                                     const char *psz_subtitle )
337 {
338     input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi );
339     bool b_ret = false;
340
341     if( p_input_thread )
342     {
343         if( !input_AddSubtitle( p_input_thread, psz_subtitle, true ) )
344             b_ret = true;
345         vlc_object_release( p_input_thread );
346     }
347     return b_ret;
348 }
349
350 libvlc_track_description_t *
351         libvlc_video_get_title_description( libvlc_media_player_t *p_mi )
352 {
353     return libvlc_get_track_description( p_mi, "title" );
354 }
355
356 libvlc_track_description_t *
357         libvlc_video_get_chapter_description( libvlc_media_player_t *p_mi,
358                                               int i_title )
359 {
360     char psz_title[12];
361     sprintf( psz_title,  "title %2i", i_title );
362     return libvlc_get_track_description( p_mi, psz_title );
363 }
364
365 char *libvlc_video_get_crop_geometry (libvlc_media_player_t *p_mi)
366 {
367     return var_GetNonEmptyString (p_mi, "crop");
368 }
369
370 void libvlc_video_set_crop_geometry( libvlc_media_player_t *p_mi,
371                                      const char *psz_geometry )
372 {
373     if (psz_geometry == NULL)
374         psz_geometry = "";
375
376     var_SetString (p_mi, "crop", psz_geometry);
377
378     size_t n;
379     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
380
381     for (size_t i = 0; i < n; i++)
382     {
383         vout_thread_t *p_vout = pp_vouts[i];
384
385         var_SetString (p_vout, "crop", psz_geometry);
386         vlc_object_release (p_vout);
387     }
388     free (pp_vouts);
389 }
390
391 int libvlc_video_get_teletext( libvlc_media_player_t *p_mi )
392 {
393     input_thread_t *p_input_thread;
394     vlc_object_t *p_zvbi = NULL;
395     int i_ret = -1, telx;
396
397     p_input_thread = libvlc_get_input_thread( p_mi );
398     if( !p_input_thread ) return i_ret;
399
400     if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
401     {
402         vlc_object_release( p_input_thread );
403         return i_ret;
404     }
405
406     telx = var_GetInteger( p_input_thread, "teletext-es" );
407     if( input_GetEsObjects( p_input_thread, telx, &p_zvbi, NULL, NULL )
408         != VLC_SUCCESS )
409     {
410         i_ret = var_GetInteger( p_zvbi, "vbi-page" );
411         vlc_object_release( p_zvbi );
412     }
413     vlc_object_release( p_input_thread );
414     return i_ret;
415 }
416
417 void libvlc_video_set_teletext( libvlc_media_player_t *p_mi, int i_page,
418                                 libvlc_exception_t *p_e )
419 {
420     input_thread_t *p_input_thread;
421     vlc_object_t *p_zvbi = NULL;
422     int telx;
423
424     p_input_thread = libvlc_get_input_thread( p_mi );
425     if( !p_input_thread ) return;
426
427     if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
428     {
429         vlc_object_release( p_input_thread );
430         return;
431     }
432
433     telx = var_GetInteger( p_input_thread, "teletext-es" );
434     if( input_GetEsObjects( p_input_thread, telx, &p_zvbi, NULL, NULL )
435         != VLC_SUCCESS )
436     {
437         int i_ret = var_SetInteger( p_zvbi, "vbi-page", i_page );
438         vlc_object_release( p_zvbi );
439         if( i_ret )
440         {
441             libvlc_exception_raise( p_e );
442             libvlc_printerr( "Unexpected error while setting teletext page" );
443         }
444     }
445     vlc_object_release( p_input_thread );
446 }
447
448 void libvlc_toggle_teletext( libvlc_media_player_t *p_mi )
449 {
450     input_thread_t *p_input_thread;
451
452     p_input_thread = libvlc_get_input_thread(p_mi);
453     if( !p_input_thread ) return;
454
455     if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
456     {
457         vlc_object_release( p_input_thread );
458         return;
459     }
460     const bool b_selected = var_GetInteger( p_input_thread, "teletext-es" ) >= 0;
461     if( b_selected )
462     {
463         var_SetInteger( p_input_thread, "spu-es", -1 );
464     }
465     else
466     {
467         vlc_value_t list;
468         if( !var_Change( p_input_thread, "teletext-es", VLC_VAR_GETLIST, &list, NULL ) )
469         {
470             if( list.p_list->i_count > 0 )
471                 var_SetInteger( p_input_thread, "spu-es", list.p_list->p_values[0].i_int );
472
473             var_FreeList( &list, NULL );
474         }
475     }
476     vlc_object_release( p_input_thread );
477 }
478
479 int libvlc_video_get_track_count( libvlc_media_player_t *p_mi )
480 {
481     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
482     int i_track_count;
483
484     if( !p_input_thread )
485         return -1;
486
487     i_track_count = var_CountChoices( p_input_thread, "video-es" );
488
489     vlc_object_release( p_input_thread );
490     return i_track_count;
491 }
492
493 libvlc_track_description_t *
494         libvlc_video_get_track_description( libvlc_media_player_t *p_mi )
495 {
496     return libvlc_get_track_description( p_mi, "video-es" );
497 }
498
499 int libvlc_video_get_track( libvlc_media_player_t *p_mi )
500 {
501     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
502     vlc_value_t val_list;
503     vlc_value_t val;
504     int i_track = -1;
505
506     if( !p_input_thread )
507         return -1;
508
509     if( var_Get( p_input_thread, "video-es", &val ) < 0 )
510     {
511         libvlc_printerr( "Video track information not found" );
512         vlc_object_release( p_input_thread );
513         return -1;
514     }
515
516     var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
517     for( int i = 0; i < val_list.p_list->i_count; i++ )
518     {
519         if( val_list.p_list->p_values[i].i_int == val.i_int )
520         {
521             i_track = i;
522             break;
523         }
524     }
525     var_FreeList( &val_list, NULL );
526     vlc_object_release( p_input_thread );
527     return i_track;
528 }
529
530 int libvlc_video_set_track( libvlc_media_player_t *p_mi, int i_track )
531 {
532     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
533     vlc_value_t val_list;
534     int i_ret = -1;
535
536     if( !p_input_thread )
537         return -1;
538
539     var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
540     for( int i = 0; i < val_list.p_list->i_count; i++ )
541     {
542         if( i_track == val_list.p_list->p_values[i].i_int )
543         {
544             if( var_SetInteger( p_input_thread, "video-es", i_track ) < 0 )
545                 break;
546             i_ret = 0;
547             goto end;
548         }
549     }
550     libvlc_printerr( "Video track number out of range" );
551 end:
552     var_FreeList( &val_list, NULL );
553     vlc_object_release( p_input_thread );
554     return i_ret;
555 }
556
557 /******************************************************************************
558  * libvlc_video_set_deinterlace : enable deinterlace
559  *****************************************************************************/
560 void libvlc_video_set_deinterlace( libvlc_media_player_t *p_mi,
561                                    const char *psz_mode )
562 {
563     if (psz_mode == NULL)
564         psz_mode = "";
565     if (*psz_mode
566      && strcmp (psz_mode, "blend")   && strcmp (psz_mode, "bob")
567      && strcmp (psz_mode, "discard") && strcmp (psz_mode, "linear")
568      && strcmp (psz_mode, "mean")    && strcmp (psz_mode, "x")
569      && strcmp (psz_mode, "yadif")   && strcmp (psz_mode, "yadif2x"))
570         return;
571
572     if (*psz_mode)
573     {
574         var_SetString (p_mi, "deinterlace-mode", psz_mode);
575         var_SetInteger (p_mi, "deinterlace", 1);
576     }
577     else
578         var_SetInteger (p_mi, "deinterlace", 0);
579
580     size_t n;
581     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
582     for (size_t i = 0; i < n; i++)
583     {
584         vout_thread_t *p_vout = pp_vouts[i];
585
586         if (*psz_mode)
587         {
588             var_SetString (p_vout, "deinterlace-mode", psz_mode);
589             var_SetInteger (p_vout, "deinterlace", 1);
590         }
591         else
592             var_SetInteger (p_vout, "deinterlace", 0);
593         vlc_object_release (p_vout);
594     }
595     free (pp_vouts);
596 }
597
598 /* ************** */
599 /* module helpers */
600 /* ************** */
601
602
603 static vlc_object_t *get_object( libvlc_media_player_t * p_mi,
604                                  const char *name, libvlc_exception_t *p_e )
605 {
606     vlc_object_t *object = NULL;
607     vout_thread_t  *vout = GetVout( p_mi, 0 );
608     libvlc_exception_clear( p_e );
609     if( vout )
610     {
611         object = vlc_object_find_name( vout, name, FIND_CHILD );
612         vlc_object_release(vout);
613     }
614     if( !object )
615     {
616         libvlc_exception_raise( p_e );
617         libvlc_printerr( "%s not enabled", name );
618     }
619     return object;
620 }
621
622
623 typedef const struct {
624     const char name[20]; /* probably will become a const char * sometime */
625     unsigned type;
626 } opt_t;
627
628
629 static void
630 set_int( libvlc_media_player_t *p_mi, const char *name,
631          const opt_t *opt, int value, libvlc_exception_t *p_e )
632 {
633     if( !opt ) return;
634
635     if( !opt->type ) /* the enabler */
636     {
637         vout_thread_t *vout = GetVout( p_mi, 0 );
638         if (vout)
639         {
640             vout_EnableFilter( vout, opt->name, value, false );
641             vlc_object_release( vout );
642         }
643         return;
644     }
645
646     vlc_object_t *object = get_object( p_mi, name, p_e );
647     if( !object ) return;
648
649     switch( opt->type )
650     {
651     case VLC_VAR_INTEGER:
652         var_SetInteger(object, opt->name, value);
653         break;
654     default:
655         libvlc_exception_raise( p_e );
656         libvlc_printerr( "Invalid argument for %s in %s", name, "set int" );
657         break;
658     }
659     vlc_object_release( object );
660 }
661
662
663 static int
664 get_int( libvlc_media_player_t *p_mi, const char *name,
665         const opt_t *opt, libvlc_exception_t *p_e )
666 {
667     if( !opt ) return 0;
668
669     vlc_object_t *object = get_object( p_mi, name, p_e );
670     if( !object ) return 0;
671
672     int ret;
673     switch( opt->type )
674     {
675     case 0: /* the enabler */
676         ret = NULL != object;
677         break;
678     case VLC_VAR_INTEGER:
679         ret = var_GetInteger(object, opt->name);
680         break;
681     default:
682         libvlc_exception_raise( p_e );
683         libvlc_printerr( "Invalid argument for %s in %s", name, "get int" );
684         ret = 0;
685         break;
686     }
687     vlc_object_release( object );
688     return ret;
689 }
690
691
692 static void
693 set_string( libvlc_media_player_t *p_mi, const char *name, const opt_t *opt,
694             const char *psz_value, libvlc_exception_t *p_e )
695 {
696     if( !opt ) return;
697     vlc_object_t *object = get_object( p_mi, name, p_e );
698     if( !object ) return;
699
700     switch( opt->type )
701     {
702     case VLC_VAR_STRING:
703         var_SetString( object, opt->name, psz_value );
704         break;
705     default:
706         libvlc_exception_raise( p_e );
707         libvlc_printerr( "Invalid argument for %s in %s", name, "set string" );
708         break;
709     }
710     vlc_object_release( object );
711 }
712
713
714 static char *
715 get_string( libvlc_media_player_t *p_mi, const char *name,
716             const opt_t *opt, libvlc_exception_t *p_e )
717 {
718     if( !opt ) return NULL;
719     vlc_object_t *object = get_object( p_mi, name, p_e );
720     if( !object ) return NULL;
721
722     char *ret;
723     switch( opt->type )
724     {
725     case VLC_VAR_STRING:
726         ret = var_GetString( object, opt->name );
727         break;
728     default:
729         libvlc_exception_raise( p_e );
730         libvlc_printerr( "Invalid argument for %s in %s", name, "get string" );
731         ret = NULL;
732         break;
733     }
734     vlc_object_release( object );
735     return ret;
736 }
737
738
739 /*****************************************************************************
740  * Marquee: FIXME: That implementation has no persistent state and requires
741  * a vout
742  *****************************************************************************/
743
744 static const opt_t *
745 marq_option_bynumber(unsigned option, libvlc_exception_t *p_e)
746 {
747     opt_t optlist[] =
748     {
749         { "marq",          0 },
750         { "marq-marquee",  VLC_VAR_STRING },
751         { "marq-color",    VLC_VAR_INTEGER },
752         { "marq-opacity",  VLC_VAR_INTEGER },
753         { "marq-position", VLC_VAR_INTEGER },
754         { "marq-refresh",  VLC_VAR_INTEGER },
755         { "marq-size",     VLC_VAR_INTEGER },
756         { "marq-timeout",  VLC_VAR_INTEGER },
757         { "marq-x",        VLC_VAR_INTEGER },
758         { "marq-y",        VLC_VAR_INTEGER },
759     };
760     enum { num_opts = sizeof(optlist) / sizeof(*optlist) };
761
762     opt_t *r = option < num_opts ? optlist+option : NULL;
763     if( !r )
764     {
765         libvlc_exception_raise( p_e );
766         libvlc_printerr( "Unknown marquee option" );
767     }
768     return r;
769 }
770
771 static vlc_object_t *get_object( libvlc_media_player_t *,
772                                  const char *, libvlc_exception_t *);
773
774 /*****************************************************************************
775  * libvlc_video_get_marquee_int : get a marq option value
776  *****************************************************************************/
777 int libvlc_video_get_marquee_int( libvlc_media_player_t *p_mi,
778                                   unsigned option, libvlc_exception_t *p_e )
779 {
780     return get_int( p_mi, "marq", marq_option_bynumber(option,p_e), p_e );
781 }
782
783 /*****************************************************************************
784  * libvlc_video_get_marquee_string : get a marq option value
785  *****************************************************************************/
786 char * libvlc_video_get_marquee_string( libvlc_media_player_t *p_mi,
787                                     unsigned option, libvlc_exception_t *p_e )
788 {
789     return get_string( p_mi, "marq", marq_option_bynumber(option,p_e), p_e );
790 }
791
792 /*****************************************************************************
793  * libvlc_video_set_marquee_int: enable, disable or set an int option
794  *****************************************************************************/
795 void libvlc_video_set_marquee_int( libvlc_media_player_t *p_mi,
796                          unsigned option, int value, libvlc_exception_t *p_e )
797 {
798     set_int( p_mi, "marq", marq_option_bynumber(option,p_e), value, p_e );
799 }
800
801 /*****************************************************************************
802  * libvlc_video_set_marquee_string: set a string option
803  *****************************************************************************/
804 void libvlc_video_set_marquee_string( libvlc_media_player_t *p_mi,
805                 unsigned option, const char * value, libvlc_exception_t *p_e )
806 {
807     set_string( p_mi, "marq", marq_option_bynumber(option,p_e), value, p_e );
808 }
809
810
811 /* logo module support */
812
813
814 static opt_t *
815 logo_option_bynumber( unsigned option, libvlc_exception_t *p_e )
816 {
817     opt_t vlogo_optlist[] = /* depends on libvlc_video_logo_option_t */
818     {
819         { "logo",          0 },
820         { "logo-file",     VLC_VAR_STRING },
821         { "logo-x",        VLC_VAR_INTEGER },
822         { "logo-y",        VLC_VAR_INTEGER },
823         { "logo-delay",    VLC_VAR_INTEGER },
824         { "logo-repeat",   VLC_VAR_INTEGER },
825         { "logo-opacity",  VLC_VAR_INTEGER },
826         { "logo-position", VLC_VAR_INTEGER },
827     };
828     enum { num_vlogo_opts = sizeof(vlogo_optlist) / sizeof(*vlogo_optlist) };
829
830     opt_t *r = option < num_vlogo_opts ? vlogo_optlist+option : NULL;
831     if( !r )
832     {
833         libvlc_exception_raise( p_e );
834         libvlc_printerr( "Unknown logo option" );
835     }
836     return r;
837 }
838
839
840 void libvlc_video_set_logo_string( libvlc_media_player_t *p_mi,
841                                    unsigned option, const char *psz_value,
842                                    libvlc_exception_t *p_e )
843 {
844     set_string( p_mi,"logo",logo_option_bynumber(option,p_e),psz_value,p_e );
845 }
846
847
848 void libvlc_video_set_logo_int( libvlc_media_player_t *p_mi,
849                                 unsigned option, int value,
850                                 libvlc_exception_t *p_e )
851 {
852     set_int( p_mi, "logo", logo_option_bynumber(option, p_e), value, p_e );
853 }
854
855
856 int libvlc_video_get_logo_int( libvlc_media_player_t *p_mi,
857                                unsigned option, libvlc_exception_t *p_e )
858 {
859     return get_int( p_mi, "logo", logo_option_bynumber(option,p_e), p_e );
860 }
861
862