1 /*****************************************************************************
2 * vout_sdl.c: SDL video output display method
3 *****************************************************************************
4 * Copyright (C) 1998, 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
28 #include <errno.h> /* ENOMEM */
29 #include <stdlib.h> /* free() */
30 #include <string.h> /* strerror() */
41 #include "video_output.h"
45 /*****************************************************************************
46 * vout_sys_t: video output SDL method descriptor
47 *****************************************************************************
48 * This structure is part of the video output thread descriptor.
49 * It describes the SDL specific properties of an output thread.
50 *****************************************************************************/
51 typedef struct vout_sys_s
53 SDL_Surface * p_display; /* display device */
55 /* Buffers informations */
56 boolean_t b_must_acquire; /* must be acquired before writing */
59 /*****************************************************************************
61 *****************************************************************************/
62 static int SDLOpenDisplay ( vout_thread_t *p_vout,
63 char *psz_display, void *p_data );
64 static void SDLCloseDisplay ( vout_thread_t *p_vout );
66 /*****************************************************************************
67 * vout_SDLCreate: allocate SDL video thread output method
68 *****************************************************************************
69 * This function allocate and initialize a SDL vout method. It uses some of the
70 * vout properties to choose the correct mode, and change them according to the
72 *****************************************************************************/
73 int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display,
74 int i_root_window, void *p_data )
76 /* Allocate structure */
77 p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
78 if( p_vout->p_sys == NULL )
80 intf_ErrMsg( "error: %s\n", strerror(ENOMEM) );
84 /* Open and initialize device */
86 if( SDLOpenDisplay( p_vout, psz_display, p_data ) )
88 intf_ErrMsg( "error: can't initialize SDL display\n" );
89 free( p_vout->p_sys );
95 /*****************************************************************************
96 * vout_SDLInit: initialize SDL video thread output method
97 *****************************************************************************
98 * This function initialize the SDL display device.
99 *****************************************************************************/
100 int vout_SDLInit( vout_thread_t *p_vout )
102 /* Acquire first buffer */
103 if( p_vout->p_sys->b_must_acquire )
105 SDL_LockSurface(p_vout->p_sys->p_display);
111 /*****************************************************************************
112 * vout_SDLEnd: terminate Sys video thread output method
113 *****************************************************************************
114 * Terminate an output method created by vout_SDLCreate
115 *****************************************************************************/
116 void vout_SDLEnd( vout_thread_t *p_vout )
119 if( p_vout->p_sys->b_must_acquire )
121 SDL_UnlockSurface ( p_vout->p_sys->p_display );
125 /*****************************************************************************
126 * vout_SDLDestroy: destroy Sys video thread output method
127 *****************************************************************************
128 * Terminate an output method created by vout_SDLCreate
129 *****************************************************************************/
130 void vout_SDLDestroy( vout_thread_t *p_vout )
132 SDLCloseDisplay( p_vout );
133 free( p_vout->p_sys );
136 /*****************************************************************************
137 * vout_SDLManage: handle Sys events
138 *****************************************************************************
139 * This function should be called regularly by video output thread. It returns
140 * a non null value if an error occured.
141 *****************************************************************************/
142 int vout_SDLManage( vout_thread_t *p_vout )
144 /* FIXME: 8bpp: change palette ?? */
148 /*****************************************************************************
149 * vout_SDLDisplay: displays previously rendered output
150 *****************************************************************************
151 * This function send the currently rendered image to the display, wait until
152 * it is displayed and switch the two rendering buffer, preparing next frame.
153 *****************************************************************************/
154 void vout_SDLDisplay( vout_thread_t *p_vout )
156 SDL_Overlay * screen;
160 /* Change display frame */
161 if( p_vout->p_sys->b_must_acquire )
164 SDL_Flip( p_vout->p_sys->p_display );
166 /* Swap buffers and change write frame */
167 SDL_LockSurface ( p_vout->p_sys->p_display );
173 * p_vout->yuv.p_buffer contains the YUV buffer to render
176 screen = SDL_CreateYUVOverlay( p_vout->i_width, p_vout->i_height , SDL_IYUV_OVERLAY, p_vout->p_sys->p_display );
177 screen->pixels = p_vout->yuv.p_buffer;
180 disp.w = p_vout->i_width;
181 disp.h = p_vout->i_height;
182 SDL_DisplayYUVOverlay( screen , &disp );
186 /* following functions are local */
188 /*****************************************************************************
189 * SDLOpenDisplay: open and initialize SDL device
190 *****************************************************************************
191 * Open and initialize display according to preferences specified in the vout
193 *****************************************************************************/
194 static int SDLOpenDisplay( vout_thread_t *p_vout, char *psz_display, void *p_data )
197 /* Initialize library */
198 if( SDL_Init(SDL_INIT_VIDEO) < 0 )
200 intf_ErrMsg( "error: can't initialize SDL library: %s\n",
206 * TODO: Check that we can request for a DOUBLEBUF HWSURFACE display
208 if(psz_display != NULL && strcmp(psz_display,"fullscreen")==0)
210 p_vout->p_sys->p_display = SDL_SetVideoMode(p_vout->i_width,
213 SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN );
216 p_vout->p_sys->p_display = SDL_SetVideoMode(p_vout->i_width,
219 SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF );
223 if( p_vout->p_sys->p_display == NULL )
225 intf_ErrMsg( "error: can't open DISPLAY default display\n" );
228 SDL_WM_SetCaption( VOUT_TITLE , VOUT_TITLE );
229 SDL_EventState(SDL_KEYUP , SDL_IGNORE); /* ignore keys up */
231 /* Check buffers properties */
232 p_vout->p_sys->b_must_acquire = 1; /* always acquire */
233 p_vout->p_sys->p_buffer[ 0 ] =
234 p_vout->p_sys->p_display->pixels;
236 SDL_Flip(p_vout->p_sys->p_display);
237 p_vout->p_sys->p_buffer[ 1 ] =
238 p_vout->p_sys->p_display->pixels;
239 SDL_Flip(p_vout->p_sys->p_display);
241 /* Set graphic context colors */
244 col_fg.r = col_fg.g = col_fg.b = -1;
245 col_bg.r = col_bg.g = col_bg.b = 0;
246 if( ggiSetGCForeground(p_vout->p_sys->p_display,
247 ggiMapColor(p_vout->p_sys->p_display,&col_fg)) ||
248 ggiSetGCBackground(p_vout->p_sys->p_display,
249 ggiMapColor(p_vout->p_sys->p_display,&col_bg)) )
251 intf_ErrMsg("error: can't set colors\n");
252 ggiClose( p_vout->p_sys->p_display );
258 /* Set clipping for text */
259 SDL_SetClipping(p_vout->p_sys->p_display, 0, 0,
260 p_vout->p_sys->p_display->w,
261 p_vout->p_sys->p_display->h);
265 /* Set thread information */
266 p_vout->i_width = p_vout->p_sys->p_display->w;
267 p_vout->i_height = p_vout->p_sys->p_display->h;
269 p_vout->i_bytes_per_line = p_vout->p_sys->p_display->format->BytesPerPixel *
270 p_vout->p_sys->p_display->w ;
272 p_vout->i_screen_depth = p_vout->p_sys->p_display->format->BitsPerPixel;
273 p_vout->i_bytes_per_pixel = p_vout->p_sys->p_display->format->BytesPerPixel;
274 p_vout->i_red_mask = p_vout->p_sys->p_display->format->Rmask;
275 p_vout->i_green_mask = p_vout->p_sys->p_display->format->Gmask;
276 p_vout->i_blue_mask = p_vout->p_sys->p_display->format->Bmask;
278 /* FIXME: palette in 8bpp ?? */
279 /* Set and initialize buffers */
280 vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ],
281 p_vout->p_sys->p_buffer[ 1 ] );
286 /*****************************************************************************
287 * SDLCloseDisplay: close and reset SDL device
288 *****************************************************************************
289 * This function returns all resources allocated by SDLOpenDisplay and restore
290 * the original state of the device.
291 *****************************************************************************/
292 static void SDLCloseDisplay( vout_thread_t *p_vout )
294 SDL_FreeSurface( p_vout->p_sys->p_display );