home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src / xmesa1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  61.0 KB  |  2,058 lines

  1. /* $Id: xmesa1.c,v 1.39 1997/11/07 03:48:03 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.5
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: xmesa1.c,v $
  26.  * Revision 1.39  1997/11/07 03:48:03  brianp
  27.  * added basic stencil buffer and accumulation buffer support for 3Dfx/Glide
  28.  *
  29.  * Revision 1.38  1997/11/02 20:21:07  brianp
  30.  * if a window doesn't have a colormap, allocate one (xlockmore)
  31.  *
  32.  * Revision 1.37  1997/08/26 02:08:42  brianp
  33.  * replaced MESA_FX_WINDOW/FULLSCREEN env vars with MESA_GLX_FX
  34.  *
  35.  * Revision 1.36  1997/08/14 01:22:18  brianp
  36.  * renamed environment vars: MESA_FX_WINDOW and MESA_FX_FULLSCREEN
  37.  *
  38.  * Revision 1.35  1997/08/13 02:06:03  brianp
  39.  * incorporated David Bucciarelli's v0.18 changes
  40.  *
  41.  * Revision 1.34  1997/08/11 01:23:41  brianp
  42.  * added a pointer cast
  43.  *
  44.  * Revision 1.33  1997/08/02 16:40:13  brianp
  45.  * removed unused FXhack variable
  46.  *
  47.  * Revision 1.32  1997/07/24 00:59:10  brianp
  48.  * implemented FXHACK (3Dfx rendering copied into X window)
  49.  *
  50.  * Revision 1.31  1997/07/18 03:15:44  brianp
  51.  * added some new assertions and error checking
  52.  *
  53.  * Revision 1.30  1997/07/11 23:11:40  brianp
  54.  * added NULL testing to XMesaFlush per Matthew Rees.  Bumped version to 2.4
  55.  *
  56.  * Revision 1.29  1997/07/11 23:07:55  brianp
  57.  * added XMesaGetDepthBuffer() function (Randy Frank)
  58.  *
  59.  * Revision 1.28  1997/06/20 02:54:37  brianp
  60.  * hopefully fixed a bug in XMesaMakeCurrent() involving reallocated memory
  61.  *
  62.  * Revision 1.27  1997/05/26 21:15:37  brianp
  63.  * now pass red/green/blue/alpha bits to gl_create_visual()
  64.  *
  65.  * Revision 1.26  1997/05/26 20:34:40  brianp
  66.  * added PF_TRUEDITHER pixel format
  67.  *
  68.  * Revision 1.25  1997/05/17 03:43:21  brianp
  69.  * prev pointer wasn't updated in free_xmesa_buffer() (Stephane Rehel)
  70.  *
  71.  * Revision 1.24  1997/05/14 03:27:48  brianp
  72.  * added XMesaDitherColor()
  73.  *
  74.  * Revision 1.23  1997/04/27 03:20:13  brianp
  75.  * added XMesaFindBuffer() and XMesaGarbageCollect
  76.  *
  77.  * Revision 1.22  1997/04/27 02:42:52  brianp
  78.  * Optimized color table setup.  Free X colormap entries when finished.
  79.  *
  80.  * Revision 1.21  1997/04/26 04:34:12  brianp
  81.  * new comments for XMesaCreateVisual()
  82.  *
  83.  * Revision 1.20  1997/04/20 20:29:11  brianp
  84.  * replaced abort() with gl_problem()
  85.  *
  86.  * Revision 1.19  1997/04/12 17:13:33  brianp
  87.  * added optimization to XMesaMakeCurrent() so rebinding current ctx is faster
  88.  *
  89.  * Revision 1.18  1997/04/12 16:23:23  brianp
  90.  * made XMesa static, removed call to xmesa_setup_DD_pointers() in MakeCurrent
  91.  *
  92.  * Revision 1.17  1997/04/04 05:23:57  brianp
  93.  * fixed problem with black/white being reversed on monochrome displays
  94.  *
  95.  * Revision 1.16  1997/01/31 20:40:46  brianp
  96.  * in XMesaCreateVisual copy viinfo to vishandle
  97.  *
  98.  * Revision 1.15  1997/01/29 19:21:39  brianp
  99.  * save a copy of the visinfo passed to XMesaCreateVisual() per Wolfram Gloger
  100.  *
  101.  * Revision 1.14  1997/01/03 23:56:13  brianp
  102.  * pick a better dithered color in xmesa_color_to_pixel() per Michael Pichler
  103.  *
  104.  * Revision 1.13  1996/12/20 20:40:55  brianp
  105.  * added .30 : .59 : .11 color weighting to noFaultXAllocColor()
  106.  *
  107.  * Revision 1.12  1996/12/03 21:40:24  brianp
  108.  * remove the shared memory ID if shmat() fails in alloc_shm_back_buffer()
  109.  *
  110.  * Revision 1.11  1996/12/03 21:12:30  brianp
  111.  * setup for 8-bit True/DirectColor no longer needs a colormap
  112.  *
  113.  * Revision 1.10  1996/11/21 03:42:44  brianp
  114.  * fixed 24/32 bit per pixel bug, added check for MESA_INFO env var
  115.  *
  116.  * Revision 1.9  1996/11/09 01:44:27  brianp
  117.  * noFaultXAllocColor() was reading from free()'d space!
  118.  *
  119.  * Revision 1.8  1996/10/22 02:44:41  brianp
  120.  * now uses DITHER_SETUP and LOOKUP_SETUP macros
  121.  *
  122.  * Revision 1.7  1996/09/27 17:10:38  brianp
  123.  * index_bits now stored in the XMesaVisual struct
  124.  *
  125.  * Revision 1.6  1996/09/27 01:31:29  brianp
  126.  * removed unused variables
  127.  *
  128.  * Revision 1.5  1996/09/20 02:55:39  brianp
  129.  * updated profiling code
  130.  *
  131.  * Revision 1.4  1996/09/19 03:42:05  brianp
  132.  * added XMesaGetCurrentBuffer
  133.  *
  134.  * Revision 1.3  1996/09/19 03:16:04  brianp
  135.  * new X/Mesa interface with XMesaContext, XMesaVisual, and XMesaBuffer types
  136.  *
  137.  * Revision 1.2  1996/09/15 14:21:27  brianp
  138.  * use new GLframebuffer and GLvisual types and functions
  139.  *
  140.  * Revision 1.1  1996/09/13 01:38:16  brianp
  141.  * Initial revision
  142.  *
  143.  */
  144.  
  145.  
  146. /*
  147.  * Mesa/X11 interface, part 1.
  148.  *
  149.  * This file contains the implementations of all the XMesa* functions.
  150.  *
  151.  *
  152.  * NOTES:
  153.  *
  154.  * The window coordinate system origin (0,0) is in the lower-left corner
  155.  * of the window.  X11's window coordinate origin is in the upper-left
  156.  * corner of the window.  Therefore, most drawing functions in this
  157.  * file have to flip Y coordinates.
  158.  *
  159.  * Define SHM in the Makefile with -DSHM if you want to compile in support
  160.  * for the MIT Shared Memory extension.  If enabled, when you use an Ximage
  161.  * for the back buffer in double buffered mode, the "swap" operation will
  162.  * be faster.  You must also link with -lXext.
  163.  *
  164.  * Byte swapping:  If the Mesa host and the X display use a different
  165.  * byte order then there's some trickiness to be aware of when using
  166.  * XImages.  The byte ordering used for the XImage is that of the X
  167.  * display, not the Mesa host.
  168.  * The color-to-pixel encoding for True/DirectColor must be done
  169.  * according to the display's visual red_mask, green_mask, and blue_mask.
  170.  * If XPutPixel is used to put a pixel into an XImage then XPutPixel will
  171.  * do byte swapping if needed.  If one wants to directly "poke" the pixel
  172.  * into the XImage's buffer then the pixel must be byte swapped first.  In
  173.  * Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format
  174.  * and use XPutPixel everywhere except in the implementation of
  175.  * glClear(GL_COLOR_BUFFER_BIT).  We want this function to be fast so
  176.  * instead of using XPutPixel we "poke" our values after byte-swapping
  177.  * the clear pixel value if needed.
  178.  *
  179.  */
  180.  
  181.  
  182. #include <assert.h>
  183. #include <ctype.h>
  184. #include <math.h>
  185. #include <stdio.h>
  186. #include <stdlib.h>
  187. #include <string.h>
  188. #include <X11/Xlib.h>
  189. #include <X11/Xutil.h>
  190. #ifdef SHM
  191. #  include <sys/ipc.h>
  192. #  include <sys/shm.h>
  193. #  include <X11/extensions/XShm.h>
  194. #endif
  195. #include "GL/xmesa.h"
  196. #include "xmesaP.h"
  197. #include "context.h"
  198. #include "macros.h"
  199. #include "matrix.h"
  200. #include "types.h"
  201.  
  202. #ifdef FX
  203. #include "GL/fxmesa.h"
  204. #define FX_WIDTH 640
  205. #define FX_HEIGHT 480
  206. #endif
  207.  
  208.  
  209. /*
  210.  * Current X/Mesa context pointer:
  211.  */
  212. static XMesaContext XMesa = NULL;
  213.  
  214.  
  215. /*
  216.  * Lookup tables for HPCR pixel format:
  217.  */
  218. static short hpcr_rTbl[256] = {
  219.  16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,  22,  23,  23,
  220.  24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,  30,  31,  31,
  221.  32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
  222.  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
  223.  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
  224.  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
  225.  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
  226.  96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
  227. 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
  228. 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
  229. 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
  230. 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
  231. 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
  232. 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
  233. 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
  234. 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
  235. };
  236.  
  237. static short hpcr_gTbl[256] = {
  238.  16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,  22,  23,  23,
  239.  24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,  30,  31,  31,
  240.  32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
  241.  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
  242.  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
  243.  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
  244.  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
  245.  96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
  246. 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
  247. 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
  248. 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
  249. 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
  250. 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
  251. 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
  252. 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
  253. 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
  254. };
  255.  
  256. static short hpcr_bTbl[256] = {
  257.  32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
  258.  40,  40,  41,  41,  42,  42,  43,  43,  44,  44,  45,  45,  46,  46,  47,  47,
  259.  48,  48,  49,  49,  50,  50,  51,  51,  52,  52,  53,  53,  54,  54,  55,  55,
  260.  56,  56,  57,  57,  58,  58,  59,  59,  60,  60,  61,  61,  62,  62,  63,  63,
  261.  64,  64,  65,  65,  66,  66,  67,  67,  68,  68,  69,  69,  70,  70,  71,  71,
  262.  72,  72,  73,  73,  74,  74,  75,  75,  76,  76,  77,  77,  78,  78,  79,  79,
  263.  80,  80,  81,  81,  82,  82,  83,  83,  84,  84,  85,  85,  86,  86,  87,  87,
  264.  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
  265.  96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
  266. 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
  267. 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
  268. 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
  269. 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
  270. 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
  271. 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
  272. 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223
  273. };
  274.  
  275.  
  276.  
  277. /**********************************************************************/
  278. /*****                     X Utility Functions                    *****/
  279. /**********************************************************************/
  280.  
  281.  
  282. /*
  283.  * X/Mesa error reporting function:
  284.  */
  285. static void error( const char *msg )
  286. {
  287.    if (getenv("MESA_DEBUG"))
  288.       fprintf( stderr, "X/Mesa error: %s\n", msg );
  289. }
  290.  
  291.  
  292. /*
  293.  * Return the host's byte order as LSBFirst or MSBFirst ala X.
  294.  */
  295. static int host_byte_order( void )
  296. {
  297.    int i = 1;
  298.    char *cptr = (char *) &i;
  299.    return (*cptr==1) ? LSBFirst : MSBFirst;
  300. }
  301.  
  302.  
  303.  
  304. /*
  305.  * Error handling.
  306.  */
  307. static int mesaXErrorFlag = 0;
  308.  
  309. static int mesaHandleXError( Display *dpy, XErrorEvent *event )
  310. {
  311.     mesaXErrorFlag = 1;
  312.     return 0;
  313. }
  314.  
  315.  
  316. /*
  317.  * Check if the X Shared Memory extension is available.
  318.  * Return:  0 = not available
  319.  *          1 = shared XImage support available
  320.  *          2 = shared Pixmap support available also
  321.  */
  322. static int check_for_xshm( Display *display )
  323. {
  324. #ifdef SHM
  325.    int major, minor, ignore;
  326.    Bool pixmaps;
  327.  
  328.    if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
  329.       if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
  330.      return (pixmaps==True) ? 2 : 1;
  331.       }
  332.       else {
  333.      return 0;
  334.       }
  335.    }
  336.    else {
  337.       return 0;
  338.    }
  339. #else
  340.    /* Can't compile XSHM support */
  341.    return 0;
  342. #endif
  343. }
  344.  
  345.  
  346. /*
  347.  * Return the width and height of the given drawable.
  348.  */
  349. static void get_drawable_size( Display *dpy, Drawable d,
  350.                    unsigned int *width, unsigned int *height )
  351. {
  352.    Window root;
  353.    int x, y;
  354.    unsigned int bw, depth;
  355.  
  356.    XGetGeometry( dpy, d, &root, &x, &y, width, height, &bw, &depth );
  357. }
  358.  
  359.  
  360.  
  361. /*
  362.  * Apply gamma correction to an intensity value in [0..max].  Return the
  363.  * new intensity value.
  364.  */
  365. static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
  366. {
  367.    double x = (double) value / (double) max;
  368.    return (GLint) ((GLfloat) max * pow( x, 1.0F/gamma ) );
  369. }
  370.  
  371.  
  372.  
  373. /*
  374.  * Return the true number of bits per pixel for XImages.
  375.  * For example, if we request a 24-bit deep visual we may actually
  376.  * get a 32-bit per pixel XImage.  This function gives us this information.
  377.  * Input:  dpy - the X display
  378.  *         visinfo - desribes the visual to be used for XImages
  379.  * Return:  true number of bits per pixel for XImages
  380.  */
  381. static int bits_per_pixel( Display *dpy, XVisualInfo *visinfo )
  382. {
  383.    XImage *img;
  384.    int bitsPerPixel;
  385.    /* Create a temporary XImage */
  386.    img = XCreateImage( dpy, visinfo->visual, visinfo->depth,
  387.                        ZPixmap, 0,           /*format, offset*/
  388.                        (char*) malloc(8),    /*data*/
  389.                        1, 1,                 /*width, height*/
  390.                        32,                   /*bitmap_pad*/
  391.                        0                     /*bytes_per_line*/
  392.                      );
  393.    assert(img);
  394.    /* grab the bits/pixel value */
  395.    bitsPerPixel = img->bits_per_pixel;
  396.    /* free the XImage */
  397.    free( img->data );
  398.    img->data = NULL;
  399.    XDestroyImage( img );
  400.    return bitsPerPixel;
  401. }
  402.  
  403.  
  404.  
  405. /*
  406.  * Determine if a given X window ID is valid (window exists).
  407.  * Do this by calling XGetWindowAttributes() for the window and
  408.  * checking if we catch an X error.
  409.  * Input:  dpy - the display
  410.  *         win - the window to check for existance
  411.  * Return:  GL_TRUE - window exists
  412.  *          GL_FALSE - window doesn't exist
  413.  */
  414. static GLboolean WindowExistsFlag;
  415.  
  416. static int window_exists_err_handler( Display* dpy, XErrorEvent* xerr )
  417. {
  418.    if (xerr->error_code == BadWindow) {
  419.       WindowExistsFlag = GL_FALSE;
  420.    }
  421.    return 0;
  422. }
  423.  
  424. static GLboolean window_exists( Display *dpy, Window win )
  425. {
  426.    XWindowAttributes wa;
  427.    int (*old_handler)( Display*, XErrorEvent* );
  428.    WindowExistsFlag = GL_TRUE;
  429.    old_handler = XSetErrorHandler(window_exists_err_handler);
  430.    XGetWindowAttributes( dpy, win, &wa ); /* dummy request */
  431.    XSetErrorHandler(old_handler);
  432.    return WindowExistsFlag;
  433. }
  434.  
  435.  
  436.  
  437. /**********************************************************************/
  438. /*****                Linked list of XMesaBuffers                 *****/
  439. /**********************************************************************/
  440.  
  441. static XMesaBuffer XMesaBufferList = NULL;
  442.  
  443.  
  444. /* Allocate a new XMesaBuffer, add to linked list */
  445. static XMesaBuffer alloc_xmesa_buffer(void)
  446. {
  447.    XMesaBuffer b = (XMesaBuffer) calloc( 1, sizeof(struct xmesa_buffer) );
  448.    if (b) {
  449.       b->Next = XMesaBufferList;
  450.       XMesaBufferList = b;
  451.    }
  452.    return b;
  453. }
  454.  
  455.  
  456. /*
  457.  * Find an XMesaBuffer by matching X display and colormap but NOT matching
  458.  * the notThis buffer.
  459.  */
  460. static XMesaBuffer find_xmesa_buffer(Display *dpy, Colormap cmap,
  461.                                      XMesaBuffer notThis)
  462. {
  463.    XMesaBuffer b;
  464.    for (b=XMesaBufferList; b; b=b->Next) {
  465.       if (b->display==dpy && b->cmap==cmap && b!=notThis) {
  466.          return b;
  467.       }
  468.    }
  469.    return NULL;
  470. }
  471.  
  472.  
  473. /*
  474.  * Free an XMesaBuffer, remove from linked list, perhaps free X colormap
  475.  * entries.
  476.  */
  477. static void free_xmesa_buffer(XMesaBuffer buffer)
  478. {
  479.    XMesaBuffer prev = NULL, b;
  480.    for (b=XMesaBufferList; b; b=b->Next) {
  481.       if (b==buffer) {
  482.          /* unlink bufer from list */
  483.          if (prev)
  484.             prev->Next = buffer->Next;
  485.          else
  486.             XMesaBufferList = buffer->Next;
  487.          /* Check to free X colors */
  488.          if (buffer->num_alloced>0) {
  489.             /* If no other buffer uses this X colormap then free the colors. */
  490.             if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) {
  491.                XFreeColors(buffer->display, buffer->cmap,
  492.                            buffer->alloced_colors, buffer->num_alloced, 0);
  493.             }
  494.          }
  495.          free(buffer);
  496.          return;
  497.       }
  498.       /* continue search */
  499.       prev = b;
  500.    }
  501.    /* buffer not found in XMesaBufferList */
  502.    gl_problem(NULL,"free_xmesa_buffer() - buffer not found\n");
  503. }
  504.  
  505.  
  506. /* Copy X color table stuff from on XMesaBuffer to another. */
  507. static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
  508. {
  509.    MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));
  510.    MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
  511.    MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g));
  512.    MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b));
  513.    dst->num_alloced = src->num_alloced;
  514.    MEMCPY(dst->alloced_colors, src->alloced_colors,
  515.           sizeof(src->alloced_colors));
  516. }
  517.  
  518.  
  519.  
  520. /**********************************************************************/
  521. /*****                   Misc Private Functions                   *****/
  522. /**********************************************************************/
  523.  
  524.  
  525. /*
  526.  * Return number of bits set in n.
  527.  */
  528. static int bitcount( unsigned long n )
  529. {
  530.    int bits;
  531.    for (bits=0; n>0; n=n>>1) {
  532.       if (n&1) {
  533.          bits++;
  534.       }
  535.    }
  536.    return bits;
  537. }
  538.  
  539.  
  540.  
  541. /*
  542.  * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
  543.  * Return:  GL_TRUE if success, GL_FALSE if error
  544.  */
  545. static GLboolean alloc_shm_back_buffer( XMesaBuffer b )
  546. {
  547. #ifdef SHM
  548.    /*
  549.     * We have to do a _lot_ of error checking here to be sure we can
  550.     * really use the XSHM extension.  It seems different servers trigger
  551.     * errors at different points if the extension won't work.  Therefore
  552.     * we have to be very careful...
  553.     */
  554.    GC gc;
  555.    int (*old_handler)( Display *, XErrorEvent * );
  556.  
  557.    b->backimage = XShmCreateImage( b->xm_visual->display,
  558.                                    b->xm_visual->visinfo->visual,
  559.                                    b->xm_visual->visinfo->depth,
  560.                    ZPixmap, NULL, &b->shminfo,
  561.                    b->width, b->height );
  562.    if (b->backimage == NULL) {
  563.       error("alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.");
  564.       b->shm = 0;
  565.       return GL_FALSE;
  566.    }
  567.  
  568.    b->shminfo.shmid = shmget( IPC_PRIVATE, b->backimage->bytes_per_line
  569.                  * b->backimage->height, IPC_CREAT|0777 );
  570.    if (b->shminfo.shmid < 0) {
  571.       if (getenv("MESA_DEBUG"))
  572.           perror("alloc_back_buffer");
  573.       XDestroyImage( b->backimage );
  574.       b->backimage = NULL;
  575.       error("alloc_back_buffer: Shared memory error (shmget), disabling.");
  576.       b->shm = 0;
  577.       return GL_FALSE;
  578.    }
  579.  
  580.    b->shminfo.shmaddr = b->backimage->data
  581.                       = (char*)shmat( b->shminfo.shmid, 0, 0 );
  582.    if (b->shminfo.shmaddr == (char *) -1) {
  583.       if (getenv("MESA_DEBUG"))
  584.           perror("alloc_back_buffer");
  585.       XDestroyImage( b->backimage );
  586.       shmctl( b->shminfo.shmid, IPC_RMID, 0 );
  587.       b->backimage = NULL;
  588.       error("alloc_back_buffer: Shared memory error (shmat), disabling.");
  589.       b->shm = 0;
  590.       return GL_FALSE;
  591.    }
  592.  
  593.    b->shminfo.readOnly = False;
  594.    mesaXErrorFlag = 0;
  595.    old_handler = XSetErrorHandler( mesaHandleXError );
  596.    /* This may trigger the X protocol error we're ready to catch: */
  597.    XShmAttach( b->xm_visual->display, &b->shminfo );
  598.    XSync( b->xm_visual->display, False );
  599.  
  600.    if (mesaXErrorFlag) {
  601.       /* we are on a remote display, this error is normal, don't print it */
  602.       XFlush( b->xm_visual->display );
  603.       mesaXErrorFlag = 0;
  604.       XDestroyImage( b->backimage );
  605.       shmdt( b->shminfo.shmaddr );
  606.       shmctl( b->shminfo.shmid, IPC_RMID, 0 );
  607.       b->backimage = NULL;
  608.       b->shm = 0;
  609.       (void) XSetErrorHandler( old_handler );
  610.       return GL_FALSE;
  611.    }
  612.  
  613.    shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */
  614.  
  615.    /* Finally, try an XShmPutImage to be really sure the extension works */
  616.    gc = XCreateGC( b->xm_visual->display, b->frontbuffer, 0, NULL );
  617.    XShmPutImage( b->xm_visual->display, b->frontbuffer, gc,
  618.          b->backimage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False );
  619.    XSync( b->xm_visual->display, False );
  620.    XFreeGC( b->xm_visual->display, gc );
  621.    (void) XSetErrorHandler( old_handler );
  622.    if (mesaXErrorFlag) {
  623.       XFlush( b->xm_visual->display );
  624.       mesaXErrorFlag = 0;
  625.       XDestroyImage( b->backimage );
  626.       shmdt( b->shminfo.shmaddr );
  627.       shmctl( b->shminfo.shmid, IPC_RMID, 0 );
  628.       b->backimage = NULL;
  629.       b->shm = 0;
  630.       return GL_FALSE;
  631.    }
  632.  
  633.    return GL_TRUE;
  634. #else
  635.    /* Can't compile XSHM support */
  636.    return GL_FALSE;
  637. #endif
  638. }
  639.  
  640.  
  641.  
  642. /*
  643.  * Setup an off-screen pixmap or Ximage to use as the back buffer.
  644.  * Input:  b - the X/Mesa buffer
  645.  */
  646. void xmesa_alloc_back_buffer( XMesaBuffer b )
  647. {
  648.    if (b->db_state==BACK_XIMAGE) {
  649.       /* Deallocate the old backimage, if any */
  650.       if (b->backimage) {
  651. #ifdef SHM
  652.      if (b->shm) {
  653.         XShmDetach( b->xm_visual->display, &b->shminfo );
  654.         XDestroyImage( b->backimage );
  655.         shmdt( b->shminfo.shmaddr );
  656.      }
  657.      else
  658. #endif
  659.        XDestroyImage( b->backimage );
  660.      b->backimage = NULL;
  661.       }
  662.  
  663.       /* Allocate new back buffer */
  664.       if (b->shm==0 || alloc_shm_back_buffer(b)==GL_FALSE) {
  665.      /* Allocate a regular XImage for the back buffer. */
  666.      b->backimage = XCreateImage( b->xm_visual->display,
  667.                                       b->xm_visual->visinfo->visual,
  668.                                       b->xm_visual->visinfo->depth,
  669.                       ZPixmap, 0,   /* format, offset */
  670.                       NULL, b->width, b->height,
  671.                       8, 0 );  /* pad, bytes_per_line */
  672.      if (!b->backimage) {
  673.         error("alloc_back_buffer: XCreateImage failed.");
  674.      }
  675.          b->backimage->data = (char *) malloc( b->backimage->height
  676.                                              * b->backimage->bytes_per_line );
  677.          if (!b->backimage->data) {
  678.             error("alloc_back_buffer: malloc failed.");
  679.             XDestroyImage( b->backimage );
  680.             b->backimage = NULL;
  681.          }
  682.       }
  683.       b->backpixmap = None;
  684.    }
  685.    else if (b->db_state==BACK_PIXMAP) {
  686.       Pixmap old_pixmap = b->backpixmap;
  687.       /* Free the old back pixmap */
  688.       if (b->backpixmap) {
  689.      XFreePixmap( b->xm_visual->display, b->backpixmap );
  690.       }
  691.       /* Allocate new back pixmap */
  692.       b->backpixmap = XCreatePixmap( b->xm_visual->display, b->frontbuffer,
  693.                      b->width, b->height,
  694.                                      b->xm_visual->visinfo->depth );
  695.       b->backimage = NULL;
  696.       /* update other references to backpixmap */
  697.       if (b->buffer==old_pixmap) {
  698.      b->buffer = b->backpixmap;
  699.       }
  700.    }
  701. }
  702.  
  703.  
  704.  
  705. /*
  706.  * A replacement for XAllocColor.  This function should never
  707.  * fail to allocate a color.  When XAllocColor fails, we return
  708.  * the nearest matching color.  If we have to allocate many colors
  709.  * this function isn't too efficient; the XQueryColors() could be
  710.  * done just once.
  711.  * Written by Michael Pichler, Brian Paul, Mark Kilgard
  712.  * Input:  dpy - X display
  713.  *         cmap - X colormap
  714.  *         cmapSize - size of colormap
  715.  * In/Out: color - the XColor struct
  716.  * Output:  exact - 1=exact color match, 0=closest match
  717.  *          alloced - 1=XAlloc worked, 0=XAlloc failed
  718.  */
  719. static void
  720. noFaultXAllocColor( Display *dpy, Colormap cmap, int cmapSize,
  721.                     XColor *color, int *exact, int *alloced )
  722. {
  723.    XColor *ctable, subColor;
  724.    int i, bestmatch;
  725.    double mindist;       /* 3*2^16^2 exceeds long int precision. */
  726.  
  727.    /* First try just using XAllocColor. */
  728.    if (XAllocColor(dpy, cmap, color)) {
  729.       *exact = 1;
  730.       *alloced = 1;
  731.       return;
  732.    }
  733.  
  734.    /* Alloc failed, search for closest match */
  735.  
  736.    /* Retrieve color table entries. */
  737.    /* XXX alloca candidate. */
  738.    ctable = (XColor *) malloc(cmapSize * sizeof(XColor));
  739.    for (i = 0; i < cmapSize; i++) {
  740.       ctable[i].pixel = i;
  741.    }
  742.    XQueryColors(dpy, cmap, ctable, cmapSize);
  743.  
  744.    /* Find best match. */
  745.    bestmatch = -1;
  746.    mindist = 0.0;
  747.    for (i = 0; i < cmapSize; i++) {
  748.       double dr = 0.30 * ((double) color->red - (double) ctable[i].red);
  749.       double dg = 0.59 * ((double) color->green - (double) ctable[i].green);
  750.       double db = 0.11 * ((double) color->blue - (double) ctable[i].blue);
  751.       double dist = dr * dr + dg * dg + db * db;
  752.       if (bestmatch < 0 || dist < mindist) {
  753.          bestmatch = i;
  754.          mindist = dist;
  755.       }
  756.    }
  757.  
  758.    /* Return result. */
  759.    subColor.red   = ctable[bestmatch].red;
  760.    subColor.green = ctable[bestmatch].green;
  761.    subColor.blue  = ctable[bestmatch].blue;
  762.    /* Try to allocate the closest match color.  This should only
  763.     * fail if the cell is read/write.  Otherwise, we're incrementing
  764.     * the cell's reference count.
  765.     */
  766.    if (XAllocColor(dpy, cmap, &subColor)) {
  767.       *alloced = 1;
  768.    }
  769.    else {
  770.       /* do this to work around a problem reported by Frank Ortega */
  771.       subColor.pixel = (unsigned long) bestmatch;
  772.       subColor.red   = ctable[bestmatch].red;
  773.       subColor.green = ctable[bestmatch].green;
  774.       subColor.blue  = ctable[bestmatch].blue;   
  775.       subColor.flags = DoRed | DoGreen | DoBlue;
  776.       *alloced = 0;
  777.    }
  778.    free(ctable);
  779.    *color = subColor;
  780.    *exact = 0;
  781. }
  782.  
  783.  
  784.  
  785. /*
  786.  * Do setup for PF_GRAYSCALE pixel format.
  787.  * Note that buffer may be NULL.
  788.  */
  789. static GLboolean setup_grayscale( XMesaVisual v, XMesaBuffer buffer,
  790.                                   Colormap cmap )
  791. {
  792.    if (v->visinfo->depth<4 || v->visinfo->depth>16) {
  793.       return GL_FALSE;
  794.    }
  795.  
  796.    if (buffer) {
  797.       XMesaBuffer prevBuffer;
  798.  
  799.       if (!cmap) {
  800.          return GL_FALSE;
  801.       }
  802.  
  803.       prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
  804.       if (prevBuffer) {
  805.          /* Copy colormap stuff from previous XMesaBuffer which uses same
  806.           * X colormap.  Do this to avoid time spent in noFaultXAllocColor.
  807.           */
  808.          copy_colortable_info(buffer, prevBuffer);
  809.       }
  810.       else {
  811.          /* Allocate 256 shades of gray */
  812.          int gray;
  813.          int colorsfailed = 0;
  814.          for (gray=0;gray<256;gray++) {
  815.             GLint r = gamma_adjust( v->RedGamma,   gray, 255 );
  816.             GLint g = gamma_adjust( v->GreenGamma, gray, 255 );
  817.             GLint b = gamma_adjust( v->BlueGamma,  gray, 255 );
  818.             int exact, alloced;
  819.             XColor xcol;
  820.             xcol.red   = (r << 8) | r;
  821.             xcol.green = (g << 8) | g;
  822.             xcol.blue  = (b << 8) | b;
  823.             noFaultXAllocColor( v->display, cmap, v->visinfo->colormap_size,
  824.                                 &xcol, &exact, &alloced );
  825.             if (!exact) {
  826.                colorsfailed++;
  827.             }
  828.             if (alloced) {
  829.                assert(buffer->num_alloced<256);
  830.                buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
  831.                buffer->num_alloced++;
  832.             }
  833.  
  834.             assert(gray < 576);
  835.             buffer->color_table[gray] = xcol.pixel;
  836.             assert(xcol.pixel < 65536);
  837.             buffer->pixel_to_r[xcol.pixel] = gray * 30 / 100;
  838.             buffer->pixel_to_g[xcol.pixel] = gray * 59 / 100;
  839.             buffer->pixel_to_b[xcol.pixel] = gray * 11 / 100;
  840.          }
  841.  
  842.          if (colorsfailed && getenv("MESA_DEBUG")) {
  843.             fprintf( stderr,
  844.                   "Note: %d out of 256 needed colors do not match exactly.\n",
  845.                   colorsfailed );
  846.          }
  847.       }
  848.    }
  849.  
  850. #define WEIGHT
  851. #ifdef WEIGHT
  852.    v->rmult = 30 * 255 / 100;
  853.    v->gmult = 59 * 255 / 100;
  854.    v->bmult = 11 * 255 / 100;
  855. #else
  856.    v->rmult = 255/3;
  857.    v->gmult = 255/3;
  858.    v->bmult = 255/3;
  859. #endif
  860.    v->dithered_pf = PF_GRAYSCALE;
  861.    v->undithered_pf = PF_GRAYSCALE;
  862.    return GL_TRUE;
  863. }
  864.  
  865.  
  866.  
  867. /*
  868.  * Setup RGB rendering for a window with a PseudoColor, StaticColor,
  869.  * or 8-bit TrueColor visual visual.  We try to allocate a palette of 225
  870.  * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB
  871.  * color.  While this function was originally designed just for 8-bit
  872.  * visuals, it has also proven to work from 4-bit up to 16-bit visuals.
  873.  * Dithering code contributed by Bob Mercier.
  874.  */
  875. static GLboolean setup_dithered_color( XMesaVisual v, XMesaBuffer buffer,
  876.                                        Window window, Colormap cmap )
  877. {
  878.    if (v->visinfo->depth<4 || v->visinfo->depth>16) {
  879.       return GL_FALSE;
  880.    }
  881.  
  882.    if (buffer) {
  883.       XMesaBuffer prevBuffer;
  884.  
  885.       if (!cmap) {
  886.          return GL_FALSE;
  887.       }
  888.  
  889.       prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
  890.       if (prevBuffer) {
  891.          /* Copy colormap stuff from previous, matching XMesaBuffer.
  892.           * Do this to avoid time spent in noFaultXAllocColor.
  893.           */
  894.          copy_colortable_info(buffer, prevBuffer);
  895.       }
  896.       else {
  897.          /* Allocate X colors and initialize color_table[], red_table[], etc */
  898.          int r, g, b, i;
  899.          int colorsfailed = 0;
  900.          for (r = 0; r < _R; r++) {
  901.             for (g = 0; g < _G; g++) {
  902.                for (b = 0; b < _B; b++) {
  903.                   XColor xcol;
  904.                   int exact, alloced;
  905.                   xcol.red  =gamma_adjust(v->RedGamma,   r*65535/(_R-1),65535);
  906.                   xcol.green=gamma_adjust(v->GreenGamma, g*65535/(_G-1),65535);
  907.                   xcol.blue =gamma_adjust(v->BlueGamma,  b*65535/(_B-1),65535);
  908.                   noFaultXAllocColor(v->display, cmap,
  909.                                      v->visinfo->colormap_size, &xcol, &exact,
  910.                                      &alloced);
  911.                   if (!exact) {
  912.                      colorsfailed++;
  913.                   }
  914.                   if (alloced) {
  915.                      assert(buffer->num_alloced<256);
  916.                      buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
  917.                      buffer->num_alloced++;
  918.                   }
  919.                   i = _MIX( r, g, b );
  920.                   assert(i < 576);
  921.                   buffer->color_table[i] = xcol.pixel;
  922.                   assert(xcol.pixel < 65536);
  923.                   buffer->pixel_to_r[xcol.pixel] = r * 255 / (_R-1);
  924.                   buffer->pixel_to_g[xcol.pixel] = g * 255 / (_G-1);
  925.                   buffer->pixel_to_b[xcol.pixel] = b * 255 / (_B-1);
  926.                }
  927.             }
  928.          }
  929.  
  930.          if (colorsfailed && getenv("MESA_DEBUG")) {
  931.             fprintf( stderr,
  932.                   "Note: %d out of %d needed colors do not match exactly.\n",
  933.                   colorsfailed, _R*_G*_B );
  934.          }
  935.       }
  936.    }
  937.  
  938.    v->rmult = 255;
  939.    v->gmult = 255;
  940.    v->bmult = 255;
  941.    v->dithered_pf = PF_DITHER;
  942.    v->undithered_pf = PF_LOOKUP;
  943.    return GL_TRUE;
  944. }
  945.  
  946.  
  947. /*
  948.  * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
  949.  * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
  950.  * Special dithering tables have to be initialized.
  951.  */
  952. static void setup_8bit_hpcr( XMesaVisual v )
  953. {
  954.    /* HP Color Recovery contributed by:  Alex De Bruyn (ad@lms.be)
  955.     * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
  956.     * on the root window AND the colormap obtainable by XGetRGBColormaps
  957.     * for that atom must be set on the window.  (see also tkInitWindow)
  958.     * If that colormap is not set, the output will look stripy.
  959.     */
  960.  
  961.    /* Setup color tables with gamma correction */
  962.    int i;
  963.    double g;
  964.  
  965.    g = 1.0 / v->RedGamma; 
  966.    for (i=0; i<256; i++) { 
  967.       GLint red = 255.0 * pow( hpcr_rTbl[i]/255.0, g ) + 0.5;
  968.       v->hpcr_rTbl[i] = CLAMP( red, 16, 239 );
  969.    }
  970.  
  971.    g = 1.0 / v->GreenGamma;
  972.    for (i=0; i<256; i++) {
  973.       GLint green = 255.0 * pow( hpcr_gTbl[i]/255.0, g ) + 0.5;
  974.       v->hpcr_gTbl[i] = CLAMP( green, 16, 239 );
  975.    }
  976.  
  977.    g = 1.0 / v->BlueGamma;
  978.    for (i=0; i<256; i++) {
  979.       GLint blue = 255.0 * pow( hpcr_bTbl[i]/255.0, g ) + 0.5;
  980.       v->hpcr_bTbl[i] = CLAMP( blue, 32, 223 );
  981.    }
  982.    v->rmult = 255;
  983.    v->gmult = 255;
  984.    v->bmult = 255;
  985.    v->undithered_pf = PF_HPCR;  /* can't really disable dithering for now */
  986.    v->dithered_pf = PF_HPCR;
  987. }
  988.  
  989.  
  990.  
  991. /*
  992.  * Setup RGB rendering for a window with a True/DirectColor visual.
  993.  */
  994. static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
  995.                              Window window, Colormap cmap )
  996. {
  997.    unsigned long rmask, gmask, bmask;
  998.    int bitsPerPixel;
  999.  
  1000.    /* Compute red multiplier (mask) and bit shift */
  1001.    v->rshift = 0;
  1002.    rmask = v->visinfo->red_mask;
  1003.    while ((rmask & 1)==0) {
  1004.       v->rshift++;
  1005.       rmask = rmask >> 1;
  1006.    }
  1007.  
  1008.    /* Compute green multiplier (mask) and bit shift */
  1009.    v->gshift = 0;
  1010.    gmask = v->visinfo->green_mask;
  1011.    while ((gmask & 1)==0) {
  1012.       v->gshift++;
  1013.       gmask = gmask >> 1;
  1014.    }
  1015.  
  1016.    /* Compute blue multiplier (mask) and bit shift */
  1017.    v->bshift = 0;
  1018.    bmask = v->visinfo->blue_mask;
  1019.    while ((bmask & 1)==0) {
  1020.       v->bshift++;
  1021.       bmask = bmask >> 1;
  1022.    }
  1023.  
  1024.    /*
  1025.     * Compute component-to-pixel lookup tables and dithering kernel
  1026.     */
  1027.    {
  1028.       static GLubyte kernel[16] = {
  1029.           0*16,  8*16,  2*16, 10*16,
  1030.          12*16,  4*16, 14*16,  6*16,
  1031.           3*16, 11*16,  1*16,  9*16,
  1032.          15*16,  7*16, 13*16,  5*16,
  1033.       };
  1034.       GLint rBits = bitcount(rmask);
  1035.       GLint gBits = bitcount(gmask);
  1036.       GLint bBits = bitcount(bmask);
  1037.       GLint minBits;
  1038.       GLint i;
  1039.  
  1040.       /* convert pixel components in [0,_mask] to RGB values in [0,255] */
  1041.       for (i=0; i<=rmask; i++)
  1042.          v->PixelToR[i] = (i * 255) / rmask;
  1043.       for (i=0; i<=gmask; i++)
  1044.          v->PixelToG[i] = (i * 255) / gmask;
  1045.       for (i=0; i<=bmask; i++)
  1046.          v->PixelToB[i] = (i * 255) / bmask;
  1047.  
  1048.       /* convert RGB values from [0,255] to pixel components */
  1049.       for (i=0;i<256;i++) {
  1050.          GLint r = gamma_adjust(v->RedGamma,   i, 255);
  1051.          GLint g = gamma_adjust(v->GreenGamma, i, 255);
  1052.          GLint b = gamma_adjust(v->BlueGamma,  i, 255);
  1053.          v->RtoPixel[i] = (r >> (8-rBits)) << v->rshift;
  1054.          v->GtoPixel[i] = (g >> (8-gBits)) << v->gshift;
  1055.          v->BtoPixel[i] = (b >> (8-bBits)) << v->bshift;
  1056.       }
  1057.       /* overflow protection */
  1058.       for (i=256;i<512;i++) {
  1059.          v->RtoPixel[i] = v->RtoPixel[255];
  1060.          v->GtoPixel[i] = v->GtoPixel[255];
  1061.          v->BtoPixel[i] = v->BtoPixel[255];
  1062.       }
  1063.  
  1064.       /* setup dithering kernel */
  1065.       minBits = rBits;
  1066.       if (gBits < minBits)  minBits = gBits;
  1067.       if (bBits < minBits)  minBits = bBits;
  1068.       for (i=0;i<16;i++) {
  1069.          v->Kernel[i] = kernel[i] >> minBits;
  1070.       }
  1071.  
  1072.       v->rmult = v->gmult = v->bmult = 255;
  1073.       v->undithered_pf = PF_TRUECOLOR;
  1074.       v->dithered_pf = (v->visinfo->depth<24) ? PF_TRUEDITHER : PF_TRUECOLOR;
  1075.    }
  1076.  
  1077.    /*
  1078.     * Now check for TrueColor visuals which we can optimize.
  1079.     */
  1080.  
  1081.    bitsPerPixel = bits_per_pixel( v->display, v->visinfo );
  1082.  
  1083.    if (   v->visinfo->red_mask  ==0x0000ff
  1084.        && v->visinfo->green_mask==0x00ff00
  1085.        && v->visinfo->blue_mask ==0xff0000
  1086.        && host_byte_order()==ImageByteOrder(v->display)
  1087.        && bitsPerPixel==32
  1088.        && sizeof(GLuint)==4
  1089.        && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
  1090.       /* common 24-bit config used on SGI, Sun */
  1091.       v->undithered_pf = v->dithered_pf = PF_8A8B8G8R;
  1092.    }
  1093.    else if (v->visinfo->red_mask  ==0xff0000
  1094.        &&   v->visinfo->green_mask==0x00ff00
  1095.        &&   v->visinfo->blue_mask ==0x0000ff
  1096.        && host_byte_order()==ImageByteOrder(v->display)
  1097.        && bitsPerPixel==32
  1098.        && sizeof(GLuint)==4
  1099.        && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
  1100.       /* common 24-bit config used on Linux, HP, IBM */
  1101.       v->undithered_pf = v->dithered_pf = PF_8R8G8B;
  1102.    }
  1103.    else if (v->visinfo->red_mask  ==0xf800
  1104.        &&   v->visinfo->green_mask==0x07e0
  1105.        &&   v->visinfo->blue_mask ==0x001f
  1106.        && host_byte_order()==ImageByteOrder(v->display)
  1107.        && bitsPerPixel==16
  1108.        && sizeof(GLushort)==2
  1109.        && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
  1110.       /* 5-6-5 color weight on common PC VGA boards */
  1111.       v->undithered_pf = PF_5R6G5B;
  1112.       v->dithered_pf = PF_TRUEDITHER;
  1113.    }
  1114.    else if (v->visinfo->red_mask  ==0xe0
  1115.        &&   v->visinfo->green_mask==0x1c
  1116.        &&   v->visinfo->blue_mask ==0x03
  1117.        && XInternAtom(v->display, "_HP_RGB_SMOOTH_MAP_LIST", True)) {
  1118.       setup_8bit_hpcr( v );
  1119.    }
  1120. }
  1121.  
  1122.  
  1123.  
  1124. /*
  1125.  * Setup RGB rendering for a window with a monochrome visual.
  1126.  */
  1127. static void setup_monochrome( XMesaVisual v )
  1128. {
  1129.    v->rmult = 255;
  1130.    v->gmult = 255;
  1131.    v->bmult = 255;
  1132.    v->dithered_pf = v->undithered_pf = PF_1BIT;
  1133.    /* if black=1 then we must flip pixel values */
  1134.    v->bitFlip = (BlackPixel(v->display, v->visinfo->screen) != 0);
  1135. }
  1136.  
  1137.  
  1138.  
  1139. /*
  1140.  * When a context is "made current" for the first time, we can finally
  1141.  * finish initializing the context's visual and buffer information.
  1142.  * Input:  v - the XMesaVisual to initialize
  1143.  *         b - the XMesaBuffer to initialize (may be NULL)
  1144.  *         rgb_flag - TRUE = RGBA mode, FALSE = color index mode
  1145.  *         window - the window/pixmap we're rendering into
  1146.  *         cmap - the colormap associated with the window/pixmap
  1147.  * Return:  GL_TRUE=success, GL_FALSE=failure
  1148.  */
  1149. static GLboolean initialize_visual_and_buffer( XMesaVisual v,
  1150.                                                XMesaBuffer b,
  1151.                                                GLboolean rgb_flag,
  1152.                                                Window window,
  1153.                                                Colormap cmap )
  1154. {
  1155.    XGCValues gcvalues;
  1156.  
  1157.    if (b) {
  1158.       assert(b->xm_visual == v);
  1159.    }
  1160.  
  1161.    if (rgb_flag==GL_FALSE) {
  1162.       /* COLOR-INDEXED WINDOW:
  1163.        * Even if the visual is TrueColor or DirectColor we treat it as
  1164.        * being color indexed.  This is weird but might be useful to someone.
  1165.        */
  1166.       v->dithered_pf = v->undithered_pf = PF_INDEX;
  1167.       v->rmult = v->gmult = v->bmult = 0;
  1168.       v->index_bits = v->visinfo->depth;
  1169.    }
  1170.    else {
  1171.       /* RGB WINDOW:
  1172.        * We support RGB rendering into almost any kind of visual.
  1173.        */
  1174.       int xclass;
  1175. #if defined(__cplusplus) || defined(c_plusplus)
  1176.       xclass = v->visinfo->c_class;
  1177. #else
  1178.       xclass = v->visinfo->class;
  1179. #endif
  1180.       if (xclass==TrueColor || xclass==DirectColor) {
  1181.      setup_truecolor( v, b, window, cmap );
  1182.       }
  1183.       else if (xclass==StaticGray && v->visinfo->depth==1) {
  1184.      setup_monochrome( v );
  1185.       }
  1186.       else if (xclass==GrayScale || xclass==StaticGray) {
  1187.          if (!setup_grayscale( v, b, cmap )) {
  1188.             return GL_FALSE;
  1189.          }
  1190.       }
  1191.       else if ((xclass==PseudoColor || xclass==StaticColor)
  1192.                && v->visinfo->depth>=4 && v->visinfo->depth<=16) {
  1193.      if (!setup_dithered_color( v, b, window, cmap )) {
  1194.             return GL_FALSE;
  1195.          }
  1196.       }
  1197.       else {
  1198.      error("XMesa: RGB mode rendering not supported in given visual.");
  1199.      return GL_FALSE;
  1200.       }
  1201.       v->index_bits = 0;
  1202.    }
  1203.  
  1204.    /*
  1205.     * If MESA_INFO env var is set print out some debugging info
  1206.     * which can help Brian figure out what's going on when a user
  1207.     * reports bugs.
  1208.     */
  1209.    if (getenv("MESA_INFO")) {
  1210.       printf("v = %p\n", v);
  1211.       printf("dithered pf = %d\n", v->dithered_pf);
  1212.       printf("undithered pf = %d\n", v->undithered_pf);
  1213.       printf("level = %d\n", v->level);
  1214.       printf("depth = %d\n", v->visinfo->depth);
  1215.       printf("bits per pixel = %d\n", bits_per_pixel(v->display, v->visinfo));
  1216.    }
  1217.  
  1218.    if (b && window) {
  1219.       /* Do window-specific initializations */
  1220.  
  1221.       /* Window dimensions */
  1222.       unsigned int w, h;
  1223.       get_drawable_size( v->display, window, &w, &h );
  1224.       b->width = w;
  1225.       b->height = h;
  1226.  
  1227.       b->frontbuffer = window;
  1228.  
  1229.       assert( v->gl_visual );
  1230.  
  1231.       /* Setup for single/double buffering */
  1232.       if (v->gl_visual->DBflag) {
  1233.          /* Double buffered */
  1234.          b->shm = check_for_xshm( v->display );
  1235.          xmesa_alloc_back_buffer( b );
  1236.          if (b->db_state==BACK_PIXMAP) {
  1237.             b->buffer = b->backpixmap;
  1238.          }
  1239.          else {
  1240.             b->buffer = XIMAGE;
  1241.          }
  1242.       }
  1243.       else {
  1244.          /* Single Buffered */
  1245.          b->buffer = b->frontbuffer;
  1246.       }
  1247.  
  1248.       /* X11 graphics contexts */
  1249.       b->gc1 = XCreateGC( v->display, window, 0, NULL );
  1250.       XSetFunction( v->display, b->gc1, GXcopy );
  1251.       b->gc2 = XCreateGC( v->display, window, 0, NULL );
  1252.       XSetFunction( v->display, b->gc2, GXcopy );
  1253.       /*
  1254.        * Don't generate Graphics Expose/NoExpose events in swapbuffers().
  1255.        * Patch contributed by Michael Pichler May 15, 1995.
  1256.        */
  1257.       gcvalues.graphics_exposures = False;
  1258.       b->cleargc = XCreateGC( v->display, window,
  1259.                               GCGraphicsExposures, &gcvalues);
  1260.       XSetFunction( v->display, b->cleargc, GXcopy );
  1261.  
  1262.       /* Initialize the row buffer XImage for use in write_color_span() */
  1263.       b->rowimage = XCreateImage( v->display,
  1264.                                   v->visinfo->visual,
  1265.                                   v->visinfo->depth,
  1266.                                   ZPixmap, 0,           /*format, offset*/
  1267.                                   (char*) malloc(MAX_WIDTH*4),  /*data*/
  1268.                                   MAX_WIDTH, 1,         /*width, height*/
  1269.                                   32,                   /*bitmap_pad*/
  1270.                                   0                     /*bytes_per_line*/ );
  1271.    }
  1272.  
  1273.    return GL_TRUE;
  1274. }
  1275.  
  1276.  
  1277.  
  1278. /*
  1279.  * Convert an RGBA color to a pixel value.
  1280.  */
  1281. unsigned long xmesa_color_to_pixel( XMesaContext xmesa,
  1282.                                     GLubyte r, GLubyte g, GLubyte b, GLubyte a)
  1283. {
  1284.    switch (xmesa->pixelformat) {
  1285.       case PF_INDEX:
  1286.          return 0;
  1287.       case PF_TRUECOLOR:
  1288.          {
  1289.             unsigned long p;
  1290.             PACK_TRUECOLOR( p, r, g, b );
  1291.             return p;
  1292.          }
  1293.       case PF_8A8B8G8R:
  1294.          return PACK_8A8B8G8R( r, g, b, a );
  1295.       case PF_8R8G8B:
  1296.          return PACK_8R8G8B( r, g, b );
  1297.       case PF_5R6G5B:
  1298.          return PACK_5R6G5B( r, g, b );
  1299.       case PF_DITHER:
  1300.          {
  1301.             DITHER_SETUP;
  1302.             return DITHER( 1, 0, r, g, b );
  1303.          }
  1304.       case PF_1BIT:
  1305.          /* 382 = (3*255)/2 */
  1306.          return ((r+g+b) > 382U) ^ xmesa->xm_visual->bitFlip;
  1307.       case PF_HPCR:
  1308.          return DITHER_HPCR(1, 1, r, g, b);
  1309.       case PF_LOOKUP:
  1310.          {
  1311.             LOOKUP_SETUP;
  1312.             return LOOKUP( r, g, b );
  1313.          }
  1314.       case PF_GRAYSCALE:
  1315.          return GRAY_RGB( r, g, b );
  1316.       case PF_TRUEDITHER:
  1317.          {
  1318.             unsigned long p;
  1319.             PACK_TRUEDITHER(p, 1, 0, r, g, b);
  1320.             return p;
  1321.          }
  1322.       default:
  1323.          gl_problem(NULL, "Bad pixel format in xmesa_color_to_pixel");
  1324.          return 0;
  1325.    }
  1326.    return 0;  /*never get here*/
  1327. }
  1328.  
  1329.  
  1330. /**********************************************************************/
  1331. /*****                       Public Functions                     *****/
  1332. /**********************************************************************/
  1333.  
  1334.  
  1335. /*
  1336.  * Create a new X/Mesa visual.
  1337.  * Input:  display - the X display
  1338.  *         visinfo - the XVisualInfo
  1339.  *         rgb_flag - TRUE=RGB(A) mode, FALSE=CI mode
  1340.  *         alpha_flag - need alpha planes?
  1341.  *         db_flag - TRUE=double bufferd, FALSE=single
  1342.  *         ximage_flag - TRUE=use XImage for back buffer, FALSE=use Pixmap
  1343.  *         depth_size - requested min bits per depth buffer value
  1344.  *         stencil_size - requested min bits per stencil buffer value
  1345.  *         accum_size - requested min bits per accum buffer value (per channel)
  1346.  *         level - 0=normal, 1=overaly, -1=underlay, etc.
  1347.  * Return:  New XMesaVisual or NULL if something goes wrong
  1348.  */
  1349. XMesaVisual XMesaCreateVisual( Display *display,
  1350.                                XVisualInfo *visinfo,
  1351.                                GLboolean rgb_flag,
  1352.                                GLboolean alpha_flag,
  1353.                                GLboolean db_flag,
  1354.                                GLboolean ximage_flag,
  1355.                                GLint depth_size,
  1356.                                GLint stencil_size,
  1357.                                GLint accum_size,
  1358.                                GLint level )
  1359. {
  1360.    char *gamma;
  1361.    XMesaVisual v;
  1362.    GLfloat red_scale, green_scale, blue_scale, alpha_scale;
  1363.    GLint red_bits, green_bits, blue_bits, alpha_bits;
  1364.  
  1365.    /* For debugging only */
  1366.    if (getenv("MESA_XSYNC")) {
  1367.       XSynchronize( display, 1 );    /* This makes debugging X easier */
  1368.    }
  1369.  
  1370.    v = (XMesaVisual) calloc( 1, sizeof(struct xmesa_visual) );
  1371.    if (!v) {
  1372.       return NULL;
  1373.    }
  1374.  
  1375.    v->display = display;
  1376.  
  1377.    /* Save a copy of the XVisualInfo struct because the user may XFree()
  1378.     * the struct but we may need some of the information contained in it
  1379.     * at a later time.
  1380.     */
  1381.    v->visinfo = (XVisualInfo *) malloc(sizeof(*visinfo));
  1382.    if(!v->visinfo) {
  1383.       free(v);
  1384.       return NULL;
  1385.    }
  1386.    MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
  1387.  
  1388.    /* Save a copy of the pointer now so we can find this visual again
  1389.     * if we need to search for it in find_glx_visual().
  1390.     */
  1391.    v->vishandle = visinfo;
  1392.  
  1393.    /* check for MESA_GAMMA environment variable */
  1394.    gamma = getenv("MESA_GAMMA");
  1395.    if (gamma) {
  1396.       v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0;
  1397.       sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma );
  1398.       if (v->RedGamma<=0.0)    v->RedGamma = 1.0;
  1399.       if (v->GreenGamma<=0.0)  v->GreenGamma = v->RedGamma;
  1400.       if (v->BlueGamma<=0.0)   v->BlueGamma = v->RedGamma;
  1401.    }
  1402.    else {
  1403.       v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0;
  1404.    }
  1405.  
  1406.    v->ximage_flag = ximage_flag;
  1407.    v->level = level;
  1408.  
  1409.    (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 );
  1410.  
  1411.    red_scale   = (GLfloat) v->rmult;
  1412.    green_scale = (GLfloat) v->gmult;
  1413.    blue_scale  = (GLfloat) v->bmult;
  1414.    alpha_scale = 255.0;
  1415.  
  1416.    {
  1417.       int xclass;
  1418. #if defined(__cplusplus) || defined(c_plusplus)
  1419.       xclass = v->visinfo->c_class;
  1420. #else
  1421.       xclass = v->visinfo->class;
  1422. #endif
  1423.       if (xclass==TrueColor || xclass==DirectColor) {
  1424.          red_bits   = bitcount(v->visinfo->red_mask);
  1425.          green_bits = bitcount(v->visinfo->green_mask);
  1426.          blue_bits  = bitcount(v->visinfo->blue_mask);
  1427.          alpha_bits = 0;
  1428.       }
  1429.       else {
  1430.          /* this is an approximation */
  1431.          int depth = v->visinfo->depth;
  1432.          red_bits = depth / 3;
  1433.          depth -= red_bits;
  1434.          green_bits = depth / 2;
  1435.          depth -= green_bits;
  1436.          blue_bits = depth;
  1437.          alpha_bits = 0;
  1438.          assert( red_bits + green_bits + blue_bits == v->visinfo->depth );
  1439.       }
  1440.    }
  1441.  
  1442.    v->gl_visual = gl_create_visual( rgb_flag, alpha_flag, db_flag,
  1443.                                     depth_size, stencil_size, accum_size,
  1444.                                     v->index_bits,
  1445.                                     red_scale, green_scale,
  1446.                                     blue_scale, alpha_scale,
  1447.                                     red_bits, green_bits,
  1448.                                     blue_bits, alpha_bits );
  1449.    if (!v->gl_visual) {
  1450.       free(v->visinfo);
  1451.       free(v);
  1452.       return NULL;
  1453.    }
  1454.  
  1455.    return v;
  1456. }
  1457.  
  1458.  
  1459.  
  1460. void XMesaDestroyVisual( XMesaVisual v )
  1461. {
  1462.    gl_destroy_visual( v->gl_visual );
  1463.    free(v->visinfo);
  1464.    free(v);
  1465. }
  1466.  
  1467.  
  1468.  
  1469. /*
  1470.  * Create a new XMesaContext.
  1471.  * Input:  v - XMesaVisual
  1472.  *         share_list - another XMesaContext with which to share display
  1473.  *                      lists or NULL if no sharing is wanted.
  1474.  * Return:  an XMesaContext or NULL if error.
  1475.  */
  1476. XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
  1477. {
  1478.    XMesaContext c;
  1479.    char *fxEnvVar;
  1480.  
  1481.    c = (XMesaContext) calloc( 1, sizeof(struct xmesa_context) );
  1482.    if (!c) {
  1483.       return NULL;
  1484.    }
  1485.  
  1486.    c->gl_ctx = gl_create_context( v->gl_visual,
  1487.                                   share_list ? share_list->gl_ctx : NULL,
  1488.                                   (void *) c );
  1489.    if (!c->gl_ctx) {
  1490.       free(c);
  1491.       return NULL;
  1492.    }
  1493.  
  1494.    if (host_byte_order()==ImageByteOrder(v->display)) {
  1495.       c->swapbytes = GL_FALSE;
  1496.    }
  1497.    else {
  1498.       c->swapbytes = GL_TRUE;
  1499.    }
  1500.  
  1501.    c->xm_visual = v;
  1502.    c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
  1503.    c->display = v->display;
  1504.    c->pixelformat = v->dithered_pf;      /* Dithering is enabled by default */
  1505.  
  1506.    c->gl_ctx->Driver.UpdateState = xmesa_setup_DD_pointers;
  1507.  
  1508. #ifdef FX
  1509.    fxEnvVar = getenv("MESA_GLX_FX");
  1510.    if (fxEnvVar) {
  1511.       if (v->undithered_pf==PF_5R6G5B && tolower(fxEnvVar[0])=='w') {
  1512.          /* Window rendering */
  1513.          int attribs[] = {
  1514.             FXMESA_DEPTH_SIZE, 1,
  1515.             FXMESA_NONE
  1516.          };
  1517.          c->FXctx = fxMesaCreateBestContext(0, FX_WIDTH, FX_HEIGHT, attribs);
  1518.          c->FXhack = c->FXctx ? GL_TRUE : GL_FALSE;
  1519.       }
  1520.       else if (tolower(fxEnvVar[0])=='f') {
  1521.          /* Full-screen rendering */
  1522.          int attribs[100];
  1523.          int numAttribs = 0;
  1524.          attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
  1525.          attribs[numAttribs++] = 1;
  1526.          if (v->gl_visual->DBflag) {
  1527.             attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
  1528.          }
  1529.          if (v->gl_visual->AccumBits > 0) {
  1530.             attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
  1531.             attribs[numAttribs++] = v->gl_visual->AccumBits;
  1532.          }
  1533.          if (v->gl_visual->StencilBits > 0) {
  1534.             attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
  1535.             attribs[numAttribs++] = v->gl_visual->StencilBits;
  1536.          }
  1537.          attribs[numAttribs++] = FXMESA_NONE;
  1538.          c->FXctx = fxMesaCreateBestContext(0, FX_WIDTH, FX_HEIGHT, attribs);
  1539.          c->FXuse = c->FXctx ? GL_TRUE : GL_FALSE;
  1540.          c->FXhack = GL_FALSE;
  1541.       }
  1542.    }
  1543. #endif
  1544.  
  1545.    return c;
  1546. }
  1547.  
  1548.  
  1549.  
  1550.  
  1551. void XMesaDestroyContext( XMesaContext c )
  1552. {
  1553. #ifdef FX
  1554.    if (c->FXctx)
  1555.       fxMesaDestroyContext(c->FXctx);
  1556. #endif
  1557.    if (c->gl_ctx)
  1558.       gl_destroy_context( c->gl_ctx );
  1559.    free( c );
  1560. }
  1561.  
  1562.  
  1563.  
  1564. /*
  1565.  * Create a new XMesaBuffer from an X window.
  1566.  * Input:  v - the XMesaVisual
  1567.  *         W - the window
  1568.  * Return:  new XMesaBuffer or NULL if error
  1569.  */
  1570. XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, Window w )
  1571. {
  1572.    XWindowAttributes attr;
  1573.    XMesaBuffer b = alloc_xmesa_buffer();
  1574.    if (!b) {
  1575.       return NULL;
  1576.    }
  1577.  
  1578.    assert(v);
  1579.  
  1580.    XGetWindowAttributes( v->display, w, &attr );
  1581.  
  1582.    if (v->visinfo->depth != attr.depth) {
  1583.       if (getenv("MESA_DEBUG")) {
  1584.          fprintf(stderr, "XMesaCreateWindowBuffer: depth mismatch between visual and window!\n");
  1585.       }
  1586.       return NULL;
  1587.    }
  1588.  
  1589.    b->xm_visual = v;
  1590.    b->pixmap_flag = GL_FALSE;
  1591.    b->display = v->display;
  1592.    if (attr.colormap) {
  1593.       b->cmap = attr.colormap;
  1594.    }
  1595.    else {
  1596.       if (getenv("MESA_DEBUG")) {
  1597.          fprintf(stderr, "Window %d has no colormap!\n", w);
  1598.       }
  1599.       /* this is weird, a window w/out a colormap!? */
  1600.       /* OK, let's just allocate a new one and hope for the best */
  1601.       b->cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
  1602.    }
  1603.  
  1604.    /* determine back buffer implementation */
  1605.    if (v->gl_visual->DBflag) {
  1606.       if (v->ximage_flag) {
  1607.      b->db_state = BACK_XIMAGE;
  1608.       }
  1609.       else {
  1610.      b->db_state = BACK_PIXMAP;
  1611.       }
  1612.    }
  1613.    else {
  1614.       b->db_state = 0;
  1615.    }
  1616.  
  1617.    b->gl_buffer = gl_create_framebuffer( v->gl_visual );
  1618.    if (!b->gl_buffer) {
  1619.       free_xmesa_buffer(b);
  1620.       return NULL;
  1621.    }
  1622.  
  1623.    if (!initialize_visual_and_buffer( v, b, v->gl_visual->RGBAflag,
  1624.                                       w, b->cmap )) {
  1625.       gl_destroy_framebuffer( b->gl_buffer );
  1626.       free_xmesa_buffer(b);
  1627.       return NULL;
  1628.    }
  1629.  
  1630.    return b;
  1631. }
  1632.  
  1633.  
  1634.  
  1635. /*
  1636.  * Create a new XMesaBuffer from an X pixmap.
  1637.  * Input:  v - the XMesaVisual
  1638.  *         p - the pixmap
  1639.  *         cmap - the colormap, may be 0 if using a TrueColor or DirectColor
  1640.  *                visual for the pixmap
  1641.  * Return:  new XMesaBuffer or NULL if error
  1642.  */
  1643. XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v, Pixmap p, Colormap cmap )
  1644. {
  1645.    XMesaBuffer b = alloc_xmesa_buffer();
  1646.    if (!b) {
  1647.       return NULL;
  1648.    }
  1649.  
  1650.    assert(v);
  1651.  
  1652.    b->xm_visual = v;
  1653.    b->pixmap_flag = GL_TRUE;
  1654.    b->display = v->display;
  1655.    b->cmap = cmap;
  1656.  
  1657.    /* determine back buffer implementation */
  1658.    if (v->gl_visual->DBflag) {
  1659.       if (v->ximage_flag) {
  1660.      b->db_state = BACK_XIMAGE;
  1661.       }
  1662.       else {
  1663.      b->db_state = BACK_PIXMAP;
  1664.       }
  1665.    }
  1666.    else {
  1667.       b->db_state = 0;
  1668.    }
  1669.  
  1670.    b->gl_buffer = gl_create_framebuffer( v->gl_visual );
  1671.    if (!b->gl_buffer) {
  1672.       free_xmesa_buffer(b);
  1673.       return NULL;
  1674.    }
  1675.  
  1676.    if (!initialize_visual_and_buffer(v, b, v->gl_visual->RGBAflag, p, cmap)) {
  1677.       gl_destroy_framebuffer( b->gl_buffer );
  1678.       free_xmesa_buffer(b);
  1679.       return NULL;
  1680.    }
  1681.  
  1682.    return b;
  1683. }
  1684.  
  1685.  
  1686.  
  1687. /*
  1688.  * Deallocate an XMesaBuffer structure and all related info.
  1689.  */
  1690. void XMesaDestroyBuffer( XMesaBuffer b )
  1691. {
  1692.    if (b->gc1)  XFreeGC( b->xm_visual->display, b->gc1 );
  1693.    if (b->gc2)  XFreeGC( b->xm_visual->display, b->gc2 );
  1694.    if (b->cleargc)  XFreeGC( b->xm_visual->display, b->cleargc );
  1695.  
  1696.    if (b->backimage) {
  1697. #ifdef SHM
  1698.        if (b->shm) {
  1699.        XShmDetach( b->xm_visual->display, &b->shminfo );
  1700.        XDestroyImage( b->backimage );
  1701.        shmdt( b->shminfo.shmaddr );
  1702.        }
  1703.        else
  1704. #endif
  1705.        XDestroyImage( b->backimage );
  1706.    }
  1707.    if (b->backpixmap) {
  1708.       XFreePixmap( b->xm_visual->display, b->backpixmap );
  1709.    }
  1710.    if (b->rowimage) {
  1711.       free( b->rowimage->data );
  1712.       b->rowimage->data = NULL;
  1713.       XDestroyImage( b->rowimage );
  1714.    }
  1715.  
  1716.    gl_destroy_framebuffer( b->gl_buffer );
  1717.    free_xmesa_buffer(b);
  1718. }
  1719.  
  1720.  
  1721.  
  1722. /*
  1723.  * Bind buffer b to context c and make c the current rendering context.
  1724.  */
  1725. GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b )
  1726. {
  1727.    if ((c && !b) || (!c && b)) {
  1728.       return GL_FALSE;
  1729.    }
  1730.  
  1731.    if (c) {
  1732. #ifdef FX
  1733.       if (c->FXctx) {
  1734.          fxMesaMakeCurrent(c->FXctx);
  1735.          XMesa = c;
  1736.          return GL_TRUE;
  1737.       }
  1738. #endif
  1739.       if (c->gl_ctx == gl_get_current_context() && c->xm_buffer == b
  1740.           && c->xm_buffer->wasCurrent) {
  1741.          /* same context and buffer, do nothing */
  1742.          return GL_TRUE;
  1743.       }
  1744.  
  1745.       c->xm_buffer = b;
  1746.  
  1747.       gl_make_current( c->gl_ctx, b->gl_buffer );
  1748.       XMesa = c;
  1749.  
  1750.       if (c->gl_ctx->Viewport.Width==0) {
  1751.      /* initialize viewport to window size */
  1752.      gl_Viewport( c->gl_ctx, 0, 0, b->width, b->height );
  1753.      c->gl_ctx->Scissor.Width = b->width;
  1754.      c->gl_ctx->Scissor.Height = b->height;
  1755.       }
  1756.  
  1757.       if (c->xm_visual->gl_visual->RGBAflag) {
  1758.          /*
  1759.           * Must recompute and set these pixel values because colormap
  1760.           * can be different for different windows.
  1761.           */
  1762.          c->pixel = xmesa_color_to_pixel( c, c->red, c->green,
  1763.                                           c->blue, c->alpha );
  1764.          XSetForeground( c->display, c->xm_buffer->gc1, c->pixel );
  1765.          c->clearpixel = xmesa_color_to_pixel( c,
  1766.                                                c->clearcolor[0],
  1767.                                                c->clearcolor[1],
  1768.                                                c->clearcolor[2],
  1769.                                                c->clearcolor[3] );
  1770.          XSetForeground( c->display, c->xm_buffer->cleargc, c->clearpixel );
  1771.       }
  1772.  
  1773.       /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
  1774.       c->xm_buffer->wasCurrent = GL_TRUE;
  1775.    }
  1776.    else {
  1777.       /* Detach */
  1778.       gl_make_current( NULL, NULL );
  1779.       XMesa = NULL;
  1780.    }
  1781.    return GL_TRUE;
  1782. }
  1783.  
  1784.  
  1785.  
  1786. XMesaContext XMesaGetCurrentContext( void )
  1787. {
  1788.    return XMesa;
  1789. }
  1790.  
  1791.  
  1792.  
  1793. XMesaBuffer XMesaGetCurrentBuffer( void )
  1794. {
  1795.    if (XMesa) {
  1796.       return XMesa->xm_buffer;
  1797.    }
  1798.    else {
  1799.       return 0;
  1800.    }
  1801. }
  1802.  
  1803.  
  1804. #ifdef FX
  1805. /*
  1806.  * Read image from VooDoo frame buffer into X/Mesa's back XImage.
  1807.  */
  1808. static void FXgetImage( XMesaBuffer b )
  1809. {
  1810.    int x, y;
  1811.    Window root;
  1812.    unsigned int bw, depth, width, height;
  1813.    assert(XMesa->FXctx);
  1814.    XGetGeometry( XMesa->xm_visual->display, b->frontbuffer,
  1815.                  &root, &x, &y, &width, &height, &bw, &depth);
  1816.    if (b->width != width || b->height != height) {
  1817.       b->width = MIN2(width, FX_WIDTH);
  1818.       b->height = MIN2(height, FX_HEIGHT);
  1819.       if (b->width & 1)  b->width--;  /* prevent odd width */
  1820.       xmesa_alloc_back_buffer( b );
  1821.    }
  1822.  
  1823.    grLfbReadRegion( GR_BUFFER_FRONTBUFFER,       /* src buffer */
  1824.                     0, FX_HEIGHT - b->height,    /* position */
  1825.                     b->width, b->height,         /* size */
  1826.                     b->width * sizeof(GLushort), /* stride*/
  1827.                     b->backimage->data);         /* dest buffer */
  1828. }
  1829. #endif
  1830.  
  1831.  
  1832. /*
  1833.  * Copy the back buffer to the front buffer.  If there's no back buffer
  1834.  * this is a no-op.
  1835.  */
  1836. void XMesaSwapBuffers( XMesaBuffer b )
  1837. {
  1838. #ifdef PROFILE
  1839.    GLdouble t0 = gl_time();
  1840. #endif
  1841.  
  1842.    if (b->db_state) {
  1843. #ifdef FX
  1844.       if (XMesa->FXctx) {
  1845.          if (XMesa->FXhack) {
  1846.             FXgetImage(b);
  1847.          }
  1848.          else if(XMesa->FXuse) {
  1849.             fxMesaSwapBuffers();
  1850.             return;
  1851.          }
  1852.       }
  1853. #endif
  1854.       if (b->backimage) {
  1855.      /* Copy Ximage from host's memory to server's window */
  1856. #ifdef SHM
  1857.      if (b->shm) {
  1858.         XShmPutImage( b->xm_visual->display, b->frontbuffer,
  1859.               b->cleargc,
  1860.               b->backimage, 0, 0,
  1861.               0, 0, b->width, b->height, False );
  1862.         /* wait for finished event??? */
  1863.      }
  1864.      else
  1865. #endif
  1866.          {
  1867.             XPutImage( b->xm_visual->display, b->frontbuffer,
  1868.                        b->cleargc,
  1869.                        b->backimage, 0, 0,
  1870.                        0, 0, b->width, b->height );
  1871.          }
  1872.       }
  1873.       else {
  1874.      /* Copy pixmap to window on server */
  1875.      XCopyArea( b->xm_visual->display,
  1876.             b->backpixmap,   /* source drawable */
  1877.             b->frontbuffer,  /* dest. drawable */
  1878.             b->cleargc,
  1879.             0, 0, b->width, b->height,  /* source region */
  1880.             0, 0                 /* dest region */
  1881.            );
  1882.       }
  1883.    }
  1884.    XSync( b->xm_visual->display, False );
  1885. #ifdef PROFILE
  1886.    XMesa->gl_ctx->SwapCount++;
  1887.    XMesa->gl_ctx->SwapTime += gl_time() - t0;
  1888. #endif
  1889. }
  1890.  
  1891.  
  1892.  
  1893. /*
  1894.  * Return a pointer to the XMesa backbuffer Pixmap or XImage.  This function
  1895.  * is a way to get "under the hood" of X/Mesa so one can manipulate the
  1896.  * back buffer directly.
  1897.  * Output:  pixmap - pointer to back buffer's Pixmap, or 0
  1898.  *          ximage - pointer to back buffer's XImage, or NULL
  1899.  * Return:  GL_TRUE = context is double buffered
  1900.  *          GL_FALSE = context is single buffered
  1901.  */
  1902. GLboolean XMesaGetBackBuffer( XMesaBuffer b, Pixmap *pixmap, XImage **ximage )
  1903. {
  1904.    if (b->db_state) {
  1905.       if (pixmap)  *pixmap = b->backpixmap;
  1906.       if (ximage)  *ximage = b->backimage;
  1907.       return GL_TRUE;
  1908.    }
  1909.    else {
  1910.       *pixmap = 0;
  1911.       *ximage = NULL;
  1912.       return GL_FALSE;
  1913.    }
  1914. }
  1915.  
  1916.  
  1917. /*
  1918.  * Return the depth buffer associated with an XMesaBuffer.
  1919.  * Input:  b - the XMesa buffer handle
  1920.  * Output:  width, height - size of buffer in pixels
  1921.  *          bytesPerValue - bytes per depth value (2 or 4)
  1922.  *          buffer - pointer to depth buffer values
  1923.  * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
  1924.  */
  1925. GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
  1926.                                GLint *bytesPerValue, void **buffer )
  1927. {
  1928.    if ((!b->gl_buffer) || (!b->gl_buffer->Depth)) {
  1929.       *width = 0;
  1930.       *height = 0;
  1931.       *bytesPerValue = 0;
  1932.       *buffer = 0;
  1933.       return GL_FALSE;
  1934.    }
  1935.    else {
  1936.       *width = b->gl_buffer->Width;
  1937.       *height = b->gl_buffer->Height;
  1938.       *bytesPerValue = sizeof(GLdepth);
  1939.       *buffer = b->gl_buffer->Depth;
  1940.       return GL_TRUE;
  1941.    }
  1942. }
  1943.  
  1944.  
  1945. void XMesaFlush( XMesaContext c )
  1946. {
  1947.    if (c && c->xm_visual) {
  1948.       XSync( c->xm_visual->display, False );
  1949.    }
  1950. }
  1951.  
  1952.  
  1953.  
  1954. const char *XMesaGetString( XMesaContext c, int name )
  1955. {
  1956.    if (name==XMESA_VERSION) {
  1957.       return "2.4";
  1958.    }
  1959.    else if (name==XMESA_EXTENSIONS) {
  1960.       return "";
  1961.    }
  1962.    else {
  1963.       return NULL;
  1964.    }
  1965. }
  1966.  
  1967.  
  1968.  
  1969. XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d )
  1970. {
  1971.    XMesaBuffer b;
  1972.    for (b=XMesaBufferList; b; b=b->Next) {
  1973.       if (b->display==dpy && b->frontbuffer==d) {
  1974.          return b;
  1975.       }
  1976.    }
  1977.    return NULL;
  1978. }
  1979.  
  1980.  
  1981.  
  1982. /*
  1983.  * Look for XMesaBuffers whose X window has been destroyed.
  1984.  * Deallocate any such XMesaBuffers.
  1985.  */
  1986. void XMesaGarbageCollect( void )
  1987. {
  1988.    XMesaBuffer b, next;
  1989.    for (b=XMesaBufferList; b; b=next) {
  1990.       next = b->Next;
  1991.       if (!b->pixmap_flag) {
  1992.          XSync(b->display, False);
  1993.          if (!window_exists( b->display, b->frontbuffer )) {
  1994.             /* found a dead window, free the ancillary info */
  1995.             XMesaDestroyBuffer( b );
  1996.          }
  1997.       }
  1998.    }
  1999. }
  2000.  
  2001.  
  2002.  
  2003. unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
  2004.                                 GLfloat red, GLfloat green,
  2005.                                 GLfloat blue, GLfloat alpha )
  2006. {
  2007.    GLint r = (GLint) (red   * (GLfloat) xmesa->xm_visual->rmult);
  2008.    GLint g = (GLint) (green * (GLfloat) xmesa->xm_visual->gmult);
  2009.    GLint b = (GLint) (blue  * (GLfloat) xmesa->xm_visual->bmult);
  2010.    GLint a = (GLint) (alpha * 255.0F);
  2011.  
  2012.    switch (xmesa->pixelformat) {
  2013.       case PF_INDEX:
  2014.          return 0;
  2015.       case PF_TRUECOLOR:
  2016.          {
  2017.             unsigned long p;
  2018.             PACK_TRUECOLOR( p, r, g, b );
  2019.             return p;
  2020.          }
  2021.       case PF_8A8B8G8R:
  2022.          return PACK_8A8B8G8R( r, g, b, a );
  2023.       case PF_8R8G8B:
  2024.          return PACK_8R8G8B( r, g, b );
  2025.       case PF_5R6G5B:
  2026.          return PACK_5R6G5B( r, g, b );
  2027.       case PF_DITHER:
  2028.          {
  2029.             DITHER_SETUP;
  2030.             return DITHER( x, y, r, g, b );
  2031.          }
  2032.       case PF_1BIT:
  2033.          /* 382 = (3*255)/2 */
  2034.          return ((r+g+b) > 382U) ^ xmesa->xm_visual->bitFlip;
  2035.       case PF_HPCR:
  2036.          return DITHER_HPCR(x, y, r, g, b);
  2037.       case PF_LOOKUP:
  2038.          {
  2039.             LOOKUP_SETUP;
  2040.             return LOOKUP( r, g, b );
  2041.          }
  2042.       case PF_GRAYSCALE:
  2043.          return GRAY_RGB( r, g, b );
  2044.       case PF_TRUEDITHER:
  2045.          {
  2046.             unsigned long p;
  2047.             PACK_TRUEDITHER(p, x, y, r, g, b);
  2048.             return p;
  2049.          }
  2050.       default:
  2051.          gl_problem(NULL, "Bad pixel format in XMesaDitherColor");
  2052.          return 0;
  2053.    }
  2054.    return 0;  /*never get here*/
  2055. }
  2056.  
  2057.  
  2058.