1 /*****************************************************************************
2 * osdmenu.c: osd filter module
3 *****************************************************************************
4 * Copyright (C) 2004-2007 M2X
7 * Authors: Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implid warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_filter.h>
37 /*****************************************************************************
39 *****************************************************************************/
41 /* FIXME: Future extension make the definition file in XML format. */
42 #define OSD_FILE_TEXT N_("Configuration file")
43 #define OSD_FILE_LONGTEXT N_( \
44 "Configuration file for the OSD Menu." )
45 #define OSD_PATH_TEXT N_("Path to OSD menu images")
46 #define OSD_PATH_LONGTEXT N_( \
47 "Path to the OSD menu images. This will override the path defined in the " \
48 "OSD configuration file." )
50 #define POSX_TEXT N_("X coordinate")
51 #define POSX_LONGTEXT N_("You can move the OSD menu by left-clicking on it." )
53 #define POSY_TEXT N_("Y coordinate")
54 #define POSY_LONGTEXT N_("You can move the OSD menu by left-clicking on it." )
56 #define POS_TEXT N_("Menu position")
57 #define POS_LONGTEXT N_( \
58 "You can enforce the OSD menu position on the video " \
59 "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
60 "also use combinations of these values, eg. 6 = top-right).")
62 #define TIMEOUT_TEXT N_("Menu timeout")
63 #define TIMEOUT_LONGTEXT N_( \
64 "OSD menu pictures get a default timeout of 15 seconds added to their " \
65 "remaining time. This will ensure that they are at least the specified " \
68 #define OSD_UPDATE_TEXT N_("Menu update interval" )
69 #define OSD_UPDATE_LONGTEXT N_( \
70 "The default is to update the OSD menu picture every 200 ms. Shorten the" \
71 " update time for environments that experience transmissions errors. " \
72 "Be careful with this option as encoding OSD menu pictures is very " \
73 "computing intensive. The range is 0 - 1000 ms." )
75 #define OSD_ALPHA_TEXT N_("Alpha transparency value (default 255)")
76 #define OSD_ALPHA_LONGTEXT N_( \
77 "The transparency of the OSD menu can be changed by giving a value " \
78 "between 0 and 255. A lower value specifies more transparency a higher " \
79 "means less transparency. The default is being not transparent " \
80 "(value 255) the minimum is fully transparent (value 0)." )
82 static const int pi_pos_values
[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
83 static const char *const ppsz_pos_descriptions
[] =
84 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
85 N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
87 /* subfilter functions */
88 static int CreateFilter ( vlc_object_t
* );
89 static void DestroyFilter( vlc_object_t
* );
90 static subpicture_t
*Filter( filter_t
*, mtime_t
);
92 static int OSDMenuUpdateEvent( vlc_object_t
*, char const *,
93 vlc_value_t
, vlc_value_t
, void * );
94 static int OSDMenuVisibleEvent( vlc_object_t
*, char const *,
95 vlc_value_t
, vlc_value_t
, void * );
96 static int OSDMenuCallback( vlc_object_t
*, char const *,
97 vlc_value_t
, vlc_value_t
, void * );
99 static int MouseEvent( filter_t
*,
102 const video_format_t
* );
104 #define OSD_CFG "osdmenu-"
106 #if defined( WIN32 ) || defined( UNDER_CE )
107 #define OSD_DEFAULT_CFG "osdmenu/default.cfg"
109 #define OSD_DEFAULT_CFG "share/osdmenu/default.cfg"
112 #define OSD_UPDATE_MIN 0
113 #define OSD_UPDATE_DEFAULT 300
114 #define OSD_UPDATE_MAX 1000
117 set_capability( "sub filter", 100 )
118 set_description( N_("On Screen Display menu") )
119 set_shortname( N_("OSD menu") )
120 add_shortcut( "osdmenu" )
122 set_category( CAT_VIDEO
)
123 set_subcategory( SUBCAT_VIDEO_SUBPIC
)
125 set_callbacks( CreateFilter
, DestroyFilter
)
127 add_integer( OSD_CFG
"x", -1, NULL
, POSX_TEXT
, POSX_LONGTEXT
, false )
128 add_integer( OSD_CFG
"y", -1, NULL
, POSY_TEXT
, POSY_LONGTEXT
, false )
129 add_integer( OSD_CFG
"position", 8, NULL
, POS_TEXT
, POS_LONGTEXT
,
131 change_integer_list( pi_pos_values
, ppsz_pos_descriptions
, NULL
)
132 add_string( OSD_CFG
"file", OSD_DEFAULT_CFG
, NULL
, OSD_FILE_TEXT
,
133 OSD_FILE_LONGTEXT
, false )
134 add_string( OSD_CFG
"file-path", NULL
, NULL
, OSD_PATH_TEXT
,
135 OSD_PATH_LONGTEXT
, false )
136 add_integer( OSD_CFG
"timeout", 15, NULL
, TIMEOUT_TEXT
,
137 TIMEOUT_LONGTEXT
, false )
138 add_integer_with_range( OSD_CFG
"update", OSD_UPDATE_DEFAULT
,
139 OSD_UPDATE_MIN
, OSD_UPDATE_MAX
, NULL
, OSD_UPDATE_TEXT
,
140 OSD_UPDATE_LONGTEXT
, true )
141 add_integer_with_range( OSD_CFG
"alpha", 255, 0, 255, NULL
,
142 OSD_ALPHA_TEXT
, OSD_ALPHA_LONGTEXT
, true )
146 /*****************************************************************************
148 *****************************************************************************/
150 /*****************************************************************************
152 *****************************************************************************/
155 int i_position
; /* relative positioning of SPU images */
156 int i_x
; /* absolute positioning of SPU images */
157 int i_y
; /* absolute positioning of SPU images */
158 mtime_t i_last_date
; /* last mdate SPU object has been sent to SPU subsytem */
159 mtime_t i_timeout
; /* duration SPU object is valid on the video output in seconds */
161 bool b_absolute
; /* do we use absolute positioning or relative? */
162 bool b_update
; /* Update OSD Menu by sending SPU objects */
163 bool b_visible
; /* OSD Menu is visible */
164 mtime_t i_update
; /* Update the OSD menu every n ms */
165 mtime_t i_end_date
; /* End data of display OSD menu */
166 int i_alpha
; /* alpha transparency value */
168 char *psz_file
; /* OSD Menu configuration file */
169 char *psz_path
; /* Path to OSD Menu pictures */
170 osd_menu_t
*p_menu
; /* pointer to OSD Menu object */
172 /* menu interaction */
178 /*****************************************************************************
179 * CreateFilter: Create the filter and open the definition file
180 *****************************************************************************/
181 static int CreateFilter ( vlc_object_t
*p_this
)
183 filter_t
*p_filter
= (filter_t
*)p_this
;
184 filter_sys_t
*p_sys
= NULL
;
186 p_filter
->p_sys
= p_sys
= (filter_sys_t
*) malloc( sizeof(filter_sys_t
) );
187 if( !p_filter
->p_sys
)
189 memset( p_sys
, 0, sizeof(filter_sys_t
) );
191 /* Populating struct */
192 p_sys
->psz_path
= var_CreateGetString( p_this
, OSD_CFG
"file-path" );
193 p_sys
->psz_file
= var_CreateGetString( p_this
, OSD_CFG
"file" );
194 if( (p_sys
->psz_file
== NULL
) ||
195 (*p_sys
->psz_file
== '\0') )
197 msg_Err( p_filter
, "unable to get filename" );
201 p_sys
->i_x
= var_CreateGetIntegerCommand( p_this
, OSD_CFG
"x" );
202 p_sys
->i_y
= var_CreateGetIntegerCommand( p_this
, OSD_CFG
"y" );
203 p_sys
->i_position
= var_CreateGetIntegerCommand( p_this
, OSD_CFG
"position" );
204 p_sys
->i_alpha
= var_CreateGetIntegerCommand( p_this
, OSD_CFG
"alpha" );
206 /* in micro seconds - divide by 2 to match user expectations */
207 p_sys
->i_timeout
= var_CreateGetIntegerCommand( p_this
, OSD_CFG
"timeout" );
208 p_sys
->i_timeout
= (mtime_t
)(p_sys
->i_timeout
* 1000000) >> 2;
209 p_sys
->i_update
= var_CreateGetIntegerCommand( p_this
, OSD_CFG
"update" );
210 p_sys
->i_update
= (mtime_t
)(p_sys
->i_update
* 1000); /* in micro seconds */
212 var_AddCallback( p_filter
, OSD_CFG
"position", OSDMenuCallback
, p_sys
);
213 var_AddCallback( p_filter
, OSD_CFG
"timeout", OSDMenuCallback
, p_sys
);
214 var_AddCallback( p_filter
, OSD_CFG
"update", OSDMenuCallback
, p_sys
);
215 var_AddCallback( p_filter
, OSD_CFG
"alpha", OSDMenuCallback
, p_sys
);
217 /* Load the osd menu subsystem */
218 p_sys
->p_menu
= osd_MenuCreate( p_this
, p_sys
->psz_file
);
219 if( p_sys
->p_menu
== NULL
)
222 /* FIXME: this plugin is not at all thread-safe w.r.t. callbacks */
223 p_sys
->p_menu
->i_position
= p_sys
->i_position
;
225 /* Check if menu position was overridden */
226 p_sys
->b_absolute
= true;
227 if( (p_sys
->i_x
< 0) || (p_sys
->i_y
< 0) )
229 p_sys
->b_absolute
= false;
230 p_sys
->p_menu
->i_x
= 0;
231 p_sys
->p_menu
->i_y
= 0;
235 p_sys
->p_menu
->i_x
= p_sys
->i_x
;
236 p_sys
->p_menu
->i_y
= p_sys
->i_y
;
239 /* Set up p_filter */
240 p_sys
->i_last_date
= mdate();
242 /* Keep track of OSD Events */
243 p_sys
->b_update
= false;
244 p_sys
->b_visible
= false;
245 p_sys
->b_clicked
= false;
247 /* Listen to osd menu core updates/visible settings. */
248 var_AddCallback( p_sys
->p_menu
, "osd-menu-update",
249 OSDMenuUpdateEvent
, p_filter
);
250 var_AddCallback( p_sys
->p_menu
, "osd-menu-visible",
251 OSDMenuVisibleEvent
, p_filter
);
253 /* Attach subpicture filter callback */
254 p_filter
->pf_sub_filter
= Filter
;
255 p_filter
->pf_sub_mouse
= MouseEvent
;
257 es_format_Init( &p_filter
->fmt_out
, SPU_ES
, VLC_CODEC_SPU
);
258 p_filter
->fmt_out
.i_priority
= 0;
263 msg_Err( p_filter
, "osdmenu filter discarded" );
265 free( p_sys
->psz_path
);
266 free( p_sys
->psz_file
);
271 /*****************************************************************************
272 * DestroyFilter: Make a clean exit of this plugin
273 *****************************************************************************/
274 static void DestroyFilter( vlc_object_t
*p_this
)
276 filter_t
*p_filter
= (filter_t
*)p_this
;
277 filter_sys_t
*p_sys
= p_filter
->p_sys
;
279 var_DelCallback( p_filter
, OSD_CFG
"position", OSDMenuCallback
, p_sys
);
280 var_DelCallback( p_filter
, OSD_CFG
"timeout", OSDMenuCallback
, p_sys
);
281 var_DelCallback( p_filter
, OSD_CFG
"update", OSDMenuCallback
, p_sys
);
282 var_DelCallback( p_filter
, OSD_CFG
"alpha", OSDMenuCallback
, p_sys
);
284 var_DelCallback( p_sys
->p_menu
, "osd-menu-update",
285 OSDMenuUpdateEvent
, p_filter
);
286 var_DelCallback( p_sys
->p_menu
, "osd-menu-visible",
287 OSDMenuVisibleEvent
, p_filter
);
289 var_Destroy( p_this
, OSD_CFG
"file-path" );
290 var_Destroy( p_this
, OSD_CFG
"file" );
291 var_Destroy( p_this
, OSD_CFG
"x" );
292 var_Destroy( p_this
, OSD_CFG
"y" );
293 var_Destroy( p_this
, OSD_CFG
"position" );
294 var_Destroy( p_this
, OSD_CFG
"timeout" );
295 var_Destroy( p_this
, OSD_CFG
"update" );
296 var_Destroy( p_this
, OSD_CFG
"alpha" );
298 osd_MenuDelete( p_filter
, p_sys
->p_menu
);
299 free( p_sys
->psz_path
);
300 free( p_sys
->psz_file
);
304 /*****************************************************************************
305 * OSDMenuEvent: callback for OSD Menu events
306 *****************************************************************************/
307 static int OSDMenuVisibleEvent( vlc_object_t
*p_this
, char const *psz_var
,
308 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
310 VLC_UNUSED(p_this
); VLC_UNUSED(psz_var
); VLC_UNUSED(oldval
);
312 filter_t
*p_filter
= (filter_t
*) p_data
;
314 p_filter
->p_sys
->b_visible
= true;
315 p_filter
->p_sys
->b_update
= true;
319 static int OSDMenuUpdateEvent( vlc_object_t
*p_this
, char const *psz_var
,
320 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
322 VLC_UNUSED(p_this
); VLC_UNUSED(psz_var
); VLC_UNUSED(oldval
);
324 filter_t
*p_filter
= (filter_t
*) p_data
;
325 filter_sys_t
*p_sys
= p_filter
->p_sys
;
327 p_sys
->b_update
= p_sys
->b_visible
? true : false;
328 p_sys
->i_end_date
= (mtime_t
) 0;
333 /*****************************************************************************
334 * create_text_region : compose a text region SPU
335 *****************************************************************************/
336 static subpicture_region_t
*create_text_region( filter_t
*p_filter
, subpicture_t
*p_spu
,
337 int i_width
, int i_height
, const char *psz_text
)
339 subpicture_region_t
*p_region
;
342 /* Create new SPU region */
343 memset( &fmt
, 0, sizeof(video_format_t
) );
344 fmt
.i_chroma
= VLC_CODEC_TEXT
;
345 fmt
.i_sar_num
= fmt
.i_sar_den
= 1;
346 fmt
.i_width
= fmt
.i_visible_width
= i_width
;
347 fmt
.i_height
= fmt
.i_visible_height
= i_height
;
348 fmt
.i_x_offset
= fmt
.i_y_offset
= 0;
349 p_region
= subpicture_region_New( &fmt
);
352 msg_Err( p_filter
, "cannot allocate another SPU region" );
355 p_region
->psz_text
= strdup( psz_text
);
359 msg_Dbg( p_filter
, "SPU text region position (%d,%d) (%d,%d) [%s]",
360 p_region
->i_x
, p_region
->i_y
,
361 p_region
->fmt
.i_width
, p_region
->fmt
.i_height
, p_region
->psz_text
);
367 /*****************************************************************************
368 * create_picture_region : compose a picture region SPU
369 *****************************************************************************/
370 static subpicture_region_t
*create_picture_region( filter_t
*p_filter
, subpicture_t
*p_spu
,
371 int i_width
, int i_height
, picture_t
*p_pic
)
373 subpicture_region_t
*p_region
= NULL
;
375 video_palette_t palette
;
377 if( !p_spu
) return NULL
;
379 /* Create new SPU region */
380 memset( &fmt
, 0, sizeof(video_format_t
) );
381 fmt
.i_chroma
= (p_pic
== NULL
) ? VLC_CODEC_YUVP
: VLC_CODEC_YUVA
;
382 fmt
.i_sar_num
= fmt
.i_sar_den
= 1;
383 fmt
.i_width
= fmt
.i_visible_width
= i_width
;
384 fmt
.i_height
= fmt
.i_visible_height
= i_height
;
385 fmt
.i_x_offset
= fmt
.i_y_offset
= 0;
386 if( fmt
.i_chroma
== VLC_CODEC_YUVP
)
388 fmt
.p_palette
= &palette
;
389 fmt
.p_palette
->i_entries
= 0;
390 fmt
.i_visible_width
= 0;
391 fmt
.i_visible_height
= 0;
394 p_region
= subpicture_region_New( &fmt
);
397 msg_Err( p_filter
, "cannot allocate SPU region" );
398 p_filter
->pf_sub_buffer_del( p_filter
, p_spu
);
401 /* FIXME the copy is probably not needed anymore */
403 picture_Copy( p_region
->p_picture
, p_pic
);
407 p_region
->i_align
= p_filter
->p_sys
->i_position
;
408 p_region
->i_alpha
= p_filter
->p_sys
->i_alpha
;
410 msg_Dbg( p_filter
, "SPU picture region position (%d,%d) (%d,%d) [%p]",
411 p_region
->i_x
, p_region
->i_y
,
412 p_region
->fmt
.i_width
, p_region
->fmt
.i_height
, p_pic
);
417 /****************************************************************************
418 * Filter: the whole thing
419 ****************************************************************************
420 * This function outputs subpictures at regular time intervals.
421 ****************************************************************************/
422 static subpicture_t
*Filter( filter_t
*p_filter
, mtime_t i_date
)
424 filter_sys_t
*p_sys
= p_filter
->p_sys
;
425 subpicture_t
*p_spu
= NULL
;
426 subpicture_region_t
*p_region
= NULL
;
429 if( !p_sys
->b_update
|| (p_sys
->i_update
<= 0) )
434 if( ( ( p_sys
->i_last_date
+ p_sys
->i_update
) > i_date
) &&
435 ( p_sys
->i_end_date
> 0 ) )
436 return NULL
; /* we are too early, so wait */
438 /* Allocate the subpicture internal data. */
439 p_spu
= filter_NewSubpicture( p_filter
);
443 p_spu
->b_ephemer
= true;
444 p_spu
->b_fade
= true;
445 if( p_filter
->p_sys
->p_menu
->i_style
== OSD_MENU_STYLE_CONCAT
)
446 p_spu
->b_absolute
= true;
448 p_spu
->b_absolute
= p_sys
->b_absolute
;
450 /* Determine the duration of the subpicture */
451 if( p_sys
->i_end_date
> 0 )
453 /* Display the subpicture again. */
454 p_spu
->i_stop
= p_sys
->i_end_date
- i_date
;
455 if( ( i_date
+ p_sys
->i_update
) >= p_sys
->i_end_date
)
456 p_sys
->b_update
= false;
460 /* There is a new OSD picture to display */
461 p_spu
->i_stop
= i_date
+ p_sys
->i_timeout
;
462 p_sys
->i_end_date
= p_spu
->i_stop
;
465 p_sys
->i_last_date
= i_date
;
466 p_spu
->i_start
= p_sys
->i_last_date
= i_date
;
468 /* Send an empty subpicture to clear the display
469 * when OSD menu should be hidden and menu picture is not allocated.
471 if( !p_filter
->p_sys
->p_menu
->p_state
->p_pic
||
472 !p_filter
->p_sys
->b_visible
)
474 p_spu
->i_alpha
= 0xFF; /* Picture is completely non transparent. */
478 if( p_sys
->b_clicked
)
480 p_sys
->b_clicked
= false;
481 osd_MenuActivate( p_filter
);
483 /* Create new spu regions
485 p_region
= create_picture_region( p_filter
, p_spu
,
486 p_filter
->p_sys
->p_menu
->p_state
->i_width
,
487 p_filter
->p_sys
->p_menu
->p_state
->i_height
,
488 p_filter
->p_sys
->p_menu
->p_state
->p_pic
);
492 p_filter
->pf_sub_buffer_del( p_filter
, p_spu
);
496 p_spu
->i_alpha
= p_filter
->p_sys
->i_alpha
;
498 /* proper positioning of OSD menu image */
499 if( p_filter
->p_sys
->p_menu
->i_style
== OSD_MENU_STYLE_CONCAT
)
501 i_x
= p_filter
->p_sys
->p_menu
->p_button
->i_x
;
502 i_y
= p_filter
->p_sys
->p_menu
->p_button
->i_y
;
506 i_x
= p_filter
->p_sys
->p_menu
->p_state
->i_x
;
507 i_y
= p_filter
->p_sys
->p_menu
->p_state
->i_y
;
512 if( p_filter
->p_sys
->p_menu
->i_style
== OSD_MENU_STYLE_CONCAT
)
514 subpicture_region_t
*p_region_list
= NULL
;
515 subpicture_region_t
*p_region_tail
= NULL
;
516 osd_menu_t
*p_osd
= p_filter
->p_sys
->p_menu
;
517 osd_button_t
*p_button
= p_osd
->p_button
;
519 /* Construct the entire OSD from individual images */
520 while( p_button
!= NULL
)
522 osd_button_t
*p_tmp
= NULL
;
523 subpicture_region_t
*p_new
= NULL
;
525 p_new
= create_picture_region( p_filter
, p_spu
,
526 p_button
->p_current_state
->p_pic
->p
[Y_PLANE
].i_visible_pitch
,
527 p_button
->p_current_state
->p_pic
->p
[Y_PLANE
].i_visible_lines
,
528 p_button
->p_current_state
->p_pic
);
531 /* Cleanup when bailing out */
532 subpicture_region_ChainDelete( p_region_list
);
533 subpicture_region_Delete( p_region
);
535 p_filter
->pf_sub_buffer_del( p_filter
, p_spu
);
541 p_region_list
= p_new
;
542 p_region_tail
= p_new
;
546 p_new
->i_x
= i_x
+p_region_tail
->fmt
.i_visible_width
;
547 p_new
->i_y
= i_y
+p_button
->i_y
;
548 p_region_tail
->p_next
= p_new
;
549 p_region_tail
= p_new
;
551 p_tmp
= p_button
->p_next
;
554 p_region
->p_next
= p_region_list
;
557 p_region
->p_next
= create_text_region( p_filter
, p_spu
,
558 p_filter
->p_sys
->p_menu
->p_state
->i_width
, p_filter
->p_sys
->p_menu
->p_state
->i_height
,
559 p_filter
->p_sys
->p_menu
->p_state
->p_visible
->psz_action
);
561 p_spu
->p_region
= p_region
;
565 static int OSDMenuCallback( vlc_object_t
*p_this
, char const *psz_var
,
566 vlc_value_t oldval
, vlc_value_t newval
,
569 VLC_UNUSED(p_this
); VLC_UNUSED(oldval
);
570 filter_sys_t
*p_sys
= (filter_sys_t
*) p_data
;
575 if( !strncmp( psz_var
, OSD_CFG
"position", 16) )
577 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
579 for( i
=0; i
< ARRAY_SIZE(pi_pos_values
); i
++ )
581 if( newval
.i_int
== pi_pos_values
[i
] )
583 p_sys
->i_position
= newval
.i_int
% 11;
589 else if( !strncmp( psz_var
, OSD_CFG
"x", 9) ||
590 !strncmp( psz_var
, OSD_CFG
"y", 9))
592 p_sys
->b_absolute
= true;
593 if( (p_sys
->i_x
< 0) || (p_sys
->i_y
< 0) )
595 p_sys
->b_absolute
= false;
596 p_sys
->p_menu
->i_x
= 0;
597 p_sys
->p_menu
->i_y
= 0;
599 else if( (p_sys
->i_x
>= 0) || (p_sys
->i_y
>= 0) )
601 p_sys
->p_menu
->i_x
= p_sys
->i_x
;
602 p_sys
->p_menu
->i_y
= p_sys
->i_y
;
605 else if( !strncmp( psz_var
, OSD_CFG
"update", 14) )
606 p_sys
->i_update
= newval
.i_int
* INT64_C(1000);
607 else if( !strncmp( psz_var
, OSD_CFG
"timeout", 15) )
608 p_sys
->i_update
= newval
.i_int
% 1000;
609 else if( !strncmp( psz_var
, OSD_CFG
"alpha", 13) )
610 p_sys
->i_alpha
= newval
.i_int
% 256;
612 p_sys
->b_update
= p_sys
->b_visible
? true : false;
616 static int MouseEvent( filter_t
*p_filter
,
617 const vlc_mouse_t
*p_old
,
618 const vlc_mouse_t
*p_new
,
619 const video_format_t
*p_fmt
)
621 filter_sys_t
*p_sys
= p_filter
->p_sys
;
623 if( !vlc_mouse_HasPressed( p_old
, p_new
, MOUSE_BUTTON_LEFT
) )
626 osd_button_t
*p_button
= osd_ButtonFind( VLC_OBJECT(p_filter
),
635 osd_ButtonSelect( VLC_OBJECT(p_filter
), p_button
);
636 p_sys
->b_update
= p_sys
->b_visible
? true : false;
637 p_sys
->b_clicked
= true;
638 msg_Dbg( p_filter
, "mouse clicked %s (%d,%d)", p_button
->psz_name
, p_new
->i_x
, p_new
->i_y
);