Search
lxdream.org :: lxdream/src/drivers/video_x11.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/video_x11.c
changeset 370:3131ba1440fc
prev352:f0df7a6d4703
next405:570d93abb5b7
author nkeynes
date Sat Sep 08 04:05:35 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Handle video driver init failure cleanly (fallback to headless)
Hookup shutdown for the GTK driver
view annotate diff log raw
     1 /**
     2  * $Id: video_x11.c,v 1.13 2007-09-08 04:05:35 nkeynes Exp $
     3  *
     4  * Shared functions for all X11-based display drivers.
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <X11/Xlib.h>
    20 #include <GL/glx.h>
    21 #include "dream.h"
    22 #include "drivers/video_x11.h"
    24 extern uint32_t video_width, video_height;
    26 /**
    27  * General X11 parameters. The front-end driver is expected to set this up
    28  * by calling video_glx_init after initializing itself.
    29  */
    30 static Display *video_x11_display = NULL;
    31 static Screen *video_x11_screen = NULL;
    32 static Window video_x11_window = 0;
    34 /**
    35  * GLX parameters.
    36  */
    37 static GLXContext glx_context;
    38 static Window glx_window;
    39 static XSetWindowAttributes win_attrs;
    41 gboolean video_glx_init( Display *display, Screen *screen, Window window,
    42 			 int width, int height, display_driver_t driver )
    43 {
    44     video_x11_display = display;
    45     video_x11_screen = screen;
    46     video_x11_window = window;
    48     if( !video_glx_create_window(width,height) ) {
    49 	return FALSE;
    50     }
    52     if( gl_fbo_is_supported() ) {
    53 	gl_fbo_init(driver);
    54 	return TRUE;
    55     } else {
    56 	/* Pbuffers? */
    57 	ERROR( "Framebuffer objects not supported (required in this version)" );
    58 	video_glx_shutdown();
    59 	return FALSE;
    60     }
    61 }
    63 gboolean video_glx_create_window( int width, int height )
    64 {
    65     int major, minor;
    66     const char *glxExts, *glxServer;
    67     int visual_attrs[] = { GLX_RGBA, GLX_RED_SIZE, 4, 
    68 			   GLX_GREEN_SIZE, 4, 
    69 			   GLX_BLUE_SIZE, 4,
    70 			   GLX_ALPHA_SIZE, 4,
    71 			   GLX_DEPTH_SIZE, 24,
    72 			   GLX_DOUBLEBUFFER, 
    73 			   None };
    74     int screen = XScreenNumberOfScreen(video_x11_screen);
    75     XVisualInfo *visual;
    77     if( glXQueryVersion( video_x11_display, &major, &minor ) == False ) {
    78 	ERROR( "X Display lacks the GLX nature" );
    79 	return FALSE;
    80     }
    81     if( major < 1 || minor < 2 ) {
    82 	ERROR( "X display supports GLX %d.%d, but we need at least 1.2", major, minor );
    83 	return FALSE;
    84     }
    86     /* Find ourselves a nice visual */
    87     visual = glXChooseVisual( video_x11_display, 
    88 			      screen,
    89 			      visual_attrs );
    90     if( visual == NULL ) {
    91 	ERROR( "Unable to obtain a compatible visual" );
    92 	return FALSE;
    93     }
    95     /* And a matching gl context */
    96     glx_context = glXCreateContext( video_x11_display, visual, None, True );
    97     if( glx_context == NULL ) {
    98 	ERROR( "Unable to obtain a GLX Context. Possibly your system is broken in some small, undefineable way" );
    99 	return FALSE;
   100     }
   103     /* Ok, all good so far. Unfortunately the visual we need to use will 
   104      * almost certainly be different from the one our frame is using. Which 
   105      * means we have to jump through the following hoops to create a 
   106      * child window with the appropriate settings.
   107      */
   108     win_attrs.event_mask = 0;
   109     win_attrs.colormap = XCreateColormap( video_x11_display, 
   110 					  RootWindowOfScreen(video_x11_screen),
   111 					  visual->visual, AllocNone );
   112     glx_window = XCreateWindow( video_x11_display, video_x11_window, 
   113 				0, 0, width, height, 0, visual->depth, 
   114 				InputOutput, visual->visual, 
   115 				CWColormap | CWEventMask, 
   116 				&win_attrs );
   117     if( glx_window == None ) {
   118 	/* Hrm. Aww, no window? */
   119 	ERROR( "Unable to create GLX window" );
   120 	glXDestroyContext( video_x11_display, glx_context );
   121 	if( win_attrs.colormap ) 
   122 	    XFreeColormap( video_x11_display, win_attrs.colormap );
   123 	return FALSE;
   124     }
   125     XMapRaised( video_x11_display, glx_window );
   127     /* And finally set the window to be the active drawing area */
   128     if( glXMakeCurrent( video_x11_display, glx_window, glx_context ) == False ) {
   129 	/* Ok you have _GOT_ to be kidding me */
   130 	ERROR( "Unable to prepare GLX window for drawing" );
   131 	XDestroyWindow( video_x11_display, glx_window );
   132 	XFreeColormap( video_x11_display, win_attrs.colormap );
   133 	glXDestroyContext( video_x11_display, glx_context );
   134 	return FALSE;
   135     }
   136     return TRUE;
   137 }
   139 void video_glx_shutdown()
   140 {
   141     if( glx_window != None ) {
   142 	XDestroyWindow( video_x11_display, glx_window );
   143 	XFreeColormap( video_x11_display, win_attrs.colormap );
   144 	glx_window = None;
   145     }
   146     if( glx_context != NULL ) {
   147 	glXDestroyContext( video_x11_display, glx_context );
   148 	glx_context = NULL;
   149     }
   150 }
   153 int video_glx_load_font( const gchar *font_name )
   154 {
   155     int lists;
   156     XFontStruct *font = XLoadQueryFont(video_x11_display, font_name );
   157     if (font == NULL)
   158 	return -1;
   160     lists = glGenLists(96);
   161     glXUseXFont(font->fid, 32, 96, lists);
   162     XFreeFont(video_x11_display, font);
   163 }
   166 void video_glx_swap_buffers( void )
   167 {
   168     glXSwapBuffers( video_x11_display, glx_window );
   169 }
.