diff options
author | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
commit | f4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch) | |
tree | 2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/extras/Mesa/src/mesa/drivers/x11 | |
parent | a840692edc9c6d19cd7c057f68e39c7d95eb767d (diff) | |
download | nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2 nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip |
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz
Keywords:
Imported nx-X11-3.1.0-1.tar.gz
into Git repository
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/x11')
16 files changed, 17139 insertions, 0 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/descrip.mms b/nx-X11/extras/Mesa/src/mesa/drivers/x11/descrip.mms new file mode 100644 index 000000000..69d14e36c --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/descrip.mms @@ -0,0 +1,51 @@ +# Makefile for core library for VMS +# contributed by Jouk Jansen joukj@hrem.stm.tudelft.nl +# Last revision : 16 June 2003 + +.first + define gl [----.include.gl] + define math [--.math] + define tnl [--.tnl] + define swrast [--.swrast] + define swrast_setup [--.swrast_setup] + define array_cache [--.array_cache] + define drivers [-] + +.include [----]mms-config. + +##### MACROS ##### + +VPATH = RCS + +INCDIR = [----.include],[--.main],[--.glapi] +LIBDIR = [----.lib] +CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short) + +SOURCES = fakeglx.c glxapi.c xfonts.c xm_api.c xm_dd.c xm_line.c xm_span.c\ + xm_tri.c xm_buffer.c + +OBJECTS =fakeglx.obj,glxapi.obj,xfonts.obj,xm_api.obj,xm_dd.obj,xm_line.obj,\ + xm_span.obj,xm_tri.obj,xm_buffer.obj + +##### RULES ##### + +VERSION=Mesa V3.4 + +##### TARGETS ##### +# Make the library +$(LIBDIR)$(GL_LIB) : $(OBJECTS) + @ library $(LIBDIR)$(GL_LIB) $(OBJECTS) + +clean : + purge + delete *.obj;* + +fakeglx.obj : fakeglx.c +glxapi.obj : glxapi.c +xfonts.obj : xfonts.c +xm_api.obj : xm_api.c +xm_buffer.obj : xm_buffer.c +xm_dd.obj : xm_dd.c +xm_line.obj : xm_line.c +xm_span.obj : xm_span.c +xm_tri.obj : xm_tri.c diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/fakeglx.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/fakeglx.c new file mode 100644 index 000000000..d3213e708 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/fakeglx.c @@ -0,0 +1,2886 @@ +/* + * Mesa 3-D graphics library + * Version: 6.4 + * + * Copyright (C) 1999-2005 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. + */ + + +/* + * This is an emulation of the GLX API which allows Mesa/GLX-based programs + * to run on X servers which do not have the real GLX extension. + * + * Thanks to the contributors: + * + * Initial version: Philip Brown (phil@bolthole.com) + * 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. + */ + + + +#include "glxheader.h" +#include "glxapi.h" +#include "GL/xmesa.h" +#include "context.h" +#include "config.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" +#include "version.h" +#include "xfonts.h" +#include "xmesaP.h" + +#ifdef __VMS +#define _mesa_sprintf sprintf +#endif + +/* This indicates the client-side GLX API and GLX encoder version. */ +#define CLIENT_MAJOR_VERSION 1 +#define CLIENT_MINOR_VERSION 4 /* but don't have 1.3's pbuffers, etc yet */ + +/* This indicates the server-side GLX decoder version. + * GLX 1.4 indicates OpenGL 1.3 support + */ +#define SERVER_MAJOR_VERSION 1 +#define SERVER_MINOR_VERSION 4 + +/* This is appended onto the glXGetClient/ServerString version strings. */ +#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING + +/* Who implemented this GLX? */ +#define VENDOR "Brian Paul" + +#define EXTENSIONS \ + "GLX_MESA_set_3dfx_mode " \ + "GLX_MESA_copy_sub_buffer " \ + "GLX_MESA_pixmap_colormap " \ + "GLX_MESA_release_buffers " \ + "GLX_ARB_get_proc_address " \ + "GLX_EXT_visual_info " \ + "GLX_EXT_visual_rating " \ + "GLX_SGI_video_sync " \ + "GLX_SGIX_fbconfig " \ + "GLX_SGIX_pbuffer " + +/* + * Our fake GLX context will contain a "real" GLX context and an XMesa context. + * + * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context, + * and vice versa. + * + * We really just need this structure in order to make the libGL functions + * glXGetCurrentContext(), glXGetCurrentDrawable() and glXGetCurrentDisplay() + * work correctly. + */ +struct fake_glx_context { + __GLXcontext glxContext; /* this MUST be first! */ + XMesaContext xmesaContext; +}; + + + +/**********************************************************************/ +/*** GLX Visual Code ***/ +/**********************************************************************/ + +#define DONT_CARE -1 + + +static XMesaVisual *VisualTable = NULL; +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; + } +} + + + +/** + * Get an array OverlayInfo records for specified screen. + * \param dpy the display + * \param screen screen number + * \param numOverlays returns numver of OverlayInfo records + * \return pointer to OverlayInfo array, free with XFree() + */ +static OverlayInfo * +GetOverlayInfo(Display *dpy, int screen, int *numOverlays) +{ + Atom overlayVisualsAtom; + Atom actualType; + Status status; + unsigned char *ovInfo; + unsigned long sizeData, bytesLeft; + int actualFormat; + + /* + * 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, screen), + overlayVisualsAtom, 0L, (long) 10000, False, + overlayVisualsAtom, &actualType, &actualFormat, + &sizeData, &bytesLeft, + &ovInfo); + + if (status != Success || actualType != overlayVisualsAtom || + actualFormat != 32 || sizeData < 4) { + /* something went wrong */ + XFree((void *) ovInfo); + *numOverlays = 0; + return NULL; + } + + *numOverlays = sizeData / 4; + return (OverlayInfo *) ovInfo; +} + + + +/** + * 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 ) +{ + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; + + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { + return 0; + } + + /* search the overlay visual list for the visual ID of interest */ + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *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 accumRedSize, GLint accumGreenSize, + GLint accumBlueSize, GLint accumAlphaSize, + GLint level, GLint numAuxBuffers ) +{ + GLboolean ximageFlag = GL_TRUE; + XMesaVisual xmvis; + GLint i; + GLboolean comparePointers; + + if (dbFlag) { + /* Check if the MESA_BACK_BUFFER env var is set */ + char *backbuffer = _mesa_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 { + _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage."); + } + } + } + + /* Comparing IDs uses less memory but sometimes fails. */ + /* XXX revisit this after 3.0 is finished. */ + if (_mesa_getenv("MESA_GLX_VISUAL_HACK")) + comparePointers = GL_TRUE; + else + comparePointers = GL_FALSE; + + /* Force the visual to have an alpha channel */ + if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA")) + alphaFlag = GL_TRUE; + + /* 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->mesa_visual.level == level + && v->mesa_visual.numAuxBuffers == numAuxBuffers + && v->ximage_flag == ximageFlag + && v->mesa_visual.rgbMode == rgbFlag + && v->mesa_visual.doubleBufferMode == dbFlag + && v->mesa_visual.stereoMode == stereoFlag + && (v->mesa_visual.alphaBits > 0) == alphaFlag + && (v->mesa_visual.depthBits >= depth_size || depth_size == 0) + && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0) + && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0) + && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0) + && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0) + && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) { + /* now either compare XVisualInfo pointers or visual IDs */ + if ((!comparePointers && v->visinfo->visualid == vinfo->visualid) + || (comparePointers && v->vishandle == vinfo)) { + return v; + } + } + } + + /* Create a new visual and add it to the list. */ + + xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag, + stereoFlag, ximageFlag, + depth_size, stencil_size, + accumRedSize, accumBlueSize, + accumBlueSize, accumAlphaSize, 0, level, + GLX_NONE_EXT ); + if (xmvis) { + /* Save a copy of the pointer now so we can find this visual again + * if we need to search for it in find_glx_visual(). + */ + xmvis->vishandle = vinfo; + /* Allocate more space for additional visual */ + VisualTable = _mesa_realloc( VisualTable, + sizeof(XMesaVisual) * NumVisuals, + sizeof(XMesaVisual) * (NumVisuals + 1)); + /* add xmvis to the list */ + VisualTable[NumVisuals] = xmvis; + NumVisuals++; + /* XXX minor hack, because XMesaCreateVisual doesn't support an + * aux buffers parameter. + */ + xmvis->mesa_visual.numAuxBuffers = numAuxBuffers; + } + return xmvis; +} + + +/** + * Return the default number of bits for the Z buffer. + * If defined, use the MESA_GLX_DEPTH_BITS env var value. + * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant. + * XXX probably do the same thing for stencil, accum, etc. + */ +static GLint +default_depth_bits(void) +{ + int zBits; + const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS"); + if (zEnv) + zBits = _mesa_atoi(zEnv); + else + zBits = DEFAULT_SOFTWARE_DEPTH_BITS; + return zBits; +} + + + +/* + * Create a GLX visual from a regular XVisualInfo. + * This is called when Fake GLX is given an XVisualInfo which wasn't + * returned by glXChooseVisual. Since this is the first time we're + * considering this visual we'll take a guess at reasonable values + * for depth buffer size, stencil size, accum size, etc. + * This is the best we can do with a client-side emulation of GLX. + */ +static XMesaVisual +create_glx_visual( Display *dpy, XVisualInfo *visinfo ) +{ + int vislevel; + GLint zBits = default_depth_bits(); + + 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,0,0,0, /* accum bits */ + vislevel, /* level */ + 0 /* numAux */ + ); + } + else if (is_usable_visual( visinfo )) { + if (_mesa_getenv("MESA_GLX_FORCE_CI")) { + /* Configure this visual as a COLOR INDEX visual. */ + return save_glx_visual( dpy, visinfo, + GL_FALSE, /* rgb */ + GL_FALSE, /* alpha */ + GL_TRUE, /* double */ + GL_FALSE, /* stereo */ + zBits, + STENCIL_BITS, + 0, 0, 0, 0, /* accum bits */ + 0, /* level */ + 0 /* numAux */ + ); + } + else { + /* 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 */ + zBits, + STENCIL_BITS, + ACCUM_BITS, /* r */ + ACCUM_BITS, /* g */ + ACCUM_BITS, /* b */ + ACCUM_BITS, /* a */ + 0, /* level */ + 0 /* numAux */ + ); + } + } + else { + _mesa_warning(NULL, "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; + + /* 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]; + } + } + + /* if that fails, try to match pointers */ + for (i=0;i<NumVisuals;i++) { + if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) { + 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; + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; + + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { + return -1; + } + + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *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; +} + + + +/** + * 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 (_mesa_bitcount((GLuint) vis->red_mask ) <= 8 && + _mesa_bitcount((GLuint) vis->green_mask) <= 8 && + _mesa_bitcount((GLuint) 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 (!_mesa_getenv( varname )) { + return NULL; + } + + _mesa_strncpy( value, _mesa_getenv(varname), 100 ); + value[99] = 0; + + sscanf( value, "%s %d", type, &depth ); + + if (_mesa_strcmp(type,"TrueColor")==0) xclass = TrueColor; + else if (_mesa_strcmp(type,"DirectColor")==0) xclass = DirectColor; + else if (_mesa_strcmp(type,"PseudoColor")==0) xclass = PseudoColor; + else if (_mesa_strcmp(type,"StaticColor")==0) xclass = StaticColor; + else if (_mesa_strcmp(type,"GrayScale")==0) xclass = GrayScale; + else if (_mesa_strcmp(type,"StaticGray")==0) xclass = StaticGray; + + if (xclass>-1 && depth>0) { + vis = get_visual( dpy, scr, depth, xclass ); + if (vis) { + return vis; + } + } + + _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.", + 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 = 0; + 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, GLboolean rgbFlag, + int level, int trans_type, int trans_value, + int min_depth, int preferred_class ) +{ + OverlayInfo *overlay_info; + int numOverlaysPerScreen; + 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; + } + + overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen); + if (!overlay_info) { + return NULL; + } + + /* Search for the deepest overlay which satisifies all criteria. */ + deepest = min_depth; + deepvis = NULL; + + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + XVisualInfo *vislist, vistemplate; + int count; + + 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 RGB was requested, make sure we have True/DirectColor */ + if (rgbFlag && vislist->CLASS != TrueColor + && vislist->CLASS != DirectColor) + continue; + + /* if CI was requested, make sure we have a color indexed visual */ + if (!rgbFlag + && (vislist->CLASS == TrueColor || vislist->CLASS == DirectColor)) + continue; + + if (deepvis==NULL || vislist->depth > deepest) { + /* YES! found a satisfactory visual */ + if (deepvis) { + XFree( 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; +} + + +/**********************************************************************/ +/*** Begin Fake GLX API Functions ***/ +/**********************************************************************/ + + +/** + * Helper used by glXChooseVisual and glXChooseFBConfig. + * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for + * the later. + * In either case, the attribute list is terminated with the value 'None'. + */ +static XMesaVisual +choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) +{ + const GLboolean rgbModeDefault = fbConfig; + const int *parselist; + XVisualInfo *vis; + int min_ci = 0; + int min_red=0, min_green=0, min_blue=0; + GLboolean rgb_flag = rgbModeDefault; + GLboolean alpha_flag = GL_FALSE; + GLboolean double_flag = GL_FALSE; + GLboolean stereo_flag = GL_FALSE; + GLint depth_size = 0; + GLint stencil_size = 0; + GLint accumRedSize = 0; + GLint accumGreenSize = 0; + GLint accumBlueSize = 0; + GLint accumAlphaSize = 0; + int level = 0; + int visual_type = DONT_CARE; + int trans_type = DONT_CARE; + int trans_value = DONT_CARE; + GLint caveat = DONT_CARE; + XMesaVisual xmvis = NULL; + int desiredVisualID = -1; + int numAux = 0; + + parselist = list; + + while (*parselist) { + + switch (*parselist) { + case GLX_USE_GL: + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + /* skip */ + parselist++; + } + break; + case GLX_BUFFER_SIZE: + parselist++; + min_ci = *parselist++; + break; + case GLX_LEVEL: + parselist++; + level = *parselist++; + break; + case GLX_RGBA: + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + rgb_flag = GL_TRUE; + parselist++; + } + break; + case GLX_DOUBLEBUFFER: + parselist++; + if (fbConfig) { + double_flag = *parselist++; + } + else { + double_flag = GL_TRUE; + } + break; + case GLX_STEREO: + parselist++; + if (fbConfig) { + stereo_flag = *parselist++; + } + else { + stereo_flag = GL_TRUE; + } + return NULL; /* stereo not supported */ + case GLX_AUX_BUFFERS: + parselist++; + numAux = *parselist++; + if (numAux > MAX_AUX_BUFFERS) + return NULL; + 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: + parselist++; + { + GLint size = *parselist++; + accumRedSize = MAX2( accumRedSize, size ); + } + break; + case GLX_ACCUM_GREEN_SIZE: + parselist++; + { + GLint size = *parselist++; + accumGreenSize = MAX2( accumGreenSize, size ); + } + break; + case GLX_ACCUM_BLUE_SIZE: + parselist++; + { + GLint size = *parselist++; + accumBlueSize = MAX2( accumBlueSize, size ); + } + break; + case GLX_ACCUM_ALPHA_SIZE: + parselist++; + { + GLint size = *parselist++; + accumAlphaSize = MAX2( accumAlphaSize, 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; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_VISUAL_CAVEAT_EXT: + parselist++; + caveat = *parselist++; /* ignored for now */ + break; + + /* + * GLX_ARB_multisample + */ + case GLX_SAMPLE_BUFFERS_ARB: + /* ms not supported */ + return NULL; + case GLX_SAMPLES_ARB: + /* ms not supported */ + return NULL; + + /* + * FBConfig attribs. + */ + case GLX_RENDER_TYPE: + if (!fbConfig) + return NULL; + parselist++; + if (*parselist == GLX_RGBA_BIT) { + rgb_flag = GL_TRUE; + } + else if (*parselist == GLX_COLOR_INDEX_BIT) { + rgb_flag = GL_FALSE; + } + else if (*parselist == 0) { + rgb_flag = GL_TRUE; + } + parselist++; + break; + case GLX_DRAWABLE_TYPE: + if (!fbConfig) + return NULL; + parselist++; + if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { + return NULL; /* bad bit */ + } + parselist++; + break; + case GLX_FBCONFIG_ID: + if (!fbConfig) + return NULL; + parselist++; + desiredVisualID = *parselist++; + break; + case GLX_X_RENDERABLE: + if (!fbConfig) + return NULL; + parselist += 2; + /* ignore */ + break; + + case None: + /* end of list */ + break; + + default: + /* undefined attribute */ + _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()", + *parselist); + return NULL; + } + } + + (void) caveat; + + /* + * 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 (desiredVisualID != -1) { + /* try to get a specific visual, by visualID */ + XVisualInfo temp; + int n; + temp.visualid = desiredVisualID; + temp.screen = screen; + vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); + if (vis) { + /* give the visual some useful GLX attributes */ + double_flag = GL_TRUE; + if (vis->depth > 8) + rgb_flag = GL_TRUE; + depth_size = default_depth_bits(); + stencil_size = STENCIL_BITS; + /* XXX accum??? */ + } + } + else 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 ); + accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0; + } + } + else { + /* over/underlay planes */ + if (rgb_flag) { + /* rgba overlay */ + 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_overlay_visual( dpy, screen, rgb_flag, level, + trans_type, trans_value, min_rgb, visual_type ); + } + else { + /* color index overlay */ + vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, + trans_type, trans_value, min_ci, visual_type ); + } + } + + if (vis) { + /* Note: we're not exactly obeying the glXChooseVisual rules here. + * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the + * largest depth buffer size, which is 32bits/value. Instead, we + * return 16 to maintain performance with earlier versions of Mesa. + */ + if (depth_size > 24) + depth_size = 31; /* 32 causes int overflow problems */ + else if (depth_size > 16) + depth_size = 24; + else if (depth_size > 0) { + depth_size = default_depth_bits(); + } + + /* we only support one size of stencil and accum buffers. */ + if (stencil_size > 0) + stencil_size = STENCIL_BITS; + if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || + accumAlphaSize > 0) { + accumRedSize = ACCUM_BITS; + accumGreenSize = ACCUM_BITS; + accumBlueSize = ACCUM_BITS; + accumAlphaSize = alpha_flag ? ACCUM_BITS : 0; + } + + xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag, + stereo_flag, depth_size, stencil_size, + accumRedSize, accumGreenSize, + accumBlueSize, accumAlphaSize, level, numAux ); + } + + return xmvis; +} + + +static XVisualInfo * +Fake_glXChooseVisual( Display *dpy, int screen, int *list ) +{ + XMesaVisual xmvis = choose_visual(dpy, screen, list, GL_FALSE); + if (xmvis) { +#if 0 + return xmvis->vishandle; +#else + /* create a new vishandle - the cached one may be stale */ + xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); + if (xmvis->vishandle) { + _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + } + return xmvis->vishandle; +#endif + } + else + return NULL; +} + + +static GLXContext +Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, + GLXContext share_list, Bool direct ) +{ + XMesaVisual xmvis; + struct fake_glx_context *glxCtx; + struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; + + if (!dpy || !visinfo) + return 0; + + glxCtx = CALLOC_STRUCT(fake_glx_context); + if (!glxCtx) + return 0; + + /* deallocate unused windows/buffers */ + XMesaGarbageCollect(); + + xmvis = find_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* This visual wasn't found with glXChooseVisual() */ + xmvis = create_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* unusable visual */ + FREE(glxCtx); + return NULL; + } + } + + glxCtx->xmesaContext = XMesaCreateContext(xmvis, + shareCtx ? shareCtx->xmesaContext : NULL); + if (!glxCtx->xmesaContext) { + FREE(glxCtx); + return NULL; + } + + glxCtx->xmesaContext->direct = GL_FALSE; + glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.currentDpy = dpy; + glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ + + assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + + return (GLXContext) glxCtx; +} + + +/* XXX these may have to be removed due to thread-safety issues. */ +static GLXContext MakeCurrent_PrevContext = 0; +static GLXDrawable MakeCurrent_PrevDrawable = 0; +static GLXDrawable MakeCurrent_PrevReadable = 0; +static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0; +static XMesaBuffer MakeCurrent_PrevReadBuffer = 0; + + +/* GLX 1.3 and later */ +static Bool +Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, + GLXDrawable read, GLXContext ctx ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + + if (ctx && draw && read) { + XMesaBuffer drawBuffer, readBuffer; + XMesaContext xmctx = glxCtx->xmesaContext; + + /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */ + if (ctx == MakeCurrent_PrevContext + && draw == MakeCurrent_PrevDrawable) { + drawBuffer = MakeCurrent_PrevDrawBuffer; + } + else { + drawBuffer = XMesaFindBuffer( dpy, draw ); + } + if (!drawBuffer) { + /* drawable must be a new window! */ + drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, xmctx); + if (!drawBuffer) { + /* Out of memory, or context/drawable depth mismatch */ + return False; + } + } + + /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ + if (ctx == MakeCurrent_PrevContext + && read == MakeCurrent_PrevReadable) { + readBuffer = MakeCurrent_PrevReadBuffer; + } + else { + readBuffer = XMesaFindBuffer( dpy, read ); + } + if (!readBuffer) { + /* drawable must be a new window! */ + readBuffer = XMesaCreateWindowBuffer2(glxCtx->xmesaContext->xm_visual, + read, xmctx); + if (!readBuffer) { + /* Out of memory, or context/drawable depth mismatch */ + return False; + } + } + + MakeCurrent_PrevContext = ctx; + MakeCurrent_PrevDrawable = draw; + MakeCurrent_PrevReadable = read; + MakeCurrent_PrevDrawBuffer = drawBuffer; + MakeCurrent_PrevReadBuffer = readBuffer; + + /* Now make current! */ + if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) { + ((__GLXcontext *) ctx)->currentDpy = dpy; + ((__GLXcontext *) ctx)->currentDrawable = draw; + ((__GLXcontext *) ctx)->currentReadable = read; + return True; + } + else { + return False; + } + } + else if (!ctx && !draw && !read) { + /* release current context w/out assigning new one. */ + XMesaMakeCurrent( NULL, NULL ); + MakeCurrent_PrevContext = 0; + MakeCurrent_PrevDrawable = 0; + MakeCurrent_PrevReadable = 0; + MakeCurrent_PrevDrawBuffer = 0; + MakeCurrent_PrevReadBuffer = 0; + return True; + } + else { + /* The args must either all be non-zero or all zero. + * This is an error. + */ + return False; + } +} + + +static Bool +Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) +{ + return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx ); +} + + +static 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->frontxrb->pixmap; +} + + +/*** GLX_MESA_pixmap_colormap ***/ + +static 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->frontxrb->pixmap; +} + + +static void +Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, pixmap); + if (b) { + XMesaDestroyBuffer(b); + } + else if (_mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n"); + } +} + + +static void +Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, + unsigned long mask ) +{ + struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src; + struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst; + XMesaContext xm_src = fakeSrc->xmesaContext; + XMesaContext xm_dst = fakeDst->xmesaContext; + (void) dpy; + _mesa_copy_context( &(xm_src->mesa), &(xm_dst->mesa), (GLuint) mask ); +} + + +static 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; +} + + +extern void _kw_ungrab_all( Display *dpy ); +void _kw_ungrab_all( Display *dpy ) +{ + XUngrabPointer( dpy, CurrentTime ); + XUngrabKeyboard( dpy, CurrentTime ); +} + + +static void +Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + (void) dpy; + MakeCurrent_PrevContext = 0; + MakeCurrent_PrevDrawable = 0; + MakeCurrent_PrevReadable = 0; + MakeCurrent_PrevDrawBuffer = 0; + MakeCurrent_PrevReadBuffer = 0; + XMesaDestroyContext( glxCtx->xmesaContext ); + XMesaGarbageCollect(); +} + + +static Bool +Fake_glXIsDirect( Display *dpy, GLXContext ctx ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + (void) dpy; + return glxCtx->xmesaContext->direct; +} + + + +static void +Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) +{ + XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); + + if (buffer) { + XMesaSwapBuffers(buffer); + } + else if (_mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", + (int) drawable); + } +} + + + +/*** GLX_MESA_copy_sub_buffer ***/ + +static 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 (_mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n"); + } +} + + +static Bool +Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) +{ + (void) dpy; + /* Return GLX version, not Mesa version */ + assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION); + *maj = CLIENT_MAJOR_VERSION; + *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION ); + return True; +} + + +/* + * Query the GLX attributes of the given XVisualInfo. + */ +static int +get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) +{ + ASSERT(xmvis); + switch(attrib) { + case GLX_USE_GL: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = (int) True; + return 0; + case GLX_BUFFER_SIZE: + *value = xmvis->visinfo->depth; + return 0; + case GLX_LEVEL: + *value = xmvis->mesa_visual.level; + return 0; + case GLX_RGBA: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; + if (xmvis->mesa_visual.rgbMode) { + *value = True; + } + else { + *value = False; + } + return 0; + case GLX_DOUBLEBUFFER: + *value = (int) xmvis->mesa_visual.doubleBufferMode; + return 0; + case GLX_STEREO: + *value = (int) xmvis->mesa_visual.stereoMode; + return 0; + case GLX_AUX_BUFFERS: + *value = xmvis->mesa_visual.numAuxBuffers; + return 0; + case GLX_RED_SIZE: + *value = xmvis->mesa_visual.redBits; + return 0; + case GLX_GREEN_SIZE: + *value = xmvis->mesa_visual.greenBits; + return 0; + case GLX_BLUE_SIZE: + *value = xmvis->mesa_visual.blueBits; + return 0; + case GLX_ALPHA_SIZE: + *value = xmvis->mesa_visual.alphaBits; + return 0; + case GLX_DEPTH_SIZE: + *value = xmvis->mesa_visual.depthBits; + return 0; + case GLX_STENCIL_SIZE: + *value = xmvis->mesa_visual.stencilBits; + return 0; + case GLX_ACCUM_RED_SIZE: + *value = xmvis->mesa_visual.accumRedBits; + return 0; + case GLX_ACCUM_GREEN_SIZE: + *value = xmvis->mesa_visual.accumGreenBits; + return 0; + case GLX_ACCUM_BLUE_SIZE: + *value = xmvis->mesa_visual.accumBlueBits; + return 0; + case GLX_ACCUM_ALPHA_SIZE: + *value = xmvis->mesa_visual.accumAlphaBits; + return 0; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_X_VISUAL_TYPE_EXT: + switch (xmvis->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 (xmvis->mesa_visual.level==0) { + /* normal planes */ + *value = GLX_NONE_EXT; + } + else if (xmvis->mesa_visual.level>0) { + /* overlay */ + if (xmvis->mesa_visual.rgbMode) { + *value = GLX_TRANSPARENT_RGB_EXT; + } + else { + *value = GLX_TRANSPARENT_INDEX_EXT; + } + } + else if (xmvis->mesa_visual.level<0) { + /* underlay */ + *value = GLX_NONE_EXT; + } + return 0; + case GLX_TRANSPARENT_INDEX_VALUE_EXT: + { + int pixel = transparent_pixel( xmvis ); + 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; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_VISUAL_CAVEAT_EXT: + /* test for zero, just in case */ + if (xmvis->mesa_visual.visualRating > 0) + *value = xmvis->mesa_visual.visualRating; + else + *value = GLX_NONE_EXT; + return 0; + + /* + * GLX_ARB_multisample + */ + case GLX_SAMPLE_BUFFERS_ARB: + *value = 0; + return 0; + case GLX_SAMPLES_ARB: + *value = 0; + return 0; + + /* + * For FBConfigs: + */ + case GLX_SCREEN_EXT: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = xmvis->visinfo->screen; + break; + case GLX_DRAWABLE_TYPE: /*SGIX too */ + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; + break; + case GLX_RENDER_TYPE_SGIX: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + if (xmvis->mesa_visual.rgbMode) + *value = GLX_RGBA_BIT; + else + *value = GLX_COLOR_INDEX_BIT; + break; + case GLX_X_RENDERABLE_SGIX: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = True; /* XXX really? */ + break; + case GLX_FBCONFIG_ID_SGIX: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = xmvis->visinfo->visualid; + break; + case GLX_MAX_PBUFFER_WIDTH: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + /* XXX or MAX_WIDTH? */ + *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen); + break; + case GLX_MAX_PBUFFER_HEIGHT: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen); + break; + case GLX_MAX_PBUFFER_PIXELS: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) * + DisplayHeight(xmvis->display, xmvis->visinfo->screen); + break; + case GLX_VISUAL_ID: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = xmvis->visinfo->visualid; + break; + + default: + return GLX_BAD_ATTRIBUTE; + } + return Success; +} + + +static int +Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, + int attrib, int *value ) +{ + XMesaVisual xmvis; + int k; + if (!dpy || !visinfo) + return GLX_BAD_ATTRIBUTE; + + xmvis = find_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* this visual wasn't obtained with glXChooseVisual */ + xmvis = create_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* this visual can't be used for GL rendering */ + if (attrib==GLX_USE_GL) { + *value = (int) False; + return 0; + } + else { + return GLX_BAD_VISUAL; + } + } + } + + k = get_config(xmvis, attrib, value, GL_FALSE); + return k; +} + + +static void +Fake_glXWaitGL( void ) +{ + XMesaContext xmesa = XMesaGetCurrentContext(); + XMesaFlush( xmesa ); +} + + + +static void +Fake_glXWaitX( void ) +{ + XMesaContext xmesa = XMesaGetCurrentContext(); + XMesaFlush( xmesa ); +} + + +static const char * +get_extensions( void ) +{ +#ifdef FX + const char *fx = _mesa_getenv("MESA_GLX_FX"); + if (fx && fx[0] != 'd') { + return EXTENSIONS; + } +#endif + return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */ +} + + + +/* GLX 1.1 and later */ +static const char * +Fake_glXQueryExtensionsString( Display *dpy, int screen ) +{ + (void) dpy; + (void) screen; + return get_extensions(); +} + + + +/* GLX 1.1 and later */ +static const char * +Fake_glXQueryServerString( Display *dpy, int screen, int name ) +{ + static char version[1000]; + _mesa_sprintf(version, "%d.%d %s", + SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); + + (void) dpy; + (void) screen; + + switch (name) { + case GLX_EXTENSIONS: + return get_extensions(); + case GLX_VENDOR: + return VENDOR; + case GLX_VERSION: + return version; + default: + return NULL; + } +} + + + +/* GLX 1.1 and later */ +static const char * +Fake_glXGetClientString( Display *dpy, int name ) +{ + static char version[1000]; + _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, + CLIENT_MINOR_VERSION, MESA_GLX_VERSION); + + (void) dpy; + + switch (name) { + case GLX_EXTENSIONS: + return get_extensions(); + case GLX_VENDOR: + return VENDOR; + case GLX_VERSION: + return version; + default: + return NULL; + } +} + + + +/* + * GLX 1.3 and later + */ + + +static int +Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, + int attribute, int *value ) +{ + XMesaVisual v = (XMesaVisual) config; + (void) dpy; + (void) config; + + if (!dpy || !config || !value) + return -1; + + return get_config(v, attribute, value, GL_TRUE); +} + + +static GLXFBConfig * +Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) +{ + XVisualInfo *visuals, visTemplate; + const long visMask = VisualScreenMask; + int i; + + /* Get list of all X visuals */ + visTemplate.screen = screen; + visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); + if (*nelements > 0) { + XMesaVisual *results; + results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual)); + if (!results) { + *nelements = 0; + return NULL; + } + for (i = 0; i < *nelements; i++) { + results[i] = create_glx_visual(dpy, visuals + i); + } + return (GLXFBConfig *) results; + } + return NULL; +} + + +static GLXFBConfig * +Fake_glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ) +{ + XMesaVisual xmvis; + + if (!attribList || !attribList[0]) { + /* return list of all configs (per GLX_SGIX_fbconfig spec) */ + return Fake_glXGetFBConfigs(dpy, screen, nitems); + } + + xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); + if (xmvis) { + GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); + if (!config) { + *nitems = 0; + return NULL; + } + *nitems = 1; + config[0] = (GLXFBConfig) xmvis; + return (GLXFBConfig *) config; + } + else { + *nitems = 0; + return NULL; + } +} + + +static XVisualInfo * +Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) +{ + if (dpy && config) { + XMesaVisual xmvis = (XMesaVisual) config; +#if 0 + return xmvis->vishandle; +#else + /* create a new vishandle - the cached one may be stale */ + xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); + if (xmvis->vishandle) { + _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + } + return xmvis->vishandle; +#endif + } + else { + return NULL; + } +} + + +static GLXWindow +Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, + const int *attribList ) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + if (!xmvis) + return 0; + + xmbuf = XMesaCreateWindowBuffer2(xmvis, win, NULL); + if (!xmbuf) + return 0; + + (void) dpy; + (void) attribList; /* Ignored in GLX 1.3 */ + + return win; /* A hack for now */ +} + + +static void +Fake_glXDestroyWindow( Display *dpy, GLXWindow window ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window); + if (b) + XMesaDestroyBuffer(b); + /* don't destroy X window */ +} + + +/* XXX untested */ +static GLXPixmap +Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, + const int *attribList ) +{ + XMesaVisual v = (XMesaVisual) config; + XMesaBuffer b; + + (void) dpy; + (void) config; + (void) pixmap; + (void) attribList; /* Ignored in GLX 1.3 */ + + if (!dpy || !config || !pixmap) + return 0; + + b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + if (!b) { + return 0; + } + + return pixmap; +} + + +static void +Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap); + if (b) + XMesaDestroyBuffer(b); + /* don't destroy X pixmap */ +} + + +static GLXPbuffer +Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, + const int *attribList ) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + const int *attrib; + int width = 0, height = 0; + GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; + + (void) dpy; + + for (attrib = attribList; *attrib; attrib++) { + switch (*attrib) { + case GLX_PBUFFER_WIDTH: + attrib++; + width = *attrib; + break; + case GLX_PBUFFER_HEIGHT: + attrib++; + height = *attrib; + break; + case GLX_PRESERVED_CONTENTS: + attrib++; + preserveContents = *attrib; /* ignored */ + break; + case GLX_LARGEST_PBUFFER: + attrib++; + useLargest = *attrib; /* ignored */ + break; + default: + return 0; + } + } + + /* not used at this time */ + (void) useLargest; + (void) preserveContents; + + if (width == 0 || height == 0) + return 0; + + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); + /* A GLXPbuffer handle must be an X Drawable because that's what + * glXMakeCurrent takes. + */ + if (xmbuf) + return (GLXPbuffer) xmbuf->frontxrb->pixmap; + else + return 0; +} + + +static void +Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, pbuf); + if (b) { + XMesaDestroyBuffer(b); + } +} + + +static void +Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, + unsigned int *value ) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); + if (!xmbuf) + return; + + switch (attribute) { + case GLX_WIDTH: + *value = xmbuf->mesa_buffer.Width; + break; + case GLX_HEIGHT: + *value = xmbuf->mesa_buffer.Height; + break; + case GLX_PRESERVED_CONTENTS: + *value = True; + break; + case GLX_LARGEST_PBUFFER: + *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; + break; + case GLX_FBCONFIG_ID: + *value = xmbuf->xm_visual->visinfo->visualid; + return; + default: + return; /* GLX_BAD_ATTRIBUTE? */ + } +} + + +static GLXContext +Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, + int renderType, GLXContext shareList, Bool direct ) +{ + struct fake_glx_context *glxCtx; + struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList; + XMesaVisual xmvis = (XMesaVisual) config; + + if (!dpy || !config || + (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE)) + return 0; + + glxCtx = CALLOC_STRUCT(fake_glx_context); + if (!glxCtx) + return 0; + + /* deallocate unused windows/buffers */ + XMesaGarbageCollect(); + + glxCtx->xmesaContext = XMesaCreateContext(xmvis, + shareCtx ? shareCtx->xmesaContext : NULL); + if (!glxCtx->xmesaContext) { + FREE(glxCtx); + return NULL; + } + + glxCtx->xmesaContext->direct = GL_FALSE; + glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.currentDpy = dpy; + glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ + + assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + + return (GLXContext) glxCtx; +} + + +static int +Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + XMesaContext xmctx = glxCtx->xmesaContext; + + (void) dpy; + (void) ctx; + + switch (attribute) { + case GLX_FBCONFIG_ID: + *value = xmctx->xm_visual->visinfo->visualid; + break; + case GLX_RENDER_TYPE: + if (xmctx->xm_visual->mesa_visual.rgbMode) + *value = GLX_RGBA_BIT; + else + *value = GLX_COLOR_INDEX_BIT; + break; + case GLX_SCREEN: + *value = 0; + return Success; + default: + return GLX_BAD_ATTRIBUTE; + } + return 0; +} + + +static void +Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) + xmbuf->selectedEvents = mask; +} + + +static void +Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, + unsigned long *mask ) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) + *mask = xmbuf->selectedEvents; + else + *mask = 0; +} + + + +/*** GLX_SGI_swap_control ***/ + +static int +Fake_glXSwapIntervalSGI(int interval) +{ + (void) interval; + return 0; +} + + + +/*** GLX_SGI_video_sync ***/ + +static int +Fake_glXGetVideoSyncSGI(unsigned int *count) +{ + (void) count; + return 0; +} + +static int +Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) +{ + (void) divisor; + (void) remainder; + (void) count; + return 0; +} + + + +/*** GLX_SGI_make_current_read ***/ + +static Bool +Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + return Fake_glXMakeContextCurrent( dpy, draw, read, ctx ); +} + +/* not used +static GLXDrawable +Fake_glXGetCurrentReadDrawableSGI(void) +{ + return 0; +} +*/ + + +/*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + +static GLXVideoSourceSGIX +Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) +{ + (void) dpy; + (void) screen; + (void) server; + (void) path; + (void) nodeClass; + (void) drainNode; + return 0; +} + +static void +Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) +{ + (void) dpy; + (void) src; +} + +#endif + + +/*** GLX_EXT_import_context ***/ + +static void +Fake_glXFreeContextEXT(Display *dpy, GLXContext context) +{ + (void) dpy; + (void) context; +} + +static GLXContextID +Fake_glXGetContextIDEXT(const GLXContext context) +{ + (void) context; + return 0; +} + +static GLXContext +Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID) +{ + (void) dpy; + (void) contextID; + return 0; +} + +static int +Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) +{ + (void) dpy; + (void) context; + (void) attribute; + (void) value; + return 0; +} + + + +/*** GLX_SGIX_fbconfig ***/ + +static int +Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) +{ + return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value); +} + +static GLXFBConfigSGIX * +Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) +{ + return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements); +} + + +static GLXPixmap +Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); + return xmbuf->frontxrb->pixmap; /* need to return an X ID */ +} + + +static GLXContext +Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) +{ + XMesaVisual xmvis = (XMesaVisual) config; + struct fake_glx_context *glxCtx; + struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; + + glxCtx = CALLOC_STRUCT(fake_glx_context); + if (!glxCtx) + return 0; + + /* deallocate unused windows/buffers */ + XMesaGarbageCollect(); + + glxCtx->xmesaContext = XMesaCreateContext(xmvis, + shareCtx ? shareCtx->xmesaContext : NULL); + if (!glxCtx->xmesaContext) { + FREE(glxCtx); + return NULL; + } + + glxCtx->xmesaContext->direct = GL_FALSE; + glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.currentDpy = dpy; + glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ + + assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + + return (GLXContext) glxCtx; +} + + +static XVisualInfo * +Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) +{ + return Fake_glXGetVisualFromFBConfig(dpy, config); +} + + +static GLXFBConfigSGIX +Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) +{ + XMesaVisual xmvis = find_glx_visual(dpy, vis); + if (!xmvis) { + /* This visual wasn't found with glXChooseVisual() */ + xmvis = create_glx_visual(dpy, vis); + } + + return (GLXFBConfigSGIX) xmvis; +} + + + +/*** GLX_SGIX_pbuffer ***/ + +static GLXPbufferSGIX +Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, + unsigned int width, unsigned int height, + int *attribList) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + const int *attrib; + GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; + + (void) dpy; + + for (attrib = attribList; attrib && *attrib; attrib++) { + switch (*attrib) { + case GLX_PRESERVED_CONTENTS_SGIX: + attrib++; + preserveContents = *attrib; /* ignored */ + break; + case GLX_LARGEST_PBUFFER_SGIX: + attrib++; + useLargest = *attrib; /* ignored */ + break; + default: + return 0; + } + } + + /* not used at this time */ + (void) useLargest; + (void) preserveContents; + + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); + /* A GLXPbuffer handle must be an X Drawable because that's what + * glXMakeCurrent takes. + */ + return (GLXPbuffer) xmbuf->frontxrb->pixmap; +} + + +static void +Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); + if (xmbuf) { + XMesaDestroyBuffer(xmbuf); + } +} + + +static int +Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) +{ + const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); + + if (!xmbuf) { + /* Generate GLXBadPbufferSGIX for bad pbuffer */ + return 0; + } + + switch (attribute) { + case GLX_PRESERVED_CONTENTS_SGIX: + *value = True; + break; + case GLX_LARGEST_PBUFFER_SGIX: + *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; + break; + case GLX_WIDTH_SGIX: + *value = xmbuf->mesa_buffer.Width; + break; + case GLX_HEIGHT_SGIX: + *value = xmbuf->mesa_buffer.Height; + break; + case GLX_EVENT_MASK_SGIX: + *value = 0; /* XXX might be wrong */ + break; + default: + *value = 0; + } + return 0; +} + + +static void +Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) { + /* Note: we'll never generate clobber events */ + xmbuf->selectedEvents = mask; + } +} + + +static void +Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) { + *mask = xmbuf->selectedEvents; + } + else { + *mask = 0; + } +} + + + +/*** GLX_SGI_cushion ***/ + +static void +Fake_glXCushionSGI(Display *dpy, Window win, float cushion) +{ + (void) dpy; + (void) win; + (void) cushion; +} + + + +/*** GLX_SGIX_video_resize ***/ + +static int +Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) window; + return 0; +} + +static int +Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) x; + (void) y; + (void) w; + (void) h; + return 0; +} + +static int +Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) x; + (void) y; + (void) w; + (void) h; + return 0; +} + +static int +Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) dx; + (void) dy; + (void) dw; + (void) dh; + return 0; +} + +static int +Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) synctype; + return 0; +} + + + +/*** GLX_SGIX_dmbuffer **/ + +#if defined(_DM_BUFFER_H_) +static Bool +Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) +{ + (void) dpy; + (void) pbuffer; + (void) params; + (void) dmbuffer; + return False; +} +#endif + + +/*** GLX_SGIX_swap_group ***/ + +static void +Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) +{ + (void) dpy; + (void) drawable; + (void) member; +} + + + +/*** GLX_SGIX_swap_barrier ***/ + +static void +Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) +{ + (void) dpy; + (void) drawable; + (void) barrier; +} + +static Bool +Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) +{ + (void) dpy; + (void) screen; + (void) max; + return False; +} + + + +/*** GLX_SUN_get_transparent_index ***/ + +static Status +Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) +{ + (void) dpy; + (void) overlay; + (void) underlay; + (void) pTransparent; + return 0; +} + + + +/*** GLX_MESA_release_buffers ***/ + +/* + * Release the depth, stencil, accum buffers attached to a GLXDrawable + * (a window or pixmap) prior to destroying the GLXDrawable. + */ +static Bool +Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, d); + if (b) { + XMesaDestroyBuffer(b); + return True; + } + return False; +} + + + +/*** GLX_MESA_set_3dfx_mode ***/ + +static Bool +Fake_glXSet3DfxModeMESA( int mode ) +{ + return XMesaSetFXmode( mode ); +} + + + +/*** GLX_NV_vertex_array range ***/ +static void * +Fake_glXAllocateMemoryNV( GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority ) +{ + (void) size; + (void) readFrequency; + (void) writeFrequency; + (void) priority; + return NULL; +} + + +static void +Fake_glXFreeMemoryNV( GLvoid *pointer ) +{ + (void) pointer; +} + + +/*** GLX_MESA_agp_offset ***/ + +static GLuint +Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) +{ + (void) pointer; + return ~0; +} + + +/* silence warning */ +extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); + + +/** + * Create a new GLX API dispatch table with its function pointers + * initialized to point to Mesa's "fake" GLX API functions. + * Note: there's a similar function (_real_GetGLXDispatchTable) that + * returns a new dispatch table with all pointers initalized to point + * to "real" GLX functions (which understand GLX wire protocol, etc). + */ +struct _glxapi_table * +_mesa_GetGLXDispatchTable(void) +{ + static struct _glxapi_table glx; + + /* be sure our dispatch table size <= libGL's table */ + { + GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); + (void) size; + assert(_glxapi_get_dispatch_table_size() >= size); + } + + /* initialize the whole table to no-ops */ + _glxapi_set_no_op_table(&glx); + + /* now initialize the table with the functions I implement */ + glx.ChooseVisual = Fake_glXChooseVisual; + glx.CopyContext = Fake_glXCopyContext; + glx.CreateContext = Fake_glXCreateContext; + glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap; + glx.DestroyContext = Fake_glXDestroyContext; + glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap; + glx.GetConfig = Fake_glXGetConfig; + /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/ + /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/ + glx.IsDirect = Fake_glXIsDirect; + glx.MakeCurrent = Fake_glXMakeCurrent; + glx.QueryExtension = Fake_glXQueryExtension; + glx.QueryVersion = Fake_glXQueryVersion; + glx.SwapBuffers = Fake_glXSwapBuffers; + glx.UseXFont = Fake_glXUseXFont; + glx.WaitGL = Fake_glXWaitGL; + glx.WaitX = Fake_glXWaitX; + + /*** GLX_VERSION_1_1 ***/ + glx.GetClientString = Fake_glXGetClientString; + glx.QueryExtensionsString = Fake_glXQueryExtensionsString; + glx.QueryServerString = Fake_glXQueryServerString; + + /*** GLX_VERSION_1_2 ***/ + /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/ + + /*** GLX_VERSION_1_3 ***/ + glx.ChooseFBConfig = Fake_glXChooseFBConfig; + glx.CreateNewContext = Fake_glXCreateNewContext; + glx.CreatePbuffer = Fake_glXCreatePbuffer; + glx.CreatePixmap = Fake_glXCreatePixmap; + glx.CreateWindow = Fake_glXCreateWindow; + glx.DestroyPbuffer = Fake_glXDestroyPbuffer; + glx.DestroyPixmap = Fake_glXDestroyPixmap; + glx.DestroyWindow = Fake_glXDestroyWindow; + /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/ + glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib; + glx.GetFBConfigs = Fake_glXGetFBConfigs; + glx.GetSelectedEvent = Fake_glXGetSelectedEvent; + glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig; + glx.MakeContextCurrent = Fake_glXMakeContextCurrent; + glx.QueryContext = Fake_glXQueryContext; + glx.QueryDrawable = Fake_glXQueryDrawable; + glx.SelectEvent = Fake_glXSelectEvent; + + /*** GLX_SGI_swap_control ***/ + glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI; + + /*** GLX_SGI_video_sync ***/ + glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI; + glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI; + + /*** GLX_SGI_make_current_read ***/ + glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI; + /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/ + +/*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX; + glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX; +#endif + + /*** GLX_EXT_import_context ***/ + glx.FreeContextEXT = Fake_glXFreeContextEXT; + glx.GetContextIDEXT = Fake_glXGetContextIDEXT; + /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/ + glx.ImportContextEXT = Fake_glXImportContextEXT; + glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT; + + /*** GLX_SGIX_fbconfig ***/ + glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX; + glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX; + glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX; + glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX; + glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX; + glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX; + + /*** GLX_SGIX_pbuffer ***/ + glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX; + glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX; + glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX; + glx.SelectEventSGIX = Fake_glXSelectEventSGIX; + glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX; + + /*** GLX_SGI_cushion ***/ + glx.CushionSGI = Fake_glXCushionSGI; + + /*** GLX_SGIX_video_resize ***/ + glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX; + glx.ChannelRectSGIX = Fake_glXChannelRectSGIX; + glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX; + glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX; + glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX; + + /*** GLX_SGIX_dmbuffer **/ +#if defined(_DM_BUFFER_H_) + glx.AssociateDMPbufferSGIX = NULL; +#endif + + /*** GLX_SGIX_swap_group ***/ + glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX; + + /*** GLX_SGIX_swap_barrier ***/ + glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX; + glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX; + + /*** GLX_SUN_get_transparent_index ***/ + glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN; + + /*** GLX_MESA_copy_sub_buffer ***/ + glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA; + + /*** GLX_MESA_release_buffers ***/ + glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA; + + /*** GLX_MESA_pixmap_colormap ***/ + glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA; + + /*** GLX_MESA_set_3dfx_mode ***/ + glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA; + + /*** GLX_NV_vertex_array_range ***/ + glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV; + glx.FreeMemoryNV = Fake_glXFreeMemoryNV; + + /*** GLX_MESA_agp_offset ***/ + glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; + + return &glx; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/glxapi.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/glxapi.c new file mode 100644 index 000000000..69af99730 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/glxapi.c @@ -0,0 +1,1348 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 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. + */ + + +/* + * This is the GLX API dispatcher. Calls to the glX* functions are + * either routed to the real GLX encoders or to Mesa's pseudo-GLX functions. + * See the glxapi.h file for more details. + */ + + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "glheader.h" +#include "glapi.h" +#include "glxapi.h" + + +extern struct _glxapi_table *_real_GetGLXDispatchTable(void); +extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); + + +struct display_dispatch { + Display *Dpy; + struct _glxapi_table *Table; + struct display_dispatch *Next; +}; + +static struct display_dispatch *DispatchList = NULL; + + +/* Display -> Dispatch caching */ +static Display *prevDisplay = NULL; +static struct _glxapi_table *prevTable = NULL; + + +static struct _glxapi_table * +get_dispatch(Display *dpy) +{ + if (!dpy) + return NULL; + + /* search list of display/dispatch pairs for this display */ + { + const struct display_dispatch *d = DispatchList; + while (d) { + if (d->Dpy == dpy) { + prevDisplay = dpy; + prevTable = d->Table; + return d->Table; /* done! */ + } + d = d->Next; + } + } + + /* A new display, determine if we should use real GLX + * or Mesa's pseudo-GLX. + */ + { + struct _glxapi_table *t = _mesa_GetGLXDispatchTable(); + + if (t) { + struct display_dispatch *d; + d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch)); + if (d) { + d->Dpy = dpy; + d->Table = t; + /* insert at head of list */ + d->Next = DispatchList; + DispatchList = d; + /* update cache */ + prevDisplay = dpy; + prevTable = t; + return t; + } + } + } + + /* If we get here that means we can't use real GLX on this display + * and the Mesa pseudo-GLX software renderer wasn't compiled in. + * Or, we ran out of memory! + */ + return NULL; +} + + +#define GET_DISPATCH(DPY, TABLE) \ + if (DPY == prevDisplay) { \ + TABLE = prevTable; \ + } \ + else if (!DPY) { \ + TABLE = NULL; \ + } \ + else { \ + TABLE = get_dispatch(DPY); \ + } + + + + +/* Set by glXMakeCurrent() and glXMakeContextCurrent() only */ +static GLXContext CurrentContext = 0; +#define __glXGetCurrentContext() CurrentContext; + + +/* + * GLX API entrypoints + */ + +/*** GLX_VERSION_1_0 ***/ + +XVisualInfo PUBLIC * +glXChooseVisual(Display *dpy, int screen, int *list) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->ChooseVisual)(dpy, screen, list); +} + + +void PUBLIC +glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->CopyContext)(dpy, src, dst, mask); +} + + +GLXContext PUBLIC +glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateContext)(dpy, visinfo, shareList, direct); +} + + +GLXPixmap PUBLIC +glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPixmap)(dpy, visinfo, pixmap); +} + + +void PUBLIC +glXDestroyContext(Display *dpy, GLXContext ctx) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyContext)(dpy, ctx); +} + + +void PUBLIC +glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyGLXPixmap)(dpy, pixmap); +} + + +int PUBLIC +glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return GLX_NO_EXTENSION; + return (t->GetConfig)(dpy, visinfo, attrib, value); +} + + +GLXContext PUBLIC +glXGetCurrentContext(void) +{ + return CurrentContext; +} + + +GLXDrawable PUBLIC +glXGetCurrentDrawable(void) +{ + __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); + return gc ? gc->currentDrawable : 0; +} + + +Bool PUBLIC +glXIsDirect(Display *dpy, GLXContext ctx) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->IsDirect)(dpy, ctx); +} + + +Bool PUBLIC +glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) +{ + Bool b; + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) { + return False; + } + b = (*t->MakeCurrent)(dpy, drawable, ctx); + if (b) { + CurrentContext = ctx; + } + return b; +} + + +Bool PUBLIC +glXQueryExtension(Display *dpy, int *errorb, int *event) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->QueryExtension)(dpy, errorb, event); +} + + +Bool PUBLIC +glXQueryVersion(Display *dpy, int *maj, int *min) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->QueryVersion)(dpy, maj, min); +} + + +void PUBLIC +glXSwapBuffers(Display *dpy, GLXDrawable drawable) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->SwapBuffers)(dpy, drawable); +} + + +void PUBLIC +glXUseXFont(Font font, int first, int count, int listBase) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->UseXFont)(font, first, count, listBase); +} + + +void PUBLIC +glXWaitGL(void) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->WaitGL)(); +} + + +void PUBLIC +glXWaitX(void) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->WaitX)(); +} + + + +/*** GLX_VERSION_1_1 ***/ + +const char PUBLIC * +glXGetClientString(Display *dpy, int name) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->GetClientString)(dpy, name); +} + + +const char PUBLIC * +glXQueryExtensionsString(Display *dpy, int screen) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->QueryExtensionsString)(dpy, screen); +} + + +const char PUBLIC * +glXQueryServerString(Display *dpy, int screen, int name) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->QueryServerString)(dpy, screen, name); +} + + +/*** GLX_VERSION_1_2 ***/ + +Display PUBLIC * +glXGetCurrentDisplay(void) +{ + /* Same code as in libGL's glxext.c */ + __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); + if (NULL == gc) return NULL; + return gc->currentDpy; +} + + + +/*** GLX_VERSION_1_3 ***/ + +GLXFBConfig PUBLIC * +glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChooseFBConfig)(dpy, screen, attribList, nitems); +} + + +GLXContext PUBLIC +glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateNewContext)(dpy, config, renderType, shareList, direct); +} + + +GLXPbuffer PUBLIC +glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreatePbuffer)(dpy, config, attribList); +} + + +GLXPixmap PUBLIC +glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreatePixmap)(dpy, config, pixmap, attribList); +} + + +GLXWindow PUBLIC +glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateWindow)(dpy, config, win, attribList); +} + + +void PUBLIC +glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyPbuffer)(dpy, pbuf); +} + + +void PUBLIC +glXDestroyPixmap(Display *dpy, GLXPixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyPixmap)(dpy, pixmap); +} + + +void PUBLIC +glXDestroyWindow(Display *dpy, GLXWindow window) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyWindow)(dpy, window); +} + + +GLXDrawable PUBLIC +glXGetCurrentReadDrawable(void) +{ + __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); + return gc ? gc->currentReadable : 0; +} + + +int PUBLIC +glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return GLX_NO_EXTENSION; + return (t->GetFBConfigAttrib)(dpy, config, attribute, value); +} + + +GLXFBConfig PUBLIC * +glXGetFBConfigs(Display *dpy, int screen, int *nelements) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetFBConfigs)(dpy, screen, nelements); +} + +void PUBLIC +glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->GetSelectedEvent)(dpy, drawable, mask); +} + + +XVisualInfo PUBLIC * +glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->GetVisualFromFBConfig)(dpy, config); +} + + +Bool PUBLIC +glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + Bool b; + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + b = (t->MakeContextCurrent)(dpy, draw, read, ctx); + if (b) { + CurrentContext = ctx; + } + return b; +} + + +int PUBLIC +glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + assert(t); + if (!t) + return 0; /* XXX correct? */ + return (t->QueryContext)(dpy, ctx, attribute, value); +} + + +void PUBLIC +glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->QueryDrawable)(dpy, draw, attribute, value); +} + + +void PUBLIC +glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->SelectEvent)(dpy, drawable, mask); +} + + + +/*** GLX_SGI_swap_control ***/ + +int PUBLIC +glXSwapIntervalSGI(int interval) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->SwapIntervalSGI)(interval); +} + + + +/*** GLX_SGI_video_sync ***/ + +int PUBLIC +glXGetVideoSyncSGI(unsigned int *count) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetVideoSyncSGI)(count); +} + +int PUBLIC +glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->WaitVideoSyncSGI)(divisor, remainder, count); +} + + + +/*** GLX_SGI_make_current_read ***/ + +Bool PUBLIC +glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx); +} + +GLXDrawable PUBLIC +glXGetCurrentReadDrawableSGI(void) +{ + return glXGetCurrentReadDrawable(); +} + + +#if defined(_VL_H) + +GLXVideoSourceSGIX PUBLIC +glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode); +} + +void PUBLIC +glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->DestroyGLXVideoSourceSGIX)(dpy, src); +} + +#endif + + +/*** GLX_EXT_import_context ***/ + +void PUBLIC +glXFreeContextEXT(Display *dpy, GLXContext context) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->FreeContextEXT)(dpy, context); +} + +GLXContextID PUBLIC +glXGetContextIDEXT(const GLXContext context) +{ + return ((__GLXcontext *) context)->xid; +} + +Display PUBLIC * +glXGetCurrentDisplayEXT(void) +{ + return glXGetCurrentDisplay(); +} + +GLXContext PUBLIC +glXImportContextEXT(Display *dpy, GLXContextID contextID) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ImportContextEXT)(dpy, contextID); +} + +int PUBLIC +glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; /* XXX ok? */ + return (t->QueryContextInfoEXT)(dpy, context, attribute, value); +} + + + +/*** GLX_SGIX_fbconfig ***/ + +int PUBLIC +glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value); +} + +GLXFBConfigSGIX PUBLIC * +glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements); +} + +GLXPixmap PUBLIC +glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap); +} + +GLXContext PUBLIC +glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct); +} + +XVisualInfo PUBLIC * +glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetVisualFromFBConfigSGIX)(dpy, config); +} + +GLXFBConfigSGIX PUBLIC +glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetFBConfigFromVisualSGIX)(dpy, vis); +} + + + +/*** GLX_SGIX_pbuffer ***/ + +GLXPbufferSGIX PUBLIC +glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list); +} + +void PUBLIC +glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyGLXPbufferSGIX)(dpy, pbuf); +} + +int PUBLIC +glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value); +} + +void PUBLIC +glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->SelectEventSGIX)(dpy, drawable, mask); +} + +void PUBLIC +glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->GetSelectedEventSGIX)(dpy, drawable, mask); +} + + + +/*** GLX_SGI_cushion ***/ + +void PUBLIC +glXCushionSGI(Display *dpy, Window win, float cushion) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->CushionSGI)(dpy, win, cushion); +} + + + +/*** GLX_SGIX_video_resize ***/ + +int PUBLIC +glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window); +} + +int PUBLIC +glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h); +} + +int PUBLIC +glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h); +} + +int PUBLIC +glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh); +} + +int PUBLIC +glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype); +} + + + +#if defined(_DM_BUFFER_H_) + +Bool PUBLIC +glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer); +} + +#endif + + +/*** GLX_SGIX_swap_group ***/ + +void PUBLIC +glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (*t->JoinSwapGroupSGIX)(dpy, drawable, member); +} + + +/*** GLX_SGIX_swap_barrier ***/ + +void PUBLIC +glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier); +} + +Bool PUBLIC +glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max); +} + + + +/*** GLX_SUN_get_transparent_index ***/ + +Status PUBLIC +glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent); +} + + + +/*** GLX_MESA_copy_sub_buffer ***/ + +void PUBLIC +glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height); +} + + + +/*** GLX_MESA_release_buffers ***/ + +Bool PUBLIC +glXReleaseBuffersMESA(Display *dpy, Window w) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->ReleaseBuffersMESA)(dpy, w); +} + + + +/*** GLX_MESA_pixmap_colormap ***/ + +GLXPixmap PUBLIC +glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap); +} + + + +/*** GLX_MESA_set_3dfx_mode ***/ + +Bool PUBLIC +glXSet3DfxModeMESA(int mode) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->Set3DfxModeMESA)(mode); +} + + + +/*** GLX_NV_vertex_array_range ***/ + +void PUBLIC * +glXAllocateMemoryNV( GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority ) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->AllocateMemoryNV)(size, readFrequency, writeFrequency, priority); +} + + +void PUBLIC +glXFreeMemoryNV( GLvoid *pointer ) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->FreeMemoryNV)(pointer); +} + + + + +/*** GLX_MESA_agp_offset */ + +GLuint PUBLIC +glXGetAGPOffsetMESA( const GLvoid *pointer ) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return ~0; + return (t->GetAGPOffsetMESA)(pointer); +} + + +/*** GLX_MESA_allocate_memory */ + +void * +glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, + float readfreq, float writefreq, float priority) +{ + /* dummy */ + return NULL; +} + +void +glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) +{ + /* dummy */ +} + + +GLuint +glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer) +{ + /* dummy */ + return 0; +} + + + +/**********************************************************************/ +/* GLX API management functions */ +/**********************************************************************/ + + +const char * +_glxapi_get_version(void) +{ + return "1.3"; +} + + +/* + * Return array of extension strings. + */ +const char ** +_glxapi_get_extensions(void) +{ + static const char *extensions[] = { +#ifdef GLX_EXT_import_context + "GLX_EXT_import_context", +#endif +#ifdef GLX_SGI_video_sync + "GLX_SGI_video_sync", +#endif +#ifdef GLX_MESA_copy_sub_buffer + "GLX_MESA_copy_sub_buffer", +#endif +#ifdef GLX_MESA_release_buffers + "GLX_MESA_release_buffers", +#endif +#ifdef GLX_MESA_pixmap_colormap + "GLX_MESA_pixmap_colormap", +#endif +#ifdef GLX_MESA_set_3dfx_mode + "GLX_MESA_set_3dfx_mode", +#endif +#ifdef GLX_SGIX_fbconfig + "GLX_SGIX_fbconfig", +#endif +#ifdef GLX_SGIX_pbuffer + "GLX_SGIX_pbuffer", +#endif + NULL + }; + return extensions; +} + + +/* + * Return size of the GLX dispatch table, in entries, not bytes. + */ +GLuint +_glxapi_get_dispatch_table_size(void) +{ + return sizeof(struct _glxapi_table) / sizeof(void *); +} + + +static int +generic_no_op_func(void) +{ + return 0; +} + + +/* + * Initialize all functions in given dispatch table to be no-ops + */ +void +_glxapi_set_no_op_table(struct _glxapi_table *t) +{ + typedef int (*nop_func)(void); + nop_func *dispatch = (nop_func *) t; + GLuint n = _glxapi_get_dispatch_table_size(); + GLuint i; + for (i = 0; i < n; i++) { + dispatch[i] = generic_no_op_func; + } +} + + +struct name_address_pair { + const char *Name; + __GLXextFuncPtr Address; +}; + +static struct name_address_pair GLX_functions[] = { + /*** GLX_VERSION_1_0 ***/ + { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual }, + { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext }, + { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext }, + { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap }, + { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext }, + { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap }, + { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig }, + { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext }, + { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable }, + { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect }, + { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent }, + { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension }, + { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion }, + { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers }, + { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont }, + { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL }, + { "glXWaitX", (__GLXextFuncPtr) glXWaitX }, + + /*** GLX_VERSION_1_1 ***/ + { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString }, + { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString }, + { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString }, + + /*** GLX_VERSION_1_2 ***/ + { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay }, + + /*** GLX_VERSION_1_3 ***/ + { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig }, + { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext }, + { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer }, + { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap }, + { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow }, + { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer }, + { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap }, + { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow }, + { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable }, + { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib }, + { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs }, + { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent }, + { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig }, + { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent }, + { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext }, + { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable }, + { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent }, + + /*** GLX_VERSION_1_4 ***/ + { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress }, + + /*** GLX_SGI_swap_control ***/ + { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI }, + + /*** GLX_SGI_video_sync ***/ + { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI }, + { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI }, + + /*** GLX_SGI_make_current_read ***/ + { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI }, + { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI }, + + /*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX }, + { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX }, +#endif + + /*** GLX_EXT_import_context ***/ + { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT }, + { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT }, + { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT }, + { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT }, + { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT }, + + /*** GLX_SGIX_fbconfig ***/ + { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX }, + { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX }, + { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX }, + { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX }, + { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX }, + { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX }, + + /*** GLX_SGIX_pbuffer ***/ + { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX }, + { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX }, + { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX }, + { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX }, + { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX }, + + /*** GLX_SGI_cushion ***/ + { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI }, + + /*** GLX_SGIX_video_resize ***/ + { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX }, + { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX }, + { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX }, + { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX }, + { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX }, + + /*** GLX_SGIX_dmbuffer **/ +#if defined(_DM_BUFFER_H_) + { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX }, +#endif + + /*** GLX_SGIX_swap_group ***/ + { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX }, + + /*** GLX_SGIX_swap_barrier ***/ + { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX }, + { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX }, + + /*** GLX_SUN_get_transparent_index ***/ + { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN }, + + /*** GLX_MESA_copy_sub_buffer ***/ + { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA }, + + /*** GLX_MESA_pixmap_colormap ***/ + { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA }, + + /*** GLX_MESA_release_buffers ***/ + { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA }, + + /*** GLX_MESA_set_3dfx_mode ***/ + { "glXSet3DfxModeMESA", (__GLXextFuncPtr) glXSet3DfxModeMESA }, + + /*** GLX_ARB_get_proc_address ***/ + { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB }, + + /*** GLX_NV_vertex_array_range ***/ + { "glXAllocateMemoryNV", (__GLXextFuncPtr) glXAllocateMemoryNV }, + { "glXFreeMemoryNV", (__GLXextFuncPtr) glXFreeMemoryNV }, + + /*** GLX_MESA_agp_offset ***/ + { "glXGetAGPOffsetMESA", (__GLXextFuncPtr) glXGetAGPOffsetMESA }, + + /*** GLX_MESA_allocate_memory ***/ + { "glXAllocateMemoryMESA", (__GLXextFuncPtr) glXAllocateMemoryMESA }, + { "glXFreeMemoryMESA", (__GLXextFuncPtr) glXFreeMemoryMESA }, + { "glXGetMemoryOffsetMESA", (__GLXextFuncPtr) glXGetMemoryOffsetMESA }, + + { NULL, NULL } /* end of list */ +}; + + + +/* + * Return address of named glX function, or NULL if not found. + */ +__GLXextFuncPtr +_glxapi_get_proc_address(const char *funcName) +{ + GLuint i; + for (i = 0; GLX_functions[i].Name; i++) { + if (strcmp(GLX_functions[i].Name, funcName) == 0) + return GLX_functions[i].Address; + } + return NULL; +} + + + +/* + * This function does not get dispatched through the dispatch table + * since it's really a "meta" function. + */ +__GLXextFuncPtr +glXGetProcAddressARB(const GLubyte *procName) +{ + __GLXextFuncPtr f; + + f = _glxapi_get_proc_address((const char *) procName); + if (f) { + return f; + } + + f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName); + return f; +} + + +/* GLX 1.4 */ +void (*glXGetProcAddress(const GLubyte *procName))() +{ + return glXGetProcAddressARB(procName); +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/glxapi.h b/nx-X11/extras/Mesa/src/mesa/drivers/x11/glxapi.h new file mode 100644 index 000000000..3187534c9 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/glxapi.h @@ -0,0 +1,223 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 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 _glxapi_h_ +#define _glxapi_h_ + + +#define GLX_GLXEXT_PROTOTYPES +#include "GL/glx.h" + + +/* The GLX API dispatcher (i.e. this code) is being built into stand-alone + * Mesa. We don't know anything about XFree86 or real GLX so we define a + * minimal __GLXContextRec here so some of the functions in this file can + * work properly. + */ +typedef struct __GLXcontextRec { + Display *currentDpy; + GLboolean isDirect; + GLXDrawable currentDrawable; + GLXDrawable currentReadable; + XID xid; +} __GLXcontext; + + +/* + * Almost all the GLX API functions get routed through this dispatch table. + * The exceptions are the glXGetCurrentXXX() functions. + * + * This dispatch table allows multiple GLX client-side modules to coexist. + * Specifically, a real GLX library (like SGI's or the Utah GLX) and Mesa's + * pseudo-GLX can be present at the same time. The former being used on + * GLX-enabled X servers and the later on non-GLX X servers. + * + * Red Hat has been using this since Red Hat Linux 7.0 (I think). + * This'll be a standard feature in XFree86 4.3. It basically allows one + * libGL to do both DRI-rendering and "fake GLX" rendering to X displays + * that lack the GLX extension. + */ +struct _glxapi_table { + /*** GLX_VERSION_1_0 ***/ + XVisualInfo *(*ChooseVisual)(Display *dpy, int screen, int *list); + void (*CopyContext)(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask); + GLXContext (*CreateContext)(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct); + GLXPixmap (*CreateGLXPixmap)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap); + void (*DestroyContext)(Display *dpy, GLXContext ctx); + void (*DestroyGLXPixmap)(Display *dpy, GLXPixmap pixmap); + int (*GetConfig)(Display *dpy, XVisualInfo *visinfo, int attrib, int *value); + /*GLXContext (*GetCurrentContext)(void);*/ + /*GLXDrawable (*GetCurrentDrawable)(void);*/ + Bool (*IsDirect)(Display *dpy, GLXContext ctx); + Bool (*MakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx); + Bool (*QueryExtension)(Display *dpy, int *errorb, int *event); + Bool (*QueryVersion)(Display *dpy, int *maj, int *min); + void (*SwapBuffers)(Display *dpy, GLXDrawable drawable); + void (*UseXFont)(Font font, int first, int count, int listBase); + void (*WaitGL)(void); + void (*WaitX)(void); + + /*** GLX_VERSION_1_1 ***/ + const char *(*GetClientString)(Display *dpy, int name); + const char *(*QueryExtensionsString)(Display *dpy, int screen); + const char *(*QueryServerString)(Display *dpy, int screen, int name); + + /*** GLX_VERSION_1_2 ***/ + /*Display *(*GetCurrentDisplay)(void);*/ + + /*** GLX_VERSION_1_3 ***/ + GLXFBConfig *(*ChooseFBConfig)(Display *dpy, int screen, const int *attribList, int *nitems); + GLXContext (*CreateNewContext)(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct); + GLXPbuffer (*CreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attribList); + GLXPixmap (*CreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList); + GLXWindow (*CreateWindow)(Display *dpy, GLXFBConfig config, Window win, const int *attribList); + void (*DestroyPbuffer)(Display *dpy, GLXPbuffer pbuf); + void (*DestroyPixmap)(Display *dpy, GLXPixmap pixmap); + void (*DestroyWindow)(Display *dpy, GLXWindow window); + /*GLXDrawable (*GetCurrentReadDrawable)(void);*/ + int (*GetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value); + GLXFBConfig *(*GetFBConfigs)(Display *dpy, int screen, int *nelements); + void (*GetSelectedEvent)(Display *dpy, GLXDrawable drawable, unsigned long *mask); + XVisualInfo *(*GetVisualFromFBConfig)(Display *dpy, GLXFBConfig config); + Bool (*MakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + int (*QueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value); + void (*QueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); + void (*SelectEvent)(Display *dpy, GLXDrawable drawable, unsigned long mask); + + /*** GLX_SGI_swap_control ***/ + int (*SwapIntervalSGI)(int); + + /*** GLX_SGI_video_sync ***/ + int (*GetVideoSyncSGI)(unsigned int *count); + int (*WaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count); + + /*** GLX_SGI_make_current_read ***/ + Bool (*MakeCurrentReadSGI)(Display *, GLXDrawable, GLXDrawable, GLXContext); + /*GLXDrawable (*GetCurrentReadDrawableSGI)(void);*/ + + /*** GLX_SGIX_video_source (needs video library) ***/ +#if defined(_VL_H_) + GLXVideoSourceSGIX (*CreateGLXVideoSourceSGIX)(Display *, int, VLServer, VLPath, int, VLNode); + void (*DestroyGLXVideoSourceSGIX)(Display *, GLXVideoSourceSGIX); +#else + void *CreateGLXVideoSourceSGIX; + void *DestroyGLXVideoSourceSGIX; +#endif + + /*** GLX_EXT_import_context ***/ + void (*FreeContextEXT)(Display *dpy, GLXContext context); + GLXContextID (*GetContextIDEXT)(const GLXContext context); + /*Display *(*GetCurrentDisplayEXT)(void);*/ + GLXContext (*ImportContextEXT)(Display *dpy, GLXContextID contextID); + int (*QueryContextInfoEXT)(Display *dpy, GLXContext context, int attribute,int *value); + + /*** GLX_SGIX_fbconfig ***/ + int (*GetFBConfigAttribSGIX)(Display *, GLXFBConfigSGIX, int, int *); + GLXFBConfigSGIX * (*ChooseFBConfigSGIX)(Display *, int, int *, int *); + GLXPixmap (*CreateGLXPixmapWithConfigSGIX)(Display *, GLXFBConfigSGIX, Pixmap); + GLXContext (*CreateContextWithConfigSGIX)(Display *, GLXFBConfigSGIX, int, GLXContext, Bool); + XVisualInfo * (*GetVisualFromFBConfigSGIX)(Display *, GLXFBConfigSGIX); + GLXFBConfigSGIX (*GetFBConfigFromVisualSGIX)(Display *, XVisualInfo *); + + /*** GLX_SGIX_pbuffer ***/ + GLXPbufferSGIX (*CreateGLXPbufferSGIX)(Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *); + void (*DestroyGLXPbufferSGIX)(Display *, GLXPbufferSGIX); + int (*QueryGLXPbufferSGIX)(Display *, GLXPbufferSGIX, int, unsigned int *); + void (*SelectEventSGIX)(Display *, GLXDrawable, unsigned long); + void (*GetSelectedEventSGIX)(Display *, GLXDrawable, unsigned long *); + + /*** GLX_SGI_cushion ***/ + void (*CushionSGI)(Display *, Window, float); + + /*** GLX_SGIX_video_resize ***/ + int (*BindChannelToWindowSGIX)(Display *, int, int, Window); + int (*ChannelRectSGIX)(Display *, int, int, int, int, int, int); + int (*QueryChannelRectSGIX)(Display *, int, int, int *, int *, int *, int *); + int (*QueryChannelDeltasSGIX)(Display *, int, int, int *, int *, int *, int *); + int (*ChannelRectSyncSGIX)(Display *, int, int, GLenum); + + /*** GLX_SGIX_dmbuffer (needs dmedia library) ***/ +#if defined (_DM_BUFFER_H_) + Bool (*AssociateDMPbufferSGIX)(Display *, GLXPbufferSGIX, DMparams *, DMbuffer); +#else + void *AssociciateDMPbufferSGIX; +#endif + + /*** GLX_SGIX_swap_group ***/ + void (*JoinSwapGroupSGIX)(Display *, GLXDrawable, GLXDrawable); + + /*** GLX_SGIX_swap_barrier ***/ + void (*BindSwapBarrierSGIX)(Display *, GLXDrawable, int); + Bool (*QueryMaxSwapBarriersSGIX)(Display *, int, int *); + + /*** GLX_SUN_get_transparent_index ***/ + Status (*GetTransparentIndexSUN)(Display *, Window, Window, long *); + + /*** GLX_MESA_copy_sub_buffer ***/ + void (*CopySubBufferMESA)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); + + /*** GLX_MESA_release_buffers ***/ + Bool (*ReleaseBuffersMESA)(Display *dpy, Window w); + + /*** GLX_MESA_pixmap_colormap ***/ + GLXPixmap (*CreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap); + + /*** GLX_MESA_set_3dfx_mode ***/ + Bool (*Set3DfxModeMESA)(int mode); + + /*** GLX_NV_vertex_array_range ***/ + void * (*AllocateMemoryNV)( GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority ); + void (*FreeMemoryNV)( GLvoid *pointer ); + + /*** GLX_MESA_agp_offset ***/ + GLuint (*GetAGPOffsetMESA)( const GLvoid *pointer ); +}; + + + +extern const char * +_glxapi_get_version(void); + + +extern const char ** +_glxapi_get_extensions(void); + + +extern GLuint +_glxapi_get_dispatch_table_size(void); + + +extern void +_glxapi_set_no_op_table(struct _glxapi_table *t); + + +extern __GLXextFuncPtr +_glxapi_get_proc_address(const char *funcName); + + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/glxheader.h b/nx-X11/extras/Mesa/src/mesa/drivers/x11/glxheader.h new file mode 100644 index 000000000..2533d5044 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/glxheader.h @@ -0,0 +1,64 @@ + +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * Copyright (C) 1999-2002 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 GLX_HEADER_H +#define GLX_HEADER_H + +#ifdef __VMS +#include <GL/vms_x_fix.h> +#endif + +#include "glheader.h" + +#ifdef XFree86Server + +# include "resource.h" +# include "windowstr.h" +# include "gcstruct.h" +# include "GL/xf86glx.h" +# include "xf86glx_util.h" + +#else + +# include <X11/Xlib.h> +# include <X11/Xutil.h> +# ifdef USE_XSHM /* was SHM */ +# include <sys/ipc.h> +# include <sys/shm.h> +# include <X11/extensions/XShm.h> +# endif +# include <GL/glx.h> + +#endif + + + +/* this silences a compiler warning on several systems */ +struct timespec; +struct itimerspec; + + +#endif /*GLX_HEADER*/ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/realglx.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/realglx.c new file mode 100644 index 000000000..30adb7465 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/realglx.c @@ -0,0 +1,180 @@ + +/* + * Mesa 3-D graphics library + * Version: 5.1 + * + * Copyright (C) 1999-2002 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. + */ + + +#include <assert.h> +#include <GL/glx.h> +#include "realglx.h" +#include "glxapi.h" + + +struct _glxapi_table * +_real_GetGLXDispatchTable(void) +{ + static struct _glxapi_table glx; + + /* be sure our dispatch table size <= libGL's table */ + { + GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); + (void) size; + assert(_glxapi_get_dispatch_table_size() >= size); + } + + /* initialize the whole table to no-ops */ + _glxapi_set_no_op_table(&glx); + + /* now initialize the table with the functions I implement */ + + /*** GLX_VERSION_1_0 ***/ + glx.ChooseVisual = _real_glXChooseVisual; + glx.CopyContext = _real_glXCopyContext; + glx.CreateContext = _real_glXCreateContext; + glx.CreateGLXPixmap = _real_glXCreateGLXPixmap; + glx.DestroyContext = _real_glXDestroyContext; + glx.DestroyGLXPixmap = _real_glXDestroyGLXPixmap; + glx.GetConfig = _real_glXGetConfig; + /*glx.GetCurrentContext = _real_glXGetCurrentContext;*/ + /*glx.GetCurrentDrawable = _real_glXGetCurrentDrawable;*/ + glx.IsDirect = _real_glXIsDirect; + glx.MakeCurrent = _real_glXMakeCurrent; + glx.QueryExtension = _real_glXQueryExtension; + glx.QueryVersion = _real_glXQueryVersion; + glx.SwapBuffers = _real_glXSwapBuffers; + glx.UseXFont = _real_glXUseXFont; + glx.WaitGL = _real_glXWaitGL; + glx.WaitX = _real_glXWaitX; + + /*** GLX_VERSION_1_1 ***/ + glx.GetClientString = _real_glXGetClientString; + glx.QueryExtensionsString = _real_glXQueryExtensionsString; + glx.QueryServerString = _real_glXQueryServerString; + + /*** GLX_VERSION_1_2 ***/ + /*glx.GetCurrentDisplay = _real_glXGetCurrentDisplay;*/ + + /*** GLX_VERSION_1_3 ***/ + glx.ChooseFBConfig = _real_glXChooseFBConfig; + glx.CreateNewContext = _real_glXCreateNewContext; + glx.CreatePbuffer = _real_glXCreatePbuffer; + glx.CreatePixmap = _real_glXCreatePixmap; + glx.CreateWindow = _real_glXCreateWindow; + glx.DestroyPbuffer = _real_glXDestroyPbuffer; + glx.DestroyPixmap = _real_glXDestroyPixmap; + glx.DestroyWindow = _real_glXDestroyWindow; + /*glx.GetCurrentReadDrawable = _real_glXGetCurrentReadDrawable;*/ + glx.GetFBConfigAttrib = _real_glXGetFBConfigAttrib; + glx.GetFBConfigs = _real_glXGetFBConfigs; + glx.GetSelectedEvent = _real_glXGetSelectedEvent; + glx.GetVisualFromFBConfig = _real_glXGetVisualFromFBConfig; + glx.MakeContextCurrent = _real_glXMakeContextCurrent; + glx.QueryContext = _real_glXQueryContext; + glx.QueryDrawable = _real_glXQueryDrawable; + glx.SelectEvent = _real_glXSelectEvent; + + /*** GLX_SGI_swap_control ***/ + glx.SwapIntervalSGI = _real_glXSwapIntervalSGI; + + /*** GLX_SGI_video_sync ***/ + glx.GetVideoSyncSGI = _real_glXGetVideoSyncSGI; + glx.WaitVideoSyncSGI = _real_glXWaitVideoSyncSGI; + + /*** GLX_SGI_make_current_read ***/ + glx.MakeCurrentReadSGI = _real_glXMakeCurrentReadSGI; + /*glx.GetCurrentReadDrawableSGI = _real_glXGetCurrentReadDrawableSGI;*/ + +#if defined(_VL_H) + /*** GLX_SGIX_video_source ***/ + glx.CreateGLXVideoSourceSGIX = _real_glXCreateGLXVideoSourceSGIX; + glx.DestroyGLXVideoSourceSGIX = _real_glXDestroyGLXVideoSourceSGIX; +#endif + + /*** GLX_EXT_import_context ***/ + glx.FreeContextEXT = _real_glXFreeContextEXT; + /*glx.GetContextIDEXT = _real_glXGetContextIDEXT;*/ + /*glx.GetCurrentDisplayEXT = _real_glXGetCurrentDisplayEXT;*/ + glx.ImportContextEXT = _real_glXImportContextEXT; + glx.QueryContextInfoEXT = _real_glXQueryContextInfoEXT; + + /*** GLX_SGIX_fbconfig ***/ + glx.GetFBConfigAttribSGIX = _real_glXGetFBConfigAttribSGIX; + glx.ChooseFBConfigSGIX = _real_glXChooseFBConfigSGIX; + glx.CreateGLXPixmapWithConfigSGIX = _real_glXCreateGLXPixmapWithConfigSGIX; + glx.CreateContextWithConfigSGIX = _real_glXCreateContextWithConfigSGIX; + glx.GetVisualFromFBConfigSGIX = _real_glXGetVisualFromFBConfigSGIX; + glx.GetFBConfigFromVisualSGIX = _real_glXGetFBConfigFromVisualSGIX; + + /*** GLX_SGIX_pbuffer ***/ + glx.CreateGLXPbufferSGIX = _real_glXCreateGLXPbufferSGIX; + glx.DestroyGLXPbufferSGIX = _real_glXDestroyGLXPbufferSGIX; + glx.QueryGLXPbufferSGIX = _real_glXQueryGLXPbufferSGIX; + glx.SelectEventSGIX = _real_glXSelectEventSGIX; + glx.GetSelectedEventSGIX = _real_glXGetSelectedEventSGIX; + + /*** GLX_SGI_cushion ***/ + glx.CushionSGI = _real_glXCushionSGI; + + /*** GLX_SGIX_video_resize ***/ + glx.BindChannelToWindowSGIX = _real_glXBindChannelToWindowSGIX; + glx.ChannelRectSGIX = _real_glXChannelRectSGIX; + glx.QueryChannelRectSGIX = _real_glXQueryChannelRectSGIX; + glx.QueryChannelDeltasSGIX = _real_glXQueryChannelDeltasSGIX; + glx.ChannelRectSyncSGIX = _real_glXChannelRectSyncSGIX; + +#if defined(_DM_BUFFER_H_) + /*** (GLX_SGIX_dmbuffer ***/ + glx.AssociateDMPbufferSGIX = NULL; +#endif + + /*** GLX_SGIX_swap_group ***/ + glx.JoinSwapGroupSGIX = _real_glXJoinSwapGroupSGIX; + + /*** GLX_SGIX_swap_barrier ***/ + glx.BindSwapBarrierSGIX = _real_glXBindSwapBarrierSGIX; + glx.QueryMaxSwapBarriersSGIX = _real_glXQueryMaxSwapBarriersSGIX; + + /*** GLX_SUN_get_transparent_index ***/ + glx.GetTransparentIndexSUN = _real_glXGetTransparentIndexSUN; + + /*** GLX_MESA_copy_sub_buffer ***/ + glx.CopySubBufferMESA = _real_glXCopySubBufferMESA; + + /*** GLX_MESA_release_buffers ***/ + glx.ReleaseBuffersMESA = _real_glXReleaseBuffersMESA; + + /*** GLX_MESA_pixmap_colormap ***/ + glx.CreateGLXPixmapMESA = _real_glXCreateGLXPixmapMESA; + + /*** GLX_MESA_set_3dfx_mode ***/ + glx.Set3DfxModeMESA = _real_glXSet3DfxModeMESA; + + /*** GLX_NV_vertex_array_range ***/ + glx.AllocateMemoryNV = _real_glXAllocateMemoryNV; + glx.FreeMemoryNV = _real_glXFreeMemoryNV; + + /*** GLX_MESA_agp_offset ***/ + glx.GetAGPOffsetMESA = _real_glXGetAGPOffsetMESA; + + return &glx; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/realglx.h b/nx-X11/extras/Mesa/src/mesa/drivers/x11/realglx.h new file mode 100644 index 000000000..150129db6 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/realglx.h @@ -0,0 +1,326 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 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 + + +extern struct _glxapi_table * +_real_GetGLXDispatchTable(void); + + +/* + * Basically just need these to prevent compiler warnings. + */ + + +extern XVisualInfo * +_real_glXChooseVisual( Display *dpy, int screen, int *list ); + +extern GLXContext +_real_glXCreateContext( Display *dpy, XVisualInfo *visinfo, + GLXContext share_list, Bool direct ); + +extern GLXPixmap +_real_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ); + +extern GLXPixmap +_real_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, + Pixmap pixmap, Colormap cmap ); + +extern void +_real_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ); + +extern void +_real_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, + unsigned long mask ); + +extern Bool +_real_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ); + +extern Bool +_real_glXQueryExtension( Display *dpy, int *errorb, int *event ); + +extern void +_real_glXDestroyContext( Display *dpy, GLXContext ctx ); + +extern Bool +_real_glXIsDirect( Display *dpy, GLXContext ctx ); + +extern void +_real_glXSwapBuffers( Display *dpy, GLXDrawable drawable ); + +extern void +_real_glXUseXFont( Font font, int first, int count, int listbase ); + +extern Bool +_real_glXQueryVersion( Display *dpy, int *maj, int *min ); + +extern int +_real_glXGetConfig( Display *dpy, XVisualInfo *visinfo, + int attrib, int *value ); + +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 ); + + +/* + * GLX 1.3 and later + */ + +extern GLXFBConfig * +_real_glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ); + +extern int +_real_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, + int attribute, int *value ); + +extern GLXFBConfig * +_real_glXGetFBConfigs( Display *dpy, int screen, int *nelements ); + +extern XVisualInfo * +_real_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ); + +extern GLXWindow +_real_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, + const int *attribList ); + +extern void +_real_glXDestroyWindow( Display *dpy, GLXWindow window ); + +extern GLXPixmap +_real_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, + const int *attribList ); + +extern void +_real_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ); + +extern GLXPbuffer +_real_glXCreatePbuffer( Display *dpy, GLXFBConfig config, + const int *attribList ); + +extern void +_real_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ); + +extern void +_real_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, + unsigned int *value ); + +extern GLXContext +_real_glXCreateNewContext( Display *dpy, GLXFBConfig config, + int renderType, GLXContext shareList, Bool direct ); + + +extern Bool +_real_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, + GLXDrawable read, GLXContext ctx ); + +extern int +_real_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ); + +extern void +_real_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ); + +extern void +_real_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, + unsigned long *mask ); + +#ifdef GLX_SGI_swap_control +extern int +_real_glXSwapIntervalSGI(int interval); +#endif + + +#ifdef GLX_SGI_video_sync +extern int +_real_glXGetVideoSyncSGI(unsigned int *count); + +extern int +_real_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count); +#endif + + +#ifdef GLX_SGI_make_current_read +extern Bool +_real_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + +extern GLXDrawable +_real_glXGetCurrentReadDrawableSGI(void); +#endif + +#if defined(_VL_H) && defined(GLX_SGIX_video_source) +extern GLXVideoSourceSGIX +_real_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); + +extern void +_real_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src); +#endif + +#ifdef GLX_EXT_import_context +extern void +_real_glXFreeContextEXT(Display *dpy, GLXContext context); + +extern GLXContextID +_real_glXGetContextIDEXT(const GLXContext context); + +extern Display * +_real_glXGetCurrentDisplayEXT(void); + +extern GLXContext +_real_glXImportContextEXT(Display *dpy, GLXContextID contextID); + +extern int +_real_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value); +#endif + +#ifdef GLX_SGIX_fbconfig +extern int +_real_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); + +extern GLXFBConfigSGIX * +_real_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements); + +extern GLXPixmap +_real_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); + +extern GLXContext +_real_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); + +extern XVisualInfo * +_real_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config); + +extern GLXFBConfigSGIX +_real_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis); +#endif + +#ifdef GLX_SGIX_pbuffer +extern GLXPbufferSGIX +_real_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); + +extern void +_real_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf); + +extern int +_real_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); + +extern void +_real_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask); + +extern void +_real_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask); +#endif + +#ifdef GLX_SGI_cushion +extern void +_real_glXCushionSGI(Display *dpy, Window win, float cushion); +#endif + +#ifdef GLX_SGIX_video_resize +extern int +_real_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window); + +extern int +_real_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h); + +extern int +_real_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h); + +extern int +_real_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh); + +extern int +_real_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype); +#endif + +#if defined(_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer) +extern Bool +_real_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); +#endif + +#ifdef GLX_SGIX_swap_group +extern void +_real_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member); +#endif + +#ifdef GLX_SGIX_swap_barrier +extern void +_real_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier); + +extern Bool +_real_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max); +#endif + +#ifdef GLX_SUN_get_transparent_index +extern Status +_real_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent); +#endif + +#ifdef GLX_MESA_release_buffers +extern Bool +_real_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ); +#endif + +#ifdef GLX_MESA_set_3dfx_mode +extern Bool +_real_glXSet3DfxModeMESA( int mode ); +#endif + +#ifdef GLX_NV_vertex_array_range +extern void * +_real_glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +extern void +_real_glXFreeMemoryNV(GLvoid *pointer); +#endif + +#ifdef GLX_MESA_agp_offset +extern GLuint +_real_glXGetAGPOffsetMESA(const GLvoid *pointer); +#endif + +#ifdef GLX_MESA_copy_sub_buffer +extern void +_real_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, + int x, int y, int width, int height ); +#endif + +#endif /* REALGLX_H */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/xfonts.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xfonts.c new file mode 100644 index 000000000..d72c600bd --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xfonts.c @@ -0,0 +1,377 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 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 __VMS +#include <GL/vms_x_fix.h> +#endif + +#include "glxheader.h" +#include "context.h" +#include "imports.h" +#include "xfonts.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, unsigned int which) +{ + unsigned int rows, pages; + unsigned int byte1 = 0, byte2 = 0; + 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) +{ + 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; + + dpy = glXGetCurrentDisplay(); + if (!dpy) + return; /* I guess glXMakeCurrent wasn't called */ + win = RootWindow(dpy, DefaultScreen(dpy)); + + fs = XQueryFont(dpy, font); + if (!fs) { + _mesa_error(NULL, 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, 1); + _mesa_error(NULL, 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 - 0; /* XXX used to subtract 1 here */ + /* but that caused a conformace failure */ + 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, 1); + 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); +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/xfonts.h b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xfonts.h new file mode 100644 index 000000000..e36f42f81 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xfonts.h @@ -0,0 +1,41 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 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 XFONTS_H +#define XFONTS_H + +#ifdef __VMS +#include <GL/vms_x_fix.h> +#endif + +#include <X11/Xlib.h> + + +extern void Fake_glXUseXFont( Font font, int first, int count, int listbase ); + + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_api.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_api.c new file mode 100644 index 000000000..6ed2be564 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_api.c @@ -0,0 +1,2675 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 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. + */ + +/* + * This file contains the implementations of all the XMesa* functions. + * + * + * NOTES: + * + * The window coordinate system origin (0,0) is in the lower-left corner + * of the window. X11's window coordinate origin is in the upper-left + * corner of the window. Therefore, most drawing functions in this + * file have to flip Y coordinates. + * + * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile + * in support for the MIT Shared Memory extension. If enabled, when you + * use an Ximage for the back buffer in double buffered mode, the "swap" + * operation will be faster. You must also link with -lXext. + * + * Byte swapping: If the Mesa host and the X display use a different + * byte order then there's some trickiness to be aware of when using + * XImages. The byte ordering used for the XImage is that of the X + * display, not the Mesa host. + * The color-to-pixel encoding for True/DirectColor must be done + * according to the display's visual red_mask, green_mask, and blue_mask. + * If XPutPixel is used to put a pixel into an XImage then XPutPixel will + * do byte swapping if needed. If one wants to directly "poke" the pixel + * into the XImage's buffer then the pixel must be byte swapped first. In + * Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format + * and use XPutPixel everywhere except in the implementation of + * glClear(GL_COLOR_BUFFER_BIT). We want this function to be fast so + * instead of using XPutPixel we "poke" our values after byte-swapping + * the clear pixel value if needed. + * + */ + +#ifdef __CYGWIN__ +#undef WIN32 +#undef __WIN32__ +#endif + +#include "glxheader.h" +#include "GL/xmesa.h" +#include "xmesaP.h" +#include "context.h" +#include "extensions.h" +#include "framebuffer.h" +#include "glthread.h" +#include "imports.h" +#include "matrix.h" +#include "mtypes.h" +#include "macros.h" +#include "renderbuffer.h" +#include "texformat.h" +#include "texobj.h" +#include "texstore.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "drivers/common/driverfuncs.h" + +#ifdef XFree86Server +#include <GL/glxtokens.h> +#endif + +/* + * Global X driver lock + */ +_glthread_Mutex _xmesa_lock; + + + +/* + * Lookup tables for HPCR pixel format: + */ +static short hpcr_rgbTbl[3][256] = { +{ + 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, + 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, + 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, +112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, +128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, +144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, +160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, +176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, +192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, +208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, +224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 +}, +{ + 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, + 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, + 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, +112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, +128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, +144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, +160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, +176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, +192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, +208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, +224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 +}, +{ + 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, + 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, + 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, + 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, + 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, + 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, + 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, +112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, +128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, +144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, +160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, +176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, +192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, +208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223 +} +}; + + + +/**********************************************************************/ +/***** X Utility Functions *****/ +/**********************************************************************/ + + +/* + * Return the host's byte order as LSBFirst or MSBFirst ala X. + */ +#ifndef XFree86Server +static int host_byte_order( void ) +{ + int i = 1; + char *cptr = (char *) &i; + return (*cptr==1) ? LSBFirst : MSBFirst; +} +#endif + + +/* + * Error handling. + */ +#ifndef XFree86Server +static volatile int mesaXErrorFlag = 0; + +static int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event ) +{ + (void) dpy; + (void) event; + mesaXErrorFlag = 1; + return 0; +} +#endif + + +/* + * Check if the X Shared Memory extension is available. + * Return: 0 = not available + * 1 = shared XImage support available + * 2 = shared Pixmap support available also + */ +#ifndef XFree86Server +static int check_for_xshm( XMesaDisplay *display ) +{ +#ifdef USE_XSHM + int major, minor, ignore; + Bool pixmaps; + + if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { + if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { + return (pixmaps==True) ? 2 : 1; + } + else { + return 0; + } + } + else { + return 0; + } +#else + /* Can't compile XSHM support */ + return 0; +#endif +} +#endif + + +/* + * Apply gamma correction to an intensity value in [0..max]. Return the + * new intensity value. + */ +static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max ) +{ + if (gamma == 1.0) { + return value; + } + else { + double x = (double) value / (double) max; + return IROUND_POS((GLfloat) max * _mesa_pow(x, 1.0F/gamma)); + } +} + + + +/* + * Return the true number of bits per pixel for XImages. + * For example, if we request a 24-bit deep visual we may actually need/get + * 32bpp XImages. This function returns the appropriate bpp. + * Input: dpy - the X display + * visinfo - desribes the visual to be used for XImages + * Return: true number of bits per pixel for XImages + */ +#ifdef XFree86Server + +static int bits_per_pixel( XMesaVisual xmv ) +{ + const int depth = xmv->nplanes; + int i; + for (i = 0; i < screenInfo.numPixmapFormats; i++) { + if (screenInfo.formats[i].depth == depth) + return screenInfo.formats[i].bitsPerPixel; + } + return depth; /* should never get here, but this should be safe */ +} + +#else + +static int bits_per_pixel( XMesaVisual xmv ) +{ + XMesaDisplay *dpy = xmv->display; + XMesaVisualInfo visinfo = xmv->visinfo; + XMesaImage *img; + int bitsPerPixel; + /* Create a temporary XImage */ + img = XCreateImage( dpy, visinfo->visual, visinfo->depth, + ZPixmap, 0, /*format, offset*/ + (char*) MALLOC(8), /*data*/ + 1, 1, /*width, height*/ + 32, /*bitmap_pad*/ + 0 /*bytes_per_line*/ + ); + assert(img); + /* grab the bits/pixel value */ + bitsPerPixel = img->bits_per_pixel; + /* free the XImage */ + _mesa_free( img->data ); + img->data = NULL; + XMesaDestroyImage( img ); + return bitsPerPixel; +} +#endif + + + +/* + * Determine if a given X window ID is valid (window exists). + * Do this by calling XGetWindowAttributes() for the window and + * checking if we catch an X error. + * Input: dpy - the display + * win - the window to check for existance + * Return: GL_TRUE - window exists + * GL_FALSE - window doesn't exist + */ +#ifndef XFree86Server +static GLboolean WindowExistsFlag; + +static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr ) +{ + (void) dpy; + if (xerr->error_code == BadWindow) { + WindowExistsFlag = GL_FALSE; + } + return 0; +} + +static GLboolean window_exists( XMesaDisplay *dpy, Window win ) +{ + XWindowAttributes wa; + int (*old_handler)( XMesaDisplay*, XErrorEvent* ); + WindowExistsFlag = GL_TRUE; + old_handler = XSetErrorHandler(window_exists_err_handler); + XGetWindowAttributes( dpy, win, &wa ); /* dummy request */ + XSetErrorHandler(old_handler); + return WindowExistsFlag; +} +#endif + + + +/**********************************************************************/ +/***** Linked list of XMesaBuffers *****/ +/**********************************************************************/ + +static XMesaBuffer XMesaBufferList = NULL; + + +/** + * Allocate a new XMesaBuffer, initialize basic fields and add to + * the list of all buffers. + */ +static XMesaBuffer +alloc_xmesa_buffer(XMesaVisual vis, BufferType type, XMesaColormap cmap) +{ + XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); + if (b) { + GLboolean swAlpha; + + b->display = vis->display; + b->xm_visual = vis; + b->type = type; + b->cmap = cmap; + + _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); + + /* determine back buffer implementation */ + if (vis->mesa_visual.doubleBufferMode) { + if (vis->ximage_flag) { + b->db_state = BACK_XIMAGE; + } + else { + b->db_state = BACK_PIXMAP; + } + } + else { + b->db_state = 0; + } + + /* Allocate the framebuffer's renderbuffers */ + assert(!b->mesa_buffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + assert(!b->mesa_buffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer); + + /* front renderbuffer */ + b->frontxrb = xmesa_new_renderbuffer(NULL, 0, vis->mesa_visual.rgbMode); + _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT, + &b->frontxrb->Base); + + /* back renderbuffer */ + if (vis->mesa_visual.doubleBufferMode) { + b->backxrb =xmesa_new_renderbuffer(NULL, 0, vis->mesa_visual.rgbMode); + _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT, + &b->backxrb->Base); + } + + /* determine if we need software alpha planes */ + if (vis->mesa_visual.alphaBits > 0 + && vis->undithered_pf != PF_8A8B8G8R + && vis->undithered_pf != PF_8A8R8G8B) { + /* Visual has alpha, but pixel format doesn't support it. + * We'll use an alpha renderbuffer wrapper. + */ + swAlpha = GL_TRUE; + } + else { + swAlpha = GL_FALSE; + } + + _mesa_add_soft_renderbuffers(&b->mesa_buffer, + GL_FALSE, /* color */ + vis->mesa_visual.haveDepthBuffer, + vis->mesa_visual.haveStencilBuffer, + vis->mesa_visual.haveAccumBuffer, + swAlpha, + vis->mesa_visual.numAuxBuffers > 0 ); + + /* insert into linked list */ + b->Next = XMesaBufferList; + XMesaBufferList = b; + } + return b; +} + + +/* + * Find an XMesaBuffer by matching X display and colormap but NOT matching + * the notThis buffer. + */ +static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy, + XMesaColormap cmap, + XMesaBuffer notThis) +{ + XMesaBuffer b; + for (b=XMesaBufferList; b; b=b->Next) { + if (b->display==dpy && b->cmap==cmap && b!=notThis) { + return b; + } + } + return NULL; +} + + +/* + * Free an XMesaBuffer, remove from linked list, perhaps free X colormap + * entries. + */ +static void free_xmesa_buffer(int client, XMesaBuffer buffer) +{ + XMesaBuffer prev = NULL, b; + (void) client; + for (b=XMesaBufferList; b; b=b->Next) { + if (b==buffer) { + /* unlink bufer from list */ + if (prev) + prev->Next = buffer->Next; + else + XMesaBufferList = buffer->Next; + /* Check to free X colors */ + if (buffer->num_alloced>0) { + /* If no other buffer uses this X colormap then free the colors. */ + if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) { +#ifdef XFree86Server + (void)FreeColors(buffer->cmap, client, + buffer->num_alloced, buffer->alloced_colors, + 0); +#else + XFreeColors(buffer->display, buffer->cmap, + buffer->alloced_colors, buffer->num_alloced, 0); +#endif + } + } + + _mesa_free_framebuffer_data(&buffer->mesa_buffer); + _mesa_free(buffer); + + return; + } + /* continue search */ + prev = b; + } + /* buffer not found in XMesaBufferList */ + _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n"); +} + + +/* Copy X color table stuff from one XMesaBuffer to another. */ +static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src) +{ + MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table)); + MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r)); + MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g)); + MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b)); + dst->num_alloced = src->num_alloced; + MEMCPY(dst->alloced_colors, src->alloced_colors, + sizeof(src->alloced_colors)); +} + + + +/**********************************************************************/ +/***** Misc Private Functions *****/ +/**********************************************************************/ + + +/* + * 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; +} + + + +/** + * Allocate a shared memory XImage back buffer for the given XMesaBuffer. + * Return: GL_TRUE if success, GL_FALSE if error + */ +#ifndef XFree86Server +static GLboolean +alloc_shm_back_buffer(XMesaBuffer b, GLuint width, GLuint height) +{ +#ifdef USE_XSHM + /* + * We have to do a _lot_ of error checking here to be sure we can + * really use the XSHM extension. It seems different servers trigger + * errors at different points if the extension won't work. Therefore + * we have to be very careful... + */ + GC gc; + int (*old_handler)( XMesaDisplay *, XErrorEvent * ); + + if (width == 0 || height == 0) { + /* this will be true the first time we're called on 'b' */ + return GL_FALSE; + } + + b->backxrb->ximage = XShmCreateImage(b->xm_visual->display, + b->xm_visual->visinfo->visual, + b->xm_visual->visinfo->depth, + ZPixmap, NULL, &b->shminfo, + width, height); + if (b->backxrb->ximage == NULL) { + _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling."); + b->shm = 0; + return GL_FALSE; + } + + b->shminfo.shmid = shmget( IPC_PRIVATE, b->backxrb->ximage->bytes_per_line + * b->backxrb->ximage->height, IPC_CREAT|0777 ); + if (b->shminfo.shmid < 0) { + _mesa_warning(NULL, "shmget failed while allocating back buffer"); + XDestroyImage( b->backxrb->ximage ); + b->backxrb->ximage = NULL; + _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling."); + b->shm = 0; + return GL_FALSE; + } + + b->shminfo.shmaddr = b->backxrb->ximage->data + = (char*)shmat( b->shminfo.shmid, 0, 0 ); + if (b->shminfo.shmaddr == (char *) -1) { + _mesa_warning(NULL, "shmat() failed while allocating back buffer"); + XDestroyImage( b->backxrb->ximage ); + shmctl( b->shminfo.shmid, IPC_RMID, 0 ); + b->backxrb->ximage = NULL; + _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling."); + b->shm = 0; + return GL_FALSE; + } + + b->shminfo.readOnly = False; + mesaXErrorFlag = 0; + old_handler = XSetErrorHandler( mesaHandleXError ); + /* This may trigger the X protocol error we're ready to catch: */ + XShmAttach( b->xm_visual->display, &b->shminfo ); + XSync( b->xm_visual->display, False ); + + if (mesaXErrorFlag) { + /* we are on a remote display, this error is normal, don't print it */ + XFlush( b->xm_visual->display ); + mesaXErrorFlag = 0; + XDestroyImage( b->backxrb->ximage ); + shmdt( b->shminfo.shmaddr ); + shmctl( b->shminfo.shmid, IPC_RMID, 0 ); + b->backxrb->ximage = NULL; + b->shm = 0; + (void) XSetErrorHandler( old_handler ); + return GL_FALSE; + } + + shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */ + + /* Finally, try an XShmPutImage to be really sure the extension works */ + gc = XCreateGC( b->xm_visual->display, b->frontxrb->drawable, 0, NULL ); + XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, gc, + b->backxrb->ximage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False ); + XSync( b->xm_visual->display, False ); + XFreeGC( b->xm_visual->display, gc ); + (void) XSetErrorHandler( old_handler ); + if (mesaXErrorFlag) { + XFlush( b->xm_visual->display ); + mesaXErrorFlag = 0; + XDestroyImage( b->backxrb->ximage ); + shmdt( b->shminfo.shmaddr ); + shmctl( b->shminfo.shmid, IPC_RMID, 0 ); + b->backxrb->ximage = NULL; + b->shm = 0; + return GL_FALSE; + } + + return GL_TRUE; +#else + /* Can't compile XSHM support */ + return GL_FALSE; +#endif +} +#endif + + + + +/* + * Setup an off-screen pixmap or Ximage to use as the back buffer. + * Input: b - the X/Mesa buffer + */ +void +xmesa_alloc_back_buffer( XMesaBuffer b, GLuint width, GLuint height ) +{ + if (width == 0 || height == 0) + return; + + if (b->db_state == BACK_XIMAGE) { + /* Deallocate the old backxrb->ximage, if any */ + if (b->backxrb->ximage) { +#if defined(USE_XSHM) && !defined(XFree86Server) + if (b->shm) { + XShmDetach( b->xm_visual->display, &b->shminfo ); + XDestroyImage( b->backxrb->ximage ); + shmdt( b->shminfo.shmaddr ); + } + else +#endif + XMesaDestroyImage( b->backxrb->ximage ); + b->backxrb->ximage = NULL; + } + + /* Allocate new back buffer */ +#ifdef XFree86Server + { + /* Allocate a regular XImage for the back buffer. */ + b->backxrb->ximage = XMesaCreateImage(b->xm_visual->BitsPerPixel, + width, height, NULL); +#else + if (b->shm == 0 || !alloc_shm_back_buffer(b, width, height)) { + /* Allocate a regular XImage for the back buffer. */ + b->backxrb->ximage = XCreateImage( b->xm_visual->display, + b->xm_visual->visinfo->visual, + GET_VISUAL_DEPTH(b->xm_visual), + ZPixmap, 0, /* format, offset */ + NULL, + width, height, + 8, 0 ); /* pad, bytes_per_line */ +#endif + if (!b->backxrb->ximage) { + _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed."); + } + b->backxrb->ximage->data = (char *) MALLOC( b->backxrb->ximage->height + * b->backxrb->ximage->bytes_per_line ); + if (!b->backxrb->ximage->data) { + _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed."); + XMesaDestroyImage( b->backxrb->ximage ); + b->backxrb->ximage = NULL; + } + /* this call just updates the width/origin fields in the xrb */ + b->backxrb->Base.AllocStorage(NULL, &b->backxrb->Base, + b->backxrb->Base.InternalFormat, + b->backxrb->ximage->width, + b->backxrb->ximage->height); + } + b->backxrb->pixmap = None; + } + else if (b->db_state==BACK_PIXMAP) { + if (!width) + width = 1; + if (!height) + height = 1; + + /* Free the old back pixmap */ + if (b->backxrb->pixmap) { + XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap ); + } + /* Allocate new back pixmap */ + b->backxrb->pixmap = XMesaCreatePixmap( b->xm_visual->display, + b->frontxrb->drawable, + width, height, + GET_VISUAL_DEPTH(b->xm_visual) ); + b->backxrb->ximage = NULL; + } +} + + + +/* + * A replacement for XAllocColor. This function should never + * fail to allocate a color. When XAllocColor fails, we return + * the nearest matching color. If we have to allocate many colors + * this function isn't too efficient; the XQueryColors() could be + * done just once. + * Written by Michael Pichler, Brian Paul, Mark Kilgard + * Input: dpy - X display + * cmap - X colormap + * cmapSize - size of colormap + * In/Out: color - the XColor struct + * Output: exact - 1=exact color match, 0=closest match + * alloced - 1=XAlloc worked, 0=XAlloc failed + */ +static void +noFaultXAllocColor( int client, + XMesaDisplay *dpy, + XMesaColormap cmap, + int cmapSize, + XMesaColor *color, + int *exact, int *alloced ) +{ +#ifdef XFree86Server + Pixel *ppixIn; + xrgb *ctable; +#else + /* we'll try to cache ctable for better remote display performance */ + static Display *prevDisplay = NULL; + static XMesaColormap prevCmap = 0; + static int prevCmapSize = 0; + static XMesaColor *ctable = NULL; +#endif + XMesaColor subColor; + int i, bestmatch; + double mindist; /* 3*2^16^2 exceeds long int precision. */ + + (void) client; + + /* First try just using XAllocColor. */ +#ifdef XFree86Server + if (AllocColor(cmap, + &color->red, &color->green, &color->blue, + &color->pixel, + client) == Success) { +#else + if (XAllocColor(dpy, cmap, color)) { +#endif + *exact = 1; + *alloced = 1; + return; + } + + /* Alloc failed, search for closest match */ + + /* Retrieve color table entries. */ + /* XXX alloca candidate. */ +#ifdef XFree86Server + ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel)); + ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb)); + for (i = 0; i < cmapSize; i++) { + ppixIn[i] = i; + } + QueryColors(cmap, cmapSize, ppixIn, ctable); +#else + if (prevDisplay != dpy || prevCmap != cmap + || prevCmapSize != cmapSize || !ctable) { + /* free previously cached color table */ + if (ctable) + _mesa_free(ctable); + /* Get the color table from X */ + ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor)); + assert(ctable); + for (i = 0; i < cmapSize; i++) { + ctable[i].pixel = i; + } + XQueryColors(dpy, cmap, ctable, cmapSize); + prevDisplay = dpy; + prevCmap = cmap; + prevCmapSize = cmapSize; + } +#endif + + /* Find best match. */ + bestmatch = -1; + mindist = 0.0; + for (i = 0; i < cmapSize; i++) { + double dr = 0.30 * ((double) color->red - (double) ctable[i].red); + double dg = 0.59 * ((double) color->green - (double) ctable[i].green); + double db = 0.11 * ((double) color->blue - (double) ctable[i].blue); + double dist = dr * dr + dg * dg + db * db; + if (bestmatch < 0 || dist < mindist) { + bestmatch = i; + mindist = dist; + } + } + + /* Return result. */ + subColor.red = ctable[bestmatch].red; + subColor.green = ctable[bestmatch].green; + subColor.blue = ctable[bestmatch].blue; + /* Try to allocate the closest match color. This should only + * fail if the cell is read/write. Otherwise, we're incrementing + * the cell's reference count. + */ +#ifdef XFree86Server + if (AllocColor(cmap, + &subColor.red, &subColor.green, &subColor.blue, + &subColor.pixel, + client) == Success) { +#else + if (XAllocColor(dpy, cmap, &subColor)) { +#endif + *alloced = 1; + } + else { + /* do this to work around a problem reported by Frank Ortega */ + subColor.pixel = (unsigned long) bestmatch; + subColor.red = ctable[bestmatch].red; + subColor.green = ctable[bestmatch].green; + subColor.blue = ctable[bestmatch].blue; + subColor.flags = DoRed | DoGreen | DoBlue; + *alloced = 0; + } +#ifdef XFree86Server + _mesa_free(ppixIn); + _mesa_free(ctable); +#else + /* don't free table, save it for next time */ +#endif + + *color = subColor; + *exact = 0; +} + + + + +/* + * Do setup for PF_GRAYSCALE pixel format. + * Note that buffer may be NULL. + */ +static GLboolean setup_grayscale( int client, XMesaVisual v, + XMesaBuffer buffer, XMesaColormap cmap ) +{ + if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { + return GL_FALSE; + } + + if (buffer) { + XMesaBuffer prevBuffer; + + if (!cmap) { + return GL_FALSE; + } + + prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); + if (prevBuffer && + (buffer->xm_visual->mesa_visual.rgbMode == + prevBuffer->xm_visual->mesa_visual.rgbMode)) { + /* Copy colormap stuff from previous XMesaBuffer which uses same + * X colormap. Do this to avoid time spent in noFaultXAllocColor. + */ + copy_colortable_info(buffer, prevBuffer); + } + else { + /* Allocate 256 shades of gray */ + int gray; + int colorsfailed = 0; + for (gray=0;gray<256;gray++) { + GLint r = gamma_adjust( v->RedGamma, gray, 255 ); + GLint g = gamma_adjust( v->GreenGamma, gray, 255 ); + GLint b = gamma_adjust( v->BlueGamma, gray, 255 ); + int exact, alloced; + XMesaColor xcol; + xcol.red = (r << 8) | r; + xcol.green = (g << 8) | g; + xcol.blue = (b << 8) | b; + noFaultXAllocColor( client, v->display, + cmap, GET_COLORMAP_SIZE(v), + &xcol, &exact, &alloced ); + if (!exact) { + colorsfailed++; + } + if (alloced) { + assert(buffer->num_alloced<256); + buffer->alloced_colors[buffer->num_alloced] = xcol.pixel; + buffer->num_alloced++; + } + + /*OLD + assert(gray < 576); + buffer->color_table[gray*3+0] = xcol.pixel; + buffer->color_table[gray*3+1] = xcol.pixel; + buffer->color_table[gray*3+2] = xcol.pixel; + assert(xcol.pixel < 65536); + buffer->pixel_to_r[xcol.pixel] = gray * 30 / 100; + buffer->pixel_to_g[xcol.pixel] = gray * 59 / 100; + buffer->pixel_to_b[xcol.pixel] = gray * 11 / 100; + */ + buffer->color_table[gray] = xcol.pixel; + assert(xcol.pixel < 65536); + buffer->pixel_to_r[xcol.pixel] = gray; + buffer->pixel_to_g[xcol.pixel] = gray; + buffer->pixel_to_b[xcol.pixel] = gray; + } + + if (colorsfailed && _mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, + "Note: %d out of 256 needed colors do not match exactly.\n", + colorsfailed ); + } + } + } + + v->dithered_pf = PF_Grayscale; + v->undithered_pf = PF_Grayscale; + return GL_TRUE; +} + + + +/* + * Setup RGB rendering for a window with a PseudoColor, StaticColor, + * or 8-bit TrueColor visual visual. We try to allocate a palette of 225 + * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB + * color. While this function was originally designed just for 8-bit + * visuals, it has also proven to work from 4-bit up to 16-bit visuals. + * Dithering code contributed by Bob Mercier. + */ +static GLboolean setup_dithered_color( int client, XMesaVisual v, + XMesaBuffer buffer, XMesaColormap cmap ) +{ + if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { + return GL_FALSE; + } + + if (buffer) { + XMesaBuffer prevBuffer; + + if (!cmap) { + return GL_FALSE; + } + + prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); + if (prevBuffer && + (buffer->xm_visual->mesa_visual.rgbMode == + prevBuffer->xm_visual->mesa_visual.rgbMode)) { + /* Copy colormap stuff from previous, matching XMesaBuffer. + * Do this to avoid time spent in noFaultXAllocColor. + */ + copy_colortable_info(buffer, prevBuffer); + } + else { + /* Allocate X colors and initialize color_table[], red_table[], etc */ + int r, g, b, i; + int colorsfailed = 0; + for (r = 0; r < DITH_R; r++) { + for (g = 0; g < DITH_G; g++) { + for (b = 0; b < DITH_B; b++) { + XMesaColor xcol; + int exact, alloced; + xcol.red =gamma_adjust(v->RedGamma, r*65535/(DITH_R-1),65535); + xcol.green=gamma_adjust(v->GreenGamma, g*65535/(DITH_G-1),65535); + xcol.blue =gamma_adjust(v->BlueGamma, b*65535/(DITH_B-1),65535); + noFaultXAllocColor( client, v->display, + cmap, GET_COLORMAP_SIZE(v), + &xcol, &exact, &alloced ); + if (!exact) { + colorsfailed++; + } + if (alloced) { + assert(buffer->num_alloced<256); + buffer->alloced_colors[buffer->num_alloced] = xcol.pixel; + buffer->num_alloced++; + } + i = DITH_MIX( r, g, b ); + assert(i < 576); + buffer->color_table[i] = xcol.pixel; + assert(xcol.pixel < 65536); + buffer->pixel_to_r[xcol.pixel] = r * 255 / (DITH_R-1); + buffer->pixel_to_g[xcol.pixel] = g * 255 / (DITH_G-1); + buffer->pixel_to_b[xcol.pixel] = b * 255 / (DITH_B-1); + } + } + } + + if (colorsfailed && _mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, + "Note: %d out of %d needed colors do not match exactly.\n", + colorsfailed, DITH_R * DITH_G * DITH_B ); + } + } + } + + v->dithered_pf = PF_Dither; + v->undithered_pf = PF_Lookup; + return GL_TRUE; +} + + +/* + * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode. + * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer. + * Special dithering tables have to be initialized. + */ +static void setup_8bit_hpcr( XMesaVisual v ) +{ + /* HP Color Recovery contributed by: Alex De Bruyn (ad@lms.be) + * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined + * on the root window AND the colormap obtainable by XGetRGBColormaps + * for that atom must be set on the window. (see also tkInitWindow) + * If that colormap is not set, the output will look stripy. + */ + + /* Setup color tables with gamma correction */ + int i; + double g; + + g = 1.0 / v->RedGamma; + for (i=0; i<256; i++) { + GLint red = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[0][i]/255.0, g )); + v->hpcr_rgbTbl[0][i] = CLAMP( red, 16, 239 ); + } + + g = 1.0 / v->GreenGamma; + for (i=0; i<256; i++) { + GLint green = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[1][i]/255.0, g )); + v->hpcr_rgbTbl[1][i] = CLAMP( green, 16, 239 ); + } + + g = 1.0 / v->BlueGamma; + for (i=0; i<256; i++) { + GLint blue = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[2][i]/255.0, g )); + v->hpcr_rgbTbl[2][i] = CLAMP( blue, 32, 223 ); + } + v->undithered_pf = PF_HPCR; /* can't really disable dithering for now */ + v->dithered_pf = PF_HPCR; + + /* which method should I use to clear */ + /* GL_FALSE: keep the ordinary method */ + /* GL_TRUE : clear with dither pattern */ + v->hpcr_clear_flag = _mesa_getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE; + + if (v->hpcr_clear_flag) { + v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display, + DefaultRootWindow(v->display), + 16, 2, 8); +#ifndef XFree86Server + v->hpcr_clear_ximage = XGetImage(v->display, v->hpcr_clear_pixmap, + 0, 0, 16, 2, AllPlanes, ZPixmap); +#endif + } +} + + +/* + * Setup RGB rendering for a window with a True/DirectColor visual. + */ +static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer, + XMesaColormap cmap ) +{ + unsigned long rmask, gmask, bmask; + (void) buffer; + (void) cmap; + + /* Compute red multiplier (mask) and bit shift */ + v->rshift = 0; + rmask = GET_REDMASK(v); + while ((rmask & 1)==0) { + v->rshift++; + rmask = rmask >> 1; + } + + /* Compute green multiplier (mask) and bit shift */ + v->gshift = 0; + gmask = GET_GREENMASK(v); + while ((gmask & 1)==0) { + v->gshift++; + gmask = gmask >> 1; + } + + /* Compute blue multiplier (mask) and bit shift */ + v->bshift = 0; + bmask = GET_BLUEMASK(v); + while ((bmask & 1)==0) { + v->bshift++; + bmask = bmask >> 1; + } + + /* + * Compute component-to-pixel lookup tables and dithering kernel + */ + { + static GLubyte kernel[16] = { + 0*16, 8*16, 2*16, 10*16, + 12*16, 4*16, 14*16, 6*16, + 3*16, 11*16, 1*16, 9*16, + 15*16, 7*16, 13*16, 5*16, + }; + GLint rBits = bitcount(rmask); + GLint gBits = bitcount(gmask); + GLint bBits = bitcount(bmask); + GLint maxBits; + GLuint i; + + /* convert pixel components in [0,_mask] to RGB values in [0,255] */ + for (i=0; i<=rmask; i++) + v->PixelToR[i] = (unsigned char) ((i * 255) / rmask); + for (i=0; i<=gmask; i++) + v->PixelToG[i] = (unsigned char) ((i * 255) / gmask); + for (i=0; i<=bmask; i++) + v->PixelToB[i] = (unsigned char) ((i * 255) / bmask); + + /* convert RGB values from [0,255] to pixel components */ + + for (i=0;i<256;i++) { + GLint r = gamma_adjust(v->RedGamma, i, 255); + GLint g = gamma_adjust(v->GreenGamma, i, 255); + GLint b = gamma_adjust(v->BlueGamma, i, 255); + v->RtoPixel[i] = (r >> (8-rBits)) << v->rshift; + v->GtoPixel[i] = (g >> (8-gBits)) << v->gshift; + v->BtoPixel[i] = (b >> (8-bBits)) << v->bshift; + } + /* overflow protection */ + for (i=256;i<512;i++) { + v->RtoPixel[i] = v->RtoPixel[255]; + v->GtoPixel[i] = v->GtoPixel[255]; + v->BtoPixel[i] = v->BtoPixel[255]; + } + + /* setup dithering kernel */ + maxBits = rBits; + if (gBits > maxBits) maxBits = gBits; + if (bBits > maxBits) maxBits = bBits; + for (i=0;i<16;i++) { + v->Kernel[i] = kernel[i] >> maxBits; + } + + v->undithered_pf = PF_Truecolor; + v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_Dither_True : PF_Truecolor; + } + + /* + * Now check for TrueColor visuals which we can optimize. + */ + if ( GET_REDMASK(v) ==0x0000ff + && GET_GREENMASK(v)==0x00ff00 + && GET_BLUEMASK(v) ==0xff0000 + && CHECK_BYTE_ORDER(v) + && v->BitsPerPixel==32 + && sizeof(GLuint)==4 + && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { + /* common 32 bpp config used on SGI, Sun */ + v->undithered_pf = v->dithered_pf = PF_8A8B8G8R; + } + else if (GET_REDMASK(v) ==0xff0000 + && GET_GREENMASK(v)==0x00ff00 + && GET_BLUEMASK(v) ==0x0000ff + && CHECK_BYTE_ORDER(v) + && v->BitsPerPixel==32 + && sizeof(GLuint)==4 + && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { + /* common 32 bpp config used on Linux, HP, IBM */ + if (GET_VISUAL_DEPTH(v)==32) + v->undithered_pf = v->dithered_pf = PF_8A8R8G8B; + else + v->undithered_pf = v->dithered_pf = PF_8R8G8B; + } + else if (GET_REDMASK(v) ==0xff0000 + && GET_GREENMASK(v)==0x00ff00 + && GET_BLUEMASK(v) ==0x0000ff + && CHECK_BYTE_ORDER(v) + && v->BitsPerPixel==24 + && sizeof(GLuint)==4 + && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { + /* common packed 24 bpp config used on Linux */ + v->undithered_pf = v->dithered_pf = PF_8R8G8B24; + } + else if (GET_REDMASK(v) ==0xf800 + && GET_GREENMASK(v)==0x07e0 + && GET_BLUEMASK(v) ==0x001f + && CHECK_BYTE_ORDER(v) + && v->BitsPerPixel==16 + && sizeof(GLushort)==2 + && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { + /* 5-6-5 color weight on common PC VGA boards */ + v->undithered_pf = PF_5R6G5B; + v->dithered_pf = PF_Dither_5R6G5B; + } + else if (GET_REDMASK(v) ==0xe0 + && GET_GREENMASK(v)==0x1c + && GET_BLUEMASK(v) ==0x03 + && CHECK_FOR_HPCR(v)) { + setup_8bit_hpcr( v ); + } +} + + + +/* + * Setup RGB rendering for a window with a monochrome visual. + */ +static void setup_monochrome( XMesaVisual v, XMesaBuffer b ) +{ + (void) b; + v->dithered_pf = v->undithered_pf = PF_1Bit; + /* if black=1 then we must flip pixel values */ + v->bitFlip = (GET_BLACK_PIXEL(v) != 0); +} + + + +/* + * When a context is "made current" for the first time, we can finally + * finish initializing the context's visual and buffer information. + * Input: v - the XMesaVisual to initialize + * b - the XMesaBuffer to initialize (may be NULL) + * rgb_flag - TRUE = RGBA mode, FALSE = color index mode + * window - the window/pixmap we're rendering into + * cmap - the colormap associated with the window/pixmap + * Return: GL_TRUE=success, GL_FALSE=failure + */ +static GLboolean initialize_visual_and_buffer( int client, + XMesaVisual v, + XMesaBuffer b, + GLboolean rgb_flag, + XMesaDrawable window, + XMesaColormap cmap ) +{ + struct xmesa_renderbuffer *front_xrb, *back_xrb; +#ifndef XFree86Server + XGCValues gcvalues; +#endif + + if (b) { + assert(b->xm_visual == v); + } + + if (b) { + front_xrb = b->frontxrb; + back_xrb = b->backxrb; + } + else { + front_xrb = back_xrb = NULL; + } + + /* Save true bits/pixel */ + v->BitsPerPixel = bits_per_pixel(v); + assert(v->BitsPerPixel > 0); + + + if (rgb_flag==GL_FALSE) { + /* COLOR-INDEXED WINDOW: + * Even if the visual is TrueColor or DirectColor we treat it as + * being color indexed. This is weird but might be useful to someone. + */ + v->dithered_pf = v->undithered_pf = PF_Index; + v->mesa_visual.indexBits = GET_VISUAL_DEPTH(v); + } + else { + /* RGB WINDOW: + * We support RGB rendering into almost any kind of visual. + */ + const int xclass = v->mesa_visual.visualType; + if (xclass==GLX_TRUE_COLOR || xclass==GLX_DIRECT_COLOR) { + setup_truecolor( v, b, cmap ); + } + else if (xclass==GLX_STATIC_GRAY && GET_VISUAL_DEPTH(v)==1) { + setup_monochrome( v, b ); + } + else if (xclass==GLX_GRAY_SCALE || xclass==GLX_STATIC_GRAY) { + if (!setup_grayscale( client, v, b, cmap )) { + return GL_FALSE; + } + } + else if ((xclass==GLX_PSEUDO_COLOR || xclass==GLX_STATIC_COLOR) + && GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) { + if (!setup_dithered_color( client, v, b, cmap )) { + return GL_FALSE; + } + } + else { + _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual."); + return GL_FALSE; + } + v->mesa_visual.indexBits = 0; + + if (_mesa_getenv("MESA_NO_DITHER")) { + v->dithered_pf = v->undithered_pf; + } + } + + + /* + * If MESA_INFO env var is set print out some debugging info + * which can help Brian figure out what's going on when a user + * reports bugs. + */ + if (_mesa_getenv("MESA_INFO")) { + _mesa_printf("X/Mesa visual = %p\n", (void *) v); + _mesa_printf("X/Mesa dithered pf = %u\n", v->dithered_pf); + _mesa_printf("X/Mesa undithered pf = %u\n", v->undithered_pf); + _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level); + _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v)); + _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); + } + + if (b && window) { + /* Do window-specific initializations */ + + b->frontxrb->drawable = window; + b->frontxrb->pixmap = (XMesaPixmap) window; + + /* Setup for single/double buffering */ + if (v->mesa_visual.doubleBufferMode) { + /* Double buffered */ +#ifndef XFree86Server + b->shm = check_for_xshm( v->display ); +#endif + xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height); + } + + /* X11 graphics contexts */ +#ifdef XFree86Server + b->gc = CreateScratchGC(v->display, window->depth); +#else + b->gc = XCreateGC( v->display, window, 0, NULL ); +#endif + XMesaSetFunction( v->display, b->gc, GXcopy ); + + /* cleargc - for glClear() */ +#ifdef XFree86Server + b->cleargc = CreateScratchGC(v->display, window->depth); +#else + b->cleargc = XCreateGC( v->display, window, 0, NULL ); +#endif + XMesaSetFunction( v->display, b->cleargc, GXcopy ); + + /* + * Don't generate Graphics Expose/NoExpose events in swapbuffers(). + * Patch contributed by Michael Pichler May 15, 1995. + */ +#ifdef XFree86Server + b->swapgc = CreateScratchGC(v->display, window->depth); + { + CARD32 v[1]; + v[0] = FALSE; + dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL); + } +#else + gcvalues.graphics_exposures = False; + b->swapgc = XCreateGC( v->display, window, + GCGraphicsExposures, &gcvalues); +#endif + XMesaSetFunction( v->display, b->swapgc, GXcopy ); + /* + * Set fill style and tile pixmap once for all for HPCR stuff + * (instead of doing it each time in clear_color_HPCR_pixmap()) + * Initialize whole stuff + * Patch contributed by Jacques Leroy March 8, 1998. + */ + if (v->hpcr_clear_flag && back_xrb->pixmap) { + int i; + for (i=0; i<16; i++) + { + XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0); + XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0); + } + XMesaPutImage(b->display, (XMesaDrawable)v->hpcr_clear_pixmap, + b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2); + XMesaSetFillStyle( v->display, b->cleargc, FillTiled); + XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap ); + } + + /* Initialize the row buffer XImage for use in write_color_span() */ +#ifdef XFree86Server + b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1, + (char *)MALLOC(MAX_WIDTH*4)); +#else + b->rowimage = XCreateImage( v->display, + v->visinfo->visual, + v->visinfo->depth, + ZPixmap, 0, /*format, offset*/ + (char*) MALLOC(MAX_WIDTH*4), /*data*/ + MAX_WIDTH, 1, /*width, height*/ + 32, /*bitmap_pad*/ + 0 /*bytes_per_line*/ ); +#endif + if (!b->rowimage) + return GL_FALSE; + } + + return GL_TRUE; +} + + + +/* + * Convert an RGBA color to a pixel value. + */ +unsigned long +xmesa_color_to_pixel(GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a, + GLuint pixelFormat) +{ + XMesaContext xmesa = XMESA_CONTEXT(ctx); + switch (pixelFormat) { + case PF_Index: + return 0; + case PF_Truecolor: + { + unsigned long p; + PACK_TRUECOLOR( p, r, g, b ); + return p; + } + case PF_8A8B8G8R: + return PACK_8A8B8G8R( r, g, b, a ); + case PF_8A8R8G8B: + return PACK_8A8R8G8B( r, g, b, a ); + case PF_8R8G8B: + /* fall through */ + case PF_8R8G8B24: + return PACK_8R8G8B( r, g, b ); + case PF_5R6G5B: + return PACK_5R6G5B( r, g, b ); + case PF_Dither: + { + DITHER_SETUP; + return DITHER( 1, 0, r, g, b ); + } + case PF_1Bit: + /* 382 = (3*255)/2 */ + return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip; + case PF_HPCR: + return DITHER_HPCR(1, 1, r, g, b); + case PF_Lookup: + { + LOOKUP_SETUP; + return LOOKUP( r, g, b ); + } + case PF_Grayscale: + return GRAY_RGB( r, g, b ); + case PF_Dither_True: + /* fall through */ + case PF_Dither_5R6G5B: + { + unsigned long p; + PACK_TRUEDITHER(p, 1, 0, r, g, b); + return p; + } + default: + _mesa_problem(ctx, "Bad pixel format in xmesa_color_to_pixel"); + } + return 0; +} + + +#define NUM_VISUAL_TYPES 6 + +/** + * Convert an X visual type to a GLX visual type. + * + * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) + * to be converted. + * \return If \c visualType is a valid X visual type, a GLX visual type will + * be returned. Otherwise \c GLX_NONE will be returned. + * + * \note + * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the + * DRI CVS tree. + */ +static GLint +xmesa_convert_from_x_visual_type( int visualType ) +{ + static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { + GLX_STATIC_GRAY, GLX_GRAY_SCALE, + GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, GLX_DIRECT_COLOR + }; + + return ( (unsigned) visualType < NUM_VISUAL_TYPES ) + ? glx_visual_types[ visualType ] : GLX_NONE; +} + + +/**********************************************************************/ +/***** Public Functions *****/ +/**********************************************************************/ + + +/* + * Create a new X/Mesa visual. + * Input: display - X11 display + * visinfo - an XVisualInfo pointer + * rgb_flag - GL_TRUE = RGB mode, + * GL_FALSE = color index mode + * alpha_flag - alpha buffer requested? + * db_flag - GL_TRUE = double-buffered, + * GL_FALSE = single buffered + * stereo_flag - stereo visual? + * ximage_flag - GL_TRUE = use an XImage for back buffer, + * GL_FALSE = use an off-screen pixmap for back buffer + * depth_size - requested bits/depth values, or zero + * stencil_size - requested bits/stencil values, or zero + * accum_red_size - requested bits/red accum values, or zero + * accum_green_size - requested bits/green accum values, or zero + * accum_blue_size - requested bits/blue accum values, or zero + * accum_alpha_size - requested bits/alpha accum values, or zero + * num_samples - number of samples/pixel if multisampling, or zero + * level - visual level, usually 0 + * visualCaveat - ala the GLX extension, usually GLX_NONE + * Return; a new XMesaVisual or 0 if error. + */ +XMesaVisual XMesaCreateVisual( XMesaDisplay *display, + XMesaVisualInfo visinfo, + GLboolean rgb_flag, + GLboolean alpha_flag, + GLboolean db_flag, + GLboolean stereo_flag, + GLboolean ximage_flag, + GLint depth_size, + GLint stencil_size, + GLint accum_red_size, + GLint accum_green_size, + GLint accum_blue_size, + GLint accum_alpha_size, + GLint num_samples, + GLint level, + GLint visualCaveat ) +{ + char *gamma; + XMesaVisual v; + GLint red_bits, green_bits, blue_bits, alpha_bits; + + /* For debugging only */ + if (_mesa_getenv("MESA_XSYNC")) { + /* This makes debugging X easier. + * In your debugger, set a breakpoint on _XError to stop when an + * X protocol error is generated. + */ +#ifdef XFree86Server + /* NOT_NEEDED */ +#else + XSynchronize( display, 1 ); +#endif + } + + v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); + if (!v) { + return NULL; + } + + /* + * In the X server, NULL is passed in for the display. It will have + * to be set before using this visual. See XMesaSetVisualDisplay() + * below. + */ + v->display = display; + + /* Save a copy of the XVisualInfo struct because the user may X_mesa_free() + * the struct but we may need some of the information contained in it + * at a later time. + */ +#ifndef XFree86Server + v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); + if(!v->visinfo) { + _mesa_free(v); + return NULL; + } + MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); +#endif + + /* check for MESA_GAMMA environment variable */ + gamma = _mesa_getenv("MESA_GAMMA"); + if (gamma) { + v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0; + sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma ); + if (v->RedGamma<=0.0) v->RedGamma = 1.0; + if (v->GreenGamma<=0.0) v->GreenGamma = v->RedGamma; + if (v->BlueGamma<=0.0) v->BlueGamma = v->RedGamma; + } + else { + v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0; + } + + v->ximage_flag = ximage_flag; + +#ifdef XFree86Server + /* We could calculate these values by ourselves. nplanes is either the sum + * of the red, green, and blue bits or the number index bits. + * ColormapEntries is either (1U << index_bits) or + * (1U << max(redBits, greenBits, blueBits)). + */ + v->nplanes = visinfo->nplanes; + v->ColormapEntries = visinfo->ColormapEntries; + + v->mesa_visual.redMask = visinfo->redMask; + v->mesa_visual.greenMask = visinfo->greenMask; + v->mesa_visual.blueMask = visinfo->blueMask; + v->mesa_visual.visualID = visinfo->vid; + v->mesa_visual.screen = 0; /* FIXME: What should be done here? */ +#else + v->mesa_visual.redMask = visinfo->red_mask; + v->mesa_visual.greenMask = visinfo->green_mask; + v->mesa_visual.blueMask = visinfo->blue_mask; + v->mesa_visual.visualID = visinfo->visualid; + v->mesa_visual.screen = visinfo->screen; +#endif + +#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus)) + v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class); +#else + v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); +#endif + + v->mesa_visual.visualRating = visualCaveat; + + (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 ); + + { + const int xclass = v->mesa_visual.visualType; + if (xclass==GLX_TRUE_COLOR || xclass==GLX_DIRECT_COLOR) { + red_bits = bitcount(GET_REDMASK(v)); + green_bits = bitcount(GET_GREENMASK(v)); + blue_bits = bitcount(GET_BLUEMASK(v)); + alpha_bits = 0; + } + else { + /* this is an approximation */ + int depth; + depth = GET_VISUAL_DEPTH(v); + red_bits = depth / 3; + depth -= red_bits; + green_bits = depth / 2; + depth -= green_bits; + blue_bits = depth; + alpha_bits = 0; + assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) ); + } + } + + if (alpha_flag && alpha_bits == 0) + alpha_bits = 8; + + _mesa_initialize_visual( &v->mesa_visual, + rgb_flag, db_flag, stereo_flag, + red_bits, green_bits, + blue_bits, alpha_bits, + v->mesa_visual.indexBits, + depth_size, + stencil_size, + accum_red_size, accum_green_size, + accum_blue_size, accum_alpha_size, + 0 ); + + /* XXX minor hack */ + v->mesa_visual.level = level; + return v; +} + + +void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v ) +{ + v->display = dpy; +} + + +void XMesaDestroyVisual( XMesaVisual v ) +{ +#ifndef XFree86Server + _mesa_free(v->visinfo); +#endif + _mesa_free(v); +} + + + +/** + * Create a new XMesaContext. + * \param v the XMesaVisual + * \param share_list another XMesaContext with which to share display + * lists or NULL if no sharing is wanted. + * \return an XMesaContext or NULL if error. + */ +XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) +{ + static GLboolean firstTime = GL_TRUE; + XMesaContext c; + GLcontext *mesaCtx; + struct dd_function_table functions; + TNLcontext *tnl; + + if (firstTime) { + _glthread_INIT_MUTEX(_xmesa_lock); + firstTime = GL_FALSE; + } + + /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ + c = (XMesaContext) CALLOC_STRUCT(xmesa_context); + if (!c) + return NULL; + + mesaCtx = &(c->mesa); + + /* initialize with default driver functions, then plug in XMesa funcs */ + _mesa_init_driver_functions(&functions); + xmesa_init_driver_functions(v, &functions); + if (!_mesa_initialize_context(mesaCtx, &v->mesa_visual, + share_list ? &(share_list->mesa) : (GLcontext *) NULL, + &functions, (void *) c)) { + _mesa_free(c); + return NULL; + } + + _mesa_enable_sw_extensions(mesaCtx); + _mesa_enable_1_3_extensions(mesaCtx); + _mesa_enable_1_4_extensions(mesaCtx); + _mesa_enable_1_5_extensions(mesaCtx); + _mesa_enable_2_0_extensions(mesaCtx); +#if SWTC + if (c->Mesa_DXTn) { + _mesa_enable_extension(c, "GL_EXT_texture_compression_s3tc"); + _mesa_enable_extension(c, "GL_S3_s3tc"); + } + _mesa_enable_extension(c, "GL_3DFX_texture_compression_FXT1"); +#endif + + /* finish up xmesa context initializations */ + c->swapbytes = CHECK_BYTE_ORDER(v) ? GL_FALSE : GL_TRUE; + c->xm_visual = v; + c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ + c->display = v->display; + c->pixelformat = v->dithered_pf; /* Dithering is enabled by default */ + + /* Initialize the software rasterizer and helper modules. + */ + if (!_swrast_CreateContext( mesaCtx ) || + !_ac_CreateContext( mesaCtx ) || + !_tnl_CreateContext( mesaCtx ) || + !_swsetup_CreateContext( mesaCtx )) { + _mesa_free_context_data(&c->mesa); + _mesa_free(c); + return NULL; + } + + /* tnl setup */ + tnl = TNL_CONTEXT(mesaCtx); + tnl->Driver.RunPipeline = _tnl_run_pipeline; + /* swrast setup */ + xmesa_register_swrast_functions( mesaCtx ); + _swsetup_Wakeup(mesaCtx); + + return c; +} + + + +void XMesaDestroyContext( XMesaContext c ) +{ + GLcontext *mesaCtx = &c->mesa; +#ifdef FX + XMesaBuffer xmbuf = XMESA_BUFFER(mesaCtx->DrawBuffer); + + if (xmbuf && xmbuf->FXctx) + fxMesaDestroyContext(xmbuf->FXctx); +#endif + _swsetup_DestroyContext( mesaCtx ); + _swrast_DestroyContext( mesaCtx ); + _tnl_DestroyContext( mesaCtx ); + _ac_DestroyContext( mesaCtx ); + _mesa_free_context_data( mesaCtx ); + _mesa_free( c ); +} + + + +/* + * XXX this isn't a public function! It's a hack for the 3Dfx driver. + * Create a new XMesaBuffer from an X window. + * Input: v - the XMesaVisual + * w - the window + * c - the context + * Return: new XMesaBuffer or NULL if error + */ +XMesaBuffer +XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c) +{ +#ifndef XFree86Server + XWindowAttributes attr; +#endif +#ifdef FX + char *fxEnvVar; +#endif + int client = 0; + XMesaBuffer b; + XMesaColormap cmap; + + assert(v); + (void) c; + + /* Check that window depth matches visual depth */ +#ifdef XFree86Server + client = CLIENT_ID(((XMesaDrawable)w)->id); + + if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) { + _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", + GET_VISUAL_DEPTH(v), ((XMesaDrawable) w)->depth); + return NULL; + } +#else + XGetWindowAttributes( v->display, w, &attr ); + + if (GET_VISUAL_DEPTH(v) != attr.depth) { + _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", + GET_VISUAL_DEPTH(v), attr.depth); + return NULL; + } +#endif + + /* Find colormap */ +#ifdef XFree86Server + cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP); +#else + if (attr.colormap) { + cmap = attr.colormap; + } + else { + _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w); + /* this is weird, a window w/out a colormap!? */ + /* OK, let's just allocate a new one and hope for the best */ + cmap = XCreateColormap(v->display, w, attr.visual, AllocNone); + } +#endif + + b = alloc_xmesa_buffer(v, WINDOW, cmap); + if (!b) { + return NULL; + } + + if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode, + (XMesaDrawable)w, cmap )) { + free_xmesa_buffer(client, b); + return NULL; + } + +#ifdef FX + fxEnvVar = _mesa_getenv("MESA_GLX_FX"); + if (fxEnvVar) { + if (fxEnvVar[0]!='d') { + int attribs[100]; + int numAttribs = 0; + int hw; + if (v->mesa_visual.depthBits > 0) { + attribs[numAttribs++] = FXMESA_DEPTH_SIZE; + attribs[numAttribs++] = v->mesa_visual.depthBits; + } + if (v->mesa_visual.doubleBufferMode) { + attribs[numAttribs++] = FXMESA_DOUBLEBUFFER; + } + if (v->mesa_visual.accumRedBits > 0) { + attribs[numAttribs++] = FXMESA_ACCUM_SIZE; + attribs[numAttribs++] = v->mesa_visual.accumRedBits; + } + if (v->mesa_visual.stencilBits > 0) { + attribs[numAttribs++] = FXMESA_STENCIL_SIZE; + attribs[numAttribs++] = v->mesa_visual.stencilBits; + } + if (v->mesa_visual.alphaBits > 0) { + attribs[numAttribs++] = FXMESA_ALPHA_SIZE; + attribs[numAttribs++] = v->mesa_visual.alphaBits; + } + if (1) { + attribs[numAttribs++] = FXMESA_SHARE_CONTEXT; + attribs[numAttribs++] = (int) &(c->mesa); + } + attribs[numAttribs++] = FXMESA_NONE; + + /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */ + hw = fxMesaSelectCurrentBoard(0); + + /* if these fail, there's a new bug somewhere */ + ASSERT(b->mesa_buffer.Width > 0); + ASSERT(b->mesa_buffer.Height > 0); + + if ((hw == GR_SSTTYPE_VOODOO) || (hw == GR_SSTTYPE_Voodoo2)) { + b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width, + b->mesa_buffer.Height, attribs); + if ((v->undithered_pf!=PF_Index) && (b->backxrb->ximage)) { + b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE; + if (b->FXctx && (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')) { + b->FXwindowHack = GL_TRUE; + FX_grSstControl(GR_CONTROL_DEACTIVATE); + } + else { + b->FXwindowHack = GL_FALSE; + } + } + } + else { + if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W') + b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE, + GR_REFRESH_75Hz, attribs); + else + b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width, + b->mesa_buffer.Height, attribs); + b->FXisHackUsable = GL_FALSE; + b->FXwindowHack = GL_FALSE; + } + /* + fprintf(stderr, + "voodoo %d, wid %d height %d hack: usable %d active %d\n", + hw, b->mesa_buffer.Width, b->mesa_buffer.Height, + b->FXisHackUsable, b->FXwindowHack); + */ + } + } + else { + _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n"); + _mesa_warning(NULL, " you have not defined the MESA_GLX_FX env. var.\n"); + _mesa_warning(NULL, " (check the README.3DFX file for more information).\n\n"); + _mesa_warning(NULL, " you can disable this message with a 'export MESA_GLX_FX=disable'.\n"); + } +#endif + + return b; +} + + +XMesaBuffer +XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w) +{ + return XMesaCreateWindowBuffer2( v, w, NULL ); +} + + +/** + * Create a new XMesaBuffer from an X pixmap. + * + * \param v the XMesaVisual + * \param p the pixmap + * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or + * \c GLX_DIRECT_COLOR visual for the pixmap + * \returns new XMesaBuffer or NULL if error + */ +XMesaBuffer +XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) +{ + int client = 0; + XMesaBuffer b; + + assert(v); + + b = alloc_xmesa_buffer(v, PIXMAP, cmap); + if (!b) { + return NULL; + } + +#ifdef XFree86Server + client = CLIENT_ID(((XMesaDrawable)p)->id); +#endif + + if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, + (XMesaDrawable)p, cmap)) { + free_xmesa_buffer(client, b); + return NULL; + } + + return b; +} + + + +XMesaBuffer +XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, + unsigned int width, unsigned int height) +{ +#ifdef XFree86Server + return 0; +#else + int client = 0; + XMesaWindow root; + XMesaDrawable drawable; /* X Pixmap Drawable */ + XMesaBuffer b; + + b = alloc_xmesa_buffer(v, PBUFFER, cmap); + if (!b) { + return NULL; + } + + /* allocate pixmap for front buffer */ + root = RootWindow( v->display, v->visinfo->screen ); + drawable = XCreatePixmap( v->display, root, width, height, v->visinfo->depth ); + + if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, + drawable, cmap)) { + free_xmesa_buffer(client, b); + return NULL; + } + + return b; +#endif +} + + + +/* + * Deallocate an XMesaBuffer structure and all related info. + */ +void XMesaDestroyBuffer( XMesaBuffer b ) +{ + int client = 0; + +#ifdef XFree86Server + if (b->frontxrb->drawable) + client = CLIENT_ID(b->frontxrb->drawable->id); +#endif + + if (b->gc) XMesaFreeGC( b->xm_visual->display, b->gc ); + if (b->cleargc) XMesaFreeGC( b->xm_visual->display, b->cleargc ); + if (b->swapgc) XMesaFreeGC( b->xm_visual->display, b->swapgc ); + + if (b->xm_visual->mesa_visual.doubleBufferMode) + { + if (b->backxrb->ximage) { +#if defined(USE_XSHM) && !defined(XFree86Server) + if (b->shm) { + XShmDetach( b->xm_visual->display, &b->shminfo ); + XDestroyImage( b->backxrb->ximage ); + shmdt( b->shminfo.shmaddr ); + } + else +#endif + XMesaDestroyImage( b->backxrb->ximage ); + } + if (b->backxrb->pixmap) { + XMesaFreePixmap( b->xm_visual->display, + (XMesaPixmap) b->backxrb->pixmap ); + if (b->xm_visual->hpcr_clear_flag) { + XMesaFreePixmap( b->xm_visual->display, + b->xm_visual->hpcr_clear_pixmap ); + XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage ); + } + } + } + if (b->rowimage) { + _mesa_free( b->rowimage->data ); + b->rowimage->data = NULL; + XMesaDestroyImage( b->rowimage ); + } + + free_xmesa_buffer(client, b); +} + + + +/* + * Bind buffer b to context c and make c the current rendering context. + */ +GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b ) +{ + return XMesaMakeCurrent2( c, b, b ); +} + + +/* + * Bind buffer b to context c and make c the current rendering context. + */ +GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, + XMesaBuffer readBuffer ) +{ + if (c) { + if (!drawBuffer || !readBuffer) + return GL_FALSE; /* must specify buffers! */ + +#ifdef FX + if (drawBuffer->FXctx) { + fxMesaMakeCurrent(drawBuffer->FXctx); + + c->xm_buffer = drawBuffer; + + return GL_TRUE; + } +#endif + if (&(c->mesa) == _mesa_get_current_context() + && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer + && c->mesa.ReadBuffer == &readBuffer->mesa_buffer + && ((XMesaBuffer) c->mesa.DrawBuffer)->wasCurrent) { + /* same context and buffer, do nothing */ + return GL_TRUE; + } + + c->xm_buffer = drawBuffer; + + _mesa_make_current(&(c->mesa), + &drawBuffer->mesa_buffer, + &readBuffer->mesa_buffer); + + if (c->xm_visual->mesa_visual.rgbMode) { + /* + * Must recompute and set these pixel values because colormap + * can be different for different windows. + */ + c->clearpixel = xmesa_color_to_pixel( &c->mesa, + c->clearcolor[0], + c->clearcolor[1], + c->clearcolor[2], + c->clearcolor[3], + c->xm_visual->undithered_pf); + XMesaSetForeground(c->display, drawBuffer->cleargc, c->clearpixel); + } + + /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ + drawBuffer->wasCurrent = GL_TRUE; + } + else { + /* Detach */ + _mesa_make_current( NULL, NULL, NULL ); + } + return GL_TRUE; +} + + +/* + * Unbind the context c from its buffer. + */ +GLboolean XMesaUnbindContext( XMesaContext c ) +{ + /* A no-op for XFree86 integration purposes */ + return GL_TRUE; +} + + +XMesaContext XMesaGetCurrentContext( void ) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + XMesaContext xmesa = XMESA_CONTEXT(ctx); + return xmesa; + } + else { + return 0; + } +} + + +XMesaBuffer XMesaGetCurrentBuffer( void ) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + return xmbuf; + } + else { + return 0; + } +} + + +/* New in Mesa 3.1 */ +XMesaBuffer XMesaGetCurrentReadBuffer( void ) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + return (XMesaBuffer) (ctx->ReadBuffer); + } + else { + return 0; + } +} + + +GLboolean XMesaForceCurrent(XMesaContext c) +{ + if (c) { + if (&(c->mesa) != _mesa_get_current_context()) { + _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer); + } + } + else { + _mesa_make_current(NULL, NULL, NULL); + } + return GL_TRUE; +} + + +GLboolean XMesaLoseCurrent(XMesaContext c) +{ + (void) c; + _mesa_make_current(NULL, NULL, NULL); + return GL_TRUE; +} + + +/* + * Switch 3Dfx support hack between window and full-screen mode. + */ +GLboolean XMesaSetFXmode( GLint mode ) +{ +#ifdef FX + const char *fx = _mesa_getenv("MESA_GLX_FX"); + if (fx && fx[0] != 'd') { + GET_CURRENT_CONTEXT(ctx); + GrHwConfiguration hw; + if (!FX_grSstQueryHardware(&hw)) { + /*fprintf(stderr, "!grSstQueryHardware\n");*/ + return GL_FALSE; + } + if (hw.num_sst < 1) { + /*fprintf(stderr, "hw.num_sst < 1\n");*/ + return GL_FALSE; + } + if (ctx) { + /* [dBorca] Hack alert: + * oh, this is sooo wrong: ctx above is + * really an fxMesaContext, not an XMesaContext + */ + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + if (mode == XMESA_FX_WINDOW) { + if (xmbuf->FXisHackUsable) { + FX_grSstControl(GR_CONTROL_DEACTIVATE); + xmbuf->FXwindowHack = GL_TRUE; + return GL_TRUE; + } + } + else if (mode == XMESA_FX_FULLSCREEN) { + FX_grSstControl(GR_CONTROL_ACTIVATE); + xmbuf->FXwindowHack = GL_FALSE; + return GL_TRUE; + } + else { + /* Error: Bad mode value */ + } + } + } + /*fprintf(stderr, "fallthrough\n");*/ +#else + (void) mode; +#endif + return GL_FALSE; +} + + + +#ifdef FX +/* + * Read image from VooDoo frame buffer into X/Mesa's back XImage. + */ +static void FXgetImage( XMesaBuffer b ) +{ + GET_CURRENT_CONTEXT(ctx); + static unsigned short pixbuf[MAX_WIDTH]; + GLuint x, y; + int xpos, ypos; + XMesaWindow root; + unsigned int bw, depth, width, height; + XMesaContext xmesa = XMESA_CONTEXT(ctx); + +#ifdef XFree86Server + x = b->frontxrb->pixmap->x; + y = b->frontxrb->pixmap->y; + width = b->frontxrb->pixmap->width; + height = b->frontxrb->pixmap->height; + depth = b->frontxrb->pixmap->depth; +#else + XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap, + &root, &xpos, &ypos, &width, &height, &bw, &depth); +#endif + if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) { + b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width); + b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height); + if (b->mesa_buffer.Width & 1) + b->mesa_buffer.Width--; /* prevent odd width */ + xmesa_alloc_back_buffer(b, b->mesa_buffer.Width, b->mesa_buffer.Height); + } + + /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */ + /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */ + if (b->xm_visual->undithered_pf==PF_5R6G5B) { + /* Special case: 16bpp RGB */ + grLfbReadRegion( GR_BUFFER_FRONTBUFFER, /* src buffer */ + 0, b->FXctx->height - b->mesa_buffer.Height, /*pos*/ + b->mesa_buffer.Width, b->mesa_buffer.Height, /* size */ + b->mesa_buffer.Width * sizeof(GLushort), /* stride */ + b->backxrb->ximage->data); /* dest buffer */ + } + else if (b->xm_visual->dithered_pf==PF_Dither + && GET_VISUAL_DEPTH(b->xm_visual)==8) { + /* Special case: 8bpp RGB */ + for (y=0;y<b->mesa_buffer.Height;y++) { + GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data + + b->backxrb->ximage->bytes_per_line * y; + XDITHER_SETUP(y); + + /* read row from 3Dfx frame buffer */ + grLfbReadRegion( GR_BUFFER_FRONTBUFFER, + 0, b->FXctx->height-(b->mesa_buffer.Height-y), + b->mesa_buffer.Width, 1, + 0, + pixbuf ); + + /* write to XImage back buffer */ + for (x=0;x<b->mesa_buffer.Width;x++) { + GLubyte r = (pixbuf[x] & 0xf800) >> 8; + GLubyte g = (pixbuf[x] & 0x07e0) >> 3; + GLubyte b = (pixbuf[x] & 0x001f) << 3; + *ptr++ = XDITHER( x, r, g, b); + } + } + } + else { + /* General case: slow! */ + for (y=0;y<b->mesa_buffer.Height;y++) { + /* read row from 3Dfx frame buffer */ + grLfbReadRegion( GR_BUFFER_FRONTBUFFER, + 0, b->FXctx->height-(b->mesa_buffer.Height-y), + b->mesa_buffer.Width, 1, + 0, + pixbuf ); + + /* write to XImage back buffer */ + for (x=0;x<b->mesa_buffer.Width;x++) { + XMesaPutPixel(b->backxrb->ximage,x,y, + xmesa_color_to_pixel(ctx, + (pixbuf[x] & 0xf800) >> 8, + (pixbuf[x] & 0x07e0) >> 3, + (pixbuf[x] & 0x001f) << 3, + 0xff, + b->xm_visual->undithered_pf)); + } + } + } + /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */ +} +#endif + + +/* + * Copy the back buffer to the front buffer. If there's no back buffer + * this is a no-op. + */ +void XMesaSwapBuffers( XMesaBuffer b ) +{ + GET_CURRENT_CONTEXT(ctx); + + /* If we're swapping the buffer associated with the current context + * we have to flush any pending rendering commands first. + */ + if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) + _mesa_notifySwapBuffers(ctx); + + if (b->db_state) { +#ifdef FX + if (b->FXctx) { + fxMesaSwapBuffers(); + + if (b->FXwindowHack) + FXgetImage(b); + else + return; + } +#endif + if (b->backxrb->ximage) { + /* Copy Ximage from host's memory to server's window */ +#if defined(USE_XSHM) && !defined(XFree86Server) + if (b->shm) { + /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ + XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, + b->swapgc, + b->backxrb->ximage, 0, 0, + 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height, + False ); + /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ + } + else +#endif + { + /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ + XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable, + b->swapgc, + b->backxrb->ximage, 0, 0, + 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height ); + /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ + } + } + else { + /* Copy pixmap to window on server */ + /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ + XMesaCopyArea( b->xm_visual->display, + b->backxrb->pixmap, /* source drawable */ + b->frontxrb->drawable, /* dest. drawable */ + b->swapgc, + 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height, + 0, 0 /* dest region */ + ); + /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ + } + } +#if !defined(XFree86Server) + XSync( b->xm_visual->display, False ); +#endif +} + + + +/* + * Copy sub-region of back buffer to front buffer + */ +void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) +{ + GET_CURRENT_CONTEXT(ctx); + + /* If we're swapping the buffer associated with the current context + * we have to flush any pending rendering commands first. + */ + if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) + _mesa_notifySwapBuffers(ctx); + + if (b->db_state) { + int yTop = b->mesa_buffer.Height - y - height; +#ifdef FX + if (b->FXctx) { + fxMesaSwapBuffers(); + if (b->FXwindowHack) + FXgetImage(b); + else + return; + } +#endif + if (b->backxrb->ximage) { + /* Copy Ximage from host's memory to server's window */ +#if defined(USE_XSHM) && !defined(XFree86Server) + if (b->shm) { + /* XXX assuming width and height aren't too large! */ + XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, + b->swapgc, + b->backxrb->ximage, x, yTop, + x, yTop, width, height, False ); + /* wait for finished event??? */ + } + else +#endif + { + /* XXX assuming width and height aren't too large! */ + XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable, + b->swapgc, + b->backxrb->ximage, x, yTop, + x, yTop, width, height ); + } + } + else { + /* Copy pixmap to window on server */ + XMesaCopyArea( b->xm_visual->display, + b->backxrb->pixmap, /* source drawable */ + b->frontxrb->drawable, /* dest. drawable */ + b->swapgc, + x, yTop, width, height, /* source region */ + x, yTop /* dest region */ + ); + } + } +} + + +/* + * Return a pointer to the XMesa backbuffer Pixmap or XImage. This function + * is a way to get "under the hood" of X/Mesa so one can manipulate the + * back buffer directly. + * Output: pixmap - pointer to back buffer's Pixmap, or 0 + * ximage - pointer to back buffer's XImage, or NULL + * Return: GL_TRUE = context is double buffered + * GL_FALSE = context is single buffered + */ +#ifndef XFree86Server +GLboolean XMesaGetBackBuffer( XMesaBuffer b, + XMesaPixmap *pixmap, + XMesaImage **ximage ) +{ + if (b->db_state) { + if (pixmap) *pixmap = b->backxrb->pixmap; + if (ximage) *ximage = b->backxrb->ximage; + return GL_TRUE; + } + else { + *pixmap = 0; + *ximage = NULL; + return GL_FALSE; + } +} +#endif /* XFree86Server */ + + +/* + * Return the depth buffer associated with an XMesaBuffer. + * Input: b - the XMesa buffer handle + * Output: width, height - size of buffer in pixels + * bytesPerValue - bytes per depth value (2 or 4) + * buffer - pointer to depth buffer values + * Return: GL_TRUE or GL_FALSE to indicate success or failure. + */ +GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, + GLint *bytesPerValue, void **buffer ) +{ + struct gl_renderbuffer *rb + = b->mesa_buffer.Attachment[BUFFER_DEPTH].Renderbuffer; + if (!rb || !rb->Data) { + *width = 0; + *height = 0; + *bytesPerValue = 0; + *buffer = 0; + return GL_FALSE; + } + else { + *width = b->mesa_buffer.Width; + *height = b->mesa_buffer.Height; + *bytesPerValue = b->mesa_buffer.Visual.depthBits <= 16 + ? sizeof(GLushort) : sizeof(GLuint); + *buffer = rb->Data; + return GL_TRUE; + } +} + + +void XMesaFlush( XMesaContext c ) +{ + if (c && c->xm_visual) { +#ifdef XFree86Server + /* NOT_NEEDED */ +#else + XSync( c->xm_visual->display, False ); +#endif + } +} + + + +const char *XMesaGetString( XMesaContext c, int name ) +{ + (void) c; + if (name==XMESA_VERSION) { + return "5.0"; + } + else if (name==XMESA_EXTENSIONS) { + return ""; + } + else { + return NULL; + } +} + + + +XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d ) +{ + XMesaBuffer b; + for (b=XMesaBufferList; b; b=b->Next) { + if (b->frontxrb->drawable == d && b->display == dpy) { + return b; + } + } + return NULL; +} + + + +/* + * Look for XMesaBuffers whose X window has been destroyed. + * Deallocate any such XMesaBuffers. + */ +void XMesaGarbageCollect( void ) +{ + XMesaBuffer b, next; + for (b=XMesaBufferList; b; b=next) { + next = b->Next; + if (b->display && b->frontxrb->drawable && b->type == WINDOW) { +#ifdef XFree86Server + /* NOT_NEEDED */ +#else + XSync(b->display, False); + if (!window_exists( b->display, b->frontxrb->drawable )) { + /* found a dead window, free the ancillary info */ + XMesaDestroyBuffer( b ); + } +#endif + } + } +} + + +void XMesaReset( void ) +{ + while (XMesaBufferList) + XMesaDestroyBuffer(XMesaBufferList); + + XMesaBufferList = NULL; +} + + +unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, + GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ) +{ + GLcontext *ctx = &xmesa->mesa; + GLint r = (GLint) (red * 255.0F); + GLint g = (GLint) (green * 255.0F); + GLint b = (GLint) (blue * 255.0F); + GLint a = (GLint) (alpha * 255.0F); + + switch (xmesa->pixelformat) { + case PF_Index: + return 0; + case PF_Truecolor: + { + unsigned long p; + PACK_TRUECOLOR( p, r, g, b ); + return p; + } + case PF_8A8B8G8R: + return PACK_8A8B8G8R( r, g, b, a ); + case PF_8A8R8G8B: + return PACK_8A8R8G8B( r, g, b, a ); + case PF_8R8G8B: + return PACK_8R8G8B( r, g, b ); + case PF_5R6G5B: + return PACK_5R6G5B( r, g, b ); + case PF_Dither: + { + DITHER_SETUP; + return DITHER( x, y, r, g, b ); + } + case PF_1Bit: + /* 382 = (3*255)/2 */ + return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip; + case PF_HPCR: + return DITHER_HPCR(x, y, r, g, b); + case PF_Lookup: + { + LOOKUP_SETUP; + return LOOKUP( r, g, b ); + } + case PF_Grayscale: + return GRAY_RGB( r, g, b ); + case PF_Dither_5R6G5B: + /* fall through */ + case PF_Dither_True: + { + unsigned long p; + PACK_TRUEDITHER(p, x, y, r, g, b); + return p; + } + default: + _mesa_problem(NULL, "Bad pixel format in XMesaDitherColor"); + } + return 0; +} + + +/* + * This is typically called when the window size changes and we need + * to reallocate the buffer's back/depth/stencil/accum buffers. + */ +void XMesaResizeBuffers( XMesaBuffer b ) +{ +#ifdef XFree86Server + GLuint winwidth, winheight; + GET_CURRENT_CONTEXT(ctx); + + winwidth = MIN2(b->frontxrb->drawable->width, MAX_WIDTH); + winheight = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT); + + xmesa_resize_buffers(ctx, &(b->mesa_buffer), winwidth, winheight); +#else + Window root; + int xpos, ypos; + unsigned int width, height, bw, depth; + GET_CURRENT_CONTEXT(ctx); + XGetGeometry( b->xm_visual->display, b->frontxrb->pixmap, + &root, &xpos, &ypos, &width, &height, &bw, &depth); + xmesa_resize_buffers(ctx, &(b->mesa_buffer), width, height); +#endif +} + diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_buffer.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_buffer.c new file mode 100644 index 000000000..593ac2bb1 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_buffer.c @@ -0,0 +1,115 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 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. + */ + + +#include "glxheader.h" +#include "GL/xmesa.h" +#include "xmesaP.h" +#include "imports.h" +#include "renderbuffer.h" + + +static void +xmesa_delete_renderbuffer(struct gl_renderbuffer *rb) +{ + /* XXX Note: the ximage or Pixmap attached to this renderbuffer + * should probably get freed here, but that's currently done in + * XMesaDestroyBuffer(). + */ + _mesa_free(rb); +} + + +/** + * Reallocate renderbuffer storage. + * This is called when the window's resized. It'll get called once for + * the front color renderbuffer and again for the back color renderbuffer. + */ +static GLboolean +xmesa_alloc_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + + if (xrb->ximage) { + /* Needed by PIXELADDR1 macro */ + xrb->width1 = xrb->ximage->bytes_per_line; + xrb->origin1 = (GLubyte *) xrb->ximage->data + xrb->width1 * (height - 1); + + /* Needed by PIXELADDR2 macro */ + xrb->width2 = xrb->ximage->bytes_per_line / 2; + xrb->origin2 = (GLushort *) xrb->ximage->data + xrb->width2 * (height - 1); + + /* Needed by PIXELADDR3 macro */ + xrb->width3 = xrb->ximage->bytes_per_line; + xrb->origin3 = (GLubyte *) xrb->ximage->data + xrb->width3 * (height - 1); + + /* Needed by PIXELADDR4 macro */ + xrb->width4 = xrb->ximage->width; + xrb->origin4 = (GLuint *) xrb->ximage->data + xrb->width4 * (height - 1); + } + else { + assert(xrb->pixmap); + } + + /* for the FLIP macro: */ + xrb->bottom = height - 1; + + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + + return GL_TRUE; +} + + +struct xmesa_renderbuffer * +xmesa_new_renderbuffer(GLcontext *ctx, GLuint name, GLboolean rgbMode) +{ + struct xmesa_renderbuffer *xrb = CALLOC_STRUCT(xmesa_renderbuffer); + if (xrb) { + GLuint name = 0; + _mesa_init_renderbuffer(&xrb->Base, name); + + xrb->Base.Delete = xmesa_delete_renderbuffer; + xrb->Base.AllocStorage = xmesa_alloc_storage; + + if (rgbMode) { + xrb->Base.InternalFormat = GL_RGBA; + xrb->Base._BaseFormat = GL_RGBA; + xrb->Base.DataType = GL_UNSIGNED_BYTE; + } + else { + xrb->Base.InternalFormat = GL_COLOR_INDEX; + xrb->Base._BaseFormat = GL_COLOR_INDEX; + xrb->Base.DataType = GL_UNSIGNED_INT; + } + xrb->Base.ComponentSizes[0] = 0; /* XXX fix? */ + } + return xrb; +} + + + + diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_dd.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_dd.c new file mode 100644 index 000000000..bc16a7bd4 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_dd.c @@ -0,0 +1,1201 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 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. + */ + + +#include "glxheader.h" +#include "bufferobj.h" +#include "buffers.h" +#include "context.h" +#include "colormac.h" +#include "depth.h" +#include "drawpix.h" +#include "extensions.h" +#include "framebuffer.h" +#include "macros.h" +#include "image.h" +#include "imports.h" +#include "mtypes.h" +#include "state.h" +#include "texobj.h" +#include "teximage.h" +#include "texstore.h" +#include "texformat.h" +#include "xmesaP.h" +#include "array_cache/acache.h" +#include "swrast/swrast.h" +#include "swrast/s_context.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" + +#ifdef XFree86Server +#include <GL/glxtokens.h> +#endif + + + +/* + * Dithering kernels and lookup tables. + */ + +const int xmesa_kernel8[DITH_DY * DITH_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, +}; + +const short xmesa_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} + } +}; + +const int xmesa_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 +}; + + +/* + * Return the size (width, height) of the X window for the given GLframebuffer. + * Output: width - width of buffer in pixels. + * height - height of buffer in pixels. + */ +static void +get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) +{ + /* We can do this cast because the first field in the XMesaBuffer + * struct is a GLframebuffer struct. If this weren't true, we'd + * need a pointer from the GLframebuffer to the XMesaBuffer. + */ + const XMesaBuffer xmBuffer = (XMesaBuffer) buffer; + unsigned int winwidth, winheight; +#ifdef XFree86Server + /* XFree86 GLX renderer */ + winwidth = MIN2(xmBuffer->frontxrb->drawable->width, MAX_WIDTH); + winheight = MIN2(xmBuffer->frontxrb->drawable->height, MAX_HEIGHT); +#else + Window root; + int winx, winy; + unsigned int bw, d; + + _glthread_LOCK_MUTEX(_xmesa_lock); + XSync(xmBuffer->xm_visual->display, 0); /* added for Chromium */ + XGetGeometry( xmBuffer->xm_visual->display, xmBuffer->frontxrb->pixmap, &root, + &winx, &winy, &winwidth, &winheight, &bw, &d ); + _glthread_UNLOCK_MUTEX(_xmesa_lock); +#endif + + *width = winwidth; + *height = winheight; +} + + +static void +finish_or_flush( GLcontext *ctx ) +{ +#ifdef XFree86Server + /* NOT_NEEDED */ +#else + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + if (xmesa) { + _glthread_LOCK_MUTEX(_xmesa_lock); + XSync( xmesa->display, False ); + _glthread_UNLOCK_MUTEX(_xmesa_lock); + } +#endif +} + + +static void +clear_index( GLcontext *ctx, GLuint index ) +{ + if (ctx->DrawBuffer->Name == 0) { + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + xmesa->clearpixel = (unsigned long) index; + XMesaSetForeground( xmesa->display, xmbuf->cleargc, (unsigned long) index ); + } +} + + +static void +clear_color( GLcontext *ctx, const GLfloat color[4] ) +{ + if (ctx->DrawBuffer->Name == 0) { + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); + xmesa->clearpixel = xmesa_color_to_pixel( ctx, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2], + xmesa->clearcolor[3], + xmesa->xm_visual->undithered_pf ); + _glthread_LOCK_MUTEX(_xmesa_lock); + XMesaSetForeground( xmesa->display, xmbuf->cleargc, + xmesa->clearpixel ); + _glthread_UNLOCK_MUTEX(_xmesa_lock); + } +} + + + +/* Set index mask ala glIndexMask */ +static void +index_mask( GLcontext *ctx, GLuint mask ) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + /* not sure this conditional is really needed */ + if (xmbuf->backxrb && xmbuf->backxrb->pixmap) { + unsigned long m; + if (mask==0xffffffff) { + m = ((unsigned long)~0L); + } + else { + m = (unsigned long) mask; + } + XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); + XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m ); + } +} + + +/* Implements glColorMask() */ +static void +color_mask(GLcontext *ctx, + GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + const int xclass = xmesa->xm_visual->mesa_visual.visualType; + (void) amask; + + if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { + unsigned long m; + if (rmask && gmask && bmask) { + m = ((unsigned long)~0L); + } + else { + m = 0; + if (rmask) m |= GET_REDMASK(xmesa->xm_visual); + if (gmask) m |= GET_GREENMASK(xmesa->xm_visual); + if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual); + } + XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); + XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m ); + } +} + + + +/**********************************************************************/ +/*** glClear implementations ***/ +/**********************************************************************/ + + +/** + * Clear the front or back color buffer, if it's implemented with a pixmap. + */ +static void +clear_pixmap(GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLboolean all, + GLint x, GLint y, GLint width, GLint height) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + + assert(xmbuf); + assert(xrb->pixmap); + assert(xmesa); + assert(xmesa->display); + assert(xrb->pixmap); + assert(xmbuf->cleargc); + + if (all) { + XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc, + 0, 0, xrb->Base.Width + 1, xrb->Base.Height + 1 ); + } + else { + XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc, + x, xrb->Base.Height - y - height, + width, height ); + } +} + + +static void +clear_8bit_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLboolean all, GLint x, GLint y, GLint width, GLint height ) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + + if (all) { + const size_t n = xrb->ximage->bytes_per_line * xrb->Base.Height; + MEMSET( xrb->ximage->data, xmesa->clearpixel, n ); + } + else { + GLint i; + for (i=0;i<height;i++) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x, y + i); + MEMSET( ptr, xmesa->clearpixel, width ); + } + } +} + + +static void +clear_HPCR_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLboolean all, GLint x, GLint y, GLint width, GLint height ) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + + if (all) { + GLint i, c16 = (xrb->ximage->bytes_per_line>>4)<<4; + GLubyte *ptr = (GLubyte *) xrb->ximage->data; + for (i = 0; i < xrb->Base.Height; i++) { + GLint j; + GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; + if (i&1) { + sptr += 16; + } + for (j=0; j<c16; j+=16) { + ptr[0] = sptr[0]; + ptr[1] = sptr[1]; + ptr[2] = sptr[2]; + ptr[3] = sptr[3]; + ptr[4] = sptr[4]; + ptr[5] = sptr[5]; + ptr[6] = sptr[6]; + ptr[7] = sptr[7]; + ptr[8] = sptr[8]; + ptr[9] = sptr[9]; + ptr[10] = sptr[10]; + ptr[11] = sptr[11]; + ptr[12] = sptr[12]; + ptr[13] = sptr[13]; + ptr[14] = sptr[14]; + ptr[15] = sptr[15]; + ptr += 16; + } + for (; j < xrb->ximage->bytes_per_line; j++) { + *ptr = sptr[j&15]; + ptr++; + } + } + } + else { + GLint i; + for (i=y; i<y+height; i++) { + GLubyte *ptr = PIXEL_ADDR1( xrb, x, i ); + int j; + const GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; + if (i&1) { + sptr += 16; + } + for (j=x; j<x+width; j++) { + *ptr = sptr[j&15]; + ptr++; + } + } + } +} + + +static void +clear_16bit_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLboolean all, GLint x, GLint y, GLint width, GLint height) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + register GLuint pixel = (GLuint) xmesa->clearpixel; + + if (xmesa->swapbytes) { + pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00); + } + + if (all) { + GLuint *ptr4 = (GLuint *) xrb->ximage->data; + if ((pixel & 0xff) == ((pixel >> 8) & 0xff)) { + /* low and high bytes are equal so use memset() */ + const GLuint n = xrb->ximage->bytes_per_line * xrb->Base.Height; + MEMSET( ptr4, pixel & 0xff, n ); + } + else { + const GLuint n = xrb->ximage->bytes_per_line * xrb->Base.Height / 4; + GLuint i; + pixel = pixel | (pixel<<16); + for (i = 0; i < n; i++) { + ptr4[i] = pixel; + } + ptr4 += n; + /* might be one last GLushort to set */ + if ((xrb->ximage->bytes_per_line * xrb->Base.Height) & 0x2) + *(GLushort *)ptr4 = pixel & 0xffff; + } + } + else { + GLint i, j; + for (j=0;j<height;j++) { + GLushort *ptr2 = PIXEL_ADDR2(xrb, x, y + j); + for (i=0;i<width;i++) { + *ptr2++ = pixel; + } + } + } +} + + +/* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */ +static void +clear_24bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLboolean all, GLint x, GLint y, GLint width, GLint height) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + const GLubyte r = xmesa->clearcolor[0]; + const GLubyte g = xmesa->clearcolor[1]; + const GLubyte b = xmesa->clearcolor[2]; + + if (all) { + if (r == g && g == b) { + /* same value for all three components (gray) */ + const GLint w3 = xrb->Base.Width * 3; + const GLint h = xrb->Base.Height; + GLint i; + for (i = 0; i < h; i++) { + bgr_t *ptr3 = PIXEL_ADDR3(xrb, 0, i); + MEMSET(ptr3, r, w3); + } + } + else { + /* the usual case */ + const GLint w = xrb->Base.Width; + const GLint h = xrb->Base.Height; + GLint i, j; + for (i = 0; i < h; i++) { + bgr_t *ptr3 = PIXEL_ADDR3(xrb, 0, i); + for (j = 0; j < w; j++) { + ptr3->r = r; + ptr3->g = g; + ptr3->b = b; + ptr3++; + } + } + } + } + else { + /* only clear subrect of color buffer */ + if (r == g && g == b) { + /* same value for all three components (gray) */ + GLint j; + for (j=0;j<height;j++) { + bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); + MEMSET(ptr3, r, 3 * width); + } + } + else { + /* non-gray clear color */ + GLint i, j; + for (j = 0; j < height; j++) { + bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); + for (i = 0; i < width; i++) { + ptr3->r = r; + ptr3->g = g; + ptr3->b = b; + ptr3++; + } + } + } + } +} + + +static void +clear_32bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLboolean all, GLint x, GLint y, GLint width, GLint height) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + register GLuint pixel = (GLuint) xmesa->clearpixel; + + if (xmesa->swapbytes) { + pixel = ((pixel >> 24) & 0x000000ff) + | ((pixel >> 8) & 0x0000ff00) + | ((pixel << 8) & 0x00ff0000) + | ((pixel << 24) & 0xff000000); + } + + if (all) { + const GLuint n = xrb->Base.Width * xrb->Base.Height; + GLuint *ptr4 = (GLuint *) xrb->ximage->data; + if (pixel == 0) { + _mesa_memset(ptr4, pixel, 4 * n); + } + else { + GLuint i; + for (i = 0; i < n; i++) + ptr4[i] = pixel; + } + } + else { + GLint i, j; + for (j = 0; j < height; j++) { + GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y + j); + for (i = 0; i < width; i++) { + ptr4[i] = pixel; + } + } + } +} + + +static void +clear_nbit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLboolean all, GLint x, GLint y, GLint width, GLint height) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaImage *img = xrb->ximage; + GLint i, j; + + /* We can ignore 'all' here - x, y, width, height are always right */ + (void) all; + + /* TODO: optimize this */ + y = YFLIP(xrb, y); + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + XMesaPutPixel(img, x+i, y-j, xmesa->clearpixel); + } + } +} + + + +static void +clear_buffers( GLcontext *ctx, GLbitfield mask, + GLboolean all, GLint x, GLint y, GLint width, GLint height ) +{ + if (ctx->DrawBuffer->Name == 0) { + /* this is a window system framebuffer */ + const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; + XMesaBuffer b = (XMesaBuffer) ctx->DrawBuffer; + + /* we can't handle color or index masking */ + if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { + if (mask & BUFFER_BIT_FRONT_LEFT) { + /* clear front color buffer */ + if (b->frontxrb == (struct xmesa_renderbuffer *) + ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer) { + /* renderbuffer is not wrapped - great! */ + b->frontxrb->clearFunc(ctx, b->frontxrb, all, x, y, + width, height); + mask &= ~BUFFER_BIT_FRONT_LEFT; + } + else { + /* we can't directly clear an alpha-wrapped color buffer */ + } + } + if (mask & BUFFER_BIT_BACK_LEFT) { + /* clear back color buffer */ + if (b->backxrb == (struct xmesa_renderbuffer *) + ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer) { + /* renderbuffer is not wrapped - great! */ + b->backxrb->clearFunc(ctx, b->backxrb, all, x, y, + width, height); + mask &= ~BUFFER_BIT_BACK_LEFT; + } + } + } + } + if (mask) + _swrast_Clear( ctx, mask, all, x, y, width, height ); +} + + +/** + * Called by ctx->Driver.ResizeBuffers() + * Resize the front/back colorbuffers to match the latest window size. + */ +void +xmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, + GLuint width, GLuint height) +{ + /* We can do this cast because the first field in the XMesaBuffer + * struct is a GLframebuffer struct. If this weren't true, we'd + * need a pointer from the GLframebuffer to the XMesaBuffer. + */ + XMesaBuffer xmBuffer = (XMesaBuffer) buffer; + + xmesa_alloc_back_buffer(xmBuffer, width, height); + + _mesa_resize_framebuffer(ctx, buffer, width, height); + + if (ctx) + ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ +} + + +#ifndef XFree86Server +/* XXX this was never tested in the Xserver environment */ + +/** + * This function implements glDrawPixels() with an XPutImage call when + * drawing to the front buffer (X Window drawable). + * The image format must be GL_BGRA to match the PF_8R8G8B pixel format. + */ +static void +xmesa_DrawPixels_8R8G8B( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + struct xmesa_renderbuffer *xrb + = (struct xmesa_renderbuffer *) ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + const SWcontext *swrast = SWRAST_CONTEXT( ctx ); + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + const XMesaGC gc = xmbuf->gc; + + ASSERT(dpy); + ASSERT(gc); + ASSERT(xmesa->xm_visual->dithered_pf == PF_8R8G8B); + ASSERT(xmesa->xm_visual->undithered_pf == PF_8R8G8B); + + if (swrast->NewState) + _swrast_validate_derived( ctx ); + + if (xrb->pixmap && + format == GL_BGRA && + type == GL_UNSIGNED_BYTE && + (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */ + ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ + ctx->Pixel.ZoomX == 1.0 && /* no zooming */ + ctx->Pixel.ZoomY == 1.0) { + int dstX = x; + int dstY = y; + int w = width; + int h = height; + int srcX = unpack->SkipPixels; + int srcY = unpack->SkipRows; + int rowLength = unpack->RowLength ? unpack->RowLength : width; + + if (unpack->BufferObj->Name) { + /* unpack from PBO */ + GLubyte *buf; + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawPixels(invalid PBO access)"); + return; + } + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, + GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY_ARB, + unpack->BufferObj); + if (!buf) { + /* buffer is already mapped - that's an error */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawPixels(PBO is mapped)"); + return; + } + pixels = ADD_POINTERS(buf, pixels); + } + + if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) { + /* This is a little tricky since all coordinates up to now have + * been in the OpenGL bottom-to-top orientation. X is top-to-bottom + * so we have to carefully compute the Y coordinates/addresses here. + */ + XMesaImage ximage; + MEMSET(&ximage, 0, sizeof(XMesaImage)); + ximage.width = width; + ximage.height = height; + ximage.format = ZPixmap; + ximage.data = (char *) pixels + + ((srcY + h - 1) * rowLength + srcX) * 4; + ximage.byte_order = LSBFirst; + ximage.bitmap_unit = 32; + ximage.bitmap_bit_order = LSBFirst; + ximage.bitmap_pad = 32; + ximage.depth = 24; + ximage.bytes_per_line = -rowLength * 4; /* negative to flip image */ + ximage.bits_per_pixel = 32; + /* it seems we don't need to set the ximage.red/green/blue_mask fields */ + /* flip Y axis for dest position */ + dstY = YFLIP(xrb, dstY) - h + 1; + XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); + } + + if (unpack->BufferObj->Name) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + unpack->BufferObj); + } + } + else { + /* software fallback */ + _swrast_DrawPixels(ctx, x, y, width, height, + format, type, unpack, pixels); + } +} + + + +/** + * This function implements glDrawPixels() with an XPutImage call when + * drawing to the front buffer (X Window drawable). The image format + * must be GL_RGB and image type must be GL_UNSIGNED_SHORT_5_6_5 to + * match the PF_5R6G5B pixel format. + */ +static void +xmesa_DrawPixels_5R6G5B( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + struct xmesa_renderbuffer *xrb + = (struct xmesa_renderbuffer *) ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + const SWcontext *swrast = SWRAST_CONTEXT( ctx ); + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + const XMesaGC gc = xmbuf->gc; + + ASSERT(dpy); + ASSERT(gc); + ASSERT(xmesa->xm_visual->undithered_pf == PF_5R6G5B); + + if (swrast->NewState) + _swrast_validate_derived( ctx ); + + if (xrb->pixmap && + format == GL_RGB && + type == GL_UNSIGNED_SHORT_5_6_5 && + !ctx->Color.DitherFlag && /* no dithering */ + (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */ + ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ + ctx->Pixel.ZoomX == 1.0 && /* no zooming */ + ctx->Pixel.ZoomY == 1.0) { + int dstX = x; + int dstY = y; + int w = width; + int h = height; + int srcX = unpack->SkipPixels; + int srcY = unpack->SkipRows; + int rowLength = unpack->RowLength ? unpack->RowLength : width; + + if (unpack->BufferObj->Name) { + /* unpack from PBO */ + GLubyte *buf; + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawPixels(invalid PBO access)"); + return; + } + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, + GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY_ARB, + unpack->BufferObj); + if (!buf) { + /* buffer is already mapped - that's an error */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawPixels(PBO is mapped)"); + return; + } + pixels = ADD_POINTERS(buf, pixels); + } + + if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) { + /* This is a little tricky since all coordinates up to now have + * been in the OpenGL bottom-to-top orientation. X is top-to-bottom + * so we have to carefully compute the Y coordinates/addresses here. + */ + XMesaImage ximage; + MEMSET(&ximage, 0, sizeof(XMesaImage)); + ximage.width = width; + ximage.height = height; + ximage.format = ZPixmap; + ximage.data = (char *) pixels + + ((srcY + h - 1) * rowLength + srcX) * 2; + ximage.byte_order = LSBFirst; + ximage.bitmap_unit = 16; + ximage.bitmap_bit_order = LSBFirst; + ximage.bitmap_pad = 16; + ximage.depth = 16; + ximage.bytes_per_line = -rowLength * 2; /* negative to flip image */ + ximage.bits_per_pixel = 16; + /* it seems we don't need to set the ximage.red/green/blue_mask fields */ + /* flip Y axis for dest position */ + dstY = YFLIP(xrb, dstY) - h + 1; + XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); + } + + if (unpack->BufferObj->Name) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + unpack->BufferObj); + } + } + else { + /* software fallback */ + _swrast_DrawPixels(ctx, x, y, width, height, + format, type, unpack, pixels); + } +} + + + +/** + * Implement glCopyPixels for the front color buffer (or back buffer Pixmap) + * for the color buffer. Don't support zooming, pixel transfer, etc. + * We do support copying from one window to another, ala glXMakeCurrentRead. + */ +static void +xmesa_CopyPixels( GLcontext *ctx, + GLint srcx, GLint srcy, GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type ) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + const SWcontext *swrast = SWRAST_CONTEXT( ctx ); + XMesaDisplay *dpy = xmesa->xm_visual->display; + const XMesaGC gc = ((XMesaBuffer) ctx->DrawBuffer)->gc; + struct xmesa_renderbuffer *srcXrb = (struct xmesa_renderbuffer *) + ctx->ReadBuffer->_ColorReadBuffer; + struct xmesa_renderbuffer *dstXrb = (struct xmesa_renderbuffer *) + ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + + ASSERT(dpy); + ASSERT(gc); + + if (swrast->NewState) + _swrast_validate_derived( ctx ); + + if (ctx->Color.DrawBuffer[0] == GL_FRONT && + ctx->Pixel.ReadBuffer == GL_FRONT && + srcXrb->pixmap && + dstXrb->pixmap && + type == GL_COLOR && + (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */ + ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ + ctx->Pixel.ZoomX == 1.0 && /* no zooming */ + ctx->Pixel.ZoomY == 1.0) { + /* Note: we don't do any special clipping work here. We could, + * but X will do it for us. + */ + srcy = YFLIP(srcXrb, srcy) - height + 1; + desty = YFLIP(dstXrb, desty) - height + 1; + XCopyArea(dpy, srcXrb->pixmap, dstXrb->pixmap, gc, + srcx, srcy, width, height, destx, desty); + } + else { + _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type ); + } +} +#endif /* XFree86Server */ + + + +/* + * Every driver should implement a GetString function in order to + * return a meaningful GL_RENDERER string. + */ +static const GLubyte * +get_string( GLcontext *ctx, GLenum name ) +{ + (void) ctx; + switch (name) { + case GL_RENDERER: +#ifdef XFree86Server + return (const GLubyte *) "Mesa GLX Indirect"; +#else + return (const GLubyte *) "Mesa X11"; +#endif + case GL_VENDOR: +#ifdef XFree86Server + return (const GLubyte *) "Mesa project: www.mesa3d.org"; +#else + return NULL; +#endif + default: + return NULL; + } +} + + +/* + * We implement the glEnable function only because we care about + * dither enable/disable. + */ +static void +enable( GLcontext *ctx, GLenum pname, GLboolean state ) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + + switch (pname) { + case GL_DITHER: + if (state) + xmesa->pixelformat = xmesa->xm_visual->dithered_pf; + else + xmesa->pixelformat = xmesa->xm_visual->undithered_pf; + break; + default: + ; /* silence compiler warning */ + } +} + + +static void +clear_color_HPCR_ximage( GLcontext *ctx, const GLfloat color[4] ) +{ + int i; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); + + if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) { + /* black is black */ + MEMSET( xmesa->xm_visual->hpcr_clear_ximage_pattern, 0x0 , + sizeof(xmesa->xm_visual->hpcr_clear_ximage_pattern)); + } + else { + /* build clear pattern */ + for (i=0; i<16; i++) { + xmesa->xm_visual->hpcr_clear_ximage_pattern[0][i] = + DITHER_HPCR(i, 0, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2]); + xmesa->xm_visual->hpcr_clear_ximage_pattern[1][i] = + DITHER_HPCR(i, 1, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2]); + } + } +} + + +static void +clear_color_HPCR_pixmap( GLcontext *ctx, const GLfloat color[4] ) +{ + int i; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); + + if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) { + /* black is black */ + for (i=0; i<16; i++) { + XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 0, 0); + XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 1, 0); + } + } + else { + for (i=0; i<16; i++) { + XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 0, + DITHER_HPCR(i, 0, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2])); + XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 1, + DITHER_HPCR(i, 1, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2])); + } + } + /* change tile pixmap content */ + XMesaPutImage(xmesa->display, + (XMesaDrawable)xmesa->xm_visual->hpcr_clear_pixmap, + XMESA_BUFFER(ctx->DrawBuffer)->cleargc, + xmesa->xm_visual->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2); +} + + +/** + * Called when the driver should update it's state, based on the new_state + * flags. + */ +void +xmesa_update_state( GLcontext *ctx, GLuint new_state ) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *front_xrb, *back_xrb; + + /* Propagate statechange information to swrast and swrast_setup + * modules. The X11 driver has no internal GL-dependent state. + */ + _swrast_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + + if (ctx->DrawBuffer->Name != 0) + return; + + front_xrb = XMESA_BUFFER(ctx->DrawBuffer)->frontxrb; + if (front_xrb) { + /* XXX check for relevant new_state flags */ + xmesa_set_renderbuffer_funcs(front_xrb, xmesa->pixelformat, + xmesa->xm_visual->BitsPerPixel); + /* setup pointers to front and back buffer clear functions */ + front_xrb->clearFunc = clear_pixmap; + } + + back_xrb = XMESA_BUFFER(ctx->DrawBuffer)->backxrb; + if (back_xrb) { + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + + /* XXX check for relevant new_state flags */ + xmesa_set_renderbuffer_funcs(back_xrb, xmesa->pixelformat, + xmesa->xm_visual->BitsPerPixel); + + if (xmbuf->backxrb->pixmap) { + back_xrb->clearFunc = clear_pixmap; + } + else { + switch (xmesa->xm_visual->BitsPerPixel) { + case 8: + if (xmesa->xm_visual->hpcr_clear_flag) { + back_xrb->clearFunc = clear_HPCR_ximage; + } + else { + back_xrb->clearFunc = clear_8bit_ximage; + } + break; + case 16: + back_xrb->clearFunc = clear_16bit_ximage; + break; + case 24: + back_xrb->clearFunc = clear_24bit_ximage; + break; + case 32: + back_xrb->clearFunc = clear_32bit_ximage; + break; + default: + back_xrb->clearFunc = clear_nbit_ximage; + break; + } + } + } + + if (xmesa->xm_visual->hpcr_clear_flag) { + /* this depends on whether we're drawing to the front or back buffer */ + /* XXX FIX THIS! */ +#if 0 + if (pixmap) { + ctx->Driver.ClearColor = clear_color_HPCR_pixmap; + } + else { + ctx->Driver.ClearColor = clear_color_HPCR_ximage; + } +#else + (void) clear_color_HPCR_pixmap; + (void) clear_color_HPCR_ximage; +#endif + } +} + + + +/** + * Called via ctx->Driver.TestProxyTeximage(). Normally, we'd just use + * the _mesa_test_proxy_teximage() fallback function, but we're going to + * special-case the 3D texture case to allow textures up to 512x512x32 + * texels. + */ +static GLboolean +test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, GLenum format, GLenum type, + GLint width, GLint height, GLint depth, GLint border) +{ + if (target == GL_PROXY_TEXTURE_3D) { + /* special case for 3D textures */ + if (width * height * depth > 512 * 512 * 64 || + width < 2 * border || + (!ctx->Extensions.ARB_texture_non_power_of_two && + _mesa_bitcount(width - 2 * border) != 1) || + height < 2 * border || + (!ctx->Extensions.ARB_texture_non_power_of_two && + _mesa_bitcount(height - 2 * border) != 1) || + depth < 2 * border || + (!ctx->Extensions.ARB_texture_non_power_of_two && + _mesa_bitcount(depth - 2 * border) != 1)) { + /* Bad size, or too many texels */ + return GL_FALSE; + } + return GL_TRUE; + } + else { + /* use the fallback routine for 1D, 2D, cube and rect targets */ + return _mesa_test_proxy_teximage(ctx, target, level, internalFormat, + format, type, width, height, depth, + border); + } +} + + +/** + * In SW, we don't really compress GL_COMPRESSED_RGB[A] textures! + */ +static const struct gl_texture_format * +choose_tex_format( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) +{ + switch (internalFormat) { + case GL_COMPRESSED_RGB_ARB: + return &_mesa_texformat_rgb; + case GL_COMPRESSED_RGBA_ARB: + return &_mesa_texformat_rgba; + default: + return _mesa_choose_tex_format(ctx, internalFormat, format, type); + } +} + + +/** + * Called by glViewport. + * This is a good time for us to poll the current X window size and adjust + * our renderbuffers to match the current window size. + * Remember, we have no opportunity to respond to conventional + * X Resize/StructureNotify events since the X driver has no event loop. + * Thus, we poll. + * Note that this trick isn't fool-proof. If the application never calls + * glViewport, our notion of the current window size may be incorrect. + */ +static void +xmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ +#if 1 + struct gl_framebuffer *fb = ctx->WinSysDrawBuffer; + GLuint newWidth, newHeight; + + get_buffer_size(fb, &newWidth, &newHeight); + if (newWidth != fb->Width || newHeight != fb->Height) { + xmesa_resize_buffers(ctx, fb, newWidth, newHeight); + } +#else + /* This also works: */ + _mesa_ResizeBuffersMESA(); +#endif +} + + +/** + * Initialize the device driver function table with the functions + * we implement in this driver. + */ +void +xmesa_init_driver_functions( XMesaVisual xmvisual, + struct dd_function_table *driver ) +{ + driver->GetString = get_string; + driver->UpdateState = xmesa_update_state; + driver->GetBufferSize = get_buffer_size; + driver->Flush = finish_or_flush; + driver->Finish = finish_or_flush; + driver->ClearIndex = clear_index; + driver->ClearColor = clear_color; + driver->IndexMask = index_mask; + driver->ColorMask = color_mask; + driver->Enable = enable; + driver->Clear = clear_buffers; + driver->ResizeBuffers = xmesa_resize_buffers; + driver->Viewport = xmesa_viewport; +#ifndef XFree86Server + driver->CopyPixels = xmesa_CopyPixels; + if (xmvisual->undithered_pf == PF_8R8G8B && + xmvisual->dithered_pf == PF_8R8G8B) { + driver->DrawPixels = xmesa_DrawPixels_8R8G8B; + } + else if (xmvisual->undithered_pf == PF_5R6G5B) { + driver->DrawPixels = xmesa_DrawPixels_5R6G5B; + } +#endif + driver->TestProxyTexImage = test_proxy_teximage; +#if SWTC + driver->ChooseTextureFormat = choose_tex_format; +#else + (void) choose_tex_format; +#endif +} + + +#define XMESA_NEW_POINT (_NEW_POINT | \ + _NEW_RENDERMODE | \ + _SWRAST_NEW_RASTERMASK) + +#define XMESA_NEW_LINE (_NEW_LINE | \ + _NEW_TEXTURE | \ + _NEW_LIGHT | \ + _NEW_DEPTH | \ + _NEW_RENDERMODE | \ + _SWRAST_NEW_RASTERMASK) + +#define XMESA_NEW_TRIANGLE (_NEW_POLYGON | \ + _NEW_TEXTURE | \ + _NEW_LIGHT | \ + _NEW_DEPTH | \ + _NEW_RENDERMODE | \ + _SWRAST_NEW_RASTERMASK) + + +/* Extend the software rasterizer with our line/point/triangle + * functions. + */ +void xmesa_register_swrast_functions( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT( ctx ); + + swrast->choose_point = xmesa_choose_point; + swrast->choose_line = xmesa_choose_line; + swrast->choose_triangle = xmesa_choose_triangle; + + swrast->invalidate_point |= XMESA_NEW_POINT; + swrast->invalidate_line |= XMESA_NEW_LINE; + swrast->invalidate_triangle |= XMESA_NEW_TRIANGLE; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_line.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_line.c new file mode 100644 index 000000000..d7c59739d --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_line.c @@ -0,0 +1,674 @@ +/* + * Mesa 3-D graphics library + * Version: 6.4 + * + * Copyright (C) 1999-2005 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. + */ + + +/* + * This file contains "accelerated" point, line, and triangle functions. + * It should be fairly easy to write new special-purpose point, line or + * triangle functions and hook them into this module. + */ + + +#include "glxheader.h" +#include "depth.h" +#include "macros.h" +#include "mtypes.h" +#include "xmesaP.h" + +/* Internal swrast includes: + */ +#include "swrast/s_depth.h" +#include "swrast/s_points.h" +#include "swrast/s_lines.h" +#include "swrast/s_context.h" + + +/**********************************************************************/ +/*** Point rendering ***/ +/**********************************************************************/ + + +/* + * Render an array of points into a pixmap, any pixel format. + */ +#if 000 +/* XXX don't use this, it doesn't dither correctly */ +static void draw_points_ANY_pixmap( GLcontext *ctx, const SWvertex *vert ) +{ + XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xmesa->xm_buffer->buffer; + XMesaGC gc = xmesa->xm_buffer->gc; + + if (xmesa->xm_visual->mesa_visual.RGBAflag) { + register int x, y; + const GLubyte *color = vert->color; + unsigned long pixel = xmesa_color_to_pixel( xmesa, + color[0], color[1], + color[2], color[3], + xmesa->pixelformat); + XMesaSetForeground( dpy, gc, pixel ); + x = (GLint) vert->win[0]; + y = YFLIP( xrb, (GLint) vert->win[1] ); + XMesaDrawPoint( dpy, buffer, gc, x, y); + } + else { + /* Color index mode */ + register int x, y; + XMesaSetForeground( dpy, gc, vert->index ); + x = (GLint) vert->win[0]; + y = YFLIP( xrb, (GLint) vert->win[1] ); + XMesaDrawPoint( dpy, buffer, gc, x, y); + } +} +#endif + + +/* Override the swrast point-selection function. Try to use one of + * our internal point functions, otherwise fall back to the standard + * swrast functions. + */ +void xmesa_choose_point( GLcontext *ctx ) +{ +#if 0 + XMesaContext xmesa = XMESA_CONTEXT(ctx); + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (ctx->RenderMode == GL_RENDER + && ctx->Point.Size == 1.0F && !ctx->Point.SmoothFlag + && swrast->_RasterMask == 0 + && !ctx->Texture._EnabledUnits + && xmesa->xm_buffer->buffer != XIMAGE) { + swrast->Point = draw_points_ANY_pixmap; + } + else { + _swrast_choose_point( ctx ); + } +#else + _swrast_choose_point( ctx ); +#endif +} + + + +/**********************************************************************/ +/*** Line rendering ***/ +/**********************************************************************/ + + +#define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \ + (struct xmesa_renderbuffer *) ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped + + +/* + * Draw a flat-shaded, PF_TRUECOLOR line into an XImage. + */ +#define NAME flat_TRUECOLOR_line +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + unsigned long pixel; \ + PACK_TRUECOLOR( pixel, color[0], color[1], color[2] ); +#define CLIP_HACK 1 +#define PLOT(X,Y) XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel ); +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, PF_8A8B8G8R line into an XImage. + */ +#define NAME flat_8A8B8G8R_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLuint pixel = PACK_8B8G8R( color[0], color[1], color[2] ); +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) *pixelPtr = pixel; +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, PF_8A8R8G8B line into an XImage. + */ +#define NAME flat_8A8R8G8B_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] ); +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) *pixelPtr = pixel; +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, PF_8R8G8B line into an XImage. + */ +#define NAME flat_8R8G8B_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] ); +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) *pixelPtr = pixel; +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, PF_8R8G8B24 line into an XImage. + */ +#define NAME flat_8R8G8B24_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; +#define PIXEL_TYPE bgr_t +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) { \ + pixelPtr->r = color[RCOMP]; \ + pixelPtr->g = color[GCOMP]; \ + pixelPtr->b = color[BCOMP]; \ +} +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, PF_5R6G5B line into an XImage. + */ +#define NAME flat_5R6G5B_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] ); +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) *pixelPtr = pixel; +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage. + */ +#define NAME flat_DITHER_5R6G5B_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + const GLubyte *color = vert1->color; +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] ); +#include "swrast/s_linetemp.h" + + + + +/* + * Draw a flat-shaded, PF_DITHER 8-bit line into an XImage. + */ +#define NAME flat_DITHER8_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLint r = color[0], g = color[1], b = color[2]; \ + DITHER_SETUP; +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) *pixelPtr = DITHER(X,Y,r,g,b); +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, PF_LOOKUP 8-bit line into an XImage. + */ +#define NAME flat_LOOKUP8_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLubyte pixel; \ + LOOKUP_SETUP; \ + pixel = (GLubyte) LOOKUP( color[0], color[1], color[2] ); +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) *pixelPtr = pixel; +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, PF_HPCR line into an XImage. + */ +#define NAME flat_HPCR_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + const GLubyte *color = vert1->color; \ + GLint r = color[0], g = color[1], b = color[2]; +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) *pixelPtr = (GLubyte) DITHER_HPCR(X,Y,r,g,b); +#include "swrast/s_linetemp.h" + + + + +/* + * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage. + */ +#define NAME flat_TRUECOLOR_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + const GLubyte *color = vert1->color; \ + unsigned long pixel; \ + PACK_TRUECOLOR( pixel, color[0], color[1], color[2] ); +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel); \ + } +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage. + */ +#define NAME flat_8A8B8G8R_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLuint pixel = PACK_8B8G8R( color[0], color[1], color[2] ); +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + *pixelPtr = pixel; \ + } +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, Z-less, PF_8A8R8G8B line into an XImage. + */ +#define NAME flat_8A8R8G8B_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] ); +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + *pixelPtr = pixel; \ + } +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage. + */ +#define NAME flat_8R8G8B_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] ); +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + *pixelPtr = pixel; \ + } +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage. + */ +#define NAME flat_8R8G8B24_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_TYPE bgr_t +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + pixelPtr->r = color[RCOMP]; \ + pixelPtr->g = color[GCOMP]; \ + pixelPtr->b = color[BCOMP]; \ + } +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage. + */ +#define NAME flat_5R6G5B_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] ); +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + *pixelPtr = pixel; \ + } +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage. + */ +#define NAME flat_DITHER_5R6G5B_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + const GLubyte *color = vert1->color; +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \ + } +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, Z-less, PF_DITHER 8-bit line into an XImage. + */ +#define NAME flat_DITHER8_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLint r = color[0], g = color[1], b = color[2]; \ + DITHER_SETUP; +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + *pixelPtr = (GLubyte) DITHER( X, Y, r, g, b); \ + } +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, Z-less, PF_LOOKUP 8-bit line into an XImage. + */ +#define NAME flat_LOOKUP8_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = vert1->color; \ + GLubyte pixel; \ + LOOKUP_SETUP; \ + pixel = (GLubyte) LOOKUP( color[0], color[1], color[2] ); +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + *pixelPtr = pixel; \ + } +#include "swrast/s_linetemp.h" + + + +/* + * Draw a flat-shaded, Z-less, PF_HPCR line into an XImage. + */ +#define NAME flat_HPCR_z_line +#define SETUP_CODE \ + GET_XRB(xrb); \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + const GLubyte *color = vert1->color; \ + GLint r = color[0], g = color[1], b = color[2]; +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y) +#define CLIP_HACK 1 +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + *pixelPtr = (GLubyte) DITHER_HPCR( X, Y, r, g, b); \ + } +#include "swrast/s_linetemp.h" + + + +#ifndef XFree86Server +/** + * Draw fast, XOR line with XDrawLine in front color buffer. + * WARNING: this isn't fully OpenGL conformant because different pixels + * will be hit versus using the other line functions. + * Don't use the code in X server GLcore module since we need a wrapper + * for the XSetLineAttributes() function call. + */ +static void +xor_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1) +{ + XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaGC gc = xmesa->xm_buffer->gc; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) + ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + unsigned long pixel = xmesa_color_to_pixel(ctx, + vert1->color[0], vert1->color[1], + vert1->color[2], vert1->color[3], + xmesa->pixelformat); + int x0 = (int) vert0->win[0]; + int y0 = YFLIP(xrb, (GLint) vert0->win[1]); + int x1 = (int) vert1->win[0]; + int y1 = YFLIP(xrb, (GLint) vert1->win[1]); + XMesaSetForeground(dpy, gc, pixel); + XMesaSetFunction(dpy, gc, GXxor); + XSetLineAttributes(dpy, gc, (int) ctx->Line.Width, + LineSolid, CapButt, JoinMiter); + XDrawLine(dpy, xrb->pixmap, gc, x0, y0, x1, y1); + XMesaSetFunction(dpy, gc, GXcopy); /* this gc is used elsewhere */ +} +#endif /* XFree86Server */ + + +static swrast_line_func get_line_func( GLcontext *ctx ) +{ + XMesaContext xmesa = XMESA_CONTEXT(ctx); + SWcontext *swrast = SWRAST_CONTEXT(ctx); + int depth = GET_VISUAL_DEPTH(xmesa->xm_visual); + GET_XRB(xrb); + + if ((ctx->DrawBuffer->_ColorDrawBufferMask[0] + & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) == 0) + return (swrast_line_func) NULL; + if (ctx->RenderMode != GL_RENDER) return (swrast_line_func) NULL; + if (ctx->Line.SmoothFlag) return (swrast_line_func) NULL; + if (ctx->Texture._EnabledUnits) return (swrast_line_func) NULL; + if (ctx->Light.ShadeModel != GL_FLAT) return (swrast_line_func) NULL; + if (ctx->Line.StippleFlag) return (swrast_line_func) NULL; + if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_line_func) NULL; + + if (xrb->ximage + && swrast->_RasterMask==DEPTH_BIT + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_TRUE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS + && ctx->Line.Width==1.0F) { + switch (xmesa->pixelformat) { + case PF_Truecolor: + return flat_TRUECOLOR_z_line; + case PF_8A8B8G8R: + return flat_8A8B8G8R_z_line; + case PF_8A8R8G8B: + return flat_8A8R8G8B_z_line; + case PF_8R8G8B: + return flat_8R8G8B_z_line; + case PF_8R8G8B24: + return flat_8R8G8B24_z_line; + case PF_5R6G5B: + return flat_5R6G5B_z_line; + case PF_Dither_5R6G5B: + return flat_DITHER_5R6G5B_z_line; + case PF_Dither: + return (depth==8) ? flat_DITHER8_z_line : (swrast_line_func) NULL; + case PF_Lookup: + return (depth==8) ? flat_LOOKUP8_z_line : (swrast_line_func) NULL; + case PF_HPCR: + return flat_HPCR_z_line; + default: + return (swrast_line_func)NULL; + } + } + if (xrb->ximage + && swrast->_RasterMask==0 + && ctx->Line.Width==1.0F) { + switch (xmesa->pixelformat) { + case PF_Truecolor: + return flat_TRUECOLOR_line; + case PF_8A8B8G8R: + return flat_8A8B8G8R_line; + case PF_8A8R8G8B: + return flat_8A8R8G8B_line; + case PF_8R8G8B: + return flat_8R8G8B_line; + case PF_8R8G8B24: + return flat_8R8G8B24_line; + case PF_5R6G5B: + return flat_5R6G5B_line; + case PF_Dither_5R6G5B: + return flat_DITHER_5R6G5B_line; + case PF_Dither: + return (depth==8) ? flat_DITHER8_line : (swrast_line_func) NULL; + case PF_Lookup: + return (depth==8) ? flat_LOOKUP8_line : (swrast_line_func) NULL; + case PF_HPCR: + return flat_HPCR_line; + default: + return (swrast_line_func)NULL; + } + } + +#ifndef XFree86Server + if (ctx->DrawBuffer->_NumColorDrawBuffers[0] == 1 + && ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT + && swrast->_RasterMask == LOGIC_OP_BIT + && ctx->Color.LogicOp == GL_XOR + && !ctx->Line.StippleFlag + && !ctx->Line.SmoothFlag) { + return xor_line; + } +#endif /* XFree86Server */ + + return (swrast_line_func) NULL; +} + + +/** + * Override for the swrast line-selection function. Try to use one + * of our internal line functions, otherwise fall back to the + * standard swrast functions. + */ +void +xmesa_choose_line(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (!(swrast->Line = get_line_func( ctx ))) + _swrast_choose_line( ctx ); +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_span.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_span.c new file mode 100644 index 000000000..664f365df --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_span.c @@ -0,0 +1,4800 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 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. + */ +/* $XFree86: xc/extras/Mesa/src/X/xm_span.c,v 1.3 2002/02/27 21:07:54 tsi Exp $ */ + +#include "glxheader.h" +#include "colormac.h" +#include "context.h" +#include "depth.h" +#include "drawpix.h" +#include "extensions.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" +#include "state.h" +#include "xmesaP.h" + +#include "swrast/swrast.h" + + +/* + * The following functions are used to trap XGetImage() calls which + * generate BadMatch errors if the drawable isn't mapped. + */ + +#ifndef XFree86Server +static int caught_xgetimage_error = 0; +static int (*old_xerror_handler)( XMesaDisplay *dpy, XErrorEvent *ev ); +static unsigned long xgetimage_serial; + +/* + * This is the error handler which will be called if XGetImage fails. + */ +static int xgetimage_error_handler( XMesaDisplay *dpy, XErrorEvent *ev ) +{ + if (ev->serial==xgetimage_serial && ev->error_code==BadMatch) { + /* caught the expected error */ + caught_xgetimage_error = 0; + } + else { + /* call the original X error handler, if any. otherwise ignore */ + if (old_xerror_handler) { + (*old_xerror_handler)( dpy, ev ); + } + } + return 0; +} + + +/* + * Call this right before XGetImage to setup error trap. + */ +static void catch_xgetimage_errors( XMesaDisplay *dpy ) +{ + xgetimage_serial = NextRequest( dpy ); + old_xerror_handler = XSetErrorHandler( xgetimage_error_handler ); + caught_xgetimage_error = 0; +} + + +/* + * Call this right after XGetImage to check if an error occured. + */ +static int check_xgetimage_errors( void ) +{ + /* restore old handler */ + (void) XSetErrorHandler( old_xerror_handler ); + /* return 0=no error, 1=error caught */ + return caught_xgetimage_error; +} +#endif + + +/* + * Read a pixel from an X drawable. + */ +static unsigned long read_pixel( XMesaDisplay *dpy, + XMesaDrawable d, int x, int y ) +{ + unsigned long p; +#ifndef XFree86Server + XMesaImage *pixel = NULL; + int error; + + catch_xgetimage_errors( dpy ); + pixel = XGetImage( dpy, d, x, y, 1, 1, AllPlanes, ZPixmap ); + error = check_xgetimage_errors(); + if (pixel && !error) { + p = XMesaGetPixel( pixel, 0, 0 ); + } + else { + p = 0; + } + if (pixel) { + XMesaDestroyImage( pixel ); + } +#else + (*dpy->GetImage)(d, x, y, 1, 1, ZPixmap, ~0L, (pointer)&p); +#endif + return p; +} + + + +/* + * The Mesa library needs to be able to draw pixels in a number of ways: + * 1. RGB vs Color Index + * 2. as horizontal spans (polygons, images) vs random locations (points, + * lines) + * 3. different color per-pixel or same color for all pixels + * + * Furthermore, the X driver needs to support rendering to 3 possible + * "buffers", usually one, but sometimes two at a time: + * 1. The front buffer as an X window + * 2. The back buffer as a Pixmap + * 3. The back buffer as an XImage + * + * Finally, if the back buffer is an XImage, we can avoid using XPutPixel and + * optimize common cases such as 24-bit and 8-bit modes. + * + * By multiplication, there's at least 48 possible combinations of the above. + * + * Below are implementations of the most commonly used combinations. They are + * accessed through function pointers which get initialized here and are used + * directly from the Mesa library. The 8 function pointers directly correspond + * to the first 3 cases listed above. + * + * + * The function naming convention is: + * + * [put|get]_[mono]_[row|values]_[format]_[pixmap|ximage] + * + * New functions optimized for specific cases can be added without too much + * trouble. An example might be the 24-bit TrueColor mode 8A8R8G8B which is + * found on IBM RS/6000 X servers. + */ + + + + +/**********************************************************************/ +/*** Write COLOR SPAN functions ***/ +/**********************************************************************/ + + +#define PUT_ROW_ARGS \ + GLcontext *ctx, \ + struct gl_renderbuffer *rb, \ + GLuint n, GLint x, GLint y, \ + const void *values, const GLubyte mask[] + +#define RGB_SPAN_ARGS \ + GLcontext *ctx, \ + struct gl_renderbuffer *rb, \ + GLuint n, GLint x, GLint y, \ + const void *values, const GLubyte mask[] + + +/* NOTE: if mask==NULL, draw all pixels */ + + +/* + * Write a span of PF_TRUECOLOR pixels to a pixmap. + */ +static void put_row_TRUECOLOR_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = XMESA_BUFFER(ctx->DrawBuffer)->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + unsigned long p; + PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + XMesaPutPixel( rowimg, i, 0, p ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_TRUECOLOR pixels to a pixmap. + */ +static void put_row_rgb_TRUECOLOR_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + unsigned long p; + PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + XMesaPutPixel( rowimg, i, 0, p ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + +/* + * Write a span of PF_TRUEDITHER pixels to a pixmap. + */ +static void put_row_TRUEDITHER_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + unsigned long p; + PACK_TRUEDITHER(p, x+i, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + XMesaPutPixel( rowimg, i, 0, p ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_TRUEDITHER pixels to a pixmap (no alpha). + */ +static void put_row_rgb_TRUEDITHER_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + unsigned long p; + PACK_TRUEDITHER(p, x+i, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + XMesaPutPixel( rowimg, i, 0, p ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_8A8B8G8R pixels to a pixmap. + */ +static void put_row_8A8B8G8R_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + PACK_8A8B8G8R(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP]) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLuint *ptr4 = (GLuint *) rowimg->data; + for (i=0;i<n;i++) { + *ptr4++ = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_8A8B8G8R pixels to a pixmap (no alpha). + */ +static void put_row_rgb_8A8B8G8R_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + PACK_8B8G8R(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLuint *ptr4 = (GLuint *) rowimg->data; + for (i=0;i<n;i++) { + *ptr4++ = PACK_8B8G8R(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + +/* + * Write a span of PF_8A8R8G8B pixels to a pixmap. + */ +static void put_row_8A8R8G8B_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + PACK_8A8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP]) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLuint *ptr4 = (GLuint *) rowimg->data; + for (i=0;i<n;i++) { + *ptr4++ = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_8A8R8G8B pixels to a pixmap (no alpha). + */ +static void put_row_rgb_8A8R8G8B_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLuint *ptr4 = (GLuint *) rowimg->data; + for (i=0;i<n;i++) { + *ptr4++ = PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + +/* + * Write a span of PF_8R8G8B pixels to a pixmap. + */ +static void put_row_8R8G8B_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLuint *ptr4 = (GLuint *) rowimg->data; + for (i=0;i<n;i++) { + *ptr4++ = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_8R8G8B24 pixels to a pixmap. + */ +static void put_row_8R8G8B24_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + y = YFLIP(xrb, y); + if (mask) { + register GLuint i; + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLuint *ptr4 = (GLuint *) rowimg->data; + register GLuint pixel; + static const GLuint shift[4] = {0, 8, 16, 24}; + register GLuint i = 0; + int w = n; + while (w > 3) { + pixel = rgba[i][BCOMP] /* << shift[0]*/; + pixel |= rgba[i][GCOMP] << shift[1]; + pixel |= rgba[i++][RCOMP] << shift[2]; + pixel |= rgba[i][BCOMP] << shift[3]; + *ptr4++ = pixel; + + pixel = rgba[i][GCOMP] /* << shift[0]*/; + pixel |= rgba[i++][RCOMP] << shift[1]; + pixel |= rgba[i][BCOMP] << shift[2]; + pixel |= rgba[i][GCOMP] << shift[3]; + *ptr4++ = pixel; + + pixel = rgba[i++][RCOMP]/* << shift[0]*/; + pixel |= rgba[i][BCOMP] << shift[1]; + pixel |= rgba[i][GCOMP] << shift[2]; + pixel |= rgba[i++][RCOMP] << shift[3]; + *ptr4++ = pixel; + + w -= 4; + } + switch (w) { + case 3: + pixel = 0; + pixel |= rgba[i][BCOMP] /*<< shift[0]*/; + pixel |= rgba[i][GCOMP] << shift[1]; + pixel |= rgba[i++][RCOMP] << shift[2]; + pixel |= rgba[i][BCOMP] << shift[3]; + *ptr4++ = pixel; + pixel = 0; + pixel |= rgba[i][GCOMP] /*<< shift[0]*/; + pixel |= rgba[i++][RCOMP] << shift[1]; + pixel |= rgba[i][BCOMP] << shift[2]; + pixel |= rgba[i][GCOMP] << shift[3]; + *ptr4++ = pixel; + pixel = 0xffffff00 & *ptr4; + pixel |= rgba[i][RCOMP] /*<< shift[0]*/; + *ptr4 = pixel; + break; + case 2: + pixel = 0; + pixel |= rgba[i][BCOMP] /*<< shift[0]*/; + pixel |= rgba[i][GCOMP] << shift[1]; + pixel |= rgba[i++][RCOMP] << shift[2]; + pixel |= rgba[i][BCOMP] << shift[3]; + *ptr4++ = pixel; + pixel = 0xffff0000 & *ptr4; + pixel |= rgba[i][GCOMP] /*<< shift[0]*/; + pixel |= rgba[i][RCOMP] << shift[1]; + *ptr4 = pixel; + break; + case 1: + pixel = 0xff000000 & *ptr4; + pixel |= rgba[i][BCOMP] /*<< shift[0]*/; + pixel |= rgba[i][GCOMP] << shift[1]; + pixel |= rgba[i][RCOMP] << shift[2]; + *ptr4 = pixel; + break; + case 0: + break; + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_8R8G8B pixels to a pixmap (no alpha). + */ +static void put_row_rgb_8R8G8B_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLuint *ptr4 = (GLuint *) rowimg->data; + for (i=0;i<n;i++) { + *ptr4++ = PACK_8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + +/* + * Write a span of PF_8R8G8B24 pixels to a pixmap (no alpha). + */ +static void put_row_rgb_8R8G8B24_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + y = YFLIP(xrb, y); + if (mask) { + register GLuint i; + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + PACK_8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLuint *ptr4 = (GLuint *) rowimg->data; + register GLuint pixel; + static const GLuint shift[4] = {0, 8, 16, 24}; + unsigned w = n; + register GLuint i = 0; + while (w > 3) { + pixel = 0; + pixel |= rgb[i][BCOMP]/* << shift[0]*/; + pixel |= rgb[i][GCOMP] << shift[1]; + pixel |= rgb[i++][RCOMP] << shift[2]; + pixel |= rgb[i][BCOMP] <<shift[3]; + *ptr4++ = pixel; + + pixel = 0; + pixel |= rgb[i][GCOMP]/* << shift[0]*/; + pixel |= rgb[i++][RCOMP] << shift[1]; + pixel |= rgb[i][BCOMP] << shift[2]; + pixel |= rgb[i][GCOMP] << shift[3]; + *ptr4++ = pixel; + + pixel = 0; + pixel |= rgb[i++][RCOMP]/* << shift[0]*/; + pixel |= rgb[i][BCOMP] << shift[1]; + pixel |= rgb[i][GCOMP] << shift[2]; + pixel |= rgb[i++][RCOMP] << shift[3]; + *ptr4++ = pixel; + w -= 4; + } + switch (w) { + case 3: + pixel = 0; + pixel |= rgb[i][BCOMP]/* << shift[0]*/; + pixel |= rgb[i][GCOMP] << shift[1]; + pixel |= rgb[i++][RCOMP] << shift[2]; + pixel |= rgb[i][BCOMP] << shift[3]; + *ptr4++ = pixel; + pixel = 0; + pixel |= rgb[i][GCOMP]/* << shift[0]*/; + pixel |= rgb[i++][RCOMP] << shift[1]; + pixel |= rgb[i][BCOMP] << shift[2]; + pixel |= rgb[i][GCOMP] << shift[3]; + *ptr4++ = pixel; + pixel = *ptr4; + pixel &= 0xffffff00; + pixel |= rgb[i++][RCOMP]/* << shift[0]*/; + *ptr4++ = pixel; + break; + case 2: + pixel = 0; + pixel |= rgb[i][BCOMP]/* << shift[0]*/; + pixel |= rgb[i][GCOMP] << shift[1]; + pixel |= rgb[i++][RCOMP] << shift[2]; + pixel |= rgb[i][BCOMP] << shift[3]; + *ptr4++ = pixel; + pixel = *ptr4; + pixel &= 0xffff0000; + pixel |= rgb[i][GCOMP]/* << shift[0]*/; + pixel |= rgb[i++][RCOMP] << shift[1]; + *ptr4++ = pixel; + break; + case 1: + pixel = *ptr4; + pixel &= 0xff000000; + pixel |= rgb[i][BCOMP]/* << shift[0]*/; + pixel |= rgb[i][GCOMP] << shift[1]; + pixel |= rgb[i++][RCOMP] << shift[2]; + *ptr4++ = pixel; + break; + case 0: + break; + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_5R6G5B pixels to a pixmap. + */ +static void put_row_5R6G5B_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLushort *ptr2 = (GLushort *) rowimg->data; + for (i=0;i<n;i++) { + ptr2[i] = PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_DITHER_5R6G5B pixels to a pixmap. + */ +static void put_row_DITHER_5R6G5B_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLushort *ptr2 = (GLushort *) rowimg->data; + for (i=0;i<n;i++) { + PACK_TRUEDITHER( ptr2[i], x+i, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_5R6G5B pixels to a pixmap (no alpha). + */ +static void put_row_rgb_5R6G5B_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLushort *ptr2 = (GLushort *) rowimg->data; + for (i=0;i<n;i++) { + ptr2[i] = PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_DITHER_5R6G5B pixels to a pixmap (no alpha). + */ +static void put_row_rgb_DITHER_5R6G5B_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLushort *ptr2 = (GLushort *) rowimg->data; + for (i=0;i<n;i++) { + PACK_TRUEDITHER( ptr2[i], x+i, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_DITHER pixels to a pixmap. + */ +static void put_row_DITHER_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + XDITHER_SETUP(y); + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, XDITHER(x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + XMesaPutPixel( rowimg, i, 0, XDITHER(x+i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_DITHER pixels to a pixmap (no alpha). + */ +static void put_row_rgb_DITHER_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + XDITHER_SETUP(y); + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, XDITHER(x, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + XMesaPutPixel( rowimg, i, 0, XDITHER(x+i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_1BIT pixels to a pixmap. + */ +static void put_row_1BIT_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + SETUP_1BIT; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + DITHER_1BIT( x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + XMesaPutPixel( rowimg, i, 0, + DITHER_1BIT( x+i, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_1BIT pixels to a pixmap (no alpha). + */ +static void put_row_rgb_1BIT_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + SETUP_1BIT; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + DITHER_1BIT(x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + /* draw all pixels */ + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + XMesaPutPixel( rowimg, i, 0, + DITHER_1BIT(x+i, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_HPCR pixels to a pixmap. + */ +static void put_row_HPCR_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + DITHER_HPCR( x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLubyte *ptr = (GLubyte *) XMESA_BUFFER(ctx->DrawBuffer)->rowimage->data; + for (i=0;i<n;i++) { + ptr[i] = DITHER_HPCR( (x+i), y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_HPCR pixels to a pixmap (no alpha). + */ +static void put_row_rgb_HPCR_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + DITHER_HPCR(x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + register GLubyte *ptr = (GLubyte *) XMESA_BUFFER(ctx->DrawBuffer)->rowimage->data; + for (i=0;i<n;i++) { + ptr[i] = DITHER_HPCR( (x+i), y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + +/* + * Write a span of PF_LOOKUP pixels to a pixmap. + */ +static void put_row_LOOKUP_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + LOOKUP_SETUP; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + XMesaPutPixel( rowimg, i, 0, LOOKUP(rgba[i][RCOMP],rgba[i][GCOMP],rgba[i][BCOMP]) ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_LOOKUP pixels to a pixmap (no alpha). + */ +static void put_row_rgb_LOOKUP_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + LOOKUP_SETUP; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, LOOKUP( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + XMesaPutPixel( rowimg, i, 0, LOOKUP(rgb[i][RCOMP],rgb[i][GCOMP],rgb[i][BCOMP]) ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_GRAYSCALE pixels to a pixmap. + */ +static void put_row_GRAYSCALE_pixmap( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + XMesaPutPixel( rowimg, i, 0, GRAY_RGB(rgba[i][RCOMP],rgba[i][GCOMP],rgba[i][BCOMP]) ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + + +/* + * Write a span of PF_GRAYSCALE pixels to a pixmap (no alpha). + */ +static void put_row_rgb_GRAYSCALE_pixmap( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; + for (i=0;i<n;i++) { + XMesaPutPixel( rowimg, i, 0, GRAY_RGB(rgb[i][RCOMP],rgb[i][GCOMP],rgb[i][BCOMP]) ); + } + XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, n, 1 ); + } +} + +/* + * Write a span of PF_TRUECOLOR pixels to an XImage. + */ +static void put_row_TRUECOLOR_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + XMesaPutPixel( img, x, y, p ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + unsigned long p; + PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + XMesaPutPixel( img, x, y, p ); + } + } +} + + +/* + * Write a span of PF_TRUECOLOR pixels to an XImage (no alpha). + */ +static void put_row_rgb_TRUECOLOR_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + XMesaPutPixel( img, x, y, p ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + unsigned long p; + PACK_TRUECOLOR( p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + XMesaPutPixel( img, x, y, p ); + } + } +} + + +/* + * Write a span of PF_TRUEDITHER pixels to an XImage. + */ +static void put_row_TRUEDITHER_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + XMesaPutPixel( img, x, y, p ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + unsigned long p; + PACK_TRUEDITHER(p, x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + XMesaPutPixel( img, x, y, p ); + } + } +} + + +/* + * Write a span of PF_TRUEDITHER pixels to an XImage (no alpha). + */ +static void put_row_rgb_TRUEDITHER_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + XMesaPutPixel( img, x, y, p ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + unsigned long p; + PACK_TRUEDITHER(p, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + XMesaPutPixel( img, x, y, p ); + } + } +} + + +/* + * Write a span of PF_8A8B8G8R-format pixels to an ximage. + */ +static void put_row_8A8B8G8R_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLuint *ptr = PIXEL_ADDR4(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++) { + ptr[i] = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ); + } + } +} + + +/* + * Write a span of PF_8A8B8G8R-format pixels to an ximage (no alpha). + */ +static void put_row_rgb_8A8B8G8R_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLuint *ptr = PIXEL_ADDR4(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = PACK_8A8B8G8R( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++) { + ptr[i] = PACK_8A8B8G8R( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 ); + } + } +} + +/* + * Write a span of PF_8A8R8G8B-format pixels to an ximage. + */ +static void put_row_8A8R8G8B_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLuint *ptr = PIXEL_ADDR4(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++) { + ptr[i] = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ); + } + } +} + + +/* + * Write a span of PF_8A8R8G8B-format pixels to an ximage (no alpha). + */ +static void put_row_rgb_8A8R8G8B_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLuint *ptr = PIXEL_ADDR4(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = PACK_8A8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++) { + ptr[i] = PACK_8A8R8G8B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 ); + } + } +} + + +/* + * Write a span of PF_8R8G8B-format pixels to an ximage. + */ +static void put_row_8R8G8B_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLuint *ptr = PIXEL_ADDR4(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = PACK_8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + } + } + } + else { + for (i=0;i<n;i++) { + ptr[i] = PACK_8R8G8B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + } + } +} + + +/* + * Write a span of PF_8R8G8B24-format pixels to an ximage. + */ +static void put_row_8R8G8B24_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte *ptr = (GLubyte *) PIXEL_ADDR3(xrb, x, y ); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + GLuint *ptr4 = (GLuint *) ptr; + register GLuint pixel = *ptr4; + switch (3 & (int)(ptr - (GLubyte*)ptr4)) { + case 0: + pixel &= 0xff000000; + pixel |= rgba[i][BCOMP]; + pixel |= rgba[i][GCOMP] << 8; + pixel |= rgba[i][RCOMP] << 16; + *ptr4 = pixel; + break; + case 3: + pixel &= 0x00ffffff; + pixel |= rgba[i][BCOMP] << 24; + *ptr4++ = pixel; + pixel = *ptr4 && 0xffff0000; + pixel |= rgba[i][GCOMP]; + pixel |= rgba[i][RCOMP] << 8; + *ptr4 = pixel; + break; + case 2: + pixel &= 0x0000ffff; + pixel |= rgba[i][BCOMP] << 16; + pixel |= rgba[i][GCOMP] << 24; + *ptr4++ = pixel; + pixel = *ptr4 && 0xffffff00; + pixel |= rgba[i][RCOMP]; + *ptr4 = pixel; + break; + case 1: + pixel &= 0x000000ff; + pixel |= rgba[i][BCOMP] << 8; + pixel |= rgba[i][GCOMP] << 16; + pixel |= rgba[i][RCOMP] << 24; + *ptr4 = pixel; + break; + } + } + ptr += 3; + } + } + else { + /* write all pixels */ + int w = n; + GLuint *ptr4 = (GLuint *) ptr; + register GLuint pixel = *ptr4; + int index = (int)(ptr - (GLubyte *)ptr4); + register GLuint i = 0; + switch (index) { + case 0: + break; + case 1: + pixel &= 0x00ffffff; + pixel |= rgba[i][BCOMP] << 24; + *ptr4++ = pixel; + pixel = *ptr4 && 0xffff0000; + pixel |= rgba[i][GCOMP]; + pixel |= rgba[i++][RCOMP] << 8; + *ptr4 = pixel; + if (0 == --w) + break; + case 2: + pixel &= 0x0000ffff; + pixel |= rgba[i][BCOMP] << 16; + pixel |= rgba[i][GCOMP] << 24; + *ptr4++ = pixel; + pixel = *ptr4 && 0xffffff00; + pixel |= rgba[i++][RCOMP]; + *ptr4 = pixel; + if (0 == --w) + break; + case 3: + pixel &= 0x000000ff; + pixel |= rgba[i][BCOMP] << 8; + pixel |= rgba[i][GCOMP] << 16; + pixel |= rgba[i++][RCOMP] << 24; + *ptr4++ = pixel; + if (0 == --w) + break; + break; + } + while (w > 3) { + pixel = rgba[i][BCOMP]; + pixel |= rgba[i][GCOMP] << 8; + pixel |= rgba[i++][RCOMP] << 16; + pixel |= rgba[i][BCOMP] << 24; + *ptr4++ = pixel; + pixel = rgba[i][GCOMP]; + pixel |= rgba[i++][RCOMP] << 8; + pixel |= rgba[i][BCOMP] << 16; + pixel |= rgba[i][GCOMP] << 24; + *ptr4++ = pixel; + pixel = rgba[i++][RCOMP]; + pixel |= rgba[i][BCOMP] << 8; + pixel |= rgba[i][GCOMP] << 16; + pixel |= rgba[i++][RCOMP] << 24; + *ptr4++ = pixel; + w -= 4; + } + switch (w) { + case 0: + break; + case 1: + pixel = *ptr4 & 0xff000000; + pixel |= rgba[i][BCOMP]; + pixel |= rgba[i][GCOMP] << 8; + pixel |= rgba[i][RCOMP] << 16; + *ptr4 = pixel; + break; + case 2: + pixel = rgba[i][BCOMP]; + pixel |= rgba[i][GCOMP] << 8; + pixel |= rgba[i++][RCOMP] << 16; + pixel |= rgba[i][BCOMP] << 24; + *ptr4++ = pixel; + pixel = *ptr4 & 0xffff0000; + pixel |= rgba[i][GCOMP]; + pixel |= rgba[i][RCOMP] << 8; + *ptr4 = pixel; + break; + case 3: + pixel = rgba[i][BCOMP]; + pixel |= rgba[i][GCOMP] << 8; + pixel |= rgba[i++][RCOMP] << 16; + pixel |= rgba[i][BCOMP] << 24; + *ptr4++ = pixel; + pixel = rgba[i][GCOMP]; + pixel |= rgba[i++][RCOMP] << 8; + pixel |= rgba[i][BCOMP] << 16; + pixel |= rgba[i][GCOMP] << 24; + *ptr4++ = pixel; + pixel = *ptr4 & 0xffffff00; + pixel |= rgba[i][RCOMP]; + *ptr4 = pixel; + break; + } + } +} + + +/* + * Write a span of PF_8R8G8B-format pixels to an ximage (no alpha). + */ +static void put_row_rgb_8R8G8B_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLuint *ptr = PIXEL_ADDR4(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++) { + ptr[i] = PACK_8R8G8B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + } + } +} + + +/* + * Write a span of PF_8R8G8B24-format pixels to an ximage (no alpha). + */ +static void put_row_rgb_8R8G8B24_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte *ptr = (GLubyte *) PIXEL_ADDR3(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + *ptr++ = rgb[i][BCOMP]; + *ptr++ = rgb[i][GCOMP]; + *ptr++ = rgb[i][RCOMP]; + } + else { + ptr += 3; + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++) { + *ptr++ = rgb[i][BCOMP]; + *ptr++ = rgb[i][GCOMP]; + *ptr++ = rgb[i][RCOMP]; + } + } +} + + +/* + * Write a span of PF_5R6G5B-format pixels to an ximage. + */ +static void put_row_5R6G5B_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLushort *ptr = PIXEL_ADDR2(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } + } + else { + /* draw all pixels */ +#if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */ + GLuint *ptr32 = (GLuint *) ptr; + GLuint extraPixel = (n & 1); + n -= extraPixel; + for (i = 0; i < n; i += 2) { + GLuint p0, p1; + p0 = PACK_5R6G5B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + p1 = PACK_5R6G5B(rgba[i+1][RCOMP], rgba[i+1][GCOMP], rgba[i+1][BCOMP]); + *ptr32++ = (p1 << 16) | p0; + } + if (extraPixel) { + ptr[n] = PACK_5R6G5B(rgba[n][RCOMP], rgba[n][GCOMP], rgba[n][BCOMP]); + } +#else + for (i = 0; i < n; i++) { + ptr[i] = PACK_5R6G5B(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + } +#endif + } +} + + +/* + * Write a span of PF_DITHER_5R6G5B-format pixels to an ximage. + */ +static void put_row_DITHER_5R6G5B_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + register GLuint i; + register GLushort *ptr = PIXEL_ADDR2(xrb, x, y); + const GLint y2 = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + PACK_TRUEDITHER( ptr[i], x, y2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } + } + else { + /* draw all pixels */ +#if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */ + GLuint *ptr32 = (GLuint *) ptr; + GLuint extraPixel = (n & 1); + n -= extraPixel; + for (i = 0; i < n; i += 2, x += 2) { + GLuint p0, p1; + PACK_TRUEDITHER( p0, x, y2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + PACK_TRUEDITHER( p1, x+1, y2, rgba[i+1][RCOMP], rgba[i+1][GCOMP], rgba[i+1][BCOMP] ); + *ptr32++ = (p1 << 16) | p0; + } + if (extraPixel) { + PACK_TRUEDITHER( ptr[n], x+n, y2, rgba[n][RCOMP], rgba[n][GCOMP], rgba[n][BCOMP]); + } +#else + for (i = 0; i < n; i++, x++) { + PACK_TRUEDITHER( ptr[i], x, y2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + } +#endif + } +} + + +/* + * Write a span of PF_5R6G5B-format pixels to an ximage (no alpha). + */ +static void put_row_rgb_5R6G5B_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLushort *ptr = PIXEL_ADDR2(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + } + } + else { + /* draw all pixels */ +#if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */ + GLuint *ptr32 = (GLuint *) ptr; + GLuint extraPixel = (n & 1); + n -= extraPixel; + for (i = 0; i < n; i += 2) { + GLuint p0, p1; + p0 = PACK_5R6G5B(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); + p1 = PACK_5R6G5B(rgb[i+1][RCOMP], rgb[i+1][GCOMP], rgb[i+1][BCOMP]); + *ptr32++ = (p1 << 16) | p0; + } + if (extraPixel) { + ptr[n] = PACK_5R6G5B(rgb[n][RCOMP], rgb[n][GCOMP], rgb[n][BCOMP]); + } +#else + for (i=0;i<n;i++) { + ptr[i] = PACK_5R6G5B( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } +#endif + } +} + + +/* + * Write a span of PF_DITHER_5R6G5B-format pixels to an ximage (no alpha). + */ +static void put_row_rgb_DITHER_5R6G5B_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + register GLuint i; + register GLushort *ptr = PIXEL_ADDR2(xrb, x, y ); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + PACK_TRUEDITHER( ptr[i], x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + } + } + else { + /* draw all pixels */ +#if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */ + GLuint *ptr32 = (GLuint *) ptr; + GLuint extraPixel = (n & 1); + n -= extraPixel; + for (i = 0; i < n; i += 2, x += 2) { + GLuint p0, p1; + PACK_TRUEDITHER( p0, x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + PACK_TRUEDITHER( p1, x+1, y, rgb[i+1][RCOMP], rgb[i+1][GCOMP], rgb[i+1][BCOMP] ); + *ptr32++ = (p1 << 16) | p0; + } + if (extraPixel) { + PACK_TRUEDITHER( ptr[n], x+n, y, rgb[n][RCOMP], rgb[n][GCOMP], rgb[n][BCOMP]); + } +#else + for (i=0;i<n;i++,x++) { + PACK_TRUEDITHER( ptr[i], x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } +#endif + } +} + + +/* + * Write a span of PF_DITHER pixels to an XImage. + */ +static void put_row_DITHER_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + int yy = YFLIP(xrb, y); + XDITHER_SETUP(yy); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaPutPixel( img, x, yy, XDITHER( x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + XMesaPutPixel( img, x, yy, XDITHER( x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + } + } +} + + +/* + * Write a span of PF_DITHER pixels to an XImage (no alpha). + */ +static void put_row_rgb_DITHER_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + int yy = YFLIP(xrb, y); + XDITHER_SETUP(yy); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaPutPixel( img, x, yy, XDITHER( x, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + XMesaPutPixel( img, x, yy, XDITHER( x, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) ); + } + } +} + + + +/* + * Write a span of 8-bit PF_DITHER pixels to an XImage. + */ +static void put_row_DITHER8_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + XDITHER_SETUP(y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + ptr[i] = (GLubyte) XDITHER( x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } + } + else { + for (i=0;i<n;i++,x++) { + ptr[i] = (GLubyte) XDITHER( x, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +static void put_row_rgb_DITHER8_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + XDITHER_SETUP(y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + ptr[i] = (GLubyte) XDITHER( x, rgb[i][0], rgb[i][1], rgb[i][2] ); + } + } + } + else { + const GLubyte *data = (GLubyte *) rgb; + for (i=0;i<n;i++,x++) { + /*ptr[i] = XDITHER( x, rgb[i][0], rgb[i][1], rgb[i][2] );*/ + ptr[i] = (GLubyte) XDITHER( x, data[i+i+i], data[i+i+i+1], data[i+i+i+2] ); + } + } +} + + + +/* + * Write a span of PF_1BIT pixels to an XImage. + */ +static void put_row_1BIT_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + SETUP_1BIT; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaPutPixel(img, x, y, DITHER_1BIT(x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP])); + } + } + } + else { + for (i=0;i<n;i++,x++) { + XMesaPutPixel( img, x, y, DITHER_1BIT(x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) ); + } + } +} + + +/* + * Write a span of PF_1BIT pixels to an XImage (no alpha). + */ +static void put_row_rgb_1BIT_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + SETUP_1BIT; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaPutPixel(img, x, y, DITHER_1BIT(x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP])); + } + } + } + else { + for (i=0;i<n;i++,x++) { + XMesaPutPixel( img, x, y, DITHER_1BIT(x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]) ); + } + } +} + + +/* + * Write a span of PF_HPCR pixels to an XImage. + */ +static void put_row_HPCR_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + register GLuint i; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + ptr[i] = DITHER_HPCR( x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + ptr[i] = DITHER_HPCR( x, y, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +/* + * Write a span of PF_HPCR pixels to an XImage (no alpha). + */ +static void put_row_rgb_HPCR_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + register GLuint i; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + ptr[i] = DITHER_HPCR( x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + ptr[i] = DITHER_HPCR( x, y, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + } +} + + +/* + * Write a span of PF_LOOKUP pixels to an XImage. + */ +static void put_row_LOOKUP_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + LOOKUP_SETUP; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaPutPixel( img, x, y, LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + XMesaPutPixel( img, x, y, LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + } + } +} + + +/* + * Write a span of PF_LOOKUP pixels to an XImage (no alpha). + */ +static void put_row_rgb_LOOKUP_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + LOOKUP_SETUP; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaPutPixel( img, x, y, LOOKUP( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + XMesaPutPixel( img, x, y, LOOKUP( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) ); + } + } +} + + +/* + * Write a span of 8-bit PF_LOOKUP pixels to an XImage. + */ +static void put_row_LOOKUP8_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + LOOKUP_SETUP; + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + ptr[i] = (GLubyte) LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + ptr[i] = (GLubyte) LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +static void put_row_rgb_LOOKUP8_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + LOOKUP_SETUP; + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + ptr[i] = (GLubyte) LOOKUP( rgb[i][0], rgb[i][1], rgb[i][2] ); + } + } + } + else { + /* draw all pixels */ + const GLubyte *data = (GLubyte *) rgb; + for (i=0;i<n;i++,x++) { + /*ptr[i] = LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );*/ + ptr[i] = (GLubyte) LOOKUP( data[i+i+i], data[i+i+i+1], data[i+i+i+2] ); + } + } +} + + +/* + * Write a span of PF_GRAYSCALE pixels to an XImage. + */ +static void put_row_GRAYSCALE_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaPutPixel( img, x, y, GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + XMesaPutPixel( img, x, y, GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + } + } +} + + +/* + * Write a span of PF_GRAYSCALE pixels to an XImage (no alpha). + */ +static void put_row_rgb_GRAYSCALE_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaPutPixel( img, x, y, GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++,x++) { + XMesaPutPixel( img, x, y, GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ) ); + } + } +} + + +/* + * Write a span of 8-bit PF_GRAYSCALE pixels to an XImage. + */ +static void put_row_GRAYSCALE8_ximage( PUT_ROW_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = (GLubyte) GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++) { + ptr[i] = (GLubyte) GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +/* + * Write a span of 8-bit PF_GRAYSCALE pixels to an XImage (no alpha). + */ +static void put_row_rgb_GRAYSCALE8_ximage( RGB_SPAN_ARGS ) +{ + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + if (mask) { + for (i=0;i<n;i++) { + if (mask[i]) { + ptr[i] = (GLubyte) GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + } + } + else { + /* draw all pixels */ + for (i=0;i<n;i++) { + ptr[i] = (GLubyte) GRAY_RGB( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); + } + } +} + + + + +/**********************************************************************/ +/*** Write COLOR PIXEL functions ***/ +/**********************************************************************/ + + +#define PUT_VALUES_ARGS \ + GLcontext *ctx, struct gl_renderbuffer *rb, \ + GLuint n, const GLint x[], const GLint y[], \ + const void *values, const GLubyte mask[] + + +/* + * Write an array of PF_TRUECOLOR pixels to a pixmap. + */ +static void put_values_TRUECOLOR_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + unsigned long p; + PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_TRUEDITHER pixels to a pixmap. + */ +static void put_values_TRUEDITHER_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_8A8B8G8R pixels to a pixmap. + */ +static void put_values_8A8B8G8R_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + +/* + * Write an array of PF_8A8R8G8B pixels to a pixmap. + */ +static void put_values_8A8R8G8B_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + +/* + * Write an array of PF_8R8G8B pixels to a pixmap. + */ +static void put_values_8R8G8B_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_8R8G8B24 pixels to a pixmap. + */ +static void put_values_8R8G8B24_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_5R6G5B pixels to a pixmap. + */ +static void put_values_5R6G5B_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_DITHER_5R6G5B pixels to a pixmap. + */ +static void put_values_DITHER_5R6G5B_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_DITHER pixels to a pixmap. + */ +static void put_values_DITHER_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + DITHER_SETUP; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + DITHER(x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_1BIT pixels to a pixmap. + */ +static void put_values_1BIT_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + SETUP_1BIT; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + DITHER_1BIT( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_HPCR pixels to a pixmap. + */ +static void put_values_HPCR_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, + DITHER_HPCR( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] )); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_LOOKUP pixels to a pixmap. + */ +static void put_values_LOOKUP_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + LOOKUP_SETUP; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_GRAYSCALE pixels to a pixmap. + */ +static void put_values_GRAYSCALE_pixmap( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_TRUECOLOR pixels to an ximage. + */ +static void put_values_TRUECOLOR_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + unsigned long p; + PACK_TRUECOLOR( p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), p ); + } + } +} + + +/* + * Write an array of PF_TRUEDITHER pixels to an XImage. + */ +static void put_values_TRUEDITHER_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), p ); + } + } +} + + +/* + * Write an array of PF_8A8B8G8R pixels to an ximage. + */ +static void put_values_8A8B8G8R_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i] ); + *ptr = PACK_8A8B8G8R( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ); + } + } +} + +/* + * Write an array of PF_8A8R8G8B pixels to an ximage. + */ +static void put_values_8A8R8G8B_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i]); + *ptr = PACK_8A8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] ); + } + } +} + + +/* + * Write an array of PF_8R8G8B pixels to an ximage. + */ +static void put_values_8R8G8B_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i]); + *ptr = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +/* + * Write an array of PF_8R8G8B24 pixels to an ximage. + */ +static void put_values_8R8G8B24_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + bgr_t *ptr = PIXEL_ADDR3(xrb, x[i], y[i] ); + ptr->r = rgba[i][RCOMP]; + ptr->g = rgba[i][GCOMP]; + ptr->b = rgba[i][BCOMP]; + } + } +} + + +/* + * Write an array of PF_5R6G5B pixels to an ximage. + */ +static void put_values_5R6G5B_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLushort *ptr = PIXEL_ADDR2(xrb, x[i], y[i] ); + *ptr = PACK_5R6G5B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +/* + * Write an array of PF_DITHER_5R6G5B pixels to an ximage. + */ +static void put_values_DITHER_5R6G5B_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLushort *ptr = PIXEL_ADDR2(xrb, x[i], y[i] ); + PACK_TRUEDITHER( *ptr, x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +/* + * Write an array of PF_DITHER pixels to an XImage. + */ +static void put_values_DITHER_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + DITHER_SETUP; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), + DITHER( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + } + } +} + + +/* + * Write an array of 8-bit PF_DITHER pixels to an XImage. + */ +static void put_values_DITHER8_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + DITHER_SETUP; + for (i=0;i<n;i++) { + if (mask[i]) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]); + *ptr = (GLubyte) DITHER( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +/* + * Write an array of PF_1BIT pixels to an XImage. + */ +static void put_values_1BIT_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + SETUP_1BIT; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), + DITHER_1BIT( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] )); + } + } +} + + +/* + * Write an array of PF_HPCR pixels to an XImage. + */ +static void put_values_HPCR_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]); + *ptr = (GLubyte) DITHER_HPCR( x[i], y[i], rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +/* + * Write an array of PF_LOOKUP pixels to an XImage. + */ +static void put_values_LOOKUP_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + LOOKUP_SETUP; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), LOOKUP(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]) ); + } + } +} + + +/* + * Write an array of 8-bit PF_LOOKUP pixels to an XImage. + */ +static void put_values_LOOKUP8_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + LOOKUP_SETUP; + for (i=0;i<n;i++) { + if (mask[i]) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]); + *ptr = (GLubyte) LOOKUP( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + +/* + * Write an array of PF_GRAYSCALE pixels to an XImage. + */ +static void put_values_GRAYSCALE_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), + GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ) ); + } + } +} + + +/* + * Write an array of 8-bit PF_GRAYSCALE pixels to an XImage. + */ +static void put_values_GRAYSCALE8_ximage( PUT_VALUES_ARGS ) +{ + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i] ); + *ptr = (GLubyte) GRAY_RGB( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); + } + } +} + + + + +/**********************************************************************/ +/*** Write MONO COLOR SPAN functions ***/ +/**********************************************************************/ + +#define PUT_MONO_ROW_ARGS \ + GLcontext *ctx, struct gl_renderbuffer *rb, \ + GLuint n, GLint x, GLint y, const void *value, \ + const GLubyte mask[] + + + +/* + * Write a span of identical pixels to a pixmap. + */ +static void put_mono_row_pixmap( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP], + color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat); + register GLuint i; + XMesaSetForeground( xmesa->display, gc, pixel ); + y = YFLIP(xrb, y); + + /* New code contributed by Jeff Epler and cleaned up by Keith + * Whitwell. + */ + for (i = 0; i < n; ) { + GLuint start = i; + + /* Identify and emit contiguous rendered pixels + */ + while (i < n && (!mask || mask[i])) + i++; + + if (start < i) + XMesaFillRectangle( dpy, buffer, gc, + (int)(x+start), (int) y, + (int)(i-start), 1); + + /* Eat up non-rendered pixels + */ + while (i < n && !mask[i]) + i++; + } +} + + + +static void +put_mono_row_ci_pixmap( PUT_MONO_ROW_ARGS ) +{ + GLuint colorIndex = *((GLuint *) value); + XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + XMesaSetForeground( xmesa->display, gc, colorIndex ); + y = YFLIP(xrb, y); + + for (i = 0 ; i < n ;) { + GLuint start = i; + + /* Identify and emit contiguous rendered pixels + */ + while (i < n && (!mask || mask[i])) + i++; + + if (start < i) + XMesaFillRectangle( dpy, buffer, gc, + (int)(x+start), (int) y, + (int)(i-start), 1); + + /* Eat up non-rendered pixels + */ + while (i < n && !mask[i]) + i++; + } +} + + + +/* + * Write a span of PF_TRUEDITHER pixels to a pixmap. + */ +static void put_mono_row_TRUEDITHER_pixmap( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + register GLuint i; + int yy = YFLIP(xrb, y); + for (i=0;i<n;i++,x++) { + if (!mask || mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x, yy, r, g, b); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) yy ); + } + } +} + + +/* + * Write a span of PF_DITHER pixels to a pixmap. + */ +static void put_mono_row_DITHER_pixmap( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + register GLuint i; + int yy = YFLIP(xrb, y); + XDITHER_SETUP(yy); + for (i=0;i<n;i++,x++) { + if (!mask || mask[i]) { + XMesaSetForeground( dpy, gc, XDITHER( x, r, g, b ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) yy ); + } + } +} + + +/* + * Write a span of PF_1BIT pixels to a pixmap. + */ +static void put_mono_row_1BIT_pixmap( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + register GLuint i; + SETUP_1BIT; + y = YFLIP(xrb, y); + for (i=0;i<n;i++,x++) { + if (!mask || mask[i]) { + XMesaSetForeground( dpy, gc, DITHER_1BIT( x, y, r, g, b ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } +} + + +/* + * Write a span of identical pixels to an XImage. + */ +static void put_mono_row_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaImage *img = xrb->ximage; + register GLuint i; + const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP], + color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat); + y = YFLIP(xrb, y); + for (i=0;i<n;i++,x++) { + if (!mask || mask[i]) { + XMesaPutPixel( img, x, y, pixel ); + } + } +} + + +static void +put_mono_row_ci_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLuint colorIndex = *((GLuint *) value); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + y = YFLIP(xrb, y); + for (i=0;i<n;i++,x++) { + if (!mask || mask[i]) { + XMesaPutPixel( img, x, y, colorIndex ); + } + } +} + + +/* + * Write a span of identical PF_TRUEDITHER pixels to an XImage. + */ +static void put_mono_row_TRUEDITHER_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaImage *img = xrb->ximage; + const GLint r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + GLuint i; + y = YFLIP(xrb, y); + for (i=0;i<n;i++) { + if (!mask || mask[i]) { + unsigned long p; + PACK_TRUEDITHER( p, x+i, y, r, g, b); + XMesaPutPixel( img, x+i, y, p ); + } + } +} + + +/* + * Write a span of identical 8A8B8G8R pixels to an XImage. + */ +static void put_mono_row_8A8B8G8R_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaContext xmesa = XMESA_CONTEXT(ctx); + GLuint i, *ptr; + const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP], + color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat); + ptr = PIXEL_ADDR4(xrb, x, y ); + for (i=0;i<n;i++) { + if (!mask || mask[i]) { + ptr[i] = pixel; + } + } +} + +/* + * Write a span of identical 8A8R8G8B pixels to an XImage. + */ +static void put_mono_row_8A8R8G8B_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + GLuint i, *ptr; + XMesaContext xmesa = XMESA_CONTEXT(ctx); + const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP], + color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat); + ptr = PIXEL_ADDR4(xrb, x, y ); + for (i=0;i<n;i++) { + if (!mask || mask[i]) { + ptr[i] = pixel; + } + } +} + + +/* + * Write a span of identical 8R8G8B pixels to an XImage. + */ +static void put_mono_row_8R8G8B_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLuint pixel = PACK_8R8G8B(color[RCOMP], color[GCOMP], color[BCOMP]); + GLuint *ptr = PIXEL_ADDR4(xrb, x, y ); + GLuint i; + for (i=0;i<n;i++) { + if (!mask || mask[i]) { + ptr[i] = pixel; + } + } +} + + +/* + * Write a span of identical 8R8G8B pixels to an XImage. + */ +static void put_mono_row_8R8G8B24_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLubyte r = color[RCOMP]; + const GLubyte g = color[GCOMP]; + const GLubyte b = color[BCOMP]; + GLuint i; + bgr_t *ptr = PIXEL_ADDR3(xrb, x, y ); + for (i=0;i<n;i++) { + if (!mask || mask[i]) { + ptr[i].r = r; + ptr[i].g = g; + ptr[i].b = b; + } + } +} + + +/* + * Write a span of identical DITHER pixels to an XImage. + */ +static void put_mono_row_DITHER_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + XMesaImage *img = xrb->ximage; + int yy = YFLIP(xrb, y); + register GLuint i; + XDITHER_SETUP(yy); + for (i=0;i<n;i++,x++) { + if (!mask || mask[i]) { + XMesaPutPixel( img, x, yy, XDITHER( x, r, g, b ) ); + } + } +} + + +/* + * Write a span of identical 8-bit DITHER pixels to an XImage. + */ +static void put_mono_row_DITHER8_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + register GLuint i; + XDITHER_SETUP(y); + for (i=0;i<n;i++,x++) { + if (!mask || mask[i]) { + ptr[i] = (GLubyte) XDITHER( x, r, g, b ); + } + } +} + + +/* + * Write a span of identical 8-bit LOOKUP pixels to an XImage. + */ +static void put_mono_row_LOOKUP8_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + GLubyte pixel; + LOOKUP_SETUP; + pixel = LOOKUP(color[RCOMP], color[GCOMP], color[BCOMP]); + for (i=0;i<n;i++) { + if (!mask || mask[i]) { + ptr[i] = pixel; + } + } +} + + +/* + * Write a span of identical PF_1BIT pixels to an XImage. + */ +static void put_mono_row_1BIT_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + XMesaImage *img = xrb->ximage; + register GLuint i; + SETUP_1BIT; + y = YFLIP(xrb, y); + for (i=0;i<n;i++,x++) { + if (!mask || mask[i]) { + XMesaPutPixel( img, x, y, DITHER_1BIT( x, y, r, g, b ) ); + } + } +} + + +/* + * Write a span of identical HPCR pixels to an XImage. + */ +static void put_mono_row_HPCR_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + register GLubyte *ptr = PIXEL_ADDR1(xrb, x, y); + register GLuint i; + for (i=0;i<n;i++,x++) { + if (!mask || mask[i]) { + ptr[i] = DITHER_HPCR( x, y, r, g, b ); + } + } +} + + +/* + * Write a span of identical 8-bit GRAYSCALE pixels to an XImage. + */ +static void put_mono_row_GRAYSCALE8_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLubyte p = GRAY_RGB(color[RCOMP], color[GCOMP], color[BCOMP]); + GLubyte *ptr = (GLubyte *) PIXEL_ADDR1(xrb, x, y); + GLuint i; + for (i=0;i<n;i++) { + if (!mask || mask[i]) { + ptr[i] = p; + } + } +} + + + +/* + * Write a span of identical PF_DITHER_5R6G5B pixels to an XImage. + */ +static void put_mono_row_DITHER_5R6G5B_ximage( PUT_MONO_ROW_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + register GLushort *ptr = PIXEL_ADDR2(xrb, x, y ); + const GLint r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + GLuint i; + y = YFLIP(xrb, y); + for (i=0;i<n;i++) { + if (!mask || mask[i]) { + PACK_TRUEDITHER(ptr[i], x+i, y, r, g, b); + } + } +} + + + +/**********************************************************************/ +/*** Write MONO COLOR PIXELS functions ***/ +/**********************************************************************/ + +#define PUT_MONO_VALUES_ARGS \ + GLcontext *ctx, struct gl_renderbuffer *rb, \ + GLuint n, const GLint x[], const GLint y[], \ + const void *value, const GLubyte mask[] + + + +/* + * Write an array of identical pixels to a pixmap. + */ +static void put_mono_values_pixmap( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP], + color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat); + XMesaSetForeground( xmesa->display, gc, pixel ); + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaDrawPoint( dpy, buffer, gc, + (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +static void +put_mono_values_ci_pixmap( PUT_MONO_VALUES_ARGS ) +{ + const GLuint colorIndex = *((GLuint *) value); + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + XMesaSetForeground( xmesa->display, gc, colorIndex ); + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaDrawPoint( dpy, buffer, gc, + (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_TRUEDITHER pixels to a pixmap. + */ +static void put_mono_values_TRUEDITHER_pixmap( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + for (i=0;i<n;i++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x[i], y[i], r, g, b); + XMesaSetForeground( dpy, gc, p ); + XMesaDrawPoint( dpy, buffer, gc, + (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_DITHER pixels to a pixmap. + */ +static void put_mono_values_DITHER_pixmap( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + DITHER_SETUP; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, DITHER( x[i], y[i], r, g, b ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of PF_1BIT pixels to a pixmap. + */ +static void put_mono_values_1BIT_pixmap( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + SETUP_1BIT; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, DITHER_1BIT( x[i], y[i], r, g, b ) ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of identical pixels to an XImage. + */ +static void put_mono_values_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + const unsigned long pixel = xmesa_color_to_pixel(ctx, color[RCOMP], + color[GCOMP], color[BCOMP], color[ACOMP], xmesa->pixelformat); + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), pixel ); + } + } +} + + +static void +put_mono_values_ci_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLuint colorIndex = *((GLuint *) value); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), colorIndex ); + } + } +} + + +/* + * Write an array of identical TRUEDITHER pixels to an XImage. + */ +static void put_mono_values_TRUEDITHER_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + const int r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + for (i=0;i<n;i++) { + if (mask[i]) { + unsigned long p; + PACK_TRUEDITHER(p, x[i], YFLIP(xrb, y[i]), r, g, b); + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), p ); + } + } +} + + + +/* + * Write an array of identical 8A8B8G8R pixels to an XImage + */ +static void put_mono_values_8A8B8G8R_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLuint p = PACK_8A8B8G8R(color[RCOMP], color[GCOMP], + color[BCOMP], color[ACOMP]); + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i] ); + *ptr = p; + } + } +} + +/* + * Write an array of identical 8A8R8G8B pixels to an XImage + */ +static void put_mono_values_8A8R8G8B_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLuint p = PACK_8A8R8G8B(color[RCOMP], color[GCOMP], + color[BCOMP], color[ACOMP]); + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i] ); + *ptr = p; + } + } +} + +/* + * Write an array of identical 8R8G8B pixels to an XImage. + */ +static void put_mono_values_8R8G8B_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + const GLuint p = PACK_8R8G8B(color[RCOMP], color[GCOMP], color[BCOMP]); + for (i=0;i<n;i++) { + if (mask[i]) { + GLuint *ptr = PIXEL_ADDR4(xrb, x[i], y[i] ); + *ptr = p; + } + } +} + + +/* + * Write an array of identical 8R8G8B pixels to an XImage. + */ +static void put_mono_values_8R8G8B24_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + bgr_t *ptr = PIXEL_ADDR3(xrb, x[i], y[i] ); + ptr->r = r; + ptr->g = g; + ptr->b = b; + } + } +} + + +/* + * Write an array of identical PF_DITHER pixels to an XImage. + */ +static void put_mono_values_DITHER_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + XMesaImage *img = xrb->ximage; + register GLuint i; + DITHER_SETUP; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), DITHER( x[i], y[i], r, g, b ) ); + } + } +} + + +/* + * Write an array of identical 8-bit PF_DITHER pixels to an XImage. + */ +static void put_mono_values_DITHER8_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + register GLuint i; + DITHER_SETUP; + for (i=0;i<n;i++) { + if (mask[i]) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]); + *ptr = (GLubyte) DITHER( x[i], y[i], r, g, b ); + } + } +} + + +/* + * Write an array of identical 8-bit PF_LOOKUP pixels to an XImage. + */ +static void put_mono_values_LOOKUP8_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + GLubyte pixel; + LOOKUP_SETUP; + pixel = LOOKUP(color[RCOMP], color[GCOMP], color[BCOMP]); + for (i=0;i<n;i++) { + if (mask[i]) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]); + *ptr = pixel; + } + } +} + + + +/* + * Write an array of identical PF_1BIT pixels to an XImage. + */ +static void put_mono_values_1BIT_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + XMesaImage *img = xrb->ximage; + register GLuint i; + SETUP_1BIT; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaPutPixel( img, x[i], YFLIP(xrb, y[i]), + DITHER_1BIT( x[i], y[i], r, g, b )); + } + } +} + + +/* + * Write an array of identical PF_HPCR pixels to an XImage. + */ +static void put_mono_values_HPCR_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + const GLubyte r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]); + *ptr = DITHER_HPCR( x[i], y[i], r, g, b ); + } + } +} + + +/* + * Write an array of identical 8-bit PF_GRAYSCALE pixels to an XImage. + */ +static void put_mono_values_GRAYSCALE8_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + register GLuint i; + register GLubyte p = GRAY_RGB(color[RCOMP], color[GCOMP], color[BCOMP]); + for (i=0;i<n;i++) { + if (mask[i]) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x[i], y[i]); + *ptr = p; + } + } +} + + +/* + * Write an array of identical PF_DITHER_5R6G5B pixels to an XImage. + */ +static void put_mono_values_DITHER_5R6G5B_ximage( PUT_MONO_VALUES_ARGS ) +{ + const GLubyte *color = (const GLubyte *) value; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + const int r = color[RCOMP], g = color[GCOMP], b = color[BCOMP]; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + GLushort *ptr = PIXEL_ADDR2(xrb, x[i], y[i] ); + PACK_TRUEDITHER(*ptr, x[i], y[i], r, g, b); + } + } +} + + + +/**********************************************************************/ +/*** Write INDEX SPAN functions ***/ +/**********************************************************************/ + +/* + * Write a span of CI pixels to a Pixmap. + */ +static void put_row_ci_pixmap( PUT_ROW_ARGS ) +{ + const GLuint *index = (GLuint *) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, (unsigned long) index[i] ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } + } + else { + for (i=0;i<n;i++,x++) { + XMesaSetForeground( dpy, gc, (unsigned long) index[i] ); + XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); + } + } +} + + +/* + * Write a span of CI pixels to an XImage. + */ +static void put_row_ci_ximage( PUT_ROW_ARGS ) +{ + const GLuint *index = (const GLuint *) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + y = YFLIP(xrb, y); + if (mask) { + for (i=0;i<n;i++,x++) { + if (mask[i]) { + XMesaPutPixel( img, x, y, (unsigned long) index[i] ); + } + } + } + else { + for (i=0;i<n;i++,x++) { + XMesaPutPixel( img, x, y, (unsigned long) index[i] ); + } + } +} + + +/**********************************************************************/ +/*** Write INDEX PIXELS functions ***/ +/**********************************************************************/ + +/* + * Write an array of CI pixels to a Pixmap. + */ +static void put_values_ci_pixmap( PUT_VALUES_ARGS ) +{ + const GLuint *index = (const GLuint *) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaDrawable buffer = xrb->drawable; + XMesaGC gc = XMESA_BUFFER(ctx->DrawBuffer)->gc; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaSetForeground( dpy, gc, (unsigned long) index[i] ); + XMesaDrawPoint( dpy, buffer, gc, (int) x[i], (int) YFLIP(xrb, y[i]) ); + } + } +} + + +/* + * Write an array of CI pixels to an XImage. + */ +static void put_values_ci_ximage( PUT_VALUES_ARGS ) +{ + const GLuint *index = (const GLuint *) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaImage *img = xrb->ximage; + register GLuint i; + for (i=0;i<n;i++) { + if (mask[i]) { + XMesaPutPixel(img, x[i], YFLIP(xrb, y[i]), (unsigned long) index[i]); + } + } +} + + + + +/**********************************************************************/ +/***** Pixel reading *****/ +/**********************************************************************/ + +#ifndef XFree86Server +/** + * Do clip testing prior to calling XGetImage. If any of the region lies + * outside the screen's bounds, XGetImage will return NULL. + * We use XTranslateCoordinates() to check if that's the case and + * adjust the x, y and length parameters accordingly. + * \return -1 if span is totally clipped away, + * else return number of pixels to skip in the destination array. + */ +static int +clip_for_xgetimage(GLcontext *ctx, GLuint *n, GLint *x, GLint *y) +{ + XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer); + Window rootWin = RootWindow(xmesa->display, 0); + Window child; + GLint screenWidth = WidthOfScreen(DefaultScreenOfDisplay(xmesa->display)); + GLint dx, dy; + if (source->type == PBUFFER || source->type == PIXMAP) + return 0; + XTranslateCoordinates(xmesa->display, source->frontxrb->pixmap, rootWin, + *x, *y, &dx, &dy, &child); + if (dx >= screenWidth) { + /* totally clipped on right */ + return -1; + } + if (dx < 0) { + /* clipped on left */ + GLint clip = -dx; + if (clip >= (GLint) *n) + return -1; /* totally clipped on left */ + *x += clip; + *n -= clip; + dx = 0; + return clip; + } + if ((GLint) (dx + *n) > screenWidth) { + /* clipped on right */ + GLint clip = dx + *n - screenWidth; + *n -= clip; + } + return 0; +} +#endif + + +/* + * Read a horizontal span of color-index pixels. + */ +static void +get_row_ci(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, void *values) +{ + GLuint *index = (GLuint *) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + GLuint i; + + y = YFLIP(xrb, y); + + if (xrb->pixmap) { +#ifndef XFree86Server + XMesaImage *span = NULL; + int error; + int k = clip_for_xgetimage(ctx, &n, &x, &y); + if (k < 0) + return; + index += k; + + catch_xgetimage_errors( xmesa->display ); + span = XGetImage( xmesa->display, xrb->pixmap, + x, y, n, 1, AllPlanes, ZPixmap ); + error = check_xgetimage_errors(); + if (span && !error) { + for (i=0;i<n;i++) { + index[i] = (GLuint) XMesaGetPixel( span, i, 0 ); + } + } + else { + /* return 0 pixels */ + for (i=0;i<n;i++) { + index[i] = 0; + } + } + if (span) { + XMesaDestroyImage( span ); + } +#else + (*xmesa->display->GetImage)(xrb->drawable, + x, y, n, 1, ZPixmap, + ~0L, (pointer)index); +#endif + } + else if (xrb->ximage) { + XMesaImage *img = xrb->ximage; + for (i=0;i<n;i++,x++) { + index[i] = (GLuint) XMesaGetPixel( img, x, y ); + } + } +} + + + +/* + * Read a horizontal span of color pixels. + */ +static void +get_row_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, void *values) +{ + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer); + + if (xrb->pixmap) { + /* Read from Pixmap or Window */ + XMesaImage *span = NULL; + int error; +#ifdef XFree86Server + span = XMesaCreateImage(xmesa->xm_visual->BitsPerPixel, n, 1, NULL); + span->data = (char *)MALLOC(span->height * span->bytes_per_line); + error = (!span->data); + (*xmesa->display->GetImage)(xrb->drawable, + x, YFLIP(xrb, y), n, 1, ZPixmap, + ~0L, (pointer)span->data); +#else + int k; + y = YFLIP(xrb, y); + k = clip_for_xgetimage(ctx, &n, &x, &y); + if (k < 0) + return; + rgba += k; + catch_xgetimage_errors( xmesa->display ); + span = XGetImage( xmesa->display, xrb->pixmap, + x, y, n, 1, AllPlanes, ZPixmap ); + error = check_xgetimage_errors(); +#endif + if (span && !error) { + switch (xmesa->pixelformat) { + case PF_Truecolor: + case PF_Dither_True: + { + const GLubyte *pixelToR = xmesa->xm_visual->PixelToR; + const GLubyte *pixelToG = xmesa->xm_visual->PixelToG; + const GLubyte *pixelToB = xmesa->xm_visual->PixelToB; + unsigned long rMask = GET_REDMASK(xmesa->xm_visual); + unsigned long gMask = GET_GREENMASK(xmesa->xm_visual); + unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual); + GLint rShift = xmesa->xm_visual->rshift; + GLint gShift = xmesa->xm_visual->gshift; + GLint bShift = xmesa->xm_visual->bshift; + GLuint i; + for (i=0;i<n;i++) { + unsigned long p; + p = XMesaGetPixel( span, i, 0 ); + rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift]; + rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift]; + rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift]; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_5R6G5B: + case PF_Dither_5R6G5B: + { + const GLubyte *pixelToR = xmesa->xm_visual->PixelToR; + const GLubyte *pixelToG = xmesa->xm_visual->PixelToG; + const GLubyte *pixelToB = xmesa->xm_visual->PixelToB; + GLuint i; + for (i=0;i<n;i++) { + unsigned long p = XMesaGetPixel( span, i, 0 ); + /* fast, but not quite accurate + rgba[i][RCOMP] = ((p >> 8) & 0xf8); + rgba[i][GCOMP] = ((p >> 3) & 0xfc); + rgba[i][BCOMP] = ((p << 3) & 0xff); + */ + rgba[i][RCOMP] = pixelToR[p >> 11]; + rgba[i][GCOMP] = pixelToG[(p >> 5) & 0x3f]; + rgba[i][BCOMP] = pixelToB[p & 0x1f]; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_8A8B8G8R: + { + const GLuint *ptr4 = (GLuint *) span->data; + GLuint i; + for (i=0;i<n;i++) { + GLuint p4 = *ptr4++; + rgba[i][RCOMP] = (GLubyte) ( p4 & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ((p4 >> 16) & 0xff); + rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff); + } + } + break; + case PF_8A8R8G8B: + { + const GLuint *ptr4 = (GLuint *) span->data; + GLuint i; + for (i=0;i<n;i++) { + GLuint p4 = *ptr4++; + rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff); + rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff); + } + } + break; + case PF_8R8G8B: + { + const GLuint *ptr4 = (GLuint *) span->data; + GLuint i; + for (i=0;i<n;i++) { + GLuint p4 = *ptr4++; + rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff); + rgba[i][ACOMP] = 255; + } + } + break; + case PF_8R8G8B24: + { + const bgr_t *ptr3 = (bgr_t *) span->data; + GLuint i; + for (i=0;i<n;i++) { + rgba[i][RCOMP] = ptr3[i].r; + rgba[i][GCOMP] = ptr3[i].g; + rgba[i][BCOMP] = ptr3[i].b; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_HPCR: + { + GLubyte *ptr1 = (GLubyte *) span->data; + GLuint i; + for (i=0;i<n;i++) { + GLubyte p = *ptr1++; + rgba[i][RCOMP] = p & 0xE0; + rgba[i][GCOMP] = (p & 0x1C) << 3; + rgba[i][BCOMP] = (p & 0x03) << 6; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_Dither: + case PF_Lookup: + case PF_Grayscale: + { + GLubyte *rTable = source->pixel_to_r; + GLubyte *gTable = source->pixel_to_g; + GLubyte *bTable = source->pixel_to_b; + if (GET_VISUAL_DEPTH(xmesa->xm_visual)==8) { + const GLubyte *ptr1 = (GLubyte *) span->data; + GLuint i; + for (i=0;i<n;i++) { + unsigned long p = *ptr1++; + rgba[i][RCOMP] = rTable[p]; + rgba[i][GCOMP] = gTable[p]; + rgba[i][BCOMP] = bTable[p]; + rgba[i][ACOMP] = 255; + } + } + else { + GLuint i; + for (i=0;i<n;i++) { + unsigned long p = XMesaGetPixel( span, i, 0 ); + rgba[i][RCOMP] = rTable[p]; + rgba[i][GCOMP] = gTable[p]; + rgba[i][BCOMP] = bTable[p]; + rgba[i][ACOMP] = 255; + } + } + } + break; + case PF_1Bit: + { + int bitFlip = xmesa->xm_visual->bitFlip; + GLuint i; + for (i=0;i<n;i++) { + unsigned long p; + p = XMesaGetPixel( span, i, 0 ) ^ bitFlip; + rgba[i][RCOMP] = (GLubyte) (p * 255); + rgba[i][GCOMP] = (GLubyte) (p * 255); + rgba[i][BCOMP] = (GLubyte) (p * 255); + rgba[i][ACOMP] = 255; + } + } + break; + default: + _mesa_problem(NULL,"Problem in DD.read_color_span (1)"); + return; + } + } + else { + /* return black pixels */ + GLuint i; + for (i=0;i<n;i++) { + rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = rgba[i][ACOMP] = 0; + } + } + if (span) { + XMesaDestroyImage( span ); + } + } + else if (xrb->ximage) { + /* Read from XImage back buffer */ + switch (xmesa->pixelformat) { + case PF_Truecolor: + case PF_Dither_True: + { + const GLubyte *pixelToR = xmesa->xm_visual->PixelToR; + const GLubyte *pixelToG = xmesa->xm_visual->PixelToG; + const GLubyte *pixelToB = xmesa->xm_visual->PixelToB; + unsigned long rMask = GET_REDMASK(xmesa->xm_visual); + unsigned long gMask = GET_GREENMASK(xmesa->xm_visual); + unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual); + GLint rShift = xmesa->xm_visual->rshift; + GLint gShift = xmesa->xm_visual->gshift; + GLint bShift = xmesa->xm_visual->bshift; + XMesaImage *img = xrb->ximage; + GLuint i; + y = YFLIP(xrb, y); + for (i=0;i<n;i++) { + unsigned long p; + p = XMesaGetPixel( img, x+i, y ); + rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift]; + rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift]; + rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift]; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_5R6G5B: + case PF_Dither_5R6G5B: + { + const GLubyte *pixelToR = xmesa->xm_visual->PixelToR; + const GLubyte *pixelToG = xmesa->xm_visual->PixelToG; + const GLubyte *pixelToB = xmesa->xm_visual->PixelToB; + const GLushort *ptr2 = PIXEL_ADDR2(xrb, x, y); + GLuint i; +#if defined(__i386__) /* word stores don't have to be on 4-byte boundaries */ + const GLuint *ptr4 = (const GLuint *) ptr2; + GLuint extraPixel = (n & 1); + n -= extraPixel; + for (i = 0; i < n; i += 2) { + const GLuint p = *ptr4++; + const GLuint p0 = p & 0xffff; + const GLuint p1 = p >> 16; + /* fast, but not quite accurate + rgba[i][RCOMP] = ((p >> 8) & 0xf8); + rgba[i][GCOMP] = ((p >> 3) & 0xfc); + rgba[i][BCOMP] = ((p << 3) & 0xff); + */ + rgba[i][RCOMP] = pixelToR[p0 >> 11]; + rgba[i][GCOMP] = pixelToG[(p0 >> 5) & 0x3f]; + rgba[i][BCOMP] = pixelToB[p0 & 0x1f]; + rgba[i][ACOMP] = 255; + rgba[i+1][RCOMP] = pixelToR[p1 >> 11]; + rgba[i+1][GCOMP] = pixelToG[(p1 >> 5) & 0x3f]; + rgba[i+1][BCOMP] = pixelToB[p1 & 0x1f]; + rgba[i+1][ACOMP] = 255; + } + if (extraPixel) { + GLushort p = ptr2[n]; + rgba[n][RCOMP] = pixelToR[p >> 11]; + rgba[n][GCOMP] = pixelToG[(p >> 5) & 0x3f]; + rgba[n][BCOMP] = pixelToB[p & 0x1f]; + rgba[n][ACOMP] = 255; + } +#else + for (i = 0; i < n; i++) { + const GLushort p = ptr2[i]; + rgba[i][RCOMP] = pixelToR[p >> 11]; + rgba[i][GCOMP] = pixelToG[(p >> 5) & 0x3f]; + rgba[i][BCOMP] = pixelToB[p & 0x1f]; + rgba[i][ACOMP] = 255; + } +#endif + } + break; + case PF_8A8B8G8R: + { + const GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y); + GLuint i; + for (i=0;i<n;i++) { + GLuint p4 = *ptr4++; + rgba[i][RCOMP] = (GLubyte) ( p4 & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ((p4 >> 16) & 0xff); + rgba[i][ACOMP] = (GLint) ((p4 >> 24) & 0xff); + } + } + break; + case PF_8A8R8G8B: + { + const GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y); + GLuint i; + for (i=0;i<n;i++) { + GLuint p4 = *ptr4++; + rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff); + rgba[i][ACOMP] = (GLint) ((p4 >> 24) & 0xff); + } + } + break; + case PF_8R8G8B: + { + const GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y); + GLuint i; + for (i=0;i<n;i++) { + GLuint p4 = *ptr4++; + rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff); + rgba[i][ACOMP] = 255; + } + } + break; + case PF_8R8G8B24: + { + const bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y); + GLuint i; + for (i=0;i<n;i++) { + rgba[i][RCOMP] = ptr3[i].r; + rgba[i][GCOMP] = ptr3[i].g; + rgba[i][BCOMP] = ptr3[i].b; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_HPCR: + { + const GLubyte *ptr1 = PIXEL_ADDR1(xrb, x, y); + GLuint i; + for (i=0;i<n;i++) { + GLubyte p = *ptr1++; + rgba[i][RCOMP] = p & 0xE0; + rgba[i][GCOMP] = (p & 0x1C) << 3; + rgba[i][BCOMP] = (p & 0x03) << 6; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_Dither: + case PF_Lookup: + case PF_Grayscale: + { + const GLubyte *rTable = source->pixel_to_r; + const GLubyte *gTable = source->pixel_to_g; + const GLubyte *bTable = source->pixel_to_b; + if (GET_VISUAL_DEPTH(xmesa->xm_visual)==8) { + GLubyte *ptr1 = PIXEL_ADDR1(xrb, x, y); + GLuint i; + for (i=0;i<n;i++) { + unsigned long p = *ptr1++; + rgba[i][RCOMP] = rTable[p]; + rgba[i][GCOMP] = gTable[p]; + rgba[i][BCOMP] = bTable[p]; + rgba[i][ACOMP] = 255; + } + } + else { + XMesaImage *img = xrb->ximage; + GLuint i; + y = YFLIP(xrb, y); + for (i=0;i<n;i++,x++) { + unsigned long p = XMesaGetPixel( img, x, y ); + rgba[i][RCOMP] = rTable[p]; + rgba[i][GCOMP] = gTable[p]; + rgba[i][BCOMP] = bTable[p]; + rgba[i][ACOMP] = 255; + } + } + } + break; + case PF_1Bit: + { + XMesaImage *img = xrb->ximage; + int bitFlip = xmesa->xm_visual->bitFlip; + GLuint i; + y = YFLIP(xrb, y); + for (i=0;i<n;i++,x++) { + unsigned long p; + p = XMesaGetPixel( img, x, y ) ^ bitFlip; + rgba[i][RCOMP] = (GLubyte) (p * 255); + rgba[i][GCOMP] = (GLubyte) (p * 255); + rgba[i][BCOMP] = (GLubyte) (p * 255); + rgba[i][ACOMP] = 255; + } + } + break; + default: + _mesa_problem(NULL,"Problem in DD.read_color_span (2)"); + return; + } + } +} + + + +/* + * Read an array of color index pixels. + */ +static void +get_values_ci(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], void *values) +{ + GLuint *indx = (GLuint *) values; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + GLuint i; + if (xrb->pixmap) { + for (i=0;i<n;i++) { + indx[i] = (GLuint) read_pixel( xmesa->display, xrb->drawable, + x[i], YFLIP(xrb, y[i]) ); + } + } + else if (xrb->ximage) { + XMesaImage *img = xrb->ximage; + for (i=0;i<n;i++) { + indx[i] = (GLuint) XMesaGetPixel( img, x[i], YFLIP(xrb, y[i]) ); + } + } +} + + + +static void +get_values_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], void *values) +{ + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; + struct xmesa_renderbuffer *xrb = (struct xmesa_renderbuffer *) rb; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaDisplay *dpy = xmesa->xm_visual->display; + XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer); + register GLuint i; + + if (xrb->pixmap) { + XMesaDrawable buffer = xrb->drawable; + switch (xmesa->pixelformat) { + case PF_Truecolor: + case PF_Dither_True: + case PF_5R6G5B: + case PF_Dither_5R6G5B: + { + unsigned long rMask = GET_REDMASK(xmesa->xm_visual); + unsigned long gMask = GET_GREENMASK(xmesa->xm_visual); + unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual); + GLubyte *pixelToR = xmesa->xm_visual->PixelToR; + GLubyte *pixelToG = xmesa->xm_visual->PixelToG; + GLubyte *pixelToB = xmesa->xm_visual->PixelToB; + GLint rShift = xmesa->xm_visual->rshift; + GLint gShift = xmesa->xm_visual->gshift; + GLint bShift = xmesa->xm_visual->bshift; + for (i=0;i<n;i++) { + unsigned long p = read_pixel( dpy, buffer, + x[i], YFLIP(xrb, y[i]) ); + rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift]; + rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift]; + rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift]; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_8A8B8G8R: + for (i=0;i<n;i++) { + unsigned long p = read_pixel( dpy, buffer, + x[i], YFLIP(xrb, y[i]) ); + rgba[i][RCOMP] = (GLubyte) ( p & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ((p >> 16) & 0xff); + rgba[i][ACOMP] = (GLubyte) ((p >> 24) & 0xff); + } + break; + case PF_8A8R8G8B: + for (i=0;i<n;i++) { + unsigned long p = read_pixel( dpy, buffer, + x[i], YFLIP(xrb, y[i]) ); + rgba[i][RCOMP] = (GLubyte) ((p >> 16) & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ( p & 0xff); + rgba[i][ACOMP] = (GLubyte) ((p >> 24) & 0xff); + } + break; + case PF_8R8G8B: + for (i=0;i<n;i++) { + unsigned long p = read_pixel( dpy, buffer, + x[i], YFLIP(xrb, y[i]) ); + rgba[i][RCOMP] = (GLubyte) ((p >> 16) & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ( p & 0xff); + rgba[i][ACOMP] = 255; + } + break; + case PF_8R8G8B24: + for (i=0;i<n;i++) { + unsigned long p = read_pixel( dpy, buffer, + x[i], YFLIP(xrb, y[i]) ); + rgba[i][RCOMP] = (GLubyte) ((p >> 16) & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ( p & 0xff); + rgba[i][ACOMP] = 255; + } + break; + case PF_HPCR: + for (i=0;i<n;i++) { + unsigned long p = read_pixel( dpy, buffer, + x[i], YFLIP(xrb, y[i]) ); + rgba[i][RCOMP] = (GLubyte) ( p & 0xE0 ); + rgba[i][GCOMP] = (GLubyte) ((p & 0x1C) << 3); + rgba[i][BCOMP] = (GLubyte) ((p & 0x03) << 6); + rgba[i][ACOMP] = (GLubyte) 255; + } + break; + case PF_Dither: + case PF_Lookup: + case PF_Grayscale: + { + GLubyte *rTable = source->pixel_to_r; + GLubyte *gTable = source->pixel_to_g; + GLubyte *bTable = source->pixel_to_b; + for (i=0;i<n;i++) { + unsigned long p = read_pixel( dpy, buffer, + x[i], YFLIP(xrb, y[i]) ); + rgba[i][RCOMP] = rTable[p]; + rgba[i][GCOMP] = gTable[p]; + rgba[i][BCOMP] = bTable[p]; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_1Bit: + { + int bitFlip = xmesa->xm_visual->bitFlip; + for (i=0;i<n;i++) { + unsigned long p = read_pixel( dpy, buffer, + x[i], YFLIP(xrb, y[i])) ^ bitFlip; + rgba[i][RCOMP] = (GLubyte) (p * 255); + rgba[i][GCOMP] = (GLubyte) (p * 255); + rgba[i][BCOMP] = (GLubyte) (p * 255); + rgba[i][ACOMP] = 255; + } + } + break; + default: + _mesa_problem(NULL,"Problem in DD.read_color_pixels (1)"); + return; + } + } + else if (xrb->ximage) { + /* Read from XImage back buffer */ + switch (xmesa->pixelformat) { + case PF_Truecolor: + case PF_Dither_True: + case PF_5R6G5B: + case PF_Dither_5R6G5B: + { + unsigned long rMask = GET_REDMASK(xmesa->xm_visual); + unsigned long gMask = GET_GREENMASK(xmesa->xm_visual); + unsigned long bMask = GET_BLUEMASK(xmesa->xm_visual); + GLubyte *pixelToR = xmesa->xm_visual->PixelToR; + GLubyte *pixelToG = xmesa->xm_visual->PixelToG; + GLubyte *pixelToB = xmesa->xm_visual->PixelToB; + GLint rShift = xmesa->xm_visual->rshift; + GLint gShift = xmesa->xm_visual->gshift; + GLint bShift = xmesa->xm_visual->bshift; + XMesaImage *img = xrb->ximage; + for (i=0;i<n;i++) { + unsigned long p; + p = XMesaGetPixel( img, x[i], YFLIP(xrb, y[i]) ); + rgba[i][RCOMP] = pixelToR[(p & rMask) >> rShift]; + rgba[i][GCOMP] = pixelToG[(p & gMask) >> gShift]; + rgba[i][BCOMP] = pixelToB[(p & bMask) >> bShift]; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_8A8B8G8R: + for (i=0;i<n;i++) { + GLuint *ptr4 = PIXEL_ADDR4(xrb, x[i], y[i]); + GLuint p4 = *ptr4; + rgba[i][RCOMP] = (GLubyte) ( p4 & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ((p4 >> 16) & 0xff); + rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff); + } + break; + case PF_8A8R8G8B: + for (i=0;i<n;i++) { + GLuint *ptr4 = PIXEL_ADDR4(xrb, x[i], y[i]); + GLuint p4 = *ptr4; + rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff); + rgba[i][ACOMP] = (GLubyte) ((p4 >> 24) & 0xff); + } + break; + case PF_8R8G8B: + for (i=0;i<n;i++) { + GLuint *ptr4 = PIXEL_ADDR4(xrb, x[i], y[i]); + GLuint p4 = *ptr4; + rgba[i][RCOMP] = (GLubyte) ((p4 >> 16) & 0xff); + rgba[i][GCOMP] = (GLubyte) ((p4 >> 8) & 0xff); + rgba[i][BCOMP] = (GLubyte) ( p4 & 0xff); + rgba[i][ACOMP] = 255; + } + break; + case PF_8R8G8B24: + for (i=0;i<n;i++) { + bgr_t *ptr3 = PIXEL_ADDR3(xrb, x[i], y[i]); + rgba[i][RCOMP] = ptr3->r; + rgba[i][GCOMP] = ptr3->g; + rgba[i][BCOMP] = ptr3->b; + rgba[i][ACOMP] = 255; + } + break; + case PF_HPCR: + for (i=0;i<n;i++) { + GLubyte *ptr1 = PIXEL_ADDR1(xrb, x[i], y[i]); + GLubyte p = *ptr1; + rgba[i][RCOMP] = p & 0xE0; + rgba[i][GCOMP] = (p & 0x1C) << 3; + rgba[i][BCOMP] = (p & 0x03) << 6; + rgba[i][ACOMP] = 255; + } + break; + case PF_Dither: + case PF_Lookup: + case PF_Grayscale: + { + GLubyte *rTable = source->pixel_to_r; + GLubyte *gTable = source->pixel_to_g; + GLubyte *bTable = source->pixel_to_b; + XMesaImage *img = xrb->ximage; + for (i=0;i<n;i++) { + unsigned long p; + p = XMesaGetPixel( img, x[i], YFLIP(xrb, y[i]) ); + rgba[i][RCOMP] = rTable[p]; + rgba[i][GCOMP] = gTable[p]; + rgba[i][BCOMP] = bTable[p]; + rgba[i][ACOMP] = 255; + } + } + break; + case PF_1Bit: + { + XMesaImage *img = xrb->ximage; + int bitFlip = xmesa->xm_visual->bitFlip; + for (i=0;i<n;i++) { + unsigned long p; + p = XMesaGetPixel( img, x[i], YFLIP(xrb, y[i]) ) ^ bitFlip; + rgba[i][RCOMP] = (GLubyte) (p * 255); + rgba[i][GCOMP] = (GLubyte) (p * 255); + rgba[i][BCOMP] = (GLubyte) (p * 255); + rgba[i][ACOMP] = 255; + } + } + break; + default: + _mesa_problem(NULL,"Problem in DD.read_color_pixels (1)"); + return; + } + } +} + + +/** + * Initialize the renderbuffer's PutRow, GetRow, etc. functions. + * This would generally only need to be called once when the renderbuffer + * is created. However, we can change pixel formats on the fly if dithering + * is enabled/disabled. Therefore, we may call this more often than that. + */ +void +xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb, + enum pixel_format pixelformat, GLint depth) +{ + const GLboolean pixmap = xrb->pixmap ? GL_TRUE : GL_FALSE; + + switch (pixelformat) { + case PF_Index: + ASSERT(xrb->Base.DataType == GL_UNSIGNED_INT); + if (pixmap) { + xrb->Base.PutRow = put_row_ci_pixmap; + xrb->Base.PutRowRGB = NULL; + xrb->Base.PutMonoRow = put_mono_row_ci_pixmap; + xrb->Base.PutValues = put_values_ci_pixmap; + xrb->Base.PutMonoValues = put_mono_values_ci_pixmap; + } + else { + xrb->Base.PutRow = put_row_ci_ximage; + xrb->Base.PutRowRGB = NULL; + xrb->Base.PutMonoRow = put_mono_row_ci_ximage; + xrb->Base.PutValues = put_values_ci_ximage; + xrb->Base.PutMonoValues = put_mono_values_ci_ximage; + } + break; + case PF_Truecolor: + if (pixmap) { + xrb->Base.PutRow = put_row_TRUECOLOR_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_TRUECOLOR_pixmap; + xrb->Base.PutMonoRow = put_mono_row_pixmap; + xrb->Base.PutValues = put_values_TRUECOLOR_pixmap; + xrb->Base.PutMonoValues = put_mono_values_pixmap; + } + else { + xrb->Base.PutRow = put_row_TRUECOLOR_ximage; + xrb->Base.PutRowRGB = put_row_rgb_TRUECOLOR_ximage; + xrb->Base.PutMonoRow = put_mono_row_ximage; + xrb->Base.PutValues = put_values_TRUECOLOR_ximage; + xrb->Base.PutMonoValues = put_mono_values_ximage; + } + break; + case PF_Dither_True: + if (pixmap) { + xrb->Base.PutRow = put_row_TRUEDITHER_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_TRUEDITHER_pixmap; + xrb->Base.PutMonoRow = put_mono_row_TRUEDITHER_pixmap; + xrb->Base.PutValues = put_values_TRUEDITHER_pixmap; + xrb->Base.PutMonoValues = put_mono_values_TRUEDITHER_pixmap; + } + else { + xrb->Base.PutRow = put_row_TRUEDITHER_ximage; + xrb->Base.PutRowRGB = put_row_rgb_TRUEDITHER_ximage; + xrb->Base.PutMonoRow = put_mono_row_TRUEDITHER_ximage; + xrb->Base.PutValues = put_values_TRUEDITHER_ximage; + xrb->Base.PutMonoValues = put_mono_values_TRUEDITHER_ximage; + } + break; + case PF_8A8B8G8R: + if (pixmap) { + xrb->Base.PutRow = put_row_8A8B8G8R_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_8A8B8G8R_pixmap; + xrb->Base.PutMonoRow = put_mono_row_pixmap; + xrb->Base.PutValues = put_values_8A8B8G8R_pixmap; + xrb->Base.PutMonoValues = put_mono_values_pixmap; + } + else { + xrb->Base.PutRow = put_row_8A8B8G8R_ximage; + xrb->Base.PutRowRGB = put_row_rgb_8A8B8G8R_ximage; + xrb->Base.PutMonoRow = put_mono_row_8A8B8G8R_ximage; + xrb->Base.PutValues = put_values_8A8B8G8R_ximage; + xrb->Base.PutMonoValues = put_mono_values_8A8B8G8R_ximage; + } + break; + case PF_8A8R8G8B: + if (pixmap) { + xrb->Base.PutRow = put_row_8A8R8G8B_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_8A8R8G8B_pixmap; + xrb->Base.PutMonoRow = put_mono_row_pixmap; + xrb->Base.PutValues = put_values_8A8R8G8B_pixmap; + xrb->Base.PutMonoValues = put_mono_values_pixmap; + } + else { + xrb->Base.PutRow = put_row_8A8R8G8B_ximage; + xrb->Base.PutRowRGB = put_row_rgb_8A8R8G8B_ximage; + xrb->Base.PutMonoRow = put_mono_row_8A8R8G8B_ximage; + xrb->Base.PutValues = put_values_8A8R8G8B_ximage; + xrb->Base.PutMonoValues = put_mono_values_8A8R8G8B_ximage; + } + break; + case PF_8R8G8B: + if (pixmap) { + xrb->Base.PutRow = put_row_8R8G8B_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_8R8G8B_pixmap; + xrb->Base.PutMonoRow = put_mono_row_pixmap; + xrb->Base.PutValues = put_values_8R8G8B_pixmap; + xrb->Base.PutMonoValues = put_mono_values_pixmap; + } + else { + xrb->Base.PutRow = put_row_8R8G8B_ximage; + xrb->Base.PutRowRGB = put_row_rgb_8R8G8B_ximage; + xrb->Base.PutMonoRow = put_mono_row_8R8G8B_ximage; + xrb->Base.PutValues = put_values_8R8G8B_ximage; + xrb->Base.PutMonoValues = put_mono_values_8R8G8B_ximage; + } + break; + case PF_8R8G8B24: + if (pixmap) { + xrb->Base.PutRow = put_row_8R8G8B24_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_8R8G8B24_pixmap; + xrb->Base.PutMonoRow = put_mono_row_pixmap; + xrb->Base.PutValues = put_values_8R8G8B24_pixmap; + xrb->Base.PutMonoValues = put_mono_values_pixmap; + } + else { + xrb->Base.PutRow = put_row_8R8G8B24_ximage; + xrb->Base.PutRowRGB = put_row_rgb_8R8G8B24_ximage; + xrb->Base.PutMonoRow = put_mono_row_8R8G8B24_ximage; + xrb->Base.PutValues = put_values_8R8G8B24_ximage; + xrb->Base.PutMonoValues = put_mono_values_8R8G8B24_ximage; + } + break; + case PF_5R6G5B: + if (pixmap) { + xrb->Base.PutRow = put_row_5R6G5B_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_5R6G5B_pixmap; + xrb->Base.PutMonoRow = put_mono_row_pixmap; + xrb->Base.PutValues = put_values_5R6G5B_pixmap; + xrb->Base.PutMonoValues = put_mono_values_pixmap; + } + else { + xrb->Base.PutRow = put_row_5R6G5B_ximage; + xrb->Base.PutRowRGB = put_row_rgb_5R6G5B_ximage; + xrb->Base.PutMonoRow = put_mono_row_ximage; + xrb->Base.PutValues = put_values_5R6G5B_ximage; + xrb->Base.PutMonoValues = put_mono_values_ximage; + } + break; + case PF_Dither_5R6G5B: + if (pixmap) { + xrb->Base.PutRow = put_row_DITHER_5R6G5B_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_DITHER_5R6G5B_pixmap; + xrb->Base.PutMonoRow = put_mono_row_TRUEDITHER_pixmap; + xrb->Base.PutValues = put_values_DITHER_5R6G5B_pixmap; + xrb->Base.PutMonoValues = put_mono_values_TRUEDITHER_pixmap; + } + else { + xrb->Base.PutRow = put_row_DITHER_5R6G5B_ximage; + xrb->Base.PutRowRGB = put_row_rgb_DITHER_5R6G5B_ximage; + xrb->Base.PutMonoRow = put_mono_row_DITHER_5R6G5B_ximage; + xrb->Base.PutValues = put_values_DITHER_5R6G5B_ximage; + xrb->Base.PutMonoValues = put_mono_values_DITHER_5R6G5B_ximage; + } + break; + case PF_Dither: + if (pixmap) { + xrb->Base.PutRow = put_row_DITHER_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_DITHER_pixmap; + xrb->Base.PutMonoRow = put_mono_row_DITHER_pixmap; + xrb->Base.PutValues = put_values_DITHER_pixmap; + xrb->Base.PutMonoValues = put_mono_values_DITHER_pixmap; + } + else { + if (depth == 8) { + xrb->Base.PutRow = put_row_DITHER8_ximage; + xrb->Base.PutRowRGB = put_row_rgb_DITHER8_ximage; + xrb->Base.PutMonoRow = put_mono_row_DITHER8_ximage; + xrb->Base.PutValues = put_values_DITHER8_ximage; + xrb->Base.PutMonoValues = put_mono_values_DITHER8_ximage; + } + else { + xrb->Base.PutRow = put_row_DITHER_ximage; + xrb->Base.PutRowRGB = put_row_rgb_DITHER_ximage; + xrb->Base.PutMonoRow = put_mono_row_DITHER_ximage; + xrb->Base.PutValues = put_values_DITHER_ximage; + xrb->Base.PutMonoValues = put_mono_values_DITHER_ximage; + } + } + break; + case PF_1Bit: + if (pixmap) { + xrb->Base.PutRow = put_row_1BIT_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_1BIT_pixmap; + xrb->Base.PutMonoRow = put_mono_row_1BIT_pixmap; + xrb->Base.PutValues = put_values_1BIT_pixmap; + xrb->Base.PutMonoValues = put_mono_values_1BIT_pixmap; + } + else { + xrb->Base.PutRow = put_row_1BIT_ximage; + xrb->Base.PutRowRGB = put_row_rgb_1BIT_ximage; + xrb->Base.PutMonoRow = put_mono_row_1BIT_ximage; + xrb->Base.PutValues = put_values_1BIT_ximage; + xrb->Base.PutMonoValues = put_mono_values_1BIT_ximage; + } + break; + case PF_HPCR: + if (pixmap) { + xrb->Base.PutRow = put_row_HPCR_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_HPCR_pixmap; + xrb->Base.PutMonoRow = put_mono_row_pixmap; + xrb->Base.PutValues = put_values_HPCR_pixmap; + xrb->Base.PutMonoValues = put_mono_values_pixmap; + } + else { + xrb->Base.PutRow = put_row_HPCR_ximage; + xrb->Base.PutRowRGB = put_row_rgb_HPCR_ximage; + xrb->Base.PutMonoRow = put_mono_row_HPCR_ximage; + xrb->Base.PutValues = put_values_HPCR_ximage; + xrb->Base.PutMonoValues = put_mono_values_HPCR_ximage; + } + break; + case PF_Lookup: + if (pixmap) { + xrb->Base.PutRow = put_row_LOOKUP_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_LOOKUP_pixmap; + xrb->Base.PutMonoRow = put_mono_row_pixmap; + xrb->Base.PutValues = put_values_LOOKUP_pixmap; + xrb->Base.PutMonoValues = put_mono_values_pixmap; + } + else { + if (depth==8) { + xrb->Base.PutRow = put_row_LOOKUP8_ximage; + xrb->Base.PutRowRGB = put_row_rgb_LOOKUP8_ximage; + xrb->Base.PutMonoRow = put_mono_row_LOOKUP8_ximage; + xrb->Base.PutValues = put_values_LOOKUP8_ximage; + xrb->Base.PutMonoValues = put_mono_values_LOOKUP8_ximage; + } + else { + xrb->Base.PutRow = put_row_LOOKUP_ximage; + xrb->Base.PutRowRGB = put_row_rgb_LOOKUP_ximage; + xrb->Base.PutMonoRow = put_mono_row_ximage; + xrb->Base.PutValues = put_values_LOOKUP_ximage; + xrb->Base.PutMonoValues = put_mono_values_ximage; + } + } + break; + case PF_Grayscale: + if (pixmap) { + xrb->Base.PutRow = put_row_GRAYSCALE_pixmap; + xrb->Base.PutRowRGB = put_row_rgb_GRAYSCALE_pixmap; + xrb->Base.PutMonoRow = put_mono_row_pixmap; + xrb->Base.PutValues = put_values_GRAYSCALE_pixmap; + xrb->Base.PutMonoValues = put_mono_values_pixmap; + } + else { + if (depth == 8) { + xrb->Base.PutRow = put_row_GRAYSCALE8_ximage; + xrb->Base.PutRowRGB = put_row_rgb_GRAYSCALE8_ximage; + xrb->Base.PutMonoRow = put_mono_row_GRAYSCALE8_ximage; + xrb->Base.PutValues = put_values_GRAYSCALE8_ximage; + xrb->Base.PutMonoValues = put_mono_values_GRAYSCALE8_ximage; + } + else { + xrb->Base.PutRow = put_row_GRAYSCALE_ximage; + xrb->Base.PutRowRGB = put_row_rgb_GRAYSCALE_ximage; + xrb->Base.PutMonoRow = put_mono_row_ximage; + xrb->Base.PutValues = put_values_GRAYSCALE_ximage; + xrb->Base.PutMonoValues = put_mono_values_ximage; + } + } + break; + default: + _mesa_problem(NULL, "Bad pixel format in xmesa_update_state (1)"); + return; + } + + + /* Get functions */ + if (pixelformat == PF_Index) { + xrb->Base.GetRow = get_row_ci; + xrb->Base.GetValues = get_values_ci; + } + else { + xrb->Base.GetRow = get_row_rgba; + xrb->Base.GetValues = get_values_rgba; + } +} + diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_tri.c b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_tri.c new file mode 100644 index 000000000..87989f46f --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xm_tri.c @@ -0,0 +1,1623 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 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. + */ + + +/* + * This file contains "accelerated" triangle functions. It should be + * fairly easy to write new special-purpose triangle functions and hook + * them into this module. + */ + + +#include "glxheader.h" +#include "depth.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" +#include "xmesaP.h" + +/* Internal swrast includes: + */ +#include "swrast/s_context.h" +#include "swrast/s_depth.h" +#include "swrast/s_triangle.h" + + +#define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \ + (struct xmesa_renderbuffer *) ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped + + +/**********************************************************************/ +/*** Triangle rendering ***/ +/**********************************************************************/ + + +/* + * XImage, smooth, depth-buffered, PF_TRUECOLOR triangle. + */ +#define NAME smooth_TRUECOLOR_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); + +#define RENDER_SPAN( span ) \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + GLuint i; \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p; \ + PACK_TRUECOLOR(p, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(xrb->ximage, x, y, p); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + +#include "swrast/s_tritemp.h" + + + + +/* + * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle. + */ +#define NAME smooth_8A8B8G8R_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = PACK_8B8G8R(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, PF_8A8R8G8B triangle. + */ +#define NAME smooth_8A8R8G8B_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); + +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = PACK_8R8G8B(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, PF_8R8G8B triangle. + */ +#define NAME smooth_8R8G8B_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); + +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = PACK_8R8G8B(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, PF_8R8G8B24 triangle. + */ +#define NAME smooth_8R8G8B24_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y) +#define PIXEL_TYPE bgr_t +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + PIXEL_TYPE *ptr = pRow + i; \ + ptr->r = FixedToInt(span.red); \ + ptr->g = FixedToInt(span.green); \ + ptr->b = FixedToInt(span.blue); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, PF_TRUEDITHER triangle. + */ +#define NAME smooth_TRUEDITHER_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p; \ + PACK_TRUEDITHER(p, x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(xrb->ximage, x, y, p); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, PF_5R6G5B triangle. + */ +#define NAME smooth_5R6G5B_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = PACK_5R6G5B(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, PF_DITHER_5R6G5B triangle. + */ +#define NAME smooth_DITHER_5R6G5B_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + PACK_TRUEDITHER(pRow[i], x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle. + */ +#define NAME smooth_DITHER8_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + XDITHER_SETUP(y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) XDITHER(x, FixedToInt(span.red),\ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, PF_DITHER triangle. + */ +#define NAME smooth_DITHER_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define SETUP_CODE \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + XDITHER_SETUP(y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p = XDITHER(x, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(img, x, y, p); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle. + */ +#define NAME smooth_LOOKUP8_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + LOOKUP_SETUP; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = LOOKUP(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, depth-buffered, 8-bit PF_HPCR triangle. + */ +#define NAME smooth_HPCR_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = DITHER_HPCR(x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, PF_TRUECOLOR triangle. + */ +#define NAME flat_TRUECOLOR_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; \ + unsigned long pixel; \ + PACK_TRUECOLOR(pixel, v2->color[0], v2->color[1], v2->color[2]); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + XMesaPutPixel(img, x, y, pixel); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, PF_8A8B8G8R triangle. + */ +#define NAME flat_8A8B8G8R_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + GLuint p = PACK_8B8G8R( v2->color[0], v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) p; \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, PF_8A8R8G8B triangle. + */ +#define NAME flat_8A8R8G8B_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + GLuint p = PACK_8R8G8B( v2->color[0], v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) p; \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, PF_8R8G8B triangle. + */ +#define NAME flat_8R8G8B_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + GLuint p = PACK_8R8G8B( v2->color[0], v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) p; \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } + +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, PF_8R8G8B24 triangle. + */ +#define NAME flat_8R8G8B24_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y) +#define PIXEL_TYPE bgr_t +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = v2->color; +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + PIXEL_TYPE *ptr = pRow + i; \ + ptr->r = color[RCOMP]; \ + ptr->g = color[GCOMP]; \ + ptr->b = color[BCOMP]; \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, PF_TRUEDITHER triangle. + */ +#define NAME flat_TRUEDITHER_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p; \ + PACK_TRUEDITHER(p, x, y, v2->color[0], \ + v2->color[1], v2->color[2]); \ + XMesaPutPixel(img, x, y, p); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, PF_5R6G5B triangle. + */ +#define NAME flat_5R6G5B_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + GLushort p = PACK_5R6G5B( v2->color[0], v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) p; \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, PF_DITHER_5R6G5B triangle. + */ +#define NAME flat_DITHER_5R6G5B_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + const GLubyte *color = v2->color; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + PACK_TRUEDITHER(pRow[i], x, y, color[RCOMP], \ + color[GCOMP], color[BCOMP]); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle. + */ +#define NAME flat_DITHER8_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + FLAT_DITHER_SETUP( v2->color[0], v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + FLAT_DITHER_ROW_SETUP(YFLIP(xrb, y)); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) FLAT_DITHER(x); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, PF_DITHER triangle. + */ +#define NAME flat_DITHER_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define SETUP_CODE \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; \ + FLAT_DITHER_SETUP( v2->color[0], v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + FLAT_DITHER_ROW_SETUP(y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p = FLAT_DITHER(x); \ + XMesaPutPixel(img, x, y, p); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, 8-bit PF_HPCR triangle. + */ +#define NAME flat_HPCR_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + GLubyte r = v2->color[0]; \ + GLubyte g = v2->color[1]; \ + GLubyte b = v2->color[2]; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) DITHER_HPCR(x, y, r, g, b); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle. + */ +#define NAME flat_LOOKUP8_z_triangle +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + LOOKUP_SETUP; \ + GLubyte r = v2->color[0]; \ + GLubyte g = v2->color[1]; \ + GLubyte b = v2->color[2]; \ + GLubyte p = LOOKUP(r,g,b); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = p; \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, PF_TRUECOLOR triangle. + */ +#define NAME smooth_TRUECOLOR_triangle +#define INTERP_RGB 1 +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + unsigned long p; \ + PACK_TRUECOLOR(p, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(img, x, y, p); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle. + */ +#define NAME smooth_8A8B8G8R_triangle +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = PACK_8B8G8R(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, PF_8A8R8G8B triangle. + */ +#define NAME smooth_8A8R8G8B_triangle +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = PACK_8R8G8B(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle. + */ +#define NAME smooth_8R8G8B_triangle +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = PACK_8R8G8B(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle. + */ +#define NAME smooth_8R8G8B24_triangle +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y) +#define PIXEL_TYPE bgr_t +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + PIXEL_TYPE *pixel = pRow; \ + for (i = 0; i < span.end; i++, pixel++) { \ + pixel->r = FixedToInt(span.red); \ + pixel->g = FixedToInt(span.green); \ + pixel->b = FixedToInt(span.blue); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, PF_TRUEDITHER triangle. + */ +#define NAME smooth_TRUEDITHER_triangle +#define INTERP_RGB 1 +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + unsigned long p; \ + PACK_TRUEDITHER(p, x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(img, x, y, p ); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle. + */ +#define NAME smooth_5R6G5B_triangle +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = (PIXEL_TYPE) PACK_5R6G5B(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, PF_DITHER_5R6G5B triangle. + */ +#define NAME smooth_DITHER_5R6G5B_triangle +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + PACK_TRUEDITHER(pRow[i], x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle. + */ +#define NAME smooth_DITHER8_triangle +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + XDITHER_SETUP(y); \ + for (i = 0; i < span.end; i++, x++) { \ + pRow[i] = (PIXEL_TYPE) XDITHER(x, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, PF_DITHER triangle. + */ +#define NAME smooth_DITHER_triangle +#define INTERP_RGB 1 +#define SETUP_CODE \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + XDITHER_SETUP(y); \ + for (i = 0; i < span.end; i++, x++) { \ + unsigned long p = XDITHER(x, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + XMesaPutPixel(img, x, y, p); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle. + */ +#define NAME smooth_LOOKUP8_triangle +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + LOOKUP_SETUP; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = LOOKUP(FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, smooth, NON-depth-buffered, 8-bit PF_HPCR triangle. + */ +#define NAME smooth_HPCR_triangle +#define INTERP_RGB 1 +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + pRow[i] = DITHER_HPCR(x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, PF_TRUECOLOR triangle. + */ +#define NAME flat_TRUECOLOR_triangle +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; \ + unsigned long pixel; \ + PACK_TRUECOLOR(pixel, v2->color[0], v2->color[1], v2->color[2]); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + XMesaPutPixel(img, x, y, pixel); \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle. + */ +#define NAME flat_8A8B8G8R_triangle +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + unsigned long p = PACK_8B8G8R( v2->color[0], \ + v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = (PIXEL_TYPE) p; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, PF_8A8R8G8B triangle. + */ +#define NAME flat_8A8R8G8B_triangle +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + unsigned long p = PACK_8R8G8B( v2->color[0], \ + v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = (PIXEL_TYPE) p; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle. + */ +#define NAME flat_8R8G8B_triangle +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) +#define PIXEL_TYPE GLuint +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + unsigned long p = PACK_8R8G8B( v2->color[0], \ + v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = (PIXEL_TYPE) p; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, PF_8R8G8B24 triangle. + */ +#define NAME flat_8R8G8B24_triangle +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y) +#define PIXEL_TYPE bgr_t +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + const GLubyte *color = v2->color; +#define RENDER_SPAN( span ) \ + GLuint i; \ + PIXEL_TYPE *pixel = pRow; \ + for (i = 0; i < span.end; i++, pixel++) { \ + pixel->r = color[RCOMP]; \ + pixel->g = color[GCOMP]; \ + pixel->b = color[BCOMP]; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, PF_TRUEDITHER triangle. + */ +#define NAME flat_TRUEDITHER_triangle +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + unsigned long p; \ + PACK_TRUEDITHER(p, x, y, v2->color[0], \ + v2->color[1], v2->color[2] ); \ + XMesaPutPixel(img, x, y, p); \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle. + */ +#define NAME flat_5R6G5B_triangle +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + unsigned long p = PACK_5R6G5B( v2->color[0], \ + v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = (PIXEL_TYPE) p; \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, PF_DITHER_5R6G5B triangle. + */ +#define NAME flat_DITHER_5R6G5B_triangle +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) +#define PIXEL_TYPE GLushort +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + const GLubyte *color = v2->color; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + PACK_TRUEDITHER(pRow[i], x, y, color[RCOMP], \ + color[GCOMP], color[BCOMP]); \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle. + */ +#define NAME flat_DITHER8_triangle +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + FLAT_DITHER_SETUP( v2->color[0], v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + FLAT_DITHER_ROW_SETUP(YFLIP(xrb, y)); \ + for (i = 0; i < span.end; i++, x++) { \ + pRow[i] = (PIXEL_TYPE) FLAT_DITHER(x); \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, PF_DITHER triangle. + */ +#define NAME flat_DITHER_triangle +#define SETUP_CODE \ + GET_XRB(xrb); \ + XMesaImage *img = xrb->ximage; \ + FLAT_DITHER_SETUP( v2->color[0], v2->color[1], v2->color[2] ); +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + FLAT_DITHER_ROW_SETUP(y); \ + for (i = 0; i < span.end; i++, x++) { \ + unsigned long p = FLAT_DITHER(x); \ + XMesaPutPixel(img, x, y, p ); \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, 8-bit PF_HPCR triangle. + */ +#define NAME flat_HPCR_triangle +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + XMesaContext xmesa = XMESA_CONTEXT(ctx); \ + GET_XRB(xrb); \ + GLubyte r = v2->color[0]; \ + GLubyte g = v2->color[1]; \ + GLubyte b = v2->color[2]; +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = YFLIP(xrb, span.y); \ + for (i = 0; i < span.end; i++, x++) { \ + pRow[i] = (PIXEL_TYPE) DITHER_HPCR(x, y, r, g, b); \ + } +#include "swrast/s_tritemp.h" + + + +/* + * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle. + */ +#define NAME flat_LOOKUP8_triangle +#define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y) +#define PIXEL_TYPE GLubyte +#define BYTES_PER_ROW (xrb->ximage->bytes_per_line) +#define SETUP_CODE \ + GET_XRB(xrb); \ + LOOKUP_SETUP; \ + GLubyte r = v2->color[0]; \ + GLubyte g = v2->color[1]; \ + GLubyte b = v2->color[2]; \ + GLubyte p = LOOKUP(r,g,b); +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.end; i++) { \ + pRow[i] = (PIXEL_TYPE) p; \ + } +#include "swrast/s_tritemp.h" + + + +#ifdef DEBUG +extern void _xmesa_print_triangle_func( swrast_tri_func triFunc ); +void _xmesa_print_triangle_func( swrast_tri_func triFunc ) +{ + _mesa_printf("XMesa tri func = "); + if (triFunc ==smooth_TRUECOLOR_z_triangle) + _mesa_printf("smooth_TRUECOLOR_z_triangle\n"); + else if (triFunc ==smooth_8A8B8G8R_z_triangle) + _mesa_printf("smooth_8A8B8G8R_z_triangle\n"); + else if (triFunc ==smooth_8A8R8G8B_z_triangle) + _mesa_printf("smooth_8A8R8G8B_z_triangle\n"); + else if (triFunc ==smooth_8R8G8B_z_triangle) + _mesa_printf("smooth_8R8G8B_z_triangle\n"); + else if (triFunc ==smooth_8R8G8B24_z_triangle) + _mesa_printf("smooth_8R8G8B24_z_triangle\n"); + else if (triFunc ==smooth_TRUEDITHER_z_triangle) + _mesa_printf("smooth_TRUEDITHER_z_triangle\n"); + else if (triFunc ==smooth_5R6G5B_z_triangle) + _mesa_printf("smooth_5R6G5B_z_triangle\n"); + else if (triFunc ==smooth_DITHER_5R6G5B_z_triangle) + _mesa_printf("smooth_DITHER_5R6G5B_z_triangle\n"); + else if (triFunc ==smooth_HPCR_z_triangle) + _mesa_printf("smooth_HPCR_z_triangle\n"); + else if (triFunc ==smooth_DITHER8_z_triangle) + _mesa_printf("smooth_DITHER8_z_triangle\n"); + else if (triFunc ==smooth_LOOKUP8_z_triangle) + _mesa_printf("smooth_LOOKUP8_z_triangle\n"); + else if (triFunc ==flat_TRUECOLOR_z_triangle) + _mesa_printf("flat_TRUECOLOR_z_triangle\n"); + else if (triFunc ==flat_8A8B8G8R_z_triangle) + _mesa_printf("flat_8A8B8G8R_z_triangle\n"); + else if (triFunc ==flat_8A8R8G8B_z_triangle) + _mesa_printf("flat_8A8R8G8B_z_triangle\n"); + else if (triFunc ==flat_8R8G8B_z_triangle) + _mesa_printf("flat_8R8G8B_z_triangle\n"); + else if (triFunc ==flat_8R8G8B24_z_triangle) + _mesa_printf("flat_8R8G8B24_z_triangle\n"); + else if (triFunc ==flat_TRUEDITHER_z_triangle) + _mesa_printf("flat_TRUEDITHER_z_triangle\n"); + else if (triFunc ==flat_5R6G5B_z_triangle) + _mesa_printf("flat_5R6G5B_z_triangle\n"); + else if (triFunc ==flat_DITHER_5R6G5B_z_triangle) + _mesa_printf("flat_DITHER_5R6G5B_z_triangle\n"); + else if (triFunc ==flat_HPCR_z_triangle) + _mesa_printf("flat_HPCR_z_triangle\n"); + else if (triFunc ==flat_DITHER8_z_triangle) + _mesa_printf("flat_DITHER8_z_triangle\n"); + else if (triFunc ==flat_LOOKUP8_z_triangle) + _mesa_printf("flat_LOOKUP8_z_triangle\n"); + else if (triFunc ==smooth_TRUECOLOR_triangle) + _mesa_printf("smooth_TRUECOLOR_triangle\n"); + else if (triFunc ==smooth_8A8B8G8R_triangle) + _mesa_printf("smooth_8A8B8G8R_triangle\n"); + else if (triFunc ==smooth_8A8R8G8B_triangle) + _mesa_printf("smooth_8A8R8G8B_triangle\n"); + else if (triFunc ==smooth_8R8G8B_triangle) + _mesa_printf("smooth_8R8G8B_triangle\n"); + else if (triFunc ==smooth_8R8G8B24_triangle) + _mesa_printf("smooth_8R8G8B24_triangle\n"); + else if (triFunc ==smooth_TRUEDITHER_triangle) + _mesa_printf("smooth_TRUEDITHER_triangle\n"); + else if (triFunc ==smooth_5R6G5B_triangle) + _mesa_printf("smooth_5R6G5B_triangle\n"); + else if (triFunc ==smooth_DITHER_5R6G5B_triangle) + _mesa_printf("smooth_DITHER_5R6G5B_triangle\n"); + else if (triFunc ==smooth_HPCR_triangle) + _mesa_printf("smooth_HPCR_triangle\n"); + else if (triFunc ==smooth_DITHER8_triangle) + _mesa_printf("smooth_DITHER8_triangle\n"); + else if (triFunc ==smooth_LOOKUP8_triangle) + _mesa_printf("smooth_LOOKUP8_triangle\n"); + else if (triFunc ==flat_TRUECOLOR_triangle) + _mesa_printf("flat_TRUECOLOR_triangle\n"); + else if (triFunc ==flat_TRUEDITHER_triangle) + _mesa_printf("flat_TRUEDITHER_triangle\n"); + else if (triFunc ==flat_8A8B8G8R_triangle) + _mesa_printf("flat_8A8B8G8R_triangle\n"); + else if (triFunc ==flat_8A8R8G8B_triangle) + _mesa_printf("flat_8A8R8G8B_triangle\n"); + else if (triFunc ==flat_8R8G8B_triangle) + _mesa_printf("flat_8R8G8B_triangle\n"); + else if (triFunc ==flat_8R8G8B24_triangle) + _mesa_printf("flat_8R8G8B24_triangle\n"); + else if (triFunc ==flat_5R6G5B_triangle) + _mesa_printf("flat_5R6G5B_triangle\n"); + else if (triFunc ==flat_DITHER_5R6G5B_triangle) + _mesa_printf("flat_DITHER_5R6G5B_triangle\n"); + else if (triFunc ==flat_HPCR_triangle) + _mesa_printf("flat_HPCR_triangle\n"); + else if (triFunc ==flat_DITHER8_triangle) + _mesa_printf("flat_DITHER8_triangle\n"); + else if (triFunc ==flat_LOOKUP8_triangle) + _mesa_printf("flat_LOOKUP8_triangle\n"); + else + _mesa_printf("???\n"); +} +#endif + + +#ifdef DEBUG + +/* record the current triangle function name */ +static const char *triFuncName = NULL; + +#define USE(triFunc) \ +do { \ + triFuncName = #triFunc; \ + return triFunc; \ +} while (0) + +#else + +#define USE(triFunc) return triFunc + +#endif + + +static swrast_tri_func get_triangle_func( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + XMesaContext xmesa = XMESA_CONTEXT(ctx); + int depth = GET_VISUAL_DEPTH(xmesa->xm_visual); + GET_XRB(xrb); + +#ifdef DEBUG + triFuncName = NULL; +#endif + + if ((ctx->DrawBuffer->_ColorDrawBufferMask[0] + & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) == 0) + return (swrast_tri_func) NULL; + if (ctx->RenderMode != GL_RENDER) return (swrast_tri_func) NULL; + if (ctx->Polygon.SmoothFlag) return (swrast_tri_func) NULL; + if (ctx->Texture._EnabledUnits) return (swrast_tri_func) NULL; + if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_tri_func) NULL; + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) + return (swrast_tri_func) NULL; + + if (xrb->ximage) { + if ( ctx->Light.ShadeModel==GL_SMOOTH + && swrast->_RasterMask==DEPTH_BIT + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_TRUE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS + && ctx->Polygon.StippleFlag==GL_FALSE) { + switch (xmesa->pixelformat) { + case PF_Truecolor: + USE(smooth_TRUECOLOR_z_triangle); + case PF_8A8B8G8R: + USE(smooth_8A8B8G8R_z_triangle); + case PF_8A8R8G8B: + USE(smooth_8A8R8G8B_z_triangle); + case PF_8R8G8B: + USE(smooth_8R8G8B_z_triangle); + case PF_8R8G8B24: + USE(smooth_8R8G8B24_z_triangle); + case PF_Dither_True: + USE(smooth_TRUEDITHER_z_triangle); + case PF_5R6G5B: + USE(smooth_5R6G5B_z_triangle); + case PF_Dither_5R6G5B: + USE(smooth_DITHER_5R6G5B_z_triangle); + case PF_HPCR: + USE(smooth_HPCR_z_triangle); + case PF_Dither: + if (depth == 8) + USE(smooth_DITHER8_z_triangle); + else + USE(smooth_DITHER_z_triangle); + case PF_Lookup: + if (depth == 8) + USE(smooth_LOOKUP8_z_triangle); + else + return (swrast_tri_func) NULL; + default: + return (swrast_tri_func) NULL; + } + } + if ( ctx->Light.ShadeModel==GL_FLAT + && swrast->_RasterMask==DEPTH_BIT + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_TRUE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS + && ctx->Polygon.StippleFlag==GL_FALSE) { + switch (xmesa->pixelformat) { + case PF_Truecolor: + USE(flat_TRUECOLOR_z_triangle); + case PF_8A8B8G8R: + USE(flat_8A8B8G8R_z_triangle); + case PF_8A8R8G8B: + USE(flat_8A8R8G8B_z_triangle); + case PF_8R8G8B: + USE(flat_8R8G8B_z_triangle); + case PF_8R8G8B24: + USE(flat_8R8G8B24_z_triangle); + case PF_Dither_True: + USE(flat_TRUEDITHER_z_triangle); + case PF_5R6G5B: + USE(flat_5R6G5B_z_triangle); + case PF_Dither_5R6G5B: + USE(flat_DITHER_5R6G5B_z_triangle); + case PF_HPCR: + USE(flat_HPCR_z_triangle); + case PF_Dither: + if (depth == 8) + USE(flat_DITHER8_z_triangle); + else + USE(flat_DITHER_z_triangle); + case PF_Lookup: + if (depth == 8) + USE(flat_LOOKUP8_z_triangle); + else + return (swrast_tri_func) NULL; + default: + return (swrast_tri_func) NULL; + } + } + if ( swrast->_RasterMask==0 /* no depth test */ + && ctx->Light.ShadeModel==GL_SMOOTH + && ctx->Polygon.StippleFlag==GL_FALSE) { + switch (xmesa->pixelformat) { + case PF_Truecolor: + USE(smooth_TRUECOLOR_triangle); + case PF_8A8B8G8R: + USE(smooth_8A8B8G8R_triangle); + case PF_8A8R8G8B: + USE(smooth_8A8R8G8B_triangle); + case PF_8R8G8B: + USE(smooth_8R8G8B_triangle); + case PF_8R8G8B24: + USE(smooth_8R8G8B24_triangle); + case PF_Dither_True: + USE(smooth_TRUEDITHER_triangle); + case PF_5R6G5B: + USE(smooth_5R6G5B_triangle); + case PF_Dither_5R6G5B: + USE(smooth_DITHER_5R6G5B_triangle); + case PF_HPCR: + USE(smooth_HPCR_triangle); + case PF_Dither: + if (depth == 8) + USE(smooth_DITHER8_triangle); + else + USE(smooth_DITHER_triangle); + case PF_Lookup: + if (depth == 8) + USE(smooth_LOOKUP8_triangle); + else + return (swrast_tri_func) NULL; + default: + return (swrast_tri_func) NULL; + } + } + + if ( swrast->_RasterMask==0 /* no depth test */ + && ctx->Light.ShadeModel==GL_FLAT + && ctx->Polygon.StippleFlag==GL_FALSE) { + switch (xmesa->pixelformat) { + case PF_Truecolor: + USE(flat_TRUECOLOR_triangle); + case PF_Dither_True: + USE(flat_TRUEDITHER_triangle); + case PF_8A8B8G8R: + USE(flat_8A8B8G8R_triangle); + case PF_8A8R8G8B: + USE(flat_8A8R8G8B_triangle); + case PF_8R8G8B: + USE(flat_8R8G8B_triangle); + case PF_8R8G8B24: + USE(flat_8R8G8B24_triangle); + case PF_5R6G5B: + USE(flat_5R6G5B_triangle); + case PF_Dither_5R6G5B: + USE(flat_DITHER_5R6G5B_triangle); + case PF_HPCR: + USE(flat_HPCR_triangle); + case PF_Dither: + if (depth == 8) + USE(flat_DITHER8_triangle); + else + USE(flat_DITHER_triangle); + case PF_Lookup: + if (depth == 8) + USE(flat_LOOKUP8_triangle); + else + return (swrast_tri_func) NULL; + default: + return (swrast_tri_func) NULL; + } + } + + return (swrast_tri_func) NULL; + } + else { + /* draw to pixmap */ + return (swrast_tri_func) NULL; + } +} + + +/* Override for the swrast tri-selection function. Try to use one + * of our internal tri functions, otherwise fall back to the + * standard swrast functions. + */ +void xmesa_choose_triangle( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (!(swrast->Triangle = get_triangle_func( ctx ))) + _swrast_choose_triangle( ctx ); +} + diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/x11/xmesaP.h b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xmesaP.h new file mode 100644 index 000000000..26255ae56 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/x11/xmesaP.h @@ -0,0 +1,555 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 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 "GL/xf86glx.h" +# include "xf86glx_util.h" +#elif defined(USE_XSHM) +# include <X11/extensions/XShm.h> +#endif +#include "GL/xmesa.h" +#include "mtypes.h" +#if defined(FX) +#include "GL/fxmesa.h" +#include "../glide/fxdrv.h" +#endif + + +extern _glthread_Mutex _xmesa_lock; + + +/* for PF_8R8G8B24 pixel format */ +typedef struct { + GLubyte b; + GLubyte g; + GLubyte r; +} bgr_t; + + +struct xmesa_renderbuffer; + + +/* Function pointer for clearing color buffers */ +typedef void (*ClearFunc)( GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLboolean all, GLint x, GLint y, + GLint width, GLint height ); + + + + +/** Framebuffer pixel formats */ +enum pixel_format { + PF_Index, /**< Color Index mode */ + PF_Truecolor, /**< TrueColor or DirectColor, any depth */ + PF_Dither_True, /**< TrueColor with dithering */ + PF_8A8B8G8R, /**< 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */ + PF_8R8G8B, /**< 32-bit TrueColor: 8-R, 8-G, 8-B bits */ + PF_5R6G5B, /**< 16-bit TrueColor: 5-R, 6-G, 5-B bits */ + PF_Dither, /**< Color-mapped RGB with dither */ + PF_Lookup, /**< Color-mapped RGB without dither */ + PF_HPCR, /**< HP Color Recovery (ad@lms.be 30/08/95) */ + PF_1Bit, /**< monochrome dithering of RGB */ + PF_Grayscale, /**< Grayscale or StaticGray */ + PF_8R8G8B24, /**< 24-bit TrueColor: 8-R, 8-G, 8-B bits */ + PF_Dither_5R6G5B, /**< 16-bit dithered TrueColor: 5-R, 6-G, 5-B */ + PF_8A8R8G8B /**< 32-bit TrueColor: 8-A, 8-R, 8-G, 8-B */ +}; + + +/* + * "Derived" from GLvisual. Basically corresponds to an XVisualInfo. + */ +struct xmesa_visual { + GLvisual mesa_visual; /* Device independent visual parameters */ + XMesaDisplay *display; /* The X11 display */ +#ifdef XFree86Server + GLint ColormapEntries; + GLint nplanes; +#else + XMesaVisualInfo visinfo; /* X's visual info (pointer to private copy) */ + XVisualInfo *vishandle; /* Only used in fakeglx.c */ +#endif + GLint BitsPerPixel; /* True bits per pixel for XImages */ + + GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */ + + enum pixel_format dithered_pf; /* Pixel format when dithering */ + enum pixel_format undithered_pf;/* Pixel format when not dithering */ + + GLfloat RedGamma; /* Gamma values, 1.0 is default */ + GLfloat GreenGamma; + GLfloat BlueGamma; + + /* 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 __GLcontextRec. Basically corresponds to a GLXContext. + */ +struct xmesa_context { + GLcontext mesa; /* the core library context (containment) */ + XMesaVisual xm_visual; /* Describes the buffers */ + XMesaBuffer xm_buffer; /* current span/point/line/triangle buffer */ + + XMesaDisplay *display; /* == xm_visual->display */ + GLboolean swapbytes; /* Host byte order != display byte order? */ + GLboolean direct; /* Direct rendering context? */ + + enum pixel_format pixelformat; + + GLubyte clearcolor[4]; /* current clearing color */ + unsigned long clearpixel; /* current clearing pixel value */ +}; + + + +typedef enum { + WINDOW, /* An X window */ + GLXWINDOW, /* GLX window */ + PIXMAP, /* GLX pixmap */ + PBUFFER /* GLX Pbuffer */ +} BufferType; + + +/** + * An xmesa_renderbuffer represents the back or front color buffer. + * For the front color buffer: + * <drawable> is the X window + * For the back color buffer: + * Either <ximage> or <pixmap> will be used, never both. + * In any case, <drawable> always equals <pixmap>. + * For stand-alone Mesa, we could merge <drawable> and <pixmap> into one + * field. We don't do that for the server-side GLcore module because + * pixmaps and drawables are different and we'd need a bunch of casts. + */ +struct xmesa_renderbuffer +{ + struct gl_renderbuffer Base; /* Base class */ + + XMesaDrawable drawable; /* Usually the X window ID */ + XMesaPixmap pixmap; /* Back color buffer */ + XMesaImage *ximage; /* The back buffer, if not using a Pixmap */ + + GLubyte *origin1; /* used for PIXEL_ADDR1 macro */ + GLint width1; + GLushort *origin2; /* used for PIXEL_ADDR2 macro */ + GLint width2; + GLubyte *origin3; /* used for PIXEL_ADDR3 macro */ + GLint width3; + GLuint *origin4; /* used for PIXEL_ADDR4 macro */ + GLint width4; + + GLint bottom; /* used for FLIP macro */ + + ClearFunc clearFunc; +}; + + +/* + * "Derived" from GLframebuffer. Basically corresponds to a GLXDrawable. + */ +struct xmesa_buffer { + GLframebuffer mesa_buffer; /* depth, stencil, accum, etc buffers */ + /* This MUST BE FIRST! */ + GLboolean wasCurrent; /* was ever the current buffer? */ + XMesaVisual xm_visual; /* the X/Mesa visual */ + + XMesaDisplay *display; + BufferType type; /* window, pixmap, pbuffer or glxwindow */ + + struct xmesa_renderbuffer *frontxrb; /* front color renderbuffer */ + struct xmesa_renderbuffer *backxrb; /* back color renderbuffer */ + + XMesaColormap cmap; /* the X colormap */ + + unsigned long selectedEvents;/* for pbuffers only */ + + 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 USE_XSHM + XShmSegmentInfo shminfo; +#endif +#endif + + XMesaImage *rowimage; /* Used for optimized span writing */ + XMesaPixmap stipple_pixmap; /* For polygon stippling */ + XMesaGC stipple_gc; /* For polygon stippling */ + + XMesaGC gc; /* scratch GC for span, line, tri drawing */ + XMesaGC cleargc; /* GC for clearing the color buffer */ + XMesaGC swapgc; /* GC for swapping the color buffers */ + + /* 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; +#if defined(XFree86Server) + Pixel alloced_colors[256]; +#else + unsigned long alloced_colors[256]; +#endif + +#if defined( 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->db_state: */ +#define FRONT_PIXMAP 1 +#define BACK_PIXMAP 2 +#define BACK_XIMAGE 4 + + +/* + * 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_8A8R8G8B: + */ +#define PACK_8A8R8G8B( R, G, B, A ) \ + ( ((A) << 24) | ((R) << 16) | ((G) << 8) | (B) ) + + + +/* + * If pixelformat==PF_DITHER: + * + * Improved 8-bit RGB dithering code contributed by Bob Mercier + * (mercier@hollywood.cinenet.net). Thanks Bob! + */ +#ifdef DITHER666 +# define DITH_R 6 +# define DITH_G 6 +# define DITH_B 6 +# define DITH_MIX(r,g,b) (((r) * DITH_G + (g)) * DITH_B + (b)) +#else +# define DITH_R 5 +# define DITH_G 9 +# define DITH_B 5 +# define DITH_MIX(r,g,b) (((g) << 6) | ((b) << 3) | (r)) +#endif +#define DITH_DX 4 +#define DITH_DY 4 +#define DITH_N (DITH_DX * DITH_DY) + +#define _dither(C, c, d) (((unsigned)((DITH_N * (C - 1) + 1) * c + d)) >> 12) + +#define MAXC 256 +extern const int xmesa_kernel8[DITH_DY * DITH_DX]; + +/* Dither for random X,Y */ +#define DITHER_SETUP \ + int __d; \ + unsigned long *ctable = XMESA_BUFFER(ctx->DrawBuffer)->color_table; + +#define DITHER( X, Y, R, G, B ) \ + (__d = xmesa_kernel8[(((Y)&3)<<2) | ((X)&3)], \ + ctable[DITH_MIX(_dither(DITH_R, (R), __d), \ + _dither(DITH_G, (G), __d), \ + _dither(DITH_B, (B), __d))]) + +/* Dither for random X, fixed Y */ +#define XDITHER_SETUP(Y) \ + int __d; \ + unsigned long *ctable = XMESA_BUFFER(ctx->DrawBuffer)->color_table; \ + const int *kernel = &xmesa_kernel8[ ((Y)&3) << 2 ]; + +#define XDITHER( X, R, G, B ) \ + (__d = kernel[(X)&3], \ + ctable[DITH_MIX(_dither(DITH_R, (R), __d), \ + _dither(DITH_G, (G), __d), \ + _dither(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. + */ +#define FLAT_DITHER_SETUP( R, G, B ) \ + GLushort ditherValues[16]; \ + { \ + unsigned long *ctable = XMESA_BUFFER(ctx->DrawBuffer)->color_table; \ + int msdr = (DITH_N*((DITH_R)-1)+1) * (R); \ + int msdg = (DITH_N*((DITH_G)-1)+1) * (G); \ + int msdb = (DITH_N*((DITH_B)-1)+1) * (B); \ + int i; \ + for (i=0;i<16;i++) { \ + int k = xmesa_kernel8[i]; \ + int j = DITH_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 _dither_lookup(C, c) (((unsigned)((DITH_N * (C - 1) + 1) * c)) >> 12) + +#define LOOKUP_SETUP \ + unsigned long *ctable = XMESA_BUFFER(ctx->DrawBuffer)->color_table + +#define LOOKUP( R, G, B ) \ + ctable[DITH_MIX(_dither_lookup(DITH_R, (R)), \ + _dither_lookup(DITH_G, (G)), \ + _dither_lookup(DITH_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. + */ +extern const short xmesa_HPCR_DRGB[3][2][16]; + +#define DITHER_HPCR( X, Y, R, G, B ) \ + ( ((xmesa->xm_visual->hpcr_rgbTbl[0][R] + xmesa_HPCR_DRGB[0][(Y)&1][(X)&15]) & 0xE0) \ + |(((xmesa->xm_visual->hpcr_rgbTbl[1][G] + xmesa_HPCR_DRGB[1][(Y)&1][(X)&15]) & 0xE0)>>3) \ + | ((xmesa->xm_visual->hpcr_rgbTbl[2][B] + xmesa_HPCR_DRGB[2][(Y)&1][(X)&15])>>6) \ + ) + + + +/* + * If pixelformat==PF_1BIT: + */ +extern const int xmesa_kernel1[16]; + +#define SETUP_1BIT int bitFlip = xmesa->xm_visual->bitFlip +#define DITHER_1BIT( X, Y, R, G, B ) \ + (( ((int)(R)+(int)(G)+(int)(B)) > xmesa_kernel1[(((Y)&3) << 2) | ((X)&3)] ) ^ bitFlip) + + + +/* + * If pixelformat==PF_GRAYSCALE: + */ +#define GRAY_RGB( R, G, B ) XMESA_BUFFER(ctx->DrawBuffer)->color_table[((R) + (G) + (B))/3] + + + +/* + * Converts a GL window Y coord to an X window Y coord: + */ +#define YFLIP(XRB, Y) ((XRB)->bottom - (Y)) + + +/* + * Return the address of a 1, 2 or 4-byte pixel in the buffer's XImage: + * X==0 is left, Y==0 is bottom. + */ +#define PIXEL_ADDR1(XRB, X, Y) \ + ( (XRB)->origin1 - (Y) * (XRB)->width1 + (X) ) + +#define PIXEL_ADDR2(XRB, X, Y) \ + ( (XRB)->origin2 - (Y) * (XRB)->width2 + (X) ) + +#define PIXEL_ADDR3(XRB, X, Y) \ + ( (bgr_t *) ( (XRB)->origin3 - (Y) * (XRB)->width3 + 3 * (X) )) + +#define PIXEL_ADDR4(XRB, X, Y) \ + ( (XRB)->origin4 - (Y) * (XRB)->width4 + (X) ) + + + + +/* + * Return pointer to XMesaContext corresponding to a Mesa GLcontext. + * Since we're using structure containment, it's just a cast!. + */ +#define XMESA_CONTEXT(MESACTX) ((XMesaContext) (MESACTX)) + +/* + * Return pointer to XMesaBuffer corresponding to a Mesa GLframebuffer. + * Since we're using structure containment, it's just a cast!. + */ +#define XMESA_BUFFER(MESABUFF) ((XMesaBuffer) (MESABUFF)) + + + +/* + * External functions: + */ + +extern struct xmesa_renderbuffer * +xmesa_new_renderbuffer(GLcontext *ctx, GLuint name, GLboolean rgbMode); + +extern unsigned long +xmesa_color_to_pixel( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a, + GLuint pixelFormat ); + +extern void +xmesa_alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height); + +extern void xmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, + GLuint width, GLuint height); + +extern void xmesa_init_driver_functions( XMesaVisual xmvisual, + struct dd_function_table *driver ); + +extern void xmesa_update_state( GLcontext *ctx, GLuint new_state ); + +extern void +xmesa_set_renderbuffer_funcs(struct xmesa_renderbuffer *xrb, + enum pixel_format pixelformat, GLint depth); + + +/* Plugged into the software rasterizer. Try to use internal + * swrast-style point, line and triangle functions. + */ +extern void xmesa_choose_point( GLcontext *ctx ); +extern void xmesa_choose_line( GLcontext *ctx ); +extern void xmesa_choose_triangle( GLcontext *ctx ); + + +extern void xmesa_register_swrast_functions( 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 ); + + +#define SWTC 0 /* SW texture compression */ + + +#endif |