/* 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 );
/*******************************************************************************
* 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 ) );
}
/* 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 );
}
*******************************************************************************/
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 );
}
*******************************************************************************/
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 );
+ }
}
/*******************************************************************************
* 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 );
}
/*******************************************************************************
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 */
* 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() )
}
/* 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");
/* 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;
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:
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 );
}