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