Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

osd.c

00001 /*****************************************************************************
00002  * osd.c - The OSD Menu core code.
00003  *****************************************************************************
00004  * Copyright (C) 2005 M2X
00005  * $Id: osd.c 9451 2004-12-01 01:07:08Z jpsaman $
00006  *
00007  * Authors: Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <stdlib.h>
00028 #include <string.h>
00029 
00030 #include <vlc/vlc.h>
00031 #include <vlc_keys.h>
00032 #include <vlc_osd.h>
00033 
00034 #undef OSD_MENU_DEBUG
00035 
00036 /*****************************************************************************
00037  * Local prototypes
00038  *****************************************************************************/
00039 
00040 static void osd_UpdateState( osd_menu_state_t *, int, int, int, int, picture_t * );
00041 static inline osd_state_t *osd_VolumeStateChange( osd_state_t *, int );
00042 static int osd_VolumeStep( vlc_object_t *, int, int );
00043 static vlc_bool_t osd_isVisible( osd_menu_t *p_osd );
00044 
00045 static vlc_bool_t osd_isVisible( osd_menu_t *p_osd )
00046 {
00047     vlc_value_t val;
00048 
00049     var_Get( p_osd, "osd-menu-visible", &val );
00050     return val.b_bool;
00051 }
00052 
00053 /*****************************************************************************
00054  * OSD menu Funtions
00055  *****************************************************************************/
00056 osd_menu_t *__osd_MenuCreate( vlc_object_t *p_this, const char *psz_file )
00057 {
00058     osd_menu_t  *p_osd = NULL;
00059     vlc_value_t lockval;
00060     int         i_volume = 0;
00061     int         i_steps = 0;
00062 
00063     /* to be sure to avoid multiple creation */
00064     var_Create( p_this->p_libvlc, "osd_mutex", VLC_VAR_MUTEX );
00065     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00066     vlc_mutex_lock( lockval.p_address );
00067 
00068     if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL )
00069     {
00070         vlc_value_t val;
00071 
00072         msg_Dbg( p_this, "creating osd menu object" );
00073         if( ( p_osd = vlc_object_create( p_this, VLC_OBJECT_OSDMENU ) ) == NULL )
00074         {
00075             msg_Err( p_this, "out of memory" );
00076             vlc_mutex_unlock( lockval.p_address );
00077             return NULL;
00078         }
00079 
00080         /* Parse configuration file */
00081         if( osd_ConfigLoader( p_this, psz_file, &p_osd ) )
00082             goto error;
00083 
00084         /* Setup default button (first button) */
00085         p_osd->p_state->p_visible = p_osd->p_button;
00086         p_osd->p_state->p_visible->p_current_state =
00087             osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
00088         p_osd->i_width  = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch;
00089         p_osd->i_height = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines;
00090 
00091         /* Update the volume state images to match the current volume */
00092         i_volume = config_GetInt( p_this, "volume" );
00093         i_steps = osd_VolumeStep( p_this, i_volume, p_osd->p_state->p_volume->i_ranges );
00094         p_osd->p_state->p_volume->p_current_state = osd_VolumeStateChange( p_osd->p_state->p_volume->p_states, i_steps );
00095 
00096         /* Initialize OSD state */
00097         osd_UpdateState( p_osd->p_state, p_osd->i_x, p_osd->i_y,
00098                          p_osd->i_width, p_osd->i_height, NULL );
00099 
00100         vlc_object_yield( p_osd );
00101         vlc_object_attach( p_osd, p_this->p_vlc );
00102 
00103         /* Signal when an update of OSD menu is needed */
00104         var_Create( p_osd, "osd-menu-update", VLC_VAR_BOOL );
00105         var_Create( p_osd, "osd-menu-visible", VLC_VAR_BOOL );
00106 
00107         val.b_bool = VLC_FALSE;
00108         var_Set( p_osd, "osd-menu-update", val );
00109         var_Set( p_osd, "osd-menu-visible", val );
00110     }
00111     vlc_mutex_unlock( lockval.p_address );
00112     return p_osd;
00113 
00114 error:
00115     msg_Err( p_this, "creating osd menu object failed" );
00116     vlc_mutex_unlock( lockval.p_address );
00117     vlc_object_destroy( p_osd );
00118     return NULL;
00119 }
00120 
00121 void __osd_MenuDelete( vlc_object_t *p_this, osd_menu_t *p_osd )
00122 {
00123     vlc_value_t lockval;
00124 
00125     if( !p_osd || !p_this ) return;
00126 
00127     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00128     vlc_mutex_lock( lockval.p_address );
00129 
00130     vlc_object_release( p_osd );
00131     if( p_osd->i_refcount > 0 )
00132     {
00133         vlc_mutex_unlock( lockval.p_address );
00134         return;
00135     }
00136 
00137     var_Destroy( p_osd, "osd-menu-visible" );
00138     var_Destroy( p_osd, "osd-menu-update" );
00139 
00140     osd_ConfigUnload( p_this, &p_osd );
00141     vlc_object_detach( p_osd );
00142     vlc_object_destroy( p_osd );
00143     p_osd = NULL;
00144 
00145     vlc_mutex_unlock( lockval.p_address );
00146 }
00147 
00148 osd_state_t *__osd_StateChange( osd_state_t *p_states, const int i_state )
00149 {
00150     osd_state_t *p_current = p_states;
00151     osd_state_t *p_temp = NULL;
00152     int i = 0;
00153 
00154     for( i=0; p_current != NULL; i++ )
00155     {
00156         if( p_current->i_state == i_state )
00157             return p_current;
00158         p_temp = p_current->p_next;
00159         p_current = p_temp;
00160     }
00161     return p_states;
00162 }
00163 
00164 /* The volume can be modified in another interface while the OSD Menu 
00165  * has not been instantiated yet. This routines updates the "volume OSD menu item"
00166  * to reflect the current state of the GUI.
00167  */
00168 static inline osd_state_t *osd_VolumeStateChange( osd_state_t *p_current, int i_steps )
00169 {
00170     osd_state_t *p_temp = NULL;
00171     int i;
00172 
00173     if( i_steps < 0 ) i_steps = 0;
00174 
00175     for( i=0; (i < i_steps) && (p_current != NULL); i++ )
00176     {
00177         p_temp = p_current->p_next;
00178         if( !p_temp ) return p_current;
00179         p_current = p_temp;
00180     }
00181     return (!p_temp) ? p_current : p_temp;
00182 }
00183 
00184 /* Update the state of the OSD Menu */
00185 static void osd_UpdateState( osd_menu_state_t *p_state, int i_x, int i_y,
00186         int i_width, int i_height, picture_t *p_pic )
00187 {
00188     p_state->i_x = i_x;
00189     p_state->i_y = i_y;
00190     p_state->i_width = i_width;
00191     p_state->i_height = i_height;
00192     p_state->p_pic = p_pic;
00193 }
00194 
00195 void __osd_MenuShow( vlc_object_t *p_this )
00196 {
00197     osd_menu_t *p_osd = NULL;
00198     osd_button_t *p_button = NULL;
00199     vlc_value_t lockval;
00200 
00201     if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL )
00202     {
00203         msg_Err( p_this, "osd_MenuNext failed" );
00204         return;
00205     }
00206 
00207     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00208     vlc_mutex_lock( lockval.p_address );
00209 
00210 #if defined(OSD_MENU_DEBUG)
00211     msg_Dbg( p_osd, "menu on" );
00212 #endif
00213     p_button = p_osd->p_state->p_visible;
00214     if( p_button )
00215     {
00216         if( !p_button->b_range ) 
00217             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT );
00218         p_osd->p_state->p_visible = p_osd->p_button;
00219 
00220         if( !p_osd->p_state->p_visible->b_range ) 
00221             p_osd->p_state->p_visible->p_current_state =
00222                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
00223 
00224         osd_UpdateState( p_osd->p_state,
00225                 p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
00226                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
00227                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
00228                 p_osd->p_state->p_visible->p_current_state->p_pic );
00229         osd_SetMenuUpdate( p_osd, VLC_TRUE );
00230     }
00231     osd_SetMenuVisible( p_osd, VLC_TRUE );
00232 
00233     vlc_object_release( (vlc_object_t*) p_osd );
00234     vlc_mutex_unlock( lockval.p_address );
00235 }
00236 
00237 void __osd_MenuHide( vlc_object_t *p_this )
00238 {
00239     osd_menu_t *p_osd = NULL;
00240     vlc_value_t lockval;
00241 
00242     if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL )
00243     {
00244         msg_Err( p_this, "osd_MenuNext failed" );
00245         return;
00246     }
00247 
00248     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00249     vlc_mutex_lock( lockval.p_address );
00250 
00251 #if defined(OSD_MENU_DEBUG)
00252     msg_Dbg( p_osd, "menu off" );
00253 #endif
00254     osd_UpdateState( p_osd->p_state,
00255                 p_osd->p_state->i_x, p_osd->p_state->i_y,
00256                 0, 0, NULL );
00257     osd_SetMenuUpdate( p_osd, VLC_TRUE );
00258 
00259     vlc_object_release( (vlc_object_t*) p_osd );
00260     vlc_mutex_unlock( lockval.p_address );
00261 }
00262 
00263 void __osd_MenuActivate( vlc_object_t *p_this )
00264 {
00265     osd_menu_t *p_osd = NULL;
00266     osd_button_t *p_button = NULL;
00267     vlc_value_t lockval;
00268 
00269     if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL )
00270     {
00271         msg_Err( p_this, "osd_MenuNext failed" );
00272         return;
00273     }
00274 
00275     if( osd_isVisible( p_osd ) == VLC_FALSE )
00276     {
00277         vlc_object_release( (vlc_object_t*) p_osd );
00278         return;
00279     }
00280 
00281     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00282     vlc_mutex_lock( lockval.p_address );
00283 
00284 #if defined(OSD_MENU_DEBUG)
00285     msg_Dbg( p_osd, "select" );
00286 #endif
00287     p_button = p_osd->p_state->p_visible;
00288     /*
00289      * Is there a menu item above or below? If so, then select it.
00290      */
00291     if( p_button && p_button->p_up)
00292     {
00293         vlc_object_release( (vlc_object_t*) p_osd );
00294         vlc_mutex_unlock( lockval.p_address );
00295         __osd_MenuUp( p_this );   /* "menu select" means go to menu item above. */
00296         return;
00297     }
00298     if( p_button && p_button->p_down)
00299     {
00300         vlc_object_release( (vlc_object_t*) p_osd );
00301         vlc_mutex_unlock( lockval.p_address );
00302         __osd_MenuDown( p_this ); /* "menu select" means go to menu item below. */
00303         return;
00304     }
00305 
00306     if( p_button && !p_button->b_range )
00307     {
00308         p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_PRESSED );
00309         osd_UpdateState( p_osd->p_state,
00310                 p_button->i_x, p_button->i_y,
00311                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
00312                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
00313                 p_button->p_current_state->p_pic );
00314         osd_SetMenuUpdate( p_osd, VLC_TRUE );
00315         osd_SetMenuVisible( p_osd, VLC_TRUE );
00316         osd_SetKeyPressed( VLC_OBJECT(p_osd->p_vlc), config_GetInt( p_osd, p_button->psz_action ) );
00317 #if defined(OSD_MENU_DEBUG)
00318         msg_Dbg( p_osd, "select (%d, %s)", config_GetInt( p_osd, p_button->psz_action ), p_button->psz_action );
00319 #endif
00320     }
00321     vlc_object_release( (vlc_object_t*) p_osd );
00322     vlc_mutex_unlock( lockval.p_address );
00323 }
00324 
00325 void __osd_MenuNext( vlc_object_t *p_this )
00326 {
00327     osd_menu_t *p_osd = NULL;
00328     osd_button_t *p_button = NULL;
00329     vlc_value_t lockval;
00330 
00331     if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL )
00332     {
00333         msg_Err( p_this, "osd_MenuNext failed" );
00334         return;
00335     }
00336 
00337     if( osd_isVisible( p_osd ) == VLC_FALSE )
00338     {
00339         vlc_object_release( (vlc_object_t*) p_osd );
00340         return;
00341     }
00342 
00343     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00344     vlc_mutex_lock( lockval.p_address );
00345 
00346     p_button = p_osd->p_state->p_visible;
00347     if( p_button )
00348     {
00349         if( !p_button->b_range ) 
00350             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT );
00351         if( p_button->p_next )
00352             p_osd->p_state->p_visible = p_button->p_next;
00353         else
00354             p_osd->p_state->p_visible = p_osd->p_button;
00355 
00356         if( !p_osd->p_state->p_visible->b_range ) 
00357             p_osd->p_state->p_visible->p_current_state =
00358                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
00359 
00360         osd_UpdateState( p_osd->p_state, 
00361                 p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
00362                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
00363                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
00364                 p_osd->p_state->p_visible->p_current_state->p_pic );
00365         osd_SetMenuUpdate( p_osd, VLC_TRUE );
00366     }
00367 #if defined(OSD_MENU_DEBUG)
00368     msg_Dbg( p_osd, "direction right [button %s]", p_osd->p_state->p_visible->psz_action );
00369 #endif
00370 
00371     vlc_object_release( (vlc_object_t*) p_osd );
00372     vlc_mutex_unlock( lockval.p_address );
00373 }
00374 
00375 void __osd_MenuPrev( vlc_object_t *p_this )
00376 {
00377     osd_menu_t *p_osd = NULL;
00378     osd_button_t *p_button = NULL;
00379     vlc_value_t lockval;
00380 
00381     if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL )
00382     {
00383         msg_Err( p_this, "osd_MenuPrev failed" );
00384         return;
00385     }
00386 
00387     if( osd_isVisible( p_osd ) == VLC_FALSE )
00388     {
00389         vlc_object_release( (vlc_object_t*) p_osd );
00390         return;
00391     }
00392 
00393     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00394     vlc_mutex_lock( lockval.p_address );
00395 
00396     p_button = p_osd->p_state->p_visible;
00397     if( p_button )
00398     {
00399         if( !p_button->b_range ) 
00400             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT );
00401         if( p_button->p_prev )
00402             p_osd->p_state->p_visible = p_button->p_prev;
00403         else
00404             p_osd->p_state->p_visible = p_osd->p_last_button;
00405 
00406         if( !p_osd->p_state->p_visible->b_range ) 
00407             p_osd->p_state->p_visible->p_current_state =
00408                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
00409 
00410         osd_UpdateState( p_osd->p_state, 
00411                 p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
00412                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
00413                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
00414                 p_osd->p_state->p_visible->p_current_state->p_pic );
00415         osd_SetMenuUpdate( p_osd, VLC_TRUE );
00416     }
00417 #if defined(OSD_MENU_DEBUG)
00418     msg_Dbg( p_osd, "direction left [button %s]", p_osd->p_state->p_visible->psz_action );
00419 #endif
00420 
00421     vlc_object_release( (vlc_object_t*) p_osd );
00422     vlc_mutex_unlock( lockval.p_address );
00423 }
00424 
00425 void __osd_MenuUp( vlc_object_t *p_this )
00426 {
00427     osd_menu_t *p_osd = NULL;
00428     osd_button_t *p_button = NULL;
00429     vlc_value_t lockval;
00430 #if defined(OSD_MENU_DEBUG)
00431     vlc_value_t val;
00432 #endif
00433 
00434     if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL )
00435     {
00436         msg_Err( p_this, "osd_MenuDown failed" );
00437         return;
00438     }
00439 
00440     if( osd_isVisible( p_osd ) == VLC_FALSE )
00441     {
00442         vlc_object_release( (vlc_object_t*) p_osd );
00443         return;
00444     }
00445 
00446     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00447     vlc_mutex_lock( lockval.p_address );
00448 
00449     p_button = p_osd->p_state->p_visible;
00450     if( p_button )
00451     {
00452         if( !p_button->b_range ) 
00453         {
00454             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT );
00455             if( p_button->p_up )
00456                 p_osd->p_state->p_visible = p_button->p_up;
00457         }
00458 
00459         if( p_button->b_range && p_osd->p_state->p_visible->b_range ) 
00460         {
00461             osd_state_t *p_temp = p_osd->p_state->p_visible->p_current_state;
00462             if( p_temp && p_temp->p_next )
00463                 p_osd->p_state->p_visible->p_current_state = p_temp->p_next;
00464         }
00465         else if( !p_osd->p_state->p_visible->b_range )
00466         {
00467             p_osd->p_state->p_visible->p_current_state =
00468                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
00469         }
00470 
00471         osd_UpdateState( p_osd->p_state, 
00472                 p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
00473                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
00474                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
00475                 p_osd->p_state->p_visible->p_current_state->p_pic );
00476         osd_SetMenuUpdate( p_osd, VLC_TRUE );
00477         /* If this is a range style action with associated images of only one state, 
00478             * then perform "menu select" on every menu navigation
00479             */
00480         if( p_button->b_range ) 
00481         {
00482             osd_SetKeyPressed( VLC_OBJECT(p_osd->p_vlc), config_GetInt(p_osd, p_button->psz_action) );
00483 #if defined(OSD_MENU_DEBUG)
00484             msg_Dbg( p_osd, "select (%d, %s)", val.i_int, p_button->psz_action );
00485 #endif
00486         }
00487     }
00488 #if defined(OSD_MENU_DEBUG)
00489     msg_Dbg( p_osd, "direction up [button %s]", p_osd->p_state->p_visible->psz_action );
00490 #endif
00491 
00492     vlc_object_release( (vlc_object_t*) p_osd );
00493     vlc_mutex_unlock( lockval.p_address );
00494 }
00495 
00496 void __osd_MenuDown( vlc_object_t *p_this )
00497 {
00498     osd_menu_t *p_osd = NULL;
00499     osd_button_t *p_button = NULL;
00500     vlc_value_t lockval;
00501 #if defined(OSD_MENU_DEBUG)
00502     vlc_value_t val;
00503 #endif
00504 
00505     if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL )
00506     {
00507         msg_Err( p_this, "osd_MenuDown failed" );
00508         return;
00509     }
00510 
00511     if( osd_isVisible( p_osd ) == VLC_FALSE )
00512     {
00513         vlc_object_release( (vlc_object_t*) p_osd );
00514         return;
00515     }
00516 
00517     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00518     vlc_mutex_lock( lockval.p_address );
00519 
00520     p_button = p_osd->p_state->p_visible;
00521     if( p_button )
00522     {
00523         if( !p_button->b_range ) 
00524         {
00525             p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT );
00526             if( p_button->p_down )
00527                 p_osd->p_state->p_visible = p_button->p_down;
00528         }
00529 
00530         if( p_button->b_range && p_osd->p_state->p_visible->b_range ) 
00531         {
00532             osd_state_t *p_temp = p_osd->p_state->p_visible->p_current_state;
00533             if( p_temp && p_temp->p_prev )
00534                 p_osd->p_state->p_visible->p_current_state = p_temp->p_prev;
00535         }
00536         else if( !p_osd->p_state->p_visible->b_range )
00537         {
00538             p_osd->p_state->p_visible->p_current_state =
00539                 osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT );
00540         }
00541 
00542         osd_UpdateState( p_osd->p_state, 
00543                 p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y,
00544                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
00545                 p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
00546                 p_osd->p_state->p_visible->p_current_state->p_pic );
00547         osd_SetMenuUpdate( p_osd, VLC_TRUE );
00548         /* If this is a range style action with associated images of only one state,
00549          * then perform "menu select" on every menu navigation
00550          */
00551         if( p_button->b_range ) 
00552         {
00553             osd_SetKeyPressed( VLC_OBJECT(p_osd->p_vlc), config_GetInt(p_osd, p_button->psz_action_down) );
00554 #if defined(OSD_MENU_DEBUG)
00555             msg_Dbg( p_osd, "select (%d, %s)", val.i_int, p_button->psz_action_down );
00556 #endif
00557         }
00558     }
00559 #if defined(OSD_MENU_DEBUG)
00560     msg_Dbg( p_osd, "direction down [button %s]", p_osd->p_state->p_visible->psz_action ); 
00561 #endif
00562 
00563     vlc_object_release( (vlc_object_t*) p_osd );
00564     vlc_mutex_unlock( lockval.p_address );
00565 }
00566 
00567 static int osd_VolumeStep( vlc_object_t *p_this, int i_volume, int i_steps )
00568 {
00569     int i_volume_step = 0;
00570 
00571     i_volume_step = config_GetInt( p_this->p_vlc, "volume-step" );
00572     return (i_volume/i_volume_step);
00573 }
00574 
00581 void __osd_Volume( vlc_object_t *p_this )
00582 {
00583     osd_menu_t *p_osd = NULL;
00584     osd_button_t *p_button = NULL;
00585     vlc_value_t lockval;
00586     int i_volume = 0;
00587     int i_steps = 0;
00588 
00589     if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL )
00590     {
00591         msg_Err( p_this, "OSD menu volume update failed" );
00592         return;
00593     }
00594 
00595     var_Get( p_this->p_libvlc, "osd_mutex", &lockval );
00596     vlc_mutex_lock( lockval.p_address );
00597 
00598     p_button = p_osd->p_state->p_volume;
00599     if( p_osd->p_state->p_volume ) 
00600         p_osd->p_state->p_visible = p_osd->p_state->p_volume;
00601     if( p_button && p_button->b_range )
00602     {
00603         /* Update the volume state images to match the current volume */
00604         i_volume = config_GetInt( p_this, "volume" );
00605         i_steps = osd_VolumeStep( p_this, i_volume, p_button->i_ranges );
00606         p_button->p_current_state = osd_VolumeStateChange( p_button->p_states, i_steps );
00607 
00608         osd_UpdateState( p_osd->p_state,
00609                 p_button->i_x, p_button->i_y,
00610                 p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch,
00611                 p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_lines,
00612                 p_button->p_current_state->p_pic );
00613         osd_SetMenuUpdate( p_osd, VLC_TRUE );
00614         osd_SetMenuVisible( p_osd, VLC_TRUE );
00615     }
00616     vlc_object_release( (vlc_object_t*) p_osd );
00617     vlc_mutex_unlock( lockval.p_address );
00618 }

Generated on Tue Dec 20 10:15:01 2005 for vlc-0.8.4a by  doxygen 1.4.2