]> git.sesse.net Git - vlc/blob - modules/misc/osd/osd_menu.c
Fix merge conflicts for src/osd/osd.c
[vlc] / modules / misc / osd / osd_menu.c
1 /*****************************************************************************
2  * parser.c :  OSD import module
3  *****************************************************************************
4  * Copyright (C) 2007 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 #include <vlc/vlc.h>
29 #include <vlc_vout.h>
30 #include <vlc_config.h>
31
32 #include <vlc_keys.h>
33 #include <vlc_image.h>
34 #include <vlc_osd.h>
35 #include <vlc_charset.h>
36
37 #include "osd_menu.h"
38
39 #undef OSD_MENU_DEBUG
40
41 /*****************************************************************************
42  * Local prototypes
43  *****************************************************************************/
44 static const char *ppsz_button_states[] = { "unselect", "select", "pressed" };
45
46 /*****************************************************************************
47  * Create a new Menu structure
48  *****************************************************************************/
49 osd_menu_t *osd_MenuNew( osd_menu_t *p_menu, const char *psz_path, int i_x, int i_y )
50 {
51     if( !p_menu ) return NULL;
52
53     p_menu->p_state = (osd_menu_state_t *) malloc( sizeof( osd_menu_state_t ) );
54     if( !p_menu->p_state )
55     {
56         msg_Err( p_menu, "Memory allocation for OSD Menu state failed" );
57         return NULL;
58     }
59
60     memset(p_menu->p_state, 0, sizeof(osd_menu_state_t));
61     if( psz_path != NULL )
62         p_menu->psz_path = strdup( psz_path );
63     else
64         p_menu->psz_path = NULL;
65     p_menu->i_x = i_x;
66     p_menu->i_y = i_y;
67     p_menu->i_style = OSD_MENU_STYLE_SIMPLE;
68
69     return p_menu;
70 }
71
72 /*****************************************************************************
73  * Free the menu
74  *****************************************************************************/
75 void osd_MenuFree( vlc_object_t *p_this, osd_menu_t *p_menu )
76 {
77     msg_Dbg( p_this, "freeing menu" );
78     osd_ButtonFree( p_this, p_menu->p_button );
79     p_menu->p_button = NULL;
80     p_menu->p_last_button = NULL;
81     if( p_menu->psz_path ) free( p_menu->psz_path );
82     p_menu->psz_path = NULL;
83     if( p_menu->p_state ) free( p_menu->p_state );
84     p_menu->p_state = NULL;
85 }
86
87 /*****************************************************************************
88  * Create a new button
89  *****************************************************************************/
90 osd_button_t *osd_ButtonNew( const char *psz_action, int i_x, int i_y )
91 {
92     osd_button_t *p_button = NULL;
93     p_button = (osd_button_t*) malloc( sizeof(osd_button_t) );
94     if( !p_button )
95         return NULL;
96
97     memset( p_button, 0, sizeof(osd_button_t) );
98     p_button->psz_action = strdup(psz_action);
99     p_button->psz_action_down = NULL;
100     p_button->p_feedback = NULL;
101     p_button->i_x = i_x;
102     p_button->i_y = i_y;
103
104     return p_button;
105 }
106
107 /*****************************************************************************
108  * Free a button
109  *****************************************************************************/
110 void osd_ButtonFree( vlc_object_t *p_this, osd_button_t *p_button )
111 {
112     osd_button_t *p_current = p_button;
113     osd_button_t *p_next = NULL;
114     osd_button_t *p_prev = NULL;
115
116     /* First walk to the end. */
117     while( p_current->p_next )
118     {
119         p_next = p_current->p_next;
120         p_current = p_next;
121     }
122     /* Then free end first and walk to the start. */
123     while( p_current->p_prev )
124     {
125         msg_Dbg( p_this, "+ freeing button %s [%p]", p_current->psz_action, p_current );
126         p_prev = p_current->p_prev;
127         p_current = p_prev;
128         if( p_current->p_next )
129         {
130             if( p_current->p_next->psz_name )
131                 free( p_current->p_next->psz_name );
132             if( p_current->p_next->psz_action )
133                 free( p_current->p_next->psz_action );
134             if( p_current->p_next->psz_action_down )
135                 free( p_current->p_next->psz_action_down );
136             if( p_current->p_feedback && p_current->p_feedback->p_data_orig )
137                 free( p_current->p_feedback->p_data_orig );
138             if( p_current->p_feedback )
139                 free( p_current->p_feedback );
140
141             p_current->p_next->psz_action_down = NULL;
142             p_current->p_next->psz_action = NULL;
143             p_current->p_next->psz_name = NULL;
144             p_current->p_feedback = NULL;
145
146             /* Free all states first */
147             if( p_current->p_next->p_states )
148                 osd_StatesFree( p_this, p_current->p_next->p_states );
149             p_current->p_next->p_states = NULL;
150             if( p_current->p_next) free( p_current->p_next );
151             p_current->p_next = NULL;
152         }
153
154         if( p_current->p_up )
155         {
156             if( p_current->p_up->psz_name )
157                 free( p_current->p_up->psz_name );
158             if( p_current->p_up->psz_action )
159                 free( p_current->p_up->psz_action );
160             if( p_current->p_up->psz_action_down )
161                 free( p_current->p_up->psz_action_down );
162             if( p_current->p_feedback && p_current->p_feedback->p_data_orig )
163                 free( p_current->p_feedback->p_data_orig );
164             if( p_current->p_feedback )
165                 free( p_current->p_feedback );
166
167             p_current->p_up->psz_action_down = NULL;
168             p_current->p_up->psz_action = NULL;
169             p_current->p_up->psz_name = NULL;
170             p_current->p_feedback = NULL;
171
172             /* Free all states first */
173             if( p_current->p_up->p_states )
174                 osd_StatesFree( p_this, p_current->p_up->p_states );
175             p_current->p_up->p_states = NULL;
176             if( p_current->p_up ) free( p_current->p_up );
177             p_current->p_up = NULL;
178         }
179     }
180     /* Free the last one. */
181     if( p_button )
182     {
183         msg_Dbg( p_this, "+ freeing button %s [%p]", p_button->psz_action, p_button );
184         if( p_button->psz_name ) free( p_button->psz_name );
185         if( p_button->psz_action ) free( p_button->psz_action );
186         if( p_button->psz_action_down ) free( p_button->psz_action_down );
187         if( p_current->p_feedback && p_current->p_feedback->p_data_orig )
188             free( p_current->p_feedback->p_data_orig );
189         if( p_current->p_feedback )
190             free( p_current->p_feedback );
191
192         p_button->psz_name = NULL;
193         p_button->psz_action = NULL;
194         p_button->psz_action_down = NULL;
195         p_current->p_feedback = NULL;
196
197         if( p_button->p_states )
198             osd_StatesFree( p_this, p_button->p_states );
199         p_button->p_states = NULL;
200         free( p_button );
201         p_button = NULL;
202     }
203 }
204
205 /*****************************************************************************
206  * Create a new state image
207  *****************************************************************************/
208 osd_state_t *osd_StateNew( vlc_object_t *p_this, const char *psz_file, const char *psz_state )
209 {
210     osd_menu_t *p_this;
211     osd_state_t *p_state = NULL;
212     video_format_t fmt_in, fmt_out;
213
214     p_state = (osd_state_t*) malloc( sizeof(osd_state_t) );
215     if( !p_state )
216         return NULL;
217
218     memset( p_state, 0, sizeof(osd_state_t) );
219
220     memset( &fmt_in, 0, sizeof(video_format_t) );
221     memset( &fmt_out, 0, sizeof(video_format_t) );
222
223     fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A');
224     if( p_osd->p_image )
225     {
226         p_state->p_pic = image_ReadUrl( p_osd->p_image, p_osd->psz_file,
227                                         &fmt_in, &fmt_out );
228     }
229
230     if( psz_state )
231     {
232         p_state->psz_state = strdup( psz_state );
233         if( strncmp( ppsz_button_states[0], psz_state,
234                      strlen(ppsz_button_states[0]) ) == 0 )
235             p_state->i_state = OSD_BUTTON_UNSELECT;
236         else if( strncmp( ppsz_button_states[1], psz_state,
237                           strlen(ppsz_button_states[1]) ) == 0 )
238             p_state->i_state = OSD_BUTTON_SELECT;
239         else if( strncmp( ppsz_button_states[2], psz_state,
240                           strlen(ppsz_button_states[2]) ) == 0 )
241             p_state->i_state = OSD_BUTTON_PRESSED;
242     }
243     return p_state;
244 }
245
246 /*****************************************************************************
247  * Free state images
248  *****************************************************************************/
249 void osd_StatesFree( vlc_object_t *p_this, osd_state_t *p_states )
250 {
251     osd_state_t *p_state = p_states;
252     osd_state_t *p_next = NULL;
253     osd_state_t *p_prev = NULL;
254
255     while( p_state->p_next )
256     {
257         p_next = p_state->p_next;
258         p_state = p_next;
259     }
260     /* Then free end first and walk to the start. */
261     while( p_state->p_prev )
262     {
263         msg_Dbg( p_this, " |- freeing state %s [%p]", p_state->psz_state, p_state );
264         p_prev = p_state->p_prev;
265         p_state = p_prev;
266         if( p_state->p_next )
267         {
268             if( p_state->p_next->p_pic && p_state->p_next->p_pic->p_data_orig )
269                 free( p_state->p_next->p_pic->p_data_orig );
270             if( p_state->p_next->p_pic ) free( p_state->p_next->p_pic );
271             p_state->p_next->p_pic = NULL;
272             if( p_state->p_next->psz_state ) free( p_state->p_next->psz_state );
273             p_state->p_next->psz_state = NULL;
274             free( p_state->p_next );
275             p_state->p_next = NULL;
276         }
277     }
278     /* Free the last one. */
279     if( p_states )
280     {
281         msg_Dbg( p_this, " |- freeing state %s [%p]", p_state->psz_state, p_states );
282         if( p_states->p_pic && p_states->p_pic->p_data_orig )
283             free( p_states->p_pic->p_data_orig );
284         if( p_states->p_pic ) free( p_states->p_pic );
285         p_states->p_pic = NULL;
286         if( p_state->psz_state ) free( p_state->psz_state );
287         p_state->psz_state = NULL;
288         free( p_states );
289         p_states = NULL;
290     }
291 }