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 280:715202395e0f
prev160:17c4c0e4f9ce
next290:4d11ef6766be
author nkeynes
date Mon Jan 15 08:30:50 2007 +0000 (17 years ago)
permissions -rw-r--r--
last change Commit testyuv WIP
view annotate diff log raw
     1 /**
     2  * $Id: video_x11.c,v 1.7 2007-01-14 02:55:06 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 /**
    25  * General X11 parameters. The front-end driver is expected to set this up
    26  * by calling video_x11_set_display after initializing itself.
    27  */
    28 Display *video_x11_display = NULL;
    29 Screen *video_x11_screen = NULL;
    30 Window video_x11_window = 0;
    32 /**
    33  * GLX parameters.
    34  */
    35 GLXContext glx_context;
    36 Window glx_window;
    37 gboolean glx_open = FALSE;
    39 void video_x11_set_display( Display *display, Screen *screen, Window window )
    40 {
    41     video_x11_display = display;
    42     video_x11_screen = screen;
    43     video_x11_window = window;
    44 }
    47 gboolean video_glx_create_window( int x, int y, int width, int height )
    48 {
    49     int major, minor;
    50     const char *glxExts, *glxServer;
    51     int visual_attrs[] = { GLX_RGBA, GLX_RED_SIZE, 4, 
    52 			   GLX_GREEN_SIZE, 4, 
    53 			   GLX_BLUE_SIZE, 4,
    54 			   GLX_ALPHA_SIZE, 4,
    55 			   GLX_DEPTH_SIZE, 16,
    56 			   GLX_DOUBLEBUFFER, 
    57 			   None };
    58     int screen = XScreenNumberOfScreen(video_x11_screen);
    59     XSetWindowAttributes win_attrs;
    60     XVisualInfo *visual;
    62     if( glXQueryVersion( video_x11_display, &major, &minor ) == False ) {
    63 	ERROR( "X Display lacks the GLX nature" );
    64 	return FALSE;
    65     }
    66     if( major < 1 || minor < 2 ) {
    67 	ERROR( "X display supports GLX %d.%d, but we need at least 1.2", major, minor );
    68 	return FALSE;
    69     }
    71     glxExts = glXQueryExtensionsString( video_x11_display, screen );
    72     glxServer = glXQueryServerString( video_x11_display, screen, GLX_VENDOR );
    73     INFO( "GLX version %d.%d, %s. Supported exts: %s", major, minor,
    74 	  glxServer, glxExts );
    76     /* Find ourselves a nice visual */
    77     visual = glXChooseVisual( video_x11_display, 
    78 			      screen,
    79 			      visual_attrs );
    80     if( visual == NULL ) {
    81 	ERROR( "Unable to obtain a compatible visual" );
    82 	return FALSE;
    83     }
    85     /* And a matching gl context */
    86     glx_context = glXCreateContext( video_x11_display, visual, None, True );
    87     if( glx_context == NULL ) {
    88 	ERROR( "Unable to obtain a GLX Context. Possibly your system is broken in some small, undefineable way" );
    89 	return FALSE;
    90     }
    93     /* Ok, all good so far. Unfortunately the visual we need to use will 
    94      * almost certainly be different from the one our frame is using. Which 
    95      * means we have to jump through the following hoops to create a 
    96      * child window with the appropriate settings.
    97      */
    98     win_attrs.event_mask = 0;
    99     win_attrs.colormap = XCreateColormap( video_x11_display, 
   100 					  RootWindowOfScreen(video_x11_screen),
   101 					  visual->visual, AllocNone );
   102     glx_window = XCreateWindow( video_x11_display, video_x11_window, 
   103 				x, y, width, height, 0, visual->depth, 
   104 				InputOutput, visual->visual, 
   105 				CWColormap | CWEventMask, 
   106 				&win_attrs );
   107     if( glx_window == None ) {
   108 	/* Hrm. Aww, no window? */
   109 	ERROR( "Unable to create GLX window" );
   110 	glXDestroyContext( video_x11_display, glx_context );
   111 	if( win_attrs.colormap ) 
   112 	    XFreeColormap( video_x11_display, win_attrs.colormap );
   113 	return FALSE;
   114     }
   115     XMapRaised( video_x11_display, glx_window );
   117     /* And finally set the window to be the active drawing area */
   118     if( glXMakeCurrent( video_x11_display, glx_window, glx_context ) == False ) {
   119 	/* Ok you have _GOT_ to be kidding me */
   120 	ERROR( "Unable to prepare GLX window for drawing" );
   121 	XDestroyWindow( video_x11_display, glx_window );
   122 	XFreeColormap( video_x11_display, win_attrs.colormap );
   123 	glXDestroyContext( video_x11_display, glx_context );
   124 	return FALSE;
   125     }
   127     hasRequiredGLExtensions();
   128     fprintf(stderr, "GLX extensions: %s\n", glxExts );
   129     glx_open = TRUE;
   130     return TRUE;
   131 }
   133 int video_glx_load_font( const gchar *font_name )
   134 {
   135     int lists;
   136     XFontStruct *font = XLoadQueryFont(video_x11_display, font_name );
   137     if (font == NULL)
   138 	return -1;
   140     lists = glGenLists(96);
   141     glXUseXFont(font->fid, 32, 96, lists);
   142     XFreeFont(video_x11_display, font);
   143 }
   147 gboolean video_glx_set_render_format( int x, int y, int width, int height )
   148 {
   149     if( glx_open )
   150 	return TRUE;
   151     return video_glx_create_window( x, y, width, height );
   152 }
   154 gboolean video_glx_display_frame( video_buffer_t frame )
   155 {
   156     GLenum type, format = GL_RGB;
   157     switch( frame->colour_format ) {
   158     case COLFMT_RGB565:
   159 	type = GL_UNSIGNED_SHORT_5_6_5;
   160 	break;
   161     case COLFMT_RGB888:
   162 	type = GL_UNSIGNED_BYTE;
   163 	break;
   164     case COLFMT_ARGB1555:
   165 	type = GL_UNSIGNED_SHORT_5_5_5_1;
   166 	break;
   167     case COLFMT_ARGB8888:
   168 	format = GL_BGRA;
   169 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
   170 	break;
   171     }
   172     glDrawBuffer( GL_FRONT );
   173     glViewport( 0, 0, frame->hres, frame->vres );
   174     glMatrixMode(GL_PROJECTION);
   175     glLoadIdentity();
   176     glOrtho( 0, frame->hres, frame->vres, 0, 0, -65535 );
   177     glMatrixMode(GL_MODELVIEW);
   178     glLoadIdentity();
   179     glRasterPos2i( 0, 0 );
   180     glPixelZoom( 1.0f, -1.0f );
   181     glDrawPixels( frame->hres, frame->vres, format, type,
   182 		  frame->data );
   183     glFlush();
   184     return TRUE;
   185 }
   187 gboolean video_glx_blank( int width, int height, uint32_t colour )
   188 {
   189     glDrawBuffer( GL_FRONT );
   190     glViewport( 0, 0, width, height );
   191     glMatrixMode( GL_PROJECTION );
   192     glLoadIdentity();
   193     glOrtho( 0, width, height, 0, 0, -65535 );
   194     glMatrixMode(GL_MODELVIEW);
   195     glLoadIdentity();
   196     glColor3b( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF );
   197     glRecti(0,0, width, height );
   198     glFlush();
   199     return TRUE;
   200 }
   202 void video_glx_swap_buffers( void )
   203 {
   204     glXSwapBuffers( video_x11_display, glx_window );
   205 }
   207 void video_glx_create_pixmap( int width, int height )
   208 {
   210 }
.