xm_api.c revision 655ba5d9927187e76b66f5886d090624dc4b1dd9
1655ba5d9927187e76b66f5886d090624dc4b1dd9Brian Paul/* $Id: xm_api.c,v 1.23 2001/05/29 19:48:47 brianp Exp $ */
2693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
3693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
4693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Mesa 3-D graphics library
5536ede7e00ff5e2f10be3bf9b60cd2cfa80b3518Brian Paul * Version:  3.5
65e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen *
7693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
85e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen *
9693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a
10693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * copy of this software and associated documentation files (the "Software"),
11693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * to deal in the Software without restriction, including without limitation
12693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * and/or sell copies of the Software, and to permit persons to whom the
14693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Software is furnished to do so, subject to the following conditions:
155e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen *
16693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * The above copyright notice and this permission notice shall be included
17693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * in all copies or substantial portions of the Software.
185e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen *
19693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
26693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
27693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
28693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
29693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * This file contains the implementations of all the XMesa* functions.
30693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *
31693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *
32693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * NOTES:
33693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *
34693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * The window coordinate system origin (0,0) is in the lower-left corner
35693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * of the window.  X11's window coordinate origin is in the upper-left
36693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * corner of the window.  Therefore, most drawing functions in this
37693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * file have to flip Y coordinates.
38693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *
39693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile
40693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * in support for the MIT Shared Memory extension.  If enabled, when you
41693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * use an Ximage for the back buffer in double buffered mode, the "swap"
42693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * operation will be faster.  You must also link with -lXext.
43693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *
44693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Byte swapping:  If the Mesa host and the X display use a different
45693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * byte order then there's some trickiness to be aware of when using
46693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * XImages.  The byte ordering used for the XImage is that of the X
47693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * display, not the Mesa host.
48693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * The color-to-pixel encoding for True/DirectColor must be done
49693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * according to the display's visual red_mask, green_mask, and blue_mask.
50693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * If XPutPixel is used to put a pixel into an XImage then XPutPixel will
51693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * do byte swapping if needed.  If one wants to directly "poke" the pixel
52693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * into the XImage's buffer then the pixel must be byte swapped first.  In
53693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format
54693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * and use XPutPixel everywhere except in the implementation of
55693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * glClear(GL_COLOR_BUFFER_BIT).  We want this function to be fast so
56693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * instead of using XPutPixel we "poke" our values after byte-swapping
57693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * the clear pixel value if needed.
58693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *
59693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
60693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
61693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef __CYGWIN__
62693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#undef WIN32
63693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#undef __WIN32__
64693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
65693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
66693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#include "glxheader.h"
67693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#include "GL/xmesa.h"
68693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#include "xmesaP.h"
69693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#include "context.h"
70693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#include "extensions.h"
71693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#include "glthread.h"
72693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#include "matrix.h"
73693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#include "mem.h"
7433143303feaf84afbef2e63ac0adab2d70b3c344Brian Paul#include "mmath.h"
755e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen#include "mtypes.h"
76693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef HAVE_CONFIG_H
77693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#include "conf.h"
78693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
79a4575499679d9d91055a35c7673b81872ec127cbJouk Jansen#include "macros.h"
80724abeb058ca9372c5a9b9e38ee43dde1accaa41Keith Whitwell#include "swrast/swrast.h"
81ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell#include "swrast_setup/swrast_setup.h"
82cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "array_cache/acache.h"
8323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell#include "tnl/tnl.h"
84693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
85693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef GLX_NONE_EXT
86693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#define GLX_NONE_EXT 0x8000
87693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
88693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
89693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
90693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
91693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Global X driver lock
92693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
93693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul_glthread_Mutex _xmesa_lock;
94693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
95693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
96693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
97693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
98693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Lookup tables for HPCR pixel format:
99693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
100693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic short hpcr_rgbTbl[3][256] = {
101693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
102693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,  22,  23,  23,
103693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,  30,  31,  31,
104693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
105693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
106693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
107693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
108693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
109693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
110693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
111693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
112693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
113693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
114693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
115693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
116693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
117693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
118693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul},
119693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
120693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,  22,  23,  23,
121693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,  30,  31,  31,
122693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
123693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
124693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
125693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
126693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
127693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
128693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
129693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
130693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
131693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
132693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
133693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
134693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
135693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
136693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul},
137693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
138693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
139693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 40,  40,  41,  41,  42,  42,  43,  43,  44,  44,  45,  45,  46,  46,  47,  47,
140693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 48,  48,  49,  49,  50,  50,  51,  51,  52,  52,  53,  53,  54,  54,  55,  55,
141693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 56,  56,  57,  57,  58,  58,  59,  59,  60,  60,  61,  61,  62,  62,  63,  63,
142693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 64,  64,  65,  65,  66,  66,  67,  67,  68,  68,  69,  69,  70,  70,  71,  71,
143693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 72,  72,  73,  73,  74,  74,  75,  75,  76,  76,  77,  77,  78,  78,  79,  79,
144693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 80,  80,  81,  81,  82,  82,  83,  83,  84,  84,  85,  85,  86,  86,  87,  87,
145693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
146693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
147693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
148693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
149693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
150693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
151693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
152693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
153693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223
1545e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen}
155693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul};
156693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
157693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
158693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
159693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/**********************************************************************/
160693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*****                     X Utility Functions                    *****/
161693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/**********************************************************************/
162693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
163693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
164693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
165693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * X/Mesa error reporting function:
166693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
167693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic void error( const char *msg )
168693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
169693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (getenv("MESA_DEBUG"))
170693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf( stderr, "X/Mesa error: %s\n", msg );
171693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
172693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
173693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
174693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
175693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return the host's byte order as LSBFirst or MSBFirst ala X.
176693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
177693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
178693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic int host_byte_order( void )
179693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
180693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int i = 1;
181693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   char *cptr = (char *) &i;
182693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return (*cptr==1) ? LSBFirst : MSBFirst;
183693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
184693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
185693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
186693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
187693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
188693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Error handling.
189693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
190693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
191693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic int mesaXErrorFlag = 0;
192693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
193693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event )
194693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
195693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) dpy;
196693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) event;
197693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   mesaXErrorFlag = 1;
198693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return 0;
199693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
200693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
201693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
202693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
203693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
204693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Check if the X Shared Memory extension is available.
205693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  0 = not available
206693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *          1 = shared XImage support available
207693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *          2 = shared Pixmap support available also
208693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
209693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
210693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic int check_for_xshm( XMesaDisplay *display )
211693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
212693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef USE_XSHM
213693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int major, minor, ignore;
214693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   Bool pixmaps;
215693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
216693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
217693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
218693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 return (pixmaps==True) ? 2 : 1;
219693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
220693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
221693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 return 0;
222693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
223693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
224693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
225693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return 0;
226693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
227693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
228693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Can't compile XSHM support */
229693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return 0;
230693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
231693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
232693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
233693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
234693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
235693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
236693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return the width and height of the given drawable.
237693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
238693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic void get_drawable_size( XMesaDisplay *dpy, XMesaDrawable d,
239693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               unsigned int *width, unsigned int *height)
240693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
241693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
242693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    (void) dpy;
243693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    *width = d->width;
244693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    *height = d->height;
245693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
246693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   Window root;
247693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int x, y;
248693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   unsigned int bw, depth;
249693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
250693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   _glthread_LOCK_MUTEX(_xmesa_lock);
251693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XGetGeometry( dpy, d, &root, &x, &y, width, height, &bw, &depth );
252693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   _glthread_UNLOCK_MUTEX(_xmesa_lock);
253693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
254693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
255693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
256693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
257693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
258693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Apply gamma correction to an intensity value in [0..max].  Return the
259693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * new intensity value.
260693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
261693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
262693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
263693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (gamma == 1.0) {
264693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return value;
265693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
266693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
267693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      double x = (double) value / (double) max;
26833143303feaf84afbef2e63ac0adab2d70b3c344Brian Paul      return IROUND_POS((GLfloat) max * pow(x, 1.0F/gamma));
269693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
270693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
271693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
272693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
273693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
274693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
275693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return the true number of bits per pixel for XImages.
276693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * For example, if we request a 24-bit deep visual we may actually need/get
277693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * 32bpp XImages.  This function returns the appropriate bpp.
278693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  dpy - the X display
279693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         visinfo - desribes the visual to be used for XImages
280693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  true number of bits per pixel for XImages
281693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
282693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#define GET_BITS_PER_PIXEL(xmv) bits_per_pixel(xmv)
283693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
284693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
285693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
286693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic int bits_per_pixel( XMesaVisual xmv )
287693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
288693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaVisualInfo visinfo = xmv->visinfo;
289693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   const int depth = visinfo->nplanes;
290693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int i;
291693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (i = 0; i < screenInfo.numPixmapFormats; i++) {
292693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (screenInfo.formats[i].depth == depth)
293693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return screenInfo.formats[i].bitsPerPixel;
294693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
295693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return depth;  /* should never get here, but this should be safe */
296693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
297693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
298693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
299693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
300693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic int bits_per_pixel( XMesaVisual xmv )
301693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
302693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaDisplay *dpy = xmv->display;
303693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaVisualInfo visinfo = xmv->visinfo;
304693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaImage *img;
305693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int bitsPerPixel;
306693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Create a temporary XImage */
307693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   img = XCreateImage( dpy, visinfo->visual, visinfo->depth,
308693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		       ZPixmap, 0,           /*format, offset*/
309693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		       (char*) MALLOC(8),    /*data*/
310693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		       1, 1,                 /*width, height*/
311693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		       32,                   /*bitmap_pad*/
312693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		       0                     /*bytes_per_line*/
313693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                     );
314693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   assert(img);
315693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* grab the bits/pixel value */
316693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   bitsPerPixel = img->bits_per_pixel;
317693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* free the XImage */
318693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   FREE( img->data );
319693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   img->data = NULL;
320693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaDestroyImage( img );
321693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return bitsPerPixel;
322693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
323693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
324693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
325693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
326693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
327693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
328693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Determine if a given X window ID is valid (window exists).
329693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Do this by calling XGetWindowAttributes() for the window and
330693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * checking if we catch an X error.
331693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  dpy - the display
332693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         win - the window to check for existance
333693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  GL_TRUE - window exists
334693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *          GL_FALSE - window doesn't exist
335693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
336693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
337693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic GLboolean WindowExistsFlag;
338693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
339693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr )
340693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
341693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) dpy;
342693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (xerr->error_code == BadWindow) {
343693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      WindowExistsFlag = GL_FALSE;
344693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
345693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return 0;
346693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
347693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
348693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic GLboolean window_exists( XMesaDisplay *dpy, Window win )
349693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
350693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XWindowAttributes wa;
351693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int (*old_handler)( XMesaDisplay*, XErrorEvent* );
352693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   WindowExistsFlag = GL_TRUE;
353693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   old_handler = XSetErrorHandler(window_exists_err_handler);
354693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XGetWindowAttributes( dpy, win, &wa ); /* dummy request */
355693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XSetErrorHandler(old_handler);
356693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return WindowExistsFlag;
357693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
358693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
359693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
360693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
361693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
362693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/**********************************************************************/
363693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*****                Linked list of XMesaBuffers                 *****/
364693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/**********************************************************************/
365693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
366693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic XMesaBuffer XMesaBufferList = NULL;
367693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
368693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
369693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/* Allocate a new XMesaBuffer, add to linked list */
370693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic XMesaBuffer alloc_xmesa_buffer(void)
371693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
372693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
373693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b) {
374693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->Next = XMesaBufferList;
375693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaBufferList = b;
376693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
377693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return b;
378693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
379693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
380693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
381693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
382693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Find an XMesaBuffer by matching X display and colormap but NOT matching
383693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * the notThis buffer.
384693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
385693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
386693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                     XMesaColormap cmap,
387693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                     XMesaBuffer notThis)
388693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
389693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaBuffer b;
390693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (b=XMesaBufferList; b; b=b->Next) {
391693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->display==dpy && b->cmap==cmap && b!=notThis) {
392693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return b;
393693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
394693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
395693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return NULL;
396693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
397693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
398693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
399693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
400693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Free an XMesaBuffer, remove from linked list, perhaps free X colormap
401693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * entries.
402693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
403693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic void free_xmesa_buffer(int client, XMesaBuffer buffer)
404693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
405693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaBuffer prev = NULL, b;
406693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) client;
407693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (b=XMesaBufferList; b; b=b->Next) {
408693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b==buffer) {
409693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* unlink bufer from list */
410693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (prev)
411693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            prev->Next = buffer->Next;
412693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         else
413693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            XMesaBufferList = buffer->Next;
414693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Check to free X colors */
415693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (buffer->num_alloced>0) {
416693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /* If no other buffer uses this X colormap then free the colors. */
417693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) {
418693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
419693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               (void)FreeColors(buffer->cmap, client,
420693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				buffer->num_alloced, buffer->alloced_colors,
421693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				0);
422693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
423693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               XFreeColors(buffer->display, buffer->cmap,
424693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                           buffer->alloced_colors, buffer->num_alloced, 0);
425693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
426693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            }
427693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
4281832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul
4291832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul         _mesa_free_framebuffer_data(&buffer->mesa_buffer);
430693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         FREE(buffer);
4311832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul
432693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return;
433693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
434693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* continue search */
435693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      prev = b;
436693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
437693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* buffer not found in XMesaBufferList */
43808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul   _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n");
439693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
440693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
441693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
442693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/* Copy X color table stuff from one XMesaBuffer to another. */
443693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
444693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
445693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));
446693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
447693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g));
448693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b));
449693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   dst->num_alloced = src->num_alloced;
450693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   MEMCPY(dst->alloced_colors, src->alloced_colors,
451693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          sizeof(src->alloced_colors));
452693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
453693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
454693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
455693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
456693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/**********************************************************************/
457693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*****                   Misc Private Functions                   *****/
458693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/**********************************************************************/
459693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
460693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
461693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
462693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return number of bits set in n.
463693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
464693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic int bitcount( unsigned long n )
465693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
466693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int bits;
467693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (bits=0; n>0; n=n>>1) {
468693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (n&1) {
469693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         bits++;
470693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
471693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
472693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return bits;
473693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
474693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
475693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
476693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
477693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
478693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
479693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  GL_TRUE if success, GL_FALSE if error
480693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
481693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
482693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic GLboolean alloc_shm_back_buffer( XMesaBuffer b )
483693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
484693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef USE_XSHM
485693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /*
486693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * We have to do a _lot_ of error checking here to be sure we can
487693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * really use the XSHM extension.  It seems different servers trigger
488693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * errors at different points if the extension won't work.  Therefore
489693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * we have to be very careful...
490693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
491693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GC gc;
492693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int (*old_handler)( XMesaDisplay *, XErrorEvent * );
493693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
494693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->backimage = XShmCreateImage( b->xm_visual->display,
495693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                   b->xm_visual->visinfo->visual,
496693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                   b->xm_visual->visinfo->depth,
497693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				   ZPixmap, NULL, &b->shminfo,
498693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				   b->width, b->height );
499693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->backimage == NULL) {
500693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      error("alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.");
501693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->shm = 0;
502693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_FALSE;
503693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
504693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
505693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->shminfo.shmid = shmget( IPC_PRIVATE, b->backimage->bytes_per_line
506693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			     * b->backimage->height, IPC_CREAT|0777 );
507693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->shminfo.shmid < 0) {
508693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (getenv("MESA_DEBUG"))
509693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          perror("alloc_back_buffer");
510693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XDestroyImage( b->backimage );
511693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->backimage = NULL;
512693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      error("alloc_back_buffer: Shared memory error (shmget), disabling.");
513693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->shm = 0;
514693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_FALSE;
515693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
516693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
517693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->shminfo.shmaddr = b->backimage->data
518693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                      = (char*)shmat( b->shminfo.shmid, 0, 0 );
519693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->shminfo.shmaddr == (char *) -1) {
520693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (getenv("MESA_DEBUG"))
521693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          perror("alloc_back_buffer");
522693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XDestroyImage( b->backimage );
523693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
524693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->backimage = NULL;
525693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      error("alloc_back_buffer: Shared memory error (shmat), disabling.");
526693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->shm = 0;
527693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_FALSE;
528693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
529693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
530693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->shminfo.readOnly = False;
531693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   mesaXErrorFlag = 0;
532693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   old_handler = XSetErrorHandler( mesaHandleXError );
533693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* This may trigger the X protocol error we're ready to catch: */
534693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XShmAttach( b->xm_visual->display, &b->shminfo );
535693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XSync( b->xm_visual->display, False );
536693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
537693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (mesaXErrorFlag) {
538693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* we are on a remote display, this error is normal, don't print it */
539693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XFlush( b->xm_visual->display );
540693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      mesaXErrorFlag = 0;
541693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XDestroyImage( b->backimage );
542693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      shmdt( b->shminfo.shmaddr );
543693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
544693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->backimage = NULL;
545693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->shm = 0;
546693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      (void) XSetErrorHandler( old_handler );
547693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_FALSE;
548693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
549693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
550693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */
551693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
552693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Finally, try an XShmPutImage to be really sure the extension works */
553693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   gc = XCreateGC( b->xm_visual->display, b->frontbuffer, 0, NULL );
554693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XShmPutImage( b->xm_visual->display, b->frontbuffer, gc,
555693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		 b->backimage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False );
556693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XSync( b->xm_visual->display, False );
557693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XFreeGC( b->xm_visual->display, gc );
558693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) XSetErrorHandler( old_handler );
559693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (mesaXErrorFlag) {
560693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XFlush( b->xm_visual->display );
561693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      mesaXErrorFlag = 0;
562693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XDestroyImage( b->backimage );
563693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      shmdt( b->shminfo.shmaddr );
564693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
565693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->backimage = NULL;
566693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->shm = 0;
567693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_FALSE;
568693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
569693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
570693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->backimage) {
571693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      int height = b->backimage->height;
572693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Needed by PIXELADDR1 macro */
573693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->ximage_width1 = b->backimage->bytes_per_line;
574693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->ximage_origin1 = (GLubyte *) b->backimage->data
575693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                        + b->ximage_width1 * (height-1);
576693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Needed by PIXELADDR2 macro */
577693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->ximage_width2 = b->backimage->bytes_per_line / 2;
578693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->ximage_origin2 = (GLushort *) b->backimage->data
579693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                        + b->ximage_width2 * (height-1);
580693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Needed by PIXELADDR3 macro */
581693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->ximage_width3 = b->backimage->bytes_per_line;
582693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->ximage_origin3 = (GLubyte *) b->backimage->data
583693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                        + b->ximage_width3 * (height-1);
584693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Needed by PIXELADDR4 macro */
585693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->ximage_width4 = b->backimage->width;
586693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->ximage_origin4 = (GLuint *) b->backimage->data
587693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                        + b->ximage_width4 * (height-1);
588693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
589693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
590693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_TRUE;
591693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
592693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Can't compile XSHM support */
593693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_FALSE;
594693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
595693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
596693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
597693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
598693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
599693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
600693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
601693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Setup an off-screen pixmap or Ximage to use as the back buffer.
602693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  b - the X/Mesa buffer
603693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
604693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid xmesa_alloc_back_buffer( XMesaBuffer b )
605693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
606693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->db_state==BACK_XIMAGE) {
607693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Deallocate the old backimage, if any */
608693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->backimage) {
609693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#if defined(USE_XSHM) && !defined(XFree86Server)
610693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 if (b->shm) {
611693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    XShmDetach( b->xm_visual->display, &b->shminfo );
612693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    XDestroyImage( b->backimage );
613693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    shmdt( b->shminfo.shmaddr );
614693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 }
615693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 else
616693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
617693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	   XMesaDestroyImage( b->backimage );
618693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 b->backimage = NULL;
619693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
620693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
621693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Allocate new back buffer */
622693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
623693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      {
624693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 /* Allocate a regular XImage for the back buffer. */
625693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 b->backimage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
626693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul					 b->width, b->height, NULL);
627693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
628693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->shm==0
629693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	  || alloc_shm_back_buffer(b)==GL_FALSE
630693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	  ) {
631693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 /* Allocate a regular XImage for the back buffer. */
632693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 b->backimage = XCreateImage( b->xm_visual->display,
633693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                      b->xm_visual->visinfo->visual,
634693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                      GET_VISUAL_DEPTH(b->xm_visual),
635693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				      ZPixmap, 0,   /* format, offset */
636693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				      NULL, b->width, b->height,
637693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				      8, 0 );  /* pad, bytes_per_line */
638693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
639693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 if (!b->backimage) {
640693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    error("alloc_back_buffer: XCreateImage failed.");
641693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 }
642693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         b->backimage->data = (char *) MALLOC( b->backimage->height
643693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                             * b->backimage->bytes_per_line );
644693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (!b->backimage->data) {
645693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            error("alloc_back_buffer: MALLOC failed.");
646693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            XMesaDestroyImage( b->backimage );
647693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            b->backimage = NULL;
648693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
649693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
650693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->backpixmap = None;
651693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
652693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else if (b->db_state==BACK_PIXMAP) {
653693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaPixmap old_pixmap = b->backpixmap;
654693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Free the old back pixmap */
655693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->backpixmap) {
656693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
657693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
658693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Allocate new back pixmap */
659693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->backpixmap = XMesaCreatePixmap( b->xm_visual->display, b->frontbuffer,
660693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul					 b->width, b->height,
661693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul					 GET_VISUAL_DEPTH(b->xm_visual) );
662693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->backimage = NULL;
663693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* update other references to backpixmap */
664693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->buffer==(XMesaDrawable)old_pixmap) {
665693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 b->buffer = (XMesaDrawable)b->backpixmap;
666693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
667693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
668693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
669693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
670693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
671693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
672693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
673693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * A replacement for XAllocColor.  This function should never
674693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * fail to allocate a color.  When XAllocColor fails, we return
675693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * the nearest matching color.  If we have to allocate many colors
676693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * this function isn't too efficient; the XQueryColors() could be
677693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * done just once.
678693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Written by Michael Pichler, Brian Paul, Mark Kilgard
679693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  dpy - X display
680693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         cmap - X colormap
681693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         cmapSize - size of colormap
682693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * In/Out: color - the XColor struct
683693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Output:  exact - 1=exact color match, 0=closest match
684693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *          alloced - 1=XAlloc worked, 0=XAlloc failed
685693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
686693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic void
687693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulnoFaultXAllocColor( int client,
688693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                    XMesaDisplay *dpy,
689693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                    XMesaColormap cmap,
690693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                    int cmapSize,
691693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                    XMesaColor *color,
692693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                    int *exact, int *alloced )
693693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
694693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
695693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   Pixel *ppixIn;
696693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   xrgb *ctable;
697693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
698693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* we'll try to cache ctable for better remote display performance */
699693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   static Display *prevDisplay = NULL;
700693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   static XMesaColormap prevCmap = 0;
701693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   static int prevCmapSize = 0;
702693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   static XMesaColor *ctable = NULL;
703693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
704693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaColor subColor;
705693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int i, bestmatch;
706693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   double mindist;       /* 3*2^16^2 exceeds long int precision. */
707693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
708693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) client;
709693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
710693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* First try just using XAllocColor. */
711693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
712693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (AllocColor(cmap,
713693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		  &color->red, &color->green, &color->blue,
714693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		  &color->pixel,
715693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		  client) == Success) {
716693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
717693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (XAllocColor(dpy, cmap, color)) {
718693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
719693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *exact = 1;
720693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *alloced = 1;
721693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return;
722693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
723693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
724693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Alloc failed, search for closest match */
725693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
726693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Retrieve color table entries. */
727693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* XXX alloca candidate. */
728693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
729693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel));
730693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb));
731693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (i = 0; i < cmapSize; i++) {
732693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      ppixIn[i] = i;
733693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
734693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   QueryColors(cmap, cmapSize, ppixIn, ctable);
735693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
736693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (prevDisplay != dpy || prevCmap != cmap
737693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       || prevCmapSize != cmapSize || !ctable) {
738693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* free previously cached color table */
739693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (ctable)
740693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         FREE(ctable);
741693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Get the color table from X */
742693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor));
743693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      assert(ctable);
744693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (i = 0; i < cmapSize; i++) {
745693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         ctable[i].pixel = i;
746693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
747693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XQueryColors(dpy, cmap, ctable, cmapSize);
748693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      prevDisplay = dpy;
749693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      prevCmap = cmap;
750693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      prevCmapSize = cmapSize;
751693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
752693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
753693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
754693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Find best match. */
755693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   bestmatch = -1;
756693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   mindist = 0.0;
757693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (i = 0; i < cmapSize; i++) {
758693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      double dr = 0.30 * ((double) color->red - (double) ctable[i].red);
759693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      double dg = 0.59 * ((double) color->green - (double) ctable[i].green);
760693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      double db = 0.11 * ((double) color->blue - (double) ctable[i].blue);
761693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      double dist = dr * dr + dg * dg + db * db;
762693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (bestmatch < 0 || dist < mindist) {
763693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         bestmatch = i;
764693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         mindist = dist;
765693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
766693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
767693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
768693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Return result. */
769693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   subColor.red   = ctable[bestmatch].red;
770693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   subColor.green = ctable[bestmatch].green;
771693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   subColor.blue  = ctable[bestmatch].blue;
772693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Try to allocate the closest match color.  This should only
773693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * fail if the cell is read/write.  Otherwise, we're incrementing
774693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * the cell's reference count.
775693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
776693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
777693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (AllocColor(cmap,
778693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		  &subColor.red, &subColor.green, &subColor.blue,
779693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		  &subColor.pixel,
780693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		  client) == Success) {
781693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
782693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (XAllocColor(dpy, cmap, &subColor)) {
783693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
784693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *alloced = 1;
785693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
786693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
787693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* do this to work around a problem reported by Frank Ortega */
788693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      subColor.pixel = (unsigned long) bestmatch;
789693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      subColor.red   = ctable[bestmatch].red;
790693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      subColor.green = ctable[bestmatch].green;
7915e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen      subColor.blue  = ctable[bestmatch].blue;
792693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      subColor.flags = DoRed | DoGreen | DoBlue;
793693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *alloced = 0;
794693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
795693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
796693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   FREE(ppixIn);
797693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   FREE(ctable);
798693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
799693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* don't free table, save it for next time */
800693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
801693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
802693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   *color = subColor;
803693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   *exact = 0;
804693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
805693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
806693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
807693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
808693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
809693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
810693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Do setup for PF_GRAYSCALE pixel format.
811693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Note that buffer may be NULL.
812693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
813693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic GLboolean setup_grayscale( int client, XMesaVisual v,
814693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                  XMesaBuffer buffer, XMesaColormap cmap )
815693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
816693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
817693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_FALSE;
818693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
819693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
820693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (buffer) {
821693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaBuffer prevBuffer;
822693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
823693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (!cmap) {
824693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return GL_FALSE;
825693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
826693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
827693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
828693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (prevBuffer &&
8291832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul          (buffer->xm_visual->mesa_visual.rgbMode ==
8301832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul           prevBuffer->xm_visual->mesa_visual.rgbMode)) {
831693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Copy colormap stuff from previous XMesaBuffer which uses same
832693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          * X colormap.  Do this to avoid time spent in noFaultXAllocColor.
833693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          */
834693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         copy_colortable_info(buffer, prevBuffer);
835693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
836693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
837693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Allocate 256 shades of gray */
838693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         int gray;
839693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         int colorsfailed = 0;
840693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         for (gray=0;gray<256;gray++) {
841693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            GLint r = gamma_adjust( v->RedGamma,   gray, 255 );
842693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            GLint g = gamma_adjust( v->GreenGamma, gray, 255 );
843693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            GLint b = gamma_adjust( v->BlueGamma,  gray, 255 );
844693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            int exact, alloced;
845693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            XMesaColor xcol;
846693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            xcol.red   = (r << 8) | r;
847693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            xcol.green = (g << 8) | g;
848693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            xcol.blue  = (b << 8) | b;
849693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            noFaultXAllocColor( client, v->display,
850693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                cmap, GET_COLORMAP_SIZE(v),
851693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                &xcol, &exact, &alloced );
852693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            if (!exact) {
853693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               colorsfailed++;
854693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            }
855693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            if (alloced) {
856693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               assert(buffer->num_alloced<256);
857693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
858693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               buffer->num_alloced++;
859693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            }
860693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
861693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /*OLD
862693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            assert(gray < 576);
863693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->color_table[gray*3+0] = xcol.pixel;
864693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->color_table[gray*3+1] = xcol.pixel;
865693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->color_table[gray*3+2] = xcol.pixel;
866693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            assert(xcol.pixel < 65536);
867693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->pixel_to_r[xcol.pixel] = gray * 30 / 100;
868693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->pixel_to_g[xcol.pixel] = gray * 59 / 100;
869693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->pixel_to_b[xcol.pixel] = gray * 11 / 100;
870693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            */
871693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->color_table[gray] = xcol.pixel;
872693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            assert(xcol.pixel < 65536);
873693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->pixel_to_r[xcol.pixel] = gray;
874693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->pixel_to_g[xcol.pixel] = gray;
875693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            buffer->pixel_to_b[xcol.pixel] = gray;
876693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
877693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
878693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (colorsfailed && getenv("MESA_DEBUG")) {
879693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            fprintf( stderr,
880693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  "Note: %d out of 256 needed colors do not match exactly.\n",
881693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  colorsfailed );
882693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
883693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
884693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
885693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
886693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->dithered_pf = PF_GRAYSCALE;
887693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->undithered_pf = PF_GRAYSCALE;
888693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_TRUE;
889693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
890693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
891693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
892693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
893693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
894693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Setup RGB rendering for a window with a PseudoColor, StaticColor,
895693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * or 8-bit TrueColor visual visual.  We try to allocate a palette of 225
896693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB
897693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * color.  While this function was originally designed just for 8-bit
898693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * visuals, it has also proven to work from 4-bit up to 16-bit visuals.
899693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Dithering code contributed by Bob Mercier.
900693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
901693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic GLboolean setup_dithered_color( int client, XMesaVisual v,
902693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                       XMesaBuffer buffer, XMesaColormap cmap )
903693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
904693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
905693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_FALSE;
906693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
907693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
908693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (buffer) {
909693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaBuffer prevBuffer;
910693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
911693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (!cmap) {
912693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return GL_FALSE;
913693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
914693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
915693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
916693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (prevBuffer &&
9171832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul          (buffer->xm_visual->mesa_visual.rgbMode ==
9181832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul           prevBuffer->xm_visual->mesa_visual.rgbMode)) {
919693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Copy colormap stuff from previous, matching XMesaBuffer.
920693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          * Do this to avoid time spent in noFaultXAllocColor.
921693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          */
922693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         copy_colortable_info(buffer, prevBuffer);
923693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
924693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
925693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Allocate X colors and initialize color_table[], red_table[], etc */
926693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         int r, g, b, i;
927693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         int colorsfailed = 0;
928693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         for (r = 0; r < _R; r++) {
929693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            for (g = 0; g < _G; g++) {
930693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               for (b = 0; b < _B; b++) {
931693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  XMesaColor xcol;
932693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  int exact, alloced;
933693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  xcol.red  =gamma_adjust(v->RedGamma,   r*65535/(_R-1),65535);
934693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  xcol.green=gamma_adjust(v->GreenGamma, g*65535/(_G-1),65535);
935693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  xcol.blue =gamma_adjust(v->BlueGamma,  b*65535/(_B-1),65535);
936693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  noFaultXAllocColor( client, v->display,
937693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                      cmap, GET_COLORMAP_SIZE(v),
938693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                      &xcol, &exact, &alloced );
939693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  if (!exact) {
940693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                     colorsfailed++;
941693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  }
942693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  if (alloced) {
943693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                     assert(buffer->num_alloced<256);
944693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                     buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
945693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                     buffer->num_alloced++;
946693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  }
947693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  i = _MIX( r, g, b );
948693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  assert(i < 576);
949693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  buffer->color_table[i] = xcol.pixel;
950693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  assert(xcol.pixel < 65536);
951693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  buffer->pixel_to_r[xcol.pixel] = r * 255 / (_R-1);
952693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  buffer->pixel_to_g[xcol.pixel] = g * 255 / (_G-1);
953693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  buffer->pixel_to_b[xcol.pixel] = b * 255 / (_B-1);
954693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               }
955693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            }
956693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
957693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
958693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (colorsfailed && getenv("MESA_DEBUG")) {
959693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            fprintf( stderr,
960693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  "Note: %d out of %d needed colors do not match exactly.\n",
961693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                  colorsfailed, _R*_G*_B );
962693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
963693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
964693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
965693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
966693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->dithered_pf = PF_DITHER;
967693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->undithered_pf = PF_LOOKUP;
968693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_TRUE;
969693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
970693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
971693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
972693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
973693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
974693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
975693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Special dithering tables have to be initialized.
976693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
977693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic void setup_8bit_hpcr( XMesaVisual v )
978693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
979693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* HP Color Recovery contributed by:  Alex De Bruyn (ad@lms.be)
980693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
981693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * on the root window AND the colormap obtainable by XGetRGBColormaps
982693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * for that atom must be set on the window.  (see also tkInitWindow)
983693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * If that colormap is not set, the output will look stripy.
984693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
985693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
986693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Setup color tables with gamma correction */
987693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int i;
988693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   double g;
989693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
9905e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen   g = 1.0 / v->RedGamma;
9915e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen   for (i=0; i<256; i++) {
99233143303feaf84afbef2e63ac0adab2d70b3c344Brian Paul      GLint red = IROUND_POS(255.0 * pow( hpcr_rgbTbl[0][i]/255.0, g ));
993693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->hpcr_rgbTbl[0][i] = CLAMP( red, 16, 239 );
994693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
995693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
996693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   g = 1.0 / v->GreenGamma;
997693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (i=0; i<256; i++) {
99833143303feaf84afbef2e63ac0adab2d70b3c344Brian Paul      GLint green = IROUND_POS(255.0 * pow( hpcr_rgbTbl[1][i]/255.0, g ));
999693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->hpcr_rgbTbl[1][i] = CLAMP( green, 16, 239 );
1000693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1001693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1002693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   g = 1.0 / v->BlueGamma;
1003693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (i=0; i<256; i++) {
100433143303feaf84afbef2e63ac0adab2d70b3c344Brian Paul      GLint blue = IROUND_POS(255.0 * pow( hpcr_rgbTbl[2][i]/255.0, g ));
1005693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->hpcr_rgbTbl[2][i] = CLAMP( blue, 32, 223 );
1006693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1007693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->undithered_pf = PF_HPCR;  /* can't really disable dithering for now */
1008693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->dithered_pf = PF_HPCR;
1009693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1010693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* which method should I use to clear */
1011693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* GL_FALSE: keep the ordinary method  */
1012693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* GL_TRUE : clear with dither pattern */
1013693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->hpcr_clear_flag = getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE;
1014693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1015693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (v->hpcr_clear_flag) {
1016693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display,
1017693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               DefaultRootWindow(v->display),
1018693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               16, 2, 8);
1019693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
1020693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->hpcr_clear_ximage = XGetImage(v->display, v->hpcr_clear_pixmap,
1021693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                       0, 0, 16, 2, AllPlanes, ZPixmap);
1022693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1023693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1024693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1025693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1026693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1027693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
1028693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Setup RGB rendering for a window with a True/DirectColor visual.
1029693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
1030693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
1031693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                             XMesaWindow window, XMesaColormap cmap )
1032693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1033693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   unsigned long rmask, gmask, bmask;
1034693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) buffer;
1035693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) window;
1036693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) cmap;
1037693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1038693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Compute red multiplier (mask) and bit shift */
1039693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->rshift = 0;
1040693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   rmask = GET_REDMASK(v);
1041693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   while ((rmask & 1)==0) {
1042693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->rshift++;
1043693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      rmask = rmask >> 1;
1044693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1045693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1046693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Compute green multiplier (mask) and bit shift */
1047693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->gshift = 0;
1048693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   gmask = GET_GREENMASK(v);
1049693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   while ((gmask & 1)==0) {
1050693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->gshift++;
1051693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      gmask = gmask >> 1;
1052693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1053693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1054693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Compute blue multiplier (mask) and bit shift */
1055693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->bshift = 0;
1056693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   bmask = GET_BLUEMASK(v);
1057693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   while ((bmask & 1)==0) {
1058693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->bshift++;
1059693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      bmask = bmask >> 1;
1060693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1061693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1062693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /*
1063693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * Compute component-to-pixel lookup tables and dithering kernel
1064693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
1065693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   {
1066693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      static GLubyte kernel[16] = {
1067693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          0*16,  8*16,  2*16, 10*16,
1068693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         12*16,  4*16, 14*16,  6*16,
1069693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          3*16, 11*16,  1*16,  9*16,
1070693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         15*16,  7*16, 13*16,  5*16,
1071693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      };
1072693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      GLint rBits = bitcount(rmask);
1073693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      GLint gBits = bitcount(gmask);
1074693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      GLint bBits = bitcount(bmask);
10753cbbef53bcf9a74beec3d6699a03e8d0c2eb24e2Brian Paul      GLint maxBits;
1076693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      GLuint i;
1077693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1078693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* convert pixel components in [0,_mask] to RGB values in [0,255] */
1079693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (i=0; i<=rmask; i++)
1080693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         v->PixelToR[i] = (unsigned char) ((i * 255) / rmask);
1081693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (i=0; i<=gmask; i++)
1082693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         v->PixelToG[i] = (unsigned char) ((i * 255) / gmask);
1083693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (i=0; i<=bmask; i++)
1084693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         v->PixelToB[i] = (unsigned char) ((i * 255) / bmask);
1085693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1086693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* convert RGB values from [0,255] to pixel components */
1087693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1088693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (i=0;i<256;i++) {
1089693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         GLint r = gamma_adjust(v->RedGamma,   i, 255);
1090693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         GLint g = gamma_adjust(v->GreenGamma, i, 255);
1091693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         GLint b = gamma_adjust(v->BlueGamma,  i, 255);
1092693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         v->RtoPixel[i] = (r >> (8-rBits)) << v->rshift;
1093693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         v->GtoPixel[i] = (g >> (8-gBits)) << v->gshift;
1094693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         v->BtoPixel[i] = (b >> (8-bBits)) << v->bshift;
1095693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1096693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* overflow protection */
1097693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (i=256;i<512;i++) {
1098693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         v->RtoPixel[i] = v->RtoPixel[255];
1099693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         v->GtoPixel[i] = v->GtoPixel[255];
1100693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         v->BtoPixel[i] = v->BtoPixel[255];
1101693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1102693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1103693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* setup dithering kernel */
11043cbbef53bcf9a74beec3d6699a03e8d0c2eb24e2Brian Paul      maxBits = rBits;
11053cbbef53bcf9a74beec3d6699a03e8d0c2eb24e2Brian Paul      if (gBits > maxBits)  maxBits = gBits;
11063cbbef53bcf9a74beec3d6699a03e8d0c2eb24e2Brian Paul      if (bBits > maxBits)  maxBits = bBits;
1107693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (i=0;i<16;i++) {
11083cbbef53bcf9a74beec3d6699a03e8d0c2eb24e2Brian Paul         v->Kernel[i] = kernel[i] >> maxBits;
1109693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1110693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1111693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->undithered_pf = PF_TRUECOLOR;
1112693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_TRUEDITHER : PF_TRUECOLOR;
1113693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1114693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1115693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /*
1116693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * Now check for TrueColor visuals which we can optimize.
1117693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
1118693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (   GET_REDMASK(v)  ==0x0000ff
1119693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && GET_GREENMASK(v)==0x00ff00
1120693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && GET_BLUEMASK(v) ==0xff0000
1121693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && CHECK_BYTE_ORDER(v)
1122693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && v->BitsPerPixel==32
1123693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && sizeof(GLuint)==4
1124693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1125693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* common 32 bpp config used on SGI, Sun */
1126693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->undithered_pf = v->dithered_pf = PF_8A8B8G8R;
1127693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1128693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else if (GET_REDMASK(v)  ==0xff0000
1129693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       &&   GET_GREENMASK(v)==0x00ff00
1130693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       &&   GET_BLUEMASK(v) ==0x0000ff
1131693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && CHECK_BYTE_ORDER(v)
1132693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && v->BitsPerPixel==32
1133693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && sizeof(GLuint)==4
1134693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1135693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* common 32 bpp config used on Linux, HP, IBM */
1136693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->undithered_pf = v->dithered_pf = PF_8R8G8B;
1137693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1138693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else if (GET_REDMASK(v)  ==0xff0000
1139693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       &&   GET_GREENMASK(v)==0x00ff00
1140693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       &&   GET_BLUEMASK(v) ==0x0000ff
1141693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && CHECK_BYTE_ORDER(v)
1142693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && v->BitsPerPixel==24
1143693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && sizeof(GLuint)==4
1144693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1145693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* common packed 24 bpp config used on Linux */
1146693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->undithered_pf = v->dithered_pf = PF_8R8G8B24;
1147693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1148693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else if (GET_REDMASK(v)  ==0xf800
1149693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       &&   GET_GREENMASK(v)==0x07e0
1150693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       &&   GET_BLUEMASK(v) ==0x001f
1151693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && CHECK_BYTE_ORDER(v)
1152693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && v->BitsPerPixel==16
1153693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && sizeof(GLushort)==2
1154693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1155693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* 5-6-5 color weight on common PC VGA boards */
1156693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->undithered_pf = PF_5R6G5B;
1157693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->dithered_pf = PF_DITHER_5R6G5B;
1158693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1159693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else if (GET_REDMASK(v)  ==0xe0
1160693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       &&   GET_GREENMASK(v)==0x1c
1161693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       &&   GET_BLUEMASK(v) ==0x03
1162693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       && CHECK_FOR_HPCR(v)) {
1163693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      setup_8bit_hpcr( v );
1164693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1165693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1166693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1167693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1168693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1169693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
1170693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Setup RGB rendering for a window with a monochrome visual.
1171693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
1172693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic void setup_monochrome( XMesaVisual v, XMesaBuffer b )
1173693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1174693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) b;
1175693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->dithered_pf = v->undithered_pf = PF_1BIT;
1176693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* if black=1 then we must flip pixel values */
1177693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->bitFlip = (GET_BLACK_PIXEL(v) != 0);
1178693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1179693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1180693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1181693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1182693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
1183693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * When a context is "made current" for the first time, we can finally
1184693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * finish initializing the context's visual and buffer information.
1185693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  v - the XMesaVisual to initialize
1186693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         b - the XMesaBuffer to initialize (may be NULL)
1187693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         rgb_flag - TRUE = RGBA mode, FALSE = color index mode
1188693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         window - the window/pixmap we're rendering into
1189693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         cmap - the colormap associated with the window/pixmap
1190693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  GL_TRUE=success, GL_FALSE=failure
1191693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
1192693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic GLboolean initialize_visual_and_buffer( int client,
1193693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               XMesaVisual v,
1194693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               XMesaBuffer b,
1195693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               GLboolean rgb_flag,
1196693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               XMesaDrawable window,
1197693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               XMesaColormap cmap
1198693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                             )
1199693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1200693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
1201693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XGCValues gcvalues;
1202693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1203693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1204693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b) {
1205693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      assert(b->xm_visual == v);
1206693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1207693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1208693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Save true bits/pixel */
1209693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->BitsPerPixel = GET_BITS_PER_PIXEL(v);
1210693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   assert(v->BitsPerPixel > 0);
1211693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1212693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1213693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (rgb_flag==GL_FALSE) {
1214693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* COLOR-INDEXED WINDOW:
1215693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * Even if the visual is TrueColor or DirectColor we treat it as
1216693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * being color indexed.  This is weird but might be useful to someone.
1217693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       */
1218693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->dithered_pf = v->undithered_pf = PF_INDEX;
1219693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->index_bits = GET_VISUAL_DEPTH(v);
1220693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1221693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
1222693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* RGB WINDOW:
1223693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * We support RGB rendering into almost any kind of visual.
1224693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       */
1225693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      int xclass;
1226693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      xclass = GET_VISUAL_CLASS(v);
1227693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (xclass==TrueColor || xclass==DirectColor) {
1228693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 setup_truecolor( v, b, (XMesaWindow)window, cmap );
1229693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1230693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else if (xclass==StaticGray && GET_VISUAL_DEPTH(v)==1) {
1231693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 setup_monochrome( v, b );
1232693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1233693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else if (xclass==GrayScale || xclass==StaticGray) {
1234693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (!setup_grayscale( client, v, b, cmap )) {
1235693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return GL_FALSE;
1236693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
1237693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1238693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else if ((xclass==PseudoColor || xclass==StaticColor)
1239693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               && GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) {
1240693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 if (!setup_dithered_color( client, v, b, cmap )) {
1241693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return GL_FALSE;
1242693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
1243693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1244693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
1245693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 error("XMesa: RGB mode rendering not supported in given visual.");
1246693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 return GL_FALSE;
1247693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1248693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->index_bits = 0;
1249693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1250693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (getenv("MESA_NO_DITHER")) {
1251693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 v->dithered_pf = v->undithered_pf;
1252693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1253693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1254693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1255693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1256693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /*
1257693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * If MESA_INFO env var is set print out some debugging info
1258693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * which can help Brian figure out what's going on when a user
1259693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * reports bugs.
1260693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
1261693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (getenv("MESA_INFO")) {
1262693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr, "X/Mesa visual = %p\n", v);
1263693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr, "X/Mesa dithered pf = %u\n", v->dithered_pf);
1264693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr, "X/Mesa undithered pf = %u\n", v->undithered_pf);
1265693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr, "X/Mesa level = %d\n", v->level);
1266693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr, "X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v));
1267693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr, "X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
1268693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1269693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1270693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b && window) {
1271693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Do window-specific initializations */
1272693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1273693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Window dimensions */
1274693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      unsigned int w, h;
1275693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      get_drawable_size( v->display, window, &w, &h );
1276693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->width = w;
1277693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->height = h;
1278693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1279693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->frontbuffer = window;
1280693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1281693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Setup for single/double buffering */
12821832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul      if (v->mesa_visual.doubleBufferMode) {
1283693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Double buffered */
1284693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
1285693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         b->shm = check_for_xshm( v->display );
1286693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1287693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         xmesa_alloc_back_buffer( b );
1288693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (b->db_state==BACK_PIXMAP) {
1289693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            b->buffer = (XMesaDrawable)b->backpixmap;
1290693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
1291693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         else {
1292693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            b->buffer = XIMAGE;
1293693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
1294693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1295693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
1296693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Single Buffered */
1297693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         b->buffer = b->frontbuffer;
1298693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1299693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1300693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* X11 graphics contexts */
1301693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1302c19d783e0715ac01ad4d3fd0705500d2bf6f7039Brian Paul      b->gc = CreateScratchGC(v->display, window->depth);
1303693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
1304c19d783e0715ac01ad4d3fd0705500d2bf6f7039Brian Paul      b->gc = XCreateGC( v->display, window, 0, NULL );
1305693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1306c19d783e0715ac01ad4d3fd0705500d2bf6f7039Brian Paul      XMesaSetFunction( v->display, b->gc, GXcopy );
1307693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1308693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /*
1309693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * Don't generate Graphics Expose/NoExpose events in swapbuffers().
1310693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * Patch contributed by Michael Pichler May 15, 1995.
1311693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       */
1312693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1313693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->cleargc = CreateScratchGC(v->display, window->depth);
1314693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      {
1315693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	  CARD32 v[1];
1316693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	  v[0] = FALSE;
1317693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	  dixChangeGC(NullClient, b->cleargc, GCGraphicsExposures, v, NULL);
1318693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1319693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
1320693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      gcvalues.graphics_exposures = False;
1321693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->cleargc = XCreateGC( v->display, window,
1322693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                              GCGraphicsExposures, &gcvalues);
1323693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1324693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaSetFunction( v->display, b->cleargc, GXcopy );
1325693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /*
1326693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * Set fill style and tile pixmap once for all for HPCR stuff
1327693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * (instead of doing it each time in clear_color_HPCR_pixmap())
1328693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * Initialize whole stuff
1329693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * Patch contributed by Jacques Leroy March 8, 1998.
1330693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       */
1331693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (v->hpcr_clear_flag && b->buffer!=XIMAGE) {
1332693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	int i;
1333693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	for (i=0; i<16; i++)
1334693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul        {
1335693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	   XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0);
1336693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	   XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0);
1337693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul        }
1338693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul        XMesaPutImage(b->display, (XMesaDrawable)v->hpcr_clear_pixmap,
1339693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		      b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2);
1340693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	XMesaSetFillStyle( v->display, b->cleargc, FillTiled);
1341693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap );
1342693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1343693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1344693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Initialize the row buffer XImage for use in write_color_span() */
1345693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1346693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1,
1347693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				     (char *)MALLOC(MAX_WIDTH*4));
1348693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
1349693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->rowimage = XCreateImage( v->display,
1350693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                  v->visinfo->visual,
1351693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                  v->visinfo->depth,
1352693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                  ZPixmap, 0,           /*format, offset*/
1353693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                  (char*) MALLOC(MAX_WIDTH*4),  /*data*/
1354693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                  MAX_WIDTH, 1,         /*width, height*/
1355693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                  32,                   /*bitmap_pad*/
1356693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                  0                     /*bytes_per_line*/ );
1357693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1358693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1359693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1360693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_TRUE;
1361693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1362693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1363693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1364693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1365693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
1366693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Convert an RGBA color to a pixel value.
1367693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
1368693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulunsigned long
1369693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulxmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLubyte a,
1370693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                      GLuint pixelFormat)
1371693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1372693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   switch (pixelFormat) {
1373693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_INDEX:
1374693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return 0;
1375693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_TRUECOLOR:
1376693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
1377693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            unsigned long p;
1378693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            PACK_TRUECOLOR( p, r, g, b );
1379693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return p;
1380693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
1381693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_8A8B8G8R:
1382693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return PACK_8A8B8G8R( r, g, b, a );
1383693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_8R8G8B:
1384693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* fall through */
1385693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_8R8G8B24:
1386693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return PACK_8R8G8B( r, g, b );
1387693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_5R6G5B:
1388693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return PACK_5R6G5B( r, g, b );
1389693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_DITHER:
1390693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
1391693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            DITHER_SETUP;
1392693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return DITHER( 1, 0, r, g, b );
1393693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
1394693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_1BIT:
1395693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* 382 = (3*255)/2 */
1396693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
1397693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_HPCR:
1398693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return DITHER_HPCR(1, 1, r, g, b);
1399693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_LOOKUP:
1400693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
1401693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            LOOKUP_SETUP;
1402693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return LOOKUP( r, g, b );
1403693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
1404693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_GRAYSCALE:
1405693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return GRAY_RGB( r, g, b );
1406693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_TRUEDITHER:
1407693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* fall through */
1408693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_DITHER_5R6G5B:
1409693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
1410693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            unsigned long p;
1411693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            PACK_TRUEDITHER(p, 1, 0, r, g, b);
1412693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return p;
1413693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
1414693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      default:
141508836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_problem(NULL, "Bad pixel format in xmesa_color_to_pixel");
1416693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1417693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return 0;
1418693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1419693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1420693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1421693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/**********************************************************************/
1422693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*****                       Public Functions                     *****/
1423693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/**********************************************************************/
1424693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1425693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1426693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
1427693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Create a new X/Mesa visual.
1428693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  display - X11 display
1429693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         visinfo - an XVisualInfo pointer
1430693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         rgb_flag - GL_TRUE = RGB mode,
1431693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *                    GL_FALSE = color index mode
1432693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         alpha_flag - alpha buffer requested?
1433693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         db_flag - GL_TRUE = double-buffered,
1434693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *                   GL_FALSE = single buffered
1435693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         stereo_flag - stereo visual?
1436693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         ximage_flag - GL_TRUE = use an XImage for back buffer,
1437693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *                       GL_FALSE = use an off-screen pixmap for back buffer
1438693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         depth_size - requested bits/depth values, or zero
1439693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         stencil_size - requested bits/stencil values, or zero
1440693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         accum_red_size - requested bits/red accum values, or zero
1441693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         accum_green_size - requested bits/green accum values, or zero
1442693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         accum_blue_size - requested bits/blue accum values, or zero
1443693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         accum_alpha_size - requested bits/alpha accum values, or zero
1444693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         num_samples - number of samples/pixel if multisampling, or zero
1445693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         level - visual level, usually 0
1446693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         visualCaveat - ala the GLX extension, usually GLX_NONE_EXT
1447693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return;  a new XMesaVisual or 0 if error.
1448693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
1449693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulXMesaVisual XMesaCreateVisual( XMesaDisplay *display,
1450693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               XMesaVisualInfo visinfo,
1451693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLboolean rgb_flag,
1452693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLboolean alpha_flag,
1453693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLboolean db_flag,
1454693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLboolean stereo_flag,
1455693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLboolean ximage_flag,
1456693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint depth_size,
1457693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint stencil_size,
1458693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint accum_red_size,
1459693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint accum_green_size,
1460693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint accum_blue_size,
1461693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint accum_alpha_size,
1462693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint num_samples,
1463693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint level,
1464693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint visualCaveat )
1465693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1466693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   char *gamma;
1467693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaVisual v;
1468693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GLint red_bits, green_bits, blue_bits, alpha_bits;
1469693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1470693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* For debugging only */
1471693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (getenv("MESA_XSYNC")) {
1472693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* This makes debugging X easier.
1473693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * In your debugger, set a breakpoint on _XError to stop when an
1474693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       * X protocol error is generated.
1475693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       */
1476693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1477693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* NOT_NEEDED */
1478693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
1479693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XSynchronize( display, 1 );
1480693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1481693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1482693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1483693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual);
1484693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (!v) {
1485693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
1486693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1487693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1488693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /*
1489693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * In the X server, NULL is passed in for the display.  It will have
1490693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * to be set before using this visual.  See XMesaSetVisualDisplay()
1491693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * below.
1492693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
1493693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->display = display;
1494693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1495693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Save a copy of the XVisualInfo struct because the user may XFREE()
1496693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * the struct but we may need some of the information contained in it
1497693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * at a later time.
1498693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
1499693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1500693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->visinfo = visinfo;
1501693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
1502693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
1503693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if(!v->visinfo) {
1504693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      FREE(v);
1505693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
1506693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1507693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
1508693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1509693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Save a copy of the pointer now so we can find this visual again
1510693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * if we need to search for it in find_glx_visual().
1511693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
1512693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->vishandle = visinfo;
1513693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1514693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1515693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1516693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Initialize the depth of the screen */
1517693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   {
1518693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       PixmapFormatRec *format;
1519693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1520693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       for (format = screenInfo.formats;
1521693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    format->depth != display->rootDepth;
1522693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    format++)
1523693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	   ;
1524693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       v->screen_depth = format->bitsPerPixel;
1525693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1526693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1527693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1528693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* check for MESA_GAMMA environment variable */
1529693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   gamma = getenv("MESA_GAMMA");
1530693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (gamma) {
1531693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0;
1532693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma );
1533693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (v->RedGamma<=0.0)    v->RedGamma = 1.0;
1534693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (v->GreenGamma<=0.0)  v->GreenGamma = v->RedGamma;
1535693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (v->BlueGamma<=0.0)   v->BlueGamma = v->RedGamma;
1536693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1537693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
1538693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0;
1539693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1540693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1541693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->ximage_flag = ximage_flag;
1542693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->level = level;
1543693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   v->VisualCaveat = visualCaveat;
1544693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1545693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 );
1546693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1547693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   {
1548693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      int xclass;
1549693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      xclass = GET_VISUAL_CLASS(v);
1550693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (xclass==TrueColor || xclass==DirectColor) {
1551693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         red_bits   = bitcount(GET_REDMASK(v));
1552693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         green_bits = bitcount(GET_GREENMASK(v));
1553693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         blue_bits  = bitcount(GET_BLUEMASK(v));
1554693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         alpha_bits = 0;
1555693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1556693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
1557693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* this is an approximation */
1558693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         int depth;
1559693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         depth = GET_VISUAL_DEPTH(v);
1560693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         red_bits = depth / 3;
1561693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         depth -= red_bits;
1562693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         green_bits = depth / 2;
1563693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         depth -= green_bits;
1564693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         blue_bits = depth;
1565693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         alpha_bits = 0;
1566693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) );
1567693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1568693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1569693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1570693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (alpha_flag && alpha_bits == 0)
1571693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      alpha_bits = 8;
1572693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
15731832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul   _mesa_initialize_visual( &v->mesa_visual,
15741832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                            rgb_flag, db_flag, stereo_flag,
15751832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                            red_bits, green_bits,
15761832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                            blue_bits, alpha_bits,
15771832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                            v->index_bits,
15781832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                            depth_size,
15791832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                            stencil_size,
15801832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                            accum_red_size, accum_green_size,
15811832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                            accum_blue_size, accum_alpha_size,
15821832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                            0 );
1583693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return v;
1584693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1585693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1586693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1587693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v )
1588693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1589693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    v->display = dpy;
1590693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1591693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1592693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1593693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid XMesaDestroyVisual( XMesaVisual v )
1594693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1595693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
1596693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   FREE(v->visinfo);
1597693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1598693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   FREE(v);
1599693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1600693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1601693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1602693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1603693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
1604693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Create a new XMesaContext.
1605693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  v - XMesaVisual
1606693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         share_list - another XMesaContext with which to share display
1607693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *                      lists or NULL if no sharing is wanted.
1608693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  an XMesaContext or NULL if error.
1609693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
16107a1f3a37a10b162b067239dafa19fc6865a41f14Keith WhitwellXMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
1611693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1612693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaContext c;
1613ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell   GLcontext *ctx;
1614693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GLboolean direct = GL_TRUE; /* XXXX */
1615693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* NOT_DONE: should this be GL_FALSE??? */
1616693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   static GLboolean firstTime = GL_TRUE;
1617693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1618693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (firstTime) {
1619693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      _glthread_INIT_MUTEX(_xmesa_lock);
1620693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      firstTime = GL_FALSE;
1621693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1622693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1623693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
1624693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (!c) {
1625693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
1626693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1627693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
16281832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul   ctx = c->gl_ctx = _mesa_create_context( &v->mesa_visual,
16297a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell                      share_list ? share_list->gl_ctx : (GLcontext *) NULL,
16307a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell                      (void *) c, direct );
1631693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (!c->gl_ctx) {
1632693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      FREE(c);
1633693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
1634693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1635693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
16365a9026c65d260dc185e072163999f5d810015108Brian Paul   _mesa_enable_sw_extensions(ctx);
1637693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1638693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (CHECK_BYTE_ORDER(v)) {
1639693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      c->swapbytes = GL_FALSE;
1640693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1641693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
1642693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      c->swapbytes = GL_TRUE;
1643693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1644693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1645693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   c->xm_visual = v;
1646693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
1647693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   c->display = v->display;
1648693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   c->pixelformat = v->dithered_pf;      /* Dithering is enabled by default */
1649693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1650ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell   ctx->Driver.UpdateState = xmesa_update_state;
1651a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell
1652ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell   /* Initialize the software rasterizer and helper modules.
1653ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell    */
1654ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell   _swrast_CreateContext( ctx );
1655cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   _ac_CreateContext( ctx );
165623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell   _tnl_CreateContext( ctx );
1657cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   _swsetup_CreateContext( ctx );
1658ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell
1659ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell   xmesa_register_swrast_functions( ctx );
1660ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell
1661709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   /* Set up some constant pointers:
1662709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell    */
1663709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   xmesa_init_pointers( ctx );
1664709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell
1665709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell
16665e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen   /* Run the config file
1667ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell    */
16689e351d52ae52927fbe505e8808e70de3e646be79Brian Paul   _mesa_read_config_file( ctx );
1669ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell
16707a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell
16717a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell   return c;
1672693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1673693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1674693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1675693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1676693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1677693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid XMesaDestroyContext( XMesaContext c )
1678693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1679693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef FX
1680693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (c->xm_buffer && c->xm_buffer->FXctx)
1681693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fxMesaDestroyContext(c->xm_buffer->FXctx);
1682693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1683ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell   if (c->gl_ctx) {
1684ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell      _swsetup_DestroyContext( c->gl_ctx );
1685ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell      _swrast_DestroyContext( c->gl_ctx );
1686709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell      _tnl_DestroyContext( c->gl_ctx );
1687709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell      _ac_DestroyContext( c->gl_ctx );
1688b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul      _mesa_destroy_context( c->gl_ctx );
1689ec0585883a85a495d94e24970d64e5d6fc889147Keith Whitwell   }
1690693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1691693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Disassociate old buffer with this context */
1692693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (c->xm_buffer)
1693693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       c->xm_buffer->xm_context = NULL;
1694693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1695693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* Destroy any buffers which are using this context.  If we don't
1696693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * we may have dangling references.  Hmm, maybe we should just
1697693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * set the buffer's context pointer to NULL instead of deleting it?
1698693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * Let's see if we get any bug reports...
1699693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * This contributed by Doug Rabson <dfr@calcaphon.com>
1700693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
1701693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   {
1702693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaBuffer b, next;
1703693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (b = XMesaBufferList; b; b = next) {
1704693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         next = b->Next;
1705693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (!b->pixmap_flag) {
1706693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
1707693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            XSync(b->display, False);
1708693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1709693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            if (b->xm_context == c) {
1710693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               /* found a context created for this context */
1711693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul               XMesaDestroyBuffer( b );
1712693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            }
1713693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
1714693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1715693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1716693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1717693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   FREE( c );
1718693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1719693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1720693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1721693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1722693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
1723693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * XXX this isn't a public function!  It's a hack for the 3Dfx driver.
1724693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Create a new XMesaBuffer from an X window.
1725693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  v - the XMesaVisual
1726693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         w - the window
1727693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         c - the context
1728693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  new XMesaBuffer or NULL if error
1729693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
1730693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulXMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v, XMesaWindow w,
1731693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                      XMesaContext c )
1732693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1733693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifndef XFree86Server
1734693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XWindowAttributes attr;
1735693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1736693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef FX
1737693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   char *fxEnvVar;
1738693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1739693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int client = 0;
1740693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1741693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaBuffer b = alloc_xmesa_buffer();
1742693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (!b) {
1743693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
1744693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1745693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1746693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) c;
1747693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1748693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1749693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   client = CLIENT_ID(((XMesaDrawable)w)->id);
1750693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1751693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1752693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   assert(v);
1753693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1754693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
17557a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell   if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) {
1756693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
17577a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell   XGetWindowAttributes( v->display, w, &attr );
17587a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell
17597a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell   if (GET_VISUAL_DEPTH(v) != attr.depth) {
1760693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1761693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (getenv("MESA_DEBUG")) {
1762693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         fprintf(stderr, "XMesaCreateWindowBuffer: depth mismatch between visual and window!\n");
1763693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1764693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
1765693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1766693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1767693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->xm_context = NULL; /* Associate no context with this buffer */
1768693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1769693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->xm_visual = v;
1770693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->pixmap_flag = GL_FALSE;
1771693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->display = v->display;
1772693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1773693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
1774693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
1775693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (attr.colormap) {
1776693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->cmap = attr.colormap;
1777693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1778693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
1779693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (getenv("MESA_DEBUG")) {
1780693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         fprintf(stderr, "Window %u has no colormap!\n", (unsigned int) w);
1781693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1782693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* this is weird, a window w/out a colormap!? */
1783693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* OK, let's just allocate a new one and hope for the best */
1784693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
1785693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1786693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1787693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1788693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* determine back buffer implementation */
17891832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul   if (v->mesa_visual.doubleBufferMode) {
1790693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (v->ximage_flag) {
1791693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 b->db_state = BACK_XIMAGE;
1792693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1793693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
1794693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 b->db_state = BACK_PIXMAP;
1795693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1796693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1797693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
1798693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->db_state = 0;
1799693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1800693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
18011832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul   _mesa_initialize_framebuffer(&b->mesa_buffer,
18021832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                &v->mesa_visual,
18031832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.depthBits > 0,
18041832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.stencilBits > 0,
18051832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.accumRedBits > 0,
18061832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.alphaBits > 0 );
1807693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
18081832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul   if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
1809693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                      (XMesaDrawable)w, b->cmap )) {
1810693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      free_xmesa_buffer(client, b);
1811693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
1812693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1813693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1814693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef FX
1815693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   fxEnvVar = getenv("MESA_GLX_FX");
1816693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (fxEnvVar) {
18177a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell     if (fxEnvVar[0]!='d') {
18187a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       int attribs[100];
18197a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       int numAttribs = 0;
18207a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       int hw;
18211832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul       if (v->mesa_visual.depthBits > 0) {
18227a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	 attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
18237a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	 attribs[numAttribs++] = 1;
18247a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       }
18251832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul       if (v->mesa_visual.doubleBufferMode) {
18267a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	 attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
18277a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       }
18281832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul       if (v->mesa_visual.accumRedBits > 0) {
18297a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	 attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
18301832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul	 attribs[numAttribs++] = v->mesa_visual.accumRedBits;
18317a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       }
18321832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul       if (v->mesa_visual.stencilBits > 0) {
18337a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
18341832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul         attribs[numAttribs++] = v->mesa_visual.stencilBits;
18357a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       }
18361832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul       if (v->mesa_visual.alphaBits > 0) {
18377a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
18387a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         attribs[numAttribs++] = 1;
18397a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       }
18407a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       if (c->gl_ctx) {
1841693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#define FXMESA_SHARE_CONTEXT 990099  /* keep in sync with fxapi.c! */
18427a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
18437a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         attribs[numAttribs++] = (int) c->gl_ctx;
18447a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       }
18457a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       attribs[numAttribs++] = FXMESA_NONE;
18467a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell
18477a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       if ((hw = fxQueryHardware())==GR_SSTTYPE_VOODOO) {
18487a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
18497a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         if ((v->undithered_pf!=PF_INDEX) && (b->backimage)) {
18507a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	   b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
18517a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	   if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
18527a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	     b->FXwindowHack = b->FXctx ? GL_TRUE : GL_FALSE;
18537a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	   else
18547a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	     b->FXwindowHack = GL_FALSE;
18557a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         }
18567a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       }
18577a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       else {
18587a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
18597a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	   b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
18607a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell					  GR_REFRESH_75Hz, attribs);
18617a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         else
18627a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell	   b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
18637a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         b->FXisHackUsable = GL_FALSE;
18647a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell         b->FXwindowHack = GL_FALSE;
18657a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       }
18667a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       /*
18677a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       fprintf(stderr,
18687a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell               "voodoo %d, wid %d height %d hack: usable %d active %d\n",
18697a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell               hw, b->width, b->height, b->FXisHackUsable, b->FXwindowHack);
18707a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell       */
18717a1f3a37a10b162b067239dafa19fc6865a41f14Keith Whitwell     }
1872693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1873693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
1874693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr,"WARNING: This Mesa Library includes the Glide driver but\n");
1875693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr,"         you have not defined the MESA_GLX_FX env. var.\n");
1876693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr,"         (check the README.3DFX file for more information).\n\n");
1877693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      fprintf(stderr,"         you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
1878693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1879693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1880693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1881693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return b;
1882693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1883693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1884693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1885693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulXMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, XMesaWindow w )
1886693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1887693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return XMesaCreateWindowBuffer2( v, w, NULL );
1888693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1889693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1890693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1891693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
1892693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Create a new XMesaBuffer from an X pixmap.
1893693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  v - the XMesaVisual
1894693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         p - the pixmap
1895693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *         cmap - the colormap, may be 0 if using a TrueColor or DirectColor
1896693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *                visual for the pixmap
1897693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  new XMesaBuffer or NULL if error
1898693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
1899693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulXMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
1900693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				     XMesaPixmap p, XMesaColormap cmap )
1901693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1902693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int client = 0;
1903693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaBuffer b = alloc_xmesa_buffer();
1904693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (!b) {
1905693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
1906693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1907693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1908693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1909693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1910693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   client = CLIENT_ID(((XMesaDrawable)p)->id);
1911693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1912693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1913693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   assert(v);
1914693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1915693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->xm_context = NULL; /* Associate no context with this buffer */
1916693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1917693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->xm_visual = v;
1918693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->pixmap_flag = GL_TRUE;
1919693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->display = v->display;
1920693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   b->cmap = cmap;
1921693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1922693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* determine back buffer implementation */
19231832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul   if (v->mesa_visual.doubleBufferMode) {
1924693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (v->ximage_flag) {
1925693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 b->db_state = BACK_XIMAGE;
1926693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1927693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
1928693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 b->db_state = BACK_PIXMAP;
1929693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1930693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1931693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
1932693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->db_state = 0;
1933693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1934693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
19351832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul   _mesa_initialize_framebuffer(&b->mesa_buffer,
19361832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                &v->mesa_visual,
19371832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.depthBits > 0,
19381832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.stencilBits > 0,
19391832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.accumRedBits +
19401832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.accumGreenBits +
19411832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.accumBlueBits > 0,
19421832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                                v->mesa_visual.alphaBits > 0 );
1943693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
19441832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul   if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
1945693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul				     (XMesaDrawable)p, cmap)) {
1946693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      free_xmesa_buffer(client, b);
1947693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
1948693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1949693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1950693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return b;
1951693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
1952693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1953693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1954693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1955693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
1956693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Deallocate an XMesaBuffer structure and all related info.
1957693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
1958693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid XMesaDestroyBuffer( XMesaBuffer b )
1959693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
1960693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   int client = 0;
1961693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1962693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
1963693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->frontbuffer)
1964693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       client = CLIENT_ID(b->frontbuffer->id);
1965693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1966693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1967c19d783e0715ac01ad4d3fd0705500d2bf6f7039Brian Paul   if (b->gc)  XMesaFreeGC( b->xm_visual->display, b->gc );
1968693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->cleargc)  XMesaFreeGC( b->xm_visual->display, b->cleargc );
1969693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1970693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->backimage) {
1971693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#if defined(USE_XSHM) && !defined(XFree86Server)
1972693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       if (b->shm) {
1973693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	   XShmDetach( b->xm_visual->display, &b->shminfo );
1974693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	   XDestroyImage( b->backimage );
1975693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	   shmdt( b->shminfo.shmaddr );
1976693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       }
1977693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       else
1978693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
1979693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	   XMesaDestroyImage( b->backimage );
1980693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1981693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->backpixmap) {
1982693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
1983693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->xm_visual->hpcr_clear_flag) {
1984693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	XMesaFreePixmap( b->xm_visual->display,
1985693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			 b->xm_visual->hpcr_clear_pixmap );
1986693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage );
1987693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
1988693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1989693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->rowimage) {
1990693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      FREE( b->rowimage->data );
1991693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->rowimage->data = NULL;
1992693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaDestroyImage( b->rowimage );
1993693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
1994693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1995693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->xm_context)
1996693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul       b->xm_context->xm_buffer = NULL;
1997693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
1998693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   free_xmesa_buffer(client, b);
1999693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2000693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2001693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2002693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2003693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2004693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Bind buffer b to context c and make c the current rendering context.
2005693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2006693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulGLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b )
2007693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2008693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return XMesaMakeCurrent2( c, b, b );
2009693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2010693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2011693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2012693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2013693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Bind buffer b to context c and make c the current rendering context.
2014693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2015693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulGLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
2016693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                             XMesaBuffer readBuffer )
2017693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2018693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (c) {
2019693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (!drawBuffer || !readBuffer)
2020693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return GL_FALSE;  /* must specify buffers! */
2021693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2022693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef FX
2023693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (drawBuffer->FXctx) {
2024693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         fxMesaMakeCurrent(drawBuffer->FXctx);
2025693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2026693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Disassociate old buffer from this context */
2027693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (c->xm_buffer)
2028693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            c->xm_buffer->xm_context = NULL;
2029693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2030693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Associate the context with this buffer */
2031693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         drawBuffer->xm_context = c;
2032693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2033693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         c->xm_buffer = drawBuffer;
2034693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         c->xm_read_buffer = readBuffer;
2035693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         c->use_read_buffer = (drawBuffer != readBuffer);
2036693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2037693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return GL_TRUE;
2038693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2039693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2040b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul      if (c->gl_ctx == _mesa_get_current_context()
2041693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          && c->xm_buffer == drawBuffer
2042693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          && c->xm_read_buffer == readBuffer
2043693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          && c->xm_buffer->wasCurrent) {
2044693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* same context and buffer, do nothing */
2045693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return GL_TRUE;
2046693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2047693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2048693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Disassociate old buffer with this context */
2049693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (c->xm_buffer)
2050693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	  c->xm_buffer->xm_context = NULL;
2051693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      drawBuffer->xm_context = c; /* Associate the context with this buffer */
2052693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2053693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      c->xm_buffer = drawBuffer;
2054693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      c->xm_read_buffer = readBuffer;
2055693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      c->use_read_buffer = (drawBuffer != readBuffer);
2056693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
20571832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul      _mesa_make_current2(c->gl_ctx,
20581832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                          &drawBuffer->mesa_buffer,
20591832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul                          &readBuffer->mesa_buffer);
2060693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2061693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (c->gl_ctx->Viewport.Width == 0) {
2062693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 /* initialize viewport to window size */
2063693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 _mesa_Viewport( 0, 0, drawBuffer->width, drawBuffer->height );
2064693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 c->gl_ctx->Scissor.Width = drawBuffer->width;
2065693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 c->gl_ctx->Scissor.Height = drawBuffer->height;
2066693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2067693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
20681832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul      if (c->xm_visual->mesa_visual.rgbMode) {
2069693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /*
2070693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          * Must recompute and set these pixel values because colormap
2071693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          * can be different for different windows.
2072693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul          */
2073693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         c->clearpixel = xmesa_color_to_pixel( c,
2074693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               c->clearcolor[0],
2075693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               c->clearcolor[1],
2076693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               c->clearcolor[2],
2077693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               c->clearcolor[3],
2078693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                               c->xm_visual->undithered_pf);
2079693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         XMesaSetForeground(c->display, c->xm_buffer->cleargc, c->clearpixel);
2080693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2081693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2082693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
2083693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      c->xm_buffer->wasCurrent = GL_TRUE;
2084693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2085693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
2086693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Detach */
2087b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul      _mesa_make_current2( NULL, NULL, NULL );
2088693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2089693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_TRUE;
2090693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2091693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2092693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2093693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2094693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Unbind the context c from its buffer.
2095693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2096693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulGLboolean XMesaUnbindContext( XMesaContext c )
2097693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2098693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* A no-op for XFree86 integration purposes */
2099693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_TRUE;
2100693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2101693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2102693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2103693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulXMesaContext XMesaGetCurrentContext( void )
2104693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2105693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GET_CURRENT_CONTEXT(ctx);
2106693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (ctx) {
2107693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
2108693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return xmesa;
2109693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2110693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
2111693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return 0;
2112693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2113693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2114693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2115693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2116693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulXMesaBuffer XMesaGetCurrentBuffer( void )
2117693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2118693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GET_CURRENT_CONTEXT(ctx);
2119693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (ctx) {
2120693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
2121693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return xmesa->xm_buffer;
2122693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2123693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
2124693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return 0;
2125693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2126693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2127693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2128693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2129693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/* New in Mesa 3.1 */
2130693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulXMesaBuffer XMesaGetCurrentReadBuffer( void )
2131693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2132693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GET_CURRENT_CONTEXT(ctx);
2133693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (ctx) {
2134693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
2135693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return xmesa->xm_buffer;
2136693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2137693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
2138693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return 0;
2139693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2140693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2141693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2142693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2143693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulGLboolean XMesaForceCurrent(XMesaContext c)
2144693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2145693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (c) {
2146b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul      if (c->gl_ctx != _mesa_get_current_context()) {
21471832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul	 _mesa_make_current(c->gl_ctx, &c->xm_buffer->mesa_buffer);
2148693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2149693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2150693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
2151b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul      _mesa_make_current(NULL, NULL);
2152693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2153693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_TRUE;
2154693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2155693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2156693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2157693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulGLboolean XMesaLoseCurrent(XMesaContext c)
2158693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2159693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) c;
2160b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul   _mesa_make_current(NULL, NULL);
2161693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_TRUE;
2162693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2163693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2164693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2165693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2166693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Switch 3Dfx support hack between window and full-screen mode.
2167693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2168693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulGLboolean XMesaSetFXmode( GLint mode )
2169693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2170693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef FX
2171693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   const char *fx = getenv("MESA_GLX_FX");
2172693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (fx && fx[0] != 'd') {
2173693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      GET_CURRENT_CONTEXT(ctx);
2174693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      GrHwConfiguration hw;
2175693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (!FX_grSstQueryHardware(&hw)) {
2176693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /*fprintf(stderr, "!grSstQueryHardware\n");*/
2177693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return GL_FALSE;
2178693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2179693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (hw.num_sst < 1) {
2180693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /*fprintf(stderr, "hw.num_sst < 1\n");*/
2181693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return GL_FALSE;
2182693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2183693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (ctx) {
2184693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
2185693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (mode == XMESA_FX_WINDOW) {
2186693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    if (xmesa->xm_buffer->FXisHackUsable) {
2187693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	       FX_grSstControl(GR_CONTROL_DEACTIVATE);
2188693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	       xmesa->xm_buffer->FXwindowHack = GL_TRUE;
2189693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	       return GL_TRUE;
2190693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    }
2191693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 }
2192693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 else if (mode == XMESA_FX_FULLSCREEN) {
2193693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    FX_grSstControl(GR_CONTROL_ACTIVATE);
2194693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    xmesa->xm_buffer->FXwindowHack = GL_FALSE;
2195693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    return GL_TRUE;
2196693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 }
2197693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 else {
2198693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    /* Error: Bad mode value */
2199693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 }
2200693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2201693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2202693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /*fprintf(stderr, "fallthrough\n");*/
2203693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
2204693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) mode;
2205693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2206693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return GL_FALSE;
2207693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2208693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2209693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2210693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2211693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef FX
2212693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2213693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Read image from VooDoo frame buffer into X/Mesa's back XImage.
2214693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2215693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulstatic void FXgetImage( XMesaBuffer b )
2216693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2217693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   static unsigned short pixbuf[MAX_WIDTH];
221801915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul   GLuint x, y;
221901915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul   int xpos, ypos;
2220693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaWindow root;
2221693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   unsigned int bw, depth, width, height;
2222693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaContext xmesa = (XMesaContext) b->xm_context->gl_ctx->DriverCtx;
2223693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2224693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   assert(xmesa->xm_buffer->FXctx);
2225693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2226693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
2227693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   x = b->frontbuffer->x;
2228693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   y = b->frontbuffer->y;
2229693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   width = b->frontbuffer->width;
2230693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   height = b->frontbuffer->height;
2231693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   depth = b->frontbuffer->depth;
2232693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
2233693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XGetGeometry( xmesa->xm_visual->display, b->frontbuffer,
223401915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul                 &root, &xpos, &ypos, &width, &height, &bw, &depth);
2235693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2236693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->width != width || b->height != height) {
2237693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->width = MIN2((int)width, xmesa->xm_buffer->FXctx->width);
2238693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      b->height = MIN2((int)height, xmesa->xm_buffer->FXctx->height);
2239693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->width & 1)
2240693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         b->width--;  /* prevent odd width */
2241693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      xmesa_alloc_back_buffer( b );
2242693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2243693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2244693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   grLfbWriteColorFormat(GR_COLORFORMAT_ARGB);
2245693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (xmesa->xm_visual->undithered_pf==PF_5R6G5B) {
2246693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Special case: 16bpp RGB */
2247693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      grLfbReadRegion( GR_BUFFER_FRONTBUFFER,       /* src buffer */
2248693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                       0, xmesa->xm_buffer->FXctx->height - b->height,  /*pos*/
2249693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                       b->width, b->height,         /* size */
2250693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                       b->width * sizeof(GLushort), /* stride */
2251693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                       b->backimage->data);         /* dest buffer */
2252693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2253693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else if (xmesa->xm_visual->dithered_pf==PF_DITHER
2254693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    && GET_VISUAL_DEPTH(xmesa->xm_visual)==8) {
2255693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* Special case: 8bpp RGB */
2256693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (y=0;y<b->height;y++) {
2257693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         GLubyte *ptr = (GLubyte*) xmesa->xm_buffer->backimage->data
2258693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                        + xmesa->xm_buffer->backimage->bytes_per_line * y;
2259693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         XDITHER_SETUP(y);
2260693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2261693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* read row from 3Dfx frame buffer */
2262693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
2263693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                          0, xmesa->xm_buffer->FXctx->height-(b->height-y),
22645e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen                          b->width, 1,
2265693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                          0,
2266693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                          pixbuf );
2267693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2268693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* write to XImage back buffer */
2269693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         for (x=0;x<b->width;x++) {
2270693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            GLubyte r = (pixbuf[x] & 0xf800) >> 8;
2271693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
2272693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            GLubyte b = (pixbuf[x] & 0x001f) << 3;
2273693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            *ptr++ = XDITHER( x, r, g, b);
2274693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2275693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2276693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2277693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
2278693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* General case: slow! */
2279693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      for (y=0;y<b->height;y++) {
2280693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* read row from 3Dfx frame buffer */
2281693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
2282693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                          0, xmesa->xm_buffer->FXctx->height-(b->height-y),
22835e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen                          b->width, 1,
2284693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                          0,
2285693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                          pixbuf );
2286693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2287693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* write to XImage back buffer */
2288693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         for (x=0;x<b->width;x++) {
2289693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            XMesaPutPixel(b->backimage,x,y,
2290693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			  xmesa_color_to_pixel(xmesa,
2291693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul					       (pixbuf[x] & 0xf800) >> 8,
2292693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul					       (pixbuf[x] & 0x07e0) >> 3,
2293693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul					       (pixbuf[x] & 0x001f) << 3,
2294693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul					       0xff, xmesa->pixelformat));
2295693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2296693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2297693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2298693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   grLfbWriteColorFormat(GR_COLORFORMAT_ABGR);
2299693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2300693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2301693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2302693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2303693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2304693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Copy the back buffer to the front buffer.  If there's no back buffer
2305693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * this is a no-op.
2306693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2307693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid XMesaSwapBuffers( XMesaBuffer b )
2308693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2309693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GET_CURRENT_CONTEXT(ctx);
2310693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2311693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* If we're swapping the buffer associated with the current context
2312693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * we have to flush any pending rendering commands first.
2313693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
2314693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->xm_context && b->xm_context->gl_ctx == ctx)
2315693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      _mesa_swapbuffers(ctx);
2316693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2317693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->db_state) {
2318693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef FX
2319693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->FXctx) {
2320693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         fxMesaSwapBuffers();
2321693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2322693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (b->FXwindowHack)
2323693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            FXgetImage(b);
2324693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         else
2325693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return;
2326693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2327693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2328693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul     if (b->backimage) {
2329693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 /* Copy Ximage from host's memory to server's window */
2330693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#if defined(USE_XSHM) && !defined(XFree86Server)
2331693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 if (b->shm) {
2332693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2333693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	    XShmPutImage( b->xm_visual->display, b->frontbuffer,
2334693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			  b->cleargc,
2335693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			  b->backimage, 0, 0,
2336693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			  0, 0, b->width, b->height, False );
2337693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2338693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 }
2339693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 else
2340693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2341693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
2342693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2343693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            XMesaPutImage( b->xm_visual->display, b->frontbuffer,
2344693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			   b->cleargc,
2345693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			   b->backimage, 0, 0,
2346693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			   0, 0, b->width, b->height );
2347693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2348693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2349693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2350693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
2351693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 /* Copy pixmap to window on server */
2352693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2353693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 XMesaCopyArea( b->xm_visual->display,
2354693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			b->backpixmap,   /* source drawable */
2355693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			b->frontbuffer,  /* dest. drawable */
2356693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			b->cleargc,
2357693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			0, 0, b->width, b->height,  /* source region */
2358693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			0, 0                 /* dest region */
2359693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul		      );
2360693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2361693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2362693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2363655ba5d9927187e76b66f5886d090624dc4b1dd9Brian Paul#if !defined(XFree86Server)
2364693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XSync( b->xm_visual->display, False );
2365693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2366693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2367693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2368693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2369693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2370693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2371693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Copy sub-region of back buffer to front buffer
2372693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2373693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
2374693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2375693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GET_CURRENT_CONTEXT(ctx);
2376693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2377693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   /* If we're swapping the buffer associated with the current context
2378693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    * we have to flush any pending rendering commands first.
2379693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    */
2380693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->xm_context->gl_ctx == ctx)
2381693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      _mesa_swapbuffers(ctx);
2382693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2383693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->db_state) {
2384536ede7e00ff5e2f10be3bf9b60cd2cfa80b3518Brian Paul      int yTop = b->height - y - height;
2385693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef FX
2386693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->FXctx) {
2387693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         fxMesaSwapBuffers();
2388693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (b->FXwindowHack)
2389693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            FXgetImage(b);
2390693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         else
2391693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return;
2392693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2393693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2394693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->backimage) {
2395693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Copy Ximage from host's memory to server's window */
2396693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#if defined(USE_XSHM) && !defined(XFree86Server)
2397693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (b->shm) {
2398693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /* XXX assuming width and height aren't too large! */
2399693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            XShmPutImage( b->xm_visual->display, b->frontbuffer,
2400693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                          b->cleargc,
2401693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                          b->backimage, x, yTop,
2402693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                          x, yTop, width, height, False );
2403693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /* wait for finished event??? */
2404693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2405693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         else
2406693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2407693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
2408693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /* XXX assuming width and height aren't too large! */
2409693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            XMesaPutImage( b->xm_visual->display, b->frontbuffer,
2410693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			   b->cleargc,
2411693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			   b->backimage, x, yTop,
2412693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			   x, yTop, width, height );
2413693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2414693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2415693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      else {
2416693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* Copy pixmap to window on server */
2417693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         XMesaCopyArea( b->xm_visual->display,
2418693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			b->backpixmap,           /* source drawable */
2419693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			b->frontbuffer,          /* dest. drawable */
2420693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			b->cleargc,
2421693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			x, yTop, width, height,  /* source region */
2422693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul			x, yTop                  /* dest region */
2423693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                      );
2424693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2425693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2426693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2427693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2428693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2429693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2430693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return a pointer to the XMesa backbuffer Pixmap or XImage.  This function
2431693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * is a way to get "under the hood" of X/Mesa so one can manipulate the
2432693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * back buffer directly.
2433693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Output:  pixmap - pointer to back buffer's Pixmap, or 0
2434693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *          ximage - pointer to back buffer's XImage, or NULL
2435693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  GL_TRUE = context is double buffered
2436693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *          GL_FALSE = context is single buffered
2437693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2438693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulGLboolean XMesaGetBackBuffer( XMesaBuffer b,
2439693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                              XMesaPixmap *pixmap,
2440693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                              XMesaImage **ximage )
2441693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2442693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (b->db_state) {
2443693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (pixmap)  *pixmap = b->backpixmap;
2444693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (ximage)  *ximage = b->backimage;
2445693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_TRUE;
2446693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2447693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
2448693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *pixmap = 0;
2449693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *ximage = NULL;
2450693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_FALSE;
2451693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2452693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2453693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2454693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2455693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2456693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return the depth buffer associated with an XMesaBuffer.
2457693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Input:  b - the XMesa buffer handle
2458693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Output:  width, height - size of buffer in pixels
2459693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *          bytesPerValue - bytes per depth value (2 or 4)
2460693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul *          buffer - pointer to depth buffer values
2461693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
2462693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2463693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulGLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
2464693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                               GLint *bytesPerValue, void **buffer )
2465693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
24661832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul   if (!b->mesa_buffer.DepthBuffer) {
2467693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *width = 0;
2468693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *height = 0;
2469693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *bytesPerValue = 0;
2470693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *buffer = 0;
2471693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_FALSE;
2472693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2473693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
24741832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul      *width = b->mesa_buffer.Width;
24751832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul      *height = b->mesa_buffer.Height;
2476693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      *bytesPerValue = sizeof(GLdepth);
24771832f1cc86758fdcbd122edd5bf9e7a29ccade20Brian Paul      *buffer = b->mesa_buffer.DepthBuffer;
2478693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return GL_TRUE;
2479693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2480693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2481693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2482693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2483693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid XMesaFlush( XMesaContext c )
2484693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2485693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (c && c->xm_visual) {
2486693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
2487693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      /* NOT_NEEDED */
2488693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
2489693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      XSync( c->xm_visual->display, False );
2490693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2491693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2492693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2493693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2494693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2495693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2496693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulconst char *XMesaGetString( XMesaContext c, int name )
2497693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2498693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   (void) c;
2499693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   if (name==XMESA_VERSION) {
2500693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return "3.1";
2501693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2502693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else if (name==XMESA_EXTENSIONS) {
2503693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return "";
2504693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2505693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   else {
2506693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      return NULL;
2507693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2508693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2509693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2510693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2511693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2512693f81be4c16bcec4e017e9b3189f518d157d85fBrian PaulXMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d )
2513693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2514693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaBuffer b;
2515693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (b=XMesaBufferList; b; b=b->Next) {
2516693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (b->frontbuffer==d && b->display==dpy) {
2517693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return b;
2518693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2519693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2520693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return NULL;
2521693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2522693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2523693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2524693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2525693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul/*
2526693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Look for XMesaBuffers whose X window has been destroyed.
2527693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul * Deallocate any such XMesaBuffers.
2528693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul */
2529693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid XMesaGarbageCollect( void )
2530693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2531693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   XMesaBuffer b, next;
2532693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   for (b=XMesaBufferList; b; b=next) {
2533693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      next = b->Next;
2534693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      if (!b->pixmap_flag) {
2535693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#ifdef XFree86Server
2536693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	 /* NOT_NEEDED */
2537693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#else
2538693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         XSync(b->display, False);
2539693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         if (!window_exists( b->display, b->frontbuffer )) {
2540693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            /* found a dead window, free the ancillary info */
2541693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            XMesaDestroyBuffer( b );
2542693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2543693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul#endif
2544693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      }
2545693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2546693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2547693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2548693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2549693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulvoid XMesaReset( void )
2550693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2551693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    while (XMesaBufferList)
2552693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul	XMesaDestroyBuffer(XMesaBufferList);
2553693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2554693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul    XMesaBufferList = NULL;
2555693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2556693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2557693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2558693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paulunsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
2559693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                GLfloat red, GLfloat green,
2560693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul                                GLfloat blue, GLfloat alpha )
2561693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul{
2562693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GLint r = (GLint) (red   * 255.0F);
2563693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GLint g = (GLint) (green * 255.0F);
2564693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GLint b = (GLint) (blue  * 255.0F);
2565693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   GLint a = (GLint) (alpha * 255.0F);
2566693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2567693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   switch (xmesa->pixelformat) {
2568693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_INDEX:
2569693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return 0;
2570693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_TRUECOLOR:
2571693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
2572693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            unsigned long p;
2573693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            PACK_TRUECOLOR( p, r, g, b );
2574693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return p;
2575693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2576693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_8A8B8G8R:
2577693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return PACK_8A8B8G8R( r, g, b, a );
2578693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_8R8G8B:
2579693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return PACK_8R8G8B( r, g, b );
2580693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_5R6G5B:
2581693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return PACK_5R6G5B( r, g, b );
2582693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_DITHER:
2583693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
2584693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            DITHER_SETUP;
2585693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return DITHER( x, y, r, g, b );
2586693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2587693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_1BIT:
2588693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* 382 = (3*255)/2 */
2589693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
2590693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_HPCR:
2591693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return DITHER_HPCR(x, y, r, g, b);
2592693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_LOOKUP:
2593693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
2594693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            LOOKUP_SETUP;
2595693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return LOOKUP( r, g, b );
2596693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2597693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_GRAYSCALE:
2598693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         return GRAY_RGB( r, g, b );
2599693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_DITHER_5R6G5B:
2600693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         /* fall through */
2601693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      case PF_TRUEDITHER:
2602693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         {
2603693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            unsigned long p;
2604693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            PACK_TRUEDITHER(p, x, y, r, g, b);
2605693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul            return p;
2606693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul         }
2607693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul      default:
260808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_problem(NULL, "Bad pixel format in XMesaDitherColor");
2609693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   }
2610693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul   return 0;
2611693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul}
2612693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2613693f81be4c16bcec4e017e9b3189f518d157d85fBrian Paul
2614