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 531:f0fee3ba71d1
prev481:3b2d6c5a19ad
author nkeynes
date Wed Nov 21 11:45:33 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Add config guard around GTK display device
view annotate diff log raw
     1 /**
     2  * $Id: video_x11.c,v 1.20 2007-10-31 12:05:23 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 "pvr2/pvr2.h"
    23 #include "drivers/video_x11.h"
    24 #include "drivers/gl_common.h"
    26 extern uint32_t video_width, video_height;
    28 /**
    29  * General X11 parameters. The front-end driver is expected to set this up
    30  * by calling video_glx_init after initializing itself.
    31  */
    32 static Display *video_x11_display = NULL;
    33 static Screen *video_x11_screen = NULL;
    34 static Window video_x11_window = 0;
    35 static gboolean glsl_loaded = FALSE;
    37 /**
    38  * GLX parameters.
    39  */
    40 static GLXContext glx_context;
    41 static Window glx_window;
    42 static XSetWindowAttributes win_attrs;
    44 gboolean video_glx_create_window( int width, int height );
    45 gboolean video_glx_init_context( Window window );
    47 gboolean video_glx_init( Display *display, Screen *screen, Window window,
    48 			 int width, int height, display_driver_t driver )
    49 {
    50     video_x11_display = display;
    51     video_x11_screen = screen;
    52     glx_window = video_x11_window = window;
    54     if( !video_glx_init_context(glx_window) ) {
    55 	return FALSE;
    56     }
    58     if( !glXIsDirect(video_x11_display, glx_context) ) {
    59     	WARN( "Not using direct rendering - this is likely to be slow" );
    60     }
    62     if( gl_fbo_is_supported() ) {
    63 	gl_fbo_init(driver);
    65 #ifdef USE_GLSL
    66 	if( glsl_is_supported() ) {
    67 	    glsl_loaded = glsl_load_shaders( glsl_vertex_shader_src, glsl_fragment_shader_src );
    68 	    if( !glsl_loaded ) {
    69 	        WARN( "Shaders failed to load" );
    70 	    }
    71 	} else {
    72 	    WARN( "Shaders not supported" );
    73 	}
    74 #endif
    75 	return TRUE;
    76     } else {
    77 	/* Pbuffers? */
    78 	ERROR( "Framebuffer objects not supported (required in this version)" );
    79 	video_glx_shutdown();
    80 	return FALSE;
    81     }
    82 }
    84 /**
    85  * Create a new window with a custom visual - not used at the moment,
    86  * but retained for future reference.
    87  */
    88 gboolean video_x11_create_window( int width, int height )
    89 {
    90     int visual_attrs[] = { GLX_RGBA, GLX_RED_SIZE, 4, 
    91 			   GLX_GREEN_SIZE, 4, 
    92 			   GLX_BLUE_SIZE, 4,
    93 			   GLX_ALPHA_SIZE, 4,
    94 			   GLX_DEPTH_SIZE, 24,
    95 			   GLX_DOUBLEBUFFER, 
    96 			   None };
    97     int screen = XScreenNumberOfScreen(video_x11_screen);
    98     XVisualInfo *visual;
    99     /* Find ourselves a nice visual */
   100     visual = glXChooseVisual( video_x11_display, 
   101 			      screen,
   102 			      visual_attrs );
   104     /* Create a child window with the visual in question */
   105     win_attrs.event_mask = 0;
   106     win_attrs.colormap = XCreateColormap( video_x11_display, 
   107 					  RootWindowOfScreen(video_x11_screen),
   108 					  visual->visual, AllocNone );
   109     glx_window = XCreateWindow( video_x11_display, video_x11_window, 
   110 				0, 0, width, height, 0, visual->depth, 
   111 				InputOutput, visual->visual, 
   112 				CWColormap | CWEventMask, 
   113 				&win_attrs );
   114     if( glx_window == None ) {
   115 	/* Hrm. Aww, no window? */
   116 	ERROR( "Unable to create GLX window" );
   117 	if( win_attrs.colormap ) 
   118 	    XFreeColormap( video_x11_display, win_attrs.colormap );
   119 	XFree(visual);
   120 	return FALSE;
   121     }
   122     XMapRaised( video_x11_display, glx_window );
   124     XFree(visual);
   125     return TRUE;
   126 }
   128 gboolean video_glx_init_context( Window window )
   129 {
   130     XWindowAttributes attr;
   131     XVisualInfo *visual;
   132     XVisualInfo query;
   133     int query_items = 1;
   135     XGetWindowAttributes(video_x11_display, window, &attr);
   137     query.visualid = XVisualIDFromVisual(attr.visual);
   138     visual = XGetVisualInfo(video_x11_display, VisualIDMask, &query, &query_items );
   139     if( visual == NULL ) {
   140 	ERROR( "Unable to obtain a compatible visual" );
   141 	return FALSE;
   142     }
   144     int major, minor;
   145     if( glXQueryVersion( video_x11_display, &major, &minor ) == False ) {
   146 	ERROR( "X Display lacks the GLX nature" );
   147 	XFree(visual);
   148 	return FALSE;
   149     }
   150     if( major < 1 || minor < 2 ) {
   151 	ERROR( "X display supports GLX %d.%d, but we need at least 1.2", major, minor );
   152 	XFree(visual);
   153 	return FALSE;
   154     }
   156     /* And a matching gl context */
   157     glx_context = glXCreateContext( video_x11_display, visual, None, True );
   158     if( glx_context == NULL ) {
   159 	ERROR( "Unable to obtain a GLX Context. Possibly your system is broken in some small, undefineable way" );
   160 	XFree(visual);
   161 	return FALSE;
   162     }
   164     if( glXMakeCurrent( video_x11_display, window, glx_context ) == False ) {
   165 	ERROR( "Unable to prepare GLX context for drawing" );
   166 	glXDestroyContext( video_x11_display, glx_context );
   167 	XFree(visual);
   168 	return FALSE;
   169     }
   170     XFree(visual);
   172     texcache_gl_init();
   173     return TRUE;
   174 }
   177 void video_glx_shutdown()
   178 {
   179     if( glsl_loaded ) {
   180 	glsl_unload_shaders();
   181     }
   182     if( glx_window != None ) {
   183 	XDestroyWindow( video_x11_display, glx_window );
   184 	XFreeColormap( video_x11_display, win_attrs.colormap );
   185 	glx_window = None;
   186     }
   187     if( glx_context != NULL ) {
   188 	glXDestroyContext( video_x11_display, glx_context );
   189 	glx_context = NULL;
   190     }
   191 }
   194 int video_glx_load_font( const gchar *font_name )
   195 {
   196     int lists;
   197     XFontStruct *font = XLoadQueryFont(video_x11_display, font_name );
   198     if (font == NULL)
   199 	return -1;
   201     lists = glGenLists(96);
   202     glXUseXFont(font->fid, 32, 96, lists);
   203     XFreeFont(video_x11_display, font);
   204     return lists;
   205 }
   208 void video_glx_swap_buffers( void )
   209 {
   210     glXSwapBuffers( video_x11_display, glx_window );
   211 }
.