]> git.sesse.net Git - vlc/blobdiff - src/video_output/video_ggi.c
Suppression de la ligne verte.
[vlc] / src / video_output / video_ggi.c
index 0424722c6775be224a35d1af3a2d96110ff9cc05..cce62907652d522a932cd0fb000a5afe57325686 100644 (file)
@@ -32,14 +32,15 @@ typedef struct vout_sys_s
     /* GGI system informations */
     ggi_visual_t        p_display;                           /* display device */
 
-    /* Buffer index */
-    int                 i_buffer_index;    
+    /* Buffers informations */
+    ggi_directbuffer *  p_buffer[2];                                /* buffers */
+    boolean_t           b_must_acquire;     /* must be acquired before writing */    
 } vout_sys_t;
 
 /*******************************************************************************
  * Local prototypes
  *******************************************************************************/
-static int     GGIOpenDisplay   ( vout_thread_t *p_vout );
+static int     GGIOpenDisplay   ( vout_thread_t *p_vout, char *psz_display );
 static void    GGICloseDisplay  ( vout_thread_t *p_vout );
 
 /*******************************************************************************
@@ -49,7 +50,7 @@ static void    GGICloseDisplay  ( vout_thread_t *p_vout );
  * vout properties to choose the correct mode, and change them according to the 
  * mode actually used.
  *******************************************************************************/
-int vout_SysCreate( vout_thread_t *p_vout )
+int vout_SysCreate( vout_thread_t *p_vout, char *psz_display, int i_root_window )
 {    
     /* Allocate structure */
     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );    
@@ -60,13 +61,12 @@ int vout_SysCreate( vout_thread_t *p_vout )
     }
 
     /* Open and initialize device */
-    if( GGIOpenDisplay( p_vout ) )
+    if( GGIOpenDisplay( p_vout, psz_display ) )
     {
         intf_ErrMsg("error: can't initialize GGI display\n");        
         free( p_vout->p_sys );
         return( 1 );        
     }
-    
     return( 0 );
 }
 
@@ -77,7 +77,12 @@ int vout_SysCreate( vout_thread_t *p_vout )
  *******************************************************************************/
 int vout_SysInit( vout_thread_t *p_vout )
 {
-    p_vout->p_sys->i_buffer_index = 0;
+    /* Acquire first buffer */
+    if( p_vout->p_sys->b_must_acquire )
+    {
+        ggiResourceAcquire( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource, GGI_ACTYPE_WRITE );        
+    }    
+
     return( 0 );
 }
 
@@ -88,7 +93,11 @@ int vout_SysInit( vout_thread_t *p_vout )
  *******************************************************************************/
 void vout_SysEnd( vout_thread_t *p_vout )
 {
-    ;
+    /* Release buffer */
+    if( p_vout->p_sys->b_must_acquire )
+    {
+        ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource );
+    }
 }
 
 /*******************************************************************************
@@ -106,15 +115,11 @@ void vout_SysDestroy( vout_thread_t *p_vout )
  * vout_SysManage: handle Sys events
  *******************************************************************************
  * This function should be called regularly by video output thread. It returns 
- * a negative value if something happened which does not allow the thread to 
- * continue, and a positive one if the thread can go on, but the images have 
- * been modified and therefore it is useless to display them.
+ * a non null value if an error occured.
  *******************************************************************************/
 int vout_SysManage( vout_thread_t *p_vout )
 {
-    //??
-
-    return( 0 );
+    return( 0 );    
 }
 
 /*******************************************************************************
@@ -126,26 +131,34 @@ int vout_SysManage( vout_thread_t *p_vout )
 void vout_SysDisplay( vout_thread_t *p_vout )
 {
     /* Change display frame */
+    if( p_vout->p_sys->b_must_acquire )
+    {            
+        ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource );
+    }    
     ggiFlush( p_vout->p_sys->p_display ); // ??    
-    ggiSetDisplayFrame( p_vout->p_sys->p_display, p_vout->p_sys->i_buffer_index );      
+    ggiSetDisplayFrame( p_vout->p_sys->p_display, 
+                        p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->frame );      
         
     /* Swap buffers and change write frame */
-    p_vout->p_sys->i_buffer_index = ++p_vout->p_sys->i_buffer_index & 1;
-    ggiSetWriteFrame( p_vout->p_sys->p_display, p_vout->p_sys->i_buffer_index );        
+    if( p_vout->p_sys->b_must_acquire )
+    {            
+        ggiResourceAcquire( p_vout->p_sys->p_buffer[ (p_vout->i_buffer_index + 1) & 1]->resource, 
+                            GGI_ACTYPE_WRITE );
+    } 
+    ggiSetWriteFrame( p_vout->p_sys->p_display,
+                      p_vout->p_sys->p_buffer[ (p_vout->i_buffer_index + 1) & 1]->frame );    
 }
 
 /*******************************************************************************
- * vout_SysGetPicture: get current display buffer informations
+ * vout_SysGetVisual: send visual to interface driver
  *******************************************************************************
- * This function returns the address of the current display buffer, and the
- * number of samples per line. For 15, 16 and 32 bits displays, this value is 
- * the number of pixels in a line.
+ * This function is not part of the regular vout_Sys* API, but is used by GGI
+ * interface to get back visual display pointer once the output thread has
+ * been spawned. This visual is used to keep track of keyboard events.
  *******************************************************************************/
-byte_t * vout_SysGetPicture( vout_thread_t *p_vout, int *pi_eol_offset )
+ggi_visual_t    vout_SysGetVisual( vout_thread_t *p_vout )
 {
-    *pi_eol_offset = p_vout->i_width;
-//????
-//    return( p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ].data );        
+    return( p_vout->p_sys->p_display );    
 }
 
 /* following functions are local */
@@ -156,9 +169,12 @@ byte_t * vout_SysGetPicture( vout_thread_t *p_vout, int *pi_eol_offset )
  * Open and initialize display according to preferences specified in the vout
  * thread fields.
  *******************************************************************************/
-static int GGIOpenDisplay( vout_thread_t *p_vout )
+static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display )
 {
     ggi_mode    mode;                                       /* mode descriptor */    
+    ggi_color   col_fg;                                    /* foreground color */    
+    ggi_color   col_bg;                                    /* background color */    
+    int         i_index;                                 /* all purposes index */    
     
     /* Initialize library */
     if( ggiInit() )
@@ -168,7 +184,7 @@ static int GGIOpenDisplay( vout_thread_t *p_vout )
     }
 
     /* Open display */
-    p_vout->p_sys->p_display = ggiOpen( NULL );
+    p_vout->p_sys->p_display = ggiOpen( psz_display, NULL );
     if( p_vout->p_sys->p_display == NULL )
     {
         intf_ErrMsg("error: can't open GGI default display\n");
@@ -179,7 +195,7 @@ static int GGIOpenDisplay( vout_thread_t *p_vout )
     /* Find most appropriate mode */
     mode.frames =       2;                                        /* 2 buffers */
     mode.visible.x =    p_vout->i_width;                      /* minimum width */
-    mode.visible.y =    p_vout->i_width;                      /* maximum width */    
+    mode.visible.y =    p_vout->i_height;                    /* minimum height */    
     mode.virt.x =       GGI_AUTO;
     mode.virt.y =       GGI_AUTO;
     mode.size.x =       GGI_AUTO;
@@ -201,9 +217,75 @@ static int GGIOpenDisplay( vout_thread_t *p_vout )
         return( 1 );        
     }            
 
+    /* Check buffers properties */
+    p_vout->p_sys->b_must_acquire = 0;    
+    for( i_index = 0; i_index < 2; i_index++ )
+    {
+        /* Get buffer address */
+        p_vout->p_sys->p_buffer[ i_index ] = 
+            ggiDBGetBuffer( p_vout->p_sys->p_display, i_index );
+        if( p_vout->p_sys->p_buffer[ i_index ] == NULL )
+        {
+            intf_ErrMsg("error: double buffering is not possible\n");
+            ggiClose( p_vout->p_sys->p_display );        
+            ggiExit();
+            return( 1 );            
+        }        
+        
+        /* Check buffer properties */
+        if( ! (p_vout->p_sys->p_buffer[ i_index ]->type & GGI_DB_SIMPLE_PLB) ||
+            (p_vout->p_sys->p_buffer[ i_index ]->page_size != 0) ||
+            (p_vout->p_sys->p_buffer[ i_index ]->write == NULL ) ||
+            (p_vout->p_sys->p_buffer[ i_index ]->noaccess != 0) ||
+            (p_vout->p_sys->p_buffer[ i_index ]->align != 0) )
+        {
+            intf_ErrMsg("error: incorrect video memory type\n");
+            ggiClose( p_vout->p_sys->p_display );        
+            ggiExit();
+            return( 1 ); 
+        } 
+
+        /* Check if buffer needs to be acquired before write */
+        if( ggiResourceMustAcquire( p_vout->p_sys->p_buffer[ i_index ]->resource ) )
+        {
+            p_vout->p_sys->b_must_acquire = 1;            
+        }            
+    } 
+#ifdef DEBUG
+    if( p_vout->p_sys->b_must_acquire )
+    {
+        intf_DbgMsg("buffers must be acquired\n");        
+    }    
+#endif
+
+    /* Set graphic context colors */
+    col_fg.r = col_fg.g = col_fg.b = -1;    
+    col_bg.r = col_bg.g = col_bg.b = 0;    
+    if( ggiSetGCForeground(p_vout->p_sys->p_display, 
+                           ggiMapColor(p_vout->p_sys->p_display,&col_fg)) ||
+        ggiSetGCBackground(p_vout->p_sys->p_display, 
+                           ggiMapColor(p_vout->p_sys->p_display,&col_bg)) )
+    {
+        intf_ErrMsg("error: can't set colors\n");
+        ggiClose( p_vout->p_sys->p_display );        
+        ggiExit();
+        return( 1 );  
+    }    
+
+    /* Set clipping for text */
+    if( ggiSetGCClipping(p_vout->p_sys->p_display, 0, 0, 
+                         mode.visible.x, mode.visible.y ) )
+    {
+        intf_ErrMsg("error: can't set clipping\n");
+        ggiClose( p_vout->p_sys->p_display );        
+        ggiExit();
+        return( 1 );  
+    }
+    
     /* Set thread information */
     p_vout->i_width =           mode.visible.x;    
     p_vout->i_height =          mode.visible.y;
+    p_vout->i_bytes_per_line =  p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.stride;    
     switch( mode.graphtype )
     {
     case GT_15BIT:
@@ -230,6 +312,9 @@ static int GGIOpenDisplay( vout_thread_t *p_vout )
         break;        
     }
 
+    /* Set and initialize buffers */
+    vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ]->write, p_vout->p_sys->p_buffer[ 1 ]->write );
+
     return( 0 );    
 }