]> git.sesse.net Git - vlc/blob - modules/misc/osd/osd_menu.c
xml_ReaderUseDTD: remove useless parameter
[vlc] / modules / misc / osd / osd_menu.c
1 /*****************************************************************************
2  * parser.c : OSD import module
3  *****************************************************************************
4  * Copyright (C) 2007-2008 M2X
5  * $Id$
6  *
7  * Authors: Jean-Paul Saman
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33 #include <vlc_image.h>
34 #include <vlc_osd.h>
35
36 #include "osd_menu.h"
37
38 #undef OSD_MENU_DEBUG
39
40 const char * const ppsz_button_states[] = { "unselect", "select", "pressed" };
41
42 /*****************************************************************************
43  * Local prototypes
44  *****************************************************************************/
45
46 /*****************************************************************************
47  * Create a new Menu structure
48  *****************************************************************************/
49 osd_menu_t *osd_MenuNew( osd_menu_t *p_menu, const char *psz_path,
50                          int i_x, int i_y )
51 {
52     if( !p_menu ) return NULL;
53
54     p_menu->p_state = calloc( 1, sizeof( osd_menu_state_t ) );
55     if( !p_menu->p_state )
56         return NULL;
57
58     p_menu->psz_path = psz_path ? strdup( psz_path ) : NULL;
59     p_menu->i_x = i_x;
60     p_menu->i_y = i_y;
61     p_menu->i_style = OSD_MENU_STYLE_SIMPLE;
62
63     return p_menu;
64 }
65
66 /*****************************************************************************
67  * Free the menu
68  *****************************************************************************/
69 void osd_MenuFree( osd_menu_t *p_menu )
70 {
71     msg_Dbg( p_menu, "freeing menu" );
72     osd_ButtonFree( p_menu, p_menu->p_button );
73
74     free( p_menu->psz_path );
75     free( p_menu->p_state );
76
77     p_menu->p_button = NULL;
78     p_menu->p_last_button = NULL;
79     p_menu->psz_path = NULL;
80     p_menu->p_state = NULL;
81 }
82
83 /*****************************************************************************
84  * Create a new button
85  *****************************************************************************/
86 osd_button_t *osd_ButtonNew( const char *psz_action, int i_x, int i_y )
87 {
88     osd_button_t *p_button = NULL;
89     p_button = calloc( 1, sizeof(osd_button_t) );
90     if( !p_button )
91         return NULL;
92
93     p_button->psz_action = strdup(psz_action);
94     p_button->psz_action_down = NULL;
95     p_button->p_feedback = NULL;
96     p_button->i_x = i_x;
97     p_button->i_y = i_y;
98
99     return p_button;
100 }
101
102 /*****************************************************************************
103  * Free a button
104  *****************************************************************************/
105 void osd_ButtonFree( osd_menu_t *p_menu, osd_button_t *p_button )
106 {
107     osd_button_t *p_current = p_button;
108     osd_button_t *p_next = NULL;
109     osd_button_t *p_prev = NULL;
110
111     if( !p_current ) return;
112
113     /* First walk to the end. */
114     while( p_current->p_next )
115     {
116         p_next = p_current->p_next;
117         p_current = p_next;
118     }
119     /* Then free end first and walk to the start. */
120     while( p_current->p_prev )
121     {
122         msg_Dbg( p_menu, "+ freeing button %s [%p]",
123                  p_current->psz_action, p_current );
124         p_prev = p_current->p_prev;
125         p_current = p_prev;
126         if( p_current->p_next )
127         {
128             free( p_current->p_next->psz_name );
129             free( p_current->p_next->psz_action );
130             free( p_current->p_next->psz_action_down );
131             if( p_current->p_feedback )
132             {
133                 free( p_current->p_feedback->p_data_orig );
134                 free( p_current->p_feedback );
135                 p_current->p_feedback = NULL;
136             }
137
138             /* Free all states first */
139             if( p_current->p_next->p_states )
140                 osd_StatesFree( p_menu, p_current->p_next->p_states );
141
142             free( p_current->p_next );
143             p_current->p_next = NULL;
144         }
145
146         if( p_current->p_up )
147         {
148             free( p_current->p_up->psz_name );
149             free( p_current->p_up->psz_action );
150             free( p_current->p_up->psz_action_down );
151             if( p_current->p_feedback )
152             {
153                 free( p_current->p_feedback->p_data_orig );
154                 free( p_current->p_feedback );
155             }
156
157             p_current->p_feedback = NULL;
158
159             /* Free all states first */
160             if( p_current->p_up->p_states )
161                 osd_StatesFree( p_menu, p_current->p_up->p_states );
162             free( p_current->p_up );
163             p_current->p_up = NULL;
164         }
165     }
166     /* Free the last one. */
167     if( p_button )
168     {
169         msg_Dbg( p_menu, "+ freeing button %s [%p]",
170                  p_button->psz_action, p_button );
171         free( p_button->psz_name );
172         free( p_button->psz_action );
173         free( p_button->psz_action_down );
174         if( p_current->p_feedback )
175         {
176             free( p_current->p_feedback->p_data_orig );
177             free( p_current->p_feedback );
178             p_current->p_feedback = NULL;
179         }
180
181         if( p_button->p_states )
182             osd_StatesFree( p_menu, p_button->p_states );
183
184         free( p_button );
185     }
186 }
187
188 /*****************************************************************************
189  * Create a new state image
190  *****************************************************************************/
191 osd_state_t *osd_StateNew( osd_menu_t *p_menu, const char *psz_file,
192                            const char *psz_state )
193 {
194     osd_state_t *p_state = NULL;
195     video_format_t fmt_in, fmt_out;
196
197     p_state = calloc( 1, sizeof(osd_state_t) );
198     if( !p_state )
199         return NULL;
200
201     memset( &fmt_in, 0, sizeof(video_format_t) );
202     memset( &fmt_out, 0, sizeof(video_format_t) );
203
204     fmt_out.i_chroma = VLC_CODEC_YUVA;
205     if( p_menu->p_image )
206     {
207         p_state->p_pic = image_ReadUrl( p_menu->p_image, psz_file,
208                                         &fmt_in, &fmt_out );
209         if( p_state->p_pic )
210         {
211             p_state->i_width  = p_state->p_pic->p[Y_PLANE].i_visible_pitch;
212             p_state->i_height = p_state->p_pic->p[Y_PLANE].i_visible_lines;
213         }
214     }
215
216     if( psz_state )
217     {
218         p_state->psz_state = strdup( psz_state );
219         if( strncmp( ppsz_button_states[0], psz_state,
220                      strlen(ppsz_button_states[0]) ) == 0 )
221             p_state->i_state = OSD_BUTTON_UNSELECT;
222         else if( strncmp( ppsz_button_states[1], psz_state,
223                           strlen(ppsz_button_states[1]) ) == 0 )
224             p_state->i_state = OSD_BUTTON_SELECT;
225         else if( strncmp( ppsz_button_states[2], psz_state,
226                           strlen(ppsz_button_states[2]) ) == 0 )
227             p_state->i_state = OSD_BUTTON_PRESSED;
228     }
229     return p_state;
230 }
231
232 /*****************************************************************************
233  * Free state images
234  *****************************************************************************/
235 void osd_StatesFree( osd_menu_t *p_menu, osd_state_t *p_states )
236 {
237     osd_state_t *p_state = p_states;
238     osd_state_t *p_next = NULL;
239     osd_state_t *p_prev = NULL;
240
241     if( !p_state ) return;
242
243     while( p_state->p_next )
244     {
245         p_next = p_state->p_next;
246         p_state = p_next;
247     }
248     /* Then free end first and walk to the start. */
249     while( p_state->p_prev )
250     {
251         msg_Dbg( p_menu, " |- freeing state %s [%p]",
252                  p_state->psz_state, p_state );
253         p_prev = p_state->p_prev;
254         p_state = p_prev;
255         if( p_state->p_next )
256         {
257             if( p_state->p_next->p_pic )
258             {
259                 free( p_state->p_next->p_pic->p_data_orig );
260                 free( p_state->p_next->p_pic );
261             }
262             free( p_state->p_next->psz_state );
263             free( p_state->p_next );
264             p_state->p_next = NULL;
265         }
266     }
267     /* Free the last one. */
268     if( p_states )
269     {
270         msg_Dbg( p_menu, " |- freeing state %s [%p]",
271                  p_state->psz_state, p_states );
272         if( p_states->p_pic )
273         {
274             free( p_states->p_pic->p_data_orig );
275             free( p_states->p_pic );
276         }
277         free( p_state->psz_state );
278         free( p_states );
279     }
280 }
281