]> git.sesse.net Git - vlc/blob - modules/video_filter/marq.c
Only update the marquee text if needed (ie we're using % or $ chars)
[vlc] / modules / video_filter / marq.c
1 /*****************************************************************************
2  * marq.c : marquee display video plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2003-2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Mark Moriarty
8  *          Sigmund Augdal Helberg <dnumgis@videolan.org>
9  *          Antoine Cellerier <dionoea . videolan \ org>
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdlib.h>                                      /* malloc(), free() */
30 #include <string.h>
31
32 #include <time.h>
33
34 #include <vlc/vlc.h>
35 #include <vlc/vout.h>
36
37 #include "vlc_filter.h"
38 #include "vlc_block.h"
39 #include "vlc_osd.h"
40 #include "vlc_playlist.h"
41 #include "vlc_meta.h"
42 #include "vlc_input.h"
43 #include <vlc/aout.h>
44
45 /*****************************************************************************
46  * Local prototypes
47  *****************************************************************************/
48 static int  CreateFilter ( vlc_object_t * );
49 static void DestroyFilter( vlc_object_t * );
50 static subpicture_t *Filter( filter_t *, mtime_t );
51
52
53 static int MarqueeCallback( vlc_object_t *p_this, char const *psz_var,
54                             vlc_value_t oldval, vlc_value_t newval,
55                             void *p_data );
56 static int pi_color_values[] = { 0xf0000000, 0x00000000, 0x00808080, 0x00C0C0C0,
57                0x00FFFFFF, 0x00800000, 0x00FF0000, 0x00FF00FF, 0x00FFFF00,
58                0x00808000, 0x00008000, 0x00008080, 0x0000FF00, 0x00800080,
59                0x00000080, 0x000000FF, 0x0000FFFF};
60 static char *ppsz_color_descriptions[] = { N_("Default"), N_("Black"),
61                N_("Gray"), N_("Silver"), N_("White"), N_("Maroon"), N_("Red"),
62                N_("Fuchsia"), N_("Yellow"), N_("Olive"), N_("Green"),
63                N_("Teal"), N_("Lime"), N_("Purple"), N_("Navy"), N_("Blue"),
64                N_("Aqua") };
65
66 /*****************************************************************************
67  * filter_sys_t: marquee filter descriptor
68  *****************************************************************************/
69 struct filter_sys_t
70 {
71     int i_xoff, i_yoff;  /* offsets for the display string in the video window */
72     int i_pos; /* permit relative positioning (top, bottom, left, right, center) */
73     int i_timeout;
74
75     char *psz_marquee;    /* marquee string */
76
77     text_style_t *p_style; /* font control */
78
79     time_t last_time;
80
81     vlc_bool_t b_need_update;
82 };
83
84 #define MSG_TEXT N_("Text")
85 #define MSG_LONGTEXT N_( \
86     "Marquee text to display. " \
87     "(Available format strings: " \
88     "Time related: %Y = year, %m = month, %d = day, %H = hour, " \
89     "%M = minute, %S = second, ... " \
90     "Meta data related: $a = artist, $b = album, $c = copyright, " \
91     "$d = description, $e = encoded by, $g = genre, " \
92     "$l = language, $n = track num, $p = now playing, " \
93     "$r = rating, $s = subtitles language, $t = title, "\
94     "$u = url, $A = date, " \
95     "$B = audio bitrate (in kb/s), $C = chapter," \
96     "$D = duration, $F = full name with path, $I = title, "\
97     "$L = time left, " \
98     "$N = name, $O = audio language, $P = position (in %), $R = rate, " \
99     "$S = audio sample rate (in kHz), " \
100     "$T = time, $U = publisher, $V = volume, $_ = new line) ")
101 #define POSX_TEXT N_("X offset")
102 #define POSX_LONGTEXT N_("X offset, from the left screen edge." )
103 #define POSY_TEXT N_("Y offset")
104 #define POSY_LONGTEXT N_("Y offset, down from the top." )
105 #define TIMEOUT_TEXT N_("Timeout")
106 #define TIMEOUT_LONGTEXT N_("Number of milliseconds the marquee must remain " \
107                             "displayed. Default value is " \
108                             "0 (remains forever).")
109 #define OPACITY_TEXT N_("Opacity")
110 #define OPACITY_LONGTEXT N_("Opacity (inverse of transparency) of " \
111     "overlayed text. 0 = transparent, 255 = totally opaque. " )
112 #define SIZE_TEXT N_("Font size, pixels")
113 #define SIZE_LONGTEXT N_("Font size, in pixels. Default is -1 (use default " \
114     "font size)." )
115
116 #define COLOR_TEXT N_("Color")
117 #define COLOR_LONGTEXT N_("Color of the text that will be rendered on "\
118     "the video. This must be an hexadecimal (like HTML colors). The first two "\
119     "chars are for red, then green, then blue. #000000 = black, #FF0000 = red,"\
120     " #00FF00 = green, #FFFF00 = yellow (red + green), #FFFFFF = white" )
121
122 #define POS_TEXT N_("Marquee position")
123 #define POS_LONGTEXT N_( \
124   "You can enforce the marquee position on the video " \
125   "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
126   "also use combinations of these values, eg 6 = top-right).")
127
128 static int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
129 static char *ppsz_pos_descriptions[] =
130      { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
131      N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
132
133 /*****************************************************************************
134  * Module descriptor
135  *****************************************************************************/
136 vlc_module_begin();
137     set_capability( "sub filter", 0 );
138     set_shortname( N_("Marquee" ));
139     set_callbacks( CreateFilter, DestroyFilter );
140     set_category( CAT_VIDEO );
141     set_subcategory( SUBCAT_VIDEO_SUBPIC );
142     add_string( "marq-marquee", "VLC", NULL, MSG_TEXT, MSG_LONGTEXT,
143                 VLC_FALSE );
144
145     set_section( N_("Position"), NULL );
146     add_integer( "marq-x", -1, NULL, POSX_TEXT, POSX_LONGTEXT, VLC_TRUE );
147     add_integer( "marq-y", 0, NULL, POSY_TEXT, POSY_LONGTEXT, VLC_TRUE );
148     add_integer( "marq-position", 5, NULL, POS_TEXT, POS_LONGTEXT, VLC_FALSE );
149
150     set_section( N_("Font"), NULL );
151     /* 5 sets the default to top [1] left [4] */
152     change_integer_list( pi_pos_values, ppsz_pos_descriptions, 0 );
153     add_integer_with_range( "marq-opacity", 255, 0, 255, NULL,
154         OPACITY_TEXT, OPACITY_LONGTEXT, VLC_FALSE );
155     add_integer( "marq-color", 0xFFFFFF, NULL, COLOR_TEXT, COLOR_LONGTEXT,
156                   VLC_FALSE );
157         change_integer_list( pi_color_values, ppsz_color_descriptions, 0 );
158     add_integer( "marq-size", -1, NULL, SIZE_TEXT, SIZE_LONGTEXT, VLC_FALSE );
159
160     set_section( N_("Misc"), NULL );
161     add_integer( "marq-timeout", 0, NULL, TIMEOUT_TEXT, TIMEOUT_LONGTEXT,
162                  VLC_FALSE );
163
164     set_description( _("Marquee display") );
165     add_shortcut( "marq" );
166     add_shortcut( "time" );
167 vlc_module_end();
168
169 /*****************************************************************************
170  * CreateFilter: allocates marquee video filter
171  *****************************************************************************/
172 static int CreateFilter( vlc_object_t *p_this )
173 {
174     filter_t *p_filter = (filter_t *)p_this;
175     filter_sys_t *p_sys;
176
177     /* Allocate structure */
178     p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) );
179     if( p_sys == NULL )
180     {
181         msg_Err( p_filter, "out of memory" );
182         return VLC_ENOMEM;
183     }
184
185     p_sys->p_style = malloc( sizeof( text_style_t ) );
186     memcpy( p_sys->p_style, &default_text_style, sizeof( text_style_t ) );
187
188 #define CREATE_VAR( stor, type, var ) \
189     p_sys->stor = var_CreateGet##type( p_filter->p_libvlc, var ); \
190     var_AddCallback( p_filter->p_libvlc, var, MarqueeCallback, p_sys );
191
192     CREATE_VAR( i_xoff, Integer, "marq-x" );
193     CREATE_VAR( i_yoff, Integer, "marq-y" );
194     CREATE_VAR( i_timeout,Integer, "marq-timeout" );
195     CREATE_VAR( i_pos, Integer, "marq-position" );
196     CREATE_VAR( psz_marquee, String, "marq-marquee" );
197     CREATE_VAR( p_style->i_font_alpha, Integer, "marq-opacity" );
198     CREATE_VAR( p_style->i_font_color, Integer, "marq-color" );
199     CREATE_VAR( p_style->i_font_size, Integer, "marq-size" );
200
201     p_sys->p_style->i_font_alpha = 255 - p_sys->p_style->i_font_alpha ;
202
203     /* Misc init */
204     p_filter->pf_sub_filter = Filter;
205     p_sys->last_time = ((time_t)-1);
206     p_sys->b_need_update = VLC_TRUE;
207
208     return VLC_SUCCESS;
209 }
210 /*****************************************************************************
211  * DestroyFilter: destroy marquee video filter
212  *****************************************************************************/
213 static void DestroyFilter( vlc_object_t *p_this )
214 {
215     filter_t *p_filter = (filter_t *)p_this;
216     filter_sys_t *p_sys = p_filter->p_sys;
217
218     if( p_sys->p_style ) free( p_sys->p_style );
219     if( p_sys->psz_marquee ) free( p_sys->psz_marquee );
220     free( p_sys );
221
222     /* Delete the marquee variables */
223 #define DEL_VAR(var) \
224     var_DelCallback( p_filter->p_libvlc, var, MarqueeCallback, p_sys ); \
225     var_Destroy( p_filter->p_libvlc, var );
226     DEL_VAR( "marq-x" );
227     DEL_VAR( "marq-y" );
228     DEL_VAR( "marq-marquee" );
229     DEL_VAR( "marq-timeout" );
230     DEL_VAR( "marq-position" );
231     DEL_VAR( "marq-color" );
232     DEL_VAR( "marq-opacity" );
233     DEL_VAR( "marq-size" );
234 }
235 /****************************************************************************
236  * String formating functions
237  ****************************************************************************/
238
239 static char *FormatTime(char *tformat )
240 {
241     char buffer[255];
242     time_t curtime;
243 #if defined(HAVE_LOCALTIME_R)
244     struct tm loctime;
245 #else
246     struct tm *loctime;
247 #endif
248
249     /* Get the current time.  */
250     curtime = time( NULL );
251
252     /* Convert it to local time representation.  */
253 #if defined(HAVE_LOCALTIME_R)
254     localtime_r( &curtime, &loctime );
255     strftime( buffer, 255, tformat, &loctime );
256 #else
257     loctime = localtime( &curtime );
258     strftime( buffer, 255, tformat, loctime );
259 #endif
260     return strdup( buffer );
261 }
262
263 #define INSERT_STRING( check, string )                              \
264                     if( check && string )                           \
265                     {                                               \
266                         int len = strlen( string );                 \
267                         dst = realloc( dst,                         \
268                                        i_size = i_size + len + 1 ); \
269                         strncpy( d, string, len+1 );                \
270                         d += len;                                   \
271                     }                                               \
272                     else                                            \
273                     {                                               \
274                         *d = '-';                                   \
275                         d++;                                        \
276                     }
277 char *FormatMeta( vlc_object_t *p_object, char *string )
278 {
279     char *s = string;
280     char *dst = malloc( 1000 );
281     char *d = dst;
282     int b_is_format = 0;
283     char buf[10];
284     int i_size = strlen( string );
285
286     playlist_t *p_playlist = pl_Yield( p_object );
287     input_thread_t *p_input = p_playlist->p_input;
288     input_item_t *p_item = NULL;
289     pl_Release( p_object );
290     if( p_input )
291     {
292         vlc_object_yield( p_input );
293         p_item = p_input->input.p_item;
294         if( p_item )
295             vlc_mutex_lock( &p_item->lock );
296     }
297
298     sprintf( dst, string );
299
300     while( *s )
301     {
302         if( b_is_format )
303         {
304             switch( *s )
305             {
306                 case 'a':
307                     INSERT_STRING( p_item && p_item->p_meta,
308                                    p_item->p_meta->psz_artist );
309                     break;
310                 case 'b':
311                     INSERT_STRING( p_item && p_item->p_meta,
312                                    p_item->p_meta->psz_album );
313                     break;
314                 case 'c':
315                     INSERT_STRING( p_item && p_item->p_meta,
316                                    p_item->p_meta->psz_copyright );
317                     break;
318                 case 'd':
319                     INSERT_STRING( p_item && p_item->p_meta,
320                                    p_item->p_meta->psz_description );
321                     break;
322                 case 'e':
323                     INSERT_STRING( p_item && p_item->p_meta,
324                                    p_item->p_meta->psz_encodedby );
325                     break;
326                 case 'g':
327                     INSERT_STRING( p_item && p_item->p_meta,
328                                    p_item->p_meta->psz_genre );
329                     break;
330                 case 'l':
331                     INSERT_STRING( p_item && p_item->p_meta,
332                                    p_item->p_meta->psz_language );
333                     break;
334                 case 'n':
335                     INSERT_STRING( p_item && p_item->p_meta,
336                                    p_item->p_meta->psz_tracknum );
337                     break;
338                 case 'p':
339                     INSERT_STRING( p_item && p_item->p_meta,
340                                    p_item->p_meta->psz_nowplaying );
341                     break;
342                 case 'r':
343                     INSERT_STRING( p_item && p_item->p_meta,
344                                    p_item->p_meta->psz_rating );
345                     break;
346                 case 's':
347                 {
348                     char *lang;
349                     if( p_input )
350                     {
351                         lang = var_GetString( p_input, "sub-language" );
352                     }
353                     else
354                     {
355                         lang = strdup( "-" );
356                     }
357                     INSERT_STRING( 1, lang );
358                     free( lang );
359                     break;
360                 }
361                 case 't':
362                     INSERT_STRING( p_item && p_item->p_meta,
363                                    p_item->p_meta->psz_title );
364                     break;
365                 case 'u':
366                     INSERT_STRING( p_item && p_item->p_meta,
367                                    p_item->p_meta->psz_url );
368                     break;
369                 case 'A':
370                     INSERT_STRING( p_item && p_item->p_meta,
371                                    p_item->p_meta->psz_date );
372                     break;
373                 case 'B':
374                     if( p_input )
375                     {
376                         snprintf( buf, 10, "%d",
377                                   var_GetInteger( p_input, "bit-rate" )/1000 );
378                     }
379                     else
380                     {
381                         sprintf( buf, "-" );
382                     }
383                     INSERT_STRING( 1, buf );
384                     break;
385                 case 'C':
386                     if( p_input )
387                     {
388                         snprintf( buf, 10, "%d",
389                                   var_GetInteger( p_input, "chapter" ) );
390                     }
391                     else
392                     {
393                         sprintf( buf, "-" );
394                     }
395                     INSERT_STRING( 1, buf );
396                     break;
397                 case 'D':
398                     if( p_item )
399                     {
400                         sprintf( buf, "%02d:%02d:%02d",
401                                  (int)(p_item->i_duration/(3600000000)),
402                                  (int)((p_item->i_duration/(60000000))%60),
403                                  (int)((p_item->i_duration/1000000)%60) );
404                     }
405                     else
406                     {
407                         sprintf( buf, "--:--:--" );
408                     }
409                     INSERT_STRING( 1, buf );
410                     break;
411                 case 'F':
412                     INSERT_STRING( p_item, p_item->psz_uri );
413                     break;
414                 case 'I':
415                     if( p_input )
416                     {
417                         snprintf( buf, 10, "%d",
418                                   var_GetInteger( p_input, "title" ) );
419                     }
420                     else
421                     {
422                         sprintf( buf, "-" );
423                     }
424                     INSERT_STRING( 1, buf );
425                     break;
426                 case 'L':
427                     if( p_item && p_input )
428                     {
429                         sprintf( buf, "%02d:%02d:%02d",
430                      (int)((p_item->i_duration-p_input->i_time)/(3600000000)),
431                      (int)(((p_item->i_duration-p_input->i_time)/(60000000))%60),
432                      (int)(((p_item->i_duration-p_input->i_time)/1000000)%60) );
433                     }
434                     else
435                     {
436                         sprintf( buf, "--:--:--" );
437                     }
438                     INSERT_STRING( 1, buf );
439                     break;
440                 case 'N':
441                     INSERT_STRING( p_item, p_item->psz_name );
442                     break;
443                 case 'O':
444                 {
445                     char *lang;
446                     if( p_input )
447                     {
448                         lang = var_GetString( p_input, "audio-language" );
449                     }
450                     else
451                     {
452                         lang = strdup( "-" );
453                     }
454                     INSERT_STRING( 1, lang );
455                     free( lang );
456                     break;
457                 }
458                 case 'P':
459                     if( p_input )
460                     {
461                         snprintf( buf, 10, "%2.1lf",
462                                   var_GetFloat( p_input, "position" ) * 100. );
463                     }
464                     else
465                     {
466                         sprintf( buf, "--.-%%" );
467                     }
468                     INSERT_STRING( 1, buf );
469                     break;
470                 case 'R':
471                     if( p_input )
472                     {
473                         int r = var_GetInteger( p_input, "rate" );
474                         snprintf( buf, 10, "%d.%d", r/1000, r%1000 );
475                     }
476                     else
477                     {
478                         sprintf( buf, "-" );
479                     }
480                     INSERT_STRING( 1, buf );
481                     break;
482                 case 'S':
483                     if( p_input )
484                     {
485                         int r = var_GetInteger( p_input, "sample-rate" );
486                         snprintf( buf, 10, "%d.%d", r/1000, (r/100)%10 );
487                     }
488                     else
489                     {
490                         sprintf( buf, "-" );
491                     }
492                     INSERT_STRING( 1, buf );
493                     break;
494                 case 'T':
495                     if( p_input )
496                     {
497                         sprintf( buf, "%02d:%02d:%02d",
498                                  (int)(p_input->i_time/(3600000000)),
499                                  (int)((p_input->i_time/(60000000))%60),
500                                  (int)((p_input->i_time/1000000)%60) );
501                     }
502                     else
503                     {
504                         sprintf( buf, "--:--:--" );
505                     }
506                     INSERT_STRING( 1, buf );
507                     break;
508                 case 'U':
509                     INSERT_STRING( p_item && p_item->p_meta,
510                                    p_item->p_meta->psz_publisher );
511                     break;
512                 case 'V':
513                 {
514                     audio_volume_t volume;
515                     aout_VolumeGet( p_object, &volume );
516                     snprintf( buf, 10, "%d", volume );
517                     INSERT_STRING( 1, buf );
518                     break;
519                 }
520                 case '_':
521                     *d = '\n';
522                     d++;
523                     break;
524
525                 default:
526                     *d = *s;
527                     d++;
528                     break;
529             }
530             b_is_format = 0;
531         }
532         else if( *s == '$' )
533         {
534             b_is_format = 1;
535         }
536         else
537         {
538             *d = *s;
539             d++;
540         }
541         s++;
542     }
543     *d = '\0';
544
545     if( p_input )
546     {
547         vlc_object_release( p_input );
548         if( p_item )
549             vlc_mutex_unlock( &p_item->lock );
550     }
551
552     return dst;
553 }
554
555 /****************************************************************************
556  * Filter: the whole thing
557  ****************************************************************************
558  * This function outputs subpictures at regular time intervals.
559  ****************************************************************************/
560 static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
561 {
562     filter_sys_t *p_sys = p_filter->p_sys;
563     subpicture_t *p_spu;
564     video_format_t fmt;
565     time_t t;
566     char *buf;
567
568     if( p_sys->last_time == time( NULL ) )
569     {
570         return NULL;
571     }
572
573     if( p_sys->b_need_update == VLC_FALSE )
574     {
575         return NULL;
576     }
577
578     p_spu = p_filter->pf_sub_buffer_new( p_filter );
579     if( !p_spu ) return NULL;
580
581     memset( &fmt, 0, sizeof(video_format_t) );
582     fmt.i_chroma = VLC_FOURCC('T','E','X','T');
583     fmt.i_aspect = 0;
584     fmt.i_width = fmt.i_height = 0;
585     fmt.i_x_offset = 0;
586     fmt.i_y_offset = 0;
587     p_spu->p_region = p_spu->pf_create_region( VLC_OBJECT(p_filter), &fmt );
588     if( !p_spu->p_region )
589     {
590         p_filter->pf_sub_buffer_del( p_filter, p_spu );
591         return NULL;
592     }
593
594     t = p_sys->last_time = time( NULL );
595
596     if( strchr( p_sys->psz_marquee, '%' ) || strchr( p_sys->psz_marquee, '$' ) )
597     {
598         p_sys->b_need_update = VLC_TRUE;
599     }
600     else
601     {
602         p_sys->b_need_update = VLC_FALSE;
603     }
604     buf = FormatTime( p_sys->psz_marquee );
605     p_spu->p_region->psz_text = FormatMeta( VLC_OBJECT( p_filter ), buf );
606     free( buf );
607     p_spu->i_start = date;
608     p_spu->i_stop  = p_sys->i_timeout == 0 ? 0 : date + p_sys->i_timeout * 1000;
609     p_spu->b_ephemer = VLC_TRUE;
610
611     /*  where to locate the string: */
612     if( p_sys->i_xoff < 0 || p_sys->i_yoff < 0 )
613     {   /* set to one of the 9 relative locations */
614         p_spu->i_flags = p_sys->i_pos;
615         p_spu->i_x = 0;
616         p_spu->i_y = 0;
617         p_spu->b_absolute = VLC_FALSE;
618     }
619     else
620     {   /*  set to an absolute xy, referenced to upper left corner */
621         p_spu->i_flags = OSD_ALIGN_LEFT | OSD_ALIGN_TOP;
622         p_spu->i_x = p_sys->i_xoff;
623         p_spu->i_y = p_sys->i_yoff;
624         p_spu->b_absolute = VLC_TRUE;
625     }
626     p_spu->p_region->p_style = p_sys->p_style;
627
628     return p_spu;
629 }
630
631 /**********************************************************************
632  * Callback to update params on the fly
633  **********************************************************************/
634 static int MarqueeCallback( vlc_object_t *p_this, char const *psz_var,
635                             vlc_value_t oldval, vlc_value_t newval,
636                             void *p_data )
637 {
638     filter_sys_t *p_sys = (filter_sys_t *) p_data;
639
640     if( !strncmp( psz_var, "marq-marquee", 7 ) )
641     {
642         if( p_sys->psz_marquee ) free( p_sys->psz_marquee );
643         p_sys->psz_marquee = strdup( newval.psz_string );
644     }
645     else if ( !strncmp( psz_var, "marq-x", 6 ) )
646     {
647         p_sys->i_xoff = newval.i_int;
648     }
649     else if ( !strncmp( psz_var, "marq-y", 6 ) )
650     {
651         p_sys->i_yoff = newval.i_int;
652     }
653     else if ( !strncmp( psz_var, "marq-color", 8 ) )  /* "marq-col" */
654     {
655         p_sys->p_style->i_font_color = newval.i_int;
656     }
657     else if ( !strncmp( psz_var, "marq-opacity", 8 ) ) /* "marq-opa" */
658     {
659         p_sys->p_style->i_font_alpha = 255 - newval.i_int;
660     }
661     else if ( !strncmp( psz_var, "marq-size", 6 ) )
662     {
663         p_sys->p_style->i_font_size = newval.i_int;
664     }
665     else if ( !strncmp( psz_var, "marq-timeout", 12 ) )
666     {
667         p_sys->i_timeout = newval.i_int;
668     }
669     else if ( !strncmp( psz_var, "marq-position", 8 ) )
670     /* willing to accept a match against marq-pos */
671     {
672         p_sys->i_pos = newval.i_int;
673         p_sys->i_xoff = -1;       /* force to relative positioning */
674     }
675     p_sys->b_need_update = VLC_TRUE;
676     return VLC_SUCCESS;
677 }