1 /*****************************************************************************
2 * osd.c - The OSD Menu core code.
3 *****************************************************************************
4 * Copyright (C) 2005-2008 M2X
7 * Authors: Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 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 implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
35 #include <vlc_image.h>
36 #include <vlc_modules.h>
42 /*****************************************************************************
44 *****************************************************************************/
46 static void osd_UpdateState( osd_menu_state_t
*, int, int, int, int, picture_t
* );
47 static inline osd_state_t
*osd_VolumeStateChange( osd_state_t
*, int );
48 static int osd_VolumeStep( vlc_object_t
*, int, int );
49 static bool osd_ParserLoad( osd_menu_t
*, const char * );
50 static void osd_ParserUnload( osd_menu_t
* );
52 static inline bool osd_isVisible( osd_menu_t
*p_osd
)
54 return var_GetBool( p_osd
, "osd-menu-visible" );
57 static vlc_mutex_t osd_mutex
= VLC_STATIC_MUTEX
;
59 /*****************************************************************************
60 * Wrappers for loading and unloading osd parser modules.
61 *****************************************************************************/
62 static bool osd_ParserLoad( osd_menu_t
*p_menu
, const char *psz_file
)
64 /* Stuff needed for Parser */
65 p_menu
->psz_file
= strdup( psz_file
);
66 p_menu
->p_image
= image_HandlerCreate( p_menu
);
67 if( !p_menu
->p_image
|| !p_menu
->psz_file
)
69 msg_Err( p_menu
, "unable to load images, aborting .." );
75 const char *psz_ext
= strrchr( p_menu
->psz_file
, '.' );
77 if( psz_ext
&& !strcmp( psz_ext
, ".cfg") )
78 psz_type
= "import-osd";
80 psz_type
= "import-osd-xml";
82 p_menu
->p_parser
= module_need( p_menu
, "osd parser",
84 if( !p_menu
->p_parser
)
92 static void osd_ParserUnload( osd_menu_t
*p_menu
)
95 image_HandlerDelete( p_menu
->p_image
);
97 if( p_menu
->p_parser
)
98 module_unneed( p_menu
, p_menu
->p_parser
);
100 free( p_menu
->psz_file
);
104 * Change state on an osd_button_t.
106 * This function selects the specified state and returns a pointer
107 * vlc_custom_create to it. The following states are currently supported:
108 * \see OSD_BUTTON_UNSELECT
109 * \see OSD_BUTTON_SELECT
110 * \see OSD_BUTTON_PRESSED
112 static osd_state_t
*osd_StateChange( osd_button_t
*p_button
, const int i_state
)
114 osd_state_t
*p_current
= p_button
->p_states
;
115 osd_state_t
*p_temp
= NULL
;
118 for( i
= 0; p_current
!= NULL
; i
++ )
120 if( p_current
->i_state
== i_state
)
122 p_button
->i_x
= p_current
->i_x
;
123 p_button
->i_y
= p_current
->i_y
;
124 p_button
->i_width
= p_current
->i_width
;
125 p_button
->i_height
= p_current
->i_height
;
128 p_temp
= p_current
->p_next
;
131 return p_button
->p_states
;
134 #undef osd_MenuCreate
135 /*****************************************************************************
137 *****************************************************************************/
138 osd_menu_t
*osd_MenuCreate( vlc_object_t
*p_this
, const char *psz_file
)
140 osd_menu_t
*p_osd
= NULL
;
145 /* to be sure to avoid multiple creation */
146 vlc_mutex_lock( &osd_mutex
);
148 var_Create( p_this
->p_libvlc
, "osd-object", VLC_VAR_ADDRESS
);
149 var_Get( p_this
->p_libvlc
, "osd-object", &val
);
150 if( val
.p_address
== NULL
)
152 p_osd
= vlc_custom_create( p_this
->p_libvlc
, sizeof( *p_osd
),
157 p_osd
->p_parser
= NULL
;
159 /* Parse configuration file */
160 if ( !osd_ParserLoad( p_osd
, psz_file
) )
162 if( !p_osd
->p_state
)
165 /* Setup default button (first button) */
166 p_osd
->p_state
->p_visible
= p_osd
->p_button
;
167 p_osd
->p_state
->p_visible
->p_current_state
=
168 osd_StateChange( p_osd
->p_state
->p_visible
, OSD_BUTTON_SELECT
);
169 p_osd
->i_width
= p_osd
->p_state
->p_visible
->p_current_state
->p_pic
->p
[Y_PLANE
].i_visible_pitch
;
170 p_osd
->i_height
= p_osd
->p_state
->p_visible
->p_current_state
->p_pic
->p
[Y_PLANE
].i_visible_lines
;
172 if( p_osd
->p_state
->p_volume
)
174 /* Update the volume state images to match the current volume */
175 i_volume
= config_GetInt( p_this
, "volume" );
176 i_steps
= osd_VolumeStep( p_this
, i_volume
, p_osd
->p_state
->p_volume
->i_ranges
);
177 p_osd
->p_state
->p_volume
->p_current_state
= osd_VolumeStateChange(
178 p_osd
->p_state
->p_volume
->p_states
, i_steps
);
180 /* Initialize OSD state */
181 osd_UpdateState( p_osd
->p_state
, p_osd
->i_x
, p_osd
->i_y
,
182 p_osd
->i_width
, p_osd
->i_height
, NULL
);
184 /* Signal when an update of OSD menu is needed */
185 var_Create( p_osd
, "osd-menu-update", VLC_VAR_BOOL
);
186 var_Create( p_osd
, "osd-menu-visible", VLC_VAR_BOOL
);
188 var_SetBool( p_osd
, "osd-menu-update", false );
189 var_SetBool( p_osd
, "osd-menu-visible", false );
191 var_SetAddress( p_this
->p_libvlc
, "osd-object", p_osd
);
194 p_osd
= val
.p_address
;
195 vlc_object_hold( p_osd
);
196 vlc_mutex_unlock( &osd_mutex
);
200 vlc_mutex_unlock( &osd_mutex
);
201 osd_MenuDelete( p_this
, p_osd
);
205 #undef osd_MenuDelete
206 void osd_MenuDelete( vlc_object_t
*p_this
, osd_menu_t
*p_osd
)
208 if( !p_osd
|| !p_this
) return;
210 vlc_mutex_lock( &osd_mutex
);
212 if( vlc_internals( VLC_OBJECT(p_osd
) )->i_refcount
== 1 )
214 var_Destroy( p_osd
, "osd-menu-visible" );
215 var_Destroy( p_osd
, "osd-menu-update" );
216 osd_ParserUnload( p_osd
);
217 var_SetAddress( p_this
->p_libvlc
, "osd-object", NULL
);
220 vlc_object_release( p_osd
);
221 vlc_mutex_unlock( &osd_mutex
);
224 static osd_menu_t
*osd_Find( vlc_object_t
*p_this
, bool visible
,
229 vlc_mutex_lock( &osd_mutex
);
230 menu
= var_GetAddress( p_this
->p_libvlc
, "osd-object" );
231 if( menu
== NULL
|| ( visible
&& !osd_isVisible(menu
) ) )
233 vlc_mutex_unlock( &osd_mutex
);
234 msg_Err( p_this
, "%s failed", func
);
238 #define osd_Find(o) (osd_Find)(o, false, __func__)
239 #define osd_FindVisible(o) (osd_Find)(o, true, __func__)
241 /* The volume can be modified in another interface while the OSD Menu
242 * has not been instantiated yet. This routines updates the "volume OSD menu item"
243 * to reflect the current state of the GUI.
245 static inline osd_state_t
*osd_VolumeStateChange( osd_state_t
*p_current
, int i_steps
)
247 osd_state_t
*p_temp
= NULL
;
250 if( i_steps
< 0 ) i_steps
= 0;
252 for( i
=0; (i
< i_steps
) && (p_current
!= NULL
); i
++ )
254 p_temp
= p_current
->p_next
;
255 if( !p_temp
) return p_current
;
258 return (!p_temp
) ? p_current
: p_temp
;
261 /* Update the state of the OSD Menu */
262 static void osd_UpdateState( osd_menu_state_t
*p_state
, int i_x
, int i_y
,
263 int i_width
, int i_height
, picture_t
*p_pic
)
267 p_state
->i_width
= i_width
;
268 p_state
->i_height
= i_height
;
269 p_state
->p_pic
= p_pic
;
273 void osd_MenuShow( vlc_object_t
*p_this
)
275 osd_button_t
*p_button
= NULL
;
277 osd_menu_t
*p_osd
= osd_Find( p_this
);
281 #if defined(OSD_MENU_DEBUG)
282 msg_Dbg( p_osd
, "menu on" );
284 p_button
= p_osd
->p_state
->p_visible
;
287 if( !p_button
->b_range
)
288 p_button
->p_current_state
= osd_StateChange( p_button
, OSD_BUTTON_UNSELECT
);
289 p_osd
->p_state
->p_visible
= p_osd
->p_button
;
291 if( !p_osd
->p_state
->p_visible
->b_range
)
292 p_osd
->p_state
->p_visible
->p_current_state
=
293 osd_StateChange( p_osd
->p_state
->p_visible
, OSD_BUTTON_SELECT
);
295 osd_UpdateState( p_osd
->p_state
,
296 p_osd
->p_state
->p_visible
->i_x
, p_osd
->p_state
->p_visible
->i_y
,
297 p_osd
->p_state
->p_visible
->p_current_state
->i_width
,
298 p_osd
->p_state
->p_visible
->p_current_state
->i_height
,
299 p_osd
->p_state
->p_visible
->p_current_state
->p_pic
);
300 osd_SetMenuUpdate( p_osd
, true );
302 osd_SetMenuVisible( p_osd
, true );
304 vlc_mutex_unlock( &osd_mutex
);
308 void osd_MenuHide( vlc_object_t
*p_this
)
310 osd_menu_t
*p_osd
= osd_Find( p_this
);
314 #if defined(OSD_MENU_DEBUG)
315 msg_Dbg( p_osd
, "menu off" );
317 osd_UpdateState( p_osd
->p_state
,
318 p_osd
->p_state
->i_x
, p_osd
->p_state
->i_y
,
320 osd_SetMenuUpdate( p_osd
, true );
322 vlc_mutex_unlock( &osd_mutex
);
325 #undef osd_MenuActivate
326 void osd_MenuActivate( vlc_object_t
*p_this
)
328 osd_button_t
*p_button
= NULL
;
330 osd_menu_t
*p_osd
= osd_FindVisible( p_this
);
334 #if defined(OSD_MENU_DEBUG)
335 msg_Dbg( p_osd
, "select" );
337 p_button
= p_osd
->p_state
->p_visible
;
339 * Is there a menu item above or below? If so, then select it.
341 if( p_button
&& p_button
->p_up
)
343 vlc_mutex_unlock( &osd_mutex
);
344 osd_MenuUp( p_this
); /* "menu select" means go to menu item above. */
347 if( p_button
&& p_button
->p_down
)
349 vlc_mutex_unlock( &osd_mutex
);
350 osd_MenuDown( p_this
); /* "menu select" means go to menu item below. */
354 if( p_button
&& !p_button
->b_range
)
356 p_button
->p_current_state
= osd_StateChange( p_button
, OSD_BUTTON_PRESSED
);
357 osd_UpdateState( p_osd
->p_state
,
358 p_button
->i_x
, p_button
->i_y
,
359 p_osd
->p_state
->p_visible
->p_current_state
->i_width
,
360 p_osd
->p_state
->p_visible
->p_current_state
->i_height
,
361 p_button
->p_current_state
->p_pic
);
362 osd_SetMenuUpdate( p_osd
, true );
363 osd_SetMenuVisible( p_osd
, true );
364 osd_SetKeyPressed( VLC_OBJECT(p_osd
->p_libvlc
),
365 var_InheritInteger( p_osd
, p_button
->psz_action
) );
366 #if defined(OSD_MENU_DEBUG)
367 msg_Dbg( p_osd
, "select (%d, %s)",
368 (int)var_InheritInteger( p_osd
, p_button
->psz_action
),
369 p_button
->psz_action
);
372 vlc_mutex_unlock( &osd_mutex
);
376 void osd_MenuNext( vlc_object_t
*p_this
)
378 osd_button_t
*p_button
= NULL
;
380 osd_menu_t
*p_osd
= osd_FindVisible( p_this
);
384 p_button
= p_osd
->p_state
->p_visible
;
387 if( !p_button
->b_range
)
388 p_button
->p_current_state
= osd_StateChange( p_button
, OSD_BUTTON_UNSELECT
);
389 if( p_button
->p_next
)
390 p_osd
->p_state
->p_visible
= p_button
->p_next
;
392 p_osd
->p_state
->p_visible
= p_osd
->p_button
;
394 if( !p_osd
->p_state
->p_visible
->b_range
)
395 p_osd
->p_state
->p_visible
->p_current_state
=
396 osd_StateChange( p_osd
->p_state
->p_visible
, OSD_BUTTON_SELECT
);
398 osd_UpdateState( p_osd
->p_state
,
399 p_osd
->p_state
->p_visible
->i_x
, p_osd
->p_state
->p_visible
->i_y
,
400 p_osd
->p_state
->p_visible
->p_current_state
->i_width
,
401 p_osd
->p_state
->p_visible
->p_current_state
->i_height
,
402 p_osd
->p_state
->p_visible
->p_current_state
->p_pic
);
403 osd_SetMenuUpdate( p_osd
, true );
405 #if defined(OSD_MENU_DEBUG)
406 msg_Dbg( p_osd
, "direction right [button %s]", p_osd
->p_state
->p_visible
->psz_action
);
409 vlc_mutex_unlock( &osd_mutex
);
413 void osd_MenuPrev( vlc_object_t
*p_this
)
415 osd_button_t
*p_button
= NULL
;
417 osd_menu_t
*p_osd
= osd_FindVisible( p_this
);
421 p_button
= p_osd
->p_state
->p_visible
;
424 if( !p_button
->b_range
)
425 p_button
->p_current_state
= osd_StateChange( p_button
, OSD_BUTTON_UNSELECT
);
426 if( p_button
->p_prev
)
427 p_osd
->p_state
->p_visible
= p_button
->p_prev
;
429 p_osd
->p_state
->p_visible
= p_osd
->p_last_button
;
431 if( !p_osd
->p_state
->p_visible
->b_range
)
432 p_osd
->p_state
->p_visible
->p_current_state
=
433 osd_StateChange( p_osd
->p_state
->p_visible
, OSD_BUTTON_SELECT
);
435 osd_UpdateState( p_osd
->p_state
,
436 p_osd
->p_state
->p_visible
->i_x
, p_osd
->p_state
->p_visible
->i_y
,
437 p_osd
->p_state
->p_visible
->p_current_state
->i_width
,
438 p_osd
->p_state
->p_visible
->p_current_state
->i_height
,
439 p_osd
->p_state
->p_visible
->p_current_state
->p_pic
);
440 osd_SetMenuUpdate( p_osd
, true );
442 #if defined(OSD_MENU_DEBUG)
443 msg_Dbg( p_osd
, "direction left [button %s]", p_osd
->p_state
->p_visible
->psz_action
);
446 vlc_mutex_unlock( &osd_mutex
);
450 void osd_MenuUp( vlc_object_t
*p_this
)
452 osd_button_t
*p_button
= NULL
;
453 #if defined(OSD_MENU_DEBUG)
457 osd_menu_t
*p_osd
= osd_FindVisible( p_this
);
461 p_button
= p_osd
->p_state
->p_visible
;
464 if( !p_button
->b_range
)
466 p_button
->p_current_state
= osd_StateChange( p_button
, OSD_BUTTON_SELECT
);
468 p_osd
->p_state
->p_visible
= p_button
->p_up
;
471 if( p_button
->b_range
&& p_osd
->p_state
->p_visible
->b_range
)
473 osd_state_t
*p_temp
= p_osd
->p_state
->p_visible
->p_current_state
;
474 if( p_temp
&& p_temp
->p_next
)
475 p_osd
->p_state
->p_visible
->p_current_state
= p_temp
->p_next
;
477 else if( !p_osd
->p_state
->p_visible
->b_range
)
479 p_osd
->p_state
->p_visible
->p_current_state
=
480 osd_StateChange( p_osd
->p_state
->p_visible
, OSD_BUTTON_SELECT
);
483 osd_UpdateState( p_osd
->p_state
,
484 p_osd
->p_state
->p_visible
->i_x
, p_osd
->p_state
->p_visible
->i_y
,
485 p_osd
->p_state
->p_visible
->p_current_state
->i_width
,
486 p_osd
->p_state
->p_visible
->p_current_state
->i_height
,
487 p_osd
->p_state
->p_visible
->p_current_state
->p_pic
);
488 osd_SetMenuUpdate( p_osd
, true );
489 /* If this is a range style action with associated images of only one state,
490 * then perform "menu select" on every menu navigation
492 if( p_button
->b_range
)
494 osd_SetKeyPressed( VLC_OBJECT(p_osd
->p_libvlc
),
495 var_InheritInteger(p_osd
, p_button
->psz_action
) );
496 #if defined(OSD_MENU_DEBUG)
497 msg_Dbg( p_osd
, "select (%"PRId64
", %s)", val
.i_int
, p_button
->psz_action
);
501 #if defined(OSD_MENU_DEBUG)
502 msg_Dbg( p_osd
, "direction up [button %s]", p_osd
->p_state
->p_visible
->psz_action
);
505 vlc_mutex_unlock( &osd_mutex
);
509 void osd_MenuDown( vlc_object_t
*p_this
)
511 osd_button_t
*p_button
= NULL
;
512 #if defined(OSD_MENU_DEBUG)
516 osd_menu_t
*p_osd
= osd_FindVisible( p_this
);
520 p_button
= p_osd
->p_state
->p_visible
;
523 if( !p_button
->b_range
)
525 p_button
->p_current_state
= osd_StateChange( p_button
, OSD_BUTTON_SELECT
);
526 if( p_button
->p_down
)
527 p_osd
->p_state
->p_visible
= p_button
->p_down
;
530 if( p_button
->b_range
&& p_osd
->p_state
->p_visible
->b_range
)
532 osd_state_t
*p_temp
= p_osd
->p_state
->p_visible
->p_current_state
;
533 if( p_temp
&& p_temp
->p_prev
)
534 p_osd
->p_state
->p_visible
->p_current_state
= p_temp
->p_prev
;
536 else if( !p_osd
->p_state
->p_visible
->b_range
)
538 p_osd
->p_state
->p_visible
->p_current_state
=
539 osd_StateChange( p_osd
->p_state
->p_visible
, OSD_BUTTON_SELECT
);
542 osd_UpdateState( p_osd
->p_state
,
543 p_osd
->p_state
->p_visible
->i_x
, p_osd
->p_state
->p_visible
->i_y
,
544 p_osd
->p_state
->p_visible
->p_current_state
->i_width
,
545 p_osd
->p_state
->p_visible
->p_current_state
->i_height
,
546 p_osd
->p_state
->p_visible
->p_current_state
->p_pic
);
547 osd_SetMenuUpdate( p_osd
, true );
548 /* If this is a range style action with associated images of only one state,
549 * then perform "menu select" on every menu navigation
551 if( p_button
->b_range
)
553 osd_SetKeyPressed( VLC_OBJECT(p_osd
->p_libvlc
),
554 var_InheritInteger(p_osd
, p_button
->psz_action_down
) );
555 #if defined(OSD_MENU_DEBUG)
556 msg_Dbg( p_osd
, "select (%"PRId64
", %s)", val
.i_int
, p_button
->psz_action_down
);
560 #if defined(OSD_MENU_DEBUG)
561 msg_Dbg( p_osd
, "direction down [button %s]", p_osd
->p_state
->p_visible
->psz_action
);
564 vlc_mutex_unlock( &osd_mutex
);
567 static int osd_VolumeStep( vlc_object_t
*p_this
, int i_volume
, int i_steps
)
569 int i_volume_step
= 0;
572 i_volume_step
= config_GetInt( p_this
->p_libvlc
, "volume-step" );
573 return (i_volume
/i_volume_step
);
578 * Display current audio volume bitmap
580 * The OSD Menu audio volume bar is updated to reflect the new audio volume. Call this function
581 * when the audio volume is updated outside the OSD menu command "menu up", "menu down" or "menu select".
583 void osd_Volume( vlc_object_t
*p_this
)
585 osd_button_t
*p_button
= NULL
;
589 osd_menu_t
*p_osd
= osd_FindVisible( p_this
);
593 if( p_osd
->p_state
&& p_osd
->p_state
->p_volume
)
596 p_button
= p_osd
->p_state
->p_volume
;
597 if( p_osd
->p_state
->p_volume
)
598 p_osd
->p_state
->p_visible
= p_osd
->p_state
->p_volume
;
599 if( p_button
&& p_button
->b_range
)
601 /* Update the volume state images to match the current volume */
602 i_volume
= config_GetInt( p_this
, "volume" );
603 i_steps
= osd_VolumeStep( p_this
, i_volume
, p_button
->i_ranges
);
604 p_button
->p_current_state
= osd_VolumeStateChange( p_button
->p_states
, i_steps
);
606 osd_UpdateState( p_osd
->p_state
,
607 p_button
->i_x
, p_button
->i_y
,
608 p_button
->p_current_state
->i_width
,
609 p_button
->p_current_state
->i_height
,
610 p_button
->p_current_state
->p_pic
);
611 osd_SetMenuUpdate( p_osd
, true );
612 osd_SetMenuVisible( p_osd
, true );
615 vlc_mutex_unlock( &osd_mutex
);
618 #undef osd_ButtonFind
619 osd_button_t
*osd_ButtonFind( vlc_object_t
*p_this
, int i_x
, int i_y
,
620 int i_window_height
, int i_window_width
,
621 int i_scale_width
, int i_scale_height
)
623 osd_button_t
*p_button
;
625 osd_menu_t
*p_osd
= osd_FindVisible( p_this
);
629 p_button
= p_osd
->p_button
;
630 for( ; p_button
!= NULL
; p_button
= p_button
->p_next
)
632 int i_source_video_width
= ( i_window_width
* 1000 ) / i_scale_width
;
633 int i_source_video_height
= ( i_window_height
* 1000 ) / i_scale_height
;
634 int i_y_offset
= p_button
->i_y
;
635 int i_x_offset
= p_button
->i_x
;
636 int i_width
= p_button
->i_width
;
637 int i_height
= p_button
->i_height
;
639 if( p_osd
->i_position
> 0 )
641 int i_inv_scale_y
= i_source_video_height
;
642 int i_inv_scale_x
= i_source_video_width
;
645 if( p_osd
->i_position
& SUBPICTURE_ALIGN_BOTTOM
)
647 i_y_offset
= i_window_height
- p_button
->i_height
-
648 (p_osd
->i_y
+ p_button
->i_y
) * i_inv_scale_y
/ 1000;
650 else if ( !(p_osd
->i_position
& SUBPICTURE_ALIGN_TOP
) )
652 i_y_offset
= i_window_height
/ 2 - p_button
->i_height
/ 2;
655 if( p_osd
->i_position
& SUBPICTURE_ALIGN_RIGHT
)
657 i_x_offset
= i_window_width
- p_button
->i_width
-
658 (pi_x
+ p_button
->i_x
)
659 * i_inv_scale_x
/ 1000;
661 else if ( !(p_osd
->i_position
& SUBPICTURE_ALIGN_LEFT
) )
663 i_x_offset
= i_window_width
/ 2 - p_button
->i_width
/ 2;
666 i_width
= i_window_width
- p_button
->i_width
- i_inv_scale_x
/ 1000;
667 i_height
= i_window_height
- p_button
->i_height
- i_inv_scale_y
/ 1000;
670 // TODO: write for Up / Down case too.
671 // TODO: handle absolute positioning case
672 if( ( i_x
>= i_x_offset
) && ( i_x
<= i_x_offset
+ i_width
) &&
673 ( i_y
>= i_y_offset
) && ( i_y
<= i_y_offset
+ i_height
) )
675 vlc_mutex_unlock( &osd_mutex
);
680 vlc_mutex_unlock( &osd_mutex
);
684 #undef osd_ButtonSelect
686 * Select the button provided as the new active button
688 void osd_ButtonSelect( vlc_object_t
*p_this
, osd_button_t
*p_button
)
692 osd_menu_t
*p_osd
= osd_FindVisible( p_this
);
696 p_old
= p_osd
->p_state
->p_visible
;
699 if( !p_old
->b_range
)
700 p_old
->p_current_state
= osd_StateChange( p_old
, OSD_BUTTON_UNSELECT
);
701 p_osd
->p_state
->p_visible
= p_button
;
703 if( !p_osd
->p_state
->p_visible
->b_range
)
704 p_osd
->p_state
->p_visible
->p_current_state
=
705 osd_StateChange( p_osd
->p_state
->p_visible
, OSD_BUTTON_SELECT
);
707 osd_UpdateState( p_osd
->p_state
,
708 p_osd
->p_state
->p_visible
->i_x
, p_osd
->p_state
->p_visible
->i_y
,
709 p_osd
->p_state
->p_visible
->p_current_state
->i_width
,
710 p_osd
->p_state
->p_visible
->p_current_state
->i_height
,
711 p_osd
->p_state
->p_visible
->p_current_state
->p_pic
);
712 osd_SetMenuUpdate( p_osd
, true );
714 #if defined(OSD_MENU_DEBUG)
715 msg_Dbg( p_osd
, "button selected is [button %s]", p_osd
->p_state
->p_visible
->psz_action
);
718 vlc_mutex_unlock( &osd_mutex
);