- * X11 events and allows window resizing. It returns a non null value on
- * error.
- *****************************************************************************/
-int vout_MGAManage( vout_thread_t *p_vout )
-{
- /*
- * Color/Grayscale or gamma change: in 8bpp, just change the colormap
- */
- if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE) && (p_vout->i_screen_depth == 8) )
- {
- /* FIXME: clear flags ?? */
- }
-
- /*
- * Size change
- */
- if( p_vout->i_changes & VOUT_SIZE_CHANGE )
- {
- intf_DbgMsg("resizing window");
- p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
-
- /* Resize window */
- XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
- p_vout->i_width, p_vout->i_height );
-
- /* Destroy XImages to change their size */
- vout_MGAEnd( p_vout );
-
- /* Recreate XImages. If SysInit failed, the thread can't go on. */
- if( vout_MGAInit( p_vout ) )
- {
- intf_ErrMsg("error: can't resize display");
- return( 1 );
- }
-
- /* Tell the video output thread that it will need to rebuild YUV
- * tables. This is needed since convertion buffer size may have changed */
- p_vout->i_changes |= VOUT_YUV_CHANGE;
- intf_Msg("vout: video display resized (%dx%d)", p_vout->i_width, p_vout->i_height);
- }
-
- return 0;
-}
-
-/*****************************************************************************
- * vout_MGADisplay: displays previously rendered output
- *****************************************************************************
- * This function send the currently rendered image to X11 server, wait until
- * it is displayed and switch the two rendering buffer, preparing next frame.
- *****************************************************************************/
-void vout_MGADisplay( vout_thread_t *p_vout )
-{
- if( p_vout->p_sys->b_shm) /* XShm is used */
- {
- /* Display rendered image using shared memory extension */
- XShmPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
- p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
- 0, 0, 0, 0,
- p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
- p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height, True);
-
- /* Send the order to the X server */
- XFlush(p_vout->p_sys->p_display);
- }
- else /* regular X11 capabilities are used */
- {
- XPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
- p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
- 0, 0, 0, 0,
- p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
- p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height);
-
- /* Send the order to the X server */
- XFlush(p_vout->p_sys->p_display);
- }
-}
-
-/* following functions are local */
-
-/*****************************************************************************
- * X11OpenDisplay: open and initialize X11 device
- *****************************************************************************
- * Create a window according to video output given size, and set other
- * properties according to the display properties.
- *****************************************************************************/
-static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root_window )
-{
- XPixmapFormatValues * p_xpixmap_format; /* pixmap formats */
- XVisualInfo * p_xvisual; /* visuals informations */
- XVisualInfo xvisual_template; /* visual template */
- int i_count; /* array size */
-
- /* Open display */
- p_vout->p_sys->p_display = XOpenDisplay( psz_display );
- if( p_vout->p_sys->p_display == NULL )
- {
- intf_ErrMsg("error: can't open display %s", psz_display );
- return( 1 );
- }
-
- /* Initialize structure */
- p_vout->p_sys->root_window = root_window;
- p_vout->p_sys->b_shm = (XShmQueryExtension(p_vout->p_sys->p_display) == True);
- p_vout->p_sys->i_screen = DefaultScreen( p_vout->p_sys->p_display );
- if( !p_vout->p_sys->b_shm )
- {
- intf_Msg("vout: XShm video extension is not available");
- }
-
- /* Get screen depth */
- p_vout->i_screen_depth = XDefaultDepth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen );
- switch( p_vout->i_screen_depth )
- {
- case 8:
- /*
- * Screen depth is 8bpp. Use PseudoColor visual with private colormap.
- */
- xvisual_template.screen = p_vout->p_sys->i_screen;
- xvisual_template.class = DirectColor;
- p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
- &xvisual_template, &i_count );
- if( p_xvisual == NULL )
- {
- intf_ErrMsg("error: no PseudoColor visual available");
- XCloseDisplay( p_vout->p_sys->p_display );
- return( 1 );
- }
- /* FIXME: SetColormap; ?? */
- p_vout->i_bytes_per_pixel = 1;
- break;
- case 15:
- case 16:
- case 24:
- default:
- /*
- * Screen depth is higher than 8bpp. TrueColor visual is used.
- */
- xvisual_template.screen = p_vout->p_sys->i_screen;
- xvisual_template.class = TrueColor;
- p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
- &xvisual_template, &i_count );
- if( p_xvisual == NULL )
- {
- intf_ErrMsg("error: no TrueColor visual available");
- XCloseDisplay( p_vout->p_sys->p_display );
- return( 1 );
- }
- p_vout->i_red_mask = p_xvisual->red_mask;
- p_vout->i_green_mask = p_xvisual->green_mask;
- p_vout->i_blue_mask = p_xvisual->blue_mask;
-
- /* There is no difference yet between 3 and 4 Bpp. The only way to find
- * the actual number of bytes per pixel is to list supported pixmap
- * formats. */
- p_xpixmap_format = XListPixmapFormats( p_vout->p_sys->p_display, &i_count );
- p_vout->i_bytes_per_pixel = 0;
- for( ; i_count--; p_xpixmap_format++ )
- {
- if( p_xpixmap_format->bits_per_pixel / 8 > p_vout->i_bytes_per_pixel )
- {
- p_vout->i_bytes_per_pixel = p_xpixmap_format->bits_per_pixel / 8;
- }
- }
- break;
- }
- p_vout->p_sys->p_visual = p_xvisual->visual;
- XFree( p_xvisual );
-
- /* Create a window */
- if( X11CreateWindow( p_vout ) )
- {
- intf_ErrMsg("error: can't open a window");
- XCloseDisplay( p_vout->p_sys->p_display );
- return( 1 );
- }
- return( 0 );
-}
-
-/*****************************************************************************
- * X11CloseDisplay: close X11 device
- *****************************************************************************
- * Returns all resources allocated by X11OpenDisplay and restore the original
- * state of the display.
- *****************************************************************************/
-static void X11CloseDisplay( vout_thread_t *p_vout )
-{
- /* Destroy colormap */
- if( p_vout->i_screen_depth == 8 )
- {
- XFreeColormap( p_vout->p_sys->p_display, p_vout->p_sys->colormap );
- }
-
- /* Destroy window and close display */
- X11DestroyWindow( p_vout );
- XCloseDisplay( p_vout->p_sys->p_display );
-}
-
-/*****************************************************************************
- * X11CreateWindow: create X11 vout window
- *****************************************************************************
- * The video output window will be created. Normally, this window is wether
- * full screen or part of a parent window. Therefore, it does not need a
- * title or other hints. Thery are still supplied in case the window would be
- * spawned as a standalone one by the interface.
- *****************************************************************************/
-static int X11CreateWindow( vout_thread_t *p_vout )
-{
- XSetWindowAttributes xwindow_attributes; /* window attributes */
- XGCValues xgcvalues; /* graphic context configuration */
- XEvent xevent; /* first events */
- boolean_t b_expose; /* 'expose' event received */
- boolean_t b_map_notify; /* 'map_notify' event received */
-
- /* Prepare window attributes */
- xwindow_attributes.backing_store = Always; /* save the hidden part */
-
- /* Create the window and set hints */
- p_vout->p_sys->window = XCreateSimpleWindow( p_vout->p_sys->p_display,
- p_vout->p_sys->root_window,
- 0, 0,
- p_vout->i_width, p_vout->i_height,
- 0, 0, 0);
- XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window,
- ExposureMask | StructureNotifyMask );
- XChangeWindowAttributes( p_vout->p_sys->p_display, p_vout->p_sys->window,
- CWBackingStore, &xwindow_attributes);
-
- /* Creation of a graphic context that doesn't generate a GraphicsExpose event
- when using functions like XCopyArea */
- xgcvalues.graphics_exposures = False;
- p_vout->p_sys->gc = XCreateGC( p_vout->p_sys->p_display, p_vout->p_sys->window,
- GCGraphicsExposures, &xgcvalues);
-
- /* Send orders to server, and wait until window is displayed - two events
- * must be received: a MapNotify event, an Expose event allowing drawing in the
- * window */
- b_expose = 0;
- b_map_notify = 0;
- XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window);
- do
- {
- XNextEvent( p_vout->p_sys->p_display, &xevent);
- if( (xevent.type == Expose)
- && (xevent.xexpose.window == p_vout->p_sys->window) )
- {
- b_expose = 1;
- }
- else if( (xevent.type == MapNotify)
- && (xevent.xmap.window == p_vout->p_sys->window) )
- {
- b_map_notify = 1;
- }
- }
- while( !( b_expose && b_map_notify ) );
- XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window, 0 );
-
- /* At this stage, the window is openned, displayed, and ready to receive
- * data */
- return( 0 );
-}
-
-/*****************************************************************************
- * X11DestroyWindow: destroy X11 window
- *****************************************************************************
- * Destroy an X11 window created by vout_CreateWindow
- *****************************************************************************/
-static void X11DestroyWindow( vout_thread_t *p_vout )
-{
- XUnmapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
- XFreeGC( p_vout->p_sys->p_display, p_vout->p_sys->gc );
- XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
-}
-
-/*****************************************************************************
- * X11CreateImage: create an XImage
- *****************************************************************************
- * Create a simple XImage used as a buffer.
- *****************************************************************************/
-static int X11CreateImage( vout_thread_t *p_vout, XImage **pp_ximage )
-{
- byte_t * pb_data; /* image data storage zone */
- int i_quantum; /* XImage quantum (see below) */
-
- /* Allocate memory for image */
- p_vout->i_bytes_per_line = p_vout->i_width * p_vout->i_bytes_per_pixel;
- pb_data = (byte_t *) malloc( p_vout->i_bytes_per_line * p_vout->i_height );
- if( !pb_data ) /* error */
- {
- intf_ErrMsg("error: %s", strerror(ENOMEM));
- return( 1 );
- }
-
- /* Optimize the quantum of a scanline regarding its size - the quantum is
- a diviser of the number of bits between the start of two scanlines. */
- if( !(( p_vout->i_bytes_per_line ) % 32) )
- {
- i_quantum = 32;
- }
- else
- {
- if( !(( p_vout->i_bytes_per_line ) % 16) )
- {
- i_quantum = 16;
- }
- else
- {
- i_quantum = 8;
- }
- }
-
- /* Create XImage */
- *pp_ximage = XCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
- p_vout->i_screen_depth, ZPixmap, 0, pb_data,
- p_vout->i_width, p_vout->i_height, i_quantum, 0);
- if(! *pp_ximage ) /* error */
- {
- intf_ErrMsg( "error: XCreateImage() failed" );
- free( pb_data );
- return( 1 );
- }
-
- return 0;
-}
-
-/*****************************************************************************
- * X11CreateShmImage: create an XImage using shared memory extension
- *****************************************************************************
- * Prepare an XImage for DisplayX11ShmImage function.
- * The order of the operations respects the recommandations of the mit-shm
- * document by J.Corbet and K.Packard. Most of the parameters were copied from
- * there.