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

osd_parser.c

00001 /*****************************************************************************
00002  * osd_parser.c - The OSD Menu  parser core code.
00003  *****************************************************************************
00004  * Copyright (C) 2005 M2X
00005  * $Id: osd_parser.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_config.h>
00032 #include <vlc_video.h>
00033 
00034 #include <vlc_keys.h>
00035 #include <vlc_image.h>
00036 #include <vlc_osd.h>
00037 
00038 
00039 #undef OSD_MENU_DEBUG
00040 
00041 /*****************************************************************************
00042  * Local prototypes
00043  *****************************************************************************/
00044 static const char *ppsz_button_states[] = { "unselect", "select", "pressed" };
00045 
00046 /* OSD Menu structure support routines */
00047 static osd_menu_t   *osd_MenuNew( osd_menu_t *, const char *, int, int );
00048 static osd_button_t *osd_ButtonNew( const char *, int, int );
00049 static osd_state_t  *osd_StateNew( vlc_object_t *, const char *, const char * );
00050 
00051 static void osd_MenuFree  ( vlc_object_t *, osd_menu_t * );
00052 static void osd_ButtonFree( vlc_object_t *, osd_button_t * );
00053 static void osd_StatesFree( vlc_object_t *, osd_state_t * );
00054 
00055 static picture_t *osd_LoadImage( vlc_object_t *, const char *);
00056 
00057 /*****************************************************************************
00058  * osd_LoadImage: loads the logo image into memory
00059  *****************************************************************************/
00060 static picture_t *osd_LoadImage( vlc_object_t *p_this, const char *psz_filename )
00061 {
00062     picture_t *p_pic = NULL;
00063     image_handler_t *p_image;
00064     video_format_t fmt_in = {0}, fmt_out = {0};
00065 
00066     fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A');
00067     p_image = image_HandlerCreate( p_this );
00068     if( p_image )
00069     {
00070         p_pic = image_ReadUrl( p_image, psz_filename, &fmt_in, &fmt_out );
00071         image_HandlerDelete( p_image );
00072 #if 0        
00073         p_pic = osd_YuvaYuvp( p_this, p_pic );
00074 #endif
00075     }
00076     else msg_Err( p_this, "unable to handle this chroma" );
00077 
00078     return p_pic;
00079 }
00080 
00081 /*****************************************************************************
00082  * Create a new Menu structure
00083  *****************************************************************************/
00084 static osd_menu_t *osd_MenuNew( osd_menu_t *p_menu, const char *psz_path, int i_x, int i_y )
00085 {
00086     if( !p_menu ) return NULL;
00087     
00088     p_menu->p_state = (osd_menu_state_t *) malloc( sizeof( osd_menu_state_t ) );
00089     if( !p_menu->p_state )
00090         msg_Err( p_menu, "memory allocation for OSD Menu state failed." );
00091 
00092     if( psz_path != NULL )
00093         p_menu->psz_path = strdup( psz_path );
00094     else
00095         p_menu->psz_path = NULL;
00096     p_menu->i_x = i_x;
00097     p_menu->i_y = i_y;
00098     
00099     return p_menu; 
00100 }
00101 
00102 /*****************************************************************************
00103  * Free the menu
00104  *****************************************************************************/
00105 static void osd_MenuFree( vlc_object_t *p_this, osd_menu_t *p_menu )
00106 {
00107     msg_Dbg( p_this, "freeing menu" );
00108     osd_ButtonFree( p_this, p_menu->p_button );
00109     p_menu->p_button = NULL;
00110     p_menu->p_last_button = NULL;
00111     if( p_menu->psz_path ) free( p_menu->psz_path );
00112     p_menu->psz_path = NULL;
00113     if( p_menu->p_state ) free( p_menu->p_state );
00114     p_menu->p_state = NULL;
00115 }
00116 
00117 /*****************************************************************************
00118  * Create a new button
00119  *****************************************************************************/
00120 static osd_button_t *osd_ButtonNew( const char *psz_action, int i_x, int i_y )
00121 {
00122     osd_button_t *p_button = NULL;
00123     p_button = (osd_button_t*) malloc( sizeof(osd_button_t) );
00124     if( !p_button )
00125         return NULL;
00126     
00127     memset( p_button, 0, sizeof(osd_button_t) );
00128     p_button->psz_action = strdup(psz_action);
00129     p_button->psz_action_down = NULL;
00130     p_button->p_feedback = NULL;
00131     p_button->i_x = i_x;
00132     p_button->i_y = i_y;
00133     
00134     return p_button;
00135 }
00136 
00137 /*****************************************************************************
00138  * Free a button
00139  *****************************************************************************/ 
00140 static void osd_ButtonFree( vlc_object_t *p_this, osd_button_t *p_button )
00141 {
00142     osd_button_t *p_current = p_button;
00143     osd_button_t *p_next = NULL;
00144     osd_button_t *p_prev = NULL;
00145     
00146     /* First walk to the end. */
00147     while( p_current->p_next )
00148     {
00149         p_next = p_current->p_next;
00150         p_current = p_next;        
00151     }
00152     /* Then free end first and walk to the start. */
00153     while( p_current->p_prev )
00154     {
00155         msg_Dbg( p_this, "+ freeing button %s [%p]", p_current->psz_action, p_current );
00156         p_prev = p_current->p_prev;
00157         p_current = p_prev;
00158         if( p_current->p_next )
00159         {
00160             if( p_current->p_next->psz_name ) 
00161                 free( p_current->p_next->psz_name );
00162             if( p_current->p_next->psz_action )
00163                 free( p_current->p_next->psz_action );
00164             if( p_current->p_next->psz_action_down )
00165                 free( p_current->p_next->psz_action_down );
00166             if( p_current->p_feedback && p_current->p_feedback->p_data_orig )
00167                 free( p_current->p_feedback->p_data_orig );
00168             if( p_current->p_feedback )
00169                 free( p_current->p_feedback );
00170             
00171             p_current->p_next->psz_action_down = NULL;
00172             p_current->p_next->psz_action = NULL;
00173             p_current->p_next->psz_name = NULL;
00174             p_current->p_feedback = NULL;
00175                             
00176             /* Free all states first */            
00177             if( p_current->p_next->p_states )   
00178                 osd_StatesFree( p_this, p_current->p_next->p_states );
00179             p_current->p_next->p_states = NULL;          
00180             if( p_current->p_next) free( p_current->p_next );
00181             p_current->p_next = NULL;  
00182         }            
00183         
00184         if( p_current->p_up )
00185         {
00186             if( p_current->p_up->psz_name ) 
00187                 free( p_current->p_up->psz_name );
00188             if( p_current->p_up->psz_action )
00189                 free( p_current->p_up->psz_action );
00190             if( p_current->p_up->psz_action_down )
00191                 free( p_current->p_up->psz_action_down );
00192             if( p_current->p_feedback && p_current->p_feedback->p_data_orig )
00193                 free( p_current->p_feedback->p_data_orig );
00194             if( p_current->p_feedback )
00195                 free( p_current->p_feedback );
00196             
00197             p_current->p_up->psz_action_down = NULL;
00198             p_current->p_up->psz_action = NULL;
00199             p_current->p_up->psz_name = NULL;
00200             p_current->p_feedback = NULL;
00201             
00202             /* Free all states first */            
00203             if( p_current->p_up->p_states )   
00204                 osd_StatesFree( p_this, p_current->p_up->p_states );
00205             p_current->p_up->p_states = NULL;          
00206             if( p_current->p_up ) free( p_current->p_up );
00207             p_current->p_up = NULL;          
00208         }
00209     }    
00210     /* Free the last one. */
00211     if( p_button ) 
00212     {
00213         msg_Dbg( p_this, "+ freeing button %s [%p]", p_button->psz_action, p_button );    
00214         if( p_button->psz_name ) free( p_button->psz_name );
00215         if( p_button->psz_action ) free( p_button->psz_action );
00216         if( p_button->psz_action_down ) free( p_button->psz_action_down );   
00217         if( p_current->p_feedback && p_current->p_feedback->p_data_orig )
00218             free( p_current->p_feedback->p_data_orig );
00219         if( p_current->p_feedback )
00220             free( p_current->p_feedback );
00221         
00222         p_button->psz_name = NULL;
00223         p_button->psz_action = NULL;
00224         p_button->psz_action_down = NULL;
00225         p_current->p_feedback = NULL;
00226                 
00227         if( p_button->p_states )
00228             osd_StatesFree( p_this, p_button->p_states );
00229         p_button->p_states = NULL;          
00230         free( p_button );
00231         p_button = NULL;
00232     }
00233 }
00234 
00235 /*****************************************************************************
00236  * Create a new state image
00237  *****************************************************************************/
00238 static osd_state_t *osd_StateNew( vlc_object_t *p_this, const char *psz_file, const char *psz_state )
00239 {
00240     osd_state_t *p_state = NULL;
00241     p_state = (osd_state_t*) malloc( sizeof(osd_state_t) );
00242     if( !p_state )
00243         return NULL;
00244         
00245     memset( p_state, 0, sizeof(osd_state_t) );    
00246     p_state->p_pic = osd_LoadImage( p_this, psz_file );
00247 
00248     if( psz_state )
00249     {
00250         p_state->psz_state = strdup( psz_state );
00251         if( strncmp( ppsz_button_states[0], psz_state, strlen(ppsz_button_states[0]) ) == 0 )
00252             p_state->i_state = OSD_BUTTON_UNSELECT;
00253         else if( strncmp( ppsz_button_states[1], psz_state, strlen(ppsz_button_states[1]) ) == 0 )
00254             p_state->i_state = OSD_BUTTON_SELECT;
00255         else if( strncmp( ppsz_button_states[2], psz_state, strlen(ppsz_button_states[2]) ) == 0 )
00256             p_state->i_state = OSD_BUTTON_PRESSED;
00257     }
00258     return p_state;
00259 }
00260 
00261 /*****************************************************************************
00262  * Free state images
00263  *****************************************************************************/
00264 static void osd_StatesFree( vlc_object_t *p_this, osd_state_t *p_states )
00265 {
00266     osd_state_t *p_state = p_states;
00267     osd_state_t *p_next = NULL;
00268     osd_state_t *p_prev = NULL;
00269     
00270     while( p_state->p_next )
00271     {
00272         p_next = p_state->p_next;
00273         p_state = p_next;
00274     }
00275     /* Then free end first and walk to the start. */
00276     while( p_state->p_prev )
00277     {
00278         msg_Dbg( p_this, " |- freeing state %s [%p]", p_state->psz_state, p_state );
00279         p_prev = p_state->p_prev;
00280         p_state = p_prev;
00281         if( p_state->p_next )
00282         {
00283             if( p_state->p_next->p_pic && p_state->p_next->p_pic->p_data_orig )
00284                 free( p_state->p_next->p_pic->p_data_orig );
00285             if( p_state->p_next->p_pic ) free( p_state->p_next->p_pic );
00286             p_state->p_next->p_pic = NULL;      
00287             if( p_state->p_next->psz_state ) free( p_state->p_next->psz_state );
00288             p_state->p_next->psz_state = NULL;
00289             free( p_state->p_next );
00290             p_state->p_next = NULL;        
00291         }
00292     }
00293     /* Free the last one. */
00294     if( p_states )
00295     {
00296         msg_Dbg( p_this, " |- freeing state %s [%p]", p_state->psz_state, p_states );
00297         if( p_states->p_pic && p_states->p_pic->p_data_orig )
00298             free( p_states->p_pic->p_data_orig );
00299         if( p_states->p_pic ) free( p_states->p_pic );
00300         p_states->p_pic = NULL;
00301         if( p_state->psz_state ) free( p_state->psz_state );
00302         p_state->psz_state = NULL;
00303         free( p_states );
00304         p_states = NULL;
00305     }
00306 }
00307 
00308 /*****************************************************************************
00309  * osd_ConfigLoader: Load and parse osd text configurationfile
00310  *****************************************************************************/
00311 int osd_ConfigLoader( vlc_object_t *p_this, const char *psz_file,
00312     osd_menu_t **p_menu )
00313 {
00314     osd_button_t   *p_current = NULL; /* button currently processed */
00315     osd_button_t   *p_prev = NULL;    /* previous processed button */ 
00316 
00317 #define MAX_FILE_PATH 256    
00318     FILE       *fd = NULL;
00319     int        result = 0;
00320     
00321     msg_Dbg( p_this, "opening osd definition file %s", psz_file );
00322     fd = fopen( psz_file, "r" );
00323     if( !fd )  
00324     {
00325         msg_Err( p_this, "failed opening osd definition file %s", psz_file );
00326         return VLC_EGENERIC;
00327     }
00328     
00329     /* Read first line */    
00330     if( !feof( fd ) )
00331     {
00332         char action[25] = "";
00333         char path[MAX_FILE_PATH] = "";
00334         char *psz_path = NULL;
00335         size_t i_len = 0;
00336 
00337         /* override images path ? */
00338         psz_path = config_GetPsz( p_this, "osdmenu-file-path" );
00339         if( psz_path == NULL )
00340         {                                    
00341             result = fscanf(fd, "%24s %255s", &action[0], &path[0] );
00342         }
00343         else
00344         {
00345             /* psz_path is not null and therefor &path[0] cannot be NULL 
00346              * it might be null terminated.
00347              */
00348             strncpy( &path[0], psz_path, MAX_FILE_PATH );
00349             free( psz_path );
00350             psz_path = NULL;
00351         }
00352         /* NULL terminate before asking the length of path[] */
00353         path[MAX_FILE_PATH-1] = '\0';
00354         i_len = strlen(&path[0]);
00355         if( i_len == MAX_FILE_PATH )
00356             i_len--; /* truncate to prevent buffer overflow */
00357 #if defined(WIN32) || defined(UNDER_CE)
00358         if( (i_len > 0) && path[i_len] != '\\' )
00359             path[i_len] = '\\';
00360 #else        
00361         if( (i_len > 0) && path[i_len] != '/' )
00362             path[i_len] = '/';
00363 #endif
00364         path[i_len+1] = '\0';
00365         if( result == 0 || result == EOF )
00366             goto error;                        
00367         msg_Dbg( p_this, "%s=%s", &action[0], &path[0] );
00368          
00369         if( i_len == 0 )
00370             *p_menu = osd_MenuNew( *p_menu, NULL, 0, 0 );
00371         else
00372             *p_menu = osd_MenuNew( *p_menu, &path[0], 0, 0 );
00373     }
00374     
00375     if( !*p_menu )
00376         goto error;
00377         
00378     /* read successive lines */
00379     while( !feof( fd ) )
00380     {   
00381         osd_state_t   *p_state_current = NULL; /* button state currently processed */
00382         osd_state_t   *p_state_prev = NULL;    /* previous state processed button */ 
00383         
00384         char cmd[25] = "";      
00385         char action[25] = "";
00386         char state[25]  = "";
00387         char file[256]  = "";
00388         char path[512]  = "";        
00389         int  i_x = 0;
00390         int  i_y = 0;
00391 
00392         result = fscanf( fd, "%24s %24s (%d,%d)", &cmd[0], &action[0], &i_x, &i_y );
00393         if( result == 0 )
00394             goto error;              
00395         if( strncmp( &cmd[0], "action", 6 ) != 0 )
00396             break;
00397         msg_Dbg( p_this, " + %s hotkey=%s (%d,%d)", &cmd[0], &action[0], i_x, i_y );                    
00398                 
00399         p_prev = p_current;
00400         p_current = osd_ButtonNew( &action[0], i_x, i_y );   
00401         if( !p_current )
00402             goto error;
00403         
00404         if( p_prev )
00405             p_prev->p_next = p_current;            
00406         else
00407             (*p_menu)->p_button = p_current;            
00408         p_current->p_prev = p_prev;
00409         
00410         /* parse all states */
00411         while( !feof( fd ) )
00412         {
00413             char type[25] = "";
00414             
00415             result = fscanf( fd, "\t%24s", &state[0] );   
00416             if( result == 0 )
00417                 goto error;
00418             
00419             /* FIXME: We only parse one level deep now */    
00420             if( strncmp( &state[0], "action", 6 ) == 0 )
00421             {
00422                 osd_button_t   *p_up = NULL;
00423                 
00424                 result = fscanf( fd, "%24s (%d,%d)", &action[0], &i_x, &i_y );
00425                 if( result == 0 )
00426                     goto error;
00427                 /* create new button */                
00428                 p_up = osd_ButtonNew( &action[0], i_x, i_y );                 
00429                 if( !p_up ) 
00430                     goto error;
00431                 /* Link to list */                    
00432                 p_up->p_down = p_current;
00433                 p_current->p_up = p_up;                 
00434                 msg_Dbg( p_this, " + (menu up) hotkey=%s (%d,%d)", &action[0], i_x, i_y );
00435                 /* Parse type state */
00436                 result = fscanf( fd, "\t%24s %24s", &cmd[0], &type[0] );   
00437                 if( result == 0 )
00438                     goto error;
00439                 if( strncmp( &cmd[0], "type", 4 ) == 0 )
00440                 {  
00441                     if( strncmp( &type[0], "volume", 6 ) == 0 )
00442                     {
00443                         (*p_menu)->p_state->p_volume = p_up;
00444                         msg_Dbg( p_this, " + type=%s", &type[0] );
00445                     }
00446                 }
00447                 /* Parse range state */
00448                 result = fscanf( fd, "\t%24s", &state[0] );   
00449                 if( result == 0 )
00450                     goto error;
00451                 /* Parse the range state */        
00452                 if( strncmp( &state[0], "range", 5 ) == 0 )
00453                 {
00454                     osd_state_t   *p_range_current = NULL; /* range state currently processed */
00455                     osd_state_t   *p_range_prev = NULL;    /* previous state processed range */ 
00456                     int i_index = 0;
00457                                                             
00458                     p_up->b_range = VLC_TRUE;
00459     
00460                     result = fscanf( fd, "\t%24s", &action[0] );   
00461                     if( result == 0 )
00462                         goto error;
00463                     
00464                     result = fscanf( fd, "\t%d", &i_index );   
00465                     if( result == 0 )
00466                         goto error;
00467                                                                                             
00468                     msg_Dbg( p_this, " + (menu up) hotkey down %s, file=%s%s", &action[0], (*p_menu)->psz_path, &file[0] );
00469                     
00470                     if( p_up->psz_action_down ) free( p_up->psz_action_down );
00471                     p_up->psz_action_down = strdup( &action[0] );                     
00472                     
00473                     /* Parse range contstruction :
00474                      * range <hotkey> 
00475                      *      <state1> <file1>
00476                      *
00477                      *      <stateN> <fileN>
00478                      * end 
00479                      */                
00480                     while( !feof( fd ) )
00481                     {
00482                         result = fscanf( fd, "\t%255s", &file[0] );   
00483                         if( result == 0 )
00484                             goto error;
00485                         if( strncmp( &file[0], "end", 3 ) == 0 )
00486                             break;
00487                         
00488                         p_range_prev = p_range_current;
00489             
00490                         if( (*p_menu)->psz_path )
00491                         {
00492                             size_t i_path_size = strlen( (*p_menu)->psz_path );
00493                             size_t i_file_size = strlen( &file[0] );
00494                             
00495                             strncpy( &path[0], (*p_menu)->psz_path, i_path_size );
00496                             strncpy( &path[i_path_size], &file[0], 512 - (i_path_size + i_file_size) );
00497                             path[ i_path_size + i_file_size ] = '\0';
00498                             
00499                             p_range_current = osd_StateNew( p_this, &path[0], "pressed" );
00500                         }
00501                         else /* absolute paths are used. */
00502                             p_range_current = osd_StateNew( p_this, &file[0], "pressed" );
00503                             
00504                         if( !p_range_current || !p_range_current->p_pic )
00505                             goto error;
00506                             
00507                         /* increment the number of ranges for this button */                
00508                         p_up->i_ranges++;
00509                         
00510                         if( p_range_prev )
00511                             p_range_prev->p_next = p_range_current;
00512                         else
00513                             p_up->p_states = p_range_current;                                
00514                         p_range_current->p_prev = p_range_prev;
00515                         
00516                         msg_Dbg( p_this, "  |- range=%d, file=%s%s", 
00517                                 p_up->i_ranges, 
00518                                 (*p_menu)->psz_path, &file[0] );                        
00519                     }
00520                     if( i_index > 0 )
00521                     { 
00522                         osd_state_t *p_range = NULL;
00523                         
00524                         /* Find the default index for state range */                        
00525                         p_range = p_up->p_states;
00526                         while( (--i_index > 0) && p_range->p_next )
00527                         {
00528                             osd_state_t *p_temp = NULL;
00529                             p_temp = p_range->p_next;
00530                             p_range = p_temp;
00531                         }
00532                         p_up->p_current_state = p_range;
00533                     }                    
00534                     else p_up->p_current_state = p_up->p_states;
00535                     
00536                 }   
00537                 result = fscanf( fd, "\t%24s", &state[0] );   
00538                 if( result == 0 )
00539                     goto error;                    
00540                 if( strncmp( &state[0], "end", 3 ) != 0 )
00541                     goto error;
00542                     
00543                 /* Continue at the beginning of the while() */
00544                 continue;
00545             }
00546             
00547             /* Parse the range state */        
00548             if( strncmp( &state[0], "range", 5 ) == 0 )
00549             {
00550                 osd_state_t   *p_range_current = NULL; /* range state currently processed */
00551                 osd_state_t   *p_range_prev = NULL;    /* previous state processed range */ 
00552                 int i_index = 0;
00553                                                         
00554                 p_current->b_range = VLC_TRUE;
00555 
00556                 result = fscanf( fd, "\t%24s", &action[0] );   
00557                 if( result == 0 )
00558                     goto error;
00559                 
00560                 result = fscanf( fd, "\t%d", &i_index );   
00561                 if( result == 0 )
00562                     goto error;
00563                                                                                         
00564                 msg_Dbg( p_this, " + hotkey down %s, file=%s%s", &action[0], (*p_menu)->psz_path, &file[0] );                        
00565                 if( p_current->psz_action_down ) free( p_current->psz_action_down );
00566                 p_current->psz_action_down = strdup( &action[0] );                     
00567                 
00568                 /* Parse range contstruction :
00569                  * range <hotkey> 
00570                  *      <state1> <file1>
00571                  *
00572                  *      <stateN> <fileN>
00573                  * end 
00574                  */                
00575                 while( !feof( fd ) )
00576                 {
00577                     result = fscanf( fd, "\t%255s", &file[0] );   
00578                     if( result == 0 )
00579                         goto error;
00580                     if( strncmp( &file[0], "end", 3 ) == 0 )
00581                         break;
00582                     
00583                     p_range_prev = p_range_current;
00584         
00585                     if( (*p_menu)->psz_path )
00586                     {
00587                         size_t i_path_size = strlen( (*p_menu)->psz_path );
00588                         size_t i_file_size = strlen( &file[0] );
00589                         
00590                         strncpy( &path[0], (*p_menu)->psz_path, i_path_size );
00591                         strncpy( &path[i_path_size], &file[0], 512 - (i_path_size + i_file_size) );
00592                         path[ i_path_size + i_file_size ] = '\0';
00593                         
00594                         p_range_current = osd_StateNew( p_this, &path[0], "pressed" );
00595                     }
00596                     else /* absolute paths are used. */
00597                         p_range_current = osd_StateNew( p_this, &file[0], "pressed" );
00598                         
00599                     if( !p_range_current || !p_range_current->p_pic )
00600                         goto error;
00601                         
00602                     /* increment the number of ranges for this button */                
00603                     p_current->i_ranges++;
00604                     
00605                     if( p_range_prev )
00606                         p_range_prev->p_next = p_range_current;
00607                     else
00608                         p_current->p_states = p_range_current;                                
00609                     p_range_current->p_prev = p_range_prev;
00610                     
00611                     msg_Dbg( p_this, "  |- range=%d, file=%s%s", 
00612                             p_current->i_ranges, 
00613                             (*p_menu)->psz_path, &file[0] );                        
00614                 }
00615                 if( i_index > 0 )
00616                 {             
00617                     osd_state_t *p_range = NULL;
00618                        
00619                     /* Find the default index for state range */                        
00620                     p_range = p_current->p_states;
00621                     while( (--i_index > 0) && p_range->p_next )
00622                     {
00623                         osd_state_t *p_temp = NULL;
00624                         p_temp = p_range->p_next;
00625                         p_range = p_temp;
00626                     }
00627                     p_current->p_current_state = p_range;
00628                 }                    
00629                 else p_current->p_current_state = p_current->p_states;
00630                 /* Continue at the beginning of the while() */
00631                 continue;
00632             }   
00633             if( strncmp( &state[0], "end", 3 ) == 0 )
00634                 break;
00635                 
00636             result = fscanf( fd, "\t%255s", &file[0] );   
00637             if( result == 0 )
00638                 goto error;                                
00639             
00640             p_state_prev = p_state_current;
00641 
00642             if( ( strncmp( ppsz_button_states[0], &state[0], strlen(ppsz_button_states[0]) ) != 0 ) &&
00643                 ( strncmp( ppsz_button_states[1], &state[0], strlen(ppsz_button_states[1]) ) != 0 ) &&
00644                 ( strncmp( ppsz_button_states[2], &state[0], strlen(ppsz_button_states[2]) ) != 0 ) )
00645             {
00646                 msg_Err( p_this, "invalid button state %s for button %s expected %d: unselect, select or pressed)",
00647                                     &state[0], &action[0], strlen(&state[0]));
00648                 goto error;
00649             }
00650             
00651             if( (*p_menu)->psz_path )
00652             {
00653                 size_t i_path_size = strlen( (*p_menu)->psz_path );
00654                 size_t i_file_size = strlen( &file[0] );
00655                 
00656                 strncpy( &path[0], (*p_menu)->psz_path, i_path_size );
00657                 strncpy( &path[i_path_size], &file[0], 512 - (i_path_size + i_file_size) );
00658                 path[ i_path_size + i_file_size ] = '\0';
00659                 
00660                 p_state_current = osd_StateNew( p_this, &path[0], &state[0] );
00661             }
00662             else /* absolute paths are used. */
00663                 p_state_current = osd_StateNew( p_this, &file[0], &state[0] );
00664                 
00665             if( !p_state_current || !p_state_current->p_pic )
00666                 goto error;
00667                 
00668             if( p_state_prev )
00669                 p_state_prev->p_next = p_state_current;
00670             else
00671                 p_current->p_states = p_state_current;                                
00672             p_state_current->p_prev = p_state_prev;
00673             
00674             msg_Dbg( p_this, " |- state=%s, file=%s%s", &state[0], (*p_menu)->psz_path, &file[0] );
00675         }
00676         p_current->p_current_state = p_current->p_states;
00677     }
00678 
00679     /* Find the last button and store its pointer. 
00680      * The OSD menu behaves like a roundrobin list.
00681      */        
00682     p_current = (*p_menu)->p_button;
00683     while( p_current && p_current->p_next )
00684     {
00685         osd_button_t *p_temp = NULL;
00686         p_temp = p_current->p_next;
00687         p_current = p_temp;
00688     }
00689     (*p_menu)->p_last_button = p_current;
00690     fclose( fd );
00691     return 0;
00692     
00693 #undef MAX_FILE_PATH 
00694 error:
00695     msg_Err( p_this, "parsing file failed (returned %d)", result );
00696     fclose( fd );
00697     return 1;        
00698 }
00699 
00700 /*****************************************************************************
00701  * osd_ConfigUnload: Load and parse osd text configurationfile
00702  *****************************************************************************/
00703 void osd_ConfigUnload( vlc_object_t *p_this, osd_menu_t **p_osd)
00704 {
00705     msg_Dbg( p_this, "unloading OSD menu structure" );
00706     osd_MenuFree( p_this, *p_osd );
00707 }

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