Changeset 82e29c9ba1135639fe10881591e6261bc3396ae4

Show
Ignore:
Timestamp:
11/15/07 14:38:32 (10 months ago)
Author:
Jean-Paul Saman <jpsaman@videolan.org>
git-committer:
Jean-Paul Saman <jpsaman@videolan.org> 1195133912 +0000
git-parent:

[9d6bf51a76aa5877fbdce794b0a7ffd267ef1e5a]

git-author:
Jean-Paul Saman <jpsaman@videolan.org> 1195133912 +0000
Message:

Implement clickable osdmenu. The clickable positioning and scaling guessing is not complete (the whole spu region is now clickable with current configurations).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/vlc_osd.h

    r1f7592f r82e29c9  
    286286#define OSD_BUTTON_PRESSED  2 
    287287 
    288 static const char *ppsz_button_states[] = { "unselect", "select", "pressed" }; 
    289  
    290288/** 
    291289 * OSD State object 
     
    303301    char        *psz_state; /*< state name */ 
    304302    int          i_state;   /*< state index */ 
     303 
     304    int     i_x;            /*< x-position of button state image */ 
     305    int     i_y;            /*< y-position of button state image */ 
     306    int     i_width;        /*< width of button state image */ 
     307    int     i_height;       /*< height of button state image */ 
    305308}; 
    306309 
     
    331334    int     i_x;            /*< x-position of button visible state image */ 
    332335    int     i_y;            /*< y-position of button visible state image */ 
     336    int     i_width;        /*< width of button visible state image */ 
     337    int     i_height;       /*< height of button visible state image */ 
    333338 
    334339    /* range style button */ 
     
    390395    int     i_height;   /*< height of OSD Menu on the video screen */ 
    391396    int     i_style;    /*< style of spu region generation */ 
     397    int     i_position; /*< display position */ 
    392398 
    393399    char             *psz_path;  /*< directory where OSD menu images are stored */ 
     
    422428VLC_EXPORT( void, __osd_MenuDelete, ( vlc_object_t *, osd_menu_t * ) ); 
    423429 
    424 /** 
    425  * Change state on an osd_button_t. 
    426  * 
    427  * This function selects the specified state and returns a pointer to it. The 
    428  * following states are currently supported: 
    429  * \see OSD_BUTTON_UNSELECT 
    430  * \see OSD_BUTTON_SELECT 
    431  * \see OSD_BUTTON_PRESSED 
    432  */ 
    433 VLC_EXPORT( osd_state_t *, __osd_StateChange, ( osd_state_t *, const int ) ); 
    434  
    435430#define osd_MenuCreate(object,file) __osd_MenuCreate( VLC_OBJECT(object), file ) 
    436431#define osd_MenuDelete(object,osd)  __osd_MenuDelete( VLC_OBJECT(object), osd ) 
    437 #define osd_StateChange(object,value) __osd_StateChange( object, value ) 
     432 
     433/** 
     434 * Find OSD Menu button at position x,y 
     435 */ 
     436VLC_EXPORT( osd_button_t *, __osd_ButtonFind, ( vlc_object_t *p_this, 
     437     int, int, int, int, int, int ) ); 
     438 
     439#define osd_ButtonFind(object,x,y,h,w,sh,sw)  __osd_ButtonFind(object,x,y,h,w,sh,sw) 
     440 
     441/** 
     442 * Select the button provided as the new active button 
     443 */ 
     444VLC_EXPORT( void, __osd_ButtonSelect, ( vlc_object_t *, osd_button_t *) ); 
     445 
     446#define osd_ButtonSelect(object,button) __osd_ButtonSelect(object,button) 
    438447 
    439448/** 
  • modules/misc/osd/osd_menu.c

    rb993600 r82e29c9  
    219219        p_state->p_pic = image_ReadUrl( p_menu->p_image, psz_file, 
    220220                                        &fmt_in, &fmt_out ); 
     221 
     222        p_state->i_width  = p_state->p_pic->p[Y_PLANE].i_visible_pitch; 
     223        p_state->i_height = p_state->p_pic->p[Y_PLANE].i_visible_lines; 
    221224    } 
    222225 
  • modules/misc/osd/osd_menu.h

    rb993600 r82e29c9  
    2525#define _OSD_MENU_PARSER_H_ 
    2626 
     27static const char *ppsz_button_states[] = { "unselect", "select", "pressed" }; 
     28 
    2729/* OSD Menu structure support routines for internal use by 
    2830 * OSD Menu configuration file parsers only. 
  • modules/misc/osd/simple.c

    r1f7592f r82e29c9  
    270270                            goto error; 
    271271 
     272                        p_range_current->i_x = i_x; 
     273                        p_range_current->i_y = i_y; 
     274 
    272275                        /* increment the number of ranges for this button */ 
    273276                        p_up->i_ranges++; 
     
    367370                        goto error; 
    368371 
     372                    p_range_current->i_x = i_x; 
     373                    p_range_current->i_y = i_y; 
     374 
    369375                    /* increment the number of ranges for this button */ 
    370376                    p_current->i_ranges++; 
     
    434440                goto error; 
    435441 
     442            p_state_current->i_x = i_x; 
     443            p_state_current->i_y = i_y; 
     444 
    436445            if( p_state_prev ) 
    437446                p_state_prev->p_next = p_state_current; 
  • modules/video_filter/osdmenu.c

    r1bc8330 r82e29c9  
    8585static void DestroyFilter( vlc_object_t * ); 
    8686static subpicture_t *Filter( filter_t *, mtime_t ); 
     87 
    8788static int OSDMenuUpdateEvent( vlc_object_t *, char const *, 
    8889                    vlc_value_t, vlc_value_t, void * ); 
     
    9192static int OSDMenuCallback( vlc_object_t *, char const *, 
    9293                            vlc_value_t, vlc_value_t, void * ); 
     94 
     95static int MouseEvent( vlc_object_t *, char const *, 
     96                        vlc_value_t , vlc_value_t , void * ); 
    9397 
    9498#define OSD_CFG "osdmenu-" 
     
    158162    char        *psz_path;      /* Path to OSD Menu pictures */ 
    159163    osd_menu_t  *p_menu;        /* pointer to OSD Menu object */ 
     164 
     165    /* menu interaction */ 
     166    vout_thread_t *p_vout; 
     167    vlc_bool_t  b_clicked; 
     168    uint32_t    i_mouse_x; 
     169    uint32_t    i_mouse_y; 
    160170}; 
    161171 
     
    207217        goto error; 
    208218 
     219    p_sys->p_menu->i_position = p_sys->i_position; 
     220 
    209221    /* Check if menu position was overridden */ 
    210222    p_sys->b_absolute = VLC_TRUE; 
     
    234246    p_sys->b_update  = VLC_FALSE; 
    235247    p_sys->b_visible = VLC_FALSE; 
     248    p_sys->b_clicked = VLC_FALSE; 
    236249 
    237250    /* Listen to osd menu core updates/visible settings. */ 
     
    244257    p_filter->pf_sub_filter = Filter; 
    245258 
     259    p_sys->p_vout = vlc_object_find( p_this, VLC_OBJECT_VOUT, FIND_ANYWHERE ); 
     260    if( p_sys->p_vout ) 
     261    { 
     262        var_AddCallback( p_sys->p_vout, "mouse-x", 
     263                        MouseEvent, p_sys ); 
     264        var_AddCallback( p_sys->p_vout, "mouse-y", 
     265                        MouseEvent, p_sys ); 
     266        var_AddCallback( p_sys->p_vout, "mouse-clicked", 
     267                        MouseEvent, p_sys ); 
     268    } 
     269 
    246270    es_format_Init( &p_filter->fmt_out, SPU_ES, VLC_FOURCC( 's','p','u',' ' ) ); 
    247271    p_filter->fmt_out.i_priority = 0; 
     
    276300    var_DelCallback( p_sys->p_menu, "osd-menu-visible", 
    277301                     OSDMenuVisibleEvent, p_filter ); 
     302 
     303    if( p_sys->p_vout ) 
     304    { 
     305        var_DelCallback( p_sys->p_vout, "mouse-x", 
     306                        MouseEvent, p_sys ); 
     307        var_DelCallback( p_sys->p_vout, "mouse-y", 
     308                        MouseEvent, p_sys ); 
     309        var_DelCallback( p_sys->p_vout, "mouse-clicked", 
     310                        MouseEvent, p_sys ); 
     311 
     312        vlc_object_release( p_sys->p_vout ); 
     313        p_sys->p_vout = NULL; 
     314    } 
    278315 
    279316    var_Destroy( p_this, OSD_CFG "file-path" ); 
     
    469506    } 
    470507 
     508    if( p_sys->p_vout && p_sys->b_clicked ) 
     509    { 
     510        p_sys->b_clicked = VLC_FALSE; 
     511        osd_MenuActivate( p_filter ); 
     512    } 
    471513    /* Create new spu regions 
    472514    */ 
     
    607649    return VLC_SUCCESS; 
    608650} 
     651 
     652/***************************************************************************** 
     653 * MouseEvent: callback for mouse events 
     654 *****************************************************************************/ 
     655static int MouseEvent( vlc_object_t *p_this, char const *psz_var, 
     656                       vlc_value_t oldval, vlc_value_t newval, void *p_data ) 
     657{ 
     658    filter_sys_t *p_sys = (filter_sys_t *)p_data; 
     659    vout_thread_t *p_vout = (vout_thread_t*)p_sys->p_vout; 
     660    int i_x, i_y; 
     661    int i_v; 
     662 
     663#define MOUSE_DOWN    1 
     664#define MOUSE_CLICKED 2 
     665#define MOUSE_MOVE_X  4 
     666#define MOUSE_MOVE_Y  8 
     667#define MOUSE_MOVE    12 
     668    uint8_t mouse= 0; 
     669 
     670    int v_h = p_vout->output.i_height; 
     671    int v_w = p_vout->output.i_width; 
     672 
     673    if( psz_var[6] == 'x' ) mouse |= MOUSE_MOVE_X; 
     674    if( psz_var[6] == 'y' ) mouse |= MOUSE_MOVE_Y; 
     675    if( psz_var[6] == 'c' ) mouse |= MOUSE_CLICKED; 
     676 
     677    i_v = var_GetInteger( p_sys->p_vout, "mouse-button-down" ); 
     678    if( i_v & 0x1 ) mouse |= MOUSE_DOWN; 
     679    i_y = var_GetInteger( p_sys->p_vout, "mouse-y" ); 
     680    i_x = var_GetInteger( p_sys->p_vout, "mouse-x" ); 
     681 
     682    if( i_y < 0 || i_x < 0 || i_y >= v_h || i_x >= v_w ) 
     683        return VLC_SUCCESS; 
     684 
     685    if( mouse & MOUSE_CLICKED ) 
     686    { 
     687        int i_scale_width, i_scale_height; 
     688        osd_button_t *p_button = NULL; 
     689 
     690        i_scale_width = p_vout->fmt_out.i_visible_width * 1000 / 
     691            p_vout->fmt_in.i_visible_width; 
     692        i_scale_height = p_vout->fmt_out.i_visible_height * 1000 / 
     693            p_vout->fmt_in.i_visible_height; 
     694 
     695        p_button = osd_ButtonFind( p_this, i_x, i_y, v_h, v_w, 
     696                                   i_scale_width, i_scale_height ); 
     697        if( p_button ) 
     698        { 
     699            osd_ButtonSelect( p_this, p_button ); 
     700            p_sys->b_update = p_sys->b_visible ? VLC_TRUE : VLC_FALSE; 
     701            p_sys->b_clicked = VLC_TRUE; 
     702            msg_Dbg( p_this, "mouse clicked %s (%d,%d)\n", p_button->psz_name, i_x, i_y ); 
     703        } 
     704    } 
     705    return VLC_SUCCESS; 
     706} 
  • src/osd/osd.c

    r6f3acaa r82e29c9  
    3535#undef OSD_MENU_DEBUG 
    3636 
     37static const char *ppsz_button_states[] = { "unselect", "select", "pressed" }; 
     38 
    3739/***************************************************************************** 
    3840 * Local prototypes 
     
    114116} 
    115117 
     118/** 
     119 * Change state on an osd_button_t. 
     120 * 
     121 * This function selects the specified state and returns a pointer to it. The 
     122 * following states are currently supported: 
     123 * \see OSD_BUTTON_UNSELECT 
     124 * \see OSD_BUTTON_SELECT 
     125 * \see OSD_BUTTON_PRESSED 
     126 */ 
     127static osd_state_t *osd_StateChange( osd_button_t *p_button, const int i_state ) 
     128{ 
     129    osd_state_t *p_current = p_button->p_states; 
     130    osd_state_t *p_temp = NULL; 
     131    int i = 0; 
     132 
     133    for( i=0; p_current != NULL; i++ ) 
     134    { 
     135        if( p_current->i_state == i_state ) 
     136        { 
     137            p_button->i_x = p_current->i_x; 
     138            p_button->i_y = p_current->i_y; 
     139            p_button->i_width = p_current->i_width; 
     140            p_button->i_height = p_current->i_height; 
     141            return p_current; 
     142        } 
     143        p_temp = p_current->p_next; 
     144        p_current = p_temp; 
     145    } 
     146    return p_button->p_states; 
     147} 
     148 
    116149/***************************************************************************** 
    117150 * OSD menu Funtions 
     
    142175        p_osd->p_state->p_visible = p_osd->p_button; 
    143176        p_osd->p_state->p_visible->p_current_state = 
    144             osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); 
     177            osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT ); 
    145178        p_osd->i_width  = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch; 
    146179        p_osd->i_height = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines; 
     
    207240} 
    208241 
    209 osd_state_t *__osd_StateChange( osd_state_t *p_states, const int i_state ) 
    210 { 
    211     osd_state_t *p_current = p_states; 
    212     osd_state_t *p_temp = NULL; 
    213     int i = 0; 
    214  
    215     for( i=0; p_current != NULL; i++ ) 
    216     { 
    217         if( p_current->i_state == i_state ) 
    218             return p_current; 
    219         p_temp = p_current->p_next; 
    220         p_current = p_temp; 
    221     } 
    222     return p_states; 
    223 } 
    224  
    225242/* The volume can be modified in another interface while the OSD Menu 
    226243 * has not been instantiated yet. This routines updates the "volume OSD menu item" 
     
    277294    { 
    278295        if( !p_button->b_range ) 
    279             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT ); 
     296            p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_UNSELECT ); 
    280297        p_osd->p_state->p_visible = p_osd->p_button; 
    281298 
    282299        if( !p_osd->p_state->p_visible->b_range ) 
    283300            p_osd->p_state->p_visible->p_current_state = 
    284                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); 
     301                osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT ); 
    285302 
    286303        osd_UpdateState( p_osd->p_state, 
    287304                p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, 
    288                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, 
    289                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines
     305                p_osd->p_state->p_visible->p_current_state->i_width, 
     306                p_osd->p_state->p_visible->p_current_state->i_height
    290307                p_osd->p_state->p_visible->p_current_state->p_pic ); 
    291308        osd_SetMenuUpdate( p_osd, VLC_TRUE ); 
     
    370387    if( p_button && !p_button->b_range ) 
    371388    { 
    372         p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_PRESSED ); 
     389        p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_PRESSED ); 
    373390        osd_UpdateState( p_osd->p_state, 
    374391                p_button->i_x, p_button->i_y, 
    375                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, 
    376                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines
     392                p_osd->p_state->p_visible->p_current_state->i_width, 
     393                p_osd->p_state->p_visible->p_current_state->i_height
    377394                p_button->p_current_state->p_pic ); 
    378395        osd_SetMenuUpdate( p_osd, VLC_TRUE ); 
     
    413430    { 
    414431        if( !p_button->b_range ) 
    415             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT ); 
     432            p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_UNSELECT ); 
    416433        if( p_button->p_next ) 
    417434            p_osd->p_state->p_visible = p_button->p_next; 
     
    421438        if( !p_osd->p_state->p_visible->b_range ) 
    422439            p_osd->p_state->p_visible->p_current_state = 
    423                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); 
     440                osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT ); 
    424441 
    425442        osd_UpdateState( p_osd->p_state, 
    426443                p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, 
    427                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, 
    428                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines
     444                p_osd->p_state->p_visible->p_current_state->i_width, 
     445                p_osd->p_state->p_visible->p_current_state->i_height
    429446                p_osd->p_state->p_visible->p_current_state->p_pic ); 
    430447        osd_SetMenuUpdate( p_osd, VLC_TRUE ); 
     
    464481    { 
    465482        if( !p_button->b_range ) 
    466             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT ); 
     483            p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_UNSELECT ); 
    467484        if( p_button->p_prev ) 
    468485            p_osd->p_state->p_visible = p_button->p_prev; 
     
    472489        if( !p_osd->p_state->p_visible->b_range ) 
    473490            p_osd->p_state->p_visible->p_current_state = 
    474                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); 
     491                osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT ); 
    475492 
    476493        osd_UpdateState( p_osd->p_state, 
    477494                p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, 
    478                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, 
    479                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines
     495                p_osd->p_state->p_visible->p_current_state->i_width, 
     496                p_osd->p_state->p_visible->p_current_state->i_height
    480497                p_osd->p_state->p_visible->p_current_state->p_pic ); 
    481498        osd_SetMenuUpdate( p_osd, VLC_TRUE ); 
     
    518535        if( !p_button->b_range ) 
    519536        { 
    520             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT ); 
     537            p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_SELECT ); 
    521538            if( p_button->p_up ) 
    522539                p_osd->p_state->p_visible = p_button->p_up; 
     
    532549        { 
    533550            p_osd->p_state->p_visible->p_current_state = 
    534                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); 
     551                osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT ); 
    535552        } 
    536553 
    537554        osd_UpdateState( p_osd->p_state, 
    538555                p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, 
    539                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, 
    540                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines
     556                p_osd->p_state->p_visible->p_current_state->i_width, 
     557                p_osd->p_state->p_visible->p_current_state->i_height
    541558                p_osd->p_state->p_visible->p_current_state->p_pic ); 
    542559        osd_SetMenuUpdate( p_osd, VLC_TRUE ); 
     
    590607        if( !p_button->b_range ) 
    591608        { 
    592             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT ); 
     609            p_button->p_current_state = osd_StateChange( p_button, OSD_BUTTON_SELECT ); 
    593610            if( p_button->p_down ) 
    594611                p_osd->p_state->p_visible = p_button->p_down; 
     
    604621        { 
    605622            p_osd->p_state->p_visible->p_current_state = 
    606                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); 
     623                osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT ); 
    607624        } 
    608625 
    609626        osd_UpdateState( p_osd->p_state, 
    610627                p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, 
    611                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, 
    612                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines
     628                p_osd->p_state->p_visible->p_current_state->i_width, 
     629                p_osd->p_state->p_visible->p_current_state->i_height
    613630                p_osd->p_state->p_visible->p_current_state->p_pic ); 
    614631        osd_SetMenuUpdate( p_osd, VLC_TRUE ); 
     
    679696            osd_UpdateState( p_osd->p_state, 
    680697                    p_button->i_x, p_button->i_y, 
    681                     p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, 
    682                     p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_lines
     698                    p_button->p_current_state->i_width, 
     699                    p_button->p_current_state->i_height
    683700                    p_button->p_current_state->p_pic ); 
    684701            osd_SetMenuUpdate( p_osd, VLC_TRUE ); 
     
    689706    } 
    690707} 
     708 
     709osd_button_t *__osd_ButtonFind( vlc_object_t *p_this, int i_x, int i_y, 
     710    int i_window_height, int i_window_width, 
     711    int i_scale_width, int i_scale_height ) 
     712{ 
     713    osd_menu_t *p_osd; 
     714    osd_button_t *p_button, *p_start, *p_end; 
     715    vlc_value_t lockval; 
     716 
     717    p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ); 
     718    if( p_osd == NULL ) 
     719    { 
     720        msg_Err( p_this, "OSD menu button find failed" ); 
     721        return NULL; 
     722    } 
     723 
     724    if( osd_isVisible( p_osd ) == VLC_FALSE ) 
     725    { 
     726        vlc_object_release( (vlc_object_t*) p_osd ); 
     727        return NULL; 
     728    } 
     729 
     730    var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); 
     731    vlc_mutex_lock( lockval.p_address ); 
     732 
     733    p_button = p_osd->p_button; 
     734    for( ; p_button != NULL; p_button = p_button->p_next ) 
     735    { 
     736        int i_source_video_width  = ( i_window_width  * 1000 ) / i_scale_width; 
     737        int i_source_video_height = ( i_window_height * 1000 ) / i_scale_height; 
     738        int i_y_offset = p_button->i_y; 
     739        int i_x_offset = p_button->i_x; 
     740        int i_width = p_button->i_width; 
     741        int i_height = p_button->i_height; 
     742 
     743        if( p_osd->i_position > 0 ) 
     744        { 
     745            int i_inv_scale_y = i_source_video_height; 
     746            int i_inv_scale_x = i_source_video_width; 
     747            int pi_x = 0; 
     748 
     749            if( p_osd->i_position & SUBPICTURE_ALIGN_BOTTOM ) 
     750            { 
     751                i_y_offset = i_window_height - p_button->i_height - 
     752                    (p_osd->i_y + p_button->i_y) * i_inv_scale_y / 1000; 
     753            } 
     754            else if ( !(p_osd->i_position & SUBPICTURE_ALIGN_TOP) ) 
     755            { 
     756                i_y_offset = i_window_height / 2 - p_button->i_height / 2; 
     757            } 
     758 
     759            if( p_osd->i_position & SUBPICTURE_ALIGN_RIGHT ) 
     760            { 
     761                i_x_offset = i_window_width - p_button->i_width - 
     762                    (pi_x + p_button->i_x) 
     763                    * i_inv_scale_x / 1000; 
     764            } 
     765            else if ( !(p_osd->i_position & SUBPICTURE_ALIGN_LEFT) ) 
     766            { 
     767                i_x_offset = i_window_width / 2 - p_button->i_width / 2; 
     768            } 
     769 
     770            i_width = i_window_width - p_button->i_width - i_inv_scale_x / 1000; 
     771            i_height = i_window_height - p_button->i_height - i_inv_scale_y / 1000; 
     772        } 
     773 
     774        // TODO: write for Up / Down case too. 
     775        // TODO: handle absolute positioning case 
     776        if( ( i_x >= i_x_offset ) && ( i_x <= i_x_offset + i_width ) && 
     777            ( i_y >= i_y_offset ) && ( i_y <= i_y_offset + i_height ) ) 
     778        { 
     779            vlc_object_release( (vlc_object_t*) p_osd ); 
     780            vlc_mutex_unlock( lockval.p_address ); 
     781            return p_button; 
     782        } 
     783    } 
     784 
     785    vlc_object_release( (vlc_object_t*) p_osd ); 
     786    vlc_mutex_unlock( lockval.p_address ); 
     787    return NULL; 
     788} 
     789 
     790/** 
     791 * Select the button provided as the new active button 
     792 */ 
     793void __osd_ButtonSelect( vlc_object_t *p_this, osd_button_t *p_button ) 
     794{ 
     795    osd_menu_t *p_osd; 
     796    osd_button_t *p_old; 
     797    vlc_value_t lockval; 
     798 
     799    p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ); 
     800    if( p_osd == NULL ) 
     801    { 
     802        msg_Err( p_this, "OSD menu button select failed" ); 
     803        return; 
     804    } 
     805 
     806    if( osd_isVisible( p_osd ) == VLC_FALSE ) 
     807    { 
     808        vlc_object_release( (vlc_object_t*) p_osd ); 
     809        return; 
     810    } 
     811 
     812    var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); 
     813    vlc_mutex_lock( lockval.p_address ); 
     814 
     815    p_old = p_osd->p_state->p_visible; 
     816    if( p_old ) 
     817    { 
     818        if( !p_old->b_range ) 
     819            p_old->p_current_state = osd_StateChange( p_old, OSD_BUTTON_UNSELECT ); 
     820        p_osd->p_state->p_visible = p_button; 
     821 
     822        if( !p_osd->p_state->p_visible->b_range ) 
     823            p_osd->p_state->p_visible->p_current_state = 
     824                osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT ); 
     825 
     826        osd_UpdateState( p_osd->p_state, 
     827                p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, 
     828                p_osd->p_state->p_visible->p_current_state->i_width, 
     829                p_osd->p_state->p_visible->p_current_state->i_height, 
     830                p_osd->p_state->p_visible->p_current_state->p_pic ); 
     831        osd_SetMenuUpdate( p_osd, VLC_TRUE ); 
     832    } 
     833#if defined(OSD_MENU_DEBUG) 
     834    msg_Dbg( p_osd, "button selected is [button %s]", p_osd->p_state->p_visible->psz_action ); 
     835#endif 
     836 
     837    vlc_object_release( (vlc_object_t*) p_osd ); 
     838    vlc_mutex_unlock( lockval.p_address ); 
     839}