]> git.sesse.net Git - vlc/blob - src/video_output/video_ggi.c
Juste une modif � la con dans video_output pour que le message "waiting
[vlc] / src / video_output / video_ggi.c
1 /*******************************************************************************
2  * vout_ggi.c: GGI video output display method
3  * (c)1998 VideoLAN
4  *******************************************************************************/
5
6 /*******************************************************************************
7  * Preamble
8  *******************************************************************************/
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ggi/ggi.h>
13
14 #include "config.h"
15 #include "common.h"
16 #include "mtime.h"
17 #include "vlc_thread.h"
18
19 #include "video.h"
20 #include "video_output.h"
21 #include "video_sys.h"
22 #include "intf_msg.h"
23
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
31
32     /* GGI system informations */
33     ggi_visual_t        p_display;                           /* display device */
34
35     /* Buffers informations */
36     ggi_directbuffer *  p_buffer[2];                                /* buffers */
37     boolean_t           b_must_acquire;     /* must be acquired before writing */    
38 } vout_sys_t;
39
40 /*******************************************************************************
41  * Local prototypes
42  *******************************************************************************/
43 static int     GGIOpenDisplay   ( vout_thread_t *p_vout, char *psz_display );
44 static void    GGICloseDisplay  ( vout_thread_t *p_vout );
45
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 
51  * mode actually used.
52  *******************************************************************************/
53 int vout_SysCreate( vout_thread_t *p_vout, char *psz_display, int i_root_window )
54 {    
55     /* Allocate structure */
56     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );    
57     if( p_vout->p_sys == NULL )
58     {
59         intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
60         return( 1 );
61     }
62
63     /* Open and initialize device */
64     if( GGIOpenDisplay( p_vout, psz_display ) )
65     {
66         intf_ErrMsg("error: can't initialize GGI display\n");        
67         free( p_vout->p_sys );
68         return( 1 );        
69     }
70     return( 0 );
71 }
72
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 )
79 {
80     /* Acquire first buffer */
81     if( p_vout->p_sys->b_must_acquire )
82     {
83         ggiResourceAcquire( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource, GGI_ACTYPE_WRITE );        
84     }    
85
86     return( 0 );
87 }
88
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 )
95 {
96     /* Release buffer */
97     if( p_vout->p_sys->b_must_acquire )
98     {
99         ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource );
100     }
101 }
102
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 )
109 {
110     GGICloseDisplay( p_vout );
111     free( p_vout->p_sys );
112 }
113
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 )
121 {
122     //?? 8bpp: change palette
123     return( 0 );    
124 }
125
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 )
133 {
134     /* Change display frame */
135     if( p_vout->p_sys->b_must_acquire )
136     {            
137         ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource );
138     }    
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 );      
142         
143     /* Swap buffers and change write frame */
144     if( p_vout->p_sys->b_must_acquire )
145     {            
146         ggiResourceAcquire( p_vout->p_sys->p_buffer[ (p_vout->i_buffer_index + 1) & 1]->resource, 
147                             GGI_ACTYPE_WRITE );
148     } 
149     ggiSetWriteFrame( p_vout->p_sys->p_display,
150                       p_vout->p_sys->p_buffer[ (p_vout->i_buffer_index + 1) & 1]->frame );    
151 }
152
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 )
161 {
162     return( p_vout->p_sys->p_display );    
163 }
164
165 /* following functions are local */
166
167 /*******************************************************************************
168  * GGIOpenDisplay: open and initialize GGI device 
169  *******************************************************************************
170  * Open and initialize display according to preferences specified in the vout
171  * thread fields.
172  *******************************************************************************/
173 static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display )
174 {
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 */    
179     
180     /* Initialize library */
181     if( ggiInit() )
182     {
183         intf_ErrMsg("error: can't initialize GGI library\n");
184         return( 1 );        
185     }
186
187     /* Open display */
188     p_vout->p_sys->p_display = ggiOpen( psz_display, NULL );
189     if( p_vout->p_sys->p_display == NULL )
190     {
191         intf_ErrMsg("error: can't open GGI default display\n");
192         ggiExit();
193         return( 1 );        
194     }
195     
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 );
208
209     /* Check that returned mode has some minimum properties */
210     //??
211     
212     /* Set mode */
213     if( ggiSetMode( p_vout->p_sys->p_display, &mode ) )
214     {
215         intf_ErrMsg("error: can't set GGI mode\n");
216         ggiClose( p_vout->p_sys->p_display );        
217         ggiExit();
218         return( 1 );        
219     }            
220
221     /* Check buffers properties */
222     p_vout->p_sys->b_must_acquire = 0;    
223     for( i_index = 0; i_index < 2; i_index++ )
224     {
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 )
229         {
230             intf_ErrMsg("error: double buffering is not possible\n");
231             ggiClose( p_vout->p_sys->p_display );        
232             ggiExit();
233             return( 1 );            
234         }        
235         
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) )
242         {
243             intf_ErrMsg("error: incorrect video memory type\n");
244             ggiClose( p_vout->p_sys->p_display );        
245             ggiExit();
246             return( 1 ); 
247         } 
248
249         /* Check if buffer needs to be acquired before write */
250         if( ggiResourceMustAcquire( p_vout->p_sys->p_buffer[ i_index ]->resource ) )
251         {
252             p_vout->p_sys->b_must_acquire = 1;            
253         }            
254     } 
255 #ifdef DEBUG
256     if( p_vout->p_sys->b_must_acquire )
257     {
258         intf_DbgMsg("buffers must be acquired\n");        
259     }    
260 #endif
261
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)) )
269     {
270         intf_ErrMsg("error: can't set colors\n");
271         ggiClose( p_vout->p_sys->p_display );        
272         ggiExit();
273         return( 1 );  
274     }    
275
276     /* Set clipping for text */
277     if( ggiSetGCClipping(p_vout->p_sys->p_display, 0, 0, 
278                          mode.visible.x, mode.visible.y ) )
279     {
280         intf_ErrMsg("error: can't set clipping\n");
281         ggiClose( p_vout->p_sys->p_display );        
282         ggiExit();
283         return( 1 );  
284     }
285     
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;            
295     //?? palette in 8bpp
296     
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 );
299
300     return( 0 );    
301 }
302
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 )
310 {
311     // Restore original mode and close display
312     ggiClose( p_vout->p_sys->p_display );    
313
314     // Exit library
315     ggiExit();    
316 }
317