Commit 82e29c9b authored by Jean-Paul Saman's avatar Jean-Paul Saman

Implement clickable osdmenu. The clickable positioning and scaling guessing is...

Implement clickable osdmenu. The clickable positioning and scaling guessing is not complete (the whole spu region is now clickable with current configurations).
parent 9d6bf51a
......@@ -285,8 +285,6 @@ static const text_style_t default_text_style = { NULL, 22, 0xffffff, 0xff, STYLE
#define OSD_BUTTON_SELECT 1
#define OSD_BUTTON_PRESSED 2
static const char *ppsz_button_states[] = { "unselect", "select", "pressed" };
/**
* OSD State object
*
......@@ -302,6 +300,11 @@ struct osd_state_t
char *psz_state; /*< state name */
int i_state; /*< state index */
int i_x; /*< x-position of button state image */
int i_y; /*< y-position of button state image */
int i_width; /*< width of button state image */
int i_height; /*< height of button state image */
};
/**
......@@ -330,6 +333,8 @@ struct osd_button_t
int i_x; /*< x-position of button visible state image */
int i_y; /*< y-position of button visible state image */
int i_width; /*< width of button visible state image */
int i_height; /*< height of button visible state image */
/* range style button */
vlc_bool_t b_range; /*< button should be interpreted as range */
......@@ -389,6 +394,7 @@ struct osd_menu_t
int i_width; /*< width of OSD Menu on the video screen */
int i_height; /*< height of OSD Menu on the video screen */
int i_style; /*< style of spu region generation */
int i_position; /*< display position */
char *psz_path; /*< directory where OSD menu images are stored */
osd_button_t *p_button; /*< doubly linked list of buttons */
......@@ -421,20 +427,23 @@ VLC_EXPORT( osd_menu_t *, __osd_MenuCreate, ( vlc_object_t *, const char * ) );
*/
VLC_EXPORT( void, __osd_MenuDelete, ( vlc_object_t *, osd_menu_t * ) );
#define osd_MenuCreate(object,file) __osd_MenuCreate( VLC_OBJECT(object), file )
#define osd_MenuDelete(object,osd) __osd_MenuDelete( VLC_OBJECT(object), osd )
/**
* Change state on an osd_button_t.
*
* This function selects the specified state and returns a pointer to it. The
* following states are currently supported:
* \see OSD_BUTTON_UNSELECT
* \see OSD_BUTTON_SELECT
* \see OSD_BUTTON_PRESSED
* Find OSD Menu button at position x,y
*/
VLC_EXPORT( osd_state_t *, __osd_StateChange, ( osd_state_t *, const int ) );
VLC_EXPORT( osd_button_t *, __osd_ButtonFind, ( vlc_object_t *p_this,
int, int, int, int, int, int ) );
#define osd_MenuCreate(object,file) __osd_MenuCreate( VLC_OBJECT(object), file )
#define osd_MenuDelete(object,osd) __osd_MenuDelete( VLC_OBJECT(object), osd )
#define osd_StateChange(object,value) __osd_StateChange( object, value )
#define osd_ButtonFind(object,x,y,h,w,sh,sw) __osd_ButtonFind(object,x,y,h,w,sh,sw)
/**
* Select the button provided as the new active button
*/
VLC_EXPORT( void, __osd_ButtonSelect, ( vlc_object_t *, osd_button_t *) );
#define osd_ButtonSelect(object,button) __osd_ButtonSelect(object,button)
/**
* Show the OSD menu.
......
......@@ -218,6 +218,9 @@ osd_state_t *osd_StateNew( osd_menu_t *p_menu, const char *psz_file,
{
p_state->p_pic = image_ReadUrl( p_menu->p_image, psz_file,
&fmt_in, &fmt_out );
p_state->i_width = p_state->p_pic->p[Y_PLANE].i_visible_pitch;
p_state->i_height = p_state->p_pic->p[Y_PLANE].i_visible_lines;
}
if( psz_state )
......
......@@ -24,6 +24,8 @@
#ifndef _OSD_MENU_PARSER_H_
#define _OSD_MENU_PARSER_H_
static const char *ppsz_button_states[] = { "unselect", "select", "pressed" };
/* OSD Menu structure support routines for internal use by
* OSD Menu configuration file parsers only.
*/
......
......@@ -269,6 +269,9 @@ int osd_parser_simpleOpen( vlc_object_t *p_this )
if( !p_range_current || !p_range_current->p_pic )
goto error;
p_range_current->i_x = i_x;
p_range_current->i_y = i_y;
/* increment the number of ranges for this button */
p_up->i_ranges++;
......@@ -366,6 +369,9 @@ int osd_parser_simpleOpen( vlc_object_t *p_this )
if( !p_range_current || !p_range_current->p_pic )
goto error;
p_range_current->i_x = i_x;
p_range_current->i_y = i_y;
/* increment the number of ranges for this button */
p_current->i_ranges++;
......@@ -433,6 +439,9 @@ int osd_parser_simpleOpen( vlc_object_t *p_this )
if( !p_state_current || !p_state_current->p_pic )
goto error;
p_state_current->i_x = i_x;
p_state_current->i_y = i_y;
if( p_state_prev )
p_state_prev->p_next = p_state_current;
else
......
......@@ -84,6 +84,7 @@ static const char *ppsz_pos_descriptions[] =
static int CreateFilter ( vlc_object_t * );
static void DestroyFilter( vlc_object_t * );
static subpicture_t *Filter( filter_t *, mtime_t );
static int OSDMenuUpdateEvent( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static int OSDMenuVisibleEvent( vlc_object_t *, char const *,
......@@ -91,6 +92,9 @@ static int OSDMenuVisibleEvent( vlc_object_t *, char const *,
static int OSDMenuCallback( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static int MouseEvent( vlc_object_t *, char const *,
vlc_value_t , vlc_value_t , void * );
#define OSD_CFG "osdmenu-"
#if defined( WIN32 ) || defined( UNDER_CE )
......@@ -157,6 +161,12 @@ struct filter_sys_t
char *psz_file; /* OSD Menu configuration file */
char *psz_path; /* Path to OSD Menu pictures */
osd_menu_t *p_menu; /* pointer to OSD Menu object */
/* menu interaction */
vout_thread_t *p_vout;
vlc_bool_t b_clicked;
uint32_t i_mouse_x;
uint32_t i_mouse_y;
};
/*****************************************************************************
......@@ -206,6 +216,8 @@ static int CreateFilter ( vlc_object_t *p_this )
if( p_sys->p_menu == NULL )
goto error;
p_sys->p_menu->i_position = p_sys->i_position;
/* Check if menu position was overridden */
p_sys->b_absolute = VLC_TRUE;
if( (p_sys->i_x < 0) || (p_sys->i_y < 0) )
......@@ -233,6 +245,7 @@ static int CreateFilter ( vlc_object_t *p_this )
/* Keep track of OSD Events */
p_sys->b_update = VLC_FALSE;
p_sys->b_visible = VLC_FALSE;
p_sys->b_clicked = VLC_FALSE;
/* Listen to osd menu core updates/visible settings. */
var_AddCallback( p_sys->p_menu, "osd-menu-update",
......@@ -243,6 +256,17 @@ static int CreateFilter ( vlc_object_t *p_this )
/* Attach subpicture filter callback */
p_filter->pf_sub_filter = Filter;
p_sys->p_vout = vlc_object_find( p_this, VLC_OBJECT_VOUT, FIND_ANYWHERE );
if( p_sys->p_vout )
{
var_AddCallback( p_sys->p_vout, "mouse-x",
MouseEvent, p_sys );
var_AddCallback( p_sys->p_vout, "mouse-y",
MouseEvent, p_sys );
var_AddCallback( p_sys->p_vout, "mouse-clicked",
MouseEvent, p_sys );
}
es_format_Init( &p_filter->fmt_out, SPU_ES, VLC_FOURCC( 's','p','u',' ' ) );
p_filter->fmt_out.i_priority = 0;
......@@ -276,6 +300,19 @@ static void DestroyFilter( vlc_object_t *p_this )
var_DelCallback( p_sys->p_menu, "osd-menu-visible",
OSDMenuVisibleEvent, p_filter );
if( p_sys->p_vout )
{
var_DelCallback( p_sys->p_vout, "mouse-x",
MouseEvent, p_sys );
var_DelCallback( p_sys->p_vout, "mouse-y",
MouseEvent, p_sys );
var_DelCallback( p_sys->p_vout, "mouse-clicked",
MouseEvent, p_sys );
vlc_object_release( p_sys->p_vout );
p_sys->p_vout = NULL;
}
var_Destroy( p_this, OSD_CFG "file-path" );
var_Destroy( p_this, OSD_CFG "file" );
var_Destroy( p_this, OSD_CFG "x" );
......@@ -468,6 +505,11 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t i_date )
return p_spu;
}
if( p_sys->p_vout && p_sys->b_clicked )
{
p_sys->b_clicked = VLC_FALSE;
osd_MenuActivate( p_filter );
}
/* Create new spu regions
*/
p_region = create_picture_region( p_filter, p_spu,
......@@ -606,3 +648,59 @@ static int OSDMenuCallback( vlc_object_t *p_this, char const *psz_var,
p_sys->b_update = p_sys->b_visible ? VLC_TRUE : VLC_FALSE;
return VLC_SUCCESS;
}
/*****************************************************************************
* MouseEvent: callback for mouse events
*****************************************************************************/
static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
filter_sys_t *p_sys = (filter_sys_t *)p_data;
vout_thread_t *p_vout = (vout_thread_t*)p_sys->p_vout;
int i_x, i_y;
int i_v;
#define MOUSE_DOWN 1
#define MOUSE_CLICKED 2
#define MOUSE_MOVE_X 4
#define MOUSE_MOVE_Y 8
#define MOUSE_MOVE 12
uint8_t mouse= 0;
int v_h = p_vout->output.i_height;
int v_w = p_vout->output.i_width;
if( psz_var[6] == 'x' ) mouse |= MOUSE_MOVE_X;
if( psz_var[6] == 'y' ) mouse |= MOUSE_MOVE_Y;
if( psz_var[6] == 'c' ) mouse |= MOUSE_CLICKED;
i_v = var_GetInteger( p_sys->p_vout, "mouse-button-down" );
if( i_v & 0x1 ) mouse |= MOUSE_DOWN;
i_y = var_GetInteger( p_sys->p_vout, "mouse-y" );
i_x = var_GetInteger( p_sys->p_vout, "mouse-x" );
if( i_y < 0 || i_x < 0 || i_y >= v_h || i_x >= v_w )
return VLC_SUCCESS;
if( mouse & MOUSE_CLICKED )
{
int i_scale_width, i_scale_height;
osd_button_t *p_button = NULL;
i_scale_width = p_vout->fmt_out.i_visible_width * 1000 /
p_vout->fmt_in.i_visible_width;
i_scale_height = p_vout->fmt_out.i_visible_height * 1000 /
p_vout->fmt_in.i_visible_height;
p_button = osd_ButtonFind( p_this, i_x, i_y, v_h, v_w,
i_scale_width, i_scale_height );
if( p_button )
{
osd_ButtonSelect( p_this, p_button );
p_sys->b_update = p_sys->b_visible ? VLC_TRUE : VLC_FALSE;
p_sys->b_clicked = VLC_TRUE;
msg_Dbg( p_this, "mouse clicked %s (%d,%d)\n", p_button->psz_name, i_x, i_y );
}
}
return VLC_SUCCESS;
}
......@@ -34,6 +34,8 @@
#undef OSD_MENU_DEBUG
static const char *ppsz_button_states[] = { "unselect", "select", "pressed" };
/*****************************************************************************
* Local prototypes
*****************************************************************************/
......@@ -113,6 +115,37 @@ static void osd_ParserUnload( vlc_object_t *p_this, osd_menu_t *p_menu )
vlc_object_destroy( p_menu );
}
/**
* Change state on an osd_button_t.
*
* This function selects the specified state and returns a pointer to it. The
* following states are currently supported:
* \see OSD_BUTTON_UNSELECT
* \see OSD_BUTTON_SELECT
* \see OSD_BUTTON_PRESSED
*/
static osd_state_t *osd_StateChange( osd_button_t *p_button, const int i_state )
{
osd_state_t *p_current = p_button->p_states;
osd_state_t *p_temp = NULL;
int i = 0;
for( i=0; p_current != NULL; i++ )
{
if( p_current->i_state == i_state )
{
p_button->i_x = p_current->i_x;
p_button->i_y = p_current->i_y;
p_button->i_width = p_current->i_width;
p_button->i_height = p_current->i_height;
return p_current;
}
p_temp = p_current->p_next;
p_current = p_temp;
}
return p_button->p_states;
}
/*****************************************************************************
* OSD menu Funtions
*****************************************************************************/
......@@ -141,7 +174,7 @@ osd_menu_t *__osd_MenuCreate( vlc_object_t *p_this, const char *psz_file )
/* Setup default button (first button) */
p_osd->p_state->p_visible = p_osd->p_button;
p_osd->p_state->p_visible->p_current_state =
osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT );
p_osd->i_width = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch;
p_osd->i_height = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines;
......@@ -206,22 +239,6 @@ void __osd_MenuDelete( vlc_object_t *p_this, osd_menu_t *p_osd )
vlc_mutex_unlock( lockval.p_address );
}
osd_state_t *__osd_StateChange( osd_state_t *p_states, const int i_state )
{
osd_state_t *p_current = p_states;
osd_state_t *p_temp = NULL;
int i = 0;
for( i=0; p_current != NULL; i++ )
{
if( p_current->i_state == i_state )
return p_current;
p_temp = p_current->p_next;
p_current = p_temp;
}
return p_states;
}
/* The volume can be modified in another interface while the OSD Menu
* has not been instantiated yet. This routines updates the "volume OSD menu item"
* to reflect the current state of the GUI.
......@@ -276,17 +293,17 @@ void __osd_MenuShow( vlc_object_t *p_this )
if( p_button )
{
if( !p_button->b_range )
p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT );
p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_UNSELECT );
p_osd->p_state->p_visible = p_osd->p_button;
if( !p_osd->p_state->p_visible->b_range )
p_osd->p_state->p_visible->p_current_state =
osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT );
osd_UpdateState( p_osd->p_state,
p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
p_osd->p_state->p_visible->p_current_state->i_width,
p_osd->p_state->p_visible->p_current_state->i_height,
p_osd->p_state->p_visible->p_current_state->p_pic );
osd_SetMenuUpdate( p_osd, VLC_TRUE );
}
......@@ -369,11 +386,11 @@ void __osd_MenuActivate( vlc_object_t *p_this )
if( p_button && !p_button->b_range )
{
p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_PRESSED );
p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_PRESSED );
osd_UpdateState( p_osd->p_state,
p_button->i_x, p_button->i_y,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
p_osd->p_state->p_visible->p_current_state->i_width,
p_osd->p_state->p_visible->p_current_state->i_height,
p_button->p_current_state->p_pic );
osd_SetMenuUpdate( p_osd, VLC_TRUE );
osd_SetMenuVisible( p_osd, VLC_TRUE );
......@@ -412,7 +429,7 @@ void __osd_MenuNext( vlc_object_t *p_this )
if( p_button )
{
if( !p_button->b_range )
p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT );
p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_UNSELECT );
if( p_button->p_next )
p_osd->p_state->p_visible = p_button->p_next;
else
......@@ -420,12 +437,12 @@ void __osd_MenuNext( vlc_object_t *p_this )
if( !p_osd->p_state->p_visible->b_range )
p_osd->p_state->p_visible->p_current_state =
osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT );
osd_UpdateState( p_osd->p_state,
p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
p_osd->p_state->p_visible->p_current_state->i_width,
p_osd->p_state->p_visible->p_current_state->i_height,
p_osd->p_state->p_visible->p_current_state->p_pic );
osd_SetMenuUpdate( p_osd, VLC_TRUE );
}
......@@ -463,7 +480,7 @@ void __osd_MenuPrev( vlc_object_t *p_this )
if( p_button )
{
if( !p_button->b_range )
p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT );
p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_UNSELECT );
if( p_button->p_prev )
p_osd->p_state->p_visible = p_button->p_prev;
else
......@@ -471,12 +488,12 @@ void __osd_MenuPrev( vlc_object_t *p_this )
if( !p_osd->p_state->p_visible->b_range )
p_osd->p_state->p_visible->p_current_state =
osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT );
osd_UpdateState( p_osd->p_state,
p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
p_osd->p_state->p_visible->p_current_state->i_width,
p_osd->p_state->p_visible->p_current_state->i_height,
p_osd->p_state->p_visible->p_current_state->p_pic );
osd_SetMenuUpdate( p_osd, VLC_TRUE );
}
......@@ -517,7 +534,7 @@ void __osd_MenuUp( vlc_object_t *p_this )
{
if( !p_button->b_range )
{
p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT );
p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_SELECT );
if( p_button->p_up )
p_osd->p_state->p_visible = p_button->p_up;
}
......@@ -531,13 +548,13 @@ void __osd_MenuUp( vlc_object_t *p_this )
else if( !p_osd->p_state->p_visible->b_range )
{
p_osd->p_state->p_visible->p_current_state =
osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT );
}
osd_UpdateState( p_osd->p_state,
p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
p_osd->p_state->p_visible->p_current_state->i_width,
p_osd->p_state->p_visible->p_current_state->i_height,
p_osd->p_state->p_visible->p_current_state->p_pic );
osd_SetMenuUpdate( p_osd, VLC_TRUE );
/* If this is a range style action with associated images of only one state,
......@@ -589,7 +606,7 @@ void __osd_MenuDown( vlc_object_t *p_this )
{
if( !p_button->b_range )
{
p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT );
p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_SELECT );
if( p_button->p_down )
p_osd->p_state->p_visible = p_button->p_down;
}
......@@ -603,13 +620,13 @@ void __osd_MenuDown( vlc_object_t *p_this )
else if( !p_osd->p_state->p_visible->b_range )
{
p_osd->p_state->p_visible->p_current_state =
osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT );
}
osd_UpdateState( p_osd->p_state,
p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
p_osd->p_state->p_visible->p_current_state->i_width,
p_osd->p_state->p_visible->p_current_state->i_height,
p_osd->p_state->p_visible->p_current_state->p_pic );
osd_SetMenuUpdate( p_osd, VLC_TRUE );
/* If this is a range style action with associated images of only one state,
......@@ -678,8 +695,8 @@ void __osd_Volume( vlc_object_t *p_this )
osd_UpdateState( p_osd->p_state,
p_button->i_x, p_button->i_y,
p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
p_button->p_current_state->i_width,
p_button->p_current_state->i_height,
p_button->p_current_state->p_pic );
osd_SetMenuUpdate( p_osd, VLC_TRUE );
osd_SetMenuVisible( p_osd, VLC_TRUE );
......@@ -688,3 +705,135 @@ void __osd_Volume( vlc_object_t *p_this )
vlc_mutex_unlock( lockval.p_address );
}
}
osd_button_t *__osd_ButtonFind( vlc_object_t *p_this, int i_x, int i_y,
int i_window_height, int i_window_width,
int i_scale_width, int i_scale_height )
{
osd_menu_t *p_osd;
osd_button_t *p_button, *p_start, *p_end;
vlc_value_t lockval;
p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE );
if( p_osd == NULL )
{
msg_Err( p_this, "OSD menu button find failed" );
return NULL;
}
if( osd_isVisible( p_osd ) == VLC_FALSE )
{
vlc_object_release( (vlc_object_t*) p_osd );
return NULL;
}
var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
vlc_mutex_lock( lockval.p_address );
p_button = p_osd->p_button;
for( ; p_button != NULL; p_button = p_button->p_next )
{
int i_source_video_width = ( i_window_width * 1000 ) / i_scale_width;
int i_source_video_height = ( i_window_height * 1000 ) / i_scale_height;
int i_y_offset = p_button->i_y;
int i_x_offset = p_button->i_x;
int i_width = p_button->i_width;
int i_height = p_button->i_height;
if( p_osd->i_position > 0 )
{
int i_inv_scale_y = i_source_video_height;
int i_inv_scale_x = i_source_video_width;
int pi_x = 0;
if( p_osd->i_position & SUBPICTURE_ALIGN_BOTTOM )
{
i_y_offset = i_window_height - p_button->i_height -
(p_osd->i_y + p_button->i_y) * i_inv_scale_y / 1000;
}
else if ( !(p_osd->i_position & SUBPICTURE_ALIGN_TOP) )
{
i_y_offset = i_window_height / 2 - p_button->i_height / 2;
}
if( p_osd->i_position & SUBPICTURE_ALIGN_RIGHT )
{
i_x_offset = i_window_width - p_button->i_width -
(pi_x + p_button->i_x)
* i_inv_scale_x / 1000;
}
else if ( !(p_osd->i_position & SUBPICTURE_ALIGN_LEFT) )
{
i_x_offset = i_window_width / 2 - p_button->i_width / 2;
}
i_width = i_window_width - p_button->i_width - i_inv_scale_x / 1000;
i_height = i_window_height - p_button->i_height - i_inv_scale_y / 1000;
}
// TODO: write for Up / Down case too.
// TODO: handle absolute positioning case
if( ( i_x >= i_x_offset ) && ( i_x <= i_x_offset + i_width ) &&
( i_y >= i_y_offset ) && ( i_y <= i_y_offset + i_height ) )
{
vlc_object_release( (vlc_object_t*) p_osd );
vlc_mutex_unlock( lockval.p_address );
return p_button;
}
}
vlc_object_release( (vlc_object_t*) p_osd );
vlc_mutex_unlock( lockval.p_address );
return NULL;
}
/**
* Select the button provided as the new active button
*/
void __osd_ButtonSelect( vlc_object_t *p_this, osd_button_t *p_button )
{
osd_menu_t *p_osd;
osd_button_t *p_old;
vlc_value_t lockval;
p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE );
if( p_osd == NULL )
{
msg_Err( p_this, "OSD menu button select failed" );
return;
}
if( osd_isVisible( p_osd ) == VLC_FALSE )
{
vlc_object_release( (vlc_object_t*) p_osd );
return;
}
var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
vlc_mutex_lock( lockval.p_address );
p_old = p_osd->p_state->p_visible;
if( p_old )
{
if( !p_old->b_range )
p_old->p_current_state = osd_StateChange( p_old, OSD_BUTTON_UNSELECT );
p_osd->p_state->p_visible = p_button;
if( !p_osd->p_state->p_visible->b_range )
p_osd->p_state->p_visible->p_current_state =
osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT );