xm_api.c revision b305028464f02947c0cce0476af0e35f4ed1fafa
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Mesa 3-D graphics library
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Version:  5.1
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * copy of this software and associated documentation files (the "Software"),
9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * to deal in the Software without restriction, including without limitation
10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * the rights to use, copy, modify, merge, publish, distribute, sublicense,
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * and/or sell copies of the Software, and to permit persons to whom the
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Software is furnished to do so, subject to the following conditions:
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * The above copyright notice and this permission notice shall be included
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * in all copies or substantial portions of the Software.
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/*
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * This file contains the implementations of all the XMesa* functions.
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * NOTES:
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *
310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * The window coordinate system origin (0,0) is in the lower-left corner
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * of the window.  X11's window coordinate origin is in the upper-left
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * corner of the window.  Therefore, most drawing functions in this
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * file have to flip Y coordinates.
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * in support for the MIT Shared Memory extension.  If enabled, when you
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * use an Ximage for the back buffer in double buffered mode, the "swap"
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * operation will be faster.  You must also link with -lXext.
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Byte swapping:  If the Mesa host and the X display use a different
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * byte order then there's some trickiness to be aware of when using
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * XImages.  The byte ordering used for the XImage is that of the X
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * display, not the Mesa host.
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * The color-to-pixel encoding for True/DirectColor must be done
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * according to the display's visual red_mask, green_mask, and blue_mask.
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * If XPutPixel is used to put a pixel into an XImage then XPutPixel will
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * do byte swapping if needed.  If one wants to directly "poke" the pixel
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * into the XImage's buffer then the pixel must be byte swapped first.  In
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * and use XPutPixel everywhere except in the implementation of
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * glClear(GL_COLOR_BUFFER_BIT).  We want this function to be fast so
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * instead of using XPutPixel we "poke" our values after byte-swapping
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * the clear pixel value if needed.
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef __CYGWIN__
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#undef WIN32
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#undef __WIN32__
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "glxheader.h"
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "GL/xmesa.h"
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "xmesaP.h"
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "context.h"
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions.h"
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "glthread.h"
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "imports.h"
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "matrix.h"
710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "mtypes.h"
720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "macros.h"
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "texformat.h"
740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "texobj.h"
750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "texstore.h"
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "swrast/swrast.h"
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "swrast_setup/swrast_setup.h"
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "array_cache/acache.h"
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "tnl/tnl.h"
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef GLX_NONE_EXT
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define GLX_NONE_EXT 0x8000
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/*
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Global X driver lock
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)_glthread_Mutex _xmesa_lock;
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)/*
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Lookup tables for HPCR pixel format:
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static short hpcr_rgbTbl[3][256] = {
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,  22,  23,  23,
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,  30,  31,  31,
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)},
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles){
116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,  22,  23,  23,
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,  30,  31,  31,
118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)},
133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles){
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 40,  40,  41,  41,  42,  42,  43,  43,  44,  44,  45,  45,  46,  46,  47,  47,
136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 48,  48,  49,  49,  50,  50,  51,  51,  52,  52,  53,  53,  54,  54,  55,  55,
137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 56,  56,  57,  57,  58,  58,  59,  59,  60,  60,  61,  61,  62,  62,  63,  63,
138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 64,  64,  65,  65,  66,  66,  67,  67,  68,  68,  69,  69,  70,  70,  71,  71,
139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 72,  72,  73,  73,  74,  74,  75,  75,  76,  76,  77,  77,  78,  78,  79,  79,
140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 80,  80,  81,  81,  82,  82,  83,  83,  84,  84,  85,  85,  86,  86,  87,  87,
141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/**********************************************************************/
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*****                     X Utility Functions                    *****/
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/**********************************************************************/
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/*
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Return the host's byte order as LSBFirst or MSBFirst ala X.
162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */
163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#ifndef XFree86Server
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static int host_byte_order( void )
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   int i = 1;
167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   char *cptr = (char *) &i;
168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   return (*cptr==1) ? LSBFirst : MSBFirst;
169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif
171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/*
174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Error handling.
175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */
176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#ifndef XFree86Server
177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)static volatile int mesaXErrorFlag = 0;
178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)static int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event )
180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles){
181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   (void) dpy;
182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   (void) event;
183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   mesaXErrorFlag = 1;
184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   return 0;
185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif
187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)/*
190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Check if the X Shared Memory extension is available.
191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Return:  0 = not available
192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *          1 = shared XImage support available
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *          2 = shared Pixmap support available also
194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */
195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#ifndef XFree86Server
196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)static int check_for_xshm( XMesaDisplay *display )
197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles){
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef USE_XSHM
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   int major, minor, ignore;
200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   Bool pixmaps;
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)	 return (pixmaps==True) ? 2 : 1;
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      else {
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)	 return 0;
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   }
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   else {
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return 0;
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   }
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#else
214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   /* Can't compile XSHM support */
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   return 0;
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/*
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Return the width and height of the given drawable.
223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static void get_drawable_size( XMesaDisplay *dpy, XMesaDrawable d,
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               unsigned int *width, unsigned int *height)
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef XFree86Server
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    (void) dpy;
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *width = d->width;
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *height = d->height;
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   Window root;
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   int x, y;
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   unsigned int bw, depth;
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   _glthread_LOCK_MUTEX(_xmesa_lock);
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   XGetGeometry( dpy, d, &root, &x, &y, width, height, &bw, &depth );
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   _glthread_UNLOCK_MUTEX(_xmesa_lock);
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/*
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Apply gamma correction to an intensity value in [0..max].  Return the
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * new intensity value.
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   if (gamma == 1.0) {
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return value;
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   }
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   else {
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      double x = (double) value / (double) max;
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return IROUND_POS((GLfloat) max * _mesa_pow(x, 1.0F/gamma));
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   }
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/*
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Return the true number of bits per pixel for XImages.
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * For example, if we request a 24-bit deep visual we may actually need/get
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * 32bpp XImages.  This function returns the appropriate bpp.
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Input:  dpy - the X display
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *         visinfo - desribes the visual to be used for XImages
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Return:  true number of bits per pixel for XImages
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef XFree86Server
2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static int bits_per_pixel( XMesaVisual xmv )
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   XMesaVisualInfo visinfo = xmv->visinfo;
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   const int depth = visinfo->nplanes;
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   int i;
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   for (i = 0; i < screenInfo.numPixmapFormats; i++) {
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (screenInfo.formats[i].depth == depth)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         return screenInfo.formats[i].bitsPerPixel;
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   }
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   return depth;  /* should never get here, but this should be safe */
2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#else
2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustatic int bits_per_pixel( XMesaVisual xmv )
2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu{
2865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu   XMesaDisplay *dpy = xmv->display;
2875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu   XMesaVisualInfo visinfo = xmv->visinfo;
2885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu   XMesaImage *img;
2895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu   int bitsPerPixel;
2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu   /* Create a temporary XImage */
2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu   img = XCreateImage( dpy, visinfo->visual, visinfo->depth,
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)		       ZPixmap, 0,           /*format, offset*/
2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu		       (char*) MALLOC(8),    /*data*/
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		       1, 1,                 /*width, height*/
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		       32,                   /*bitmap_pad*/
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		       0                     /*bytes_per_line*/
297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                     );
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   assert(img);
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   /* grab the bits/pixel value */
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   bitsPerPixel = img->bits_per_pixel;
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   /* free the XImage */
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   FREE( img->data );
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   img->data = NULL;
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   XMesaDestroyImage( img );
305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   return bitsPerPixel;
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/*
3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Determine if a given X window ID is valid (window exists).
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Do this by calling XGetWindowAttributes() for the window and
3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * checking if we catch an X error.
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Input:  dpy - the display
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *         win - the window to check for existance
317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Return:  GL_TRUE - window exists
318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) *          GL_FALSE - window doesn't exist
319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) */
320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#ifndef XFree86Server
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static GLboolean WindowExistsFlag;
322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr )
324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles){
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   (void) dpy;
326424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)   if (xerr->error_code == BadWindow) {
327424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      WindowExistsFlag = GL_FALSE;
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   }
329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)   return 0;
330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static GLboolean window_exists( XMesaDisplay *dpy, Window win )
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles){
334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   XWindowAttributes wa;
3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   int (*old_handler)( XMesaDisplay*, XErrorEvent* );
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   WindowExistsFlag = GL_TRUE;
337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)   old_handler = XSetErrorHandler(window_exists_err_handler);
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   XGetWindowAttributes( dpy, win, &wa ); /* dummy request */
339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)   XSetErrorHandler(old_handler);
340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)   return WindowExistsFlag;
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif
343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**********************************************************************/
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*****                Linked list of XMesaBuffers                 *****/
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/**********************************************************************/
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static XMesaBuffer XMesaBufferList = NULL;
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/* Allocate a new XMesaBuffer, add to linked list */
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static XMesaBuffer alloc_xmesa_buffer(void)
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   if (b) {
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      b->Next = XMesaBufferList;
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      XMesaBufferList = b;
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   }
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   return b;
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/*
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Find an XMesaBuffer by matching X display and colormap but NOT matching
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * the notThis buffer.
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     XMesaColormap cmap,
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     XMesaBuffer notThis)
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   XMesaBuffer b;
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   for (b=XMesaBufferList; b; b=b->Next) {
3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (b->display==dpy && b->cmap==cmap && b!=notThis) {
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         return b;
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
3790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)   return NULL;
3800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)/*
3840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * Free an XMesaBuffer, remove from linked list, perhaps free X colormap
3850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) * entries.
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void free_xmesa_buffer(int client, XMesaBuffer buffer)
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci{
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   XMesaBuffer prev = NULL, b;
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   (void) client;
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   for (b=XMesaBufferList; b; b=b->Next) {
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (b==buffer) {
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         /* unlink bufer from list */
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         if (prev)
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            prev->Next = buffer->Next;
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         else
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            XMesaBufferList = buffer->Next;
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         /* Check to free X colors */
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         if (buffer->num_alloced>0) {
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            /* If no other buffer uses this X colormap then free the colors. */
401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) {
402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifdef XFree86Server
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               (void)FreeColors(buffer->cmap, client,
404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch				buffer->num_alloced, buffer->alloced_colors,
405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch				0);
406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#else
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               XFreeColors(buffer->display, buffer->cmap,
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           buffer->alloced_colors, buffer->num_alloced, 0);
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            }
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         }
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         _mesa_free_framebuffer_data(&buffer->mesa_buffer);
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         FREE(buffer);
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         return;
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      /* continue search */
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      prev = b;
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   }
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   /* buffer not found in XMesaBufferList */
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n");
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/* Copy X color table stuff from one XMesaBuffer to another. */
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles){
42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));
430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g));
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b));
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   dst->num_alloced = src->num_alloced;
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   MEMCPY(dst->alloced_colors, src->alloced_colors,
43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          sizeof(src->alloced_colors));
436f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/**********************************************************************/
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/*****                   Misc Private Functions                   *****/
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/**********************************************************************/
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/*
44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Return number of bits set in n.
44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) */
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static int bitcount( unsigned long n )
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   int bits;
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   for (bits=0; n>0; n=n>>1) {
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (n&1) {
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         bits++;
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   }
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   return bits;
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/*
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Return:  GL_TRUE if success, GL_FALSE if error
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef XFree86Server
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static GLboolean alloc_shm_back_buffer( XMesaBuffer b )
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef USE_XSHM
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   /*
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    * We have to do a _lot_ of error checking here to be sure we can
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    * really use the XSHM extension.  It seems different servers trigger
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    * errors at different points if the extension won't work.  Therefore
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    * we have to be very careful...
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    */
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   GC gc;
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   int (*old_handler)( XMesaDisplay *, XErrorEvent * );
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   b->backimage = XShmCreateImage( b->xm_visual->display,
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   b->xm_visual->visinfo->visual,
4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                   b->xm_visual->visinfo->depth,
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)				   ZPixmap, NULL, &b->shminfo,
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)				   b->width, b->height );
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   if (b->backimage == NULL) {
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.");
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      b->shm = 0;
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return GL_FALSE;
48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)   }
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   b->shminfo.shmid = shmget( IPC_PRIVATE, b->backimage->bytes_per_line
490d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)			     * b->backimage->height, IPC_CREAT|0777 );
491d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   if (b->shminfo.shmid < 0) {
492d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      _mesa_warning(NULL, "shmget failed while allocating back buffer");
493d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      XDestroyImage( b->backimage );
494d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      b->backimage = NULL;
495d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.");
496d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      b->shm = 0;
4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return GL_FALSE;
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   b->shminfo.shmaddr = b->backimage->data
5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      = (char*)shmat( b->shminfo.shmid, 0, 0 );
5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   if (b->shminfo.shmaddr == (char *) -1) {
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      _mesa_warning(NULL, "shmat() failed while allocating back buffer");
5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      XDestroyImage( b->backimage );
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
506d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      b->backimage = NULL;
50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.");
50868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      b->shm = 0;
5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return GL_FALSE;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   }
51190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   b->shminfo.readOnly = False;
513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   mesaXErrorFlag = 0;
5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   old_handler = XSetErrorHandler( mesaHandleXError );
5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   /* This may trigger the X protocol error we're ready to catch: */
51690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   XShmAttach( b->xm_visual->display, &b->shminfo );
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   XSync( b->xm_visual->display, False );
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   if (mesaXErrorFlag) {
52090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      /* we are on a remote display, this error is normal, don't print it */
521ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      XFlush( b->xm_visual->display );
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mesaXErrorFlag = 0;
523d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      XDestroyImage( b->backimage );
5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      shmdt( b->shminfo.shmaddr );
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      b->backimage = NULL;
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      b->shm = 0;
5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      (void) XSetErrorHandler( old_handler );
5291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return GL_FALSE;
530d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   }
53168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
53268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)   shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
534d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   /* Finally, try an XShmPutImage to be really sure the extension works */
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   gc = XCreateGC( b->xm_visual->display, b->frontbuffer, 0, NULL );
536d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   XShmPutImage( b->xm_visual->display, b->frontbuffer, gc,
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		 b->backimage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False );
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   XSync( b->xm_visual->display, False );
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   XFreeGC( b->xm_visual->display, gc );
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   (void) XSetErrorHandler( old_handler );
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   if (mesaXErrorFlag) {
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      XFlush( b->xm_visual->display );
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      mesaXErrorFlag = 0;
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      XDestroyImage( b->backimage );
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shmdt( b->shminfo.shmaddr );
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      b->backimage = NULL;
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      b->shm = 0;
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GL_FALSE;
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   }
551
552   if (b->backimage) {
553      int height = b->backimage->height;
554      /* Needed by PIXELADDR1 macro */
555      b->ximage_width1 = b->backimage->bytes_per_line;
556      b->ximage_origin1 = (GLubyte *) b->backimage->data
557                        + b->ximage_width1 * (height-1);
558      /* Needed by PIXELADDR2 macro */
559      b->ximage_width2 = b->backimage->bytes_per_line / 2;
560      b->ximage_origin2 = (GLushort *) b->backimage->data
561                        + b->ximage_width2 * (height-1);
562      /* Needed by PIXELADDR3 macro */
563      b->ximage_width3 = b->backimage->bytes_per_line;
564      b->ximage_origin3 = (GLubyte *) b->backimage->data
565                        + b->ximage_width3 * (height-1);
566      /* Needed by PIXELADDR4 macro */
567      b->ximage_width4 = b->backimage->width;
568      b->ximage_origin4 = (GLuint *) b->backimage->data
569                        + b->ximage_width4 * (height-1);
570   }
571
572   return GL_TRUE;
573#else
574   /* Can't compile XSHM support */
575   return GL_FALSE;
576#endif
577}
578#endif
579
580
581
582/*
583 * Setup an off-screen pixmap or Ximage to use as the back buffer.
584 * Input:  b - the X/Mesa buffer
585 */
586void xmesa_alloc_back_buffer( XMesaBuffer b )
587{
588   if (b->db_state==BACK_XIMAGE) {
589      /* Deallocate the old backimage, if any */
590      if (b->backimage) {
591#if defined(USE_XSHM) && !defined(XFree86Server)
592	 if (b->shm) {
593	    XShmDetach( b->xm_visual->display, &b->shminfo );
594	    XDestroyImage( b->backimage );
595	    shmdt( b->shminfo.shmaddr );
596	 }
597	 else
598#endif
599	   XMesaDestroyImage( b->backimage );
600	 b->backimage = NULL;
601      }
602
603      /* Allocate new back buffer */
604#ifdef XFree86Server
605      {
606	 /* Allocate a regular XImage for the back buffer. */
607	 b->backimage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
608					 b->width, b->height, NULL);
609#else
610      if (b->shm==0 || alloc_shm_back_buffer(b)==GL_FALSE) {
611	 /* Allocate a regular XImage for the back buffer. */
612	 b->backimage = XCreateImage( b->xm_visual->display,
613                                      b->xm_visual->visinfo->visual,
614                                      GET_VISUAL_DEPTH(b->xm_visual),
615				      ZPixmap, 0,   /* format, offset */
616				      NULL, b->width, b->height,
617				      8, 0 );  /* pad, bytes_per_line */
618#endif
619	 if (!b->backimage) {
620	    _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.");
621	 }
622         b->backimage->data = (char *) MALLOC( b->backimage->height
623                                             * b->backimage->bytes_per_line );
624         if (!b->backimage->data) {
625            _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.");
626            XMesaDestroyImage( b->backimage );
627            b->backimage = NULL;
628         }
629      }
630      b->backpixmap = None;
631   }
632   else if (b->db_state==BACK_PIXMAP) {
633      XMesaPixmap old_pixmap = b->backpixmap;
634      /* Free the old back pixmap */
635      if (b->backpixmap) {
636	 XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
637      }
638      /* Allocate new back pixmap */
639      b->backpixmap = XMesaCreatePixmap( b->xm_visual->display, b->frontbuffer,
640					 b->width, b->height,
641					 GET_VISUAL_DEPTH(b->xm_visual) );
642      b->backimage = NULL;
643      /* update other references to backpixmap */
644      if (b->buffer==(XMesaDrawable)old_pixmap) {
645	 b->buffer = (XMesaDrawable)b->backpixmap;
646      }
647   }
648}
649
650
651
652/*
653 * A replacement for XAllocColor.  This function should never
654 * fail to allocate a color.  When XAllocColor fails, we return
655 * the nearest matching color.  If we have to allocate many colors
656 * this function isn't too efficient; the XQueryColors() could be
657 * done just once.
658 * Written by Michael Pichler, Brian Paul, Mark Kilgard
659 * Input:  dpy - X display
660 *         cmap - X colormap
661 *         cmapSize - size of colormap
662 * In/Out: color - the XColor struct
663 * Output:  exact - 1=exact color match, 0=closest match
664 *          alloced - 1=XAlloc worked, 0=XAlloc failed
665 */
666static void
667noFaultXAllocColor( int client,
668                    XMesaDisplay *dpy,
669                    XMesaColormap cmap,
670                    int cmapSize,
671                    XMesaColor *color,
672                    int *exact, int *alloced )
673{
674#ifdef XFree86Server
675   Pixel *ppixIn;
676   xrgb *ctable;
677#else
678   /* we'll try to cache ctable for better remote display performance */
679   static Display *prevDisplay = NULL;
680   static XMesaColormap prevCmap = 0;
681   static int prevCmapSize = 0;
682   static XMesaColor *ctable = NULL;
683#endif
684   XMesaColor subColor;
685   int i, bestmatch;
686   double mindist;       /* 3*2^16^2 exceeds long int precision. */
687
688   (void) client;
689
690   /* First try just using XAllocColor. */
691#ifdef XFree86Server
692   if (AllocColor(cmap,
693		  &color->red, &color->green, &color->blue,
694		  &color->pixel,
695		  client) == Success) {
696#else
697   if (XAllocColor(dpy, cmap, color)) {
698#endif
699      *exact = 1;
700      *alloced = 1;
701      return;
702   }
703
704   /* Alloc failed, search for closest match */
705
706   /* Retrieve color table entries. */
707   /* XXX alloca candidate. */
708#ifdef XFree86Server
709   ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel));
710   ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb));
711   for (i = 0; i < cmapSize; i++) {
712      ppixIn[i] = i;
713   }
714   QueryColors(cmap, cmapSize, ppixIn, ctable);
715#else
716   if (prevDisplay != dpy || prevCmap != cmap
717       || prevCmapSize != cmapSize || !ctable) {
718      /* free previously cached color table */
719      if (ctable)
720         FREE(ctable);
721      /* Get the color table from X */
722      ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor));
723      assert(ctable);
724      for (i = 0; i < cmapSize; i++) {
725         ctable[i].pixel = i;
726      }
727      XQueryColors(dpy, cmap, ctable, cmapSize);
728      prevDisplay = dpy;
729      prevCmap = cmap;
730      prevCmapSize = cmapSize;
731   }
732#endif
733
734   /* Find best match. */
735   bestmatch = -1;
736   mindist = 0.0;
737   for (i = 0; i < cmapSize; i++) {
738      double dr = 0.30 * ((double) color->red - (double) ctable[i].red);
739      double dg = 0.59 * ((double) color->green - (double) ctable[i].green);
740      double db = 0.11 * ((double) color->blue - (double) ctable[i].blue);
741      double dist = dr * dr + dg * dg + db * db;
742      if (bestmatch < 0 || dist < mindist) {
743         bestmatch = i;
744         mindist = dist;
745      }
746   }
747
748   /* Return result. */
749   subColor.red   = ctable[bestmatch].red;
750   subColor.green = ctable[bestmatch].green;
751   subColor.blue  = ctable[bestmatch].blue;
752   /* Try to allocate the closest match color.  This should only
753    * fail if the cell is read/write.  Otherwise, we're incrementing
754    * the cell's reference count.
755    */
756#ifdef XFree86Server
757   if (AllocColor(cmap,
758		  &subColor.red, &subColor.green, &subColor.blue,
759		  &subColor.pixel,
760		  client) == Success) {
761#else
762   if (XAllocColor(dpy, cmap, &subColor)) {
763#endif
764      *alloced = 1;
765   }
766   else {
767      /* do this to work around a problem reported by Frank Ortega */
768      subColor.pixel = (unsigned long) bestmatch;
769      subColor.red   = ctable[bestmatch].red;
770      subColor.green = ctable[bestmatch].green;
771      subColor.blue  = ctable[bestmatch].blue;
772      subColor.flags = DoRed | DoGreen | DoBlue;
773      *alloced = 0;
774   }
775#ifdef XFree86Server
776   FREE(ppixIn);
777   FREE(ctable);
778#else
779   /* don't free table, save it for next time */
780#endif
781
782   *color = subColor;
783   *exact = 0;
784}
785
786
787
788
789/*
790 * Do setup for PF_GRAYSCALE pixel format.
791 * Note that buffer may be NULL.
792 */
793static GLboolean setup_grayscale( int client, XMesaVisual v,
794                                  XMesaBuffer buffer, XMesaColormap cmap )
795{
796   if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
797      return GL_FALSE;
798   }
799
800   if (buffer) {
801      XMesaBuffer prevBuffer;
802
803      if (!cmap) {
804         return GL_FALSE;
805      }
806
807      prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
808      if (prevBuffer &&
809          (buffer->xm_visual->mesa_visual.rgbMode ==
810           prevBuffer->xm_visual->mesa_visual.rgbMode)) {
811         /* Copy colormap stuff from previous XMesaBuffer which uses same
812          * X colormap.  Do this to avoid time spent in noFaultXAllocColor.
813          */
814         copy_colortable_info(buffer, prevBuffer);
815      }
816      else {
817         /* Allocate 256 shades of gray */
818         int gray;
819         int colorsfailed = 0;
820         for (gray=0;gray<256;gray++) {
821            GLint r = gamma_adjust( v->RedGamma,   gray, 255 );
822            GLint g = gamma_adjust( v->GreenGamma, gray, 255 );
823            GLint b = gamma_adjust( v->BlueGamma,  gray, 255 );
824            int exact, alloced;
825            XMesaColor xcol;
826            xcol.red   = (r << 8) | r;
827            xcol.green = (g << 8) | g;
828            xcol.blue  = (b << 8) | b;
829            noFaultXAllocColor( client, v->display,
830                                cmap, GET_COLORMAP_SIZE(v),
831                                &xcol, &exact, &alloced );
832            if (!exact) {
833               colorsfailed++;
834            }
835            if (alloced) {
836               assert(buffer->num_alloced<256);
837               buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
838               buffer->num_alloced++;
839            }
840
841            /*OLD
842            assert(gray < 576);
843            buffer->color_table[gray*3+0] = xcol.pixel;
844            buffer->color_table[gray*3+1] = xcol.pixel;
845            buffer->color_table[gray*3+2] = xcol.pixel;
846            assert(xcol.pixel < 65536);
847            buffer->pixel_to_r[xcol.pixel] = gray * 30 / 100;
848            buffer->pixel_to_g[xcol.pixel] = gray * 59 / 100;
849            buffer->pixel_to_b[xcol.pixel] = gray * 11 / 100;
850            */
851            buffer->color_table[gray] = xcol.pixel;
852            assert(xcol.pixel < 65536);
853            buffer->pixel_to_r[xcol.pixel] = gray;
854            buffer->pixel_to_g[xcol.pixel] = gray;
855            buffer->pixel_to_b[xcol.pixel] = gray;
856         }
857
858         if (colorsfailed && _mesa_getenv("MESA_DEBUG")) {
859            _mesa_warning(NULL,
860                  "Note: %d out of 256 needed colors do not match exactly.\n",
861                  colorsfailed );
862         }
863      }
864   }
865
866   v->dithered_pf = PF_Grayscale;
867   v->undithered_pf = PF_Grayscale;
868   return GL_TRUE;
869}
870
871
872
873/*
874 * Setup RGB rendering for a window with a PseudoColor, StaticColor,
875 * or 8-bit TrueColor visual visual.  We try to allocate a palette of 225
876 * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB
877 * color.  While this function was originally designed just for 8-bit
878 * visuals, it has also proven to work from 4-bit up to 16-bit visuals.
879 * Dithering code contributed by Bob Mercier.
880 */
881static GLboolean setup_dithered_color( int client, XMesaVisual v,
882                                       XMesaBuffer buffer, XMesaColormap cmap )
883{
884   (void) DitherValues;  /* silence warning */
885
886   if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
887      return GL_FALSE;
888   }
889
890   if (buffer) {
891      XMesaBuffer prevBuffer;
892
893      if (!cmap) {
894         return GL_FALSE;
895      }
896
897      prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
898      if (prevBuffer &&
899          (buffer->xm_visual->mesa_visual.rgbMode ==
900           prevBuffer->xm_visual->mesa_visual.rgbMode)) {
901         /* Copy colormap stuff from previous, matching XMesaBuffer.
902          * Do this to avoid time spent in noFaultXAllocColor.
903          */
904         copy_colortable_info(buffer, prevBuffer);
905      }
906      else {
907         /* Allocate X colors and initialize color_table[], red_table[], etc */
908         int r, g, b, i;
909         int colorsfailed = 0;
910         for (r = 0; r < DITH_R; r++) {
911            for (g = 0; g < DITH_G; g++) {
912               for (b = 0; b < DITH_B; b++) {
913                  XMesaColor xcol;
914                  int exact, alloced;
915                  xcol.red  =gamma_adjust(v->RedGamma,   r*65535/(DITH_R-1),65535);
916                  xcol.green=gamma_adjust(v->GreenGamma, g*65535/(DITH_G-1),65535);
917                  xcol.blue =gamma_adjust(v->BlueGamma,  b*65535/(DITH_B-1),65535);
918                  noFaultXAllocColor( client, v->display,
919                                      cmap, GET_COLORMAP_SIZE(v),
920                                      &xcol, &exact, &alloced );
921                  if (!exact) {
922                     colorsfailed++;
923                  }
924                  if (alloced) {
925                     assert(buffer->num_alloced<256);
926                     buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
927                     buffer->num_alloced++;
928                  }
929                  i = DITH_MIX( r, g, b );
930                  assert(i < 576);
931                  buffer->color_table[i] = xcol.pixel;
932                  assert(xcol.pixel < 65536);
933                  buffer->pixel_to_r[xcol.pixel] = r * 255 / (DITH_R-1);
934                  buffer->pixel_to_g[xcol.pixel] = g * 255 / (DITH_G-1);
935                  buffer->pixel_to_b[xcol.pixel] = b * 255 / (DITH_B-1);
936               }
937            }
938         }
939
940         if (colorsfailed && _mesa_getenv("MESA_DEBUG")) {
941            _mesa_warning(NULL,
942                  "Note: %d out of %d needed colors do not match exactly.\n",
943                  colorsfailed, DITH_R * DITH_G * DITH_B );
944         }
945      }
946   }
947
948   v->dithered_pf = PF_Dither;
949   v->undithered_pf = PF_Lookup;
950   return GL_TRUE;
951}
952
953
954/*
955 * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
956 * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
957 * Special dithering tables have to be initialized.
958 */
959static void setup_8bit_hpcr( XMesaVisual v )
960{
961   /* HP Color Recovery contributed by:  Alex De Bruyn (ad@lms.be)
962    * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
963    * on the root window AND the colormap obtainable by XGetRGBColormaps
964    * for that atom must be set on the window.  (see also tkInitWindow)
965    * If that colormap is not set, the output will look stripy.
966    */
967
968   /* Setup color tables with gamma correction */
969   int i;
970   double g;
971
972   g = 1.0 / v->RedGamma;
973   for (i=0; i<256; i++) {
974      GLint red = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[0][i]/255.0, g ));
975      v->hpcr_rgbTbl[0][i] = CLAMP( red, 16, 239 );
976   }
977
978   g = 1.0 / v->GreenGamma;
979   for (i=0; i<256; i++) {
980      GLint green = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[1][i]/255.0, g ));
981      v->hpcr_rgbTbl[1][i] = CLAMP( green, 16, 239 );
982   }
983
984   g = 1.0 / v->BlueGamma;
985   for (i=0; i<256; i++) {
986      GLint blue = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[2][i]/255.0, g ));
987      v->hpcr_rgbTbl[2][i] = CLAMP( blue, 32, 223 );
988   }
989   v->undithered_pf = PF_HPCR;  /* can't really disable dithering for now */
990   v->dithered_pf = PF_HPCR;
991
992   /* which method should I use to clear */
993   /* GL_FALSE: keep the ordinary method  */
994   /* GL_TRUE : clear with dither pattern */
995   v->hpcr_clear_flag = _mesa_getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE;
996
997   if (v->hpcr_clear_flag) {
998      v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display,
999                                               DefaultRootWindow(v->display),
1000                                               16, 2, 8);
1001#ifndef XFree86Server
1002      v->hpcr_clear_ximage = XGetImage(v->display, v->hpcr_clear_pixmap,
1003                                       0, 0, 16, 2, AllPlanes, ZPixmap);
1004#endif
1005   }
1006}
1007
1008
1009/*
1010 * Setup RGB rendering for a window with a True/DirectColor visual.
1011 */
1012static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
1013                             XMesaColormap cmap )
1014{
1015   unsigned long rmask, gmask, bmask;
1016   (void) buffer;
1017   (void) cmap;
1018
1019   /* Compute red multiplier (mask) and bit shift */
1020   v->rshift = 0;
1021   rmask = GET_REDMASK(v);
1022   while ((rmask & 1)==0) {
1023      v->rshift++;
1024      rmask = rmask >> 1;
1025   }
1026
1027   /* Compute green multiplier (mask) and bit shift */
1028   v->gshift = 0;
1029   gmask = GET_GREENMASK(v);
1030   while ((gmask & 1)==0) {
1031      v->gshift++;
1032      gmask = gmask >> 1;
1033   }
1034
1035   /* Compute blue multiplier (mask) and bit shift */
1036   v->bshift = 0;
1037   bmask = GET_BLUEMASK(v);
1038   while ((bmask & 1)==0) {
1039      v->bshift++;
1040      bmask = bmask >> 1;
1041   }
1042
1043   /*
1044    * Compute component-to-pixel lookup tables and dithering kernel
1045    */
1046   {
1047      static GLubyte kernel[16] = {
1048          0*16,  8*16,  2*16, 10*16,
1049         12*16,  4*16, 14*16,  6*16,
1050          3*16, 11*16,  1*16,  9*16,
1051         15*16,  7*16, 13*16,  5*16,
1052      };
1053      GLint rBits = bitcount(rmask);
1054      GLint gBits = bitcount(gmask);
1055      GLint bBits = bitcount(bmask);
1056      GLint maxBits;
1057      GLuint i;
1058
1059      /* convert pixel components in [0,_mask] to RGB values in [0,255] */
1060      for (i=0; i<=rmask; i++)
1061         v->PixelToR[i] = (unsigned char) ((i * 255) / rmask);
1062      for (i=0; i<=gmask; i++)
1063         v->PixelToG[i] = (unsigned char) ((i * 255) / gmask);
1064      for (i=0; i<=bmask; i++)
1065         v->PixelToB[i] = (unsigned char) ((i * 255) / bmask);
1066
1067      /* convert RGB values from [0,255] to pixel components */
1068
1069      for (i=0;i<256;i++) {
1070         GLint r = gamma_adjust(v->RedGamma,   i, 255);
1071         GLint g = gamma_adjust(v->GreenGamma, i, 255);
1072         GLint b = gamma_adjust(v->BlueGamma,  i, 255);
1073         v->RtoPixel[i] = (r >> (8-rBits)) << v->rshift;
1074         v->GtoPixel[i] = (g >> (8-gBits)) << v->gshift;
1075         v->BtoPixel[i] = (b >> (8-bBits)) << v->bshift;
1076      }
1077      /* overflow protection */
1078      for (i=256;i<512;i++) {
1079         v->RtoPixel[i] = v->RtoPixel[255];
1080         v->GtoPixel[i] = v->GtoPixel[255];
1081         v->BtoPixel[i] = v->BtoPixel[255];
1082      }
1083
1084      /* setup dithering kernel */
1085      maxBits = rBits;
1086      if (gBits > maxBits)  maxBits = gBits;
1087      if (bBits > maxBits)  maxBits = bBits;
1088      for (i=0;i<16;i++) {
1089         v->Kernel[i] = kernel[i] >> maxBits;
1090      }
1091
1092      v->undithered_pf = PF_Truecolor;
1093      v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_Dither_True : PF_Truecolor;
1094   }
1095
1096   /*
1097    * Now check for TrueColor visuals which we can optimize.
1098    */
1099   if (   GET_REDMASK(v)  ==0x0000ff
1100       && GET_GREENMASK(v)==0x00ff00
1101       && GET_BLUEMASK(v) ==0xff0000
1102       && CHECK_BYTE_ORDER(v)
1103       && v->BitsPerPixel==32
1104       && sizeof(GLuint)==4
1105       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1106      /* common 32 bpp config used on SGI, Sun */
1107      v->undithered_pf = v->dithered_pf = PF_8A8B8G8R;
1108   }
1109   else if (GET_REDMASK(v)  ==0xff0000
1110       &&   GET_GREENMASK(v)==0x00ff00
1111       &&   GET_BLUEMASK(v) ==0x0000ff
1112       && CHECK_BYTE_ORDER(v)
1113       && v->BitsPerPixel==32
1114       && sizeof(GLuint)==4
1115       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1116      /* common 32 bpp config used on Linux, HP, IBM */
1117      v->undithered_pf = v->dithered_pf = PF_8R8G8B;
1118   }
1119   else if (GET_REDMASK(v)  ==0xff0000
1120       &&   GET_GREENMASK(v)==0x00ff00
1121       &&   GET_BLUEMASK(v) ==0x0000ff
1122       && CHECK_BYTE_ORDER(v)
1123       && v->BitsPerPixel==24
1124       && sizeof(GLuint)==4
1125       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1126      /* common packed 24 bpp config used on Linux */
1127      v->undithered_pf = v->dithered_pf = PF_8R8G8B24;
1128   }
1129   else if (GET_REDMASK(v)  ==0xf800
1130       &&   GET_GREENMASK(v)==0x07e0
1131       &&   GET_BLUEMASK(v) ==0x001f
1132       && CHECK_BYTE_ORDER(v)
1133       && v->BitsPerPixel==16
1134       && sizeof(GLushort)==2
1135       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1136      /* 5-6-5 color weight on common PC VGA boards */
1137      v->undithered_pf = PF_5R6G5B;
1138      v->dithered_pf = PF_Dither_5R6G5B;
1139   }
1140   else if (GET_REDMASK(v)  ==0xe0
1141       &&   GET_GREENMASK(v)==0x1c
1142       &&   GET_BLUEMASK(v) ==0x03
1143       && CHECK_FOR_HPCR(v)) {
1144      setup_8bit_hpcr( v );
1145   }
1146}
1147
1148
1149
1150/*
1151 * Setup RGB rendering for a window with a monochrome visual.
1152 */
1153static void setup_monochrome( XMesaVisual v, XMesaBuffer b )
1154{
1155   (void) b;
1156   v->dithered_pf = v->undithered_pf = PF_1Bit;
1157   /* if black=1 then we must flip pixel values */
1158   v->bitFlip = (GET_BLACK_PIXEL(v) != 0);
1159}
1160
1161
1162
1163/*
1164 * When a context is "made current" for the first time, we can finally
1165 * finish initializing the context's visual and buffer information.
1166 * Input:  v - the XMesaVisual to initialize
1167 *         b - the XMesaBuffer to initialize (may be NULL)
1168 *         rgb_flag - TRUE = RGBA mode, FALSE = color index mode
1169 *         window - the window/pixmap we're rendering into
1170 *         cmap - the colormap associated with the window/pixmap
1171 * Return:  GL_TRUE=success, GL_FALSE=failure
1172 */
1173static GLboolean initialize_visual_and_buffer( int client,
1174                                               XMesaVisual v,
1175                                               XMesaBuffer b,
1176                                               GLboolean rgb_flag,
1177                                               XMesaDrawable window,
1178                                               XMesaColormap cmap )
1179{
1180#ifndef XFree86Server
1181   XGCValues gcvalues;
1182#endif
1183
1184   if (b) {
1185      assert(b->xm_visual == v);
1186   }
1187
1188   /* Save true bits/pixel */
1189   v->BitsPerPixel = bits_per_pixel(v);
1190   assert(v->BitsPerPixel > 0);
1191
1192
1193   if (rgb_flag==GL_FALSE) {
1194      /* COLOR-INDEXED WINDOW:
1195       * Even if the visual is TrueColor or DirectColor we treat it as
1196       * being color indexed.  This is weird but might be useful to someone.
1197       */
1198      v->dithered_pf = v->undithered_pf = PF_Index;
1199      v->index_bits = GET_VISUAL_DEPTH(v);
1200   }
1201   else {
1202      /* RGB WINDOW:
1203       * We support RGB rendering into almost any kind of visual.
1204       */
1205      int xclass;
1206      xclass = GET_VISUAL_CLASS(v);
1207      if (xclass==TrueColor || xclass==DirectColor) {
1208	 setup_truecolor( v, b, cmap );
1209      }
1210      else if (xclass==StaticGray && GET_VISUAL_DEPTH(v)==1) {
1211	 setup_monochrome( v, b );
1212      }
1213      else if (xclass==GrayScale || xclass==StaticGray) {
1214         if (!setup_grayscale( client, v, b, cmap )) {
1215            return GL_FALSE;
1216         }
1217      }
1218      else if ((xclass==PseudoColor || xclass==StaticColor)
1219               && GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) {
1220	 if (!setup_dithered_color( client, v, b, cmap )) {
1221            return GL_FALSE;
1222         }
1223      }
1224      else {
1225	 _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual.");
1226	 return GL_FALSE;
1227      }
1228      v->index_bits = 0;
1229
1230      if (_mesa_getenv("MESA_NO_DITHER")) {
1231	 v->dithered_pf = v->undithered_pf;
1232      }
1233   }
1234
1235
1236   /*
1237    * If MESA_INFO env var is set print out some debugging info
1238    * which can help Brian figure out what's going on when a user
1239    * reports bugs.
1240    */
1241   if (_mesa_getenv("MESA_INFO")) {
1242      _mesa_printf("X/Mesa visual = %p\n", (void *) v);
1243      _mesa_printf("X/Mesa dithered pf = %u\n", v->dithered_pf);
1244      _mesa_printf("X/Mesa undithered pf = %u\n", v->undithered_pf);
1245      _mesa_printf("X/Mesa level = %d\n", v->level);
1246      _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v));
1247      _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
1248   }
1249
1250   if (b && window) {
1251      /* Do window-specific initializations */
1252
1253      /* Window dimensions */
1254      unsigned int w, h;
1255      get_drawable_size( v->display, window, &w, &h );
1256      b->width = w;
1257      b->height = h;
1258
1259      b->frontbuffer = window;
1260
1261      /* Setup for single/double buffering */
1262      if (v->mesa_visual.doubleBufferMode) {
1263         /* Double buffered */
1264#ifndef XFree86Server
1265         b->shm = check_for_xshm( v->display );
1266#endif
1267         xmesa_alloc_back_buffer( b );
1268         if (b->db_state==BACK_PIXMAP) {
1269            b->buffer = (XMesaDrawable)b->backpixmap;
1270         }
1271         else {
1272            b->buffer = XIMAGE;
1273         }
1274      }
1275      else {
1276         /* Single Buffered */
1277         b->buffer = b->frontbuffer;
1278      }
1279
1280      /* X11 graphics contexts */
1281#ifdef XFree86Server
1282      b->gc = CreateScratchGC(v->display, window->depth);
1283#else
1284      b->gc = XCreateGC( v->display, window, 0, NULL );
1285#endif
1286      XMesaSetFunction( v->display, b->gc, GXcopy );
1287
1288      /* cleargc - for glClear() */
1289#ifdef XFree86Server
1290      b->cleargc = CreateScratchGC(v->display, window->depth);
1291#else
1292      b->cleargc = XCreateGC( v->display, window, 0, NULL );
1293#endif
1294      XMesaSetFunction( v->display, b->cleargc, GXcopy );
1295
1296      /*
1297       * Don't generate Graphics Expose/NoExpose events in swapbuffers().
1298       * Patch contributed by Michael Pichler May 15, 1995.
1299       */
1300#ifdef XFree86Server
1301      b->swapgc = CreateScratchGC(v->display, window->depth);
1302      {
1303	  CARD32 v[1];
1304	  v[0] = FALSE;
1305	  dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL);
1306      }
1307#else
1308      gcvalues.graphics_exposures = False;
1309      b->swapgc = XCreateGC( v->display, window,
1310                              GCGraphicsExposures, &gcvalues);
1311#endif
1312      XMesaSetFunction( v->display, b->swapgc, GXcopy );
1313      /*
1314       * Set fill style and tile pixmap once for all for HPCR stuff
1315       * (instead of doing it each time in clear_color_HPCR_pixmap())
1316       * Initialize whole stuff
1317       * Patch contributed by Jacques Leroy March 8, 1998.
1318       */
1319      if (v->hpcr_clear_flag && b->buffer!=XIMAGE) {
1320	int i;
1321	for (i=0; i<16; i++)
1322        {
1323	   XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0);
1324	   XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0);
1325        }
1326        XMesaPutImage(b->display, (XMesaDrawable)v->hpcr_clear_pixmap,
1327		      b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2);
1328	XMesaSetFillStyle( v->display, b->cleargc, FillTiled);
1329	XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap );
1330      }
1331
1332      /* Initialize the row buffer XImage for use in write_color_span() */
1333#ifdef XFree86Server
1334      b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1,
1335				     (char *)MALLOC(MAX_WIDTH*4));
1336#else
1337      b->rowimage = XCreateImage( v->display,
1338                                  v->visinfo->visual,
1339                                  v->visinfo->depth,
1340                                  ZPixmap, 0,           /*format, offset*/
1341                                  (char*) MALLOC(MAX_WIDTH*4),  /*data*/
1342                                  MAX_WIDTH, 1,         /*width, height*/
1343                                  32,                   /*bitmap_pad*/
1344                                  0                     /*bytes_per_line*/ );
1345#endif
1346   }
1347
1348   return GL_TRUE;
1349}
1350
1351
1352
1353/*
1354 * Convert an RGBA color to a pixel value.
1355 */
1356unsigned long
1357xmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLubyte a,
1358                      GLuint pixelFormat)
1359{
1360   switch (pixelFormat) {
1361      case PF_Index:
1362         return 0;
1363      case PF_Truecolor:
1364         {
1365            unsigned long p;
1366            PACK_TRUECOLOR( p, r, g, b );
1367            return p;
1368         }
1369      case PF_8A8B8G8R:
1370         return PACK_8A8B8G8R( r, g, b, a );
1371      case PF_8R8G8B:
1372         /* fall through */
1373      case PF_8R8G8B24:
1374         return PACK_8R8G8B( r, g, b );
1375      case PF_5R6G5B:
1376         return PACK_5R6G5B( r, g, b );
1377      case PF_Dither:
1378         {
1379            DITHER_SETUP;
1380            return DITHER( 1, 0, r, g, b );
1381         }
1382      case PF_1Bit:
1383         /* 382 = (3*255)/2 */
1384         return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
1385      case PF_HPCR:
1386         return DITHER_HPCR(1, 1, r, g, b);
1387      case PF_Lookup:
1388         {
1389            LOOKUP_SETUP;
1390            return LOOKUP( r, g, b );
1391         }
1392      case PF_Grayscale:
1393         return GRAY_RGB( r, g, b );
1394      case PF_Dither_True:
1395         /* fall through */
1396      case PF_Dither_5R6G5B:
1397         {
1398            unsigned long p;
1399            PACK_TRUEDITHER(p, 1, 0, r, g, b);
1400            return p;
1401         }
1402      default:
1403         _mesa_problem(NULL, "Bad pixel format in xmesa_color_to_pixel");
1404   }
1405   return 0;
1406}
1407
1408
1409/**********************************************************************/
1410/*****                       Public Functions                     *****/
1411/**********************************************************************/
1412
1413
1414/*
1415 * Create a new X/Mesa visual.
1416 * Input:  display - X11 display
1417 *         visinfo - an XVisualInfo pointer
1418 *         rgb_flag - GL_TRUE = RGB mode,
1419 *                    GL_FALSE = color index mode
1420 *         alpha_flag - alpha buffer requested?
1421 *         db_flag - GL_TRUE = double-buffered,
1422 *                   GL_FALSE = single buffered
1423 *         stereo_flag - stereo visual?
1424 *         ximage_flag - GL_TRUE = use an XImage for back buffer,
1425 *                       GL_FALSE = use an off-screen pixmap for back buffer
1426 *         depth_size - requested bits/depth values, or zero
1427 *         stencil_size - requested bits/stencil values, or zero
1428 *         accum_red_size - requested bits/red accum values, or zero
1429 *         accum_green_size - requested bits/green accum values, or zero
1430 *         accum_blue_size - requested bits/blue accum values, or zero
1431 *         accum_alpha_size - requested bits/alpha accum values, or zero
1432 *         num_samples - number of samples/pixel if multisampling, or zero
1433 *         level - visual level, usually 0
1434 *         visualCaveat - ala the GLX extension, usually GLX_NONE_EXT
1435 * Return;  a new XMesaVisual or 0 if error.
1436 */
1437XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
1438                               XMesaVisualInfo visinfo,
1439                               GLboolean rgb_flag,
1440                               GLboolean alpha_flag,
1441                               GLboolean db_flag,
1442                               GLboolean stereo_flag,
1443                               GLboolean ximage_flag,
1444                               GLint depth_size,
1445                               GLint stencil_size,
1446                               GLint accum_red_size,
1447                               GLint accum_green_size,
1448                               GLint accum_blue_size,
1449                               GLint accum_alpha_size,
1450                               GLint num_samples,
1451                               GLint level,
1452                               GLint visualCaveat )
1453{
1454   char *gamma;
1455   XMesaVisual v;
1456   GLint red_bits, green_bits, blue_bits, alpha_bits;
1457
1458   /* For debugging only */
1459   if (_mesa_getenv("MESA_XSYNC")) {
1460      /* This makes debugging X easier.
1461       * In your debugger, set a breakpoint on _XError to stop when an
1462       * X protocol error is generated.
1463       */
1464#ifdef XFree86Server
1465      /* NOT_NEEDED */
1466#else
1467      XSynchronize( display, 1 );
1468#endif
1469   }
1470
1471   v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual);
1472   if (!v) {
1473      return NULL;
1474   }
1475
1476   /*
1477    * In the X server, NULL is passed in for the display.  It will have
1478    * to be set before using this visual.  See XMesaSetVisualDisplay()
1479    * below.
1480    */
1481   v->display = display;
1482
1483   /* Save a copy of the XVisualInfo struct because the user may XFREE()
1484    * the struct but we may need some of the information contained in it
1485    * at a later time.
1486    */
1487#ifdef XFree86Server
1488   v->visinfo = visinfo;
1489#else
1490   v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
1491   if(!v->visinfo) {
1492      FREE(v);
1493      return NULL;
1494   }
1495   MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
1496#endif
1497
1498#ifdef XFree86Server
1499   /* Initialize the depth of the screen */
1500   {
1501       PixmapFormatRec *format;
1502
1503       for (format = screenInfo.formats;
1504	    format->depth != display->rootDepth;
1505	    format++)
1506	   ;
1507       v->screen_depth = format->bitsPerPixel;
1508   }
1509#endif
1510
1511   /* check for MESA_GAMMA environment variable */
1512   gamma = _mesa_getenv("MESA_GAMMA");
1513   if (gamma) {
1514      v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0;
1515      sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma );
1516      if (v->RedGamma<=0.0)    v->RedGamma = 1.0;
1517      if (v->GreenGamma<=0.0)  v->GreenGamma = v->RedGamma;
1518      if (v->BlueGamma<=0.0)   v->BlueGamma = v->RedGamma;
1519   }
1520   else {
1521      v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0;
1522   }
1523
1524   v->ximage_flag = ximage_flag;
1525   v->level = level;
1526   v->VisualCaveat = visualCaveat;
1527
1528   (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 );
1529
1530   {
1531      int xclass;
1532      xclass = GET_VISUAL_CLASS(v);
1533      if (xclass==TrueColor || xclass==DirectColor) {
1534         red_bits   = bitcount(GET_REDMASK(v));
1535         green_bits = bitcount(GET_GREENMASK(v));
1536         blue_bits  = bitcount(GET_BLUEMASK(v));
1537         alpha_bits = 0;
1538      }
1539      else {
1540         /* this is an approximation */
1541         int depth;
1542         depth = GET_VISUAL_DEPTH(v);
1543         red_bits = depth / 3;
1544         depth -= red_bits;
1545         green_bits = depth / 2;
1546         depth -= green_bits;
1547         blue_bits = depth;
1548         alpha_bits = 0;
1549         assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) );
1550      }
1551   }
1552
1553   if (alpha_flag && alpha_bits == 0)
1554      alpha_bits = 8;
1555
1556   _mesa_initialize_visual( &v->mesa_visual,
1557                            rgb_flag, db_flag, stereo_flag,
1558                            red_bits, green_bits,
1559                            blue_bits, alpha_bits,
1560                            v->index_bits,
1561                            depth_size,
1562                            stencil_size,
1563                            accum_red_size, accum_green_size,
1564                            accum_blue_size, accum_alpha_size,
1565                            0 );
1566   return v;
1567}
1568
1569
1570void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v )
1571{
1572    v->display = dpy;
1573}
1574
1575
1576void XMesaDestroyVisual( XMesaVisual v )
1577{
1578#ifndef XFree86Server
1579   FREE(v->visinfo);
1580#endif
1581   FREE(v);
1582}
1583
1584
1585
1586/*
1587 * Create a new XMesaContext.
1588 * Input:  v - XMesaVisual
1589 *         share_list - another XMesaContext with which to share display
1590 *                      lists or NULL if no sharing is wanted.
1591 * Return:  an XMesaContext or NULL if error.
1592 */
1593XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
1594{
1595   static GLboolean firstTime = GL_TRUE;
1596   XMesaContext c;
1597   GLboolean direct = GL_TRUE; /* not really */
1598   GLcontext *mesaCtx;
1599
1600   if (firstTime) {
1601      _glthread_INIT_MUTEX(_xmesa_lock);
1602      firstTime = GL_FALSE;
1603   }
1604
1605   c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
1606   if (!c) {
1607      return NULL;
1608   }
1609
1610   mesaCtx = &(c->mesa);
1611
1612   /* Setup these pointers here since they're using for making the default
1613    * and proxy texture objects.  Actually, we don't really need to do
1614    * this since we're using the default fallback functions which
1615    * _mesa_initialize_context() would plug in if needed.
1616    */
1617   mesaCtx->Driver.NewTextureObject = _mesa_new_texture_object;
1618   mesaCtx->Driver.DeleteTexture = _mesa_delete_texture_object;
1619
1620   if (!_mesa_initialize_context(mesaCtx, &v->mesa_visual,
1621                      share_list ? &(share_list->mesa) : (GLcontext *) NULL,
1622                      (void *) c, direct)) {
1623      FREE(c);
1624      return NULL;
1625   }
1626
1627   _mesa_enable_sw_extensions(mesaCtx);
1628   _mesa_enable_1_3_extensions(mesaCtx);
1629   _mesa_enable_1_4_extensions(mesaCtx);
1630   _mesa_enable_1_5_extensions(mesaCtx);
1631
1632   if (CHECK_BYTE_ORDER(v)) {
1633      c->swapbytes = GL_FALSE;
1634   }
1635   else {
1636      c->swapbytes = GL_TRUE;
1637   }
1638
1639   c->xm_visual = v;
1640   c->xm_draw_buffer = NULL;   /* set later by XMesaMakeCurrent */
1641   c->xm_read_buffer = NULL;   /* set later by XMesaMakeCurrent */
1642   c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
1643   c->display = v->display;
1644   c->pixelformat = v->dithered_pf;      /* Dithering is enabled by default */
1645
1646   mesaCtx->Driver.UpdateState = xmesa_update_state;
1647
1648   /* Initialize the software rasterizer and helper modules.
1649    */
1650   _swrast_CreateContext( mesaCtx );
1651   _ac_CreateContext( mesaCtx );
1652   _tnl_CreateContext( mesaCtx );
1653   _swsetup_CreateContext( mesaCtx );
1654
1655   xmesa_register_swrast_functions( mesaCtx );
1656
1657   /* Set up some constant pointers:
1658    */
1659   xmesa_init_pointers( mesaCtx );
1660
1661   return c;
1662}
1663
1664
1665
1666
1667void XMesaDestroyContext( XMesaContext c )
1668{
1669   GLcontext *mesaCtx = &c->mesa;
1670#ifdef FX
1671   if (c->xm_draw_buffer && c->xm_buffer->FXctx)
1672      fxMesaDestroyContext(c->xm_draw_buffer->FXctx);
1673#endif
1674   _swsetup_DestroyContext( mesaCtx );
1675   _swrast_DestroyContext( mesaCtx );
1676   _tnl_DestroyContext( mesaCtx );
1677   _ac_DestroyContext( mesaCtx );
1678   _mesa_free_context_data( mesaCtx );
1679   _mesa_free( c );
1680}
1681
1682
1683
1684/*
1685 * XXX this isn't a public function!  It's a hack for the 3Dfx driver.
1686 * Create a new XMesaBuffer from an X window.
1687 * Input:  v - the XMesaVisual
1688 *         w - the window
1689 *         c - the context
1690 * Return:  new XMesaBuffer or NULL if error
1691 */
1692XMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v, XMesaWindow w,
1693                                      XMesaContext c )
1694{
1695#ifndef XFree86Server
1696   XWindowAttributes attr;
1697#endif
1698#ifdef FX
1699   char *fxEnvVar;
1700#endif
1701   int client = 0;
1702
1703   XMesaBuffer b = alloc_xmesa_buffer();
1704   if (!b) {
1705      return NULL;
1706   }
1707
1708   (void) c;
1709
1710#ifdef XFree86Server
1711   client = CLIENT_ID(((XMesaDrawable)w)->id);
1712#endif
1713
1714   assert(v);
1715
1716#ifdef XFree86Server
1717   if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) {
1718#else
1719   XGetWindowAttributes( v->display, w, &attr );
1720
1721   if (GET_VISUAL_DEPTH(v) != attr.depth) {
1722#endif
1723      _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual and window!\n");
1724      return NULL;
1725   }
1726
1727   b->xm_visual = v;
1728   b->type = WINDOW;
1729   b->display = v->display;
1730#ifdef XFree86Server
1731   b->cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
1732#else
1733   if (attr.colormap) {
1734      b->cmap = attr.colormap;
1735   }
1736   else {
1737      _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w);
1738      /* this is weird, a window w/out a colormap!? */
1739      /* OK, let's just allocate a new one and hope for the best */
1740      b->cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
1741   }
1742#endif
1743
1744   /* determine back buffer implementation */
1745   if (v->mesa_visual.doubleBufferMode) {
1746      if (v->ximage_flag) {
1747	 b->db_state = BACK_XIMAGE;
1748      }
1749      else {
1750	 b->db_state = BACK_PIXMAP;
1751      }
1752   }
1753   else {
1754      b->db_state = 0;
1755   }
1756
1757   _mesa_initialize_framebuffer(&b->mesa_buffer,
1758                                &v->mesa_visual,
1759                                v->mesa_visual.depthBits > 0,
1760                                v->mesa_visual.stencilBits > 0,
1761                                v->mesa_visual.accumRedBits > 0,
1762                                v->mesa_visual.alphaBits > 0 );
1763
1764   if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
1765                                      (XMesaDrawable)w, b->cmap )) {
1766      free_xmesa_buffer(client, b);
1767      return NULL;
1768   }
1769
1770#ifdef FX
1771   fxEnvVar = _mesa_getenv("MESA_GLX_FX");
1772   if (fxEnvVar) {
1773     if (fxEnvVar[0]!='d') {
1774       int attribs[100];
1775       int numAttribs = 0;
1776       int hw;
1777       if (v->mesa_visual.depthBits > 0) {
1778	 attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
1779	 attribs[numAttribs++] = v->mesa_visual.depthBits;
1780       }
1781       if (v->mesa_visual.doubleBufferMode) {
1782	 attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
1783       }
1784       if (v->mesa_visual.accumRedBits > 0) {
1785	 attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
1786	 attribs[numAttribs++] = v->mesa_visual.accumRedBits;
1787       }
1788       if (v->mesa_visual.stencilBits > 0) {
1789         attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
1790         attribs[numAttribs++] = v->mesa_visual.stencilBits;
1791       }
1792       if (v->mesa_visual.alphaBits > 0) {
1793         attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
1794         attribs[numAttribs++] = v->mesa_visual.alphaBits;
1795       }
1796       if (1) {
1797         attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
1798         attribs[numAttribs++] = (int) &(c->mesa);
1799       }
1800       attribs[numAttribs++] = FXMESA_NONE;
1801
1802       /* [dBorca] need to revise this ASAP!!! */
1803       /*if ((hw = fxQueryHardware())==GR_SSTTYPE_VOODOO) {
1804         b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
1805         if ((v->undithered_pf!=PF_Index) && (b->backimage)) {
1806	   b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
1807	   if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
1808	     b->FXwindowHack = b->FXctx ? GL_TRUE : GL_FALSE;
1809	   else
1810	     b->FXwindowHack = GL_FALSE;
1811         }
1812       }
1813       else */{
1814         if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
1815	   b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
1816					  GR_REFRESH_75Hz, attribs);
1817         else
1818	   b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
1819         b->FXisHackUsable = GL_FALSE;
1820         b->FXwindowHack = GL_FALSE;
1821       }
1822       /*
1823       fprintf(stderr,
1824               "voodoo %d, wid %d height %d hack: usable %d active %d\n",
1825               hw, b->width, b->height, b->FXisHackUsable, b->FXwindowHack);
1826       */
1827     }
1828   }
1829   else {
1830      _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n");
1831      _mesa_warning(NULL, "         you have not defined the MESA_GLX_FX env. var.\n");
1832      _mesa_warning(NULL, "         (check the README.3DFX file for more information).\n\n");
1833      _mesa_warning(NULL, "         you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
1834   }
1835#endif
1836
1837   return b;
1838}
1839
1840
1841XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, XMesaWindow w )
1842{
1843   return XMesaCreateWindowBuffer2( v, w, NULL );
1844}
1845
1846
1847/*
1848 * Create a new XMesaBuffer from an X pixmap.
1849 * Input:  v - the XMesaVisual
1850 *         p - the pixmap
1851 *         cmap - the colormap, may be 0 if using a TrueColor or DirectColor
1852 *                visual for the pixmap
1853 * Return:  new XMesaBuffer or NULL if error
1854 */
1855XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
1856				     XMesaPixmap p, XMesaColormap cmap )
1857{
1858   int client = 0;
1859   XMesaBuffer b = alloc_xmesa_buffer();
1860   if (!b) {
1861      return NULL;
1862   }
1863
1864
1865#ifdef XFree86Server
1866   client = CLIENT_ID(((XMesaDrawable)p)->id);
1867#endif
1868
1869   assert(v);
1870
1871   b->xm_visual = v;
1872   b->type = PIXMAP;
1873   b->display = v->display;
1874   b->cmap = cmap;
1875
1876   /* determine back buffer implementation */
1877   if (v->mesa_visual.doubleBufferMode) {
1878      if (v->ximage_flag) {
1879	 b->db_state = BACK_XIMAGE;
1880      }
1881      else {
1882	 b->db_state = BACK_PIXMAP;
1883      }
1884   }
1885   else {
1886      b->db_state = 0;
1887   }
1888
1889   _mesa_initialize_framebuffer(&b->mesa_buffer,
1890                                &v->mesa_visual,
1891                                v->mesa_visual.depthBits > 0,
1892                                v->mesa_visual.stencilBits > 0,
1893                                v->mesa_visual.accumRedBits +
1894                                v->mesa_visual.accumGreenBits +
1895                                v->mesa_visual.accumBlueBits > 0,
1896                                v->mesa_visual.alphaBits > 0 );
1897
1898   if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
1899				     (XMesaDrawable)p, cmap)) {
1900      free_xmesa_buffer(client, b);
1901      return NULL;
1902   }
1903
1904   return b;
1905}
1906
1907
1908
1909XMesaBuffer XMesaCreatePBuffer( XMesaVisual v, XMesaColormap cmap,
1910                                unsigned int width, unsigned int height )
1911{
1912#ifdef XFree86Server
1913   return 0;
1914#else
1915   int client = 0;
1916   XMesaWindow root;
1917   XMesaDrawable drawable;  /* X Pixmap Drawable */
1918   XMesaBuffer b = alloc_xmesa_buffer();
1919   if (!b) {
1920      return NULL;
1921   }
1922
1923   b->xm_visual = v;
1924   b->type = PBUFFER;
1925   b->display = v->display;
1926   b->cmap = cmap;
1927
1928   /* allocate pixmap for front buffer */
1929   root = RootWindow( v->display, v->visinfo->screen );
1930   drawable = XCreatePixmap( v->display, root, width, height, v->visinfo->depth );
1931
1932   /* determine back buffer implementation */
1933   if (v->mesa_visual.doubleBufferMode) {
1934      if (v->ximage_flag) {
1935	 b->db_state = BACK_XIMAGE;
1936      }
1937      else {
1938	 b->db_state = BACK_PIXMAP;
1939      }
1940   }
1941   else {
1942      b->db_state = 0;
1943   }
1944
1945   _mesa_initialize_framebuffer(&b->mesa_buffer,
1946                                &v->mesa_visual,
1947                                v->mesa_visual.depthBits > 0,
1948                                v->mesa_visual.stencilBits > 0,
1949                                v->mesa_visual.accumRedBits +
1950                                v->mesa_visual.accumGreenBits +
1951                                v->mesa_visual.accumBlueBits > 0,
1952                                v->mesa_visual.alphaBits > 0 );
1953
1954   if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
1955				     drawable, cmap)) {
1956      free_xmesa_buffer(client, b);
1957      return NULL;
1958   }
1959
1960   return b;
1961#endif
1962}
1963
1964
1965
1966/*
1967 * Deallocate an XMesaBuffer structure and all related info.
1968 */
1969void XMesaDestroyBuffer( XMesaBuffer b )
1970{
1971   int client = 0;
1972
1973#ifdef XFree86Server
1974   if (b->frontbuffer)
1975       client = CLIENT_ID(b->frontbuffer->id);
1976#endif
1977
1978   if (b->gc)  XMesaFreeGC( b->xm_visual->display, b->gc );
1979   if (b->cleargc)  XMesaFreeGC( b->xm_visual->display, b->cleargc );
1980   if (b->swapgc)  XMesaFreeGC( b->xm_visual->display, b->swapgc );
1981
1982   if (b->backimage) {
1983#if defined(USE_XSHM) && !defined(XFree86Server)
1984       if (b->shm) {
1985	   XShmDetach( b->xm_visual->display, &b->shminfo );
1986	   XDestroyImage( b->backimage );
1987	   shmdt( b->shminfo.shmaddr );
1988       }
1989       else
1990#endif
1991	   XMesaDestroyImage( b->backimage );
1992   }
1993   if (b->backpixmap) {
1994      XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
1995      if (b->xm_visual->hpcr_clear_flag) {
1996	XMesaFreePixmap( b->xm_visual->display,
1997			 b->xm_visual->hpcr_clear_pixmap );
1998	XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage );
1999      }
2000   }
2001   if (b->rowimage) {
2002      FREE( b->rowimage->data );
2003      b->rowimage->data = NULL;
2004      XMesaDestroyImage( b->rowimage );
2005   }
2006
2007   free_xmesa_buffer(client, b);
2008}
2009
2010
2011
2012/*
2013 * Bind buffer b to context c and make c the current rendering context.
2014 */
2015GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b )
2016{
2017   return XMesaMakeCurrent2( c, b, b );
2018}
2019
2020
2021/*
2022 * Bind buffer b to context c and make c the current rendering context.
2023 */
2024GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
2025                             XMesaBuffer readBuffer )
2026{
2027   if (c) {
2028      if (!drawBuffer || !readBuffer)
2029         return GL_FALSE;  /* must specify buffers! */
2030
2031#ifdef FX
2032      if (drawBuffer->FXctx) {
2033         fxMesaMakeCurrent(drawBuffer->FXctx);
2034
2035         c->xm_draw_buffer = drawBuffer;
2036         c->xm_read_buffer = readBuffer;
2037         c->xm_buffer = drawBuffer;
2038
2039         return GL_TRUE;
2040      }
2041#endif
2042      if (&(c->mesa) == _mesa_get_current_context()
2043          && c->xm_draw_buffer == drawBuffer
2044          && c->xm_read_buffer == readBuffer
2045          && c->xm_draw_buffer->wasCurrent) {
2046         /* same context and buffer, do nothing */
2047         return GL_TRUE;
2048      }
2049
2050      c->xm_draw_buffer = drawBuffer;
2051      c->xm_read_buffer = readBuffer;
2052      c->xm_buffer = drawBuffer;
2053
2054      _mesa_make_current2(&(c->mesa),
2055                          &drawBuffer->mesa_buffer,
2056                          &readBuffer->mesa_buffer);
2057
2058      if (c->mesa.Viewport.Width == 0) {
2059	 /* initialize viewport to window size */
2060	 _mesa_Viewport( 0, 0, drawBuffer->width, drawBuffer->height );
2061	 c->mesa.Scissor.Width = drawBuffer->width;
2062	 c->mesa.Scissor.Height = drawBuffer->height;
2063      }
2064
2065      if (c->xm_visual->mesa_visual.rgbMode) {
2066         /*
2067          * Must recompute and set these pixel values because colormap
2068          * can be different for different windows.
2069          */
2070         c->clearpixel = xmesa_color_to_pixel( c,
2071                                               c->clearcolor[0],
2072                                               c->clearcolor[1],
2073                                               c->clearcolor[2],
2074                                               c->clearcolor[3],
2075                                               c->xm_visual->undithered_pf);
2076         XMesaSetForeground(c->display, c->xm_draw_buffer->cleargc, c->clearpixel);
2077      }
2078
2079      /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
2080      c->xm_draw_buffer->wasCurrent = GL_TRUE;
2081   }
2082   else {
2083      /* Detach */
2084      _mesa_make_current2( NULL, NULL, NULL );
2085   }
2086   return GL_TRUE;
2087}
2088
2089
2090/*
2091 * Unbind the context c from its buffer.
2092 */
2093GLboolean XMesaUnbindContext( XMesaContext c )
2094{
2095   /* A no-op for XFree86 integration purposes */
2096   return GL_TRUE;
2097}
2098
2099
2100XMesaContext XMesaGetCurrentContext( void )
2101{
2102   GET_CURRENT_CONTEXT(ctx);
2103   if (ctx) {
2104      XMesaContext xmesa = XMESA_CONTEXT(ctx);
2105      return xmesa;
2106   }
2107   else {
2108      return 0;
2109   }
2110}
2111
2112
2113XMesaBuffer XMesaGetCurrentBuffer( void )
2114{
2115   GET_CURRENT_CONTEXT(ctx);
2116   if (ctx) {
2117      XMesaContext xmesa = XMESA_CONTEXT(ctx);
2118      return xmesa->xm_draw_buffer;
2119   }
2120   else {
2121      return 0;
2122   }
2123}
2124
2125
2126/* New in Mesa 3.1 */
2127XMesaBuffer XMesaGetCurrentReadBuffer( void )
2128{
2129   GET_CURRENT_CONTEXT(ctx);
2130   if (ctx) {
2131      XMesaContext xmesa = XMESA_CONTEXT(ctx);
2132      return xmesa->xm_read_buffer;
2133   }
2134   else {
2135      return 0;
2136   }
2137}
2138
2139
2140GLboolean XMesaForceCurrent(XMesaContext c)
2141{
2142   if (c) {
2143      if (&(c->mesa) != _mesa_get_current_context()) {
2144	 _mesa_make_current(&(c->mesa), &c->xm_draw_buffer->mesa_buffer);
2145      }
2146   }
2147   else {
2148      _mesa_make_current(NULL, NULL);
2149   }
2150   return GL_TRUE;
2151}
2152
2153
2154GLboolean XMesaLoseCurrent(XMesaContext c)
2155{
2156   (void) c;
2157   _mesa_make_current(NULL, NULL);
2158   return GL_TRUE;
2159}
2160
2161
2162/*
2163 * Switch 3Dfx support hack between window and full-screen mode.
2164 */
2165GLboolean XMesaSetFXmode( GLint mode )
2166{
2167#ifdef FX
2168   const char *fx = _mesa_getenv("MESA_GLX_FX");
2169   if (fx && fx[0] != 'd') {
2170      GET_CURRENT_CONTEXT(ctx);
2171      GrHwConfiguration hw;
2172      if (!FX_grSstQueryHardware(&hw)) {
2173         /*fprintf(stderr, "!grSstQueryHardware\n");*/
2174         return GL_FALSE;
2175      }
2176      if (hw.num_sst < 1) {
2177         /*fprintf(stderr, "hw.num_sst < 1\n");*/
2178         return GL_FALSE;
2179      }
2180      if (ctx) {
2181         XMesaContext xmesa = XMESA_CONTEXT(ctx);
2182         if (mode == XMESA_FX_WINDOW) {
2183	    if (xmesa->xm_draw_buffer->FXisHackUsable) {
2184	       FX_grSstControl(GR_CONTROL_DEACTIVATE);
2185	       xmesa->xm_draw_buffer->FXwindowHack = GL_TRUE;
2186	       return GL_TRUE;
2187	    }
2188	 }
2189	 else if (mode == XMESA_FX_FULLSCREEN) {
2190	    FX_grSstControl(GR_CONTROL_ACTIVATE);
2191	    xmesa->xm_draw_buffer->FXwindowHack = GL_FALSE;
2192	    return GL_TRUE;
2193	 }
2194	 else {
2195	    /* Error: Bad mode value */
2196	 }
2197      }
2198   }
2199   /*fprintf(stderr, "fallthrough\n");*/
2200#else
2201   (void) mode;
2202#endif
2203   return GL_FALSE;
2204}
2205
2206
2207
2208#ifdef FX
2209/*
2210 * Read image from VooDoo frame buffer into X/Mesa's back XImage.
2211 */
2212static void FXgetImage( XMesaBuffer b )
2213{
2214   GET_CURRENT_CONTEXT(ctx);
2215   static unsigned short pixbuf[MAX_WIDTH];
2216   GLuint x, y;
2217   int xpos, ypos;
2218   XMesaWindow root;
2219   unsigned int bw, depth, width, height;
2220   XMesaContext xmesa = XMESA_CONTEXT(ctx);
2221
2222#ifdef XFree86Server
2223   x = b->frontbuffer->x;
2224   y = b->frontbuffer->y;
2225   width = b->frontbuffer->width;
2226   height = b->frontbuffer->height;
2227   depth = b->frontbuffer->depth;
2228#else
2229   XGetGeometry( b->xm_visual->display, b->frontbuffer,
2230                 &root, &xpos, &ypos, &width, &height, &bw, &depth);
2231#endif
2232   if (b->width != width || b->height != height) {
2233      b->width = MIN2((int)width, b->FXctx->width);
2234      b->height = MIN2((int)height, b->FXctx->height);
2235      if (b->width & 1)
2236         b->width--;  /* prevent odd width */
2237      xmesa_alloc_back_buffer( b );
2238   }
2239
2240   grLfbWriteColorFormat(GR_COLORFORMAT_ARGB);
2241   if (b->xm_visual->undithered_pf==PF_5R6G5B) {
2242      /* Special case: 16bpp RGB */
2243      grLfbReadRegion( GR_BUFFER_FRONTBUFFER,       /* src buffer */
2244                       0, b->FXctx->height - b->height,  /*pos*/
2245                       b->width, b->height,         /* size */
2246                       b->width * sizeof(GLushort), /* stride */
2247                       b->backimage->data);         /* dest buffer */
2248   }
2249   else if (b->xm_visual->dithered_pf==PF_Dither
2250	    && GET_VISUAL_DEPTH(b->xm_visual)==8) {
2251      /* Special case: 8bpp RGB */
2252      for (y=0;y<b->height;y++) {
2253         GLubyte *ptr = (GLubyte*) b->backimage->data
2254                        + b->backimage->bytes_per_line * y;
2255         XDITHER_SETUP(y);
2256
2257         /* read row from 3Dfx frame buffer */
2258         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
2259                          0, b->FXctx->height-(b->height-y),
2260                          b->width, 1,
2261                          0,
2262                          pixbuf );
2263
2264         /* write to XImage back buffer */
2265         for (x=0;x<b->width;x++) {
2266            GLubyte r = (pixbuf[x] & 0xf800) >> 8;
2267            GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
2268            GLubyte b = (pixbuf[x] & 0x001f) << 3;
2269            *ptr++ = XDITHER( x, r, g, b);
2270         }
2271      }
2272   }
2273   else {
2274      /* General case: slow! */
2275      for (y=0;y<b->height;y++) {
2276         /* read row from 3Dfx frame buffer */
2277         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
2278                          0, b->FXctx->height-(b->height-y),
2279                          b->width, 1,
2280                          0,
2281                          pixbuf );
2282
2283         /* write to XImage back buffer */
2284         for (x=0;x<b->width;x++) {
2285            XMesaPutPixel(b->backimage,x,y,
2286			  xmesa_color_to_pixel(xmesa,
2287					       (pixbuf[x] & 0xf800) >> 8,
2288					       (pixbuf[x] & 0x07e0) >> 3,
2289					       (pixbuf[x] & 0x001f) << 3,
2290					       0xff,
2291                                               b->xm_visual->undithered_pf));
2292         }
2293      }
2294   }
2295   grLfbWriteColorFormat(GR_COLORFORMAT_ABGR);
2296}
2297#endif
2298
2299
2300/*
2301 * Copy the back buffer to the front buffer.  If there's no back buffer
2302 * this is a no-op.
2303 */
2304void XMesaSwapBuffers( XMesaBuffer b )
2305{
2306   GET_CURRENT_CONTEXT(ctx);
2307
2308   /* If we're swapping the buffer associated with the current context
2309    * we have to flush any pending rendering commands first.
2310    */
2311   if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
2312      _mesa_notifySwapBuffers(ctx);
2313
2314   if (b->db_state) {
2315#ifdef FX
2316      if (b->FXctx) {
2317         fxMesaSwapBuffers();
2318
2319         if (b->FXwindowHack)
2320            FXgetImage(b);
2321         else
2322            return;
2323      }
2324#endif
2325     if (b->backimage) {
2326	 /* Copy Ximage from host's memory to server's window */
2327#if defined(USE_XSHM) && !defined(XFree86Server)
2328	 if (b->shm) {
2329            /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2330	    XShmPutImage( b->xm_visual->display, b->frontbuffer,
2331			  b->swapgc,
2332			  b->backimage, 0, 0,
2333			  0, 0, b->width, b->height, False );
2334            /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2335	 }
2336	 else
2337#endif
2338         {
2339            /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2340            XMesaPutImage( b->xm_visual->display, b->frontbuffer,
2341			   b->swapgc,
2342			   b->backimage, 0, 0,
2343			   0, 0, b->width, b->height );
2344            /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2345         }
2346      }
2347      else {
2348	 /* Copy pixmap to window on server */
2349         /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2350	 XMesaCopyArea( b->xm_visual->display,
2351			b->backpixmap,   /* source drawable */
2352			b->frontbuffer,  /* dest. drawable */
2353			b->swapgc,
2354			0, 0, b->width, b->height,  /* source region */
2355			0, 0                 /* dest region */
2356		      );
2357         /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2358      }
2359   }
2360#if !defined(XFree86Server)
2361   XSync( b->xm_visual->display, False );
2362#endif
2363}
2364
2365
2366
2367/*
2368 * Copy sub-region of back buffer to front buffer
2369 */
2370void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
2371{
2372   GET_CURRENT_CONTEXT(ctx);
2373
2374   /* If we're swapping the buffer associated with the current context
2375    * we have to flush any pending rendering commands first.
2376    */
2377   if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
2378      _mesa_notifySwapBuffers(ctx);
2379
2380   if (b->db_state) {
2381      int yTop = b->height - y - height;
2382#ifdef FX
2383      if (b->FXctx) {
2384         fxMesaSwapBuffers();
2385         if (b->FXwindowHack)
2386            FXgetImage(b);
2387         else
2388            return;
2389      }
2390#endif
2391      if (b->backimage) {
2392         /* Copy Ximage from host's memory to server's window */
2393#if defined(USE_XSHM) && !defined(XFree86Server)
2394         if (b->shm) {
2395            /* XXX assuming width and height aren't too large! */
2396            XShmPutImage( b->xm_visual->display, b->frontbuffer,
2397                          b->swapgc,
2398                          b->backimage, x, yTop,
2399                          x, yTop, width, height, False );
2400            /* wait for finished event??? */
2401         }
2402         else
2403#endif
2404         {
2405            /* XXX assuming width and height aren't too large! */
2406            XMesaPutImage( b->xm_visual->display, b->frontbuffer,
2407			   b->swapgc,
2408			   b->backimage, x, yTop,
2409			   x, yTop, width, height );
2410         }
2411      }
2412      else {
2413         /* Copy pixmap to window on server */
2414         XMesaCopyArea( b->xm_visual->display,
2415			b->backpixmap,           /* source drawable */
2416			b->frontbuffer,          /* dest. drawable */
2417			b->swapgc,
2418			x, yTop, width, height,  /* source region */
2419			x, yTop                  /* dest region */
2420                      );
2421      }
2422   }
2423}
2424
2425
2426/*
2427 * Return a pointer to the XMesa backbuffer Pixmap or XImage.  This function
2428 * is a way to get "under the hood" of X/Mesa so one can manipulate the
2429 * back buffer directly.
2430 * Output:  pixmap - pointer to back buffer's Pixmap, or 0
2431 *          ximage - pointer to back buffer's XImage, or NULL
2432 * Return:  GL_TRUE = context is double buffered
2433 *          GL_FALSE = context is single buffered
2434 */
2435GLboolean XMesaGetBackBuffer( XMesaBuffer b,
2436                              XMesaPixmap *pixmap,
2437                              XMesaImage **ximage )
2438{
2439   if (b->db_state) {
2440      if (pixmap)  *pixmap = b->backpixmap;
2441      if (ximage)  *ximage = b->backimage;
2442      return GL_TRUE;
2443   }
2444   else {
2445      *pixmap = 0;
2446      *ximage = NULL;
2447      return GL_FALSE;
2448   }
2449}
2450
2451
2452/*
2453 * Return the depth buffer associated with an XMesaBuffer.
2454 * Input:  b - the XMesa buffer handle
2455 * Output:  width, height - size of buffer in pixels
2456 *          bytesPerValue - bytes per depth value (2 or 4)
2457 *          buffer - pointer to depth buffer values
2458 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
2459 */
2460GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
2461                               GLint *bytesPerValue, void **buffer )
2462{
2463   if (!b->mesa_buffer.DepthBuffer) {
2464      *width = 0;
2465      *height = 0;
2466      *bytesPerValue = 0;
2467      *buffer = 0;
2468      return GL_FALSE;
2469   }
2470   else {
2471      *width = b->mesa_buffer.Width;
2472      *height = b->mesa_buffer.Height;
2473      *bytesPerValue = sizeof(GLdepth);
2474      *buffer = b->mesa_buffer.DepthBuffer;
2475      return GL_TRUE;
2476   }
2477}
2478
2479
2480void XMesaFlush( XMesaContext c )
2481{
2482   if (c && c->xm_visual) {
2483#ifdef XFree86Server
2484      /* NOT_NEEDED */
2485#else
2486      XSync( c->xm_visual->display, False );
2487#endif
2488   }
2489}
2490
2491
2492
2493const char *XMesaGetString( XMesaContext c, int name )
2494{
2495   (void) c;
2496   if (name==XMESA_VERSION) {
2497      return "5.0";
2498   }
2499   else if (name==XMESA_EXTENSIONS) {
2500      return "";
2501   }
2502   else {
2503      return NULL;
2504   }
2505}
2506
2507
2508
2509XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d )
2510{
2511   XMesaBuffer b;
2512   for (b=XMesaBufferList; b; b=b->Next) {
2513      if (b->frontbuffer==d && b->display==dpy) {
2514         return b;
2515      }
2516   }
2517   return NULL;
2518}
2519
2520
2521
2522/*
2523 * Look for XMesaBuffers whose X window has been destroyed.
2524 * Deallocate any such XMesaBuffers.
2525 */
2526void XMesaGarbageCollect( void )
2527{
2528   XMesaBuffer b, next;
2529   for (b=XMesaBufferList; b; b=next) {
2530      next = b->Next;
2531      if (b->display && b->frontbuffer && b->type == WINDOW) {
2532#ifdef XFree86Server
2533	 /* NOT_NEEDED */
2534#else
2535         XSync(b->display, False);
2536         if (!window_exists( b->display, b->frontbuffer )) {
2537            /* found a dead window, free the ancillary info */
2538            XMesaDestroyBuffer( b );
2539         }
2540#endif
2541      }
2542   }
2543}
2544
2545
2546void XMesaReset( void )
2547{
2548    while (XMesaBufferList)
2549	XMesaDestroyBuffer(XMesaBufferList);
2550
2551    XMesaBufferList = NULL;
2552}
2553
2554
2555unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
2556                                GLfloat red, GLfloat green,
2557                                GLfloat blue, GLfloat alpha )
2558{
2559   GLint r = (GLint) (red   * 255.0F);
2560   GLint g = (GLint) (green * 255.0F);
2561   GLint b = (GLint) (blue  * 255.0F);
2562   GLint a = (GLint) (alpha * 255.0F);
2563
2564   (void) DitherValues; /* silence warning */
2565
2566   switch (xmesa->pixelformat) {
2567      case PF_Index:
2568         return 0;
2569      case PF_Truecolor:
2570         {
2571            unsigned long p;
2572            PACK_TRUECOLOR( p, r, g, b );
2573            return p;
2574         }
2575      case PF_8A8B8G8R:
2576         return PACK_8A8B8G8R( r, g, b, a );
2577      case PF_8R8G8B:
2578         return PACK_8R8G8B( r, g, b );
2579      case PF_5R6G5B:
2580         return PACK_5R6G5B( r, g, b );
2581      case PF_Dither:
2582         {
2583            DITHER_SETUP;
2584            return DITHER( x, y, r, g, b );
2585         }
2586      case PF_1Bit:
2587         /* 382 = (3*255)/2 */
2588         return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
2589      case PF_HPCR:
2590         return DITHER_HPCR(x, y, r, g, b);
2591      case PF_Lookup:
2592         {
2593            LOOKUP_SETUP;
2594            return LOOKUP( r, g, b );
2595         }
2596      case PF_Grayscale:
2597         return GRAY_RGB( r, g, b );
2598      case PF_Dither_5R6G5B:
2599         /* fall through */
2600      case PF_Dither_True:
2601         {
2602            unsigned long p;
2603            PACK_TRUEDITHER(p, x, y, r, g, b);
2604            return p;
2605         }
2606      default:
2607         _mesa_problem(NULL, "Bad pixel format in XMesaDitherColor");
2608   }
2609   return 0;
2610}
2611
2612
2613/*
2614 * This is typically called when the window size changes and we need
2615 * to reallocate the buffer's back/depth/stencil/accum buffers.
2616 */
2617void XMesaResizeBuffers( XMesaBuffer b )
2618{
2619   xmesa_resize_buffers( &(b->mesa_buffer) );
2620
2621}
2622
2623