xm_api.c revision e4656003caee346d9c4eb23256d73409271291a7
178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* $Id: xm_api.c,v 1.43 2002/10/05 18:27:41 brianp Exp $ */ 278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Mesa 3-D graphics library 578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Version: 4.0.2 678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. 878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Permission is hereby granted, free of charge, to any person obtaining a 1078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * copy of this software and associated documentation files (the "Software"), 1178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * to deal in the Software without restriction, including without limitation 1278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * and/or sell copies of the Software, and to permit persons to whom the 1478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Software is furnished to do so, subject to the following conditions: 1578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 1678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * The above copyright notice and this permission notice shall be included 1778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * in all copies or substantial portions of the Software. 1878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 1978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 2678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* $XFree86: xc/extras/Mesa/src/X/xm_api.c,v 1.2 2002/02/26 23:37:31 tsi Exp $ */ 2778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 2878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 2978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * This file contains the implementations of all the XMesa* functions. 3078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 3178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 3278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * NOTES: 3378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 3478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * The window coordinate system origin (0,0) is in the lower-left corner 3578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * of the window. X11's window coordinate origin is in the upper-left 3678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * corner of the window. Therefore, most drawing functions in this 3778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * file have to flip Y coordinates. 3878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 3978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile 4078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * in support for the MIT Shared Memory extension. If enabled, when you 4178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * use an Ximage for the back buffer in double buffered mode, the "swap" 4278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * operation will be faster. You must also link with -lXext. 4378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 4478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Byte swapping: If the Mesa host and the X display use a different 4578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * byte order then there's some trickiness to be aware of when using 4678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * XImages. The byte ordering used for the XImage is that of the X 4778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * display, not the Mesa host. 4878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * The color-to-pixel encoding for True/DirectColor must be done 4978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * according to the display's visual red_mask, green_mask, and blue_mask. 5078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * If XPutPixel is used to put a pixel into an XImage then XPutPixel will 5178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * do byte swapping if needed. If one wants to directly "poke" the pixel 5278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * into the XImage's buffer then the pixel must be byte swapped first. In 5378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format 5478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * and use XPutPixel everywhere except in the implementation of 5578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * glClear(GL_COLOR_BUFFER_BIT). We want this function to be fast so 5678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * instead of using XPutPixel we "poke" our values after byte-swapping 5778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * the clear pixel value if needed. 5878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 5978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 6078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 6178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifdef __CYGWIN__ 6278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#undef WIN32 6378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#undef __WIN32__ 6478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 6578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 6678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "glxheader.h" 6778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "GL/xmesa.h" 6878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "xmesaP.h" 6978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "context.h" 7078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "extensions.h" 7178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "glthread.h" 7278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "imports.h" 7378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "matrix.h" 7478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "mem.h" 7578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "mmath.h" 7678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "mtypes.h" 7778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifdef HAVE_CONFIG_H 7878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "conf.h" 7978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 8078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "macros.h" 8178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "texformat.h" 8278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "texstore.h" 8378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "swrast/swrast.h" 8478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "swrast_setup/swrast_setup.h" 8578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "array_cache/acache.h" 8678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "tnl/tnl.h" 8778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 8878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifndef GLX_NONE_EXT 8978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#define GLX_NONE_EXT 0x8000 9078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 9178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 9278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 9378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 9478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Global X driver lock 9578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 9678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch_glthread_Mutex _xmesa_lock; 9778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 9878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 9978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 10078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 10178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Lookup tables for HPCR pixel format: 10278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 10378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic short hpcr_rgbTbl[3][256] = { 10478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 10578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 10678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 10778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 10878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 10978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 11078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 11178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 11278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 11378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 11478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 11578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 11678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 11778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 11878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 11978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 12078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 12178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch}, 12278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 12378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 12478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 12578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 12678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 12778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 12878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 12978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 13078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 13178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 13278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 13378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 13478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 13578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 13678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 13778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 13878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 13978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch}, 14078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 14178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 14278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 14378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 14478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 14578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 14678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 14778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 14878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 14978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 15078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 15178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 15278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 15378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 15478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 15578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 15678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223 15778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 15878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch}; 15978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 16078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 16178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 16278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/**********************************************************************/ 16378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/***** X Utility Functions *****/ 16478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/**********************************************************************/ 16578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 16678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 16778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 16878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * X/Mesa error reporting function: 16978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 17078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic void error( const char *msg ) 17178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 17278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch (void)DitherValues; /* Muffle compiler */ 17378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 17478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (getenv("MESA_DEBUG")) 17578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch fprintf( stderr, "X/Mesa error: %s\n", msg ); 17678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 17778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 17878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 17978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 18078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Return the host's byte order as LSBFirst or MSBFirst ala X. 18178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 18278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifndef XFree86Server 18378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic int host_byte_order( void ) 18478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 18578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch int i = 1; 18678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch char *cptr = (char *) &i; 18778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return (*cptr==1) ? LSBFirst : MSBFirst; 18878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 18978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 19078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 19178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 19278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 19378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Error handling. 19478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 19578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifndef XFree86Server 19678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic int mesaXErrorFlag = 0; 19778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 19878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event ) 19978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 20078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch (void) dpy; 20178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch (void) event; 20278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch mesaXErrorFlag = 1; 20378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return 0; 20478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 20578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 20678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 20778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 20878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 20978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Check if the X Shared Memory extension is available. 21078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Return: 0 = not available 21178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 1 = shared XImage support available 21278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 2 = shared Pixmap support available also 21378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 21478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifndef XFree86Server 21578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic int check_for_xshm( XMesaDisplay *display ) 21678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 21778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifdef USE_XSHM 21878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch int major, minor, ignore; 21978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch Bool pixmaps; 22078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 22178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { 22278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { 22378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return (pixmaps==True) ? 2 : 1; 22478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 22578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch else { 22678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return 0; 22778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 22878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 22978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch else { 23078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return 0; 23178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 23278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#else 23378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* Can't compile XSHM support */ 23478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return 0; 23578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 23678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 23778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 23878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 23978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 24078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 24178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Return the width and height of the given drawable. 24278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 24378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic void get_drawable_size( XMesaDisplay *dpy, XMesaDrawable d, 24478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch unsigned int *width, unsigned int *height) 24578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 24678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifdef XFree86Server 24778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch (void) dpy; 24878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch *width = d->width; 24978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch *height = d->height; 25078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#else 25178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch Window root; 25278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch int x, y; 25378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch unsigned int bw, depth; 25478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 25578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch _glthread_LOCK_MUTEX(_xmesa_lock); 25678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XGetGeometry( dpy, d, &root, &x, &y, width, height, &bw, &depth ); 25778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch _glthread_UNLOCK_MUTEX(_xmesa_lock); 25878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 25978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 26078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 26178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 26278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 26378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Apply gamma correction to an intensity value in [0..max]. Return the 26478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * new intensity value. 26578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 26678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic GLint gamma_adjust( GLfloat gamma, GLint value, GLint max ) 26778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 26878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (gamma == 1.0) { 26978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return value; 27078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 27178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch else { 27278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch double x = (double) value / (double) max; 27378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return IROUND_POS((GLfloat) max * pow(x, 1.0F/gamma)); 27478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 27578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 27678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 27778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 27878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 27978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 28078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Return the true number of bits per pixel for XImages. 28178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * For example, if we request a 24-bit deep visual we may actually need/get 28278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * 32bpp XImages. This function returns the appropriate bpp. 28378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Input: dpy - the X display 28478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * visinfo - desribes the visual to be used for XImages 28578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Return: true number of bits per pixel for XImages 28678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 28778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifdef XFree86Server 28878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 28978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic int bits_per_pixel( XMesaVisual xmv ) 29078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 29178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaVisualInfo visinfo = xmv->visinfo; 29278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch const int depth = visinfo->nplanes; 29378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch int i; 29478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch for (i = 0; i < screenInfo.numPixmapFormats; i++) { 29578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (screenInfo.formats[i].depth == depth) 29678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return screenInfo.formats[i].bitsPerPixel; 29778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 29878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return depth; /* should never get here, but this should be safe */ 29978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 30078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 30178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#else 30278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 30378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic int bits_per_pixel( XMesaVisual xmv ) 30478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 30578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaDisplay *dpy = xmv->display; 30678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaVisualInfo visinfo = xmv->visinfo; 30778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaImage *img; 30878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch int bitsPerPixel; 30978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* Create a temporary XImage */ 31078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch img = XCreateImage( dpy, visinfo->visual, visinfo->depth, 31178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch ZPixmap, 0, /*format, offset*/ 31278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch (char*) MALLOC(8), /*data*/ 31378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 1, 1, /*width, height*/ 31478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 32, /*bitmap_pad*/ 31578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 0 /*bytes_per_line*/ 31678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch ); 31778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch assert(img); 31878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* grab the bits/pixel value */ 31978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch bitsPerPixel = img->bits_per_pixel; 32078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* free the XImage */ 32178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch FREE( img->data ); 32278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch img->data = NULL; 32378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaDestroyImage( img ); 32478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return bitsPerPixel; 32578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 32678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 32778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 32878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 32978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 33078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 33178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Determine if a given X window ID is valid (window exists). 33278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Do this by calling XGetWindowAttributes() for the window and 33378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * checking if we catch an X error. 33478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Input: dpy - the display 33578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * win - the window to check for existance 33678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Return: GL_TRUE - window exists 33778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * GL_FALSE - window doesn't exist 33878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 33978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifndef XFree86Server 34078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic GLboolean WindowExistsFlag; 34178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 34278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr ) 34378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 34478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch (void) dpy; 34578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (xerr->error_code == BadWindow) { 34678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch WindowExistsFlag = GL_FALSE; 34778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 34878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return 0; 34978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 35078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 35178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic GLboolean window_exists( XMesaDisplay *dpy, Window win ) 35278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 35378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XWindowAttributes wa; 35478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch int (*old_handler)( XMesaDisplay*, XErrorEvent* ); 35578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch WindowExistsFlag = GL_TRUE; 35678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch old_handler = XSetErrorHandler(window_exists_err_handler); 35778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XGetWindowAttributes( dpy, win, &wa ); /* dummy request */ 35878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XSetErrorHandler(old_handler); 35978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return WindowExistsFlag; 36078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 36178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 36278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 36378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 36478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 36578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/**********************************************************************/ 36678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/***** Linked list of XMesaBuffers *****/ 36778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/**********************************************************************/ 36878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 36978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic XMesaBuffer XMesaBufferList = NULL; 37078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 37178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 37278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* Allocate a new XMesaBuffer, add to linked list */ 37378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic XMesaBuffer alloc_xmesa_buffer(void) 37478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 37578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); 37678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (b) { 37778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch b->Next = XMesaBufferList; 37878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaBufferList = b; 37978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 38078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return b; 38178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 38278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 38378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 38478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 38578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Find an XMesaBuffer by matching X display and colormap but NOT matching 38678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * the notThis buffer. 38778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 38878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy, 38978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaColormap cmap, 39078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaBuffer notThis) 39178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 39278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaBuffer b; 39378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch for (b=XMesaBufferList; b; b=b->Next) { 39478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (b->display==dpy && b->cmap==cmap && b!=notThis) { 39578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return b; 39678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 39778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 39878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return NULL; 39978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 40078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 40178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 40278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 40378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Free an XMesaBuffer, remove from linked list, perhaps free X colormap 40478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * entries. 40578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 40678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic void free_xmesa_buffer(int client, XMesaBuffer buffer) 40778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 40878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaBuffer prev = NULL, b; 40978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch (void) client; 41078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch for (b=XMesaBufferList; b; b=b->Next) { 41178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (b==buffer) { 41278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* unlink bufer from list */ 41378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (prev) 41478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch prev->Next = buffer->Next; 41578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch else 41678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XMesaBufferList = buffer->Next; 41778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* Check to free X colors */ 41878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (buffer->num_alloced>0) { 41978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* If no other buffer uses this X colormap then free the colors. */ 42078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) { 42178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifdef XFree86Server 42278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch (void)FreeColors(buffer->cmap, client, 42378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch buffer->num_alloced, buffer->alloced_colors, 42478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 0); 42578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#else 42678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch XFreeColors(buffer->display, buffer->cmap, 42778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch buffer->alloced_colors, buffer->num_alloced, 0); 42878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#endif 42978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 43078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 43178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 43278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch _mesa_free_framebuffer_data(&buffer->mesa_buffer); 43378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch FREE(buffer); 43478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 43578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return; 43678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 43778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* continue search */ 43878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch prev = b; 43978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 44078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* buffer not found in XMesaBufferList */ 44178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n"); 44278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 44378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 44478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 44578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* Copy X color table stuff from one XMesaBuffer to another. */ 44678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src) 44778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 44878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table)); 44978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r)); 45078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g)); 45178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b)); 45278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch dst->num_alloced = src->num_alloced; 45378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch MEMCPY(dst->alloced_colors, src->alloced_colors, 45478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch sizeof(src->alloced_colors)); 45578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 45678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 45778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 45878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 45978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/**********************************************************************/ 46078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/***** Misc Private Functions *****/ 46178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/**********************************************************************/ 46278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 46378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 46478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 46578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Return number of bits set in n. 46678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 46778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic int bitcount( unsigned long n ) 46878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 46978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch int bits; 47078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch for (bits=0; n>0; n=n>>1) { 47178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch if (n&1) { 47278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch bits++; 47378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 47478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch } 47578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch return bits; 47678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch} 47778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 47878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 47978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch 48078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/* 48178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Allocate a shared memory XImage back buffer for the given XMesaBuffer. 48278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch * Return: GL_TRUE if success, GL_FALSE if error 48378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch */ 48478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifndef XFree86Server 48578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochstatic GLboolean alloc_shm_back_buffer( XMesaBuffer b ) 48678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch{ 48778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifdef USE_XSHM 48878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch /* 489 * We have to do a _lot_ of error checking here to be sure we can 490 * really use the XSHM extension. It seems different servers trigger 491 * errors at different points if the extension won't work. Therefore 492 * we have to be very careful... 493 */ 494 GC gc; 495 int (*old_handler)( XMesaDisplay *, XErrorEvent * ); 496 497 b->backimage = XShmCreateImage( b->xm_visual->display, 498 b->xm_visual->visinfo->visual, 499 b->xm_visual->visinfo->depth, 500 ZPixmap, NULL, &b->shminfo, 501 b->width, b->height ); 502 if (b->backimage == NULL) { 503 error("alloc_back_buffer: Shared memory error (XShmCreateImage), disabling."); 504 b->shm = 0; 505 return GL_FALSE; 506 } 507 508 b->shminfo.shmid = shmget( IPC_PRIVATE, b->backimage->bytes_per_line 509 * b->backimage->height, IPC_CREAT|0777 ); 510 if (b->shminfo.shmid < 0) { 511 if (getenv("MESA_DEBUG")) 512 perror("alloc_back_buffer"); 513 XDestroyImage( b->backimage ); 514 b->backimage = NULL; 515 error("alloc_back_buffer: Shared memory error (shmget), disabling."); 516 b->shm = 0; 517 return GL_FALSE; 518 } 519 520 b->shminfo.shmaddr = b->backimage->data 521 = (char*)shmat( b->shminfo.shmid, 0, 0 ); 522 if (b->shminfo.shmaddr == (char *) -1) { 523 if (getenv("MESA_DEBUG")) 524 perror("alloc_back_buffer"); 525 XDestroyImage( b->backimage ); 526 shmctl( b->shminfo.shmid, IPC_RMID, 0 ); 527 b->backimage = NULL; 528 error("alloc_back_buffer: Shared memory error (shmat), disabling."); 529 b->shm = 0; 530 return GL_FALSE; 531 } 532 533 b->shminfo.readOnly = False; 534 mesaXErrorFlag = 0; 535 old_handler = XSetErrorHandler( mesaHandleXError ); 536 /* This may trigger the X protocol error we're ready to catch: */ 537 XShmAttach( b->xm_visual->display, &b->shminfo ); 538 XSync( b->xm_visual->display, False ); 539 540 if (mesaXErrorFlag) { 541 /* we are on a remote display, this error is normal, don't print it */ 542 XFlush( b->xm_visual->display ); 543 mesaXErrorFlag = 0; 544 XDestroyImage( b->backimage ); 545 shmdt( b->shminfo.shmaddr ); 546 shmctl( b->shminfo.shmid, IPC_RMID, 0 ); 547 b->backimage = NULL; 548 b->shm = 0; 549 (void) XSetErrorHandler( old_handler ); 550 return GL_FALSE; 551 } 552 553 shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */ 554 555 /* Finally, try an XShmPutImage to be really sure the extension works */ 556 gc = XCreateGC( b->xm_visual->display, b->frontbuffer, 0, NULL ); 557 XShmPutImage( b->xm_visual->display, b->frontbuffer, gc, 558 b->backimage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False ); 559 XSync( b->xm_visual->display, False ); 560 XFreeGC( b->xm_visual->display, gc ); 561 (void) XSetErrorHandler( old_handler ); 562 if (mesaXErrorFlag) { 563 XFlush( b->xm_visual->display ); 564 mesaXErrorFlag = 0; 565 XDestroyImage( b->backimage ); 566 shmdt( b->shminfo.shmaddr ); 567 shmctl( b->shminfo.shmid, IPC_RMID, 0 ); 568 b->backimage = NULL; 569 b->shm = 0; 570 return GL_FALSE; 571 } 572 573 if (b->backimage) { 574 int height = b->backimage->height; 575 /* Needed by PIXELADDR1 macro */ 576 b->ximage_width1 = b->backimage->bytes_per_line; 577 b->ximage_origin1 = (GLubyte *) b->backimage->data 578 + b->ximage_width1 * (height-1); 579 /* Needed by PIXELADDR2 macro */ 580 b->ximage_width2 = b->backimage->bytes_per_line / 2; 581 b->ximage_origin2 = (GLushort *) b->backimage->data 582 + b->ximage_width2 * (height-1); 583 /* Needed by PIXELADDR3 macro */ 584 b->ximage_width3 = b->backimage->bytes_per_line; 585 b->ximage_origin3 = (GLubyte *) b->backimage->data 586 + b->ximage_width3 * (height-1); 587 /* Needed by PIXELADDR4 macro */ 588 b->ximage_width4 = b->backimage->width; 589 b->ximage_origin4 = (GLuint *) b->backimage->data 590 + b->ximage_width4 * (height-1); 591 } 592 593 return GL_TRUE; 594#else 595 /* Can't compile XSHM support */ 596 return GL_FALSE; 597#endif 598} 599#endif 600 601 602 603/* 604 * Setup an off-screen pixmap or Ximage to use as the back buffer. 605 * Input: b - the X/Mesa buffer 606 */ 607void xmesa_alloc_back_buffer( XMesaBuffer b ) 608{ 609 if (b->db_state==BACK_XIMAGE) { 610 /* Deallocate the old backimage, if any */ 611 if (b->backimage) { 612#if defined(USE_XSHM) && !defined(XFree86Server) 613 if (b->shm) { 614 XShmDetach( b->xm_visual->display, &b->shminfo ); 615 XDestroyImage( b->backimage ); 616 shmdt( b->shminfo.shmaddr ); 617 } 618 else 619#endif 620 XMesaDestroyImage( b->backimage ); 621 b->backimage = NULL; 622 } 623 624 /* Allocate new back buffer */ 625#ifdef XFree86Server 626 { 627 /* Allocate a regular XImage for the back buffer. */ 628 b->backimage = XMesaCreateImage(b->xm_visual->BitsPerPixel, 629 b->width, b->height, NULL); 630#else 631 if (b->shm==0 || alloc_shm_back_buffer(b)==GL_FALSE) { 632 /* Allocate a regular XImage for the back buffer. */ 633 b->backimage = XCreateImage( b->xm_visual->display, 634 b->xm_visual->visinfo->visual, 635 GET_VISUAL_DEPTH(b->xm_visual), 636 ZPixmap, 0, /* format, offset */ 637 NULL, b->width, b->height, 638 8, 0 ); /* pad, bytes_per_line */ 639#endif 640 if (!b->backimage) { 641 error("alloc_back_buffer: XCreateImage failed."); 642 } 643 b->backimage->data = (char *) MALLOC( b->backimage->height 644 * b->backimage->bytes_per_line ); 645 if (!b->backimage->data) { 646 error("alloc_back_buffer: MALLOC failed."); 647 XMesaDestroyImage( b->backimage ); 648 b->backimage = NULL; 649 } 650 } 651 b->backpixmap = None; 652 } 653 else if (b->db_state==BACK_PIXMAP) { 654 XMesaPixmap old_pixmap = b->backpixmap; 655 /* Free the old back pixmap */ 656 if (b->backpixmap) { 657 XMesaFreePixmap( b->xm_visual->display, b->backpixmap ); 658 } 659 /* Allocate new back pixmap */ 660 b->backpixmap = XMesaCreatePixmap( b->xm_visual->display, b->frontbuffer, 661 b->width, b->height, 662 GET_VISUAL_DEPTH(b->xm_visual) ); 663 b->backimage = NULL; 664 /* update other references to backpixmap */ 665 if (b->buffer==(XMesaDrawable)old_pixmap) { 666 b->buffer = (XMesaDrawable)b->backpixmap; 667 } 668 } 669} 670 671 672 673/* 674 * A replacement for XAllocColor. This function should never 675 * fail to allocate a color. When XAllocColor fails, we return 676 * the nearest matching color. If we have to allocate many colors 677 * this function isn't too efficient; the XQueryColors() could be 678 * done just once. 679 * Written by Michael Pichler, Brian Paul, Mark Kilgard 680 * Input: dpy - X display 681 * cmap - X colormap 682 * cmapSize - size of colormap 683 * In/Out: color - the XColor struct 684 * Output: exact - 1=exact color match, 0=closest match 685 * alloced - 1=XAlloc worked, 0=XAlloc failed 686 */ 687static void 688noFaultXAllocColor( int client, 689 XMesaDisplay *dpy, 690 XMesaColormap cmap, 691 int cmapSize, 692 XMesaColor *color, 693 int *exact, int *alloced ) 694{ 695#ifdef XFree86Server 696 Pixel *ppixIn; 697 xrgb *ctable; 698#else 699 /* we'll try to cache ctable for better remote display performance */ 700 static Display *prevDisplay = NULL; 701 static XMesaColormap prevCmap = 0; 702 static int prevCmapSize = 0; 703 static XMesaColor *ctable = NULL; 704#endif 705 XMesaColor subColor; 706 int i, bestmatch; 707 double mindist; /* 3*2^16^2 exceeds long int precision. */ 708 709 (void) client; 710 711 /* First try just using XAllocColor. */ 712#ifdef XFree86Server 713 if (AllocColor(cmap, 714 &color->red, &color->green, &color->blue, 715 &color->pixel, 716 client) == Success) { 717#else 718 if (XAllocColor(dpy, cmap, color)) { 719#endif 720 *exact = 1; 721 *alloced = 1; 722 return; 723 } 724 725 /* Alloc failed, search for closest match */ 726 727 /* Retrieve color table entries. */ 728 /* XXX alloca candidate. */ 729#ifdef XFree86Server 730 ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel)); 731 ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb)); 732 for (i = 0; i < cmapSize; i++) { 733 ppixIn[i] = i; 734 } 735 QueryColors(cmap, cmapSize, ppixIn, ctable); 736#else 737 if (prevDisplay != dpy || prevCmap != cmap 738 || prevCmapSize != cmapSize || !ctable) { 739 /* free previously cached color table */ 740 if (ctable) 741 FREE(ctable); 742 /* Get the color table from X */ 743 ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor)); 744 assert(ctable); 745 for (i = 0; i < cmapSize; i++) { 746 ctable[i].pixel = i; 747 } 748 XQueryColors(dpy, cmap, ctable, cmapSize); 749 prevDisplay = dpy; 750 prevCmap = cmap; 751 prevCmapSize = cmapSize; 752 } 753#endif 754 755 /* Find best match. */ 756 bestmatch = -1; 757 mindist = 0.0; 758 for (i = 0; i < cmapSize; i++) { 759 double dr = 0.30 * ((double) color->red - (double) ctable[i].red); 760 double dg = 0.59 * ((double) color->green - (double) ctable[i].green); 761 double db = 0.11 * ((double) color->blue - (double) ctable[i].blue); 762 double dist = dr * dr + dg * dg + db * db; 763 if (bestmatch < 0 || dist < mindist) { 764 bestmatch = i; 765 mindist = dist; 766 } 767 } 768 769 /* Return result. */ 770 subColor.red = ctable[bestmatch].red; 771 subColor.green = ctable[bestmatch].green; 772 subColor.blue = ctable[bestmatch].blue; 773 /* Try to allocate the closest match color. This should only 774 * fail if the cell is read/write. Otherwise, we're incrementing 775 * the cell's reference count. 776 */ 777#ifdef XFree86Server 778 if (AllocColor(cmap, 779 &subColor.red, &subColor.green, &subColor.blue, 780 &subColor.pixel, 781 client) == Success) { 782#else 783 if (XAllocColor(dpy, cmap, &subColor)) { 784#endif 785 *alloced = 1; 786 } 787 else { 788 /* do this to work around a problem reported by Frank Ortega */ 789 subColor.pixel = (unsigned long) bestmatch; 790 subColor.red = ctable[bestmatch].red; 791 subColor.green = ctable[bestmatch].green; 792 subColor.blue = ctable[bestmatch].blue; 793 subColor.flags = DoRed | DoGreen | DoBlue; 794 *alloced = 0; 795 } 796#ifdef XFree86Server 797 FREE(ppixIn); 798 FREE(ctable); 799#else 800 /* don't free table, save it for next time */ 801#endif 802 803 *color = subColor; 804 *exact = 0; 805} 806 807 808 809 810/* 811 * Do setup for PF_GRAYSCALE pixel format. 812 * Note that buffer may be NULL. 813 */ 814static GLboolean setup_grayscale( int client, XMesaVisual v, 815 XMesaBuffer buffer, XMesaColormap cmap ) 816{ 817 if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { 818 return GL_FALSE; 819 } 820 821 if (buffer) { 822 XMesaBuffer prevBuffer; 823 824 if (!cmap) { 825 return GL_FALSE; 826 } 827 828 prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); 829 if (prevBuffer && 830 (buffer->xm_visual->mesa_visual.rgbMode == 831 prevBuffer->xm_visual->mesa_visual.rgbMode)) { 832 /* Copy colormap stuff from previous XMesaBuffer which uses same 833 * X colormap. Do this to avoid time spent in noFaultXAllocColor. 834 */ 835 copy_colortable_info(buffer, prevBuffer); 836 } 837 else { 838 /* Allocate 256 shades of gray */ 839 int gray; 840 int colorsfailed = 0; 841 for (gray=0;gray<256;gray++) { 842 GLint r = gamma_adjust( v->RedGamma, gray, 255 ); 843 GLint g = gamma_adjust( v->GreenGamma, gray, 255 ); 844 GLint b = gamma_adjust( v->BlueGamma, gray, 255 ); 845 int exact, alloced; 846 XMesaColor xcol; 847 xcol.red = (r << 8) | r; 848 xcol.green = (g << 8) | g; 849 xcol.blue = (b << 8) | b; 850 noFaultXAllocColor( client, v->display, 851 cmap, GET_COLORMAP_SIZE(v), 852 &xcol, &exact, &alloced ); 853 if (!exact) { 854 colorsfailed++; 855 } 856 if (alloced) { 857 assert(buffer->num_alloced<256); 858 buffer->alloced_colors[buffer->num_alloced] = xcol.pixel; 859 buffer->num_alloced++; 860 } 861 862 /*OLD 863 assert(gray < 576); 864 buffer->color_table[gray*3+0] = xcol.pixel; 865 buffer->color_table[gray*3+1] = xcol.pixel; 866 buffer->color_table[gray*3+2] = xcol.pixel; 867 assert(xcol.pixel < 65536); 868 buffer->pixel_to_r[xcol.pixel] = gray * 30 / 100; 869 buffer->pixel_to_g[xcol.pixel] = gray * 59 / 100; 870 buffer->pixel_to_b[xcol.pixel] = gray * 11 / 100; 871 */ 872 buffer->color_table[gray] = xcol.pixel; 873 assert(xcol.pixel < 65536); 874 buffer->pixel_to_r[xcol.pixel] = gray; 875 buffer->pixel_to_g[xcol.pixel] = gray; 876 buffer->pixel_to_b[xcol.pixel] = gray; 877 } 878 879 if (colorsfailed && getenv("MESA_DEBUG")) { 880 fprintf( stderr, 881 "Note: %d out of 256 needed colors do not match exactly.\n", 882 colorsfailed ); 883 } 884 } 885 } 886 887 v->dithered_pf = PF_GRAYSCALE; 888 v->undithered_pf = PF_GRAYSCALE; 889 return GL_TRUE; 890} 891 892 893 894/* 895 * Setup RGB rendering for a window with a PseudoColor, StaticColor, 896 * or 8-bit TrueColor visual visual. We try to allocate a palette of 225 897 * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB 898 * color. While this function was originally designed just for 8-bit 899 * visuals, it has also proven to work from 4-bit up to 16-bit visuals. 900 * Dithering code contributed by Bob Mercier. 901 */ 902static GLboolean setup_dithered_color( int client, XMesaVisual v, 903 XMesaBuffer buffer, XMesaColormap cmap ) 904{ 905 if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) { 906 return GL_FALSE; 907 } 908 909 if (buffer) { 910 XMesaBuffer prevBuffer; 911 912 if (!cmap) { 913 return GL_FALSE; 914 } 915 916 prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); 917 if (prevBuffer && 918 (buffer->xm_visual->mesa_visual.rgbMode == 919 prevBuffer->xm_visual->mesa_visual.rgbMode)) { 920 /* Copy colormap stuff from previous, matching XMesaBuffer. 921 * Do this to avoid time spent in noFaultXAllocColor. 922 */ 923 copy_colortable_info(buffer, prevBuffer); 924 } 925 else { 926 /* Allocate X colors and initialize color_table[], red_table[], etc */ 927 int r, g, b, i; 928 int colorsfailed = 0; 929 for (r = 0; r < _R; r++) { 930 for (g = 0; g < _G; g++) { 931 for (b = 0; b < _B; b++) { 932 XMesaColor xcol; 933 int exact, alloced; 934 xcol.red =gamma_adjust(v->RedGamma, r*65535/(_R-1),65535); 935 xcol.green=gamma_adjust(v->GreenGamma, g*65535/(_G-1),65535); 936 xcol.blue =gamma_adjust(v->BlueGamma, b*65535/(_B-1),65535); 937 noFaultXAllocColor( client, v->display, 938 cmap, GET_COLORMAP_SIZE(v), 939 &xcol, &exact, &alloced ); 940 if (!exact) { 941 colorsfailed++; 942 } 943 if (alloced) { 944 assert(buffer->num_alloced<256); 945 buffer->alloced_colors[buffer->num_alloced] = xcol.pixel; 946 buffer->num_alloced++; 947 } 948 i = _MIX( r, g, b ); 949 assert(i < 576); 950 buffer->color_table[i] = xcol.pixel; 951 assert(xcol.pixel < 65536); 952 buffer->pixel_to_r[xcol.pixel] = r * 255 / (_R-1); 953 buffer->pixel_to_g[xcol.pixel] = g * 255 / (_G-1); 954 buffer->pixel_to_b[xcol.pixel] = b * 255 / (_B-1); 955 } 956 } 957 } 958 959 if (colorsfailed && getenv("MESA_DEBUG")) { 960 fprintf( stderr, 961 "Note: %d out of %d needed colors do not match exactly.\n", 962 colorsfailed, _R*_G*_B ); 963 } 964 } 965 } 966 967 v->dithered_pf = PF_DITHER; 968 v->undithered_pf = PF_LOOKUP; 969 return GL_TRUE; 970} 971 972 973/* 974 * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode. 975 * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer. 976 * Special dithering tables have to be initialized. 977 */ 978static void setup_8bit_hpcr( XMesaVisual v ) 979{ 980 /* HP Color Recovery contributed by: Alex De Bruyn (ad@lms.be) 981 * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined 982 * on the root window AND the colormap obtainable by XGetRGBColormaps 983 * for that atom must be set on the window. (see also tkInitWindow) 984 * If that colormap is not set, the output will look stripy. 985 */ 986 987 /* Setup color tables with gamma correction */ 988 int i; 989 double g; 990 991 g = 1.0 / v->RedGamma; 992 for (i=0; i<256; i++) { 993 GLint red = IROUND_POS(255.0 * pow( hpcr_rgbTbl[0][i]/255.0, g )); 994 v->hpcr_rgbTbl[0][i] = CLAMP( red, 16, 239 ); 995 } 996 997 g = 1.0 / v->GreenGamma; 998 for (i=0; i<256; i++) { 999 GLint green = IROUND_POS(255.0 * pow( hpcr_rgbTbl[1][i]/255.0, g )); 1000 v->hpcr_rgbTbl[1][i] = CLAMP( green, 16, 239 ); 1001 } 1002 1003 g = 1.0 / v->BlueGamma; 1004 for (i=0; i<256; i++) { 1005 GLint blue = IROUND_POS(255.0 * pow( hpcr_rgbTbl[2][i]/255.0, g )); 1006 v->hpcr_rgbTbl[2][i] = CLAMP( blue, 32, 223 ); 1007 } 1008 v->undithered_pf = PF_HPCR; /* can't really disable dithering for now */ 1009 v->dithered_pf = PF_HPCR; 1010 1011 /* which method should I use to clear */ 1012 /* GL_FALSE: keep the ordinary method */ 1013 /* GL_TRUE : clear with dither pattern */ 1014 v->hpcr_clear_flag = getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE; 1015 1016 if (v->hpcr_clear_flag) { 1017 v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display, 1018 DefaultRootWindow(v->display), 1019 16, 2, 8); 1020#ifndef XFree86Server 1021 v->hpcr_clear_ximage = XGetImage(v->display, v->hpcr_clear_pixmap, 1022 0, 0, 16, 2, AllPlanes, ZPixmap); 1023#endif 1024 } 1025} 1026 1027 1028/* 1029 * Setup RGB rendering for a window with a True/DirectColor visual. 1030 */ 1031static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer, 1032 XMesaColormap cmap ) 1033{ 1034 unsigned long rmask, gmask, bmask; 1035 (void) buffer; 1036 (void) cmap; 1037 1038 /* Compute red multiplier (mask) and bit shift */ 1039 v->rshift = 0; 1040 rmask = GET_REDMASK(v); 1041 while ((rmask & 1)==0) { 1042 v->rshift++; 1043 rmask = rmask >> 1; 1044 } 1045 1046 /* Compute green multiplier (mask) and bit shift */ 1047 v->gshift = 0; 1048 gmask = GET_GREENMASK(v); 1049 while ((gmask & 1)==0) { 1050 v->gshift++; 1051 gmask = gmask >> 1; 1052 } 1053 1054 /* Compute blue multiplier (mask) and bit shift */ 1055 v->bshift = 0; 1056 bmask = GET_BLUEMASK(v); 1057 while ((bmask & 1)==0) { 1058 v->bshift++; 1059 bmask = bmask >> 1; 1060 } 1061 1062 /* 1063 * Compute component-to-pixel lookup tables and dithering kernel 1064 */ 1065 { 1066 static GLubyte kernel[16] = { 1067 0*16, 8*16, 2*16, 10*16, 1068 12*16, 4*16, 14*16, 6*16, 1069 3*16, 11*16, 1*16, 9*16, 1070 15*16, 7*16, 13*16, 5*16, 1071 }; 1072 GLint rBits = bitcount(rmask); 1073 GLint gBits = bitcount(gmask); 1074 GLint bBits = bitcount(bmask); 1075 GLint maxBits; 1076 GLuint i; 1077 1078 /* convert pixel components in [0,_mask] to RGB values in [0,255] */ 1079 for (i=0; i<=rmask; i++) 1080 v->PixelToR[i] = (unsigned char) ((i * 255) / rmask); 1081 for (i=0; i<=gmask; i++) 1082 v->PixelToG[i] = (unsigned char) ((i * 255) / gmask); 1083 for (i=0; i<=bmask; i++) 1084 v->PixelToB[i] = (unsigned char) ((i * 255) / bmask); 1085 1086 /* convert RGB values from [0,255] to pixel components */ 1087 1088 for (i=0;i<256;i++) { 1089 GLint r = gamma_adjust(v->RedGamma, i, 255); 1090 GLint g = gamma_adjust(v->GreenGamma, i, 255); 1091 GLint b = gamma_adjust(v->BlueGamma, i, 255); 1092 v->RtoPixel[i] = (r >> (8-rBits)) << v->rshift; 1093 v->GtoPixel[i] = (g >> (8-gBits)) << v->gshift; 1094 v->BtoPixel[i] = (b >> (8-bBits)) << v->bshift; 1095 } 1096 /* overflow protection */ 1097 for (i=256;i<512;i++) { 1098 v->RtoPixel[i] = v->RtoPixel[255]; 1099 v->GtoPixel[i] = v->GtoPixel[255]; 1100 v->BtoPixel[i] = v->BtoPixel[255]; 1101 } 1102 1103 /* setup dithering kernel */ 1104 maxBits = rBits; 1105 if (gBits > maxBits) maxBits = gBits; 1106 if (bBits > maxBits) maxBits = bBits; 1107 for (i=0;i<16;i++) { 1108 v->Kernel[i] = kernel[i] >> maxBits; 1109 } 1110 1111 v->undithered_pf = PF_TRUECOLOR; 1112 v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_TRUEDITHER : PF_TRUECOLOR; 1113 } 1114 1115 /* 1116 * Now check for TrueColor visuals which we can optimize. 1117 */ 1118 if ( GET_REDMASK(v) ==0x0000ff 1119 && GET_GREENMASK(v)==0x00ff00 1120 && GET_BLUEMASK(v) ==0xff0000 1121 && CHECK_BYTE_ORDER(v) 1122 && v->BitsPerPixel==32 1123 && sizeof(GLuint)==4 1124 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1125 /* common 32 bpp config used on SGI, Sun */ 1126 v->undithered_pf = v->dithered_pf = PF_8A8B8G8R; 1127 } 1128 else if (GET_REDMASK(v) ==0xff0000 1129 && GET_GREENMASK(v)==0x00ff00 1130 && GET_BLUEMASK(v) ==0x0000ff 1131 && CHECK_BYTE_ORDER(v) 1132 && v->BitsPerPixel==32 1133 && sizeof(GLuint)==4 1134 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1135 /* common 32 bpp config used on Linux, HP, IBM */ 1136 v->undithered_pf = v->dithered_pf = PF_8R8G8B; 1137 } 1138 else if (GET_REDMASK(v) ==0xff0000 1139 && GET_GREENMASK(v)==0x00ff00 1140 && GET_BLUEMASK(v) ==0x0000ff 1141 && CHECK_BYTE_ORDER(v) 1142 && v->BitsPerPixel==24 1143 && sizeof(GLuint)==4 1144 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1145 /* common packed 24 bpp config used on Linux */ 1146 v->undithered_pf = v->dithered_pf = PF_8R8G8B24; 1147 } 1148 else if (GET_REDMASK(v) ==0xf800 1149 && GET_GREENMASK(v)==0x07e0 1150 && GET_BLUEMASK(v) ==0x001f 1151 && CHECK_BYTE_ORDER(v) 1152 && v->BitsPerPixel==16 1153 && sizeof(GLushort)==2 1154 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { 1155 /* 5-6-5 color weight on common PC VGA boards */ 1156 v->undithered_pf = PF_5R6G5B; 1157 v->dithered_pf = PF_DITHER_5R6G5B; 1158 } 1159 else if (GET_REDMASK(v) ==0xe0 1160 && GET_GREENMASK(v)==0x1c 1161 && GET_BLUEMASK(v) ==0x03 1162 && CHECK_FOR_HPCR(v)) { 1163 setup_8bit_hpcr( v ); 1164 } 1165} 1166 1167 1168 1169/* 1170 * Setup RGB rendering for a window with a monochrome visual. 1171 */ 1172static void setup_monochrome( XMesaVisual v, XMesaBuffer b ) 1173{ 1174 (void) b; 1175 v->dithered_pf = v->undithered_pf = PF_1BIT; 1176 /* if black=1 then we must flip pixel values */ 1177 v->bitFlip = (GET_BLACK_PIXEL(v) != 0); 1178} 1179 1180 1181 1182/* 1183 * When a context is "made current" for the first time, we can finally 1184 * finish initializing the context's visual and buffer information. 1185 * Input: v - the XMesaVisual to initialize 1186 * b - the XMesaBuffer to initialize (may be NULL) 1187 * rgb_flag - TRUE = RGBA mode, FALSE = color index mode 1188 * window - the window/pixmap we're rendering into 1189 * cmap - the colormap associated with the window/pixmap 1190 * Return: GL_TRUE=success, GL_FALSE=failure 1191 */ 1192static GLboolean initialize_visual_and_buffer( int client, 1193 XMesaVisual v, 1194 XMesaBuffer b, 1195 GLboolean rgb_flag, 1196 XMesaDrawable window, 1197 XMesaColormap cmap ) 1198{ 1199#ifndef XFree86Server 1200 XGCValues gcvalues; 1201#endif 1202 1203 if (b) { 1204 assert(b->xm_visual == v); 1205 } 1206 1207 /* Save true bits/pixel */ 1208 v->BitsPerPixel = bits_per_pixel(v); 1209 assert(v->BitsPerPixel > 0); 1210 1211 1212 if (rgb_flag==GL_FALSE) { 1213 /* COLOR-INDEXED WINDOW: 1214 * Even if the visual is TrueColor or DirectColor we treat it as 1215 * being color indexed. This is weird but might be useful to someone. 1216 */ 1217 v->dithered_pf = v->undithered_pf = PF_INDEX; 1218 v->index_bits = GET_VISUAL_DEPTH(v); 1219 } 1220 else { 1221 /* RGB WINDOW: 1222 * We support RGB rendering into almost any kind of visual. 1223 */ 1224 int xclass; 1225 xclass = GET_VISUAL_CLASS(v); 1226 if (xclass==TrueColor || xclass==DirectColor) { 1227 setup_truecolor( v, b, cmap ); 1228 } 1229 else if (xclass==StaticGray && GET_VISUAL_DEPTH(v)==1) { 1230 setup_monochrome( v, b ); 1231 } 1232 else if (xclass==GrayScale || xclass==StaticGray) { 1233 if (!setup_grayscale( client, v, b, cmap )) { 1234 return GL_FALSE; 1235 } 1236 } 1237 else if ((xclass==PseudoColor || xclass==StaticColor) 1238 && GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) { 1239 if (!setup_dithered_color( client, v, b, cmap )) { 1240 return GL_FALSE; 1241 } 1242 } 1243 else { 1244 error("XMesa: RGB mode rendering not supported in given visual."); 1245 return GL_FALSE; 1246 } 1247 v->index_bits = 0; 1248 1249 if (getenv("MESA_NO_DITHER")) { 1250 v->dithered_pf = v->undithered_pf; 1251 } 1252 } 1253 1254 1255 /* 1256 * If MESA_INFO env var is set print out some debugging info 1257 * which can help Brian figure out what's going on when a user 1258 * reports bugs. 1259 */ 1260 if (getenv("MESA_INFO")) { 1261 fprintf(stderr, "X/Mesa visual = %p\n", (void *) v); 1262 fprintf(stderr, "X/Mesa dithered pf = %u\n", v->dithered_pf); 1263 fprintf(stderr, "X/Mesa undithered pf = %u\n", v->undithered_pf); 1264 fprintf(stderr, "X/Mesa level = %d\n", v->level); 1265 fprintf(stderr, "X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v)); 1266 fprintf(stderr, "X/Mesa bits per pixel = %d\n", v->BitsPerPixel); 1267 } 1268 1269 if (b && window) { 1270 /* Do window-specific initializations */ 1271 1272 /* Window dimensions */ 1273 unsigned int w, h; 1274 get_drawable_size( v->display, window, &w, &h ); 1275 b->width = w; 1276 b->height = h; 1277 1278 b->frontbuffer = window; 1279 1280 /* Setup for single/double buffering */ 1281 if (v->mesa_visual.doubleBufferMode) { 1282 /* Double buffered */ 1283#ifndef XFree86Server 1284 b->shm = check_for_xshm( v->display ); 1285#endif 1286 xmesa_alloc_back_buffer( b ); 1287 if (b->db_state==BACK_PIXMAP) { 1288 b->buffer = (XMesaDrawable)b->backpixmap; 1289 } 1290 else { 1291 b->buffer = XIMAGE; 1292 } 1293 } 1294 else { 1295 /* Single Buffered */ 1296 b->buffer = b->frontbuffer; 1297 } 1298 1299 /* X11 graphics contexts */ 1300#ifdef XFree86Server 1301 b->gc = CreateScratchGC(v->display, window->depth); 1302#else 1303 b->gc = XCreateGC( v->display, window, 0, NULL ); 1304#endif 1305 XMesaSetFunction( v->display, b->gc, GXcopy ); 1306 1307 /* cleargc - for glClear() */ 1308#ifdef XFree86Server 1309 b->cleargc = CreateScratchGC(v->display, window->depth); 1310#else 1311 b->cleargc = XCreateGC( v->display, window, 0, NULL ); 1312#endif 1313 XMesaSetFunction( v->display, b->cleargc, GXcopy ); 1314 1315 /* 1316 * Don't generate Graphics Expose/NoExpose events in swapbuffers(). 1317 * Patch contributed by Michael Pichler May 15, 1995. 1318 */ 1319#ifdef XFree86Server 1320 b->swapgc = CreateScratchGC(v->display, window->depth); 1321 { 1322 CARD32 v[1]; 1323 v[0] = FALSE; 1324 dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL); 1325 } 1326#else 1327 gcvalues.graphics_exposures = False; 1328 b->swapgc = XCreateGC( v->display, window, 1329 GCGraphicsExposures, &gcvalues); 1330#endif 1331 XMesaSetFunction( v->display, b->swapgc, GXcopy ); 1332 /* 1333 * Set fill style and tile pixmap once for all for HPCR stuff 1334 * (instead of doing it each time in clear_color_HPCR_pixmap()) 1335 * Initialize whole stuff 1336 * Patch contributed by Jacques Leroy March 8, 1998. 1337 */ 1338 if (v->hpcr_clear_flag && b->buffer!=XIMAGE) { 1339 int i; 1340 for (i=0; i<16; i++) 1341 { 1342 XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0); 1343 XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0); 1344 } 1345 XMesaPutImage(b->display, (XMesaDrawable)v->hpcr_clear_pixmap, 1346 b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2); 1347 XMesaSetFillStyle( v->display, b->cleargc, FillTiled); 1348 XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap ); 1349 } 1350 1351 /* Initialize the row buffer XImage for use in write_color_span() */ 1352#ifdef XFree86Server 1353 b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1, 1354 (char *)MALLOC(MAX_WIDTH*4)); 1355#else 1356 b->rowimage = XCreateImage( v->display, 1357 v->visinfo->visual, 1358 v->visinfo->depth, 1359 ZPixmap, 0, /*format, offset*/ 1360 (char*) MALLOC(MAX_WIDTH*4), /*data*/ 1361 MAX_WIDTH, 1, /*width, height*/ 1362 32, /*bitmap_pad*/ 1363 0 /*bytes_per_line*/ ); 1364#endif 1365 } 1366 1367 return GL_TRUE; 1368} 1369 1370 1371 1372/* 1373 * Convert an RGBA color to a pixel value. 1374 */ 1375unsigned long 1376xmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLubyte a, 1377 GLuint pixelFormat) 1378{ 1379 switch (pixelFormat) { 1380 case PF_INDEX: 1381 return 0; 1382 case PF_TRUECOLOR: 1383 { 1384 unsigned long p; 1385 PACK_TRUECOLOR( p, r, g, b ); 1386 return p; 1387 } 1388 case PF_8A8B8G8R: 1389 return PACK_8A8B8G8R( r, g, b, a ); 1390 case PF_8R8G8B: 1391 /* fall through */ 1392 case PF_8R8G8B24: 1393 return PACK_8R8G8B( r, g, b ); 1394 case PF_5R6G5B: 1395 return PACK_5R6G5B( r, g, b ); 1396 case PF_DITHER: 1397 { 1398 DITHER_SETUP; 1399 return DITHER( 1, 0, r, g, b ); 1400 } 1401 case PF_1BIT: 1402 /* 382 = (3*255)/2 */ 1403 return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip; 1404 case PF_HPCR: 1405 return DITHER_HPCR(1, 1, r, g, b); 1406 case PF_LOOKUP: 1407 { 1408 LOOKUP_SETUP; 1409 return LOOKUP( r, g, b ); 1410 } 1411 case PF_GRAYSCALE: 1412 return GRAY_RGB( r, g, b ); 1413 case PF_TRUEDITHER: 1414 /* fall through */ 1415 case PF_DITHER_5R6G5B: 1416 { 1417 unsigned long p; 1418 PACK_TRUEDITHER(p, 1, 0, r, g, b); 1419 return p; 1420 } 1421 default: 1422 _mesa_problem(NULL, "Bad pixel format in xmesa_color_to_pixel"); 1423 } 1424 return 0; 1425} 1426 1427 1428/**********************************************************************/ 1429/***** Public Functions *****/ 1430/**********************************************************************/ 1431 1432 1433/* 1434 * Create a new X/Mesa visual. 1435 * Input: display - X11 display 1436 * visinfo - an XVisualInfo pointer 1437 * rgb_flag - GL_TRUE = RGB mode, 1438 * GL_FALSE = color index mode 1439 * alpha_flag - alpha buffer requested? 1440 * db_flag - GL_TRUE = double-buffered, 1441 * GL_FALSE = single buffered 1442 * stereo_flag - stereo visual? 1443 * ximage_flag - GL_TRUE = use an XImage for back buffer, 1444 * GL_FALSE = use an off-screen pixmap for back buffer 1445 * depth_size - requested bits/depth values, or zero 1446 * stencil_size - requested bits/stencil values, or zero 1447 * accum_red_size - requested bits/red accum values, or zero 1448 * accum_green_size - requested bits/green accum values, or zero 1449 * accum_blue_size - requested bits/blue accum values, or zero 1450 * accum_alpha_size - requested bits/alpha accum values, or zero 1451 * num_samples - number of samples/pixel if multisampling, or zero 1452 * level - visual level, usually 0 1453 * visualCaveat - ala the GLX extension, usually GLX_NONE_EXT 1454 * Return; a new XMesaVisual or 0 if error. 1455 */ 1456XMesaVisual XMesaCreateVisual( XMesaDisplay *display, 1457 XMesaVisualInfo visinfo, 1458 GLboolean rgb_flag, 1459 GLboolean alpha_flag, 1460 GLboolean db_flag, 1461 GLboolean stereo_flag, 1462 GLboolean ximage_flag, 1463 GLint depth_size, 1464 GLint stencil_size, 1465 GLint accum_red_size, 1466 GLint accum_green_size, 1467 GLint accum_blue_size, 1468 GLint accum_alpha_size, 1469 GLint num_samples, 1470 GLint level, 1471 GLint visualCaveat ) 1472{ 1473 char *gamma; 1474 XMesaVisual v; 1475 GLint red_bits, green_bits, blue_bits, alpha_bits; 1476 1477 /* For debugging only */ 1478 if (getenv("MESA_XSYNC")) { 1479 /* This makes debugging X easier. 1480 * In your debugger, set a breakpoint on _XError to stop when an 1481 * X protocol error is generated. 1482 */ 1483#ifdef XFree86Server 1484 /* NOT_NEEDED */ 1485#else 1486 XSynchronize( display, 1 ); 1487#endif 1488 } 1489 1490 v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); 1491 if (!v) { 1492 return NULL; 1493 } 1494 1495 /* 1496 * In the X server, NULL is passed in for the display. It will have 1497 * to be set before using this visual. See XMesaSetVisualDisplay() 1498 * below. 1499 */ 1500 v->display = display; 1501 1502 /* Save a copy of the XVisualInfo struct because the user may XFREE() 1503 * the struct but we may need some of the information contained in it 1504 * at a later time. 1505 */ 1506#ifdef XFree86Server 1507 v->visinfo = visinfo; 1508#else 1509 v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); 1510 if(!v->visinfo) { 1511 FREE(v); 1512 return NULL; 1513 } 1514 MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); 1515 1516 /* Save a copy of the pointer now so we can find this visual again 1517 * if we need to search for it in find_glx_visual(). 1518 */ 1519 v->vishandle = visinfo; 1520#endif 1521 1522#ifdef XFree86Server 1523 /* Initialize the depth of the screen */ 1524 { 1525 PixmapFormatRec *format; 1526 1527 for (format = screenInfo.formats; 1528 format->depth != display->rootDepth; 1529 format++) 1530 ; 1531 v->screen_depth = format->bitsPerPixel; 1532 } 1533#endif 1534 1535 /* check for MESA_GAMMA environment variable */ 1536 gamma = getenv("MESA_GAMMA"); 1537 if (gamma) { 1538 v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0; 1539 sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma ); 1540 if (v->RedGamma<=0.0) v->RedGamma = 1.0; 1541 if (v->GreenGamma<=0.0) v->GreenGamma = v->RedGamma; 1542 if (v->BlueGamma<=0.0) v->BlueGamma = v->RedGamma; 1543 } 1544 else { 1545 v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0; 1546 } 1547 1548 v->ximage_flag = ximage_flag; 1549 v->level = level; 1550 v->VisualCaveat = visualCaveat; 1551 1552 (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 ); 1553 1554 { 1555 int xclass; 1556 xclass = GET_VISUAL_CLASS(v); 1557 if (xclass==TrueColor || xclass==DirectColor) { 1558 red_bits = bitcount(GET_REDMASK(v)); 1559 green_bits = bitcount(GET_GREENMASK(v)); 1560 blue_bits = bitcount(GET_BLUEMASK(v)); 1561 alpha_bits = 0; 1562 } 1563 else { 1564 /* this is an approximation */ 1565 int depth; 1566 depth = GET_VISUAL_DEPTH(v); 1567 red_bits = depth / 3; 1568 depth -= red_bits; 1569 green_bits = depth / 2; 1570 depth -= green_bits; 1571 blue_bits = depth; 1572 alpha_bits = 0; 1573 assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) ); 1574 } 1575 } 1576 1577 if (alpha_flag && alpha_bits == 0) 1578 alpha_bits = 8; 1579 1580 _mesa_initialize_visual( &v->mesa_visual, 1581 rgb_flag, db_flag, stereo_flag, 1582 red_bits, green_bits, 1583 blue_bits, alpha_bits, 1584 v->index_bits, 1585 depth_size, 1586 stencil_size, 1587 accum_red_size, accum_green_size, 1588 accum_blue_size, accum_alpha_size, 1589 0 ); 1590 return v; 1591} 1592 1593 1594void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v ) 1595{ 1596 v->display = dpy; 1597} 1598 1599 1600void XMesaDestroyVisual( XMesaVisual v ) 1601{ 1602#ifndef XFree86Server 1603 FREE(v->visinfo); 1604#endif 1605 FREE(v); 1606} 1607 1608 1609 1610/* 1611 * Create a new XMesaContext. 1612 * Input: v - XMesaVisual 1613 * share_list - another XMesaContext with which to share display 1614 * lists or NULL if no sharing is wanted. 1615 * Return: an XMesaContext or NULL if error. 1616 */ 1617XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) 1618{ 1619 static GLboolean firstTime = GL_TRUE; 1620 XMesaContext c; 1621 GLcontext *ctx; 1622 __GLimports imports; 1623 1624 if (firstTime) { 1625 _glthread_INIT_MUTEX(_xmesa_lock); 1626 firstTime = GL_FALSE; 1627 } 1628 1629 c = (XMesaContext) CALLOC_STRUCT(xmesa_context); 1630 if (!c) { 1631 return NULL; 1632 } 1633 1634 _mesa_init_default_imports( &imports, (void *) c ); 1635 ctx = c->gl_ctx = _mesa_create_context( &v->mesa_visual, 1636 share_list ? share_list->gl_ctx : (GLcontext *) NULL, 1637 &imports ); 1638 if (!c->gl_ctx) { 1639 FREE(c); 1640 return NULL; 1641 } 1642 1643 _mesa_enable_sw_extensions(ctx); 1644 _mesa_enable_1_3_extensions(ctx); 1645 1646 if (CHECK_BYTE_ORDER(v)) { 1647 c->swapbytes = GL_FALSE; 1648 } 1649 else { 1650 c->swapbytes = GL_TRUE; 1651 } 1652 1653 c->xm_visual = v; 1654 c->xm_draw_buffer = NULL; /* set later by XMesaMakeCurrent */ 1655 c->xm_read_buffer = NULL; /* set later by XMesaMakeCurrent */ 1656 c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ 1657 c->display = v->display; 1658 c->pixelformat = v->dithered_pf; /* Dithering is enabled by default */ 1659 1660 ctx->Driver.UpdateState = xmesa_update_state; 1661 1662 /* Initialize the software rasterizer and helper modules. 1663 */ 1664 _swrast_CreateContext( ctx ); 1665 _ac_CreateContext( ctx ); 1666 _tnl_CreateContext( ctx ); 1667 _swsetup_CreateContext( ctx ); 1668 1669 xmesa_register_swrast_functions( ctx ); 1670 1671 /* Set up some constant pointers: 1672 */ 1673 xmesa_init_pointers( ctx ); 1674 1675 return c; 1676} 1677 1678 1679 1680 1681void XMesaDestroyContext( XMesaContext c ) 1682{ 1683#ifdef FX 1684 if (c->xm_draw_buffer && c->xm_buffer->FXctx) 1685 fxMesaDestroyContext(c->xm_draw_buffer->FXctx); 1686#endif 1687 if (c->gl_ctx) { 1688 _swsetup_DestroyContext( c->gl_ctx ); 1689 _swrast_DestroyContext( c->gl_ctx ); 1690 _tnl_DestroyContext( c->gl_ctx ); 1691 _ac_DestroyContext( c->gl_ctx ); 1692 _mesa_destroy_context( c->gl_ctx ); 1693 } 1694 1695 FREE( c ); 1696} 1697 1698 1699 1700/* 1701 * XXX this isn't a public function! It's a hack for the 3Dfx driver. 1702 * Create a new XMesaBuffer from an X window. 1703 * Input: v - the XMesaVisual 1704 * w - the window 1705 * c - the context 1706 * Return: new XMesaBuffer or NULL if error 1707 */ 1708XMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v, XMesaWindow w, 1709 XMesaContext c ) 1710{ 1711#ifndef XFree86Server 1712 XWindowAttributes attr; 1713#endif 1714#ifdef FX 1715 char *fxEnvVar; 1716#endif 1717 int client = 0; 1718 1719 XMesaBuffer b = alloc_xmesa_buffer(); 1720 if (!b) { 1721 return NULL; 1722 } 1723 1724 (void) c; 1725 1726#ifdef XFree86Server 1727 client = CLIENT_ID(((XMesaDrawable)w)->id); 1728#endif 1729 1730 assert(v); 1731 1732#ifdef XFree86Server 1733 if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) { 1734#else 1735 XGetWindowAttributes( v->display, w, &attr ); 1736 1737 if (GET_VISUAL_DEPTH(v) != attr.depth) { 1738#endif 1739 if (getenv("MESA_DEBUG")) { 1740 fprintf(stderr, "XMesaCreateWindowBuffer: depth mismatch between visual and window!\n"); 1741 } 1742 return NULL; 1743 } 1744 1745 b->xm_visual = v; 1746 b->type = WINDOW; 1747 b->display = v->display; 1748#ifdef XFree86Server 1749 b->cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP); 1750#else 1751 if (attr.colormap) { 1752 b->cmap = attr.colormap; 1753 } 1754 else { 1755 if (getenv("MESA_DEBUG")) { 1756 fprintf(stderr, "Window %u has no colormap!\n", (unsigned int) w); 1757 } 1758 /* this is weird, a window w/out a colormap!? */ 1759 /* OK, let's just allocate a new one and hope for the best */ 1760 b->cmap = XCreateColormap(v->display, w, attr.visual, AllocNone); 1761 } 1762#endif 1763 1764 /* determine back buffer implementation */ 1765 if (v->mesa_visual.doubleBufferMode) { 1766 if (v->ximage_flag) { 1767 b->db_state = BACK_XIMAGE; 1768 } 1769 else { 1770 b->db_state = BACK_PIXMAP; 1771 } 1772 } 1773 else { 1774 b->db_state = 0; 1775 } 1776 1777 _mesa_initialize_framebuffer(&b->mesa_buffer, 1778 &v->mesa_visual, 1779 v->mesa_visual.depthBits > 0, 1780 v->mesa_visual.stencilBits > 0, 1781 v->mesa_visual.accumRedBits > 0, 1782 v->mesa_visual.alphaBits > 0 ); 1783 1784 if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode, 1785 (XMesaDrawable)w, b->cmap )) { 1786 free_xmesa_buffer(client, b); 1787 return NULL; 1788 } 1789 1790#ifdef FX 1791 fxEnvVar = getenv("MESA_GLX_FX"); 1792 if (fxEnvVar) { 1793 if (fxEnvVar[0]!='d') { 1794 int attribs[100]; 1795 int numAttribs = 0; 1796 int hw; 1797 if (v->mesa_visual.depthBits > 0) { 1798 attribs[numAttribs++] = FXMESA_DEPTH_SIZE; 1799 attribs[numAttribs++] = 1; 1800 } 1801 if (v->mesa_visual.doubleBufferMode) { 1802 attribs[numAttribs++] = FXMESA_DOUBLEBUFFER; 1803 } 1804 if (v->mesa_visual.accumRedBits > 0) { 1805 attribs[numAttribs++] = FXMESA_ACCUM_SIZE; 1806 attribs[numAttribs++] = v->mesa_visual.accumRedBits; 1807 } 1808 if (v->mesa_visual.stencilBits > 0) { 1809 attribs[numAttribs++] = FXMESA_STENCIL_SIZE; 1810 attribs[numAttribs++] = v->mesa_visual.stencilBits; 1811 } 1812 if (v->mesa_visual.alphaBits > 0) { 1813 attribs[numAttribs++] = FXMESA_ALPHA_SIZE; 1814 attribs[numAttribs++] = 1; 1815 } 1816 if (c->gl_ctx) { 1817#define FXMESA_SHARE_CONTEXT 990099 /* keep in sync with fxapi.c! */ 1818 attribs[numAttribs++] = FXMESA_SHARE_CONTEXT; 1819 attribs[numAttribs++] = (int) c->gl_ctx; 1820 } 1821 attribs[numAttribs++] = FXMESA_NONE; 1822 1823 if ((hw = fxQueryHardware())==GR_SSTTYPE_VOODOO) { 1824 b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs); 1825 if ((v->undithered_pf!=PF_INDEX) && (b->backimage)) { 1826 b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE; 1827 if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W') 1828 b->FXwindowHack = b->FXctx ? GL_TRUE : GL_FALSE; 1829 else 1830 b->FXwindowHack = GL_FALSE; 1831 } 1832 } 1833 else { 1834 if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W') 1835 b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE, 1836 GR_REFRESH_75Hz, attribs); 1837 else 1838 b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs); 1839 b->FXisHackUsable = GL_FALSE; 1840 b->FXwindowHack = GL_FALSE; 1841 } 1842 /* 1843 fprintf(stderr, 1844 "voodoo %d, wid %d height %d hack: usable %d active %d\n", 1845 hw, b->width, b->height, b->FXisHackUsable, b->FXwindowHack); 1846 */ 1847 } 1848 } 1849 else { 1850 fprintf(stderr,"WARNING: This Mesa Library includes the Glide driver but\n"); 1851 fprintf(stderr," you have not defined the MESA_GLX_FX env. var.\n"); 1852 fprintf(stderr," (check the README.3DFX file for more information).\n\n"); 1853 fprintf(stderr," you can disable this message with a 'export MESA_GLX_FX=disable'.\n"); 1854 } 1855#endif 1856 1857 return b; 1858} 1859 1860 1861XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, XMesaWindow w ) 1862{ 1863 return XMesaCreateWindowBuffer2( v, w, NULL ); 1864} 1865 1866 1867/* 1868 * Create a new XMesaBuffer from an X pixmap. 1869 * Input: v - the XMesaVisual 1870 * p - the pixmap 1871 * cmap - the colormap, may be 0 if using a TrueColor or DirectColor 1872 * visual for the pixmap 1873 * Return: new XMesaBuffer or NULL if error 1874 */ 1875XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v, 1876 XMesaPixmap p, XMesaColormap cmap ) 1877{ 1878 int client = 0; 1879 XMesaBuffer b = alloc_xmesa_buffer(); 1880 if (!b) { 1881 return NULL; 1882 } 1883 1884 1885#ifdef XFree86Server 1886 client = CLIENT_ID(((XMesaDrawable)p)->id); 1887#endif 1888 1889 assert(v); 1890 1891 b->xm_visual = v; 1892 b->type = PIXMAP; 1893 b->display = v->display; 1894 b->cmap = cmap; 1895 1896 /* determine back buffer implementation */ 1897 if (v->mesa_visual.doubleBufferMode) { 1898 if (v->ximage_flag) { 1899 b->db_state = BACK_XIMAGE; 1900 } 1901 else { 1902 b->db_state = BACK_PIXMAP; 1903 } 1904 } 1905 else { 1906 b->db_state = 0; 1907 } 1908 1909 _mesa_initialize_framebuffer(&b->mesa_buffer, 1910 &v->mesa_visual, 1911 v->mesa_visual.depthBits > 0, 1912 v->mesa_visual.stencilBits > 0, 1913 v->mesa_visual.accumRedBits + 1914 v->mesa_visual.accumGreenBits + 1915 v->mesa_visual.accumBlueBits > 0, 1916 v->mesa_visual.alphaBits > 0 ); 1917 1918 if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, 1919 (XMesaDrawable)p, cmap)) { 1920 free_xmesa_buffer(client, b); 1921 return NULL; 1922 } 1923 1924 return b; 1925} 1926 1927 1928 1929XMesaBuffer XMesaCreatePBuffer( XMesaVisual v, XMesaColormap cmap, 1930 unsigned int width, unsigned int height ) 1931{ 1932 int client = 0; 1933 XMesaWindow root; 1934 XMesaDrawable drawable; /* X Pixmap Drawable */ 1935 XMesaBuffer b = alloc_xmesa_buffer(); 1936 if (!b) { 1937 return NULL; 1938 } 1939 1940 b->xm_visual = v; 1941 b->type = PBUFFER; 1942 b->display = v->display; 1943 b->cmap = cmap; 1944 1945 /* allocate pixmap for front buffer */ 1946 root = RootWindow( v->display, v->visinfo->screen ); 1947 drawable = XCreatePixmap( v->display, root, width, height, v->visinfo->depth ); 1948 1949 /* determine back buffer implementation */ 1950 if (v->mesa_visual.doubleBufferMode) { 1951 if (v->ximage_flag) { 1952 b->db_state = BACK_XIMAGE; 1953 } 1954 else { 1955 b->db_state = BACK_PIXMAP; 1956 } 1957 } 1958 else { 1959 b->db_state = 0; 1960 } 1961 1962 _mesa_initialize_framebuffer(&b->mesa_buffer, 1963 &v->mesa_visual, 1964 v->mesa_visual.depthBits > 0, 1965 v->mesa_visual.stencilBits > 0, 1966 v->mesa_visual.accumRedBits + 1967 v->mesa_visual.accumGreenBits + 1968 v->mesa_visual.accumBlueBits > 0, 1969 v->mesa_visual.alphaBits > 0 ); 1970 1971 if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, 1972 drawable, cmap)) { 1973 free_xmesa_buffer(client, b); 1974 return NULL; 1975 } 1976 1977 return b; 1978} 1979 1980 1981 1982/* 1983 * Deallocate an XMesaBuffer structure and all related info. 1984 */ 1985void XMesaDestroyBuffer( XMesaBuffer b ) 1986{ 1987 int client = 0; 1988 1989#ifdef XFree86Server 1990 if (b->frontbuffer) 1991 client = CLIENT_ID(b->frontbuffer->id); 1992#endif 1993 1994 if (b->gc) XMesaFreeGC( b->xm_visual->display, b->gc ); 1995 if (b->cleargc) XMesaFreeGC( b->xm_visual->display, b->cleargc ); 1996 if (b->swapgc) XMesaFreeGC( b->xm_visual->display, b->swapgc ); 1997 1998 if (b->backimage) { 1999#if defined(USE_XSHM) && !defined(XFree86Server) 2000 if (b->shm) { 2001 XShmDetach( b->xm_visual->display, &b->shminfo ); 2002 XDestroyImage( b->backimage ); 2003 shmdt( b->shminfo.shmaddr ); 2004 } 2005 else 2006#endif 2007 XMesaDestroyImage( b->backimage ); 2008 } 2009 if (b->backpixmap) { 2010 XMesaFreePixmap( b->xm_visual->display, b->backpixmap ); 2011 if (b->xm_visual->hpcr_clear_flag) { 2012 XMesaFreePixmap( b->xm_visual->display, 2013 b->xm_visual->hpcr_clear_pixmap ); 2014 XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage ); 2015 } 2016 } 2017 if (b->rowimage) { 2018 FREE( b->rowimage->data ); 2019 b->rowimage->data = NULL; 2020 XMesaDestroyImage( b->rowimage ); 2021 } 2022 2023 free_xmesa_buffer(client, b); 2024} 2025 2026 2027 2028/* 2029 * Bind buffer b to context c and make c the current rendering context. 2030 */ 2031GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b ) 2032{ 2033 return XMesaMakeCurrent2( c, b, b ); 2034} 2035 2036 2037/* 2038 * Bind buffer b to context c and make c the current rendering context. 2039 */ 2040GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, 2041 XMesaBuffer readBuffer ) 2042{ 2043 if (c) { 2044 if (!drawBuffer || !readBuffer) 2045 return GL_FALSE; /* must specify buffers! */ 2046 2047#ifdef FX 2048 if (drawBuffer->FXctx) { 2049 fxMesaMakeCurrent(drawBuffer->FXctx); 2050 2051 c->xm_draw_buffer = drawBuffer; 2052 c->xm_read_buffer = readBuffer; 2053 c->xm_buffer = drawBuffer; 2054 2055 return GL_TRUE; 2056 } 2057#endif 2058 if (c->gl_ctx == _mesa_get_current_context() 2059 && c->xm_draw_buffer == drawBuffer 2060 && c->xm_read_buffer == readBuffer 2061 && c->xm_draw_buffer->wasCurrent) { 2062 /* same context and buffer, do nothing */ 2063 return GL_TRUE; 2064 } 2065 2066 c->xm_draw_buffer = drawBuffer; 2067 c->xm_read_buffer = readBuffer; 2068 c->xm_buffer = drawBuffer; 2069 2070 _mesa_make_current2(c->gl_ctx, 2071 &drawBuffer->mesa_buffer, 2072 &readBuffer->mesa_buffer); 2073 2074 if (c->gl_ctx->Viewport.Width == 0) { 2075 /* initialize viewport to window size */ 2076 _mesa_Viewport( 0, 0, drawBuffer->width, drawBuffer->height ); 2077 c->gl_ctx->Scissor.Width = drawBuffer->width; 2078 c->gl_ctx->Scissor.Height = drawBuffer->height; 2079 } 2080 2081 if (c->xm_visual->mesa_visual.rgbMode) { 2082 /* 2083 * Must recompute and set these pixel values because colormap 2084 * can be different for different windows. 2085 */ 2086 c->clearpixel = xmesa_color_to_pixel( c, 2087 c->clearcolor[0], 2088 c->clearcolor[1], 2089 c->clearcolor[2], 2090 c->clearcolor[3], 2091 c->xm_visual->undithered_pf); 2092 XMesaSetForeground(c->display, c->xm_draw_buffer->cleargc, c->clearpixel); 2093 } 2094 2095 /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ 2096 c->xm_draw_buffer->wasCurrent = GL_TRUE; 2097 } 2098 else { 2099 /* Detach */ 2100 _mesa_make_current2( NULL, NULL, NULL ); 2101 } 2102 return GL_TRUE; 2103} 2104 2105 2106/* 2107 * Unbind the context c from its buffer. 2108 */ 2109GLboolean XMesaUnbindContext( XMesaContext c ) 2110{ 2111 /* A no-op for XFree86 integration purposes */ 2112 return GL_TRUE; 2113} 2114 2115 2116XMesaContext XMesaGetCurrentContext( void ) 2117{ 2118 GET_CURRENT_CONTEXT(ctx); 2119 if (ctx) { 2120 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 2121 return xmesa; 2122 } 2123 else { 2124 return 0; 2125 } 2126} 2127 2128 2129XMesaBuffer XMesaGetCurrentBuffer( void ) 2130{ 2131 GET_CURRENT_CONTEXT(ctx); 2132 if (ctx) { 2133 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 2134 return xmesa->xm_draw_buffer; 2135 } 2136 else { 2137 return 0; 2138 } 2139} 2140 2141 2142/* New in Mesa 3.1 */ 2143XMesaBuffer XMesaGetCurrentReadBuffer( void ) 2144{ 2145 GET_CURRENT_CONTEXT(ctx); 2146 if (ctx) { 2147 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 2148 return xmesa->xm_read_buffer; 2149 } 2150 else { 2151 return 0; 2152 } 2153} 2154 2155 2156GLboolean XMesaForceCurrent(XMesaContext c) 2157{ 2158 if (c) { 2159 if (c->gl_ctx != _mesa_get_current_context()) { 2160 _mesa_make_current(c->gl_ctx, &c->xm_draw_buffer->mesa_buffer); 2161 } 2162 } 2163 else { 2164 _mesa_make_current(NULL, NULL); 2165 } 2166 return GL_TRUE; 2167} 2168 2169 2170GLboolean XMesaLoseCurrent(XMesaContext c) 2171{ 2172 (void) c; 2173 _mesa_make_current(NULL, NULL); 2174 return GL_TRUE; 2175} 2176 2177 2178/* 2179 * Switch 3Dfx support hack between window and full-screen mode. 2180 */ 2181GLboolean XMesaSetFXmode( GLint mode ) 2182{ 2183#ifdef FX 2184 const char *fx = getenv("MESA_GLX_FX"); 2185 if (fx && fx[0] != 'd') { 2186 GET_CURRENT_CONTEXT(ctx); 2187 GrHwConfiguration hw; 2188 if (!FX_grSstQueryHardware(&hw)) { 2189 /*fprintf(stderr, "!grSstQueryHardware\n");*/ 2190 return GL_FALSE; 2191 } 2192 if (hw.num_sst < 1) { 2193 /*fprintf(stderr, "hw.num_sst < 1\n");*/ 2194 return GL_FALSE; 2195 } 2196 if (ctx) { 2197 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 2198 if (mode == XMESA_FX_WINDOW) { 2199 if (xmesa->xm_draw_buffer->FXisHackUsable) { 2200 FX_grSstControl(GR_CONTROL_DEACTIVATE); 2201 xmesa->xm_draw_buffer->FXwindowHack = GL_TRUE; 2202 return GL_TRUE; 2203 } 2204 } 2205 else if (mode == XMESA_FX_FULLSCREEN) { 2206 FX_grSstControl(GR_CONTROL_ACTIVATE); 2207 xmesa->xm_draw_buffer->FXwindowHack = GL_FALSE; 2208 return GL_TRUE; 2209 } 2210 else { 2211 /* Error: Bad mode value */ 2212 } 2213 } 2214 } 2215 /*fprintf(stderr, "fallthrough\n");*/ 2216#else 2217 (void) mode; 2218#endif 2219 return GL_FALSE; 2220} 2221 2222 2223 2224#ifdef FX 2225/* 2226 * Read image from VooDoo frame buffer into X/Mesa's back XImage. 2227 */ 2228static void FXgetImage( XMesaBuffer b ) 2229{ 2230 GET_CURRENT_CONTEXT(ctx); 2231 static unsigned short pixbuf[MAX_WIDTH]; 2232 GLuint x, y; 2233 int xpos, ypos; 2234 XMesaWindow root; 2235 unsigned int bw, depth, width, height; 2236 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 2237 2238#ifdef XFree86Server 2239 x = b->frontbuffer->x; 2240 y = b->frontbuffer->y; 2241 width = b->frontbuffer->width; 2242 height = b->frontbuffer->height; 2243 depth = b->frontbuffer->depth; 2244#else 2245 XGetGeometry( b->xm_visual->display, b->frontbuffer, 2246 &root, &xpos, &ypos, &width, &height, &bw, &depth); 2247#endif 2248 if (b->width != width || b->height != height) { 2249 b->width = MIN2((int)width, b->FXctx->width); 2250 b->height = MIN2((int)height, b->FXctx->height); 2251 if (b->width & 1) 2252 b->width--; /* prevent odd width */ 2253 xmesa_alloc_back_buffer( b ); 2254 } 2255 2256 grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); 2257 if (b->xm_visual->undithered_pf==PF_5R6G5B) { 2258 /* Special case: 16bpp RGB */ 2259 grLfbReadRegion( GR_BUFFER_FRONTBUFFER, /* src buffer */ 2260 0, b->FXctx->height - b->height, /*pos*/ 2261 b->width, b->height, /* size */ 2262 b->width * sizeof(GLushort), /* stride */ 2263 b->backimage->data); /* dest buffer */ 2264 } 2265 else if (b->xm_visual->dithered_pf==PF_DITHER 2266 && GET_VISUAL_DEPTH(b->xm_visual)==8) { 2267 /* Special case: 8bpp RGB */ 2268 for (y=0;y<b->height;y++) { 2269 GLubyte *ptr = (GLubyte*) b->backimage->data 2270 + b->backimage->bytes_per_line * y; 2271 XDITHER_SETUP(y); 2272 2273 /* read row from 3Dfx frame buffer */ 2274 grLfbReadRegion( GR_BUFFER_FRONTBUFFER, 2275 0, b->FXctx->height-(b->height-y), 2276 b->width, 1, 2277 0, 2278 pixbuf ); 2279 2280 /* write to XImage back buffer */ 2281 for (x=0;x<b->width;x++) { 2282 GLubyte r = (pixbuf[x] & 0xf800) >> 8; 2283 GLubyte g = (pixbuf[x] & 0x07e0) >> 3; 2284 GLubyte b = (pixbuf[x] & 0x001f) << 3; 2285 *ptr++ = XDITHER( x, r, g, b); 2286 } 2287 } 2288 } 2289 else { 2290 /* General case: slow! */ 2291 for (y=0;y<b->height;y++) { 2292 /* read row from 3Dfx frame buffer */ 2293 grLfbReadRegion( GR_BUFFER_FRONTBUFFER, 2294 0, b->FXctx->height-(b->height-y), 2295 b->width, 1, 2296 0, 2297 pixbuf ); 2298 2299 /* write to XImage back buffer */ 2300 for (x=0;x<b->width;x++) { 2301 XMesaPutPixel(b->backimage,x,y, 2302 xmesa_color_to_pixel(xmesa, 2303 (pixbuf[x] & 0xf800) >> 8, 2304 (pixbuf[x] & 0x07e0) >> 3, 2305 (pixbuf[x] & 0x001f) << 3, 2306 0xff, 2307 b->xm_visual->undithered_pf)); 2308 } 2309 } 2310 } 2311 grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); 2312} 2313#endif 2314 2315 2316/* 2317 * Copy the back buffer to the front buffer. If there's no back buffer 2318 * this is a no-op. 2319 */ 2320void XMesaSwapBuffers( XMesaBuffer b ) 2321{ 2322 GET_CURRENT_CONTEXT(ctx); 2323 2324 /* If we're swapping the buffer associated with the current context 2325 * we have to flush any pending rendering commands first. 2326 */ 2327 if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) 2328 _mesa_swapbuffers(ctx); 2329 2330 if (b->db_state) { 2331#ifdef FX 2332 if (b->FXctx) { 2333 fxMesaSwapBuffers(); 2334 2335 if (b->FXwindowHack) 2336 FXgetImage(b); 2337 else 2338 return; 2339 } 2340#endif 2341 if (b->backimage) { 2342 /* Copy Ximage from host's memory to server's window */ 2343#if defined(USE_XSHM) && !defined(XFree86Server) 2344 if (b->shm) { 2345 /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ 2346 XShmPutImage( b->xm_visual->display, b->frontbuffer, 2347 b->swapgc, 2348 b->backimage, 0, 0, 2349 0, 0, b->width, b->height, False ); 2350 /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ 2351 } 2352 else 2353#endif 2354 { 2355 /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ 2356 XMesaPutImage( b->xm_visual->display, b->frontbuffer, 2357 b->swapgc, 2358 b->backimage, 0, 0, 2359 0, 0, b->width, b->height ); 2360 /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ 2361 } 2362 } 2363 else { 2364 /* Copy pixmap to window on server */ 2365 /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ 2366 XMesaCopyArea( b->xm_visual->display, 2367 b->backpixmap, /* source drawable */ 2368 b->frontbuffer, /* dest. drawable */ 2369 b->swapgc, 2370 0, 0, b->width, b->height, /* source region */ 2371 0, 0 /* dest region */ 2372 ); 2373 /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ 2374 } 2375 } 2376#if !defined(XFree86Server) 2377 XSync( b->xm_visual->display, False ); 2378#endif 2379} 2380 2381 2382 2383/* 2384 * Copy sub-region of back buffer to front buffer 2385 */ 2386void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) 2387{ 2388 GET_CURRENT_CONTEXT(ctx); 2389 2390 /* If we're swapping the buffer associated with the current context 2391 * we have to flush any pending rendering commands first. 2392 */ 2393 if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) 2394 _mesa_swapbuffers(ctx); 2395 2396 if (b->db_state) { 2397 int yTop = b->height - y - height; 2398#ifdef FX 2399 if (b->FXctx) { 2400 fxMesaSwapBuffers(); 2401 if (b->FXwindowHack) 2402 FXgetImage(b); 2403 else 2404 return; 2405 } 2406#endif 2407 if (b->backimage) { 2408 /* Copy Ximage from host's memory to server's window */ 2409#if defined(USE_XSHM) && !defined(XFree86Server) 2410 if (b->shm) { 2411 /* XXX assuming width and height aren't too large! */ 2412 XShmPutImage( b->xm_visual->display, b->frontbuffer, 2413 b->swapgc, 2414 b->backimage, x, yTop, 2415 x, yTop, width, height, False ); 2416 /* wait for finished event??? */ 2417 } 2418 else 2419#endif 2420 { 2421 /* XXX assuming width and height aren't too large! */ 2422 XMesaPutImage( b->xm_visual->display, b->frontbuffer, 2423 b->swapgc, 2424 b->backimage, x, yTop, 2425 x, yTop, width, height ); 2426 } 2427 } 2428 else { 2429 /* Copy pixmap to window on server */ 2430 XMesaCopyArea( b->xm_visual->display, 2431 b->backpixmap, /* source drawable */ 2432 b->frontbuffer, /* dest. drawable */ 2433 b->swapgc, 2434 x, yTop, width, height, /* source region */ 2435 x, yTop /* dest region */ 2436 ); 2437 } 2438 } 2439} 2440 2441 2442/* 2443 * Return a pointer to the XMesa backbuffer Pixmap or XImage. This function 2444 * is a way to get "under the hood" of X/Mesa so one can manipulate the 2445 * back buffer directly. 2446 * Output: pixmap - pointer to back buffer's Pixmap, or 0 2447 * ximage - pointer to back buffer's XImage, or NULL 2448 * Return: GL_TRUE = context is double buffered 2449 * GL_FALSE = context is single buffered 2450 */ 2451GLboolean XMesaGetBackBuffer( XMesaBuffer b, 2452 XMesaPixmap *pixmap, 2453 XMesaImage **ximage ) 2454{ 2455 if (b->db_state) { 2456 if (pixmap) *pixmap = b->backpixmap; 2457 if (ximage) *ximage = b->backimage; 2458 return GL_TRUE; 2459 } 2460 else { 2461 *pixmap = 0; 2462 *ximage = NULL; 2463 return GL_FALSE; 2464 } 2465} 2466 2467 2468/* 2469 * Return the depth buffer associated with an XMesaBuffer. 2470 * Input: b - the XMesa buffer handle 2471 * Output: width, height - size of buffer in pixels 2472 * bytesPerValue - bytes per depth value (2 or 4) 2473 * buffer - pointer to depth buffer values 2474 * Return: GL_TRUE or GL_FALSE to indicate success or failure. 2475 */ 2476GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, 2477 GLint *bytesPerValue, void **buffer ) 2478{ 2479 if (!b->mesa_buffer.DepthBuffer) { 2480 *width = 0; 2481 *height = 0; 2482 *bytesPerValue = 0; 2483 *buffer = 0; 2484 return GL_FALSE; 2485 } 2486 else { 2487 *width = b->mesa_buffer.Width; 2488 *height = b->mesa_buffer.Height; 2489 *bytesPerValue = sizeof(GLdepth); 2490 *buffer = b->mesa_buffer.DepthBuffer; 2491 return GL_TRUE; 2492 } 2493} 2494 2495 2496void XMesaFlush( XMesaContext c ) 2497{ 2498 if (c && c->xm_visual) { 2499#ifdef XFree86Server 2500 /* NOT_NEEDED */ 2501#else 2502 XSync( c->xm_visual->display, False ); 2503#endif 2504 } 2505} 2506 2507 2508 2509const char *XMesaGetString( XMesaContext c, int name ) 2510{ 2511 (void) c; 2512 if (name==XMESA_VERSION) { 2513 return "3.5"; 2514 } 2515 else if (name==XMESA_EXTENSIONS) { 2516 return ""; 2517 } 2518 else { 2519 return NULL; 2520 } 2521} 2522 2523 2524 2525XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d ) 2526{ 2527 XMesaBuffer b; 2528 for (b=XMesaBufferList; b; b=b->Next) { 2529 if (b->frontbuffer==d && b->display==dpy) { 2530 return b; 2531 } 2532 } 2533 return NULL; 2534} 2535 2536 2537 2538/* 2539 * Look for XMesaBuffers whose X window has been destroyed. 2540 * Deallocate any such XMesaBuffers. 2541 */ 2542void XMesaGarbageCollect( void ) 2543{ 2544 XMesaBuffer b, next; 2545 for (b=XMesaBufferList; b; b=next) { 2546 next = b->Next; 2547 if (b->display && b->frontbuffer && b->type == WINDOW) { 2548#ifdef XFree86Server 2549 /* NOT_NEEDED */ 2550#else 2551 XSync(b->display, False); 2552 if (!window_exists( b->display, b->frontbuffer )) { 2553 /* found a dead window, free the ancillary info */ 2554 XMesaDestroyBuffer( b ); 2555 } 2556#endif 2557 } 2558 } 2559} 2560 2561 2562void XMesaReset( void ) 2563{ 2564 while (XMesaBufferList) 2565 XMesaDestroyBuffer(XMesaBufferList); 2566 2567 XMesaBufferList = NULL; 2568} 2569 2570 2571unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, 2572 GLfloat red, GLfloat green, 2573 GLfloat blue, GLfloat alpha ) 2574{ 2575 GLint r = (GLint) (red * 255.0F); 2576 GLint g = (GLint) (green * 255.0F); 2577 GLint b = (GLint) (blue * 255.0F); 2578 GLint a = (GLint) (alpha * 255.0F); 2579 2580 switch (xmesa->pixelformat) { 2581 case PF_INDEX: 2582 return 0; 2583 case PF_TRUECOLOR: 2584 { 2585 unsigned long p; 2586 PACK_TRUECOLOR( p, r, g, b ); 2587 return p; 2588 } 2589 case PF_8A8B8G8R: 2590 return PACK_8A8B8G8R( r, g, b, a ); 2591 case PF_8R8G8B: 2592 return PACK_8R8G8B( r, g, b ); 2593 case PF_5R6G5B: 2594 return PACK_5R6G5B( r, g, b ); 2595 case PF_DITHER: 2596 { 2597 DITHER_SETUP; 2598 return DITHER( x, y, r, g, b ); 2599 } 2600 case PF_1BIT: 2601 /* 382 = (3*255)/2 */ 2602 return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip; 2603 case PF_HPCR: 2604 return DITHER_HPCR(x, y, r, g, b); 2605 case PF_LOOKUP: 2606 { 2607 LOOKUP_SETUP; 2608 return LOOKUP( r, g, b ); 2609 } 2610 case PF_GRAYSCALE: 2611 return GRAY_RGB( r, g, b ); 2612 case PF_DITHER_5R6G5B: 2613 /* fall through */ 2614 case PF_TRUEDITHER: 2615 { 2616 unsigned long p; 2617 PACK_TRUEDITHER(p, x, y, r, g, b); 2618 return p; 2619 } 2620 default: 2621 _mesa_problem(NULL, "Bad pixel format in XMesaDitherColor"); 2622 } 2623 return 0; 2624} 2625 2626 2627/* 2628 * This is typically called when the window size changes and we need 2629 * to reallocate the buffer's back/depth/stencil/accum buffers. 2630 */ 2631void XMesaResizeBuffers( XMesaBuffer b ) 2632{ 2633 xmesa_resize_buffers( &(b->mesa_buffer) ); 2634 2635} 2636 2637