xm_api.c revision 48f5deab94be832a782a440f55a7bc742d50a62f
19fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org/*
29e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Mesa 3-D graphics library
39e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Version:  6.5.2
49e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
59e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
69e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
79e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
89e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * copy of this software and associated documentation files (the "Software"),
99e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * to deal in the Software without restriction, including without limitation
109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Software is furnished to do so, subject to the following conditions:
139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * The above copyright notice and this permission notice shall be included
159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * in all copies or substantial portions of the Software.
169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \file xm_api.c
279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * All the XMesa* API functions.
299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * NOTES:
329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * The window coordinate system origin (0,0) is in the lower-left corner
349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * of the window.  X11's window coordinate origin is in the upper-left
359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * corner of the window.  Therefore, most drawing functions in this
369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * file have to flip Y coordinates.
379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile
399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * in support for the MIT Shared Memory extension.  If enabled, when you
409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * use an Ximage for the back buffer in double buffered mode, the "swap"
419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * operation will be faster.  You must also link with -lXext.
429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Byte swapping:  If the Mesa host and the X display use a different
449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * byte order then there's some trickiness to be aware of when using
459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * XImages.  The byte ordering used for the XImage is that of the X
469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * display, not the Mesa host.
479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * The color-to-pixel encoding for True/DirectColor must be done
489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * according to the display's visual red_mask, green_mask, and blue_mask.
499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * If XPutPixel is used to put a pixel into an XImage then XPutPixel will
509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * do byte swapping if needed.  If one wants to directly "poke" the pixel
519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * into the XImage's buffer then the pixel must be byte swapped first.  In
529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format
539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * and use XPutPixel everywhere except in the implementation of
549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * glClear(GL_COLOR_BUFFER_BIT).  We want this function to be fast so
559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * instead of using XPutPixel we "poke" our values after byte-swapping
569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * the clear pixel value if needed.
579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef __CYGWIN__
619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#undef WIN32
629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#undef __WIN32__
639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif
649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "glxheader.h"
669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "GL/xmesa.h"
679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "xmesaP.h"
689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "context.h"
699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "extensions.h"
709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "framebuffer.h"
719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "glthread.h"
729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "imports.h"
739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "macros.h"
749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "renderbuffer.h"
759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "swrast/swrast.h"
769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "swrast_setup/swrast_setup.h"
779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "vbo/vbo.h"
789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "tnl/tnl.h"
799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "tnl/t_context.h"
809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "tnl/t_pipeline.h"
819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include "drivers/common/driverfuncs.h"
829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef XFree86Server
849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#include <GL/glxtokens.h>
85c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
86c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
87c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com/**
889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Global X driver lock
899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org_glthread_Mutex _xmesa_lock;
919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
94c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com/**
95c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Lookup tables for HPCR pixel format:
96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com */
974d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.orgstatic short hpcr_rgbTbl[3][256] = {
984d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org{
999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,  22,  23,  23,
1009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,  30,  31,  31,
1019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
1029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
1039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
1049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
1059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
1069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
1089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
1099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
1109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
1119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
1129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
1139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
1149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
1159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org},
1169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
1179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,  22,  23,  23,
1189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,  30,  31,  31,
1199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
1209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
1219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
1229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
1233847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
1243847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1253847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
1269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
1279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
1289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
1299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
1309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
1319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
1329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
1339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org},
1349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
1359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 32,  32,  33,  33,  34,  34,  35,  35,  36,  36,  37,  37,  38,  38,  39,  39,
1369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 40,  40,  41,  41,  42,  42,  43,  43,  44,  44,  45,  45,  46,  46,  47,  47,
1379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 48,  48,  49,  49,  50,  50,  51,  51,  52,  52,  53,  53,  54,  54,  55,  55,
1389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 56,  56,  57,  57,  58,  58,  59,  59,  60,  60,  61,  61,  62,  62,  63,  63,
1399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 64,  64,  65,  65,  66,  66,  67,  67,  68,  68,  69,  69,  70,  70,  71,  71,
1409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 72,  72,  73,  73,  74,  74,  75,  75,  76,  76,  77,  77,  78,  78,  79,  79,
1419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 80,  80,  81,  81,  82,  82,  83,  83,  84,  84,  85,  85,  86,  86,  87,  87,
1429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
1439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
1459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
1469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
1479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
1489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
1499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
1509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223
1519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
1529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org};
1539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/
1577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org/*****                     X Utility Functions                    *****/
1587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org/**********************************************************************/
1597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
16034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
16134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org/**
16234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org * Return the host's byte order as LSBFirst or MSBFirst ala X.
1637c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org */
1647c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org#ifndef XFree86Server
1657c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic int host_byte_order( void )
166ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org{
167ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org   int i = 1;
1689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   char *cptr = (char *) &i;
1699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   return (*cptr==1) ? LSBFirst : MSBFirst;
1709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
1719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif
17231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
17331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
17431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org/**
1759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Check if the X Shared Memory extension is available.
1769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return:  0 = not available
1779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *          1 = shared XImage support available
1789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *          2 = shared Pixmap support available also
1799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
1809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic int check_for_xshm( XMesaDisplay *display )
1819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
1829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#if defined(XFree86Server)
1839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   return 0;
1849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#elif defined(USE_XSHM)
1859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   int major, minor, ignore;
1869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   Bool pixmaps;
1879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
1889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
1899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
1909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org	 return (pixmaps==True) ? 2 : 1;
1919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
1929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      else {
1939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org	 return 0;
1949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
1959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
1969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   else {
1979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      return 0;
198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   }
199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#else
200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   /* No  XSHM support */
201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   return 0;
202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
2034d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org}
2044d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
2059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
2079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Apply gamma correction to an intensity value in [0..max].  Return the
2089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * new intensity value.
2099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
2109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic GLint
2119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orggamma_adjust( GLfloat gamma, GLint value, GLint max )
2129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
2139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (gamma == 1.0) {
2149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      return value;
2159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
2169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   else {
2179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      double x = (double) value / (double) max;
2189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      return IROUND_POS((GLfloat) max * _mesa_pow(x, 1.0F/gamma));
2199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
2209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
2219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
2259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return the true number of bits per pixel for XImages.
2269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * For example, if we request a 24-bit deep visual we may actually need/get
2279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * 32bpp XImages.  This function returns the appropriate bpp.
2289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Input:  dpy - the X display
2299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *         visinfo - desribes the visual to be used for XImages
2309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return:  true number of bits per pixel for XImages
2319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
2329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic int
2339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgbits_per_pixel( XMesaVisual xmv )
2349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
2359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef XFree86Server
2369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   const int depth = xmv->nplanes;
2379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   int i;
2389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   assert(depth > 0);
2399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   for (i = 0; i < screenInfo.numPixmapFormats; i++) {
2409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (screenInfo.formats[i].depth == depth)
2419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         return screenInfo.formats[i].bitsPerPixel;
2429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
2433847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com   return depth;  /* should never get here, but this should be safe */
2443847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com#else
2453847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com   XMesaDisplay *dpy = xmv->display;
2463847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com   XMesaVisualInfo visinfo = xmv->visinfo;
2473847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com   XMesaImage *img;
2489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   int bitsPerPixel;
2499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* Create a temporary XImage */
2509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   img = XCreateImage( dpy, visinfo->visual, visinfo->depth,
2519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org		       ZPixmap, 0,           /*format, offset*/
2529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org		       (char*) MALLOC(8),    /*data*/
2539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org		       1, 1,                 /*width, height*/
2549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org		       32,                   /*bitmap_pad*/
2559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org		       0                     /*bytes_per_line*/
2569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                     );
2579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   assert(img);
2589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* grab the bits/pixel value */
2599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   bitsPerPixel = img->bits_per_pixel;
2609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* free the XImage */
2619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   _mesa_free( img->data );
2629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   img->data = NULL;
2639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   XMesaDestroyImage( img );
2649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   return bitsPerPixel;
2659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif
2669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
2679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
2699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com/*
271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Determine if a given X window ID is valid (window exists).
272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Do this by calling XGetWindowAttributes() for the window and
273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * checking if we catch an X error.
274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Input:  dpy - the display
275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *         win - the window to check for existance
276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com * Return:  GL_TRUE - window exists
277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *          GL_FALSE - window doesn't exist
278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com */
279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifndef XFree86Server
280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic GLboolean WindowExistsFlag;
281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr )
283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com{
284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   (void) dpy;
285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   if (xerr->error_code == BadWindow) {
286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      WindowExistsFlag = GL_FALSE;
287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   }
288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   return 0;
2899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic GLboolean window_exists( XMesaDisplay *dpy, Window win )
2929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   XWindowAttributes wa;
2949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   int (*old_handler)( XMesaDisplay*, XErrorEvent* );
2959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   WindowExistsFlag = GL_TRUE;
296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   old_handler = XSetErrorHandler(window_exists_err_handler);
2979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   XGetWindowAttributes( dpy, win, &wa ); /* dummy request */
298c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org   XSetErrorHandler(old_handler);
299c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org   return WindowExistsFlag;
300c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org}
3019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif
3029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
3069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Return the size of the window (or pixmap) that corresponds to the
3079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * given XMesaBuffer.
3089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param width  returns width in pixels
3099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param height  returns height in pixels
3109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
3119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgvoid
312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comxmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      GLuint *width, GLuint *height)
314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com{
315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef XFree86Server
3169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
3179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
3189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else
3199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   Window root;
3209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   Status stat;
3219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   int xpos, ypos;
3229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   unsigned int w, h, bw, depth;
3239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   _glthread_LOCK_MUTEX(_xmesa_lock);
3259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   XSync(b->xm_visual->display, 0); /* added for Chromium */
3269fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org   stat = XGetGeometry(dpy, b->frontxrb->pixmap, &root, &xpos, &ypos,
3279fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org                       &w, &h, &bw, &depth);
3289fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org   _glthread_UNLOCK_MUTEX(_xmesa_lock);
3299fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org
3309fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org   if (stat) {
3319fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org      *width = w;
3329fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org      *height = h;
3337c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org   }
3349fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org   else {
3359fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org      /* probably querying a window that's recently been destroyed */
3369fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org      _mesa_warning(NULL, "XGetGeometry failed!\n");
3379fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org      *width = *height = 1;
3389fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org   }
3394d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org#endif
3404d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org}
3419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3427c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
3439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/
3459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/*****                Linked list of XMesaBuffers                 *****/
3469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/
3479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic XMesaBuffer XMesaBufferList = NULL;
3497c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
3509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
3529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Allocate a new XMesaBuffer object which corresponds to the given drawable.
3539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Note that XMesaBuffer is derived from GLframebuffer.
3549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * The new XMesaBuffer will not have any size (Width=Height=0).
3559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org *
3569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param d  the corresponding X drawable (window or pixmap)
3577c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org * \param type  either WINDOW, PIXMAP or PBUFFER, describing d
3589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param vis  the buffer's visual
3599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \param cmap  the window's colormap, if known.
3609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * \return new XMesaBuffer or NULL if any problem
3619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
3629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic XMesaBuffer
3639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgcreate_xmesa_buffer(XMesaDrawable d, BufferType type,
3647c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org                    XMesaVisual vis, XMesaColormap cmap)
3659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
3669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   GLboolean swAlpha;
3679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   XMesaBuffer b;
3689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
3709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
3727c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org   if (!b)
3739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      return NULL;
3749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b->display = vis->display;
3769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b->xm_visual = vis;
3779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b->type = type;
3789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b->cmap = cmap;
3797c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
3809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual);
3819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /*
3839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    * Front renderbuffer
3849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    */
3859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
3869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                           GL_FALSE);
3877c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org   if (!b->frontxrb) {
3889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      _mesa_free(b);
3899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      return NULL;
3909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
3919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b->frontxrb->Parent = b;
3929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b->frontxrb->drawable = d;
3939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b->frontxrb->pixmap = (XMesaPixmap) d;
3947c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org   _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT,
3959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                          &b->frontxrb->Base);
3969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
3979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /*
3983847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    * Back renderbuffer
3993847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    */
4003847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com   if (vis->mesa_visual.doubleBufferMode) {
4017c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual,
4023847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com                                          GL_TRUE);
4033847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      if (!b->backxrb) {
4043847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com         /* XXX free front xrb too */
4059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         _mesa_free(b);
4069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         return NULL;
4079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
4087b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      b->backxrb->Parent = b;
4097b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      /* determine back buffer implementation */
4107b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP;
4117b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
4127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org      _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT,
4137b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                             &b->backxrb->Base);
4147b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org   }
4157b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
4167b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org   /*
4179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    * Software alpha planes
4189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    */
4199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (vis->mesa_visual.alphaBits > 0
4209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org       && vis->undithered_pf != PF_8A8B8G8R
4219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org       && vis->undithered_pf != PF_8A8R8G8B) {
4229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      /* Visual has alpha, but pixel format doesn't support it.
423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       * We'll use an alpha renderbuffer wrapper.
424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       */
425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      swAlpha = GL_TRUE;
426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   }
427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   else {
428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      swAlpha = GL_FALSE;
429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   }
4309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
4319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /*
4329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    * Other renderbuffer (depth, stencil, etc)
4339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    */
4349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   _mesa_add_soft_renderbuffers(&b->mesa_buffer,
4359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                GL_FALSE,  /* color */
4369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                vis->mesa_visual.haveDepthBuffer,
4379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                vis->mesa_visual.haveStencilBuffer,
4389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                vis->mesa_visual.haveAccumBuffer,
4399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                swAlpha,
4409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                vis->mesa_visual.numAuxBuffers > 0 );
4419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
4429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* insert buffer into linked list */
4439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   b->Next = XMesaBufferList;
4449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   XMesaBufferList = b;
4459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
4469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   return b;
4479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
4489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
4499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
4509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
4519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Find an XMesaBuffer by matching X display and colormap but NOT matching
4529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * the notThis buffer.
4539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
4549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic XMesaBuffer
4559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgfind_xmesa_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis)
4569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
4579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   XMesaBuffer b;
458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   for (b=XMesaBufferList; b; b=b->Next) {
4594d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org      if (b->display==dpy && b->cmap==cmap && b!=notThis) {
4609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         return b;
4619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
4629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
4639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   return NULL;
4649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
4659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
4669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
4679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
4689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Free an XMesaBuffer, remove from linked list, perhaps free X colormap
4699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * entries.
4703847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com */
4719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic void
4729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgfree_xmesa_buffer(int client, XMesaBuffer buffer)
4739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
4749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   XMesaBuffer prev = NULL, b;
4759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   (void) client;
4769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   for (b=XMesaBufferList; b; b=b->Next) {
4779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (b==buffer) {
4789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         /* unlink bufer from list */
4799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         if (prev)
4807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org            prev->Next = buffer->Next;
4817c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org         else
4829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            XMesaBufferList = buffer->Next;
4839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         /* Check to free X colors */
4849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         if (buffer->num_alloced>0) {
4859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            /* If no other buffer uses this X colormap then free the colors. */
4869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) {
487ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org#ifdef XFree86Server
48831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org               (void)FreeColors(buffer->cmap, client,
4899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org				buffer->num_alloced, buffer->alloced_colors,
4909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org				0);
4919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else
4923847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com               XFreeColors(buffer->display, buffer->cmap,
4939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                           buffer->alloced_colors, buffer->num_alloced, 0);
4949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif
4959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            }
4969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         }
4979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
4989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         _mesa_free_framebuffer_data(&buffer->mesa_buffer);
4999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         _mesa_free(buffer);
5009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
5019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         return;
502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      /* continue search */
504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      prev = b;
5059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
5069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* buffer not found in XMesaBufferList */
5079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n");
5089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
5099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
5109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
5119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
5129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Copy X color table stuff from one XMesaBuffer to another.
5139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
5149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic void
5159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgcopy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
5169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
5179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));
5189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
5199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g));
5209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b));
5219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   dst->num_alloced = src->num_alloced;
5229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   MEMCPY(dst->alloced_colors, src->alloced_colors,
5239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          sizeof(src->alloced_colors));
5249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
5259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
5269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
5279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
5289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/
5299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/*****                   Misc Private Functions                   *****/
5309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**********************************************************************/
5319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
5329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
5339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
5349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * A replacement for XAllocColor.  This function should never
5359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * fail to allocate a color.  When XAllocColor fails, we return
5369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * the nearest matching color.  If we have to allocate many colors
5379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * this function isn't too efficient; the XQueryColors() could be
5389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * done just once.
5399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Written by Michael Pichler, Brian Paul, Mark Kilgard
5409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Input:  dpy - X display
541e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org *         cmap - X colormap
542e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org *         cmapSize - size of colormap
543e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org * In/Out: color - the XColor struct
544e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org * Output:  exact - 1=exact color match, 0=closest match
545e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org *          alloced - 1=XAlloc worked, 0=XAlloc failed
546e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org */
547e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgstatic void
5489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgnoFaultXAllocColor( int client,
5499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                    XMesaDisplay *dpy,
5509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                    XMesaColormap cmap,
5519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                    int cmapSize,
5529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                    XMesaColor *color,
5539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                    int *exact, int *alloced )
5549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
5559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef XFree86Server
5569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   Pixel *ppixIn;
5579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   xrgb *ctable;
5589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else
5599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* we'll try to cache ctable for better remote display performance */
5609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   static Display *prevDisplay = NULL;
5619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   static XMesaColormap prevCmap = 0;
562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   static int prevCmapSize = 0;
563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   static XMesaColor *ctable = NULL;
564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   XMesaColor subColor;
566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   int i, bestmatch;
567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   double mindist;       /* 3*2^16^2 exceeds long int precision. */
568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   (void) client;
570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   /* First try just using XAllocColor. */
5729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifdef XFree86Server
5739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (AllocColor(cmap,
5749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org		  &color->red, &color->green, &color->blue,
5759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org		  &color->pixel,
5769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org		  client) == Success)
5779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else
57831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   if (XAllocColor(dpy, cmap, color))
57931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#endif
58031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   {
58131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org      *exact = 1;
58231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org      *alloced = 1;
58331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org      return;
58431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   }
58531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
58631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   /* Alloc failed, search for closest match */
58731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
58831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   /* Retrieve color table entries. */
58931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   /* XXX alloca candidate. */
59031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#ifdef XFree86Server
59131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel));
59231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb));
59331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   for (i = 0; i < cmapSize; i++) {
59431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org      ppixIn[i] = i;
59531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org   }
5969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   QueryColors(cmap, cmapSize, ppixIn, ctable);
5979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#else
5989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (prevDisplay != dpy || prevCmap != cmap
5999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org       || prevCmapSize != cmapSize || !ctable) {
6009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      /* free previously cached color table */
6019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (ctable)
6029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         _mesa_free(ctable);
6039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      /* Get the color table from X */
6049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor));
6059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      assert(ctable);
6069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      for (i = 0; i < cmapSize; i++) {
6079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         ctable[i].pixel = i;
6089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
6099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      XQueryColors(dpy, cmap, ctable, cmapSize);
6109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      prevDisplay = dpy;
6119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      prevCmap = cmap;
6129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      prevCmapSize = cmapSize;
6139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
6149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif
6159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
6169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* Find best match. */
6179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   bestmatch = -1;
6189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   mindist = 0.0;
6199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   for (i = 0; i < cmapSize; i++) {
6209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      double dr = 0.30 * ((double) color->red - (double) ctable[i].red);
6219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      double dg = 0.59 * ((double) color->green - (double) ctable[i].green);
6229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      double db = 0.11 * ((double) color->blue - (double) ctable[i].blue);
6237943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      double dist = dr * dr + dg * dg + db * db;
6247943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      if (bestmatch < 0 || dist < mindist) {
6257943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org         bestmatch = i;
6267943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org         mindist = dist;
6277943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org      }
6287943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org   }
6297943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org
6307943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org   /* Return result. */
6317943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org   subColor.red   = ctable[bestmatch].red;
6327943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org   subColor.green = ctable[bestmatch].green;
6337943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org   subColor.blue  = ctable[bestmatch].blue;
6347943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org   /* Try to allocate the closest match color.  This should only
6357943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org    * fail if the cell is read/write.  Otherwise, we're incrementing
6367943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org    * the cell's reference count.
6377943d46751aa94f2738bef3002bd6675b520f3b5vegorov@chromium.org    */
6387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#ifdef XFree86Server
6397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org   if (AllocColor(cmap,
6407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org		  &subColor.red, &subColor.green, &subColor.blue,
6417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org		  &subColor.pixel,
6427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org		  client) == Success) {
643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#else
644c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   if (XAllocColor(dpy, cmap, &subColor)) {
6457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#endif
6467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      *alloced = 1;
6477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org   }
6487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org   else {
64934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      /* do this to work around a problem reported by Frank Ortega */
65034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      subColor.pixel = (unsigned long) bestmatch;
65134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      subColor.red   = ctable[bestmatch].red;
65234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      subColor.green = ctable[bestmatch].green;
65334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      subColor.blue  = ctable[bestmatch].blue;
65434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      subColor.flags = DoRed | DoGreen | DoBlue;
65534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      *alloced = 0;
65634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org   }
65734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#ifdef XFree86Server
65834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org   _mesa_free(ppixIn);
65934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org   _mesa_free(ctable);
66034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org#else
66134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org   /* don't free table, save it for next time */
6627c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org#endif
6637c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
6647c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org   *color = subColor;
6657c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org   *exact = 0;
6667c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
6677c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
6687c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
6697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
6707c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org/**
6719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Do setup for PF_GRAYSCALE pixel format.
6729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Note that buffer may be NULL.
6739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
6749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic GLboolean
6759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgsetup_grayscale(int client, XMesaVisual v,
6769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                XMesaBuffer buffer, XMesaColormap cmap)
6779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
6789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
6799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      return GL_FALSE;
6809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
6819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
6829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (buffer) {
6839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      XMesaBuffer prevBuffer;
6849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
6859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (!cmap) {
6869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         return GL_FALSE;
6879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
6889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
6899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
6909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (prevBuffer &&
6919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          (buffer->xm_visual->mesa_visual.rgbMode ==
6929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org           prevBuffer->xm_visual->mesa_visual.rgbMode)) {
6939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         /* Copy colormap stuff from previous XMesaBuffer which uses same
6949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          * X colormap.  Do this to avoid time spent in noFaultXAllocColor.
6959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          */
6969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         copy_colortable_info(buffer, prevBuffer);
6979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
6989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      else {
6999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         /* Allocate 256 shades of gray */
7009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         int gray;
7019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         int colorsfailed = 0;
7029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         for (gray=0;gray<256;gray++) {
7039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            GLint r = gamma_adjust( v->RedGamma,   gray, 255 );
7049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            GLint g = gamma_adjust( v->GreenGamma, gray, 255 );
7059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            GLint b = gamma_adjust( v->BlueGamma,  gray, 255 );
7069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            int exact, alloced;
7079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            XMesaColor xcol;
7089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            xcol.red   = (r << 8) | r;
7099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            xcol.green = (g << 8) | g;
7109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            xcol.blue  = (b << 8) | b;
7119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            noFaultXAllocColor( client, v->display,
7129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                cmap, GET_COLORMAP_SIZE(v),
7139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                &xcol, &exact, &alloced );
7149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            if (!exact) {
7159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org               colorsfailed++;
7169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            }
7179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            if (alloced) {
7189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org               assert(buffer->num_alloced<256);
7199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org               buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
7209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org               buffer->num_alloced++;
7219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            }
7229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
7239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            /*OLD
7249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            assert(gray < 576);
7259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->color_table[gray*3+0] = xcol.pixel;
7269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->color_table[gray*3+1] = xcol.pixel;
7279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->color_table[gray*3+2] = xcol.pixel;
7289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            assert(xcol.pixel < 65536);
7299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->pixel_to_r[xcol.pixel] = gray * 30 / 100;
7309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->pixel_to_g[xcol.pixel] = gray * 59 / 100;
7319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->pixel_to_b[xcol.pixel] = gray * 11 / 100;
7329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            */
7339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->color_table[gray] = xcol.pixel;
7349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            assert(xcol.pixel < 65536);
7359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->pixel_to_r[xcol.pixel] = gray;
7369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->pixel_to_g[xcol.pixel] = gray;
7379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            buffer->pixel_to_b[xcol.pixel] = gray;
7389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         }
7399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
7409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         if (colorsfailed && _mesa_getenv("MESA_DEBUG")) {
7419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            _mesa_warning(NULL,
7429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  "Note: %d out of 256 needed colors do not match exactly.\n",
7439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  colorsfailed );
7449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         }
7459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
7469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
7479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
7489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->dithered_pf = PF_Grayscale;
7499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->undithered_pf = PF_Grayscale;
7509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   return GL_TRUE;
7519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
7529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
7539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
7549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
7559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
7569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Setup RGB rendering for a window with a PseudoColor, StaticColor,
7579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * or 8-bit TrueColor visual visual.  We try to allocate a palette of 225
7589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB
7599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * color.  While this function was originally designed just for 8-bit
7609e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * visuals, it has also proven to work from 4-bit up to 16-bit visuals.
7619e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Dithering code contributed by Bob Mercier.
7629e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
763ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgstatic GLboolean
764c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgsetup_dithered_color(int client, XMesaVisual v,
7659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                     XMesaBuffer buffer, XMesaColormap cmap)
7669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
7679e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
7689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      return GL_FALSE;
7699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
7709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
7719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (buffer) {
7729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      XMesaBuffer prevBuffer;
7739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
7749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (!cmap) {
7759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         return GL_FALSE;
7769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
7779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
7789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
7799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      if (prevBuffer &&
7809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          (buffer->xm_visual->mesa_visual.rgbMode ==
7819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org           prevBuffer->xm_visual->mesa_visual.rgbMode)) {
7829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         /* Copy colormap stuff from previous, matching XMesaBuffer.
7839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          * Do this to avoid time spent in noFaultXAllocColor.
7849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          */
7859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         copy_colortable_info(buffer, prevBuffer);
7869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
7879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      else {
7889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         /* Allocate X colors and initialize color_table[], red_table[], etc */
7899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         int r, g, b, i;
7909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         int colorsfailed = 0;
7919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         for (r = 0; r < DITH_R; r++) {
7929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            for (g = 0; g < DITH_G; g++) {
7939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org               for (b = 0; b < DITH_B; b++) {
7949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  XMesaColor xcol;
7959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  int exact, alloced;
7969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  xcol.red  =gamma_adjust(v->RedGamma,   r*65535/(DITH_R-1),65535);
7979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  xcol.green=gamma_adjust(v->GreenGamma, g*65535/(DITH_G-1),65535);
7989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  xcol.blue =gamma_adjust(v->BlueGamma,  b*65535/(DITH_B-1),65535);
7999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  noFaultXAllocColor( client, v->display,
8009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                      cmap, GET_COLORMAP_SIZE(v),
8019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                      &xcol, &exact, &alloced );
8029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  if (!exact) {
8039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                     colorsfailed++;
8049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  }
8059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  if (alloced) {
8069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                     assert(buffer->num_alloced<256);
8079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                     buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
8089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                     buffer->num_alloced++;
8099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  }
8109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  i = DITH_MIX( r, g, b );
8119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  assert(i < 576);
8129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  buffer->color_table[i] = xcol.pixel;
8139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  assert(xcol.pixel < 65536);
8149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  buffer->pixel_to_r[xcol.pixel] = r * 255 / (DITH_R-1);
8159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  buffer->pixel_to_g[xcol.pixel] = g * 255 / (DITH_G-1);
8169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  buffer->pixel_to_b[xcol.pixel] = b * 255 / (DITH_B-1);
8179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org               }
8189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            }
8199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         }
8209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         if (colorsfailed && _mesa_getenv("MESA_DEBUG")) {
8229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org            _mesa_warning(NULL,
8239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  "Note: %d out of %d needed colors do not match exactly.\n",
8249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                  colorsfailed, DITH_R * DITH_G * DITH_B );
8259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         }
8269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
8279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
8289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->dithered_pf = PF_Dither;
8309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->undithered_pf = PF_Lookup;
8319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   return GL_TRUE;
8329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
8339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
8369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
8379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
8389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Special dithering tables have to be initialized.
8399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
8409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic void
8419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgsetup_8bit_hpcr(XMesaVisual v)
8429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
8439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* HP Color Recovery contributed by:  Alex De Bruyn (ad@lms.be)
8449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
8459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    * on the root window AND the colormap obtainable by XGetRGBColormaps
8469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    * for that atom must be set on the window.  (see also tkInitWindow)
8479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    * If that colormap is not set, the output will look stripy.
8489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    */
8499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* Setup color tables with gamma correction */
8519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   int i;
8529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   double g;
8539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   g = 1.0 / v->RedGamma;
8559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   for (i=0; i<256; i++) {
8569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      GLint red = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[0][i]/255.0, g ));
8579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      v->hpcr_rgbTbl[0][i] = CLAMP( red, 16, 239 );
8589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
859c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
860c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   g = 1.0 / v->GreenGamma;
861c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   for (i=0; i<256; i++) {
862c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      GLint green = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[1][i]/255.0, g ));
8639e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      v->hpcr_rgbTbl[1][i] = CLAMP( green, 16, 239 );
8649e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
8659e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8669e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   g = 1.0 / v->BlueGamma;
867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   for (i=0; i<256; i++) {
8689e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      GLint blue = IROUND_POS(255.0 * _mesa_pow( hpcr_rgbTbl[2][i]/255.0, g ));
8699e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      v->hpcr_rgbTbl[2][i] = CLAMP( blue, 32, 223 );
8709e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
8719e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->undithered_pf = PF_HPCR;  /* can't really disable dithering for now */
8729e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->dithered_pf = PF_HPCR;
8739e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8749e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* which method should I use to clear */
8759e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* GL_FALSE: keep the ordinary method  */
8769e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* GL_TRUE : clear with dither pattern */
8779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->hpcr_clear_flag = _mesa_getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE;
8789e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8799e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   if (v->hpcr_clear_flag) {
8809e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display,
8819e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                               DefaultRootWindow(v->display),
8829e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                               16, 2, 8);
8839e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#ifndef XFree86Server
8849e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      v->hpcr_clear_ximage = XGetImage(v->display, v->hpcr_clear_pixmap,
8859e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org                                       0, 0, 16, 2, AllPlanes, ZPixmap);
8869e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org#endif
8879e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
8889e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org}
8899e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8909e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
8919e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/**
8929e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org * Setup RGB rendering for a window with a True/DirectColor visual.
8939e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org */
8949e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgstatic void
8959e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.orgsetup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap)
8969e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org{
8979e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   unsigned long rmask, gmask, bmask;
8989e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   (void) buffer;
8999e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   (void) cmap;
9009e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
9019e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* Compute red multiplier (mask) and bit shift */
9029e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->rshift = 0;
9039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   rmask = GET_REDMASK(v);
9049e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   while ((rmask & 1)==0) {
9059e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      v->rshift++;
9069e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      rmask = rmask >> 1;
9079e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
9089e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
9099e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* Compute green multiplier (mask) and bit shift */
9109e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->gshift = 0;
9119e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   gmask = GET_GREENMASK(v);
9129e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   while ((gmask & 1)==0) {
9139e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      v->gshift++;
9149e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      gmask = gmask >> 1;
9159e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
9169e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
9179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /* Compute blue multiplier (mask) and bit shift */
9189e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   v->bshift = 0;
9199e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   bmask = GET_BLUEMASK(v);
9209e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   while ((bmask & 1)==0) {
9219e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      v->bshift++;
9229e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      bmask = bmask >> 1;
9239e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   }
9249e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
9259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   /*
9269e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    * Compute component-to-pixel lookup tables and dithering kernel
9279e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org    */
9289e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org   {
9299e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      static GLubyte kernel[16] = {
9309e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          0*16,  8*16,  2*16, 10*16,
9319e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         12*16,  4*16, 14*16,  6*16,
9329e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org          3*16, 11*16,  1*16,  9*16,
9339e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         15*16,  7*16, 13*16,  5*16,
9349e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      };
9359e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      GLint rBits = _mesa_bitcount(rmask);
9369e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      GLint gBits = _mesa_bitcount(gmask);
9379e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      GLint bBits = _mesa_bitcount(bmask);
9389e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      GLint maxBits;
9399e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      GLuint i;
9409e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
9419e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      /* convert pixel components in [0,_mask] to RGB values in [0,255] */
9429e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      for (i=0; i<=rmask; i++)
9439e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         v->PixelToR[i] = (unsigned char) ((i * 255) / rmask);
9449e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      for (i=0; i<=gmask; i++)
9459e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         v->PixelToG[i] = (unsigned char) ((i * 255) / gmask);
9469e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      for (i=0; i<=bmask; i++)
9479e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         v->PixelToB[i] = (unsigned char) ((i * 255) / bmask);
9489e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
9499e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      /* convert RGB values from [0,255] to pixel components */
9509e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
9519e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      for (i=0;i<256;i++) {
9529e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         GLint r = gamma_adjust(v->RedGamma,   i, 255);
9539e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         GLint g = gamma_adjust(v->GreenGamma, i, 255);
9549e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         GLint b = gamma_adjust(v->BlueGamma,  i, 255);
9559e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         v->RtoPixel[i] = (r >> (8-rBits)) << v->rshift;
9569e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         v->GtoPixel[i] = (g >> (8-gBits)) << v->gshift;
9579e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org         v->BtoPixel[i] = (b >> (8-bBits)) << v->bshift;
9589e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      }
9599e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org      /* overflow protection */
960      for (i=256;i<512;i++) {
961         v->RtoPixel[i] = v->RtoPixel[255];
962         v->GtoPixel[i] = v->GtoPixel[255];
963         v->BtoPixel[i] = v->BtoPixel[255];
964      }
965
966      /* setup dithering kernel */
967      maxBits = rBits;
968      if (gBits > maxBits)  maxBits = gBits;
969      if (bBits > maxBits)  maxBits = bBits;
970      for (i=0;i<16;i++) {
971         v->Kernel[i] = kernel[i] >> maxBits;
972      }
973
974      v->undithered_pf = PF_Truecolor;
975      v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_Dither_True : PF_Truecolor;
976   }
977
978   /*
979    * Now check for TrueColor visuals which we can optimize.
980    */
981   if (   GET_REDMASK(v)  ==0x0000ff
982       && GET_GREENMASK(v)==0x00ff00
983       && GET_BLUEMASK(v) ==0xff0000
984       && CHECK_BYTE_ORDER(v)
985       && v->BitsPerPixel==32
986       && sizeof(GLuint)==4
987       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
988      /* common 32 bpp config used on SGI, Sun */
989      v->undithered_pf = v->dithered_pf = PF_8A8B8G8R;
990   }
991   else if (GET_REDMASK(v)  ==0xff0000
992       &&   GET_GREENMASK(v)==0x00ff00
993       &&   GET_BLUEMASK(v) ==0x0000ff
994       && CHECK_BYTE_ORDER(v)
995       && v->BitsPerPixel==32
996       && sizeof(GLuint)==4
997       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
998      /* common 32 bpp config used on Linux, HP, IBM */
999      if (GET_VISUAL_DEPTH(v)==32)
1000	  v->undithered_pf = v->dithered_pf = PF_8A8R8G8B;
1001      else
1002	  v->undithered_pf = v->dithered_pf = PF_8R8G8B;
1003   }
1004   else if (GET_REDMASK(v)  ==0xff0000
1005       &&   GET_GREENMASK(v)==0x00ff00
1006       &&   GET_BLUEMASK(v) ==0x0000ff
1007       && CHECK_BYTE_ORDER(v)
1008       && v->BitsPerPixel==24
1009       && sizeof(GLuint)==4
1010       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1011      /* common packed 24 bpp config used on Linux */
1012      v->undithered_pf = v->dithered_pf = PF_8R8G8B24;
1013   }
1014   else if (GET_REDMASK(v)  ==0xf800
1015       &&   GET_GREENMASK(v)==0x07e0
1016       &&   GET_BLUEMASK(v) ==0x001f
1017       && CHECK_BYTE_ORDER(v)
1018       && v->BitsPerPixel==16
1019       && sizeof(GLushort)==2
1020       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1021      /* 5-6-5 color weight on common PC VGA boards */
1022      v->undithered_pf = PF_5R6G5B;
1023      v->dithered_pf = PF_Dither_5R6G5B;
1024   }
1025   else if (GET_REDMASK(v)  ==0xe0
1026       &&   GET_GREENMASK(v)==0x1c
1027       &&   GET_BLUEMASK(v) ==0x03
1028       && CHECK_FOR_HPCR(v)) {
1029      setup_8bit_hpcr( v );
1030   }
1031}
1032
1033
1034
1035/**
1036 * Setup RGB rendering for a window with a monochrome visual.
1037 */
1038static void
1039setup_monochrome( XMesaVisual v, XMesaBuffer b )
1040{
1041   (void) b;
1042   v->dithered_pf = v->undithered_pf = PF_1Bit;
1043   /* if black=1 then we must flip pixel values */
1044   v->bitFlip = (GET_BLACK_PIXEL(v) != 0);
1045}
1046
1047
1048
1049/**
1050 * When a context is bound for the first time, we can finally finish
1051 * initializing the context's visual and buffer information.
1052 * \param v  the XMesaVisual to initialize
1053 * \param b  the XMesaBuffer to initialize (may be NULL)
1054 * \param rgb_flag  TRUE = RGBA mode, FALSE = color index mode
1055 * \param window  the window/pixmap we're rendering into
1056 * \param cmap  the colormap associated with the window/pixmap
1057 * \return GL_TRUE=success, GL_FALSE=failure
1058 */
1059static GLboolean
1060initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b,
1061                             GLboolean rgb_flag, XMesaDrawable window,
1062                             XMesaColormap cmap)
1063{
1064   ASSERT(!b || b->xm_visual == v);
1065
1066   /* Save true bits/pixel */
1067   v->BitsPerPixel = bits_per_pixel(v);
1068   assert(v->BitsPerPixel > 0);
1069
1070   if (rgb_flag == GL_FALSE) {
1071      /* COLOR-INDEXED WINDOW:
1072       * Even if the visual is TrueColor or DirectColor we treat it as
1073       * being color indexed.  This is weird but might be useful to someone.
1074       */
1075      v->dithered_pf = v->undithered_pf = PF_Index;
1076      v->mesa_visual.indexBits = GET_VISUAL_DEPTH(v);
1077   }
1078   else {
1079      /* RGB WINDOW:
1080       * We support RGB rendering into almost any kind of visual.
1081       */
1082      const int xclass = v->mesa_visual.visualType;
1083      if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
1084	 setup_truecolor( v, b, cmap );
1085      }
1086      else if (xclass == GLX_STATIC_GRAY && GET_VISUAL_DEPTH(v) == 1) {
1087	 setup_monochrome( v, b );
1088      }
1089      else if (xclass == GLX_GRAY_SCALE || xclass == GLX_STATIC_GRAY) {
1090         if (!setup_grayscale( client, v, b, cmap )) {
1091            return GL_FALSE;
1092         }
1093      }
1094      else if ((xclass == GLX_PSEUDO_COLOR || xclass == GLX_STATIC_COLOR)
1095               && GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) {
1096	 if (!setup_dithered_color( client, v, b, cmap )) {
1097            return GL_FALSE;
1098         }
1099      }
1100      else {
1101	 _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual.\n");
1102	 return GL_FALSE;
1103      }
1104      v->mesa_visual.indexBits = 0;
1105
1106      if (_mesa_getenv("MESA_NO_DITHER")) {
1107	 v->dithered_pf = v->undithered_pf;
1108      }
1109   }
1110
1111
1112   /*
1113    * If MESA_INFO env var is set print out some debugging info
1114    * which can help Brian figure out what's going on when a user
1115    * reports bugs.
1116    */
1117   if (_mesa_getenv("MESA_INFO")) {
1118      _mesa_printf("X/Mesa visual = %p\n", (void *) v);
1119      _mesa_printf("X/Mesa dithered pf = %u\n", v->dithered_pf);
1120      _mesa_printf("X/Mesa undithered pf = %u\n", v->undithered_pf);
1121      _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level);
1122      _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v));
1123      _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
1124   }
1125
1126   if (b && window) {
1127      /* Do window-specific initializations */
1128
1129      /* these should have been set in create_xmesa_buffer */
1130      ASSERT(b->frontxrb->drawable == window);
1131      ASSERT(b->frontxrb->pixmap == (XMesaPixmap) window);
1132
1133      /* Setup for single/double buffering */
1134      if (v->mesa_visual.doubleBufferMode) {
1135         /* Double buffered */
1136         b->shm = check_for_xshm( v->display );
1137      }
1138
1139      /* X11 graphics contexts */
1140#ifdef XFree86Server
1141      b->gc = CreateScratchGC(v->display, window->depth);
1142#else
1143      b->gc = XCreateGC( v->display, window, 0, NULL );
1144#endif
1145      XMesaSetFunction( v->display, b->gc, GXcopy );
1146
1147      /* cleargc - for glClear() */
1148#ifdef XFree86Server
1149      b->cleargc = CreateScratchGC(v->display, window->depth);
1150#else
1151      b->cleargc = XCreateGC( v->display, window, 0, NULL );
1152#endif
1153      XMesaSetFunction( v->display, b->cleargc, GXcopy );
1154
1155      /*
1156       * Don't generate Graphics Expose/NoExpose events in swapbuffers().
1157       * Patch contributed by Michael Pichler May 15, 1995.
1158       */
1159#ifdef XFree86Server
1160      b->swapgc = CreateScratchGC(v->display, window->depth);
1161      {
1162         CARD32 v[1];
1163         v[0] = FALSE;
1164         dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL);
1165      }
1166#else
1167      {
1168         XGCValues gcvalues;
1169         gcvalues.graphics_exposures = False;
1170         b->swapgc = XCreateGC(v->display, window,
1171                               GCGraphicsExposures, &gcvalues);
1172      }
1173#endif
1174      XMesaSetFunction( v->display, b->swapgc, GXcopy );
1175      /*
1176       * Set fill style and tile pixmap once for all for HPCR stuff
1177       * (instead of doing it each time in clear_color_HPCR_pixmap())
1178       * Initialize whole stuff
1179       * Patch contributed by Jacques Leroy March 8, 1998.
1180       */
1181      if (v->hpcr_clear_flag && b->backxrb && b->backxrb->pixmap) {
1182         int i;
1183         for (i = 0; i < 16; i++) {
1184            XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0);
1185            XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0);
1186         }
1187         XMesaPutImage(b->display, (XMesaDrawable) v->hpcr_clear_pixmap,
1188                       b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2);
1189         XMesaSetFillStyle( v->display, b->cleargc, FillTiled);
1190         XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap );
1191      }
1192
1193      /* Initialize the row buffer XImage for use in write_color_span() */
1194#ifdef XFree86Server
1195      b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1,
1196				     (char *)MALLOC(MAX_WIDTH*4));
1197#else
1198      b->rowimage = XCreateImage( v->display,
1199                                  v->visinfo->visual,
1200                                  v->visinfo->depth,
1201                                  ZPixmap, 0,           /*format, offset*/
1202                                  (char*) MALLOC(MAX_WIDTH*4),  /*data*/
1203                                  MAX_WIDTH, 1,         /*width, height*/
1204                                  32,                   /*bitmap_pad*/
1205                                  0                     /*bytes_per_line*/ );
1206#endif
1207      if (!b->rowimage)
1208         return GL_FALSE;
1209   }
1210
1211   return GL_TRUE;
1212}
1213
1214
1215
1216/*
1217 * Convert an RGBA color to a pixel value.
1218 */
1219unsigned long
1220xmesa_color_to_pixel(GLcontext *ctx,
1221                     GLubyte r, GLubyte g, GLubyte b, GLubyte a,
1222                     GLuint pixelFormat)
1223{
1224   XMesaContext xmesa = XMESA_CONTEXT(ctx);
1225   switch (pixelFormat) {
1226      case PF_Index:
1227         return 0;
1228      case PF_Truecolor:
1229         {
1230            unsigned long p;
1231            PACK_TRUECOLOR( p, r, g, b );
1232            return p;
1233         }
1234      case PF_8A8B8G8R:
1235         return PACK_8A8B8G8R( r, g, b, a );
1236      case PF_8A8R8G8B:
1237         return PACK_8A8R8G8B( r, g, b, a );
1238      case PF_8R8G8B:
1239         /* fall through */
1240      case PF_8R8G8B24:
1241         return PACK_8R8G8B( r, g, b );
1242      case PF_5R6G5B:
1243         return PACK_5R6G5B( r, g, b );
1244      case PF_Dither:
1245         {
1246            DITHER_SETUP;
1247            return DITHER( 1, 0, r, g, b );
1248         }
1249      case PF_1Bit:
1250         /* 382 = (3*255)/2 */
1251         return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
1252      case PF_HPCR:
1253         return DITHER_HPCR(1, 1, r, g, b);
1254      case PF_Lookup:
1255         {
1256            LOOKUP_SETUP;
1257            return LOOKUP( r, g, b );
1258         }
1259      case PF_Grayscale:
1260         return GRAY_RGB( r, g, b );
1261      case PF_Dither_True:
1262         /* fall through */
1263      case PF_Dither_5R6G5B:
1264         {
1265            unsigned long p;
1266            PACK_TRUEDITHER(p, 1, 0, r, g, b);
1267            return p;
1268         }
1269      default:
1270         _mesa_problem(ctx, "Bad pixel format in xmesa_color_to_pixel");
1271   }
1272   return 0;
1273}
1274
1275
1276#define NUM_VISUAL_TYPES   6
1277
1278/**
1279 * Convert an X visual type to a GLX visual type.
1280 *
1281 * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.)
1282 *        to be converted.
1283 * \return If \c visualType is a valid X visual type, a GLX visual type will
1284 *         be returned.  Otherwise \c GLX_NONE will be returned.
1285 *
1286 * \note
1287 * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the
1288 * DRI CVS tree.
1289 */
1290static GLint
1291xmesa_convert_from_x_visual_type( int visualType )
1292{
1293    static const int glx_visual_types[ NUM_VISUAL_TYPES ] = {
1294	GLX_STATIC_GRAY,  GLX_GRAY_SCALE,
1295	GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
1296	GLX_TRUE_COLOR,   GLX_DIRECT_COLOR
1297    };
1298
1299    return ( (unsigned) visualType < NUM_VISUAL_TYPES )
1300	? glx_visual_types[ visualType ] : GLX_NONE;
1301}
1302
1303
1304/**********************************************************************/
1305/*****                       Public Functions                     *****/
1306/**********************************************************************/
1307
1308
1309/*
1310 * Create a new X/Mesa visual.
1311 * Input:  display - X11 display
1312 *         visinfo - an XVisualInfo pointer
1313 *         rgb_flag - GL_TRUE = RGB mode,
1314 *                    GL_FALSE = color index mode
1315 *         alpha_flag - alpha buffer requested?
1316 *         db_flag - GL_TRUE = double-buffered,
1317 *                   GL_FALSE = single buffered
1318 *         stereo_flag - stereo visual?
1319 *         ximage_flag - GL_TRUE = use an XImage for back buffer,
1320 *                       GL_FALSE = use an off-screen pixmap for back buffer
1321 *         depth_size - requested bits/depth values, or zero
1322 *         stencil_size - requested bits/stencil values, or zero
1323 *         accum_red_size - requested bits/red accum values, or zero
1324 *         accum_green_size - requested bits/green accum values, or zero
1325 *         accum_blue_size - requested bits/blue accum values, or zero
1326 *         accum_alpha_size - requested bits/alpha accum values, or zero
1327 *         num_samples - number of samples/pixel if multisampling, or zero
1328 *         level - visual level, usually 0
1329 *         visualCaveat - ala the GLX extension, usually GLX_NONE
1330 * Return;  a new XMesaVisual or 0 if error.
1331 */
1332XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
1333                               XMesaVisualInfo visinfo,
1334                               GLboolean rgb_flag,
1335                               GLboolean alpha_flag,
1336                               GLboolean db_flag,
1337                               GLboolean stereo_flag,
1338                               GLboolean ximage_flag,
1339                               GLint depth_size,
1340                               GLint stencil_size,
1341                               GLint accum_red_size,
1342                               GLint accum_green_size,
1343                               GLint accum_blue_size,
1344                               GLint accum_alpha_size,
1345                               GLint num_samples,
1346                               GLint level,
1347                               GLint visualCaveat )
1348{
1349   char *gamma;
1350   XMesaVisual v;
1351   GLint red_bits, green_bits, blue_bits, alpha_bits;
1352
1353#ifndef XFree86Server
1354   /* For debugging only */
1355   if (_mesa_getenv("MESA_XSYNC")) {
1356      /* This makes debugging X easier.
1357       * In your debugger, set a breakpoint on _XError to stop when an
1358       * X protocol error is generated.
1359       */
1360      XSynchronize( display, 1 );
1361   }
1362#endif
1363
1364   v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual);
1365   if (!v) {
1366      return NULL;
1367   }
1368
1369   /*
1370    * In the X server, NULL is passed in for the display.  It will have
1371    * to be set before using this visual.  See XMesaSetVisualDisplay()
1372    * below.
1373    */
1374   v->display = display;
1375
1376   /* Save a copy of the XVisualInfo struct because the user may X_mesa_free()
1377    * the struct but we may need some of the information contained in it
1378    * at a later time.
1379    */
1380#ifndef XFree86Server
1381   v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
1382   if(!v->visinfo) {
1383      _mesa_free(v);
1384      return NULL;
1385   }
1386   MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
1387#endif
1388
1389   /* check for MESA_GAMMA environment variable */
1390   gamma = _mesa_getenv("MESA_GAMMA");
1391   if (gamma) {
1392      v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0;
1393      sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma );
1394      if (v->RedGamma<=0.0)    v->RedGamma = 1.0;
1395      if (v->GreenGamma<=0.0)  v->GreenGamma = v->RedGamma;
1396      if (v->BlueGamma<=0.0)   v->BlueGamma = v->RedGamma;
1397   }
1398   else {
1399      v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0;
1400   }
1401
1402   v->ximage_flag = ximage_flag;
1403
1404#ifdef XFree86Server
1405   /* We could calculate these values by ourselves.  nplanes is either the sum
1406    * of the red, green, and blue bits or the number index bits.
1407    * ColormapEntries is either (1U << index_bits) or
1408    * (1U << max(redBits, greenBits, blueBits)).
1409    */
1410   assert(visinfo->nplanes > 0);
1411   v->nplanes = visinfo->nplanes;
1412   v->ColormapEntries = visinfo->ColormapEntries;
1413
1414   v->mesa_visual.redMask = visinfo->redMask;
1415   v->mesa_visual.greenMask = visinfo->greenMask;
1416   v->mesa_visual.blueMask = visinfo->blueMask;
1417   v->mesa_visual.visualID = visinfo->vid;
1418   v->mesa_visual.screen = 0; /* FIXME: What should be done here? */
1419#else
1420   v->mesa_visual.redMask = visinfo->red_mask;
1421   v->mesa_visual.greenMask = visinfo->green_mask;
1422   v->mesa_visual.blueMask = visinfo->blue_mask;
1423   v->mesa_visual.visualID = visinfo->visualid;
1424   v->mesa_visual.screen = visinfo->screen;
1425#endif
1426
1427#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus))
1428   v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class);
1429#else
1430   v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class);
1431#endif
1432
1433   v->mesa_visual.visualRating = visualCaveat;
1434
1435   (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 );
1436
1437   {
1438      const int xclass = v->mesa_visual.visualType;
1439      if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
1440         red_bits   = _mesa_bitcount(GET_REDMASK(v));
1441         green_bits = _mesa_bitcount(GET_GREENMASK(v));
1442         blue_bits  = _mesa_bitcount(GET_BLUEMASK(v));
1443         alpha_bits = 0;
1444      }
1445      else {
1446         /* this is an approximation */
1447         int depth;
1448         depth = GET_VISUAL_DEPTH(v);
1449         red_bits = depth / 3;
1450         depth -= red_bits;
1451         green_bits = depth / 2;
1452         depth -= green_bits;
1453         blue_bits = depth;
1454         alpha_bits = 0;
1455         assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) );
1456      }
1457   }
1458
1459   if (alpha_flag && alpha_bits == 0)
1460      alpha_bits = 8;
1461
1462   _mesa_initialize_visual( &v->mesa_visual,
1463                            rgb_flag, db_flag, stereo_flag,
1464                            red_bits, green_bits,
1465                            blue_bits, alpha_bits,
1466                            v->mesa_visual.indexBits,
1467                            depth_size,
1468                            stencil_size,
1469                            accum_red_size, accum_green_size,
1470                            accum_blue_size, accum_alpha_size,
1471                            0 );
1472
1473   /* XXX minor hack */
1474   v->mesa_visual.level = level;
1475   return v;
1476}
1477
1478
1479void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v )
1480{
1481    v->display = dpy;
1482}
1483
1484
1485void XMesaDestroyVisual( XMesaVisual v )
1486{
1487#ifndef XFree86Server
1488   _mesa_free(v->visinfo);
1489#endif
1490   _mesa_free(v);
1491}
1492
1493
1494
1495/**
1496 * Create a new XMesaContext.
1497 * \param v  the XMesaVisual
1498 * \param share_list  another XMesaContext with which to share display
1499 *                    lists or NULL if no sharing is wanted.
1500 * \return an XMesaContext or NULL if error.
1501 */
1502XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
1503{
1504   static GLboolean firstTime = GL_TRUE;
1505   XMesaContext c;
1506   GLcontext *mesaCtx;
1507   struct dd_function_table functions;
1508   TNLcontext *tnl;
1509
1510   if (firstTime) {
1511      _glthread_INIT_MUTEX(_xmesa_lock);
1512      firstTime = GL_FALSE;
1513   }
1514
1515   /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
1516   c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
1517   if (!c)
1518      return NULL;
1519
1520   mesaCtx = &(c->mesa);
1521
1522   /* initialize with default driver functions, then plug in XMesa funcs */
1523   _mesa_init_driver_functions(&functions);
1524   xmesa_init_driver_functions(v, &functions);
1525   if (!_mesa_initialize_context(mesaCtx, &v->mesa_visual,
1526                      share_list ? &(share_list->mesa) : (GLcontext *) NULL,
1527                      &functions, (void *) c)) {
1528      _mesa_free(c);
1529      return NULL;
1530   }
1531
1532   _mesa_enable_sw_extensions(mesaCtx);
1533   _mesa_enable_1_3_extensions(mesaCtx);
1534   _mesa_enable_1_4_extensions(mesaCtx);
1535   _mesa_enable_1_5_extensions(mesaCtx);
1536   _mesa_enable_2_0_extensions(mesaCtx);
1537#if ENABLE_EXT_texure_compression_s3tc
1538    if (c->Mesa_DXTn) {
1539       _mesa_enable_extension(mesaCtx, "GL_EXT_texture_compression_s3tc");
1540       _mesa_enable_extension(mesaCtx, "GL_S3_s3tc");
1541    }
1542    _mesa_enable_extension(mesaCtx, "GL_3DFX_texture_compression_FXT1");
1543#endif
1544#if ENABLE_EXT_timer_query
1545    _mesa_enable_extension(mesaCtx, "GL_EXT_timer_query");
1546#endif
1547
1548   /* finish up xmesa context initializations */
1549   c->swapbytes = CHECK_BYTE_ORDER(v) ? GL_FALSE : GL_TRUE;
1550   c->xm_visual = v;
1551   c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
1552   c->display = v->display;
1553   c->pixelformat = v->dithered_pf;      /* Dithering is enabled by default */
1554
1555   /* Initialize the software rasterizer and helper modules.
1556    */
1557   if (!_swrast_CreateContext( mesaCtx ) ||
1558       !_vbo_CreateContext( mesaCtx ) ||
1559       !_tnl_CreateContext( mesaCtx ) ||
1560       !_swsetup_CreateContext( mesaCtx )) {
1561      _mesa_free_context_data(&c->mesa);
1562      _mesa_free(c);
1563      return NULL;
1564   }
1565
1566   /* tnl setup */
1567   tnl = TNL_CONTEXT(mesaCtx);
1568   tnl->Driver.RunPipeline = _tnl_run_pipeline;
1569   /* swrast setup */
1570   xmesa_register_swrast_functions( mesaCtx );
1571   _swsetup_Wakeup(mesaCtx);
1572
1573   return c;
1574}
1575
1576
1577
1578void XMesaDestroyContext( XMesaContext c )
1579{
1580   GLcontext *mesaCtx = &c->mesa;
1581#ifdef FX
1582   XMesaBuffer xmbuf = XMESA_BUFFER(mesaCtx->DrawBuffer);
1583
1584   if (xmbuf && xmbuf->FXctx)
1585      fxMesaDestroyContext(xmbuf->FXctx);
1586#endif
1587   _swsetup_DestroyContext( mesaCtx );
1588   _swrast_DestroyContext( mesaCtx );
1589   _tnl_DestroyContext( mesaCtx );
1590   _vbo_DestroyContext( mesaCtx );
1591   _mesa_free_context_data( mesaCtx );
1592   _mesa_free( c );
1593}
1594
1595
1596
1597/**
1598 * Private function for creating an XMesaBuffer which corresponds to an
1599 * X window or pixmap.
1600 * \param v  the window's XMesaVisual
1601 * \param w  the window we're wrapping
1602 * \param c  context used to initialize the buffer if 3Dfx mode in use.
1603 * \return  new XMesaBuffer or NULL if error
1604 */
1605XMesaBuffer
1606XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c)
1607{
1608#ifndef XFree86Server
1609   XWindowAttributes attr;
1610#endif
1611#ifdef FX
1612   char *fxEnvVar;
1613#endif
1614   int client = 0;
1615   XMesaBuffer b;
1616   XMesaColormap cmap;
1617
1618   assert(v);
1619   assert(w);
1620   (void) c;
1621
1622   /* Check that window depth matches visual depth */
1623#ifdef XFree86Server
1624   client = CLIENT_ID(((XMesaDrawable)w)->id);
1625
1626   if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) {
1627      _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
1628                    GET_VISUAL_DEPTH(v), ((XMesaDrawable) w)->depth);
1629      return NULL;
1630   }
1631#else
1632   XGetWindowAttributes( v->display, w, &attr );
1633
1634   if (GET_VISUAL_DEPTH(v) != attr.depth) {
1635      _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
1636                    GET_VISUAL_DEPTH(v), attr.depth);
1637      return NULL;
1638   }
1639#endif
1640
1641   /* Find colormap */
1642#ifdef XFree86Server
1643   cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
1644#else
1645   if (attr.colormap) {
1646      cmap = attr.colormap;
1647   }
1648   else {
1649      _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w);
1650      /* this is weird, a window w/out a colormap!? */
1651      /* OK, let's just allocate a new one and hope for the best */
1652      cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
1653   }
1654#endif
1655
1656   b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
1657   if (!b)
1658      return NULL;
1659
1660   if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
1661                                      (XMesaDrawable) w, cmap )) {
1662      free_xmesa_buffer(client, b);
1663      return NULL;
1664   }
1665
1666#ifdef FX
1667   fxEnvVar = _mesa_getenv("MESA_GLX_FX");
1668   if (fxEnvVar) {
1669     if (fxEnvVar[0]!='d') {
1670       int attribs[100];
1671       int numAttribs = 0;
1672       int hw;
1673       if (v->mesa_visual.depthBits > 0) {
1674	 attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
1675	 attribs[numAttribs++] = v->mesa_visual.depthBits;
1676       }
1677       if (v->mesa_visual.doubleBufferMode) {
1678	 attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
1679       }
1680       if (v->mesa_visual.accumRedBits > 0) {
1681	 attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
1682	 attribs[numAttribs++] = v->mesa_visual.accumRedBits;
1683       }
1684       if (v->mesa_visual.stencilBits > 0) {
1685         attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
1686         attribs[numAttribs++] = v->mesa_visual.stencilBits;
1687       }
1688       if (v->mesa_visual.alphaBits > 0) {
1689         attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
1690         attribs[numAttribs++] = v->mesa_visual.alphaBits;
1691       }
1692       if (1) {
1693         attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
1694         attribs[numAttribs++] = (int) &(c->mesa);
1695       }
1696       attribs[numAttribs++] = FXMESA_NONE;
1697
1698       /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */
1699       hw = fxMesaSelectCurrentBoard(0);
1700
1701       /* if these fail, there's a new bug somewhere */
1702       ASSERT(b->mesa_buffer.Width > 0);
1703       ASSERT(b->mesa_buffer.Height > 0);
1704
1705       if ((hw == GR_SSTTYPE_VOODOO) || (hw == GR_SSTTYPE_Voodoo2)) {
1706         b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
1707                                            b->mesa_buffer.Height, attribs);
1708         if ((v->undithered_pf!=PF_Index) && (b->backxrb->ximage)) {
1709	   b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
1710	   if (b->FXctx && (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')) {
1711	     b->FXwindowHack = GL_TRUE;
1712	     FX_grSstControl(GR_CONTROL_DEACTIVATE);
1713	   }
1714           else {
1715	     b->FXwindowHack = GL_FALSE;
1716	   }
1717         }
1718       }
1719       else {
1720         if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
1721	   b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
1722					  GR_REFRESH_75Hz, attribs);
1723         else
1724	   b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width,
1725                                              b->mesa_buffer.Height, attribs);
1726         b->FXisHackUsable = GL_FALSE;
1727         b->FXwindowHack = GL_FALSE;
1728       }
1729       /*
1730       fprintf(stderr,
1731               "voodoo %d, wid %d height %d hack: usable %d active %d\n",
1732               hw, b->mesa_buffer.Width, b->mesa_buffer.Height,
1733	       b->FXisHackUsable, b->FXwindowHack);
1734       */
1735     }
1736   }
1737   else {
1738      _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n");
1739      _mesa_warning(NULL, "         you have not defined the MESA_GLX_FX env. var.\n");
1740      _mesa_warning(NULL, "         (check the README.3DFX file for more information).\n\n");
1741      _mesa_warning(NULL, "         you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
1742   }
1743#endif
1744
1745   return b;
1746}
1747
1748
1749XMesaBuffer
1750XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
1751{
1752   return XMesaCreateWindowBuffer2( v, w, NULL );
1753}
1754
1755
1756/**
1757 * Create a new XMesaBuffer from an X pixmap.
1758 *
1759 * \param v    the XMesaVisual
1760 * \param p    the pixmap
1761 * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or
1762 *             \c GLX_DIRECT_COLOR visual for the pixmap
1763 * \returns new XMesaBuffer or NULL if error
1764 */
1765XMesaBuffer
1766XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
1767{
1768   int client = 0;
1769   XMesaBuffer b;
1770
1771   assert(v);
1772
1773   b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
1774   if (!b)
1775      return NULL;
1776
1777#ifdef XFree86Server
1778   client = CLIENT_ID(((XMesaDrawable)p)->id);
1779#endif
1780
1781   if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
1782				     (XMesaDrawable) p, cmap)) {
1783      free_xmesa_buffer(client, b);
1784      return NULL;
1785   }
1786
1787   return b;
1788}
1789
1790
1791
1792XMesaBuffer
1793XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
1794                   unsigned int width, unsigned int height)
1795{
1796#ifdef XFree86Server
1797   return 0;
1798#else
1799   int client = 0;
1800   XMesaWindow root;
1801   XMesaDrawable drawable;  /* X Pixmap Drawable */
1802   XMesaBuffer b;
1803
1804   /* allocate pixmap for front buffer */
1805   root = RootWindow( v->display, v->visinfo->screen );
1806   drawable = XCreatePixmap(v->display, root, width, height,
1807                            v->visinfo->depth);
1808   if (!drawable)
1809      return NULL;
1810
1811   b = create_xmesa_buffer(drawable, PBUFFER, v, cmap);
1812   if (!b)
1813      return NULL;
1814
1815   if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
1816				     drawable, cmap)) {
1817      free_xmesa_buffer(client, b);
1818      return NULL;
1819   }
1820
1821   return b;
1822#endif
1823}
1824
1825
1826
1827/*
1828 * Deallocate an XMesaBuffer structure and all related info.
1829 */
1830void XMesaDestroyBuffer( XMesaBuffer b )
1831{
1832   int client = 0;
1833
1834#ifdef XFree86Server
1835   if (b->frontxrb->drawable)
1836       client = CLIENT_ID(b->frontxrb->drawable->id);
1837#endif
1838
1839   if (b->gc)  XMesaFreeGC( b->xm_visual->display, b->gc );
1840   if (b->cleargc)  XMesaFreeGC( b->xm_visual->display, b->cleargc );
1841   if (b->swapgc)  XMesaFreeGC( b->xm_visual->display, b->swapgc );
1842
1843   if (b->xm_visual->mesa_visual.doubleBufferMode)
1844   {
1845      if (b->backxrb->ximage) {
1846#if defined(USE_XSHM) && !defined(XFree86Server)
1847         if (b->shm) {
1848            XShmDetach( b->xm_visual->display, &b->shminfo );
1849            XDestroyImage( b->backxrb->ximage );
1850            shmdt( b->shminfo.shmaddr );
1851         }
1852         else
1853#endif
1854            XMesaDestroyImage( b->backxrb->ximage );
1855      }
1856      if (b->backxrb->pixmap) {
1857         XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap );
1858         if (b->xm_visual->hpcr_clear_flag) {
1859            XMesaFreePixmap( b->xm_visual->display,
1860                             b->xm_visual->hpcr_clear_pixmap );
1861            XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage );
1862         }
1863      }
1864   }
1865   if (b->rowimage) {
1866      _mesa_free( b->rowimage->data );
1867      b->rowimage->data = NULL;
1868      XMesaDestroyImage( b->rowimage );
1869   }
1870
1871   free_xmesa_buffer(client, b);
1872}
1873
1874
1875/**
1876 * Query the current window size and update the corresponding GLframebuffer
1877 * and all attached renderbuffers.
1878 * Called when:
1879 *  1. the first time a buffer is bound to a context.
1880 *  2. from glViewport to poll for window size changes
1881 *  3. from the XMesaResizeBuffers() API function.
1882 */
1883void
1884xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
1885{
1886   GLuint width, height;
1887   xmesa_get_window_size(xmctx->display, drawBuffer, &width, &height);
1888   if (drawBuffer->mesa_buffer.Width != width ||
1889       drawBuffer->mesa_buffer.Height != height) {
1890      _mesa_resize_framebuffer(&(xmctx->mesa),
1891                               &(drawBuffer->mesa_buffer), width, height);
1892   }
1893   drawBuffer->mesa_buffer.Initialized = GL_TRUE; /* XXX TEMPORARY? */
1894}
1895
1896
1897/*
1898 * Bind buffer b to context c and make c the current rendering context.
1899 */
1900GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b )
1901{
1902   return XMesaMakeCurrent2( c, b, b );
1903}
1904
1905
1906/*
1907 * Bind buffer b to context c and make c the current rendering context.
1908 */
1909GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
1910                             XMesaBuffer readBuffer )
1911{
1912   if (c) {
1913      if (!drawBuffer || !readBuffer)
1914         return GL_FALSE;  /* must specify buffers! */
1915
1916#ifdef FX
1917      if (drawBuffer->FXctx) {
1918         fxMesaMakeCurrent(drawBuffer->FXctx);
1919
1920         c->xm_buffer = drawBuffer;
1921
1922         return GL_TRUE;
1923      }
1924#endif
1925      if (&(c->mesa) == _mesa_get_current_context()
1926          && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
1927          && c->mesa.ReadBuffer == &readBuffer->mesa_buffer
1928          && XMESA_BUFFER(c->mesa.DrawBuffer)->wasCurrent) {
1929         /* same context and buffer, do nothing */
1930         return GL_TRUE;
1931      }
1932
1933      c->xm_buffer = drawBuffer;
1934
1935      /* Call this periodically to detect when the user has begun using
1936       * GL rendering from multiple threads.
1937       */
1938      _glapi_check_multithread();
1939
1940      xmesa_check_and_update_buffer_size(c, drawBuffer);
1941      if (readBuffer != drawBuffer)
1942         xmesa_check_and_update_buffer_size(c, readBuffer);
1943
1944      _mesa_make_current(&(c->mesa),
1945                         &drawBuffer->mesa_buffer,
1946                         &readBuffer->mesa_buffer);
1947
1948      if (c->xm_visual->mesa_visual.rgbMode) {
1949         /*
1950          * Must recompute and set these pixel values because colormap
1951          * can be different for different windows.
1952          */
1953         c->clearpixel = xmesa_color_to_pixel( &c->mesa,
1954                                               c->clearcolor[0],
1955                                               c->clearcolor[1],
1956                                               c->clearcolor[2],
1957                                               c->clearcolor[3],
1958                                               c->xm_visual->undithered_pf);
1959         XMesaSetForeground(c->display, drawBuffer->cleargc, c->clearpixel);
1960      }
1961
1962      /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
1963      drawBuffer->wasCurrent = GL_TRUE;
1964   }
1965   else {
1966      /* Detach */
1967      _mesa_make_current( NULL, NULL, NULL );
1968   }
1969   return GL_TRUE;
1970}
1971
1972
1973/*
1974 * Unbind the context c from its buffer.
1975 */
1976GLboolean XMesaUnbindContext( XMesaContext c )
1977{
1978   /* A no-op for XFree86 integration purposes */
1979   return GL_TRUE;
1980}
1981
1982
1983XMesaContext XMesaGetCurrentContext( void )
1984{
1985   GET_CURRENT_CONTEXT(ctx);
1986   if (ctx) {
1987      XMesaContext xmesa = XMESA_CONTEXT(ctx);
1988      return xmesa;
1989   }
1990   else {
1991      return 0;
1992   }
1993}
1994
1995
1996XMesaBuffer XMesaGetCurrentBuffer( void )
1997{
1998   GET_CURRENT_CONTEXT(ctx);
1999   if (ctx) {
2000      XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
2001      return xmbuf;
2002   }
2003   else {
2004      return 0;
2005   }
2006}
2007
2008
2009/* New in Mesa 3.1 */
2010XMesaBuffer XMesaGetCurrentReadBuffer( void )
2011{
2012   GET_CURRENT_CONTEXT(ctx);
2013   if (ctx) {
2014      return XMESA_BUFFER(ctx->ReadBuffer);
2015   }
2016   else {
2017      return 0;
2018   }
2019}
2020
2021
2022GLboolean XMesaForceCurrent(XMesaContext c)
2023{
2024   if (c) {
2025      if (&(c->mesa) != _mesa_get_current_context()) {
2026	 _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer);
2027      }
2028   }
2029   else {
2030      _mesa_make_current(NULL, NULL, NULL);
2031   }
2032   return GL_TRUE;
2033}
2034
2035
2036GLboolean XMesaLoseCurrent(XMesaContext c)
2037{
2038   (void) c;
2039   _mesa_make_current(NULL, NULL, NULL);
2040   return GL_TRUE;
2041}
2042
2043
2044/*
2045 * Switch 3Dfx support hack between window and full-screen mode.
2046 */
2047GLboolean XMesaSetFXmode( GLint mode )
2048{
2049#ifdef FX
2050   const char *fx = _mesa_getenv("MESA_GLX_FX");
2051   if (fx && fx[0] != 'd') {
2052      GET_CURRENT_CONTEXT(ctx);
2053      GrHwConfiguration hw;
2054      if (!FX_grSstQueryHardware(&hw)) {
2055         /*fprintf(stderr, "!grSstQueryHardware\n");*/
2056         return GL_FALSE;
2057      }
2058      if (hw.num_sst < 1) {
2059         /*fprintf(stderr, "hw.num_sst < 1\n");*/
2060         return GL_FALSE;
2061      }
2062      if (ctx) {
2063         /* [dBorca] Hack alert:
2064	  * oh, this is sooo wrong: ctx above is
2065	  * really an fxMesaContext, not an XMesaContext
2066	  */
2067         XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
2068         if (mode == XMESA_FX_WINDOW) {
2069	    if (xmbuf->FXisHackUsable) {
2070	       FX_grSstControl(GR_CONTROL_DEACTIVATE);
2071	       xmbuf->FXwindowHack = GL_TRUE;
2072	       return GL_TRUE;
2073	    }
2074	 }
2075	 else if (mode == XMESA_FX_FULLSCREEN) {
2076	    FX_grSstControl(GR_CONTROL_ACTIVATE);
2077	    xmbuf->FXwindowHack = GL_FALSE;
2078	    return GL_TRUE;
2079	 }
2080	 else {
2081	    /* Error: Bad mode value */
2082	 }
2083      }
2084   }
2085   /*fprintf(stderr, "fallthrough\n");*/
2086#else
2087   (void) mode;
2088#endif
2089   return GL_FALSE;
2090}
2091
2092
2093
2094#ifdef FX
2095/*
2096 * Read image from VooDoo frame buffer into X/Mesa's back XImage.
2097 */
2098static void FXgetImage( XMesaBuffer b )
2099{
2100   GET_CURRENT_CONTEXT(ctx);
2101   static unsigned short pixbuf[MAX_WIDTH];
2102   GLuint x, y;
2103   GLuint width, height;
2104   XMesaContext xmesa = XMESA_CONTEXT(ctx);
2105
2106#ifdef XFree86Server
2107   x = b->frontxrb->pixmap->x;
2108   y = b->frontxrb->pixmap->y;
2109   width = b->frontxrb->pixmap->width;
2110   height = b->frontxrb->pixmap->height;
2111   depth = b->frontxrb->pixmap->depth;
2112#else
2113   xmesa_get_window_size(b->display, b, &width, &height);
2114   x = y = 0;
2115#endif
2116   if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) {
2117      b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width);
2118      b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height);
2119      if (b->mesa_buffer.Width & 1)
2120         b->mesa_buffer.Width--;  /* prevent odd width */
2121   }
2122
2123   /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */
2124   /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */
2125   if (b->xm_visual->undithered_pf==PF_5R6G5B) {
2126      /* Special case: 16bpp RGB */
2127      grLfbReadRegion( GR_BUFFER_FRONTBUFFER,       /* src buffer */
2128                       0, b->FXctx->height - b->mesa_buffer.Height,  /*pos*/
2129                       b->mesa_buffer.Width, b->mesa_buffer.Height,  /* size */
2130                       b->mesa_buffer.Width * sizeof(GLushort), /* stride */
2131                       b->backxrb->ximage->data);         /* dest buffer */
2132   }
2133   else if (b->xm_visual->dithered_pf==PF_Dither
2134	    && GET_VISUAL_DEPTH(b->xm_visual)==8) {
2135      /* Special case: 8bpp RGB */
2136      for (y=0;y<b->mesa_buffer.Height;y++) {
2137         GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data
2138                        + b->backxrb->ximage->bytes_per_line * y;
2139         XDITHER_SETUP(y);
2140
2141         /* read row from 3Dfx frame buffer */
2142         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
2143                          0, b->FXctx->height-(b->mesa_buffer.Height-y),
2144                          b->mesa_buffer.Width, 1,
2145                          0,
2146                          pixbuf );
2147
2148         /* write to XImage back buffer */
2149         for (x=0;x<b->mesa_buffer.Width;x++) {
2150            GLubyte r = (pixbuf[x] & 0xf800) >> 8;
2151            GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
2152            GLubyte b = (pixbuf[x] & 0x001f) << 3;
2153            *ptr++ = XDITHER( x, r, g, b);
2154         }
2155      }
2156   }
2157   else {
2158      /* General case: slow! */
2159      for (y=0;y<b->mesa_buffer.Height;y++) {
2160         /* read row from 3Dfx frame buffer */
2161         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
2162                          0, b->FXctx->height-(b->mesa_buffer.Height-y),
2163                          b->mesa_buffer.Width, 1,
2164                          0,
2165                          pixbuf );
2166
2167         /* write to XImage back buffer */
2168         for (x=0;x<b->mesa_buffer.Width;x++) {
2169            XMesaPutPixel(b->backxrb->ximage,x,y,
2170			  xmesa_color_to_pixel(ctx,
2171					       (pixbuf[x] & 0xf800) >> 8,
2172					       (pixbuf[x] & 0x07e0) >> 3,
2173					       (pixbuf[x] & 0x001f) << 3,
2174					       0xff,
2175                                               b->xm_visual->undithered_pf));
2176         }
2177      }
2178   }
2179   /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */
2180}
2181#endif
2182
2183
2184/*
2185 * Copy the back buffer to the front buffer.  If there's no back buffer
2186 * this is a no-op.
2187 */
2188void XMesaSwapBuffers( XMesaBuffer b )
2189{
2190   GET_CURRENT_CONTEXT(ctx);
2191
2192   if (!b->backxrb) {
2193      /* single buffered */
2194      return;
2195   }
2196
2197   /* If we're swapping the buffer associated with the current context
2198    * we have to flush any pending rendering commands first.
2199    */
2200   if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
2201      _mesa_notifySwapBuffers(ctx);
2202
2203   if (b->db_mode) {
2204#ifdef FX
2205      if (b->FXctx) {
2206         fxMesaSwapBuffers();
2207
2208         if (b->FXwindowHack)
2209            FXgetImage(b);
2210         else
2211            return;
2212      }
2213#endif
2214     if (b->backxrb->ximage) {
2215	 /* Copy Ximage from host's memory to server's window */
2216#if defined(USE_XSHM) && !defined(XFree86Server)
2217	 if (b->shm) {
2218            /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2219	    XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
2220			  b->swapgc,
2221			  b->backxrb->ximage, 0, 0,
2222			  0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height,
2223                          False );
2224            /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2225	 }
2226	 else
2227#endif
2228         {
2229            /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2230            XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable,
2231			   b->swapgc,
2232			   b->backxrb->ximage, 0, 0,
2233			   0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height );
2234            /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2235         }
2236      }
2237      else {
2238	 /* Copy pixmap to window on server */
2239         /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2240	 XMesaCopyArea( b->xm_visual->display,
2241			b->backxrb->pixmap,   /* source drawable */
2242			b->frontxrb->drawable,  /* dest. drawable */
2243			b->swapgc,
2244			0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height,
2245			0, 0                 /* dest region */
2246		      );
2247         /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2248      }
2249   }
2250#if !defined(XFree86Server)
2251   XSync( b->xm_visual->display, False );
2252#endif
2253}
2254
2255
2256
2257/*
2258 * Copy sub-region of back buffer to front buffer
2259 */
2260void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
2261{
2262   GET_CURRENT_CONTEXT(ctx);
2263
2264   /* If we're swapping the buffer associated with the current context
2265    * we have to flush any pending rendering commands first.
2266    */
2267   if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
2268      _mesa_notifySwapBuffers(ctx);
2269
2270   if (!b->backxrb) {
2271      /* single buffered */
2272      return;
2273   }
2274
2275   if (b->db_mode) {
2276      int yTop = b->mesa_buffer.Height - y - height;
2277#ifdef FX
2278      if (b->FXctx) {
2279         fxMesaSwapBuffers();
2280         if (b->FXwindowHack)
2281            FXgetImage(b);
2282         else
2283            return;
2284      }
2285#endif
2286      if (b->backxrb->ximage) {
2287         /* Copy Ximage from host's memory to server's window */
2288#if defined(USE_XSHM) && !defined(XFree86Server)
2289         if (b->shm) {
2290            /* XXX assuming width and height aren't too large! */
2291            XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
2292                          b->swapgc,
2293                          b->backxrb->ximage, x, yTop,
2294                          x, yTop, width, height, False );
2295            /* wait for finished event??? */
2296         }
2297         else
2298#endif
2299         {
2300            /* XXX assuming width and height aren't too large! */
2301            XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable,
2302			   b->swapgc,
2303			   b->backxrb->ximage, x, yTop,
2304			   x, yTop, width, height );
2305         }
2306      }
2307      else {
2308         /* Copy pixmap to window on server */
2309         XMesaCopyArea( b->xm_visual->display,
2310			b->backxrb->pixmap,           /* source drawable */
2311			b->frontxrb->drawable,        /* dest. drawable */
2312			b->swapgc,
2313			x, yTop, width, height,  /* source region */
2314			x, yTop                  /* dest region */
2315                      );
2316      }
2317   }
2318}
2319
2320
2321/*
2322 * Return a pointer to the XMesa backbuffer Pixmap or XImage.  This function
2323 * is a way to get "under the hood" of X/Mesa so one can manipulate the
2324 * back buffer directly.
2325 * Output:  pixmap - pointer to back buffer's Pixmap, or 0
2326 *          ximage - pointer to back buffer's XImage, or NULL
2327 * Return:  GL_TRUE = context is double buffered
2328 *          GL_FALSE = context is single buffered
2329 */
2330#ifndef XFree86Server
2331GLboolean XMesaGetBackBuffer( XMesaBuffer b,
2332                              XMesaPixmap *pixmap,
2333                              XMesaImage **ximage )
2334{
2335   if (b->db_mode) {
2336      if (pixmap)
2337         *pixmap = b->backxrb->pixmap;
2338      if (ximage)
2339         *ximage = b->backxrb->ximage;
2340      return GL_TRUE;
2341   }
2342   else {
2343      *pixmap = 0;
2344      *ximage = NULL;
2345      return GL_FALSE;
2346   }
2347}
2348#endif /* XFree86Server */
2349
2350
2351/*
2352 * Return the depth buffer associated with an XMesaBuffer.
2353 * Input:  b - the XMesa buffer handle
2354 * Output:  width, height - size of buffer in pixels
2355 *          bytesPerValue - bytes per depth value (2 or 4)
2356 *          buffer - pointer to depth buffer values
2357 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
2358 */
2359GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
2360                               GLint *bytesPerValue, void **buffer )
2361{
2362   struct gl_renderbuffer *rb
2363      = b->mesa_buffer.Attachment[BUFFER_DEPTH].Renderbuffer;
2364   if (!rb || !rb->Data) {
2365      *width = 0;
2366      *height = 0;
2367      *bytesPerValue = 0;
2368      *buffer = 0;
2369      return GL_FALSE;
2370   }
2371   else {
2372      *width = b->mesa_buffer.Width;
2373      *height = b->mesa_buffer.Height;
2374      *bytesPerValue = b->mesa_buffer.Visual.depthBits <= 16
2375         ? sizeof(GLushort) : sizeof(GLuint);
2376      *buffer = rb->Data;
2377      return GL_TRUE;
2378   }
2379}
2380
2381
2382void XMesaFlush( XMesaContext c )
2383{
2384   if (c && c->xm_visual) {
2385#ifdef XFree86Server
2386      /* NOT_NEEDED */
2387#else
2388      XSync( c->xm_visual->display, False );
2389#endif
2390   }
2391}
2392
2393
2394
2395const char *XMesaGetString( XMesaContext c, int name )
2396{
2397   (void) c;
2398   if (name==XMESA_VERSION) {
2399      return "5.0";
2400   }
2401   else if (name==XMESA_EXTENSIONS) {
2402      return "";
2403   }
2404   else {
2405      return NULL;
2406   }
2407}
2408
2409
2410
2411XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d )
2412{
2413   XMesaBuffer b;
2414   for (b=XMesaBufferList; b; b=b->Next) {
2415      if (b->frontxrb->drawable == d && b->display == dpy) {
2416         return b;
2417      }
2418   }
2419   return NULL;
2420}
2421
2422
2423/**
2424 * Free/destroy all XMesaBuffers associated with given display.
2425 */
2426void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy)
2427{
2428   XMesaBuffer b, next;
2429   for (b = XMesaBufferList; b; b = next) {
2430      next = b->Next;
2431      if (b->display == dpy) {
2432         free_xmesa_buffer(0, b);
2433      }
2434   }
2435}
2436
2437
2438/*
2439 * Look for XMesaBuffers whose X window has been destroyed.
2440 * Deallocate any such XMesaBuffers.
2441 */
2442void XMesaGarbageCollect( void )
2443{
2444   XMesaBuffer b, next;
2445   for (b=XMesaBufferList; b; b=next) {
2446      next = b->Next;
2447      if (b->display && b->frontxrb->drawable && b->type == WINDOW) {
2448#ifdef XFree86Server
2449	 /* NOT_NEEDED */
2450#else
2451         XSync(b->display, False);
2452         if (!window_exists( b->display, b->frontxrb->drawable )) {
2453            /* found a dead window, free the ancillary info */
2454            XMesaDestroyBuffer( b );
2455         }
2456#endif
2457      }
2458   }
2459}
2460
2461
2462void XMesaReset( void )
2463{
2464    while (XMesaBufferList)
2465	XMesaDestroyBuffer(XMesaBufferList);
2466
2467    XMesaBufferList = NULL;
2468}
2469
2470
2471unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
2472                                GLfloat red, GLfloat green,
2473                                GLfloat blue, GLfloat alpha )
2474{
2475   GLcontext *ctx = &xmesa->mesa;
2476   GLint r = (GLint) (red   * 255.0F);
2477   GLint g = (GLint) (green * 255.0F);
2478   GLint b = (GLint) (blue  * 255.0F);
2479   GLint a = (GLint) (alpha * 255.0F);
2480
2481   switch (xmesa->pixelformat) {
2482      case PF_Index:
2483         return 0;
2484      case PF_Truecolor:
2485         {
2486            unsigned long p;
2487            PACK_TRUECOLOR( p, r, g, b );
2488            return p;
2489         }
2490      case PF_8A8B8G8R:
2491         return PACK_8A8B8G8R( r, g, b, a );
2492      case PF_8A8R8G8B:
2493         return PACK_8A8R8G8B( r, g, b, a );
2494      case PF_8R8G8B:
2495         return PACK_8R8G8B( r, g, b );
2496      case PF_5R6G5B:
2497         return PACK_5R6G5B( r, g, b );
2498      case PF_Dither:
2499         {
2500            DITHER_SETUP;
2501            return DITHER( x, y, r, g, b );
2502         }
2503      case PF_1Bit:
2504         /* 382 = (3*255)/2 */
2505         return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
2506      case PF_HPCR:
2507         return DITHER_HPCR(x, y, r, g, b);
2508      case PF_Lookup:
2509         {
2510            LOOKUP_SETUP;
2511            return LOOKUP( r, g, b );
2512         }
2513      case PF_Grayscale:
2514         return GRAY_RGB( r, g, b );
2515      case PF_Dither_5R6G5B:
2516         /* fall through */
2517      case PF_Dither_True:
2518         {
2519            unsigned long p;
2520            PACK_TRUEDITHER(p, x, y, r, g, b);
2521            return p;
2522         }
2523      default:
2524         _mesa_problem(NULL, "Bad pixel format in XMesaDitherColor");
2525   }
2526   return 0;
2527}
2528
2529
2530/*
2531 * This is typically called when the window size changes and we need
2532 * to reallocate the buffer's back/depth/stencil/accum buffers.
2533 */
2534void
2535XMesaResizeBuffers( XMesaBuffer b )
2536{
2537   GET_CURRENT_CONTEXT(ctx);
2538   XMesaContext xmctx = XMESA_CONTEXT(ctx);
2539   xmesa_check_and_update_buffer_size(xmctx, b);
2540}
2541
2542