summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/x11
diff options
context:
space:
mode:
authorjtg <jtg>1999-08-19 00:55:39 +0000
committerjtg <jtg>1999-08-19 00:55:39 +0000
commitafb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1c (patch)
tree59d65b4da12fb5379224cf5f6b808fde91523c7f /src/mesa/drivers/x11
parentf2544d4920ce168bec9cd94d774b7ea5103a3d74 (diff)
Initial revision
Diffstat (limited to 'src/mesa/drivers/x11')
-rw-r--r--src/mesa/drivers/x11/fakeglx.c1516
-rw-r--r--src/mesa/drivers/x11/glxapi.c405
-rw-r--r--src/mesa/drivers/x11/realglx.c239
-rw-r--r--src/mesa/drivers/x11/realglx.h111
-rw-r--r--src/mesa/drivers/x11/xfonts.c398
-rw-r--r--src/mesa/drivers/x11/xmesaP.h499
6 files changed, 3168 insertions, 0 deletions
diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
new file mode 100644
index 0000000000..12567fe19c
--- /dev/null
+++ b/src/mesa/drivers/x11/fakeglx.c
@@ -0,0 +1,1516 @@
+/* $Id: fakeglx.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * A pseudo-GLX implementation to allow OpenGL/GLX programs to work with Mesa.
+ * The Fake_glX*() functions implemented here are called from glxapi.c
+ *
+ * Thanks to the contributors:
+ *
+ * Initial version: Philip Brown (philb@CSUA.Berkeley.EDU)
+ * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu)
+ * Further visual-handling refinements: Wolfram Gloger
+ * (wmglo@Dent.MED.Uni-Muenchen.DE).
+ *
+ * Notes:
+ * Don't be fooled, stereo isn't supported yet.
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/gl.h"
+#include "GL/xmesa.h"
+#include "context.h"
+#include "config.h"
+#include "fakeglx.h"
+#include "macros.h"
+#include "types.h"
+#include "xmesaP.h"
+
+
+
+#define DONT_CARE -1
+
+
+
+#define MAX_VISUALS 100
+static XMesaVisual VisualTable[MAX_VISUALS];
+static int NumVisuals = 0;
+
+
+
+/*
+ * This struct and some code fragments borrowed
+ * from Mark Kilgard's GLUT library.
+ */
+typedef struct _OverlayInfo {
+ /* Avoid 64-bit portability problems by being careful to use
+ longs due to the way XGetWindowProperty is specified. Note
+ that these parameters are passed as CARD32s over X
+ protocol. */
+ unsigned long overlay_visual;
+ long transparent_type;
+ long value;
+ long layer;
+} OverlayInfo;
+
+
+
+/* Macro to handle c_class vs class field name in XVisualInfo struct */
+#if defined(__cplusplus) || defined(c_plusplus)
+#define CLASS c_class
+#else
+#define CLASS class
+#endif
+
+
+
+
+/*
+ * Test if the given XVisualInfo is usable for Mesa rendering.
+ */
+static GLboolean is_usable_visual( XVisualInfo *vinfo )
+{
+ switch (vinfo->CLASS) {
+ case StaticGray:
+ case GrayScale:
+ /* Any StaticGray/GrayScale visual works in RGB or CI mode */
+ return GL_TRUE;
+ case StaticColor:
+ case PseudoColor:
+ /* Any StaticColor/PseudoColor visual of at least 4 bits */
+ if (vinfo->depth>=4) {
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+ case TrueColor:
+ case DirectColor:
+ /* Any depth of TrueColor or DirectColor works in RGB mode */
+ return GL_TRUE;
+ default:
+ /* This should never happen */
+ return GL_FALSE;
+ }
+}
+
+
+
+/*
+ * Return the level (overlay, normal, underlay) of a given XVisualInfo.
+ * Input: dpy - the X display
+ * vinfo - the XVisualInfo to test
+ * Return: level of the visual:
+ * 0 = normal planes
+ * >0 = overlay planes
+ * <0 = underlay planes
+ */
+static int level_of_visual( Display *dpy, XVisualInfo *vinfo )
+{
+ Atom overlayVisualsAtom;
+ OverlayInfo *overlay_info = NULL;
+ int numOverlaysPerScreen;
+ Status status;
+ Atom actualType;
+ int actualFormat;
+ unsigned long sizeData, bytesLeft;
+ int i;
+
+ /*
+ * The SERVER_OVERLAY_VISUALS property on the root window contains
+ * a list of overlay visuals. Get that list now.
+ */
+ overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
+ if (overlayVisualsAtom == None) {
+ return 0;
+ }
+
+ status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
+ overlayVisualsAtom, 0L, (long) 10000, False,
+ overlayVisualsAtom, &actualType, &actualFormat,
+ &sizeData, &bytesLeft,
+ (unsigned char **) &overlay_info );
+
+ if (status != Success || actualType != overlayVisualsAtom ||
+ actualFormat != 32 || sizeData < 4) {
+ /* something went wrong */
+ XFree((void *) overlay_info);
+ return 0;
+ }
+
+ /* search the overlay visual list for the visual ID of interest */
+ numOverlaysPerScreen = (int) (sizeData / 4);
+ for (i=0;i<numOverlaysPerScreen;i++) {
+ OverlayInfo *ov;
+ ov = overlay_info + i;
+ if (ov->overlay_visual==vinfo->visualid) {
+ /* found the visual */
+ if (/*ov->transparent_type==1 &&*/ ov->layer!=0) {
+ int level = ov->layer;
+ XFree((void *) overlay_info);
+ return level;
+ }
+ else {
+ XFree((void *) overlay_info);
+ return 0;
+ }
+ }
+ }
+
+ /* The visual ID was not found in the overlay list. */
+ XFree((void *) overlay_info);
+ return 0;
+}
+
+
+
+
+/*
+ * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
+ * configuration in our list of GLX visuals.
+ */
+static XMesaVisual
+save_glx_visual( Display *dpy, XVisualInfo *vinfo,
+ GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint depth_size, GLint stencil_size,
+ GLint accum_size, GLint level )
+{
+ GLboolean ximageFlag = GL_TRUE;
+ XMesaVisual xmvis;
+ GLint i;
+ GLboolean comparePointers;
+
+ if (dbFlag) {
+ /* Check if the MESA_BACK_BUFFER env var is set */
+ char *backbuffer = getenv("MESA_BACK_BUFFER");
+ if (backbuffer) {
+ if (backbuffer[0]=='p' || backbuffer[0]=='P') {
+ ximageFlag = GL_FALSE;
+ }
+ else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
+ ximageFlag = GL_TRUE;
+ }
+ else {
+ fprintf(stderr, "Mesa: invalid value for MESA_BACK_BUFFER ");
+ fprintf(stderr, "environment variable, using an XImage.\n");
+ }
+ }
+ }
+
+ /* Comparing IDs uses less memory but sometimes fails. */
+ /* XXX revisit this after 3.0 is finished. */
+ if (getenv("MESA_GLX_VISUAL_HACK"))
+ comparePointers = GL_TRUE;
+ else
+ comparePointers = GL_FALSE;
+
+ /* First check if a matching visual is already in the list */
+ for (i=0; i<NumVisuals; i++) {
+ XMesaVisual v = VisualTable[i];
+ if (v->display == dpy
+ && v->level == level
+ && v->ximage_flag == ximageFlag
+ && v->gl_visual->RGBAflag == rgbFlag
+ && v->gl_visual->DBflag == dbFlag
+ && v->gl_visual->StereoFlag == stereoFlag
+ && (v->gl_visual->AlphaBits > 0) == alphaFlag
+ && (v->gl_visual->DepthBits >= depth_size || depth_size == 0)
+ && (v->gl_visual->StencilBits >= stencil_size || stencil_size == 0)
+ && (v->gl_visual->AccumBits >= accum_size || accum_size == 0)) {
+ /* now either compare XVisualInfo pointers or visual IDs */
+ if ((!comparePointers && v->vishandle->visualid == vinfo->visualid)
+ || (comparePointers && v->vishandle == vinfo)) {
+ return v;
+ }
+ }
+ }
+
+ /* Create a new visual and add it to the list. */
+
+ if (NumVisuals>=MAX_VISUALS) {
+ fprintf( stderr, "GLX Error: maximum number of visuals exceeded\n");
+ return NULL;
+ }
+
+ xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
+ stereoFlag, ximageFlag,
+ depth_size, stencil_size, accum_size, level );
+ if (xmvis) {
+ VisualTable[NumVisuals] = xmvis;
+ NumVisuals++;
+ }
+ return xmvis;
+}
+
+
+
+/*
+ * Create a GLX visual from a regular XVisualInfo.
+ */
+static XMesaVisual
+create_glx_visual( Display *dpy, XVisualInfo *visinfo )
+{
+ int vislevel;
+
+ vislevel = level_of_visual( dpy, visinfo );
+ if (vislevel) {
+ /* Configure this visual as a CI, single-buffered overlay */
+ return save_glx_visual( dpy, visinfo,
+ GL_FALSE, /* rgb */
+ GL_FALSE, /* alpha */
+ GL_FALSE, /* double */
+ GL_FALSE, /* stereo */
+ 0, /* depth bits */
+ 0, /* stencil bits */
+ 0, /* accum bits */
+ vislevel /* level */
+ );
+ }
+ else if (is_usable_visual( visinfo )) {
+ /* Configure this visual as RGB, double-buffered, depth-buffered. */
+ /* This is surely wrong for some people's needs but what else */
+ /* can be done? They should use glXChooseVisual(). */
+ return save_glx_visual( dpy, visinfo,
+ GL_TRUE, /* rgb */
+ GL_FALSE, /* alpha */
+ GL_TRUE, /* double */
+ GL_FALSE, /* stereo */
+ 8*sizeof(GLdepth),
+ 8*sizeof(GLstencil),
+ 8*sizeof(GLaccum),
+ 0 /* level */
+ );
+ }
+ else {
+ fprintf(stderr,"Mesa: error in glXCreateContext: bad visual\n");
+ return NULL;
+ }
+}
+
+
+
+/*
+ * Find the GLX visual associated with an XVisualInfo.
+ */
+static XMesaVisual
+find_glx_visual( Display *dpy, XVisualInfo *vinfo )
+{
+ int i;
+
+ /* First try to match pointers */
+ for (i=0;i<NumVisuals;i++) {
+ if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
+ return VisualTable[i];
+ }
+ }
+ /* try to match visual id */
+ for (i=0;i<NumVisuals;i++) {
+ if (VisualTable[i]->display==dpy
+ && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
+ return VisualTable[i];
+ }
+ }
+ return NULL;
+}
+
+
+
+/*
+ * Return the transparent pixel value for a GLX visual.
+ * Input: glxvis - the glx_visual
+ * Return: a pixel value or -1 if no transparent pixel
+ */
+static int transparent_pixel( XMesaVisual glxvis )
+{
+ Display *dpy = glxvis->display;
+ XVisualInfo *vinfo = glxvis->visinfo;
+ Atom overlayVisualsAtom;
+ OverlayInfo *overlay_info = NULL;
+ int numOverlaysPerScreen;
+ Status status;
+ Atom actualType;
+ int actualFormat;
+ unsigned long sizeData, bytesLeft;
+ int i;
+
+ /*
+ * The SERVER_OVERLAY_VISUALS property on the root window contains
+ * a list of overlay visuals. Get that list now.
+ */
+ overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
+ if (overlayVisualsAtom == None) {
+ return -1;
+ }
+
+ status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
+ overlayVisualsAtom, 0L, (long) 10000, False,
+ overlayVisualsAtom, &actualType, &actualFormat,
+ &sizeData, &bytesLeft,
+ (unsigned char **) &overlay_info );
+
+ if (status != Success || actualType != overlayVisualsAtom ||
+ actualFormat != 32 || sizeData < 4) {
+ /* something went wrong */
+ XFree((void *) overlay_info);
+ return -1;
+ }
+
+ /* search the overlay visual list for the visual ID of interest */
+ numOverlaysPerScreen = (int) (sizeData / 4);
+ for (i=0;i<numOverlaysPerScreen;i++) {
+ OverlayInfo *ov;
+ ov = overlay_info + i;
+ if (ov->overlay_visual==vinfo->visualid) {
+ /* found it! */
+ if (ov->transparent_type==0) {
+ /* type 0 indicates no transparency */
+ XFree((void *) overlay_info);
+ return -1;
+ }
+ else {
+ /* ov->value is the transparent pixel */
+ XFree((void *) overlay_info);
+ return ov->value;
+ }
+ }
+ }
+
+ /* The visual ID was not found in the overlay list. */
+ XFree((void *) overlay_info);
+ return -1;
+}
+
+
+
+/*
+ * Return number of bits set in n.
+ */
+static int bitcount( unsigned long n )
+{
+ int bits;
+ for (bits=0; n>0; n=n>>1) {
+ if (n&1) {
+ bits++;
+ }
+ }
+ return bits;
+}
+
+
+/*
+ * Try to get an X visual which matches the given arguments.
+ */
+static XVisualInfo *get_visual( Display *dpy, int scr,
+ unsigned int depth, int xclass )
+{
+ XVisualInfo temp, *vis;
+ long mask;
+ int n;
+ unsigned int default_depth;
+ int default_class;
+
+ mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
+ temp.screen = scr;
+ temp.depth = depth;
+ temp.CLASS = xclass;
+
+ default_depth = DefaultDepth(dpy,scr);
+ default_class = DefaultVisual(dpy,scr)->CLASS;
+
+ if (depth==default_depth && xclass==default_class) {
+ /* try to get root window's visual */
+ temp.visualid = DefaultVisual(dpy,scr)->visualid;
+ mask |= VisualIDMask;
+ }
+
+ vis = XGetVisualInfo( dpy, mask, &temp, &n );
+
+ /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
+ * An SGI Infinite Reality system, for example, can have 30bpp pixels:
+ * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel.
+ */
+ if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
+ if (bitcount(vis->red_mask) <= 8
+ && bitcount(vis->green_mask) <= 8
+ && bitcount(vis->blue_mask) <= 8) {
+ return vis;
+ }
+ else {
+ XFree((void *) vis);
+ return NULL;
+ }
+ }
+
+ return vis;
+}
+
+
+
+/*
+ * Retrieve the value of the given environment variable and find
+ * the X visual which matches it.
+ * Input: dpy - the display
+ * screen - the screen number
+ * varname - the name of the environment variable
+ * Return: an XVisualInfo pointer to NULL if error.
+ */
+static XVisualInfo *get_env_visual(Display *dpy, int scr, const char *varname)
+{
+ char value[100], type[100];
+ int depth, xclass = -1;
+ XVisualInfo *vis;
+
+ if (!getenv( varname )) {
+ return NULL;
+ }
+
+ strncpy( value, getenv(varname), 100 );
+ value[99] = 0;
+
+ sscanf( value, "%s %d", type, &depth );
+
+ if (strcmp(type,"TrueColor")==0) xclass = TrueColor;
+ else if (strcmp(type,"DirectColor")==0) xclass = DirectColor;
+ else if (strcmp(type,"PseudoColor")==0) xclass = PseudoColor;
+ else if (strcmp(type,"StaticColor")==0) xclass = StaticColor;
+ else if (strcmp(type,"GrayScale")==0) xclass = GrayScale;
+ else if (strcmp(type,"StaticGray")==0) xclass = StaticGray;
+
+ if (xclass>-1 && depth>0) {
+ vis = get_visual( dpy, scr, depth, xclass );
+ if (vis) {
+ return vis;
+ }
+ }
+
+ fprintf( stderr, "Mesa: GLX unable to find visual class=%s, depth=%d.\n",
+ type, depth );
+ return NULL;
+}
+
+
+
+/*
+ * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
+ * Input: dpy, screen - X display and screen number
+ * rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode
+ * min_depth - minimum visual depth
+ * preferred_class - preferred GLX visual class or DONT_CARE
+ * Return: pointer to an XVisualInfo or NULL.
+ */
+static XVisualInfo *choose_x_visual( Display *dpy, int screen,
+ GLboolean rgba, int min_depth,
+ int preferred_class )
+{
+ XVisualInfo *vis;
+ int xclass, visclass;
+ int depth;
+
+ if (rgba) {
+ Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
+ /* First see if the MESA_RGB_VISUAL env var is defined */
+ vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
+ if (vis) {
+ return vis;
+ }
+ /* Otherwise, search for a suitable visual */
+ if (preferred_class==DONT_CARE) {
+ for (xclass=0;xclass<6;xclass++) {
+ switch (xclass) {
+ case 0: visclass = TrueColor; break;
+ case 1: visclass = DirectColor; break;
+ case 2: visclass = PseudoColor; break;
+ case 3: visclass = StaticColor; break;
+ case 4: visclass = GrayScale; break;
+ case 5: visclass = StaticGray; break;
+ }
+ if (min_depth==0) {
+ /* start with shallowest */
+ for (depth=0;depth<=32;depth++) {
+ if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
+ /* Special case: try to get 8-bit PseudoColor before */
+ /* 8-bit TrueColor */
+ vis = get_visual( dpy, screen, 8, PseudoColor );
+ if (vis) {
+ return vis;
+ }
+ }
+ vis = get_visual( dpy, screen, depth, visclass );
+ if (vis) {
+ return vis;
+ }
+ }
+ }
+ else {
+ /* start with deepest */
+ for (depth=32;depth>=min_depth;depth--) {
+ if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
+ /* Special case: try to get 8-bit PseudoColor before */
+ /* 8-bit TrueColor */
+ vis = get_visual( dpy, screen, 8, PseudoColor );
+ if (vis) {
+ return vis;
+ }
+ }
+ vis = get_visual( dpy, screen, depth, visclass );
+ if (vis) {
+ return vis;
+ }
+ }
+ }
+ }
+ }
+ else {
+ /* search for a specific visual class */
+ switch (preferred_class) {
+ case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
+ case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
+ case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
+ case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
+ case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
+ case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
+ default: return NULL;
+ }
+ if (min_depth==0) {
+ /* start with shallowest */
+ for (depth=0;depth<=32;depth++) {
+ vis = get_visual( dpy, screen, depth, visclass );
+ if (vis) {
+ return vis;
+ }
+ }
+ }
+ else {
+ /* start with deepest */
+ for (depth=32;depth>=min_depth;depth--) {
+ vis = get_visual( dpy, screen, depth, visclass );
+ if (vis) {
+ return vis;
+ }
+ }
+ }
+ }
+ }
+ else {
+ /* First see if the MESA_CI_VISUAL env var is defined */
+ vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" );
+ if (vis) {
+ return vis;
+ }
+ /* Otherwise, search for a suitable visual, starting with shallowest */
+ if (preferred_class==DONT_CARE) {
+ for (xclass=0;xclass<4;xclass++) {
+ switch (xclass) {
+ case 0: visclass = PseudoColor; break;
+ case 1: visclass = StaticColor; break;
+ case 2: visclass = GrayScale; break;
+ case 3: visclass = StaticGray; break;
+ }
+ /* try 8-bit up through 16-bit */
+ for (depth=8;depth<=16;depth++) {
+ vis = get_visual( dpy, screen, depth, visclass );
+ if (vis) {
+ return vis;
+ }
+ }
+ /* try min_depth up to 8-bit */
+ for (depth=min_depth;depth<8;depth++) {
+ vis = get_visual( dpy, screen, depth, visclass );
+ if (vis) {
+ return vis;
+ }
+ }
+ }
+ }
+ else {
+ /* search for a specific visual class */
+ switch (preferred_class) {
+ case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
+ case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
+ case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
+ case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
+ case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
+ case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
+ default: return NULL;
+ }
+ /* try 8-bit up through 16-bit */
+ for (depth=8;depth<=16;depth++) {
+ vis = get_visual( dpy, screen, depth, visclass );
+ if (vis) {
+ return vis;
+ }
+ }
+ /* try min_depth up to 8-bit */
+ for (depth=min_depth;depth<8;depth++) {
+ vis = get_visual( dpy, screen, depth, visclass );
+ if (vis) {
+ return vis;
+ }
+ }
+ }
+ }
+
+ /* didn't find a visual */
+ return NULL;
+}
+
+
+
+/*
+ * Find the deepest X over/underlay visual of at least min_depth.
+ * Input: dpy, screen - X display and screen number
+ * level - the over/underlay level
+ * trans_type - transparent pixel type: GLX_NONE_EXT,
+ * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT,
+ * or DONT_CARE
+ * trans_value - transparent pixel value or DONT_CARE
+ * min_depth - minimum visual depth
+ * preferred_class - preferred GLX visual class or DONT_CARE
+ * Return: pointer to an XVisualInfo or NULL.
+ */
+static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr,
+ int level, int trans_type,
+ int trans_value,
+ int min_depth,
+ int preferred_class )
+{
+ Atom overlayVisualsAtom;
+ OverlayInfo *overlay_info;
+ int numOverlaysPerScreen;
+ Status status;
+ Atom actualType;
+ int actualFormat;
+ unsigned long sizeData, bytesLeft;
+ int i;
+ XVisualInfo *deepvis;
+ int deepest;
+
+ /*DEBUG int tt, tv; */
+
+ switch (preferred_class) {
+ case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break;
+ case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break;
+ case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break;
+ case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break;
+ case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break;
+ case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break;
+ default: preferred_class = DONT_CARE;
+ }
+
+ /*
+ * The SERVER_OVERLAY_VISUALS property on the root window contains
+ * a list of overlay visuals. Get that list now.
+ */
+ overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
+ if (overlayVisualsAtom == (Atom) None) {
+ return NULL;
+ }
+
+ status = XGetWindowProperty(dpy, RootWindow( dpy, scr ),
+ overlayVisualsAtom, 0L, (long) 10000, False,
+ overlayVisualsAtom, &actualType, &actualFormat,
+ &sizeData, &bytesLeft,
+ (unsigned char **) &overlay_info );
+
+ if (status != Success || actualType != overlayVisualsAtom ||
+ actualFormat != 32 || sizeData < 4) {
+ /* something went wrong */
+ return NULL;
+ }
+
+ /* Search for the deepest overlay which satisifies all criteria. */
+ deepest = min_depth;
+ deepvis = NULL;
+
+ numOverlaysPerScreen = (int) (sizeData / 4);
+ for (i=0;i<numOverlaysPerScreen;i++) {
+ XVisualInfo *vislist, vistemplate;
+ int count;
+ OverlayInfo *ov;
+ ov = overlay_info + i;
+
+ if (ov->layer!=level) {
+ /* failed overlay level criteria */
+ continue;
+ }
+ if (!(trans_type==DONT_CARE
+ || (trans_type==GLX_TRANSPARENT_INDEX_EXT
+ && ov->transparent_type>0)
+ || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) {
+ /* failed transparent pixel type criteria */
+ continue;
+ }
+ if (trans_value!=DONT_CARE && trans_value!=ov->value) {
+ /* failed transparent pixel value criteria */
+ continue;
+ }
+
+ /* get XVisualInfo and check the depth */
+ vistemplate.visualid = ov->overlay_visual;
+ vistemplate.screen = scr;
+ vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask,
+ &vistemplate, &count );
+
+ if (count!=1) {
+ /* something went wrong */
+ continue;
+ }
+ if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) {
+ /* wrong visual class */
+ continue;
+ }
+
+ if (deepvis==NULL || vislist->depth > deepest) {
+ /* YES! found a satisfactory visual */
+ if (deepvis) {
+ free( deepvis );
+ }
+ deepest = vislist->depth;
+ deepvis = vislist;
+ /* DEBUG tt = ov->transparent_type;*/
+ /* DEBUG tv = ov->value; */
+ }
+ }
+
+/*DEBUG
+ if (deepvis) {
+ printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n",
+ deepvis->visualid, level, deepvis->depth, tt, tv );
+ }
+*/
+ return deepvis;
+}
+
+
+
+XVisualInfo *Fake_glXChooseVisual( Display *dpy, int screen, int *list )
+{
+ int *parselist;
+ XVisualInfo *vis;
+ int min_ci = 0;
+ int min_red=0, min_green=0, min_blue=0;
+ GLboolean rgb_flag = GL_FALSE;
+ GLboolean alpha_flag = GL_FALSE;
+ GLboolean double_flag = GL_FALSE;
+ GLboolean stereo_flag = GL_FALSE;
+ GLint depth_size = 0;
+ GLint stencil_size = 0;
+ GLint accum_size = 0;
+ int level = 0;
+ int visual_type = DONT_CARE;
+ int trans_type = DONT_CARE;
+ int trans_value = DONT_CARE;
+
+ parselist = list;
+
+ while (*parselist) {
+
+ switch (*parselist) {
+ case GLX_USE_GL:
+ /* ignore */
+ parselist++;
+ break;
+ case GLX_BUFFER_SIZE:
+ parselist++;
+ min_ci = *parselist++;
+ break;
+ case GLX_LEVEL:
+ parselist++;
+ level = *parselist++;
+ break;
+ case GLX_RGBA:
+ rgb_flag = GL_TRUE;
+ parselist++;
+ break;
+ case GLX_DOUBLEBUFFER:
+ double_flag = GL_TRUE;
+ parselist++;
+ break;
+ case GLX_STEREO:
+ stereo_flag = GL_TRUE;
+ return NULL;
+ case GLX_AUX_BUFFERS:
+ /* ignore */
+ parselist++;
+ parselist++;
+ break;
+ case GLX_RED_SIZE:
+ parselist++;
+ min_red = *parselist++;
+ break;
+ case GLX_GREEN_SIZE:
+ parselist++;
+ min_green = *parselist++;
+ break;
+ case GLX_BLUE_SIZE:
+ parselist++;
+ min_blue = *parselist++;
+ break;
+ case GLX_ALPHA_SIZE:
+ parselist++;
+ {
+ GLint size = *parselist++;
+ alpha_flag = size>0 ? 1 : 0;
+ }
+ break;
+ case GLX_DEPTH_SIZE:
+ parselist++;
+ depth_size = *parselist++;
+ break;
+ case GLX_STENCIL_SIZE:
+ parselist++;
+ stencil_size = *parselist++;
+ break;
+ case GLX_ACCUM_RED_SIZE:
+ case GLX_ACCUM_GREEN_SIZE:
+ case GLX_ACCUM_BLUE_SIZE:
+ case GLX_ACCUM_ALPHA_SIZE:
+ parselist++;
+ {
+ GLint size = *parselist++;
+ accum_size = MAX2( accum_size, size );
+ }
+ break;
+
+ /*
+ * GLX_EXT_visual_info extension
+ */
+ case GLX_X_VISUAL_TYPE_EXT:
+ parselist++;
+ visual_type = *parselist++;
+ break;
+ case GLX_TRANSPARENT_TYPE_EXT:
+ parselist++;
+ trans_type = *parselist++;
+ break;
+ case GLX_TRANSPARENT_INDEX_VALUE_EXT:
+ parselist++;
+ trans_value = *parselist++;
+ break;
+ case GLX_TRANSPARENT_RED_VALUE_EXT:
+ case GLX_TRANSPARENT_GREEN_VALUE_EXT:
+ case GLX_TRANSPARENT_BLUE_VALUE_EXT:
+ case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
+ /* ignore */
+ parselist++;
+ parselist++;
+ break;
+
+ case None:
+ break;
+ default:
+ /* undefined attribute */
+ return NULL;
+ }
+ }
+
+ /*
+ * Since we're only simulating the GLX extension this function will never
+ * find any real GL visuals. Instead, all we can do is try to find an RGB
+ * or CI visual of appropriate depth. Other requested attributes such as
+ * double buffering, depth buffer, etc. will be associated with the X
+ * visual and stored in the VisualTable[].
+ */
+ if (level==0) {
+ /* normal color planes */
+ if (rgb_flag) {
+ /* Get an RGB visual */
+ int min_rgb = min_red + min_green + min_blue;
+ if (min_rgb>1 && min_rgb<8) {
+ /* a special case to be sure we can get a monochrome visual */
+ min_rgb = 1;
+ }
+ vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
+ }
+ else {
+ /* Get a color index visual */
+ vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
+ accum_size = 0;
+ }
+ }
+ else {
+ /* over/underlay planes */
+ vis = choose_x_overlay_visual( dpy, screen, level, trans_type,
+ trans_value, min_ci, visual_type );
+ }
+
+ if (vis) {
+ if (!save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
+ stereo_flag,
+ depth_size, stencil_size, accum_size, level ))
+ return NULL;
+ }
+
+ return vis;
+}
+
+
+
+
+GLXContext Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+ GLXContext share_list, Bool direct )
+{
+ XMesaVisual glxvis;
+ XMesaContext xmctx;
+
+ /* deallocate unused windows/buffers */
+ XMesaGarbageCollect();
+
+ glxvis = find_glx_visual( dpy, visinfo );
+ if (!glxvis) {
+ /* This visual wasn't found with glXChooseVisual() */
+ glxvis = create_glx_visual( dpy, visinfo );
+ if (!glxvis) {
+ /* unusable visual */
+ return NULL;
+ }
+ }
+
+ xmctx = XMesaCreateContext( glxvis, (XMesaContext) share_list );
+ if (xmctx) {
+ /* set the direct/indirect flag */
+ xmctx->direct = direct;
+ }
+ return (GLXContext) xmctx;
+}
+
+
+static GLXDrawable MakeCurrent_PrevDrawable = 0;
+static GLXContext MakeCurrent_PrevContext = 0;
+static XMesaBuffer MakeCurrent_PrevBuffer = 0;
+
+Bool Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+{
+ if (ctx && drawable) {
+ XMesaBuffer buffer;
+
+ if (drawable==MakeCurrent_PrevDrawable && ctx==MakeCurrent_PrevContext) {
+ buffer = MakeCurrent_PrevBuffer;
+ }
+ else {
+ buffer = XMesaFindBuffer( dpy, drawable );
+ }
+ if (!buffer) {
+ /* drawable must be a new window! */
+ buffer = XMesaCreateWindowBuffer2( ctx->xm_visual, drawable, ctx );
+ if (!buffer) {
+ /* Out of memory, or context/drawable depth mismatch */
+ return False;
+ }
+ }
+ MakeCurrent_PrevContext = ctx;
+ MakeCurrent_PrevDrawable = drawable;
+ MakeCurrent_PrevBuffer = buffer;
+
+ /* Now make current! */
+ return (Bool) XMesaMakeCurrent( (XMesaContext) ctx, buffer );
+ }
+ else if (!ctx && !drawable) {
+ /* release current context w/out assigning new one. */
+ XMesaMakeCurrent( NULL, NULL );
+ MakeCurrent_PrevContext = 0;
+ MakeCurrent_PrevDrawable = 0;
+ MakeCurrent_PrevBuffer = 0;
+ return True;
+ }
+ else {
+ /* ctx XOR drawable is NULL, this is an error */
+ return False;
+ }
+}
+
+
+
+GLXPixmap Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
+ Pixmap pixmap )
+{
+ XMesaVisual v;
+ XMesaBuffer b;
+
+ v = find_glx_visual( dpy, visinfo );
+ if (!v) {
+ v = create_glx_visual( dpy, visinfo );
+ if (!v) {
+ /* unusable visual */
+ return 0;
+ }
+ }
+
+ b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
+ if (!b) {
+ return 0;
+ }
+ return b->frontbuffer;
+}
+
+
+#ifdef GLX_MESA_pixmap_colormap
+
+GLXPixmap Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
+ Pixmap pixmap, Colormap cmap )
+{
+ XMesaVisual v;
+ XMesaBuffer b;
+
+ v = find_glx_visual( dpy, visinfo );
+ if (!v) {
+ v = create_glx_visual( dpy, visinfo );
+ if (!v) {
+ /* unusable visual */
+ return 0;
+ }
+ }
+
+ b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
+ if (!b) {
+ return 0;
+ }
+ return b->frontbuffer;
+}
+
+#endif
+
+
+void Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
+{
+ XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
+ if (b) {
+ XMesaDestroyBuffer(b);
+ }
+ else if (getenv("MESA_DEBUG")) {
+ fprintf( stderr, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
+ }
+}
+
+
+void Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+ GLuint mask )
+{
+ XMesaContext xm_src = (XMesaContext) src;
+ XMesaContext xm_dst = (XMesaContext) dst;
+ (void) dpy;
+ gl_copy_context( xm_src->gl_ctx, xm_dst->gl_ctx, mask );
+}
+
+
+
+Bool Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
+{
+ /* Mesa's GLX isn't really an X extension but we try to act like one. */
+ (void) dpy;
+ (void) errorb;
+ (void) event;
+ return True;
+}
+
+
+void _kw_ungrab_all( Display *dpy )
+{
+ XUngrabPointer( dpy, CurrentTime );
+ XUngrabKeyboard( dpy, CurrentTime );
+}
+
+
+void Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
+{
+ (void) dpy;
+ MakeCurrent_PrevContext = 0;
+ MakeCurrent_PrevDrawable = 0;
+ MakeCurrent_PrevBuffer = 0;
+ XMesaDestroyContext( (XMesaContext) ctx );
+ XMesaGarbageCollect();
+}
+
+
+
+Bool Fake_glXIsDirect( Display *dpy, GLXContext ctx )
+{
+ (void) dpy;
+ return ((XMesaContext) ctx)->direct;
+}
+
+
+
+void Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
+{
+ XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
+ static GLXDrawable last = 0;
+ static Window window = 0;
+ if (drawable != last && 0) {
+ XSetWindowAttributes cwa;
+
+ _kw_ungrab_all( dpy );
+ cwa.override_redirect = 0;
+ XChangeWindowAttributes( dpy, drawable, CWOverrideRedirect,
+ &cwa );
+/* printf("KW: Ungrab display %s\n", DisplayString(dpy)); */
+
+
+/* last = drawable; */
+
+
+ if (!window) {
+ XSetWindowAttributes cwa;
+
+ if ((window = XCreateSimpleWindow( dpy,
+ RootWindow( dpy, 0 ),
+ 10,10,100,100, 0,
+ WhitePixel( dpy, 0 ),
+ BlackPixel( dpy, 0 ))) == 0)
+ {
+ printf("Failed to open radar window\n");
+ abort();
+ }
+
+ cwa.event_mask = (PointerMotionMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ KeyPressMask |
+ KeyReleaseMask |
+ ExposureMask );
+
+ XChangeWindowAttributes( dpy, window,
+ CWEventMask,
+ &cwa );
+
+ XMapWindow( dpy, window );
+ XFlush( dpy );
+ }
+ }
+ if (buffer) {
+ XMesaSwapBuffers(buffer);
+ }
+ else if (getenv("MESA_DEBUG")) {
+ fprintf(stderr, "Mesa Warning: glXSwapBuffers: invalid drawable\n");
+ }
+}
+
+
+void Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
+ int x, int y, int width, int height )
+{
+ XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
+ if (buffer) {
+ XMesaCopySubBuffer(buffer, x, y, width, height);
+ }
+ else if (getenv("MESA_DEBUG")) {
+ fprintf(stderr, "Mesa Warning: glXCopySubBufferMESA: invalid drawable\n");
+ }
+}
+
+
+
+Bool Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
+{
+ (void) dpy;
+ /* Return GLX version, not Mesa version */
+ *maj = 1;
+ *min = 1;
+ return True;
+}
+
+
+
+/*
+ * Query the GLX attributes of the given XVisualInfo.
+ */
+int Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
+ int attrib, int *value )
+{
+ XMesaVisual glxvis;
+
+ glxvis = find_glx_visual( dpy, visinfo );
+ if (!glxvis) {
+ /* this visual wasn't obtained with glXChooseVisual */
+ glxvis = create_glx_visual( dpy, visinfo );
+ if (!glxvis) {
+ /* this visual can't be used for GL rendering */
+ if (attrib==GLX_USE_GL) {
+ *value = (int) False;
+ return 0;
+ }
+ else {
+ /*fprintf( stderr, "Mesa: Error in glXGetConfig: bad visual\n");*/
+ return GLX_BAD_VISUAL;
+ }
+ }
+ }
+
+ switch(attrib) {
+ case GLX_USE_GL:
+ *value = (int) True;
+ return 0;
+ case GLX_BUFFER_SIZE:
+ *value = visinfo->depth;
+ return 0;
+ case GLX_LEVEL:
+ *value = glxvis->level;
+ return 0;
+ case GLX_RGBA:
+ if (glxvis->gl_visual->RGBAflag) {
+ *value = True;
+ }
+ else {
+ *value = False;
+ }
+ return 0;
+ case GLX_DOUBLEBUFFER:
+ *value = (int) glxvis->gl_visual->DBflag;
+ return 0;
+ case GLX_STEREO:
+ *value = (int) glxvis->gl_visual->StereoFlag;
+ return 0;
+ case GLX_AUX_BUFFERS:
+ *value = (int) False;
+ return 0;
+ case GLX_RED_SIZE:
+ *value = glxvis->gl_visual->RedBits;
+ return 0;
+ case GLX_GREEN_SIZE:
+ *value = glxvis->gl_visual->GreenBits;
+ return 0;
+ case GLX_BLUE_SIZE:
+ *value = glxvis->gl_visual->BlueBits;
+ return 0;
+ case GLX_ALPHA_SIZE:
+ *value = glxvis->gl_visual->AlphaBits;
+ return 0;
+ case GLX_DEPTH_SIZE:
+ *value = glxvis->gl_visual->DepthBits;
+ return 0;
+ case GLX_STENCIL_SIZE:
+ *value = glxvis->gl_visual->StencilBits;
+ return 0;
+ case GLX_ACCUM_RED_SIZE:
+ case GLX_ACCUM_GREEN_SIZE:
+ case GLX_ACCUM_BLUE_SIZE:
+ *value = glxvis->gl_visual->AccumBits;
+ return 0;
+ case GLX_ACCUM_ALPHA_SIZE:
+ if (glxvis->gl_visual->AlphaBits > 0)
+ *value = glxvis->gl_visual->AccumBits;
+ else
+ *value = 0;
+ return 0;
+
+ /*
+ * GLX_EXT_visual_info extension
+ */
+ case GLX_X_VISUAL_TYPE_EXT:
+ switch (glxvis->visinfo->CLASS) {
+ case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0;
+ case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0;
+ case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0;
+ case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0;
+ case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0;
+ case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0;
+ }
+ return 0;
+ case GLX_TRANSPARENT_TYPE_EXT:
+ if (glxvis->level==0) {
+ /* normal planes */
+ *value = GLX_NONE_EXT;
+ }
+ else if (glxvis->level>0) {
+ /* overlay */
+ if (glxvis->gl_visual->RGBAflag) {
+ *value = GLX_TRANSPARENT_RGB_EXT;
+ }
+ else {
+ *value = GLX_TRANSPARENT_INDEX_EXT;
+ }
+ }
+ else if (glxvis->level<0) {
+ /* underlay */
+ *value = GLX_NONE_EXT;
+ }
+ return 0;
+ case GLX_TRANSPARENT_INDEX_VALUE_EXT:
+ {
+ int pixel = transparent_pixel( glxvis );
+ if (pixel>=0) {
+ *value = pixel;
+ }
+ /* else undefined */
+ }
+ return 0;
+ case GLX_TRANSPARENT_RED_VALUE_EXT:
+ /* undefined */
+ return 0;
+ case GLX_TRANSPARENT_GREEN_VALUE_EXT:
+ /* undefined */
+ return 0;
+ case GLX_TRANSPARENT_BLUE_VALUE_EXT:
+ /* undefined */
+ return 0;
+ case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
+ /* undefined */
+ return 0;
+
+ /*
+ * Extensions
+ */
+ default:
+ return GLX_BAD_ATTRIBUTE;
+ }
+}
+
+
+
+GLXContext Fake_glXGetCurrentContext( void )
+{
+ return (GLXContext) XMesaGetCurrentContext();
+}
+
+
+
+GLXDrawable Fake_glXGetCurrentDrawable( void )
+{
+ XMesaBuffer b = XMesaGetCurrentBuffer();
+ if (b) {
+ return b->frontbuffer;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+void Fake_glXWaitGL( void )
+{
+ XMesaContext xmesa = XMesaGetCurrentContext();
+ XMesaFlush( xmesa );
+}
+
+
+
+void Fake_glXWaitX( void )
+{
+ XMesaContext xmesa = XMesaGetCurrentContext();
+ XMesaFlush( xmesa );
+}
+
+
+
+#define EXTENSIONS "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync"
+
+
+/* GLX 1.1 and later */
+const char *Fake_glXQueryExtensionsString( Display *dpy, int screen )
+{
+ static char *extensions = EXTENSIONS;
+ (void) dpy;
+ (void) screen;
+ return extensions;
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Fake_glXQueryServerString( Display *dpy, int screen, int name )
+{
+ static char *extensions = EXTENSIONS;
+ static char *vendor = "Brian Paul";
+ static char *version = "1.1 Mesa 3.0";
+
+ (void) dpy;
+ (void) screen;
+
+ switch (name) {
+ case GLX_EXTENSIONS:
+ return extensions;
+ case GLX_VENDOR:
+ return vendor;
+ case GLX_VERSION:
+ return version;
+ default:
+ return NULL;
+ }
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Fake_glXGetClientString( Display *dpy, int name )
+{
+ static char *extensions = EXTENSIONS;
+ static char *vendor = "Brian Paul";
+ static char *version = "1.1 Mesa 3.0";
+
+ (void) dpy;
+
+ switch (name) {
+ case GLX_EXTENSIONS:
+ return extensions;
+ case GLX_VENDOR:
+ return vendor;
+ case GLX_VERSION:
+ return version;
+ default:
+ return NULL;
+ }
+}
+
+
+
+/*
+ * Release the depth, stencil, accum buffers attached to a GLXDrawable
+ * (a window or pixmap) prior to destroying the GLXDrawable.
+ */
+Bool Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
+{
+ XMesaBuffer b = XMesaFindBuffer(dpy, d);
+ if (b) {
+ XMesaDestroyBuffer(b);
+ return True;
+ }
+ return False;
+}
+
+
+/* Silence compiler warnings */
+void Fake_glXDummyFunc( void )
+{
+ (void) kernel8;
+ (void) DitherValues;
+ (void) HPCR_DRGB;
+ (void) kernel1;
+}
diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c
new file mode 100644
index 0000000000..b65bada72b
--- /dev/null
+++ b/src/mesa/drivers/x11/glxapi.c
@@ -0,0 +1,405 @@
+/* $Id: glxapi.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * GLX API functions which either call fake or real GLX implementations
+ *
+ * To enable real GLX encoding the REALGLX preprocessor symbol should be
+ * defined on the command line.
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/glx.h"
+#include "fakeglx.h"
+#include "realglx.h"
+
+
+#ifdef REALGLX
+static Display *CurrentDisplay = NULL;
+#endif
+
+
+/*
+ * This functions determines whether a call to a glX*() function should
+ * be routed to the "fake" (Mesa) or "real" (GLX-encoder) functions.
+ * Input: dpy - the X display.
+ * Return: GL_TRUE if the given display supports the real GLX extension,
+ * GL_FALSE otherwise.
+ */
+static GLboolean display_has_glx( Display *dpy )
+{
+ /* TODO: we should use a lookup table to avoid calling XQueryExtension
+ * every time.
+ */
+ int ignore;
+ if (XQueryExtension( dpy, "GLX", &ignore, &ignore, &ignore )) {
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+
+XVisualInfo *glXChooseVisual( Display *dpy, int screen, int *list )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXChooseVisual( dpy, screen, list );
+ else
+#endif
+ return Fake_glXChooseVisual( dpy, screen, list );
+}
+
+
+
+int glXGetConfig( Display *dpy, XVisualInfo *visinfo, int attrib, int *value )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXGetConfig( dpy, visinfo, attrib, value );
+ else
+#endif
+ return Fake_glXGetConfig( dpy, visinfo, attrib, value );
+}
+
+
+
+GLXContext glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+ GLXContext shareList, Bool direct )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXCreateContext( dpy, visinfo, shareList, direct );
+ else
+#endif
+ return Fake_glXCreateContext( dpy, visinfo, shareList, direct );
+}
+
+
+
+void glXDestroyContext( Display *dpy, GLXContext ctx )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ Real_glXDestroyContext( dpy, ctx );
+ else
+#endif
+ Fake_glXDestroyContext( dpy, ctx );
+}
+
+
+
+void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+ GLuint mask )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ Real_glXCopyContext( dpy, src, dst, mask );
+ else
+#endif
+ Fake_glXCopyContext( dpy, src, dst, mask );
+}
+
+
+
+Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy)) {
+ if (Real_glXMakeCurrent( dpy, drawable, ctx )) {
+ CurrentDisplay = dpy;
+ return True;
+ }
+ else {
+ return False;
+ }
+ }
+ else {
+ if (Fake_glXMakeCurrent( dpy, drawable, ctx )) {
+ CurrentDisplay = dpy;
+ return True;
+ }
+ else {
+ return False;
+ }
+ }
+#else
+ return Fake_glXMakeCurrent( dpy, drawable, ctx );
+#endif
+}
+
+
+
+GLXContext glXGetCurrentContext( void )
+{
+#ifdef REALGLX
+ if (display_has_glx(CurrentDisplay))
+ return Real_glXGetCurrentContext();
+ else
+#endif
+ return Fake_glXGetCurrentContext();
+}
+
+
+
+GLXDrawable glXGetCurrentDrawable( void )
+{
+#ifdef REALGLX
+ if (display_has_glx(CurrentDisplay))
+ return Real_glXGetCurrentDrawable();
+ else
+#endif
+ return Fake_glXGetCurrentDrawable();
+}
+
+
+
+GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
+ Pixmap pixmap )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXCreateGLXPixmap( dpy, visinfo, pixmap );
+ else
+#endif
+ return Fake_glXCreateGLXPixmap( dpy, visinfo, pixmap );
+}
+
+
+void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ Real_glXDestroyGLXPixmap( dpy, pixmap );
+ else
+#endif
+ Fake_glXDestroyGLXPixmap( dpy, pixmap );
+}
+
+
+
+Bool glXQueryExtension( Display *dpy, int *errorb, int *event )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXQueryExtension( dpy, errorb, event );
+ else
+#endif
+ return Fake_glXQueryExtension( dpy, errorb, event );
+}
+
+
+
+Bool glXIsDirect( Display *dpy, GLXContext ctx )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXIsDirect( dpy, ctx );
+ else
+#endif
+ return Fake_glXIsDirect( dpy, ctx );
+}
+
+
+
+void glXSwapBuffers( Display *dpy, GLXDrawable drawable )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ Real_glXSwapBuffers( dpy, drawable );
+ else
+#endif
+ Fake_glXSwapBuffers( dpy, drawable );
+}
+
+
+
+void glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
+ int x, int y, int width, int height )
+{
+#ifdef REALGLX
+ /* can't implement! */
+ return;
+#endif
+ Fake_glXCopySubBufferMESA( dpy, drawable, x, y, width, height );
+}
+
+
+
+Bool glXQueryVersion( Display *dpy, int *maj, int *min )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXQueryVersion( dpy, maj, min );
+ else
+#endif
+ return Fake_glXQueryVersion( dpy, maj, min );
+}
+
+
+
+void glXUseXFont( Font font, int first, int count, int listBase )
+{
+#ifdef REALGLX
+ if (display_has_glx(CurrentDisplay))
+ Real_glXUseXFont( font, first, count, listBase );
+ else
+#endif
+ Fake_glXUseXFont( font, first, count, listBase );
+}
+
+
+void glXWaitGL( void )
+{
+#ifdef REALGLX
+ if (display_has_glx(CurrentDisplay))
+ Real_glXWaitGL();
+ else
+#endif
+ Fake_glXWaitGL();
+}
+
+
+
+void glXWaitX( void )
+{
+#ifdef REALGLX
+ if (display_has_glx(CurrentDisplay))
+ Real_glXWaitX();
+ else
+#endif
+ Fake_glXWaitX();
+}
+
+
+
+/* GLX 1.1 and later */
+const char *glXQueryExtensionsString( Display *dpy, int screen )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXQueryExtensionsString( dpy, screen );
+ else
+#endif
+ return Fake_glXQueryExtensionsString( dpy, screen );
+}
+
+
+
+/* GLX 1.1 and later */
+const char *glXQueryServerString( Display *dpy, int screen, int name )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXQueryServerString( dpy, screen, name );
+ else
+#endif
+ return Fake_glXQueryServerString( dpy, screen, name );
+}
+
+
+
+/* GLX 1.1 and later */
+const char *glXGetClientString( Display *dpy, int name )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return Real_glXGetClientString( dpy, name );
+ else
+#endif
+ return Fake_glXGetClientString( dpy, name );
+}
+
+
+
+#ifdef GLX_MESA_release_buffers
+Bool glXReleaseBuffersMESA( Display *dpy, Window w )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return GL_FALSE;
+ else
+#endif
+ return Fake_glXReleaseBuffersMESA( dpy, w );
+}
+#endif
+
+
+#ifdef GLX_MESA_pixmap_colormap
+GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
+ Pixmap pixmap, Colormap cmap )
+{
+#ifdef REALGLX
+ if (display_has_glx(dpy))
+ return 0;
+ else
+#endif
+ return Fake_glXCreateGLXPixmapMESA( dpy, visinfo, pixmap, cmap );
+}
+#endif
+
+
+
+#ifdef GLX_SGI_video_sync
+
+/*
+ * This function doesn't really do anything. But, at least one
+ * application uses the function so this stub is useful.
+ */
+int glXGetVideoSyncSGI(unsigned int *count)
+{
+ static unsigned int counter = 0;
+ *count = counter++;
+ return 0;
+}
+
+
+/*
+ * Again, this is really just a stub function.
+ */
+int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
+{
+ static unsigned int counter = 0;
+ while (counter % divisor != remainder)
+ counter++;
+ *count = counter;
+ return 0;
+}
+
+#endif
diff --git a/src/mesa/drivers/x11/realglx.c b/src/mesa/drivers/x11/realglx.c
new file mode 100644
index 0000000000..79a280419a
--- /dev/null
+++ b/src/mesa/drivers/x11/realglx.c
@@ -0,0 +1,239 @@
+/* $Id: realglx.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * Real GLX-encoder functions. Called from glxapi.c
+ *
+ * Steven Parker's code for the GLX client API functions should be
+ * put in this file.
+ *
+ * Also, the main API functions in api.c should somehow hook into the
+ * GLX-encoding functions...
+ */
+
+
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "realglx.h"
+
+
+
+XVisualInfo *Real_glXChooseVisual( Display *dpy, int screen, int *list )
+{
+ (void) dpy;
+ (void) screen;
+ (void) list;
+ return 0;
+}
+
+
+
+int Real_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
+ int attrib, int *value )
+{
+ (void) dpy;
+ (void) visinfo;
+ (void) attrib;
+ (void) value;
+ return 0;
+}
+
+
+
+GLXContext Real_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+ GLXContext shareList, Bool direct )
+{
+ (void) dpy;
+ (void) visinfo;
+ (void) shareList;
+ (void) direct;
+ return 0;
+}
+
+
+
+void Real_glXDestroyContext( Display *dpy, GLXContext ctx )
+{
+ (void) dpy;
+ (void) ctx;
+}
+
+
+
+void Real_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+ GLuint mask )
+{
+ (void) dpy;
+ (void) src;
+ (void) dst;
+ (void) mask;
+}
+
+
+
+Bool Real_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+{
+ (void) dpy;
+ (void) drawable;
+ (void) ctx;
+ return 0;
+}
+
+
+
+GLXContext Real_glXGetCurrentContext( void )
+{
+ return 0;
+}
+
+
+
+GLXDrawable Real_glXGetCurrentDrawable( void )
+{
+ return 0;
+}
+
+
+
+GLXPixmap Real_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
+ Pixmap pixmap )
+{
+ (void) dpy;
+ (void) visinfo;
+ (void) pixmap;
+ return 0;
+}
+
+
+void Real_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
+{
+ (void) dpy;
+ (void) pixmap;
+}
+
+
+
+Bool Real_glXQueryExtension( Display *dpy, int *errorb, int *event )
+{
+ (void) dpy;
+ (void) errorb;
+ (void) event;
+ return 0;
+}
+
+
+
+Bool Real_glXIsDirect( Display *dpy, GLXContext ctx )
+{
+ (void) dpy;
+ (void) ctx;
+ return 0;
+}
+
+
+
+void Real_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
+{
+ (void) dpy;
+ (void) drawable;
+}
+
+
+
+Bool Real_glXQueryVersion( Display *dpy, int *maj, int *min )
+{
+ (void) dpy;
+ (void) maj;
+ (void) min;
+ return 0;
+}
+
+
+
+void Real_glXUseXFont( Font font, int first, int count, int listBase )
+{
+ (void) font;
+ (void) first;
+ (void) count;
+ (void) listBase;
+}
+
+
+typedef struct {
+ struct {
+ int major_opcode;
+ } codes;
+
+
+
+} XExtDisplayInfo;
+
+
+void Real_glXWaitGL( void )
+{
+}
+
+
+
+void Real_glXWaitX( void )
+{
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Real_glXQueryExtensionsString( Display *dpy, int screen )
+{
+ (void) dpy;
+ (void) screen;
+ return 0;
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Real_glXQueryServerString( Display *dpy, int screen, int name )
+{
+ (void) dpy;
+ (void) screen;
+ (void) name;
+ return 0;
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Real_glXGetClientString( Display *dpy, int name )
+{
+ (void) dpy;
+ (void) name;
+ return 0;
+}
diff --git a/src/mesa/drivers/x11/realglx.h b/src/mesa/drivers/x11/realglx.h
new file mode 100644
index 0000000000..9587db60c9
--- /dev/null
+++ b/src/mesa/drivers/x11/realglx.h
@@ -0,0 +1,111 @@
+/* $Id: realglx.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef REALGLX_H
+#define REALGLX_H
+
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/glx.h"
+
+
+
+extern XVisualInfo *Real_glXChooseVisual( Display *dpy,
+ int screen, int *list );
+
+
+extern int Real_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
+ int attrib, int *value );
+
+
+extern GLXContext Real_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+ GLXContext shareList, Bool direct );
+
+
+extern void Real_glXDestroyContext( Display *dpy, GLXContext ctx );
+
+
+extern void Real_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+ GLuint mask );
+
+
+extern Bool Real_glXMakeCurrent( Display *dpy, GLXDrawable drawable,
+ GLXContext ctx );
+
+
+extern GLXContext Real_glXGetCurrentContext( void );
+
+
+extern GLXDrawable Real_glXGetCurrentDrawable( void );
+
+
+extern GLXPixmap Real_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
+ Pixmap pixmap );
+
+
+extern void Real_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap );
+
+
+extern Bool Real_glXQueryExtension( Display *dpy, int *errorb, int *event );
+
+
+extern Bool Real_glXIsDirect( Display *dpy, GLXContext ctx );
+
+
+extern void Real_glXSwapBuffers( Display *dpy, GLXDrawable drawable );
+
+
+extern Bool Real_glXQueryVersion( Display *dpy, int *maj, int *min );
+
+
+extern void Real_glXUseXFont( Font font, int first, int count, int listBase );
+
+
+extern void Real_glXWaitGL( void );
+
+
+extern void Real_glXWaitX( void );
+
+
+/* GLX 1.1 and later */
+extern const char *Real_glXQueryExtensionsString( Display *dpy, int screen );
+
+
+/* GLX 1.1 and later */
+extern const char *Real_glXQueryServerString( Display *dpy, int screen,
+ int name );
+
+
+/* GLX 1.1 and later */
+extern const char *Real_glXGetClientString( Display *dpy, int name );
+
+
+#endif
diff --git a/src/mesa/drivers/x11/xfonts.c b/src/mesa/drivers/x11/xfonts.c
new file mode 100644
index 0000000000..c0e0a5fcd0
--- /dev/null
+++ b/src/mesa/drivers/x11/xfonts.c
@@ -0,0 +1,398 @@
+/* $Id: xfonts.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/* xfonts.c -- glXUseXFont() for Mesa written by
+ * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/gl.h"
+#include "GL/glx.h"
+#include "GL/xmesa.h"
+#include "context.h"
+#include "fakeglx.h"
+#include "macros.h"
+#include "xmesaP.h"
+
+/* Some debugging info. */
+
+#ifdef DEBUG
+#undef _R
+#undef _G
+#undef _B
+#include <ctype.h>
+
+int debug_xfonts = 0;
+
+static void
+dump_char_struct (XCharStruct *ch, char *prefix)
+{
+ printf ("%slbearing = %d, rbearing = %d, width = %d\n",
+ prefix, ch->lbearing, ch->rbearing, ch->width);
+ printf ("%sascent = %d, descent = %d, attributes = %u\n",
+ prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes);
+}
+
+static void
+dump_font_struct (XFontStruct *font)
+{
+ printf ("ascent = %d, descent = %d\n", font->ascent, font->descent);
+ printf ("char_or_byte2 = (%u,%u)\n",
+ font->min_char_or_byte2, font->max_char_or_byte2);
+ printf ("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1);
+ printf ("all_chars_exist = %s\n", font->all_chars_exist ? "True" :
+"False");
+ printf ("default_char = %c (\\%03o)\n",
+ (char) (isprint (font->default_char) ? font->default_char : ' '),
+ font->default_char);
+ dump_char_struct (&font->min_bounds, "min> ");
+ dump_char_struct (&font->max_bounds, "max> ");
+#if 0
+ for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++)
+ {
+ char prefix[8];
+ sprintf (prefix, "%d> ", c);
+ dump_char_struct (&font->per_char[c], prefix);
+ }
+#endif
+}
+
+static void
+dump_bitmap (unsigned int width, unsigned int height, GLubyte *bitmap)
+{
+ unsigned int x, y;
+
+ printf (" ");
+ for (x = 0; x < 8*width; x++)
+ printf ("%o", 7 - (x % 8));
+ putchar ('\n');
+ for (y = 0; y < height; y++)
+ {
+ printf ("%3o:", y);
+ for (x = 0; x < 8*width; x++)
+ putchar ((bitmap[width*(height - y - 1) + x/8] & (1 << (7 - (x %
+8))))
+ ? '*' : '.');
+ printf (" ");
+ for (x = 0; x < width; x++)
+ printf ("0x%02x, ", bitmap[width*(height - y - 1) + x]);
+ putchar ('\n');
+ }
+}
+#endif /* DEBUG */
+
+
+/* Implementation. */
+
+/* Fill a BITMAP with a character C from thew current font
+ in the graphics context GC. WIDTH is the width in bytes
+ and HEIGHT is the height in bits.
+
+ Note that the generated bitmaps must be used with
+
+ glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
+ glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+ Possible optimizations:
+
+ * use only one reusable pixmap with the maximum dimensions.
+ * draw the entire font into a single pixmap (careful with
+ proportional fonts!).
+*/
+
+
+/*
+ * Generate OpenGL-compatible bitmap.
+ */
+static void
+fill_bitmap (Display *dpy, Window win, GC gc,
+ unsigned int width, unsigned int height,
+ int x0, int y0, unsigned int c, GLubyte *bitmap)
+{
+ XImage *image;
+ unsigned int x, y;
+ Pixmap pixmap;
+ XChar2b char2b;
+
+ pixmap = XCreatePixmap (dpy, win, 8*width, height, 1);
+ XSetForeground(dpy, gc, 0);
+ XFillRectangle (dpy, pixmap, gc, 0, 0, 8*width, height);
+ XSetForeground(dpy, gc, 1);
+
+ char2b.byte1 = (c >> 8) & 0xff;
+ char2b.byte2 = (c & 0xff);
+
+ XDrawString16 (dpy, pixmap, gc, x0, y0, &char2b, 1);
+
+ image = XGetImage (dpy, pixmap, 0, 0, 8*width, height, 1, XYPixmap);
+ if (image) {
+ /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */
+ for (y = 0; y < height; y++)
+ for (x = 0; x < 8*width; x++)
+ if (XGetPixel (image, x, y))
+ bitmap[width*(height - y - 1) + x/8] |= (1 << (7 - (x % 8)));
+ XDestroyImage (image);
+ }
+
+ XFreePixmap (dpy, pixmap);
+}
+
+/*
+ * determine if a given glyph is valid and return the
+ * corresponding XCharStruct.
+ */
+static XCharStruct *isvalid(XFontStruct *fs, int which)
+{
+ unsigned int rows,pages;
+ int byte1,byte2;
+ int i,valid = 1;
+
+ rows = fs->max_byte1 - fs->min_byte1 + 1;
+ pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
+
+ if (rows == 1) {
+ /* "linear" fonts */
+ if ((fs->min_char_or_byte2 > which) ||
+ (fs->max_char_or_byte2 < which)) valid = 0;
+ } else {
+ /* "matrix" fonts */
+ byte2 = which & 0xff;
+ byte1 = which >> 8;
+ if ((fs->min_char_or_byte2 > byte2) ||
+ (fs->max_char_or_byte2 < byte2) ||
+ (fs->min_byte1 > byte1) ||
+ (fs->max_byte1 < byte1)) valid = 0;
+ }
+
+ if (valid) {
+ if (fs->per_char) {
+ if (rows == 1) {
+ /* "linear" fonts */
+ return(fs->per_char + (which-fs->min_char_or_byte2) );
+ } else {
+ /* "matrix" fonts */
+ i = ((byte1 - fs->min_byte1) * pages) +
+ (byte2 - fs->min_char_or_byte2);
+ return(fs->per_char + i);
+ }
+ } else {
+ return(&fs->min_bounds);
+ }
+ }
+ return(NULL);
+}
+
+
+void Fake_glXUseXFont( Font font, int first, int count, int listbase )
+{
+ XMesaContext CC;
+ Display *dpy;
+ Window win;
+ Pixmap pixmap;
+ GC gc;
+ XGCValues values;
+ unsigned long valuemask;
+ XFontStruct *fs;
+
+ GLint swapbytes, lsbfirst, rowlength;
+ GLint skiprows, skippixels, alignment;
+
+ unsigned int max_width, max_height, max_bm_width, max_bm_height;
+ GLubyte *bm;
+
+ int i;
+
+ CC = XMesaGetCurrentContext();
+ dpy = CC->display;
+ win = CC->xm_buffer->frontbuffer;
+
+ fs = XQueryFont (dpy, font);
+ if (!fs)
+ {
+ gl_error (CC->gl_ctx, GL_INVALID_VALUE,
+ "Couldn't get font structure information");
+ return;
+ }
+
+ /* Allocate a bitmap that can fit all characters. */
+ max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
+ max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
+ max_bm_width = (max_width + 7) / 8;
+ max_bm_height = max_height;
+
+ bm = (GLubyte *) malloc ((max_bm_width * max_bm_height) * sizeof
+(GLubyte));
+ if (!bm) {
+ XFreeFontInfo( NULL, fs, 0 );
+ gl_error (CC->gl_ctx, GL_OUT_OF_MEMORY,
+ "Couldn't allocate bitmap in glXUseXFont()");
+ return;
+ }
+
+#if 0
+ /* get the page info */
+ pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
+ firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
+ lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
+ rows = fs->max_byte1 - fs->min_byte1 + 1;
+ unsigned int first_char, last_char, pages, rows;
+#endif
+
+ /* Save the current packing mode for bitmaps. */
+ glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
+ glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
+ glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
+ glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
+ glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
+ glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
+
+ /* Enforce a standard packing mode which is compatible with
+ fill_bitmap() from above. This is actually the default mode,
+ except for the (non)alignment. */
+ glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
+ glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+ pixmap = XCreatePixmap (dpy, win, 10, 10, 1);
+ values.foreground = BlackPixel (dpy, DefaultScreen (dpy));
+ values.background = WhitePixel (dpy, DefaultScreen (dpy));
+ values.font = fs->fid;
+ valuemask = GCForeground | GCBackground | GCFont;
+ gc = XCreateGC (dpy, pixmap, valuemask, &values);
+ XFreePixmap (dpy, pixmap);
+
+#ifdef DEBUG
+ if (debug_xfonts)
+ dump_font_struct (fs);
+#endif
+
+ for (i = 0; i < count; i++)
+ {
+ unsigned int width, height, bm_width, bm_height;
+ GLfloat x0, y0, dx, dy;
+ XCharStruct *ch;
+ int x, y;
+ unsigned int c = first + i;
+ int list = listbase + i;
+ int valid;
+
+ /* check on index validity and get the bounds */
+ ch = isvalid(fs, c);
+ if (!ch) {
+ ch = &fs->max_bounds;
+ valid = 0;
+ } else {
+ valid = 1;
+ }
+
+#ifdef DEBUG
+ if (debug_xfonts) {
+ char s[7];
+ sprintf (s, isprint (c) ? "%c> " : "\\%03o> ", c);
+ dump_char_struct (ch, s);
+ }
+#endif
+
+ /* glBitmap()' parameters:
+ straight from the glXUseXFont(3) manpage. */
+ width = ch->rbearing - ch->lbearing;
+ height = ch->ascent + ch->descent;
+ x0 = - ch->lbearing;
+ y0 = ch->descent - 1;
+ dx = ch->width;
+ dy = 0;
+
+ /* X11's starting point. */
+ x = - ch->lbearing;
+ y = ch->ascent;
+
+ /* Round the width to a multiple of eight. We will use this also
+ for the pixmap for capturing the X11 font. This is slightly
+ inefficient, but it makes the OpenGL part real easy. */
+ bm_width = (width + 7) / 8;
+ bm_height = height;
+
+ glNewList (list, GL_COMPILE);
+ if (valid && (bm_width > 0) && (bm_height > 0)) {
+
+ MEMSET (bm, '\0', bm_width * bm_height);
+ fill_bitmap (dpy, win, gc, bm_width, bm_height, x, y, c, bm);
+
+ glBitmap (width, height, x0, y0, dx, dy, bm);
+#ifdef DEBUG
+ if (debug_xfonts) {
+ printf ("width/height = %u/%u\n", width, height);
+ printf ("bm_width/bm_height = %u/%u\n", bm_width,
+bm_height);
+ dump_bitmap (bm_width, bm_height, bm);
+ }
+#endif
+ } else {
+ glBitmap (0, 0, 0.0, 0.0, dx, dy, NULL);
+ }
+ glEndList ();
+ }
+
+ free (bm);
+ XFreeFontInfo( NULL, fs, 0 );
+ XFreeGC (dpy, gc);
+
+ /* Restore saved packing modes. */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
+}
+
+void xmesa_xfonts_dummy( void )
+{
+ /* silence unused var warnings */
+ (void) kernel8;
+ (void) DitherValues;
+ (void) HPCR_DRGB;
+ (void) kernel1;
+}
+
+/* The End. */
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
new file mode 100644
index 0000000000..256a47f0a6
--- /dev/null
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -0,0 +1,499 @@
+/* $Id: xmesaP.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.1
+ *
+ * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef XMESAP_H
+#define XMESAP_H
+
+
+#ifdef XFree86Server
+#include "xf86glx_util.h"
+#else
+#ifdef SHM
+#include <X11/extensions/XShm.h>
+#endif
+#endif
+#include "GL/xmesa.h"
+#include "types.h"
+#ifdef FX
+#include "GL/fxmesa.h"
+#include "../FX/fxdrv.h"
+#endif
+
+
+/* for PF_8R8G8B24 pixel format */
+typedef struct {
+ GLubyte b;
+ GLubyte g;
+ GLubyte r;
+} bgr_t;
+
+
+/*
+ * "Derived" from gl_visual. Basically corresponds to an XVisualInfo.
+ */
+struct xmesa_visual {
+ GLvisual *gl_visual; /* Device independent visual parameters */
+ XMesaDisplay *display; /* The X11 display */
+#ifndef XFree86Server
+ XVisualInfo *vishandle; /* The pointer returned by glXChooseVisual */
+#endif
+ XMesaVisualInfo visinfo; /* X's visual info */
+
+ GLint level; /* 0=normal, 1=overlay, etc */
+
+ GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */
+
+ GLuint dithered_pf; /* Pixel format when dithering */
+ GLuint undithered_pf; /* Pixel format when not dithering */
+
+ GLfloat RedGamma; /* Gamma values, 1.0 is default */
+ GLfloat GreenGamma;
+ GLfloat BlueGamma;
+
+ GLint rmult, gmult, bmult; /* Range of color values */
+ GLint index_bits; /* Bits per pixel in CI mode */
+
+ /* For PF_TRUECOLOR */
+ GLint rshift, gshift, bshift;/* Pixel color component shifts */
+ GLubyte Kernel[16]; /* Dither kernel */
+ unsigned long RtoPixel[512]; /* RGB to pixel conversion */
+ unsigned long GtoPixel[512];
+ unsigned long BtoPixel[512];
+ GLubyte PixelToR[256]; /* Pixel to RGB conversion */
+ GLubyte PixelToG[256];
+ GLubyte PixelToB[256];
+
+ /* For PF_HPCR */
+ short hpcr_rgbTbl[3][256];
+ GLboolean hpcr_clear_flag;
+ GLubyte hpcr_clear_ximage_pattern[2][16];
+ XMesaImage *hpcr_clear_ximage;
+ XMesaPixmap hpcr_clear_pixmap;
+
+ /* For PF_1BIT */
+ int bitFlip;
+};
+
+
+
+/*
+ * "Derived" from gl_context. Basically corresponds to a GLXContext.
+ */
+struct xmesa_context {
+ GLcontext *gl_ctx; /* the core library context */
+ XMesaVisual xm_visual; /* Describes the buffers */
+ XMesaBuffer xm_buffer; /* current framebuffer */
+
+ XMesaDisplay *display; /* == xm_visual->display */
+ GLboolean swapbytes; /* Host byte order != display byte order? */
+ GLboolean direct; /* Direct rendering context? */
+
+ GLuint pixelformat; /* Current pixel format */
+
+ GLubyte red, green, blue, alpha; /* current drawing color */
+ unsigned long pixel; /* current drawing pixel value */
+
+ GLubyte clearcolor[4]; /* current clearing color */
+ unsigned long clearpixel; /* current clearing pixel value */
+};
+
+
+
+/*
+ * "Derived" from gl_buffer. Basically corresponds to a GLXDrawable.
+ */
+struct xmesa_buffer {
+ GLboolean wasCurrent; /* was ever the current buffer? */
+ GLframebuffer *gl_buffer; /* depth, stencil, accum, etc buffers */
+ XMesaVisual xm_visual; /* the X/Mesa visual */
+
+ XMesaContext xm_context; /* the context associated with this buffer */
+ XMesaDisplay *display;
+ GLboolean pixmap_flag; /* is the buffer a Pixmap? */
+ XMesaDrawable frontbuffer; /* either a window or pixmap */
+ XMesaPixmap backpixmap; /* back buffer Pixmap */
+ XMesaImage *backimage; /* back buffer simulated XImage */
+
+ XMesaDrawable buffer; /* the current buffer, either equal to */
+ /* frontbuffer, backpixmap or XIMAGE (None) */
+
+ XMesaColormap cmap; /* the X colormap */
+
+ GLint db_state; /* 0 = single buffered */
+ /* BACK_PIXMAP = use Pixmap for back buffer */
+ /* BACK_XIMAGE = use XImage for back buffer */
+
+#ifndef XFree86Server
+ GLuint shm; /* X Shared Memory extension status: */
+ /* 0 = not available */
+ /* 1 = XImage support available */
+ /* 2 = Pixmap support available too */
+#ifdef SHM
+ XShmSegmentInfo shminfo;
+#endif
+#endif
+
+ XMesaImage *rowimage; /* Used for optimized span writing */
+
+ GLuint width, height; /* size of buffer */
+
+ GLint bottom; /* used for FLIP macro below */
+ GLubyte *ximage_origin1; /* used for PIXELADDR1 macro */
+ GLint ximage_width1;
+ GLushort *ximage_origin2; /* used for PIXELADDR2 macro */
+ GLint ximage_width2;
+ bgr_t *ximage_origin3; /* used for PIXELADDR3 macro */
+ GLint ximage_width3;
+ GLuint *ximage_origin4; /* used for PIXELADDR4 macro */
+ GLint ximage_width4;
+
+ XMesaPixmap stipple_pixmap; /* For polygon stippling */
+ XMesaGC stipple_gc; /* For polygon stippling */
+
+ XMesaGC gc1; /* GC for infrequent color changes */
+ XMesaGC gc2; /* GC for frequent color changes */
+ XMesaGC cleargc; /* GC for clearing the color buffer */
+
+ /* The following are here instead of in the XMesaVisual
+ * because they depend on the window's colormap.
+ */
+
+ /* For PF_DITHER, PF_LOOKUP, PF_GRAYSCALE */
+ unsigned long color_table[576]; /* RGB -> pixel value */
+
+ /* For PF_DITHER, PF_LOOKUP, PF_GRAYSCALE */
+ GLubyte pixel_to_r[65536]; /* pixel value -> red */
+ GLubyte pixel_to_g[65536]; /* pixel value -> green */
+ GLubyte pixel_to_b[65536]; /* pixel value -> blue */
+
+ /* Used to do XAllocColor/XFreeColors accounting: */
+ int num_alloced;
+ unsigned long alloced_colors[256];
+
+#ifdef FX
+ /* For 3Dfx Glide only */
+ GLboolean FXisHackUsable; /* Can we render into window? */
+ GLboolean FXwindowHack; /* Are we rendering into a window? */
+ fxMesaContext FXctx;
+#endif
+
+ struct xmesa_buffer *Next; /* Linked list pointer: */
+};
+
+
+
+/* Values for xmesa->dest: */
+#define FRONT_PIXMAP 1
+#define BACK_PIXMAP 2
+#define BACK_XIMAGE 4
+
+
+/* Values for xmesa->pixelformat: */
+#define PF_INDEX 1 /* Color Index mode */
+#define PF_TRUECOLOR 2 /* TrueColor or DirectColor, any depth */
+#define PF_TRUEDITHER 3 /* TrueColor with dithering */
+#define PF_8A8B8G8R 4 /* 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */
+#define PF_8R8G8B 5 /* 32-bit TrueColor: 8-R, 8-G, 8-B bits */
+#define PF_5R6G5B 6 /* 16-bit TrueColor: 5-R, 6-G, 5-B bits */
+#define PF_DITHER 7 /* Color-mapped RGB with dither */
+#define PF_LOOKUP 8 /* Color-mapped RGB without dither */
+#define PF_HPCR 9 /* HP Color Recovery (ad@lms.be 30/08/95) */
+#define PF_1BIT 10 /* monochrome dithering of RGB */
+#define PF_GRAYSCALE 11 /* Grayscale or StaticGray */
+#define PF_8R8G8B24 12 /* 24-bit TrueColor: 8-R, 8-G, 8-B bits */
+#define PF_DITHER_5R6G5B 13 /* 16-bit dithered TrueColor: 5-R, 6-G, 5-B */
+
+
+/*
+ * If pixelformat==PF_TRUECOLOR:
+ */
+#define PACK_TRUECOLOR( PIXEL, R, G, B ) \
+ PIXEL = xmesa->xm_visual->RtoPixel[R] \
+ | xmesa->xm_visual->GtoPixel[G] \
+ | xmesa->xm_visual->BtoPixel[B]; \
+
+
+/*
+ * If pixelformat==PF_TRUEDITHER:
+ */
+#define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B ) \
+{ \
+ int d = xmesa->xm_visual->Kernel[((X)&3) | (((Y)&3)<<2)]; \
+ PIXEL = xmesa->xm_visual->RtoPixel[(R)+d] \
+ | xmesa->xm_visual->GtoPixel[(G)+d] \
+ | xmesa->xm_visual->BtoPixel[(B)+d]; \
+}
+
+
+
+/*
+ * If pixelformat==PF_8A8B8G8R:
+ */
+#define PACK_8A8B8G8R( R, G, B, A ) \
+ ( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )
+
+
+/*
+ * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
+ * shortcut.
+ */
+#define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
+
+
+
+/*
+ * If pixelformat==PF_8R8G8B:
+ */
+#define PACK_8R8G8B( R, G, B) ( ((R) << 16) | ((G) << 8) | (B) )
+
+
+/*
+ * If pixelformat==PF_5R6G5B:
+ */
+#define PACK_5R6G5B( R, G, B) ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
+
+
+
+/*
+ * If pixelformat==PF_DITHER:
+ *
+ * Improved 8-bit RGB dithering code contributed by Bob Mercier
+ * (mercier@hollywood.cinenet.net). Thanks Bob!
+ */
+#undef _R
+#undef _G
+#undef _B
+#ifdef DITHER666
+# define _R 6
+# define _G 6
+# define _B 6
+# define _MIX(r,g,b) (((r)*_G+(g))*_B+(b))
+#else
+# define _R 5
+# define _G 9
+# define _B 5
+# define _MIX(r,g,b) ( ((g)<<6) | ((b)<<3) | (r) )
+#endif
+#define _DX 4
+#define _DY 4
+#define _D (_DX*_DY)
+
+/*#define _DITH(C,c,d) (((unsigned)((_D*(C-1)+1)*c+d))/(_D*256))*/
+#define _DITH(C,c,d) (((unsigned)((_D*(C-1)+1)*c+d)) >> 12)
+
+#define MAXC 256
+static int kernel8[_DY*_DX] = {
+ 0 * MAXC, 8 * MAXC, 2 * MAXC, 10 * MAXC,
+ 12 * MAXC, 4 * MAXC, 14 * MAXC, 6 * MAXC,
+ 3 * MAXC, 11 * MAXC, 1 * MAXC, 9 * MAXC,
+ 15 * MAXC, 7 * MAXC, 13 * MAXC, 5 * MAXC,
+};
+/*static int __d;*/
+
+/* Dither for random X,Y */
+#define DITHER_SETUP \
+ int __d; \
+ unsigned long *ctable = xmesa->xm_buffer->color_table;
+
+#define DITHER( X, Y, R, G, B ) \
+ (__d = kernel8[(((Y)&3)<<2) | ((X)&3)], \
+ ctable[_MIX(_DITH(_R, (R), __d), \
+ _DITH(_G, (G), __d), \
+ _DITH(_B, (B), __d))])
+
+/* Dither for random X, fixed Y */
+#define XDITHER_SETUP(Y) \
+ int __d; \
+ unsigned long *ctable = xmesa->xm_buffer->color_table; \
+ int *kernel = &kernel8[ ((Y)&3) << 2 ];
+
+#define XDITHER( X, R, G, B ) \
+ (__d = kernel[(X)&3], \
+ ctable[_MIX(_DITH(_R, (R), __d), \
+ _DITH(_G, (G), __d), \
+ _DITH(_B, (B), __d))])
+
+
+
+/*
+ * Dithering for flat-shaded triangles. Precompute all 16 possible
+ * pixel values given the triangle's RGB color. Contributed by Martin Shenk.
+ */
+static GLushort DitherValues[16]; /* array of (up to) 16-bit pixel values */
+
+#define FLAT_DITHER_SETUP( R, G, B ) \
+ { \
+ unsigned long *ctable = xmesa->xm_buffer->color_table; \
+ int msdr = (_D*((_R)-1)+1) * (R); \
+ int msdg = (_D*((_G)-1)+1) * (G); \
+ int msdb = (_D*((_B)-1)+1) * (B); \
+ int i; \
+ for (i=0;i<16;i++) { \
+ int k = kernel8[i]; \
+ int j = _MIX( (msdr+k)>>12, (msdg+k)>>12, (msdb+k)>>12 ); \
+ DitherValues[i] = (GLushort) ctable[j]; \
+ } \
+ }
+
+#define FLAT_DITHER_ROW_SETUP(Y) \
+ GLushort *ditherRow = DitherValues + ( ((Y)&3) << 2);
+
+#define FLAT_DITHER(X) ditherRow[(X)&3]
+
+
+
+/*
+ * If pixelformat==PF_LOOKUP:
+ */
+#define _DITH0(C,c) (((unsigned)((_D*(C-1)+1)*c)) >> 12)
+
+#define LOOKUP_SETUP \
+ unsigned long *ctable = xmesa->xm_buffer->color_table
+
+#define LOOKUP( R, G, B ) \
+ ctable[_MIX(_DITH0(_R, (R)), \
+ _DITH0(_G, (G)), \
+ _DITH0(_B, (B)))]
+
+
+
+/*
+ * If pixelformat==PF_HPCR:
+ *
+ * HP Color Recovery dithering (ad@lms.be 30/08/95)
+ * HP has on it's 8-bit 700-series computers, a feature called
+ * 'Color Recovery'. This allows near 24-bit output (so they say).
+ * It is enabled by selecting the 8-bit TrueColor visual AND
+ * corresponding colormap (see tkInitWindow) AND doing some special
+ * dither.
+ */
+static const short HPCR_DRGB[3][2][16] = {
+{
+ { 16, -4, 1,-11, 14, -6, 3, -9, 15, -5, 2,-10, 13, -7, 4, -8},
+ {-15, 5, 0, 12,-13, 7, -2, 10,-14, 6, -1, 11,-12, 8, -3, 9}
+},
+{
+ {-11, 15, -7, 3, -8, 14, -4, 2,-10, 16, -6, 4, -9, 13, -5, 1},
+ { 12,-14, 8, -2, 9,-13, 5, -1, 11,-15, 7, -3, 10,-12, 6, 0}
+},
+{
+ { 6,-18, 26,-14, 2,-22, 30,-10, 8,-16, 28,-12, 4,-20, 32, -8},
+ { -4, 20,-24, 16, 0, 24,-28, 12, -6, 18,-26, 14, -2, 22,-30, 10}
+}
+};
+
+#define DITHER_HPCR( X, Y, R, G, B ) \
+ ( ((xmesa->xm_visual->hpcr_rgbTbl[0][R] + HPCR_DRGB[0][(Y)&1][(X)&15]) & 0xE0) \
+ |(((xmesa->xm_visual->hpcr_rgbTbl[1][G] + HPCR_DRGB[1][(Y)&1][(X)&15]) & 0xE0)>>3) \
+ | ((xmesa->xm_visual->hpcr_rgbTbl[2][B] + HPCR_DRGB[2][(Y)&1][(X)&15])>>6) \
+ )
+
+
+
+/*
+ * If pixelformat==PF_1BIT:
+ */
+static int const kernel1[16] = {
+ 0*47, 9*47, 4*47, 12*47, /* 47 = (255*3)/16 */
+ 6*47, 2*47, 14*47, 8*47,
+ 10*47, 1*47, 5*47, 11*47,
+ 7*47, 13*47, 3*47, 15*47 };
+
+#define SETUP_1BIT int bitFlip = xmesa->xm_visual->bitFlip
+#define DITHER_1BIT( X, Y, R, G, B ) \
+ (( ((int)(R)+(int)(G)+(int)(B)) > kernel1[(((Y)&3) << 2) | ((X)&3)] ) ^ bitFlip)
+
+
+
+/*
+ * If pixelformat==PF_GRAYSCALE:
+ */
+#define GRAY_RGB( R, G, B ) xmesa->xm_buffer->color_table[((R) + (G) + (B))/3]
+
+
+
+#define XIMAGE None
+
+
+/*
+ * Converts a GL window Y coord to an X window Y coord:
+ */
+#define FLIP(Y) (xmesa->xm_buffer->bottom-(Y))
+
+
+/*
+ * Return the address of a 1, 2 or 4-byte pixel in the back XImage:
+ * X==0 is left, Y==0 is bottom.
+ */
+#define PIXELADDR1( X, Y ) \
+ ( xmesa->xm_buffer->ximage_origin1 - (Y) * xmesa->xm_buffer->ximage_width1 + (X) )
+
+#define PIXELADDR2( X, Y ) \
+ ( xmesa->xm_buffer->ximage_origin2 - (Y) * xmesa->xm_buffer->ximage_width2 + (X) )
+
+#define PIXELADDR3( X, Y ) \
+ ( xmesa->xm_buffer->ximage_origin3 - (Y) * xmesa->xm_buffer->ximage_width3 + (X) )
+
+#define PIXELADDR4( X, Y ) \
+ ( xmesa->xm_buffer->ximage_origin4 - (Y) * xmesa->xm_buffer->ximage_width4 + (X) )
+
+
+
+/*
+ * External functions:
+ */
+
+extern unsigned long xmesa_color_to_pixel( XMesaContext xmesa,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a );
+
+extern void xmesa_alloc_back_buffer( XMesaBuffer b );
+
+extern void xmesa_update_state( GLcontext *ctx );
+
+extern points_func xmesa_get_points_func( GLcontext *ctx );
+
+extern line_func xmesa_get_line_func( GLcontext *ctx );
+
+extern triangle_func xmesa_get_triangle_func( GLcontext *ctx );
+
+
+/* XXX this is a hack to implement shared display lists with 3Dfx */
+extern XMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v,
+ XMesaWindow w,
+ XMesaContext c );
+
+
+/*
+ * These are the extra routines required for integration with XFree86.
+ * None of these routines should be user visible. -KEM
+ */
+extern void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v );
+extern GLboolean XMesaForceCurrent(XMesaContext c);
+extern GLboolean XMesaLoseCurrent(XMesaContext c);
+extern void XMesaReset( void );
+
+#endif