]> git.sesse.net Git - vlc/blob - src/osd/osd_widgets.c
Forward port of branches/0.8.1-jpsaman-thedj revision 12070. The OSD menu subsystem...
[vlc] / src / osd / osd_widgets.c
1 /*****************************************************************************\r
2  * osd_widgets.c : OSD widgets manipulation functions\r
3  *****************************************************************************\r
4  * Copyright (C) 2005 M2X\r
5  * Copyright (C) 2004 VideoLAN (Centrale Réseaux) and its contributors\r
6  *\r
7  * $Id: osd_widgets.c 9274 2004-11-10 15:16:51Z gbazin $\r
8  *\r
9  * Author: Jean-Paul Saman <jpsaman #_at_# m2x dot nl>\r
10  *\r
11  * Based on: src/video_output/video_widgets.c\r
12  *     from: Yoann Peronneau <yoann@videolan.org>\r
13  *\r
14  * This program is free software; you can redistribute it and/or modify\r
15  * it under the terms of the GNU General Public License as published by\r
16  * the Free Software Foundation; either version 2 of the License, or\r
17  * (at your option) any later version.\r
18  *\r
19  * This program is distributed in the hope that it will be useful,\r
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
22  * GNU General Public License for more details.\r
23  *\r
24  * You should have received a copy of the GNU General Public License\r
25  * along with this program; if not, write to the Free Software\r
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.\r
27  *****************************************************************************/\r
28 \r
29 /*****************************************************************************\r
30  * Preamble\r
31  *****************************************************************************/\r
32 #include <stdlib.h>                                                /* free() */\r
33 #include <vlc/vlc.h>\r
34 #include <vlc/vout.h>\r
35 #include <osd.h>\r
36 \r
37 #define STYLE_EMPTY 0\r
38 #define STYLE_FILLED 1\r
39 \r
40 /*****************************************************************************\r
41  * Local prototypes\r
42  *****************************************************************************/\r
43 static void DrawRect( picture_t *, int, int, int, int, short );\r
44 static void DrawTriangle( picture_t *, int, int, int, int, short );\r
45 static picture_t *osd_CreatePicture( int, int );\r
46 \r
47 /*****************************************************************************\r
48  * Draws a rectangle at the given position in the subpic.\r
49  * It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY).\r
50  *****************************************************************************/\r
51 static void DrawRect( picture_t *p_picture, int i_x1, int i_y1,\r
52                       int i_x2, int i_y2, short fill )\r
53 {\r
54     int x, y;\r
55     uint8_t *p_a = p_picture->A_PIXELS;\r
56     int i_pitch = p_picture->Y_PITCH;\r
57 \r
58     if( fill == STYLE_FILLED )\r
59     {\r
60         for( y = i_y1; y <= i_y2; y++ )\r
61         {\r
62             for( x = i_x1; x <= i_x2; x++ )\r
63             {\r
64                 p_a[ x + i_pitch * y ] = 0xff;\r
65             }\r
66         }\r
67     }\r
68     else\r
69     {\r
70         for( y = i_y1; y <= i_y2; y++ )\r
71         {\r
72             p_a[ i_x1 + i_pitch * y ] = 0xff;\r
73             p_a[ i_x2 + i_pitch * y ] = 0xff;\r
74         }\r
75         for( x = i_x1; x <= i_x2; x++ )\r
76         {\r
77             p_a[ x + i_pitch * i_y1 ] = 0xff;\r
78             p_a[ x + i_pitch * i_y2 ] = 0xff;\r
79         }\r
80     }\r
81 }\r
82 \r
83 /*****************************************************************************\r
84  * Draws a triangle at the given position in the subpic.\r
85  * It may be filled (fill == STYLE_FILLED) or empty (fill == STYLE_EMPTY).\r
86  *****************************************************************************/\r
87 static void DrawTriangle( picture_t *p_picture, int i_x1, int i_y1,\r
88                           int i_x2, int i_y2, short fill )\r
89 {\r
90     int x, y, i_mid, h;\r
91     uint8_t *p_a = p_picture->A_PIXELS;\r
92     int i_pitch = p_picture->Y_PITCH;\r
93 \r
94     i_mid = i_y1 + ( ( i_y2 - i_y1 ) >> 1 );\r
95 \r
96     if( i_x2 >= i_x1 )\r
97     {\r
98         if( fill == STYLE_FILLED )\r
99         {\r
100             for( y = i_y1; y <= i_mid; y++ )\r
101             {\r
102                 h = y - i_y1;\r
103                 for( x = i_x1; x <= i_x1 + h && x <= i_x2; x++ )\r
104                 {\r
105                     p_a[ x + i_pitch * y ] = 0xff;\r
106                     p_a[ x + i_pitch * ( i_y2 - h ) ] = 0xff;\r
107                 }\r
108             }\r
109         }\r
110         else\r
111         {\r
112             for( y = i_y1; y <= i_mid; y++ )\r
113             {\r
114                 h = y - i_y1;\r
115                 p_a[ i_x1 + i_pitch * y ] = 0xff;\r
116                 p_a[ i_x1 + h + i_pitch * y ] = 0xff;\r
117                 p_a[ i_x1 + i_pitch * ( i_y2 - h ) ] = 0xff;\r
118                 p_a[ i_x1 + h + i_pitch * ( i_y2 - h ) ] = 0xff;\r
119             }\r
120         }\r
121     }\r
122     else\r
123     {\r
124         if( fill == STYLE_FILLED )\r
125         {\r
126             for( y = i_y1; y <= i_mid; y++ )\r
127             {\r
128                 h = y - i_y1;\r
129                 for( x = i_x1; x >= i_x1 - h && x >= i_x2; x-- )\r
130                 {\r
131                     p_a[ x + i_pitch * y ] = 0xff;\r
132                     p_a[ x + i_pitch * ( i_y2 - h ) ] = 0xff;\r
133                 }\r
134             }\r
135         }\r
136         else\r
137         {\r
138             for( y = i_y1; y <= i_mid; y++ )\r
139             {\r
140                 h = y - i_y1;\r
141                 p_a[ i_x1 + i_pitch * y ] = 0xff;\r
142                 p_a[ i_x1 - h + i_pitch * y ] = 0xff;\r
143                 p_a[ i_x1 + i_pitch * ( i_y2 - h ) ] = 0xff;\r
144                 p_a[ i_x1 - h + i_pitch * ( i_y2 - h ) ] = 0xff;\r
145             }\r
146         }\r
147     }\r
148 }\r
149 \r
150 /*****************************************************************************\r
151  * Create Picture: creates picture\r
152  *****************************************************************************/\r
153 static picture_t *osd_CreatePicture( int i_width, int i_height )\r
154 {\r
155     picture_t *p_picture = NULL;\r
156     uint8_t *p_y, *p_u, *p_v, *p_a;\r
157     int i_pitch;\r
158 \r
159     p_picture = (picture_t*) malloc( sizeof(picture_t) );\r
160     if( p_picture == NULL )\r
161     {\r
162         return NULL;\r
163     }\r
164     /* Clear the memory */\r
165     memset( p_picture, 0, sizeof(picture_t) );\r
166 \r
167     p_y = p_picture->Y_PIXELS;\r
168     p_u = p_picture->U_PIXELS;\r
169     p_v = p_picture->V_PIXELS;\r
170     p_a = p_picture->A_PIXELS;\r
171     i_pitch = p_picture->Y_PITCH;\r
172 \r
173     /* Initialize the region pixels (only the alpha will be changed later) */\r
174     memset( p_y, 0xff, i_pitch * i_height );\r
175     memset( p_u, 0x80, i_pitch * i_height );\r
176     memset( p_v, 0x80, i_pitch * i_height );\r
177     memset( p_a, 0x00, i_pitch * i_height );\r
178 \r
179     return p_picture;\r
180 }\r
181 \r
182 /*****************************************************************************\r
183  * Displays an OSD slider.\r
184  * Types are: OSD_HOR_SLIDER and OSD_VERT_SLIDER.\r
185  *****************************************************************************/\r
186 picture_t *osd_Slider( int i_width, int i_height, int i_position, short i_type )\r
187 {\r
188     picture_t *p_picture;\r
189     int i_x_margin, i_y_margin, i_x, i_y;\r
190 \r
191     p_picture = osd_CreatePicture( i_width, i_height );\r
192     if( p_picture == NULL )\r
193         return NULL;\r
194 \r
195     i_y_margin = i_height / 10;\r
196     i_x_margin = i_y_margin;\r
197     if( i_type == OSD_HOR_SLIDER )\r
198     {\r
199         i_width = i_width - 2 * i_x_margin;\r
200         i_height = i_height / 20;\r
201         i_x = i_x_margin;\r
202         i_y = i_height - i_y_margin - i_height;\r
203     }\r
204     else\r
205     {\r
206         i_width = i_width / 40;\r
207         i_height = i_height - 2 * i_y_margin;\r
208         i_x = i_width - i_x_margin - i_width;\r
209         i_y = i_y_margin;\r
210     }\r
211 \r
212     if( i_type == OSD_HOR_SLIDER )\r
213     {\r
214         int i_x_pos = ( i_width - 2 ) * i_position / 100;\r
215         DrawRect( p_picture, i_x_pos - 1, 2, i_x_pos + 1,\r
216                   i_height - 3, STYLE_FILLED );\r
217         DrawRect( p_picture, 0, 0, i_width - 1, i_height - 1, STYLE_EMPTY );\r
218     }\r
219     else if( i_type == OSD_VERT_SLIDER )\r
220     {\r
221         int i_y_pos = i_height / 2;\r
222         DrawRect( p_picture, 2, i_height - ( i_height - 2 ) * i_position / 100,\r
223                   i_width - 3, i_height - 3, STYLE_FILLED );\r
224         DrawRect( p_picture, 1, i_y_pos, 1, i_y_pos, STYLE_FILLED );\r
225         DrawRect( p_picture, i_width - 2, i_y_pos,\r
226                   i_width - 2, i_y_pos, STYLE_FILLED );\r
227         DrawRect( p_picture, 0, 0, i_width - 1, i_height - 1, STYLE_EMPTY );\r
228     }\r
229 \r
230     return p_picture;\r
231 }\r
232 \r
233 /*****************************************************************************\r
234  * Displays an OSD icon.\r
235  * Types are: OSD_PLAY_ICON, OSD_PAUSE_ICON, OSD_SPEAKER_ICON, OSD_MUTE_ICON\r
236  *****************************************************************************/\r
237 picture_t *osd_Icon( int i_width, int i_height, short i_type )\r
238 {\r
239     picture_t *p_picture = NULL;\r
240     int i_x_margin, i_y_margin, i_x, i_y;\r
241 \r
242     p_picture = osd_CreatePicture( i_width, i_height );\r
243     if( p_picture == NULL )\r
244         return NULL;\r
245 \r
246     i_y_margin = i_height / 15;\r
247     i_x_margin = i_y_margin;\r
248     i_x = i_width - i_x_margin - i_width;\r
249     i_y = i_y_margin;\r
250 \r
251     if( i_type == OSD_PAUSE_ICON )\r
252     {\r
253         int i_bar_width = i_width / 3;\r
254         DrawRect( p_picture, 0, 0, i_bar_width - 1, i_height -1, STYLE_FILLED );\r
255         DrawRect( p_picture, i_width - i_bar_width, 0,\r
256                   i_width - 1, i_height - 1, STYLE_FILLED );\r
257     }\r
258     else if( i_type == OSD_PLAY_ICON )\r
259     {\r
260         int i_mid = i_height >> 1;\r
261         int i_delta = ( i_width - i_mid ) >> 1;\r
262         int i_y2 = ( ( i_height - 1 ) >> 1 ) * 2;\r
263         DrawTriangle( p_picture, i_delta, 0, i_width - i_delta, i_y2,\r
264                       STYLE_FILLED );\r
265     }\r
266     else if( i_type == OSD_SPEAKER_ICON || i_type == OSD_MUTE_ICON )\r
267     {\r
268         int i_mid = i_height >> 1;\r
269         int i_delta = ( i_width - i_mid ) >> 1;\r
270         int i_y2 = ( ( i_height - 1 ) >> 1 ) * 2;\r
271         DrawRect( p_picture, i_delta, i_mid / 2, i_width - i_delta,\r
272                   i_height - 1 - i_mid / 2, STYLE_FILLED );\r
273         DrawTriangle( p_picture, i_width - i_delta, 0, i_delta, i_y2,\r
274                       STYLE_FILLED );\r
275         if( i_type == OSD_MUTE_ICON )\r
276         {\r
277             uint8_t *p_a = p_picture->A_PIXELS;\r
278             int i_pitch = p_picture->Y_PITCH;\r
279             int i;\r
280             for( i = 1; i < i_pitch; i++ )\r
281             {\r
282                 int k = i + ( i_height - i - 1 ) * i_pitch;\r
283                 p_a[ k ] = 0xff - p_a[ k ];\r
284             }\r
285         }\r
286     }\r
287     \r
288     return p_picture;\r
289 }\r