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 439:f0c7928c5914
prev436:e8c461d2545e
next442:c0dcf22c8e08
author nkeynes
date Thu Oct 11 11:09:10 2007 +0000 (13 years ago)
permissions -rw-r--r--
last change Use the default visual (all we do is render onto the front buffer, so we don't really care what it is)
view annotate diff log raw
     1 /**
     2  * $Id: video_x11.c,v 1.17 2007-10-11 11:09:10 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"
    23 #include "drivers/gl_common.h"
    25 extern uint32_t video_width, video_height;
    27 /**
    28  * General X11 parameters. The front-end driver is expected to set this up
    29  * by calling video_glx_init after initializing itself.
    30  */
    31 static Display *video_x11_display = NULL;
    32 static Screen *video_x11_screen = NULL;
    33 static Window video_x11_window = 0;
    34 static gboolean glsl_loaded = FALSE;
    36 /**
    37  * GLX parameters.
    38  */
    39 static GLXContext glx_context;
    40 static Window glx_window;
    41 static XSetWindowAttributes win_attrs;
    43 gboolean video_glx_create_window( int width, int height );
    45 gboolean video_glx_init( Display *display, Screen *screen, Window window,
    46 			 int width, int height, display_driver_t driver )
    47 {
    48     video_x11_display = display;
    49     video_x11_screen = screen;
    50     video_x11_window = window;
    52     if( !video_glx_create_window(width,height) ) {
    53 	return FALSE;
    54     }
    56     if( gl_fbo_is_supported() ) {
    57 	gl_fbo_init(driver);
    59 #ifdef USE_GLSL
    60 	if( glsl_is_supported() ) {
    61 	    glsl_loaded = glsl_load_shaders( glsl_vertex_shader_src, glsl_fragment_shader_src );
    62 	    if( !glsl_loaded ) {
    63 	        WARN( "Shaders failed to load" );
    64 	    }
    65 	} else {
    66 	    WARN( "Shaders not supported" );
    67 	}
    68 #endif
    69 	return TRUE;
    70     } else {
    71 	/* Pbuffers? */
    72 	ERROR( "Framebuffer objects not supported (required in this version)" );
    73 	video_glx_shutdown();
    74 	return FALSE;
    75     }
    76 }
    78 gboolean video_glx_create_window( int width, int height )
    79 {
    80     int major, minor;
    81     int visual_attrs[] = { GLX_RGBA, GLX_RED_SIZE, 4, 
    82 			   GLX_GREEN_SIZE, 4, 
    83 			   GLX_BLUE_SIZE, 4,
    84 			   GLX_ALPHA_SIZE, 4,
    85 			   GLX_DEPTH_SIZE, 24,
    86 			   GLX_DOUBLEBUFFER, 
    87 			   None };
    88     int screen = XScreenNumberOfScreen(video_x11_screen);
    89     XVisualInfo *visual;
    91     if( glXQueryVersion( video_x11_display, &major, &minor ) == False ) {
    92 	ERROR( "X Display lacks the GLX nature" );
    93 	return FALSE;
    94     }
    95     if( major < 1 || minor < 2 ) {
    96 	ERROR( "X display supports GLX %d.%d, but we need at least 1.2", major, minor );
    97 	return FALSE;
    98     }
   100     XVisualInfo query;
   101     int query_items = 1;
   102     query.visualid = XVisualIDFromVisual(DefaultVisual(video_x11_display, screen));
   103     visual = XGetVisualInfo(video_x11_display, VisualIDMask, &query, &query_items );
   106     /* Find ourselves a nice visual */
   107     //visual = glXChooseVisual( video_x11_display, 
   108     //		      screen,
   109     //		      visual_attrs );
   110     if( visual == NULL ) {
   111 	ERROR( "Unable to obtain a compatible visual" );
   112 	return FALSE;
   113     }
   115     /* And a matching gl context */
   116     glx_context = glXCreateContext( video_x11_display, visual, None, True );
   117     if( glx_context == NULL ) {
   118 	ERROR( "Unable to obtain a GLX Context. Possibly your system is broken in some small, undefineable way" );
   119 	return FALSE;
   120     }
   121     #if 0
   123     /* Ok, all good so far. Unfortunately the visual we need to use will 
   124      * almost certainly be different from the one our frame is using. Which 
   125      * means we have to jump through the following hoops to create a 
   126      * child window with the appropriate settings.
   127      */
   128     win_attrs.event_mask = 0;
   129     win_attrs.colormap = XCreateColormap( video_x11_display, 
   130 					  RootWindowOfScreen(video_x11_screen),
   131 					  visual->visual, AllocNone );
   132     glx_window = XCreateWindow( video_x11_display, video_x11_window, 
   133 				0, 0, width, height, 0, visual->depth, 
   134 				InputOutput, visual->visual, 
   135 				CWColormap | CWEventMask, 
   136 				&win_attrs );
   137     if( glx_window == None ) {
   138 	/* Hrm. Aww, no window? */
   139 	ERROR( "Unable to create GLX window" );
   140 	glXDestroyContext( video_x11_display, gtl_context );
   141 	if( win_attrs.colormap ) 
   142 	    XFreeColormap( video_x11_display, win_attrs.colormap );
   143 	return FALSE;
   144     }
   145     XMapRaised( video_x11_display, glx_window );
   146     #endif
   148     glx_window = video_x11_window;
   150     /* And finally set the window to be the active drawing area */
   151     if( glXMakeCurrent( video_x11_display, glx_window, glx_context ) == False ) {
   152 	/* Ok you have _GOT_ to be kidding me */
   153 	ERROR( "Unable to prepare GLX window for drawing" );
   154 	XDestroyWindow( video_x11_display, glx_window );
   155 	XFreeColormap( video_x11_display, win_attrs.colormap );
   156 	glXDestroyContext( video_x11_display, glx_context );
   157 	return FALSE;
   158     }
   159     return TRUE;
   160 }
   162 void video_glx_shutdown()
   163 {
   164     if( glsl_loaded ) {
   165 	glsl_unload_shaders();
   166     }
   167     if( glx_window != None ) {
   168 	XDestroyWindow( video_x11_display, glx_window );
   169 	XFreeColormap( video_x11_display, win_attrs.colormap );
   170 	glx_window = None;
   171     }
   172     if( glx_context != NULL ) {
   173 	glXDestroyContext( video_x11_display, glx_context );
   174 	glx_context = NULL;
   175     }
   176 }
   179 int video_glx_load_font( const gchar *font_name )
   180 {
   181     int lists;
   182     XFontStruct *font = XLoadQueryFont(video_x11_display, font_name );
   183     if (font == NULL)
   184 	return -1;
   186     lists = glGenLists(96);
   187     glXUseXFont(font->fid, 32, 96, lists);
   188     XFreeFont(video_x11_display, font);
   189     return lists;
   190 }
   193 void video_glx_swap_buffers( void )
   194 {
   195     glXSwapBuffers( video_x11_display, glx_window );
   196 }
.