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 290:4d11ef6766be
prev280:715202395e0f
next317:7c90a7dc139b
author nkeynes
date Mon Jan 15 12:57:12 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Remove extension fprintf (accidental commit)
file annotate diff log raw
nkeynes@94
     1
/**
nkeynes@290
     2
 * $Id: video_x11.c,v 1.8 2007-01-15 12:57:12 nkeynes Exp $
nkeynes@94
     3
 *
nkeynes@103
     4
 * Shared functions for all X11-based display drivers.
nkeynes@94
     5
 *
nkeynes@94
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@94
     7
 *
nkeynes@94
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@94
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@94
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@94
    11
 * (at your option) any later version.
nkeynes@94
    12
 *
nkeynes@94
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@94
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@94
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@94
    16
 * GNU General Public License for more details.
nkeynes@94
    17
 */
nkeynes@94
    18
nkeynes@103
    19
#include <X11/Xlib.h>
nkeynes@103
    20
#include <GL/glx.h>
nkeynes@103
    21
#include "dream.h"
nkeynes@94
    22
#include "drivers/video_x11.h"
nkeynes@94
    23
nkeynes@103
    24
/**
nkeynes@103
    25
 * General X11 parameters. The front-end driver is expected to set this up
nkeynes@103
    26
 * by calling video_x11_set_display after initializing itself.
nkeynes@103
    27
 */
nkeynes@94
    28
Display *video_x11_display = NULL;
nkeynes@94
    29
Screen *video_x11_screen = NULL;
nkeynes@94
    30
Window video_x11_window = 0;
nkeynes@94
    31
nkeynes@103
    32
/**
nkeynes@103
    33
 * GLX parameters.
nkeynes@103
    34
 */
nkeynes@103
    35
GLXContext glx_context;
nkeynes@103
    36
Window glx_window;
nkeynes@103
    37
gboolean glx_open = FALSE;
nkeynes@103
    38
nkeynes@94
    39
void video_x11_set_display( Display *display, Screen *screen, Window window )
nkeynes@94
    40
{
nkeynes@94
    41
    video_x11_display = display;
nkeynes@94
    42
    video_x11_screen = screen;
nkeynes@94
    43
    video_x11_window = window;
nkeynes@94
    44
}
nkeynes@94
    45
nkeynes@103
    46
nkeynes@103
    47
gboolean video_glx_create_window( int x, int y, int width, int height )
nkeynes@103
    48
{
nkeynes@103
    49
    int major, minor;
nkeynes@103
    50
    const char *glxExts, *glxServer;
nkeynes@103
    51
    int visual_attrs[] = { GLX_RGBA, GLX_RED_SIZE, 4, 
nkeynes@103
    52
			   GLX_GREEN_SIZE, 4, 
nkeynes@103
    53
			   GLX_BLUE_SIZE, 4,
nkeynes@103
    54
			   GLX_ALPHA_SIZE, 4,
nkeynes@103
    55
			   GLX_DEPTH_SIZE, 16,
nkeynes@103
    56
			   GLX_DOUBLEBUFFER, 
nkeynes@103
    57
			   None };
nkeynes@103
    58
    int screen = XScreenNumberOfScreen(video_x11_screen);
nkeynes@103
    59
    XSetWindowAttributes win_attrs;
nkeynes@103
    60
    XVisualInfo *visual;
nkeynes@103
    61
nkeynes@103
    62
    if( glXQueryVersion( video_x11_display, &major, &minor ) == False ) {
nkeynes@103
    63
	ERROR( "X Display lacks the GLX nature" );
nkeynes@103
    64
	return FALSE;
nkeynes@103
    65
    }
nkeynes@103
    66
    if( major < 1 || minor < 2 ) {
nkeynes@103
    67
	ERROR( "X display supports GLX %d.%d, but we need at least 1.2", major, minor );
nkeynes@103
    68
	return FALSE;
nkeynes@103
    69
    }
nkeynes@103
    70
nkeynes@103
    71
    glxExts = glXQueryExtensionsString( video_x11_display, screen );
nkeynes@103
    72
    glxServer = glXQueryServerString( video_x11_display, screen, GLX_VENDOR );
nkeynes@103
    73
    INFO( "GLX version %d.%d, %s. Supported exts: %s", major, minor,
nkeynes@103
    74
	  glxServer, glxExts );
nkeynes@103
    75
nkeynes@103
    76
    /* Find ourselves a nice visual */
nkeynes@103
    77
    visual = glXChooseVisual( video_x11_display, 
nkeynes@103
    78
			      screen,
nkeynes@103
    79
			      visual_attrs );
nkeynes@103
    80
    if( visual == NULL ) {
nkeynes@103
    81
	ERROR( "Unable to obtain a compatible visual" );
nkeynes@103
    82
	return FALSE;
nkeynes@103
    83
    }
nkeynes@103
    84
nkeynes@103
    85
    /* And a matching gl context */
nkeynes@103
    86
    glx_context = glXCreateContext( video_x11_display, visual, None, True );
nkeynes@103
    87
    if( glx_context == NULL ) {
nkeynes@103
    88
	ERROR( "Unable to obtain a GLX Context. Possibly your system is broken in some small, undefineable way" );
nkeynes@103
    89
	return FALSE;
nkeynes@103
    90
    }
nkeynes@103
    91
    
nkeynes@103
    92
nkeynes@103
    93
    /* Ok, all good so far. Unfortunately the visual we need to use will 
nkeynes@103
    94
     * almost certainly be different from the one our frame is using. Which 
nkeynes@103
    95
     * means we have to jump through the following hoops to create a 
nkeynes@103
    96
     * child window with the appropriate settings.
nkeynes@103
    97
     */
nkeynes@103
    98
    win_attrs.event_mask = 0;
nkeynes@103
    99
    win_attrs.colormap = XCreateColormap( video_x11_display, 
nkeynes@103
   100
					  RootWindowOfScreen(video_x11_screen),
nkeynes@103
   101
					  visual->visual, AllocNone );
nkeynes@103
   102
    glx_window = XCreateWindow( video_x11_display, video_x11_window, 
nkeynes@103
   103
				x, y, width, height, 0, visual->depth, 
nkeynes@103
   104
				InputOutput, visual->visual, 
nkeynes@103
   105
				CWColormap | CWEventMask, 
nkeynes@103
   106
				&win_attrs );
nkeynes@103
   107
    if( glx_window == None ) {
nkeynes@103
   108
	/* Hrm. Aww, no window? */
nkeynes@103
   109
	ERROR( "Unable to create GLX window" );
nkeynes@103
   110
	glXDestroyContext( video_x11_display, glx_context );
nkeynes@103
   111
	if( win_attrs.colormap ) 
nkeynes@103
   112
	    XFreeColormap( video_x11_display, win_attrs.colormap );
nkeynes@103
   113
	return FALSE;
nkeynes@103
   114
    }
nkeynes@103
   115
    XMapRaised( video_x11_display, glx_window );
nkeynes@103
   116
nkeynes@103
   117
    /* And finally set the window to be the active drawing area */
nkeynes@103
   118
    if( glXMakeCurrent( video_x11_display, glx_window, glx_context ) == False ) {
nkeynes@103
   119
	/* Ok you have _GOT_ to be kidding me */
nkeynes@103
   120
	ERROR( "Unable to prepare GLX window for drawing" );
nkeynes@103
   121
	XDestroyWindow( video_x11_display, glx_window );
nkeynes@103
   122
	XFreeColormap( video_x11_display, win_attrs.colormap );
nkeynes@103
   123
	glXDestroyContext( video_x11_display, glx_context );
nkeynes@103
   124
	return FALSE;
nkeynes@103
   125
    }
nkeynes@280
   126
nkeynes@280
   127
    hasRequiredGLExtensions();
nkeynes@103
   128
    glx_open = TRUE;
nkeynes@103
   129
    return TRUE;
nkeynes@103
   130
}
nkeynes@103
   131
nkeynes@108
   132
int video_glx_load_font( const gchar *font_name )
nkeynes@108
   133
{
nkeynes@108
   134
    int lists;
nkeynes@108
   135
    XFontStruct *font = XLoadQueryFont(video_x11_display, font_name );
nkeynes@108
   136
    if (font == NULL)
nkeynes@108
   137
	return -1;
nkeynes@108
   138
    
nkeynes@108
   139
    lists = glGenLists(96);
nkeynes@108
   140
    glXUseXFont(font->fid, 32, 96, lists);
nkeynes@108
   141
    XFreeFont(video_x11_display, font);
nkeynes@108
   142
}
nkeynes@108
   143
nkeynes@108
   144
nkeynes@108
   145
nkeynes@108
   146
gboolean video_glx_set_render_format( int x, int y, int width, int height )
nkeynes@108
   147
{
nkeynes@108
   148
    if( glx_open )
nkeynes@108
   149
	return TRUE;
nkeynes@108
   150
    return video_glx_create_window( x, y, width, height );
nkeynes@108
   151
}
nkeynes@108
   152
nkeynes@112
   153
gboolean video_glx_display_frame( video_buffer_t frame )
nkeynes@112
   154
{
nkeynes@112
   155
    GLenum type, format = GL_RGB;
nkeynes@112
   156
    switch( frame->colour_format ) {
nkeynes@112
   157
    case COLFMT_RGB565:
nkeynes@112
   158
	type = GL_UNSIGNED_SHORT_5_6_5;
nkeynes@112
   159
	break;
nkeynes@112
   160
    case COLFMT_RGB888:
nkeynes@112
   161
	type = GL_UNSIGNED_BYTE;
nkeynes@112
   162
	break;
nkeynes@112
   163
    case COLFMT_ARGB1555:
nkeynes@112
   164
	type = GL_UNSIGNED_SHORT_5_5_5_1;
nkeynes@112
   165
	break;
nkeynes@112
   166
    case COLFMT_ARGB8888:
nkeynes@112
   167
	format = GL_BGRA;
nkeynes@112
   168
	type = GL_UNSIGNED_INT_8_8_8_8_REV;
nkeynes@112
   169
	break;
nkeynes@112
   170
    }
nkeynes@112
   171
    glDrawBuffer( GL_FRONT );
nkeynes@112
   172
    glViewport( 0, 0, frame->hres, frame->vres );
nkeynes@112
   173
    glMatrixMode(GL_PROJECTION);
nkeynes@112
   174
    glLoadIdentity();
nkeynes@112
   175
    glOrtho( 0, frame->hres, frame->vres, 0, 0, -65535 );
nkeynes@112
   176
    glMatrixMode(GL_MODELVIEW);
nkeynes@112
   177
    glLoadIdentity();
nkeynes@112
   178
    glRasterPos2i( 0, 0 );
nkeynes@112
   179
    glPixelZoom( 1.0f, -1.0f );
nkeynes@112
   180
    glDrawPixels( frame->hres, frame->vres, format, type,
nkeynes@112
   181
		  frame->data );
nkeynes@112
   182
    glFlush();
nkeynes@112
   183
    return TRUE;
nkeynes@112
   184
}
nkeynes@112
   185
nkeynes@160
   186
gboolean video_glx_blank( int width, int height, uint32_t colour )
nkeynes@160
   187
{
nkeynes@160
   188
    glDrawBuffer( GL_FRONT );
nkeynes@160
   189
    glViewport( 0, 0, width, height );
nkeynes@160
   190
    glMatrixMode( GL_PROJECTION );
nkeynes@160
   191
    glLoadIdentity();
nkeynes@160
   192
    glOrtho( 0, width, height, 0, 0, -65535 );
nkeynes@160
   193
    glMatrixMode(GL_MODELVIEW);
nkeynes@160
   194
    glLoadIdentity();
nkeynes@160
   195
    glColor3b( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF );
nkeynes@160
   196
    glRecti(0,0, width, height );
nkeynes@160
   197
    glFlush();
nkeynes@160
   198
    return TRUE;
nkeynes@160
   199
}
nkeynes@160
   200
nkeynes@103
   201
void video_glx_swap_buffers( void )
nkeynes@103
   202
{
nkeynes@103
   203
    glXSwapBuffers( video_x11_display, glx_window );
nkeynes@103
   204
}
nkeynes@103
   205
nkeynes@103
   206
void video_glx_create_pixmap( int width, int height )
nkeynes@103
   207
{
nkeynes@103
   208
nkeynes@103
   209
}
.