1 /*******************************************************************************
2 * vout_ggi.c: GGI video output display method
4 *******************************************************************************/
6 /*******************************************************************************
8 *******************************************************************************/
17 #include "vlc_thread.h"
20 #include "video_output.h"
21 #include "video_sys.h"
24 /*******************************************************************************
25 * vout_sys_t: video output GGI method descriptor
26 *******************************************************************************
27 * This structure is part of the video output thread descriptor.
28 * It describes the GGI specific properties of an output thread.
29 *******************************************************************************/
30 typedef struct vout_sys_s
32 /* GGI system informations */
33 ggi_visual_t p_display; /* display device */
35 /* Buffers informations */
36 ggi_directbuffer * p_buffer[2]; /* buffers */
37 boolean_t b_must_acquire; /* must be acquired before writing */
40 /*******************************************************************************
42 *******************************************************************************/
43 static int GGIOpenDisplay ( vout_thread_t *p_vout, char *psz_display );
44 static void GGICloseDisplay ( vout_thread_t *p_vout );
46 /*******************************************************************************
47 * vout_SysCreate: allocate GGI video thread output method
48 *******************************************************************************
49 * This function allocate and initialize a GGI vout method. It uses some of the
50 * vout properties to choose the correct mode, and change them according to the
52 *******************************************************************************/
53 int vout_SysCreate( vout_thread_t *p_vout, char *psz_display, int i_root_window )
55 /* Allocate structure */
56 p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
57 if( p_vout->p_sys == NULL )
59 intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
63 /* Open and initialize device */
64 if( GGIOpenDisplay( p_vout, psz_display ) )
66 intf_ErrMsg("error: can't initialize GGI display\n");
67 free( p_vout->p_sys );
73 /*******************************************************************************
74 * vout_SysInit: initialize GGI video thread output method
75 *******************************************************************************
76 * This function initialize the GGI display device.
77 *******************************************************************************/
78 int vout_SysInit( vout_thread_t *p_vout )
80 /* Acquire first buffer */
81 if( p_vout->p_sys->b_must_acquire )
83 ggiResourceAcquire( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource, GGI_ACTYPE_WRITE );
89 /*******************************************************************************
90 * vout_SysEnd: terminate Sys video thread output method
91 *******************************************************************************
92 * Terminate an output method created by vout_SysCreateOutputMethod
93 *******************************************************************************/
94 void vout_SysEnd( vout_thread_t *p_vout )
97 if( p_vout->p_sys->b_must_acquire )
99 ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource );
103 /*******************************************************************************
104 * vout_SysDestroy: destroy Sys video thread output method
105 *******************************************************************************
106 * Terminate an output method created by vout_SysCreateOutputMethod
107 *******************************************************************************/
108 void vout_SysDestroy( vout_thread_t *p_vout )
110 GGICloseDisplay( p_vout );
111 free( p_vout->p_sys );
114 /*******************************************************************************
115 * vout_SysManage: handle Sys events
116 *******************************************************************************
117 * This function should be called regularly by video output thread. It returns
118 * a non null value if an error occured.
119 *******************************************************************************/
120 int vout_SysManage( vout_thread_t *p_vout )
122 //?? 8bpp: change palette
126 /*******************************************************************************
127 * vout_SysDisplay: displays previously rendered output
128 *******************************************************************************
129 * This function send the currently rendered image to the display, wait until
130 * it is displayed and switch the two rendering buffer, preparing next frame.
131 *******************************************************************************/
132 void vout_SysDisplay( vout_thread_t *p_vout )
134 /* Change display frame */
135 if( p_vout->p_sys->b_must_acquire )
137 ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource );
139 ggiFlush( p_vout->p_sys->p_display ); // ??
140 ggiSetDisplayFrame( p_vout->p_sys->p_display,
141 p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->frame );
143 /* Swap buffers and change write frame */
144 if( p_vout->p_sys->b_must_acquire )
146 ggiResourceAcquire( p_vout->p_sys->p_buffer[ (p_vout->i_buffer_index + 1) & 1]->resource,
149 ggiSetWriteFrame( p_vout->p_sys->p_display,
150 p_vout->p_sys->p_buffer[ (p_vout->i_buffer_index + 1) & 1]->frame );
153 /*******************************************************************************
154 * vout_SysGetVisual: send visual to interface driver
155 *******************************************************************************
156 * This function is not part of the regular vout_Sys* API, but is used by GGI
157 * interface to get back visual display pointer once the output thread has
158 * been spawned. This visual is used to keep track of keyboard events.
159 *******************************************************************************/
160 ggi_visual_t vout_SysGetVisual( vout_thread_t *p_vout )
162 return( p_vout->p_sys->p_display );
165 /* following functions are local */
167 /*******************************************************************************
168 * GGIOpenDisplay: open and initialize GGI device
169 *******************************************************************************
170 * Open and initialize display according to preferences specified in the vout
172 *******************************************************************************/
173 static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display )
175 ggi_mode mode; /* mode descriptor */
176 ggi_color col_fg; /* foreground color */
177 ggi_color col_bg; /* background color */
178 int i_index; /* all purposes index */
180 /* Initialize library */
183 intf_ErrMsg("error: can't initialize GGI library\n");
188 p_vout->p_sys->p_display = ggiOpen( psz_display, NULL );
189 if( p_vout->p_sys->p_display == NULL )
191 intf_ErrMsg("error: can't open GGI default display\n");
196 /* Find most appropriate mode */
197 mode.frames = 2; /* 2 buffers */
198 mode.visible.x = p_vout->i_width; /* minimum width */
199 mode.visible.y = p_vout->i_height; /* minimum height */
200 mode.virt.x = GGI_AUTO;
201 mode.virt.y = GGI_AUTO;
202 mode.size.x = GGI_AUTO;
203 mode.size.y = GGI_AUTO;
204 mode.graphtype = GT_15BIT; /* minimum usable screen depth */
205 mode.dpp.x = GGI_AUTO;
206 mode.dpp.y = GGI_AUTO;
207 ggiCheckMode( p_vout->p_sys->p_display, &mode );
209 /* Check that returned mode has some minimum properties */
213 if( ggiSetMode( p_vout->p_sys->p_display, &mode ) )
215 intf_ErrMsg("error: can't set GGI mode\n");
216 ggiClose( p_vout->p_sys->p_display );
221 /* Check buffers properties */
222 p_vout->p_sys->b_must_acquire = 0;
223 for( i_index = 0; i_index < 2; i_index++ )
225 /* Get buffer address */
226 p_vout->p_sys->p_buffer[ i_index ] =
227 ggiDBGetBuffer( p_vout->p_sys->p_display, i_index );
228 if( p_vout->p_sys->p_buffer[ i_index ] == NULL )
230 intf_ErrMsg("error: double buffering is not possible\n");
231 ggiClose( p_vout->p_sys->p_display );
236 /* Check buffer properties */
237 if( ! (p_vout->p_sys->p_buffer[ i_index ]->type & GGI_DB_SIMPLE_PLB) ||
238 (p_vout->p_sys->p_buffer[ i_index ]->page_size != 0) ||
239 (p_vout->p_sys->p_buffer[ i_index ]->write == NULL ) ||
240 (p_vout->p_sys->p_buffer[ i_index ]->noaccess != 0) ||
241 (p_vout->p_sys->p_buffer[ i_index ]->align != 0) )
243 intf_ErrMsg("error: incorrect video memory type\n");
244 ggiClose( p_vout->p_sys->p_display );
249 /* Check if buffer needs to be acquired before write */
250 if( ggiResourceMustAcquire( p_vout->p_sys->p_buffer[ i_index ]->resource ) )
252 p_vout->p_sys->b_must_acquire = 1;
256 if( p_vout->p_sys->b_must_acquire )
258 intf_DbgMsg("buffers must be acquired\n");
262 /* Set graphic context colors */
263 col_fg.r = col_fg.g = col_fg.b = -1;
264 col_bg.r = col_bg.g = col_bg.b = 0;
265 if( ggiSetGCForeground(p_vout->p_sys->p_display,
266 ggiMapColor(p_vout->p_sys->p_display,&col_fg)) ||
267 ggiSetGCBackground(p_vout->p_sys->p_display,
268 ggiMapColor(p_vout->p_sys->p_display,&col_bg)) )
270 intf_ErrMsg("error: can't set colors\n");
271 ggiClose( p_vout->p_sys->p_display );
276 /* Set clipping for text */
277 if( ggiSetGCClipping(p_vout->p_sys->p_display, 0, 0,
278 mode.visible.x, mode.visible.y ) )
280 intf_ErrMsg("error: can't set clipping\n");
281 ggiClose( p_vout->p_sys->p_display );
286 /* Set thread information */
287 p_vout->i_width = mode.visible.x;
288 p_vout->i_height = mode.visible.y;
289 p_vout->i_bytes_per_line = p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.stride;
290 p_vout->i_screen_depth = p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.depth;
291 p_vout->i_bytes_per_pixel = p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.size / 8;
292 p_vout->i_red_mask = p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.red_mask;
293 p_vout->i_green_mask = p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.green_mask;
294 p_vout->i_blue_mask = p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.blue_mask;
297 /* Set and initialize buffers */
298 vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ]->write, p_vout->p_sys->p_buffer[ 1 ]->write );
303 /*******************************************************************************
304 * GGICloseDisplay: close and reset GGI device
305 *******************************************************************************
306 * This function returns all resources allocated by GGIOpenDisplay and restore
307 * the original state of the device.
308 *******************************************************************************/
309 static void GGICloseDisplay( vout_thread_t *p_vout )
311 // Restore original mode and close display
312 ggiClose( p_vout->p_sys->p_display );