3
* Mesa 3-D graphics library
6
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
8
* Permission is hereby granted, free of charge, to any person obtaining a
9
* copy of this software and associated documentation files (the "Software"),
10
* to deal in the Software without restriction, including without limitation
11
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
* and/or sell copies of the Software, and to permit persons to whom the
13
* Software is furnished to do so, subject to the following conditions:
15
* The above copyright notice and this permission notice shall be included
16
* in all copies or substantial portions of the Software.
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
/* $XFree86: xc/extras/Mesa/src/X/xm_api.c,v 1.6 2002/12/16 16:18:31 dawes Exp $ */
28
* This file contains the implementations of all the XMesa* functions.
33
* The window coordinate system origin (0,0) is in the lower-left corner
34
* of the window. X11's window coordinate origin is in the upper-left
35
* corner of the window. Therefore, most drawing functions in this
36
* file have to flip Y coordinates.
38
* Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile
39
* in support for the MIT Shared Memory extension. If enabled, when you
40
* use an Ximage for the back buffer in double buffered mode, the "swap"
41
* operation will be faster. You must also link with -lXext.
43
* Byte swapping: If the Mesa host and the X display use a different
44
* byte order then there's some trickiness to be aware of when using
45
* XImages. The byte ordering used for the XImage is that of the X
46
* display, not the Mesa host.
47
* The color-to-pixel encoding for True/DirectColor must be done
48
* according to the display's visual red_mask, green_mask, and blue_mask.
49
* If XPutPixel is used to put a pixel into an XImage then XPutPixel will
50
* do byte swapping if needed. If one wants to directly "poke" the pixel
51
* into the XImage's buffer then the pixel must be byte swapped first. In
52
* Mesa, when byte swapping is needed we use the PF_TRUECOLOR pixel format
53
* and use XPutPixel everywhere except in the implementation of
54
* glClear(GL_COLOR_BUFFER_BIT). We want this function to be fast so
55
* instead of using XPutPixel we "poke" our values after byte-swapping
56
* the clear pixel value if needed.
65
#include "glxheader.h"
69
#include "extensions.h"
79
#include "texformat.h"
81
#include "swrast/swrast.h"
82
#include "swrast_setup/swrast_setup.h"
83
#include "array_cache/acache.h"
87
#define GLX_NONE_EXT 0x8000
92
* Global X driver lock
94
_glthread_Mutex _xmesa_lock;
99
* Lookup tables for HPCR pixel format:
101
static short hpcr_rgbTbl[3][256] = {
103
16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
104
24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31,
105
32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39,
106
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
107
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
108
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
109
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
110
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
111
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
112
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
113
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
114
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
115
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
116
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
117
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
118
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
121
16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
122
24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31,
123
32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39,
124
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
125
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
126
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
127
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
128
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
129
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
130
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
131
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
132
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
133
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
134
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
135
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
136
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239
139
32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39,
140
40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47,
141
48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55,
142
56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63,
143
64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71,
144
72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79,
145
80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87,
146
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
147
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
148
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
149
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
150
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
151
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
152
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
153
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
154
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223
160
/**********************************************************************/
161
/***** X Utility Functions *****/
162
/**********************************************************************/
166
* X/Mesa error reporting function:
168
static void error( const char *msg )
170
(void)DitherValues; /* Muffle compiler */
172
if (getenv("MESA_DEBUG"))
173
fprintf( stderr, "X/Mesa error: %s\n", msg );
178
* Return the host's byte order as LSBFirst or MSBFirst ala X.
180
#ifndef XFree86Server
181
static int host_byte_order( void )
184
char *cptr = (char *) &i;
185
return (*cptr==1) ? LSBFirst : MSBFirst;
193
#ifndef XFree86Server
194
static int mesaXErrorFlag = 0;
196
static int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event )
207
* Check if the X Shared Memory extension is available.
208
* Return: 0 = not available
209
* 1 = shared XImage support available
210
* 2 = shared Pixmap support available also
212
#ifndef XFree86Server
213
static int check_for_xshm( XMesaDisplay *display )
216
int major, minor, ignore;
219
if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
220
if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
221
return (pixmaps==True) ? 2 : 1;
231
/* Can't compile XSHM support */
239
* Return the width and height of the given drawable.
241
static void get_drawable_size( XMesaDisplay *dpy, XMesaDrawable d,
242
unsigned int *width, unsigned int *height)
251
unsigned int bw, depth;
253
_glthread_LOCK_MUTEX(_xmesa_lock);
254
XGetGeometry( dpy, d, &root, &x, &y, width, height, &bw, &depth );
255
_glthread_UNLOCK_MUTEX(_xmesa_lock);
261
* Apply gamma correction to an intensity value in [0..max]. Return the
262
* new intensity value.
264
static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
270
double x = (double) value / (double) max;
271
return IROUND_POS((GLfloat) max * pow(x, 1.0F/gamma));
278
* Return the true number of bits per pixel for XImages.
279
* For example, if we request a 24-bit deep visual we may actually need/get
280
* 32bpp XImages. This function returns the appropriate bpp.
281
* Input: dpy - the X display
282
* visinfo - desribes the visual to be used for XImages
283
* Return: true number of bits per pixel for XImages
285
#define GET_BITS_PER_PIXEL(xmv) bits_per_pixel(xmv)
289
static int bits_per_pixel( XMesaVisual xmv )
291
XMesaVisualInfo visinfo = xmv->visinfo;
292
const int depth = visinfo->nplanes;
294
for (i = 0; i < screenInfo.numPixmapFormats; i++) {
295
if (screenInfo.formats[i].depth == depth)
296
return screenInfo.formats[i].bitsPerPixel;
298
return depth; /* should never get here, but this should be safe */
303
static int bits_per_pixel( XMesaVisual xmv )
305
XMesaDisplay *dpy = xmv->display;
306
XMesaVisualInfo visinfo = xmv->visinfo;
309
/* Create a temporary XImage */
310
img = XCreateImage( dpy, visinfo->visual, visinfo->depth,
311
ZPixmap, 0, /*format, offset*/
312
(char*) MALLOC(8), /*data*/
313
1, 1, /*width, height*/
318
/* grab the bits/pixel value */
319
bitsPerPixel = img->bits_per_pixel;
320
/* free the XImage */
323
XMesaDestroyImage( img );
331
* Determine if a given X window ID is valid (window exists).
332
* Do this by calling XGetWindowAttributes() for the window and
333
* checking if we catch an X error.
334
* Input: dpy - the display
335
* win - the window to check for existance
336
* Return: GL_TRUE - window exists
337
* GL_FALSE - window doesn't exist
339
#ifndef XFree86Server
340
static GLboolean WindowExistsFlag;
342
static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr )
345
if (xerr->error_code == BadWindow) {
346
WindowExistsFlag = GL_FALSE;
351
static GLboolean window_exists( XMesaDisplay *dpy, Window win )
353
XWindowAttributes wa;
354
int (*old_handler)( XMesaDisplay*, XErrorEvent* );
355
WindowExistsFlag = GL_TRUE;
356
old_handler = XSetErrorHandler(window_exists_err_handler);
357
XGetWindowAttributes( dpy, win, &wa ); /* dummy request */
358
XSetErrorHandler(old_handler);
359
return WindowExistsFlag;
365
/**********************************************************************/
366
/***** Linked list of XMesaBuffers *****/
367
/**********************************************************************/
369
static XMesaBuffer XMesaBufferList = NULL;
372
/* Allocate a new XMesaBuffer, add to linked list */
373
static XMesaBuffer alloc_xmesa_buffer(void)
375
XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
377
b->Next = XMesaBufferList;
385
* Find an XMesaBuffer by matching X display and colormap but NOT matching
386
* the notThis buffer.
388
static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
393
for (b=XMesaBufferList; b; b=b->Next) {
394
if (b->display==dpy && b->cmap==cmap && b!=notThis) {
403
* Free an XMesaBuffer, remove from linked list, perhaps free X colormap
406
static void free_xmesa_buffer(int client, XMesaBuffer buffer)
408
XMesaBuffer prev = NULL, b;
410
for (b=XMesaBufferList; b; b=b->Next) {
412
/* unlink bufer from list */
414
prev->Next = buffer->Next;
416
XMesaBufferList = buffer->Next;
417
/* Check to free X colors */
418
if (buffer->num_alloced>0) {
419
/* If no other buffer uses this X colormap then free the colors. */
420
if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) {
422
(void)FreeColors(buffer->cmap, client,
423
buffer->num_alloced, buffer->alloced_colors,
426
XFreeColors(buffer->display, buffer->cmap,
427
buffer->alloced_colors, buffer->num_alloced, 0);
432
_mesa_free_framebuffer_data(&buffer->mesa_buffer);
437
/* continue search */
440
/* buffer not found in XMesaBufferList */
441
_mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n");
445
/* Copy X color table stuff from one XMesaBuffer to another. */
446
static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
448
MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));
449
MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
450
MEMCPY(dst->pixel_to_g, src->pixel_to_g, sizeof(src->pixel_to_g));
451
MEMCPY(dst->pixel_to_b, src->pixel_to_b, sizeof(src->pixel_to_b));
452
dst->num_alloced = src->num_alloced;
453
MEMCPY(dst->alloced_colors, src->alloced_colors,
454
sizeof(src->alloced_colors));
459
/**********************************************************************/
460
/***** Misc Private Functions *****/
461
/**********************************************************************/
465
* Return number of bits set in n.
467
static int bitcount( unsigned long n )
470
for (bits=0; n>0; n=n>>1) {
481
* Allocate a shared memory XImage back buffer for the given XMesaBuffer.
482
* Return: GL_TRUE if success, GL_FALSE if error
484
#ifndef XFree86Server
485
static GLboolean alloc_shm_back_buffer( XMesaBuffer b )
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...
495
int (*old_handler)( XMesaDisplay *, XErrorEvent * );
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.");
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 );
515
error("alloc_back_buffer: Shared memory error (shmget), disabling.");
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 );
528
error("alloc_back_buffer: Shared memory error (shmat), disabling.");
533
b->shminfo.readOnly = False;
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 );
540
if (mesaXErrorFlag) {
541
/* we are on a remote display, this error is normal, don't print it */
542
XFlush( b->xm_visual->display );
544
XDestroyImage( b->backimage );
545
shmdt( b->shminfo.shmaddr );
546
shmctl( b->shminfo.shmid, IPC_RMID, 0 );
549
(void) XSetErrorHandler( old_handler );
553
shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */
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 );
565
XDestroyImage( b->backimage );
566
shmdt( b->shminfo.shmaddr );
567
shmctl( b->shminfo.shmid, IPC_RMID, 0 );
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);
595
/* Can't compile XSHM support */
604
* Setup an off-screen pixmap or Ximage to use as the back buffer.
605
* Input: b - the X/Mesa buffer
607
void xmesa_alloc_back_buffer( XMesaBuffer b )
609
if (b->db_state==BACK_XIMAGE) {
610
/* Deallocate the old backimage, if any */
612
#if defined(USE_XSHM) && !defined(XFree86Server)
614
XShmDetach( b->xm_visual->display, &b->shminfo );
615
XDestroyImage( b->backimage );
616
shmdt( b->shminfo.shmaddr );
620
XMesaDestroyImage( b->backimage );
624
/* Allocate new back buffer */
627
/* Allocate a regular XImage for the back buffer. */
628
b->backimage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
629
b->width, b->height, NULL);
632
|| alloc_shm_back_buffer(b)==GL_FALSE
634
/* Allocate a regular XImage for the back buffer. */
635
b->backimage = XCreateImage( b->xm_visual->display,
636
b->xm_visual->visinfo->visual,
637
GET_VISUAL_DEPTH(b->xm_visual),
638
ZPixmap, 0, /* format, offset */
639
NULL, b->width, b->height,
640
8, 0 ); /* pad, bytes_per_line */
643
error("alloc_back_buffer: XCreateImage failed.");
645
b->backimage->data = (char *) MALLOC( b->backimage->height
646
* b->backimage->bytes_per_line );
647
if (!b->backimage->data) {
648
error("alloc_back_buffer: MALLOC failed.");
649
XMesaDestroyImage( b->backimage );
653
b->backpixmap = None;
655
else if (b->db_state==BACK_PIXMAP) {
656
XMesaPixmap old_pixmap = b->backpixmap;
657
/* Free the old back pixmap */
659
XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
661
/* Allocate new back pixmap */
662
b->backpixmap = XMesaCreatePixmap( b->xm_visual->display, b->frontbuffer,
664
GET_VISUAL_DEPTH(b->xm_visual) );
666
/* update other references to backpixmap */
667
if (b->buffer==(XMesaDrawable)old_pixmap) {
668
b->buffer = (XMesaDrawable)b->backpixmap;
676
* A replacement for XAllocColor. This function should never
677
* fail to allocate a color. When XAllocColor fails, we return
678
* the nearest matching color. If we have to allocate many colors
679
* this function isn't too efficient; the XQueryColors() could be
681
* Written by Michael Pichler, Brian Paul, Mark Kilgard
682
* Input: dpy - X display
684
* cmapSize - size of colormap
685
* In/Out: color - the XColor struct
686
* Output: exact - 1=exact color match, 0=closest match
687
* alloced - 1=XAlloc worked, 0=XAlloc failed
690
noFaultXAllocColor( int client,
695
int *exact, int *alloced )
701
/* we'll try to cache ctable for better remote display performance */
702
static Display *prevDisplay = NULL;
703
static XMesaColormap prevCmap = 0;
704
static int prevCmapSize = 0;
705
static XMesaColor *ctable = NULL;
709
double mindist; /* 3*2^16^2 exceeds long int precision. */
713
/* First try just using XAllocColor. */
716
&color->red, &color->green, &color->blue,
718
client) == Success) {
720
if (XAllocColor(dpy, cmap, color)) {
727
/* Alloc failed, search for closest match */
729
/* Retrieve color table entries. */
730
/* XXX alloca candidate. */
732
ppixIn = (Pixel *) MALLOC(cmapSize * sizeof(Pixel));
733
ctable = (xrgb *) MALLOC(cmapSize * sizeof(xrgb));
734
for (i = 0; i < cmapSize; i++) {
737
QueryColors(cmap, cmapSize, ppixIn, ctable);
739
if (prevDisplay != dpy || prevCmap != cmap
740
|| prevCmapSize != cmapSize || !ctable) {
741
/* free previously cached color table */
744
/* Get the color table from X */
745
ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor));
747
for (i = 0; i < cmapSize; i++) {
750
XQueryColors(dpy, cmap, ctable, cmapSize);
753
prevCmapSize = cmapSize;
757
/* Find best match. */
760
for (i = 0; i < cmapSize; i++) {
761
double dr = 0.30 * ((double) color->red - (double) ctable[i].red);
762
double dg = 0.59 * ((double) color->green - (double) ctable[i].green);
763
double db = 0.11 * ((double) color->blue - (double) ctable[i].blue);
764
double dist = dr * dr + dg * dg + db * db;
765
if (bestmatch < 0 || dist < mindist) {
772
subColor.red = ctable[bestmatch].red;
773
subColor.green = ctable[bestmatch].green;
774
subColor.blue = ctable[bestmatch].blue;
775
/* Try to allocate the closest match color. This should only
776
* fail if the cell is read/write. Otherwise, we're incrementing
777
* the cell's reference count.
781
&subColor.red, &subColor.green, &subColor.blue,
783
client) == Success) {
785
if (XAllocColor(dpy, cmap, &subColor)) {
790
/* do this to work around a problem reported by Frank Ortega */
791
subColor.pixel = (unsigned long) bestmatch;
792
subColor.red = ctable[bestmatch].red;
793
subColor.green = ctable[bestmatch].green;
794
subColor.blue = ctable[bestmatch].blue;
795
subColor.flags = DoRed | DoGreen | DoBlue;
802
/* don't free table, save it for next time */
813
* Do setup for PF_GRAYSCALE pixel format.
814
* Note that buffer may be NULL.
816
static GLboolean setup_grayscale( int client, XMesaVisual v,
817
XMesaBuffer buffer, XMesaColormap cmap )
819
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
824
XMesaBuffer prevBuffer;
830
prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
832
(buffer->xm_visual->mesa_visual.rgbMode ==
833
prevBuffer->xm_visual->mesa_visual.rgbMode)) {
834
/* Copy colormap stuff from previous XMesaBuffer which uses same
835
* X colormap. Do this to avoid time spent in noFaultXAllocColor.
837
copy_colortable_info(buffer, prevBuffer);
840
/* Allocate 256 shades of gray */
842
int colorsfailed = 0;
843
for (gray=0;gray<256;gray++) {
844
GLint r = gamma_adjust( v->RedGamma, gray, 255 );
845
GLint g = gamma_adjust( v->GreenGamma, gray, 255 );
846
GLint b = gamma_adjust( v->BlueGamma, gray, 255 );
849
xcol.red = (r << 8) | r;
850
xcol.green = (g << 8) | g;
851
xcol.blue = (b << 8) | b;
852
noFaultXAllocColor( client, v->display,
853
cmap, GET_COLORMAP_SIZE(v),
854
&xcol, &exact, &alloced );
859
assert(buffer->num_alloced<256);
860
buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
861
buffer->num_alloced++;
866
buffer->color_table[gray*3+0] = xcol.pixel;
867
buffer->color_table[gray*3+1] = xcol.pixel;
868
buffer->color_table[gray*3+2] = xcol.pixel;
869
assert(xcol.pixel < 65536);
870
buffer->pixel_to_r[xcol.pixel] = gray * 30 / 100;
871
buffer->pixel_to_g[xcol.pixel] = gray * 59 / 100;
872
buffer->pixel_to_b[xcol.pixel] = gray * 11 / 100;
874
buffer->color_table[gray] = xcol.pixel;
875
assert(xcol.pixel < 65536);
876
buffer->pixel_to_r[xcol.pixel] = gray;
877
buffer->pixel_to_g[xcol.pixel] = gray;
878
buffer->pixel_to_b[xcol.pixel] = gray;
881
if (colorsfailed && getenv("MESA_DEBUG")) {
883
"Note: %d out of 256 needed colors do not match exactly.\n",
889
v->dithered_pf = PF_GRAYSCALE;
890
v->undithered_pf = PF_GRAYSCALE;
897
* Setup RGB rendering for a window with a PseudoColor, StaticColor,
898
* or 8-bit TrueColor visual visual. We try to allocate a palette of 225
899
* colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB
900
* color. While this function was originally designed just for 8-bit
901
* visuals, it has also proven to work from 4-bit up to 16-bit visuals.
902
* Dithering code contributed by Bob Mercier.
904
static GLboolean setup_dithered_color( int client, XMesaVisual v,
905
XMesaBuffer buffer, XMesaColormap cmap )
907
if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
912
XMesaBuffer prevBuffer;
918
prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
920
(buffer->xm_visual->mesa_visual.rgbMode ==
921
prevBuffer->xm_visual->mesa_visual.rgbMode)) {
922
/* Copy colormap stuff from previous, matching XMesaBuffer.
923
* Do this to avoid time spent in noFaultXAllocColor.
925
copy_colortable_info(buffer, prevBuffer);
928
/* Allocate X colors and initialize color_table[], red_table[], etc */
930
int colorsfailed = 0;
931
for (r = 0; r < _R; r++) {
932
for (g = 0; g < _G; g++) {
933
for (b = 0; b < _B; b++) {
936
xcol.red =gamma_adjust(v->RedGamma, r*65535/(_R-1),65535);
937
xcol.green=gamma_adjust(v->GreenGamma, g*65535/(_G-1),65535);
938
xcol.blue =gamma_adjust(v->BlueGamma, b*65535/(_B-1),65535);
939
noFaultXAllocColor( client, v->display,
940
cmap, GET_COLORMAP_SIZE(v),
941
&xcol, &exact, &alloced );
946
assert(buffer->num_alloced<256);
947
buffer->alloced_colors[buffer->num_alloced] = xcol.pixel;
948
buffer->num_alloced++;
952
buffer->color_table[i] = xcol.pixel;
953
assert(xcol.pixel < 65536);
954
buffer->pixel_to_r[xcol.pixel] = r * 255 / (_R-1);
955
buffer->pixel_to_g[xcol.pixel] = g * 255 / (_G-1);
956
buffer->pixel_to_b[xcol.pixel] = b * 255 / (_B-1);
961
if (colorsfailed && getenv("MESA_DEBUG")) {
963
"Note: %d out of %d needed colors do not match exactly.\n",
964
colorsfailed, _R*_G*_B );
969
v->dithered_pf = PF_DITHER;
970
v->undithered_pf = PF_LOOKUP;
976
* Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
977
* HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
978
* Special dithering tables have to be initialized.
980
static void setup_8bit_hpcr( XMesaVisual v )
982
/* HP Color Recovery contributed by: Alex De Bruyn (ad@lms.be)
983
* To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
984
* on the root window AND the colormap obtainable by XGetRGBColormaps
985
* for that atom must be set on the window. (see also tkInitWindow)
986
* If that colormap is not set, the output will look stripy.
989
/* Setup color tables with gamma correction */
993
g = 1.0 / v->RedGamma;
994
for (i=0; i<256; i++) {
995
GLint red = IROUND_POS(255.0 * pow( hpcr_rgbTbl[0][i]/255.0, g ));
996
v->hpcr_rgbTbl[0][i] = CLAMP( red, 16, 239 );
999
g = 1.0 / v->GreenGamma;
1000
for (i=0; i<256; i++) {
1001
GLint green = IROUND_POS(255.0 * pow( hpcr_rgbTbl[1][i]/255.0, g ));
1002
v->hpcr_rgbTbl[1][i] = CLAMP( green, 16, 239 );
1005
g = 1.0 / v->BlueGamma;
1006
for (i=0; i<256; i++) {
1007
GLint blue = IROUND_POS(255.0 * pow( hpcr_rgbTbl[2][i]/255.0, g ));
1008
v->hpcr_rgbTbl[2][i] = CLAMP( blue, 32, 223 );
1010
v->undithered_pf = PF_HPCR; /* can't really disable dithering for now */
1011
v->dithered_pf = PF_HPCR;
1013
/* which method should I use to clear */
1014
/* GL_FALSE: keep the ordinary method */
1015
/* GL_TRUE : clear with dither pattern */
1016
v->hpcr_clear_flag = getenv("MESA_HPCR_CLEAR") ? GL_TRUE : GL_FALSE;
1018
if (v->hpcr_clear_flag) {
1019
v->hpcr_clear_pixmap = XMesaCreatePixmap(v->display,
1020
DefaultRootWindow(v->display),
1022
#ifndef XFree86Server
1023
v->hpcr_clear_ximage = XGetImage(v->display, v->hpcr_clear_pixmap,
1024
0, 0, 16, 2, AllPlanes, ZPixmap);
1031
* Setup RGB rendering for a window with a True/DirectColor visual.
1033
static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
1034
XMesaColormap cmap )
1036
unsigned long rmask, gmask, bmask;
1040
/* Compute red multiplier (mask) and bit shift */
1042
rmask = GET_REDMASK(v);
1043
while ((rmask & 1)==0) {
1048
/* Compute green multiplier (mask) and bit shift */
1050
gmask = GET_GREENMASK(v);
1051
while ((gmask & 1)==0) {
1056
/* Compute blue multiplier (mask) and bit shift */
1058
bmask = GET_BLUEMASK(v);
1059
while ((bmask & 1)==0) {
1065
* Compute component-to-pixel lookup tables and dithering kernel
1068
static GLubyte kernel[16] = {
1069
0*16, 8*16, 2*16, 10*16,
1070
12*16, 4*16, 14*16, 6*16,
1071
3*16, 11*16, 1*16, 9*16,
1072
15*16, 7*16, 13*16, 5*16,
1074
GLint rBits = bitcount(rmask);
1075
GLint gBits = bitcount(gmask);
1076
GLint bBits = bitcount(bmask);
1080
/* convert pixel components in [0,_mask] to RGB values in [0,255] */
1081
for (i=0; i<=rmask; i++)
1082
v->PixelToR[i] = (unsigned char) ((i * 255) / rmask);
1083
for (i=0; i<=gmask; i++)
1084
v->PixelToG[i] = (unsigned char) ((i * 255) / gmask);
1085
for (i=0; i<=bmask; i++)
1086
v->PixelToB[i] = (unsigned char) ((i * 255) / bmask);
1088
/* convert RGB values from [0,255] to pixel components */
1090
for (i=0;i<256;i++) {
1091
GLint r = gamma_adjust(v->RedGamma, i, 255);
1092
GLint g = gamma_adjust(v->GreenGamma, i, 255);
1093
GLint b = gamma_adjust(v->BlueGamma, i, 255);
1094
v->RtoPixel[i] = (r >> (8-rBits)) << v->rshift;
1095
v->GtoPixel[i] = (g >> (8-gBits)) << v->gshift;
1096
v->BtoPixel[i] = (b >> (8-bBits)) << v->bshift;
1098
/* overflow protection */
1099
for (i=256;i<512;i++) {
1100
v->RtoPixel[i] = v->RtoPixel[255];
1101
v->GtoPixel[i] = v->GtoPixel[255];
1102
v->BtoPixel[i] = v->BtoPixel[255];
1105
/* setup dithering kernel */
1107
if (gBits > maxBits) maxBits = gBits;
1108
if (bBits > maxBits) maxBits = bBits;
1109
for (i=0;i<16;i++) {
1110
v->Kernel[i] = kernel[i] >> maxBits;
1113
v->undithered_pf = PF_TRUECOLOR;
1114
v->dithered_pf = (GET_VISUAL_DEPTH(v)<24) ? PF_TRUEDITHER : PF_TRUECOLOR;
1118
* Now check for TrueColor visuals which we can optimize.
1120
if ( GET_REDMASK(v) ==0x0000ff
1121
&& GET_GREENMASK(v)==0x00ff00
1122
&& GET_BLUEMASK(v) ==0xff0000
1123
&& CHECK_BYTE_ORDER(v)
1124
&& v->BitsPerPixel==32
1125
&& sizeof(GLuint)==4
1126
&& v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1127
/* common 32 bpp config used on SGI, Sun */
1128
v->undithered_pf = v->dithered_pf = PF_8A8B8G8R;
1130
else if (GET_REDMASK(v) ==0xff0000
1131
&& GET_GREENMASK(v)==0x00ff00
1132
&& GET_BLUEMASK(v) ==0x0000ff
1133
&& CHECK_BYTE_ORDER(v)
1134
&& v->BitsPerPixel==32
1135
&& sizeof(GLuint)==4
1136
&& v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1137
/* common 32 bpp config used on Linux, HP, IBM */
1138
v->undithered_pf = v->dithered_pf = PF_8R8G8B;
1140
else if (GET_REDMASK(v) ==0xff0000
1141
&& GET_GREENMASK(v)==0x00ff00
1142
&& GET_BLUEMASK(v) ==0x0000ff
1143
&& CHECK_BYTE_ORDER(v)
1144
&& v->BitsPerPixel==24
1145
&& sizeof(GLuint)==4
1146
&& v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1147
/* common packed 24 bpp config used on Linux */
1148
v->undithered_pf = v->dithered_pf = PF_8R8G8B24;
1150
else if (GET_REDMASK(v) ==0xf800
1151
&& GET_GREENMASK(v)==0x07e0
1152
&& GET_BLUEMASK(v) ==0x001f
1153
&& CHECK_BYTE_ORDER(v)
1154
&& v->BitsPerPixel==16
1155
&& sizeof(GLushort)==2
1156
&& v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
1157
/* 5-6-5 color weight on common PC VGA boards */
1158
v->undithered_pf = PF_5R6G5B;
1159
v->dithered_pf = PF_DITHER_5R6G5B;
1161
else if (GET_REDMASK(v) ==0xe0
1162
&& GET_GREENMASK(v)==0x1c
1163
&& GET_BLUEMASK(v) ==0x03
1164
&& CHECK_FOR_HPCR(v)) {
1165
setup_8bit_hpcr( v );
1172
* Setup RGB rendering for a window with a monochrome visual.
1174
static void setup_monochrome( XMesaVisual v, XMesaBuffer b )
1177
v->dithered_pf = v->undithered_pf = PF_1BIT;
1178
/* if black=1 then we must flip pixel values */
1179
v->bitFlip = (GET_BLACK_PIXEL(v) != 0);
1185
* When a context is "made current" for the first time, we can finally
1186
* finish initializing the context's visual and buffer information.
1187
* Input: v - the XMesaVisual to initialize
1188
* b - the XMesaBuffer to initialize (may be NULL)
1189
* rgb_flag - TRUE = RGBA mode, FALSE = color index mode
1190
* window - the window/pixmap we're rendering into
1191
* cmap - the colormap associated with the window/pixmap
1192
* Return: GL_TRUE=success, GL_FALSE=failure
1194
static GLboolean initialize_visual_and_buffer( int client,
1198
XMesaDrawable window,
1202
#ifndef XFree86Server
1207
assert(b->xm_visual == v);
1210
/* Save true bits/pixel */
1211
v->BitsPerPixel = GET_BITS_PER_PIXEL(v);
1212
assert(v->BitsPerPixel > 0);
1215
if (rgb_flag==GL_FALSE) {
1216
/* COLOR-INDEXED WINDOW:
1217
* Even if the visual is TrueColor or DirectColor we treat it as
1218
* being color indexed. This is weird but might be useful to someone.
1220
v->dithered_pf = v->undithered_pf = PF_INDEX;
1221
v->index_bits = GET_VISUAL_DEPTH(v);
1225
* We support RGB rendering into almost any kind of visual.
1228
xclass = GET_VISUAL_CLASS(v);
1229
if (xclass==TrueColor || xclass==DirectColor) {
1230
setup_truecolor( v, b, cmap );
1232
else if (xclass==StaticGray && GET_VISUAL_DEPTH(v)==1) {
1233
setup_monochrome( v, b );
1235
else if (xclass==GrayScale || xclass==StaticGray) {
1236
if (!setup_grayscale( client, v, b, cmap )) {
1240
else if ((xclass==PseudoColor || xclass==StaticColor)
1241
&& GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) {
1242
if (!setup_dithered_color( client, v, b, cmap )) {
1247
error("XMesa: RGB mode rendering not supported in given visual.");
1252
if (getenv("MESA_NO_DITHER")) {
1253
v->dithered_pf = v->undithered_pf;
1259
* If MESA_INFO env var is set print out some debugging info
1260
* which can help Brian figure out what's going on when a user
1263
if (getenv("MESA_INFO")) {
1264
fprintf(stderr, "X/Mesa visual = %p\n", (void *) v);
1265
fprintf(stderr, "X/Mesa dithered pf = %u\n", v->dithered_pf);
1266
fprintf(stderr, "X/Mesa undithered pf = %u\n", v->undithered_pf);
1267
fprintf(stderr, "X/Mesa level = %d\n", v->level);
1268
fprintf(stderr, "X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v));
1269
fprintf(stderr, "X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
1273
/* Do window-specific initializations */
1275
/* Window dimensions */
1277
get_drawable_size( v->display, window, &w, &h );
1281
b->frontbuffer = window;
1283
/* Setup for single/double buffering */
1284
if (v->mesa_visual.doubleBufferMode) {
1285
/* Double buffered */
1286
#ifndef XFree86Server
1287
b->shm = check_for_xshm( v->display );
1289
xmesa_alloc_back_buffer( b );
1290
if (b->db_state==BACK_PIXMAP) {
1291
b->buffer = (XMesaDrawable)b->backpixmap;
1298
/* Single Buffered */
1299
b->buffer = b->frontbuffer;
1302
/* X11 graphics contexts */
1303
#ifdef XFree86Server
1304
b->gc = CreateScratchGC(v->display, window->depth);
1306
b->gc = XCreateGC( v->display, window, 0, NULL );
1308
XMesaSetFunction( v->display, b->gc, GXcopy );
1310
/* cleargc - for glClear() */
1311
#ifdef XFree86Server
1312
b->cleargc = CreateScratchGC(v->display, window->depth);
1314
b->cleargc = XCreateGC( v->display, window, 0, NULL );
1316
XMesaSetFunction( v->display, b->cleargc, GXcopy );
1319
* Don't generate Graphics Expose/NoExpose events in swapbuffers().
1320
* Patch contributed by Michael Pichler May 15, 1995.
1322
#ifdef XFree86Server
1323
b->swapgc = CreateScratchGC(v->display, window->depth);
1327
dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL);
1330
gcvalues.graphics_exposures = False;
1331
b->swapgc = XCreateGC( v->display, window,
1332
GCGraphicsExposures, &gcvalues);
1334
XMesaSetFunction( v->display, b->swapgc, GXcopy );
1336
* Set fill style and tile pixmap once for all for HPCR stuff
1337
* (instead of doing it each time in clear_color_HPCR_pixmap())
1338
* Initialize whole stuff
1339
* Patch contributed by Jacques Leroy March 8, 1998.
1341
if (v->hpcr_clear_flag && b->buffer!=XIMAGE) {
1343
for (i=0; i<16; i++)
1345
XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0);
1346
XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0);
1348
XMesaPutImage(b->display, (XMesaDrawable)v->hpcr_clear_pixmap,
1349
b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2);
1350
XMesaSetFillStyle( v->display, b->cleargc, FillTiled);
1351
XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap );
1354
/* Initialize the row buffer XImage for use in write_color_span() */
1355
#ifdef XFree86Server
1356
b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1,
1357
(char *)MALLOC(MAX_WIDTH*4));
1359
b->rowimage = XCreateImage( v->display,
1362
ZPixmap, 0, /*format, offset*/
1363
(char*) MALLOC(MAX_WIDTH*4), /*data*/
1364
MAX_WIDTH, 1, /*width, height*/
1366
0 /*bytes_per_line*/ );
1376
* Convert an RGBA color to a pixel value.
1379
xmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLubyte a,
1382
switch (pixelFormat) {
1388
PACK_TRUECOLOR( p, r, g, b );
1392
return PACK_8A8B8G8R( r, g, b, a );
1396
return PACK_8R8G8B( r, g, b );
1398
return PACK_5R6G5B( r, g, b );
1402
return DITHER( 1, 0, r, g, b );
1405
/* 382 = (3*255)/2 */
1406
return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
1408
return DITHER_HPCR(1, 1, r, g, b);
1412
return LOOKUP( r, g, b );
1415
return GRAY_RGB( r, g, b );
1418
case PF_DITHER_5R6G5B:
1421
PACK_TRUEDITHER(p, 1, 0, r, g, b);
1425
_mesa_problem(NULL, "Bad pixel format in xmesa_color_to_pixel");
1431
/**********************************************************************/
1432
/***** Public Functions *****/
1433
/**********************************************************************/
1437
* Create a new X/Mesa visual.
1438
* Input: display - X11 display
1439
* visinfo - an XVisualInfo pointer
1440
* rgb_flag - GL_TRUE = RGB mode,
1441
* GL_FALSE = color index mode
1442
* alpha_flag - alpha buffer requested?
1443
* db_flag - GL_TRUE = double-buffered,
1444
* GL_FALSE = single buffered
1445
* stereo_flag - stereo visual?
1446
* ximage_flag - GL_TRUE = use an XImage for back buffer,
1447
* GL_FALSE = use an off-screen pixmap for back buffer
1448
* depth_size - requested bits/depth values, or zero
1449
* stencil_size - requested bits/stencil values, or zero
1450
* accum_red_size - requested bits/red accum values, or zero
1451
* accum_green_size - requested bits/green accum values, or zero
1452
* accum_blue_size - requested bits/blue accum values, or zero
1453
* accum_alpha_size - requested bits/alpha accum values, or zero
1454
* num_samples - number of samples/pixel if multisampling, or zero
1455
* level - visual level, usually 0
1456
* visualCaveat - ala the GLX extension, usually GLX_NONE_EXT
1457
* Return; a new XMesaVisual or 0 if error.
1459
XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
1460
XMesaVisualInfo visinfo,
1462
GLboolean alpha_flag,
1464
GLboolean stereo_flag,
1465
GLboolean ximage_flag,
1468
GLint accum_red_size,
1469
GLint accum_green_size,
1470
GLint accum_blue_size,
1471
GLint accum_alpha_size,
1474
GLint visualCaveat )
1478
GLint red_bits, green_bits, blue_bits, alpha_bits;
1480
/* For debugging only */
1481
if (getenv("MESA_XSYNC")) {
1482
/* This makes debugging X easier.
1483
* In your debugger, set a breakpoint on _XError to stop when an
1484
* X protocol error is generated.
1486
#ifdef XFree86Server
1489
XSynchronize( display, 1 );
1493
v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual);
1499
* In the X server, NULL is passed in for the display. It will have
1500
* to be set before using this visual. See XMesaSetVisualDisplay()
1503
v->display = display;
1505
/* Save a copy of the XVisualInfo struct because the user may XFREE()
1506
* the struct but we may need some of the information contained in it
1509
#ifdef XFree86Server
1510
v->visinfo = visinfo;
1512
v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
1517
MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
1519
/* Save a copy of the pointer now so we can find this visual again
1520
* if we need to search for it in find_glx_visual().
1522
v->vishandle = visinfo;
1525
#ifdef XFree86Server
1526
/* Initialize the depth of the screen */
1528
PixmapFormatRec *format;
1530
for (format = screenInfo.formats;
1531
format->depth != display->rootDepth;
1534
v->screen_depth = format->bitsPerPixel;
1538
/* check for MESA_GAMMA environment variable */
1539
gamma = getenv("MESA_GAMMA");
1541
v->RedGamma = v->GreenGamma = v->BlueGamma = 0.0;
1542
sscanf( gamma, "%f %f %f", &v->RedGamma, &v->GreenGamma, &v->BlueGamma );
1543
if (v->RedGamma<=0.0) v->RedGamma = 1.0;
1544
if (v->GreenGamma<=0.0) v->GreenGamma = v->RedGamma;
1545
if (v->BlueGamma<=0.0) v->BlueGamma = v->RedGamma;
1548
v->RedGamma = v->GreenGamma = v->BlueGamma = 1.0;
1551
v->ximage_flag = ximage_flag;
1553
v->VisualCaveat = visualCaveat;
1555
(void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 );
1559
xclass = GET_VISUAL_CLASS(v);
1560
if (xclass==TrueColor || xclass==DirectColor) {
1561
red_bits = bitcount(GET_REDMASK(v));
1562
green_bits = bitcount(GET_GREENMASK(v));
1563
blue_bits = bitcount(GET_BLUEMASK(v));
1567
/* this is an approximation */
1569
depth = GET_VISUAL_DEPTH(v);
1570
red_bits = depth / 3;
1572
green_bits = depth / 2;
1573
depth -= green_bits;
1576
assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) );
1580
if (alpha_flag && alpha_bits == 0)
1583
_mesa_initialize_visual( &v->mesa_visual,
1584
rgb_flag, db_flag, stereo_flag,
1585
red_bits, green_bits,
1586
blue_bits, alpha_bits,
1590
accum_red_size, accum_green_size,
1591
accum_blue_size, accum_alpha_size,
1597
void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v )
1603
void XMesaDestroyVisual( XMesaVisual v )
1605
#ifndef XFree86Server
1614
* Create a new XMesaContext.
1615
* Input: v - XMesaVisual
1616
* share_list - another XMesaContext with which to share display
1617
* lists or NULL if no sharing is wanted.
1618
* Return: an XMesaContext or NULL if error.
1620
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
1624
GLboolean direct = GL_TRUE; /* XXXX */
1625
/* NOT_DONE: should this be GL_FALSE??? */
1626
static GLboolean firstTime = GL_TRUE;
1629
_glthread_INIT_MUTEX(_xmesa_lock);
1630
firstTime = GL_FALSE;
1633
c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
1638
ctx = c->gl_ctx = _mesa_create_context( &v->mesa_visual,
1639
share_list ? share_list->gl_ctx : (GLcontext *) NULL,
1640
(void *) c, direct );
1646
_mesa_enable_sw_extensions(ctx);
1647
_mesa_enable_1_3_extensions(ctx);
1649
if (CHECK_BYTE_ORDER(v)) {
1650
c->swapbytes = GL_FALSE;
1653
c->swapbytes = GL_TRUE;
1657
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
1658
c->display = v->display;
1659
c->pixelformat = v->dithered_pf; /* Dithering is enabled by default */
1661
ctx->Driver.UpdateState = xmesa_update_state;
1663
/* Initialize the software rasterizer and helper modules.
1665
_swrast_CreateContext( ctx );
1666
_ac_CreateContext( ctx );
1667
_tnl_CreateContext( ctx );
1668
_swsetup_CreateContext( ctx );
1670
xmesa_register_swrast_functions( ctx );
1672
/* Set up some constant pointers:
1674
xmesa_init_pointers( ctx );
1677
/* Run the config file
1679
_mesa_read_config_file( ctx );
1688
void XMesaDestroyContext( XMesaContext c )
1691
if (c->xm_buffer && c->xm_buffer->FXctx)
1692
fxMesaDestroyContext(c->xm_buffer->FXctx);
1695
_swsetup_DestroyContext( c->gl_ctx );
1696
_swrast_DestroyContext( c->gl_ctx );
1697
_tnl_DestroyContext( c->gl_ctx );
1698
_ac_DestroyContext( c->gl_ctx );
1699
_mesa_destroy_context( c->gl_ctx );
1708
* XXX this isn't a public function! It's a hack for the 3Dfx driver.
1709
* Create a new XMesaBuffer from an X window.
1710
* Input: v - the XMesaVisual
1713
* Return: new XMesaBuffer or NULL if error
1715
XMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v, XMesaWindow w,
1718
#ifndef XFree86Server
1719
XWindowAttributes attr;
1726
XMesaBuffer b = alloc_xmesa_buffer();
1733
#ifdef XFree86Server
1734
client = CLIENT_ID(((XMesaDrawable)w)->id);
1739
#ifdef XFree86Server
1740
if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) {
1742
XGetWindowAttributes( v->display, w, &attr );
1744
if (GET_VISUAL_DEPTH(v) != attr.depth) {
1746
if (getenv("MESA_DEBUG")) {
1747
fprintf(stderr, "XMesaCreateWindowBuffer: depth mismatch between visual and window!\n");
1753
b->pixmap_flag = GL_FALSE;
1754
b->display = v->display;
1755
#ifdef XFree86Server
1756
b->cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
1758
if (attr.colormap) {
1759
b->cmap = attr.colormap;
1762
if (getenv("MESA_DEBUG")) {
1763
fprintf(stderr, "Window %u has no colormap!\n", (unsigned int) w);
1765
/* this is weird, a window w/out a colormap!? */
1766
/* OK, let's just allocate a new one and hope for the best */
1767
b->cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
1771
/* determine back buffer implementation */
1772
if (v->mesa_visual.doubleBufferMode) {
1773
if (v->ximage_flag) {
1774
b->db_state = BACK_XIMAGE;
1777
b->db_state = BACK_PIXMAP;
1784
_mesa_initialize_framebuffer(&b->mesa_buffer,
1786
v->mesa_visual.depthBits > 0,
1787
v->mesa_visual.stencilBits > 0,
1788
v->mesa_visual.accumRedBits > 0,
1789
v->mesa_visual.alphaBits > 0 );
1791
if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
1792
(XMesaDrawable)w, b->cmap )) {
1793
free_xmesa_buffer(client, b);
1798
fxEnvVar = getenv("MESA_GLX_FX");
1800
if (fxEnvVar[0]!='d') {
1804
if (v->mesa_visual.depthBits > 0) {
1805
attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
1806
attribs[numAttribs++] = 1;
1808
if (v->mesa_visual.doubleBufferMode) {
1809
attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
1811
if (v->mesa_visual.accumRedBits > 0) {
1812
attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
1813
attribs[numAttribs++] = v->mesa_visual.accumRedBits;
1815
if (v->mesa_visual.stencilBits > 0) {
1816
attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
1817
attribs[numAttribs++] = v->mesa_visual.stencilBits;
1819
if (v->mesa_visual.alphaBits > 0) {
1820
attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
1821
attribs[numAttribs++] = 1;
1824
#define FXMESA_SHARE_CONTEXT 990099 /* keep in sync with fxapi.c! */
1825
attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
1826
attribs[numAttribs++] = (int) c->gl_ctx;
1828
attribs[numAttribs++] = FXMESA_NONE;
1830
if ((hw = fxQueryHardware())==GR_SSTTYPE_VOODOO) {
1831
b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
1832
if ((v->undithered_pf!=PF_INDEX) && (b->backimage)) {
1833
b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
1834
if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
1835
b->FXwindowHack = b->FXctx ? GL_TRUE : GL_FALSE;
1837
b->FXwindowHack = GL_FALSE;
1841
if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
1842
b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
1843
GR_REFRESH_75Hz, attribs);
1845
b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
1846
b->FXisHackUsable = GL_FALSE;
1847
b->FXwindowHack = GL_FALSE;
1851
"voodoo %d, wid %d height %d hack: usable %d active %d\n",
1852
hw, b->width, b->height, b->FXisHackUsable, b->FXwindowHack);
1857
fprintf(stderr,"WARNING: This Mesa Library includes the Glide driver but\n");
1858
fprintf(stderr," you have not defined the MESA_GLX_FX env. var.\n");
1859
fprintf(stderr," (check the README.3DFX file for more information).\n\n");
1860
fprintf(stderr," you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
1868
XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, XMesaWindow w )
1870
return XMesaCreateWindowBuffer2( v, w, NULL );
1875
* Create a new XMesaBuffer from an X pixmap.
1876
* Input: v - the XMesaVisual
1878
* cmap - the colormap, may be 0 if using a TrueColor or DirectColor
1879
* visual for the pixmap
1880
* Return: new XMesaBuffer or NULL if error
1882
XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
1883
XMesaPixmap p, XMesaColormap cmap )
1886
XMesaBuffer b = alloc_xmesa_buffer();
1892
#ifdef XFree86Server
1893
client = CLIENT_ID(((XMesaDrawable)p)->id);
1899
b->pixmap_flag = GL_TRUE;
1900
b->display = v->display;
1903
/* determine back buffer implementation */
1904
if (v->mesa_visual.doubleBufferMode) {
1905
if (v->ximage_flag) {
1906
b->db_state = BACK_XIMAGE;
1909
b->db_state = BACK_PIXMAP;
1916
_mesa_initialize_framebuffer(&b->mesa_buffer,
1918
v->mesa_visual.depthBits > 0,
1919
v->mesa_visual.stencilBits > 0,
1920
v->mesa_visual.accumRedBits +
1921
v->mesa_visual.accumGreenBits +
1922
v->mesa_visual.accumBlueBits > 0,
1923
v->mesa_visual.alphaBits > 0 );
1925
if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
1926
(XMesaDrawable)p, cmap)) {
1927
free_xmesa_buffer(client, b);
1936
#if 0 /* not done */
1937
XMesaBuffer XMesaCreatePBuffer( XMesaVisual v, XMesaColormap cmap,
1938
unsigned int width, unsigned int height )
1941
XMesaBuffer b = alloc_xmesa_buffer();
1947
b->pbuffer_flag = GL_TRUE;
1948
b->display = v->display;
1951
/* determine back buffer implementation */
1952
if (v->mesa_visual.doubleBufferMode) {
1953
if (v->ximage_flag) {
1954
b->db_state = BACK_XIMAGE;
1957
b->db_state = BACK_PIXMAP;
1964
_mesa_initialize_framebuffer(&b->mesa_buffer,
1966
v->mesa_visual.depthBits > 0,
1967
v->mesa_visual.stencilBits > 0,
1968
v->mesa_visual.accumRedBits +
1969
v->mesa_visual.accumGreenBits +
1970
v->mesa_visual.accumBlueBits > 0,
1971
v->mesa_visual.alphaBits > 0 );
1973
if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
1975
free_xmesa_buffer(client, b);
1986
* Deallocate an XMesaBuffer structure and all related info.
1988
void XMesaDestroyBuffer( XMesaBuffer b )
1992
#ifdef XFree86Server
1994
client = CLIENT_ID(b->frontbuffer->id);
1997
if (b->gc) XMesaFreeGC( b->xm_visual->display, b->gc );
1998
if (b->cleargc) XMesaFreeGC( b->xm_visual->display, b->cleargc );
1999
if (b->swapgc) XMesaFreeGC( b->xm_visual->display, b->swapgc );
2002
#if defined(USE_XSHM) && !defined(XFree86Server)
2004
XShmDetach( b->xm_visual->display, &b->shminfo );
2005
XDestroyImage( b->backimage );
2006
shmdt( b->shminfo.shmaddr );
2010
XMesaDestroyImage( b->backimage );
2012
if (b->backpixmap) {
2013
XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
2014
if (b->xm_visual->hpcr_clear_flag) {
2015
XMesaFreePixmap( b->xm_visual->display,
2016
b->xm_visual->hpcr_clear_pixmap );
2017
XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage );
2021
FREE( b->rowimage->data );
2022
b->rowimage->data = NULL;
2023
XMesaDestroyImage( b->rowimage );
2026
free_xmesa_buffer(client, b);
2032
* Bind buffer b to context c and make c the current rendering context.
2034
GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b )
2036
return XMesaMakeCurrent2( c, b, b );
2041
* Bind buffer b to context c and make c the current rendering context.
2043
GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
2044
XMesaBuffer readBuffer )
2047
if (!drawBuffer || !readBuffer)
2048
return GL_FALSE; /* must specify buffers! */
2051
if (drawBuffer->FXctx) {
2052
fxMesaMakeCurrent(drawBuffer->FXctx);
2054
c->xm_buffer = drawBuffer;
2055
c->xm_read_buffer = readBuffer;
2056
c->use_read_buffer = (drawBuffer != readBuffer);
2061
if (c->gl_ctx == _mesa_get_current_context()
2062
&& c->xm_buffer == drawBuffer
2063
&& c->xm_read_buffer == readBuffer
2064
&& c->xm_buffer->wasCurrent) {
2065
/* same context and buffer, do nothing */
2069
c->xm_buffer = drawBuffer;
2070
c->xm_read_buffer = readBuffer;
2071
c->use_read_buffer = (drawBuffer != readBuffer);
2073
_mesa_make_current2(c->gl_ctx,
2074
&drawBuffer->mesa_buffer,
2075
&readBuffer->mesa_buffer);
2077
if (c->gl_ctx->Viewport.Width == 0) {
2078
/* initialize viewport to window size */
2079
_mesa_Viewport( 0, 0, drawBuffer->width, drawBuffer->height );
2080
c->gl_ctx->Scissor.Width = drawBuffer->width;
2081
c->gl_ctx->Scissor.Height = drawBuffer->height;
2084
if (c->xm_visual->mesa_visual.rgbMode) {
2086
* Must recompute and set these pixel values because colormap
2087
* can be different for different windows.
2089
c->clearpixel = xmesa_color_to_pixel( c,
2094
c->xm_visual->undithered_pf);
2095
XMesaSetForeground(c->display, c->xm_buffer->cleargc, c->clearpixel);
2098
/* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
2099
c->xm_buffer->wasCurrent = GL_TRUE;
2103
_mesa_make_current2( NULL, NULL, NULL );
2110
* Unbind the context c from its buffer.
2112
GLboolean XMesaUnbindContext( XMesaContext c )
2114
/* A no-op for XFree86 integration purposes */
2119
XMesaContext XMesaGetCurrentContext( void )
2121
GET_CURRENT_CONTEXT(ctx);
2123
XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
2132
XMesaBuffer XMesaGetCurrentBuffer( void )
2134
GET_CURRENT_CONTEXT(ctx);
2136
XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
2137
return xmesa->xm_buffer;
2145
/* New in Mesa 3.1 */
2146
XMesaBuffer XMesaGetCurrentReadBuffer( void )
2148
GET_CURRENT_CONTEXT(ctx);
2150
XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
2151
return xmesa->xm_buffer;
2159
GLboolean XMesaForceCurrent(XMesaContext c)
2162
if (c->gl_ctx != _mesa_get_current_context()) {
2163
_mesa_make_current(c->gl_ctx, &c->xm_buffer->mesa_buffer);
2167
_mesa_make_current(NULL, NULL);
2173
GLboolean XMesaLoseCurrent(XMesaContext c)
2176
_mesa_make_current(NULL, NULL);
2182
* Switch 3Dfx support hack between window and full-screen mode.
2184
GLboolean XMesaSetFXmode( GLint mode )
2187
const char *fx = getenv("MESA_GLX_FX");
2188
if (fx && fx[0] != 'd') {
2189
GET_CURRENT_CONTEXT(ctx);
2190
GrHwConfiguration hw;
2191
if (!FX_grSstQueryHardware(&hw)) {
2192
/*fprintf(stderr, "!grSstQueryHardware\n");*/
2195
if (hw.num_sst < 1) {
2196
/*fprintf(stderr, "hw.num_sst < 1\n");*/
2200
XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
2201
if (mode == XMESA_FX_WINDOW) {
2202
if (xmesa->xm_buffer->FXisHackUsable) {
2203
FX_grSstControl(GR_CONTROL_DEACTIVATE);
2204
xmesa->xm_buffer->FXwindowHack = GL_TRUE;
2208
else if (mode == XMESA_FX_FULLSCREEN) {
2209
FX_grSstControl(GR_CONTROL_ACTIVATE);
2210
xmesa->xm_buffer->FXwindowHack = GL_FALSE;
2214
/* Error: Bad mode value */
2218
/*fprintf(stderr, "fallthrough\n");*/
2229
* Read image from VooDoo frame buffer into X/Mesa's back XImage.
2231
static void FXgetImage( XMesaBuffer b )
2233
GET_CURRENT_CONTEXT(ctx);
2234
static unsigned short pixbuf[MAX_WIDTH];
2238
unsigned int bw, depth, width, height;
2239
XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
2241
#ifdef XFree86Server
2242
x = b->frontbuffer->x;
2243
y = b->frontbuffer->y;
2244
width = b->frontbuffer->width;
2245
height = b->frontbuffer->height;
2246
depth = b->frontbuffer->depth;
2248
XGetGeometry( b->xm_visual->display, b->frontbuffer,
2249
&root, &xpos, &ypos, &width, &height, &bw, &depth);
2251
if (b->width != width || b->height != height) {
2252
b->width = MIN2((int)width, b->FXctx->width);
2253
b->height = MIN2((int)height, b->FXctx->height);
2255
b->width--; /* prevent odd width */
2256
xmesa_alloc_back_buffer( b );
2259
grLfbWriteColorFormat(GR_COLORFORMAT_ARGB);
2260
if (b->xm_visual->undithered_pf==PF_5R6G5B) {
2261
/* Special case: 16bpp RGB */
2262
grLfbReadRegion( GR_BUFFER_FRONTBUFFER, /* src buffer */
2263
0, b->FXctx->height - b->height, /*pos*/
2264
b->width, b->height, /* size */
2265
b->width * sizeof(GLushort), /* stride */
2266
b->backimage->data); /* dest buffer */
2268
else if (b->xm_visual->dithered_pf==PF_DITHER
2269
&& GET_VISUAL_DEPTH(b->xm_visual)==8) {
2270
/* Special case: 8bpp RGB */
2271
for (y=0;y<b->height;y++) {
2272
GLubyte *ptr = (GLubyte*) b->backimage->data
2273
+ b->backimage->bytes_per_line * y;
2276
/* read row from 3Dfx frame buffer */
2277
grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
2278
0, b->FXctx->height-(b->height-y),
2283
/* write to XImage back buffer */
2284
for (x=0;x<b->width;x++) {
2285
GLubyte r = (pixbuf[x] & 0xf800) >> 8;
2286
GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
2287
GLubyte b = (pixbuf[x] & 0x001f) << 3;
2288
*ptr++ = XDITHER( x, r, g, b);
2293
/* General case: slow! */
2294
for (y=0;y<b->height;y++) {
2295
/* read row from 3Dfx frame buffer */
2296
grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
2297
0, b->FXctx->height-(b->height-y),
2302
/* write to XImage back buffer */
2303
for (x=0;x<b->width;x++) {
2304
XMesaPutPixel(b->backimage,x,y,
2305
xmesa_color_to_pixel(xmesa,
2306
(pixbuf[x] & 0xf800) >> 8,
2307
(pixbuf[x] & 0x07e0) >> 3,
2308
(pixbuf[x] & 0x001f) << 3,
2310
b->xm_visual->undithered_pf));
2314
grLfbWriteColorFormat(GR_COLORFORMAT_ABGR);
2320
* Copy the back buffer to the front buffer. If there's no back buffer
2323
void XMesaSwapBuffers( XMesaBuffer b )
2325
GET_CURRENT_CONTEXT(ctx);
2327
/* If we're swapping the buffer associated with the current context
2328
* we have to flush any pending rendering commands first.
2330
if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
2331
_mesa_swapbuffers(ctx);
2336
fxMesaSwapBuffers();
2338
if (b->FXwindowHack)
2345
/* Copy Ximage from host's memory to server's window */
2346
#if defined(USE_XSHM) && !defined(XFree86Server)
2348
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2349
XShmPutImage( b->xm_visual->display, b->frontbuffer,
2352
0, 0, b->width, b->height, False );
2353
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2358
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2359
XMesaPutImage( b->xm_visual->display, b->frontbuffer,
2362
0, 0, b->width, b->height );
2363
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2367
/* Copy pixmap to window on server */
2368
/*_glthread_LOCK_MUTEX(_xmesa_lock);*/
2369
XMesaCopyArea( b->xm_visual->display,
2370
b->backpixmap, /* source drawable */
2371
b->frontbuffer, /* dest. drawable */
2373
0, 0, b->width, b->height, /* source region */
2374
0, 0 /* dest region */
2376
/*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
2379
#if !defined(XFree86Server)
2380
XSync( b->xm_visual->display, False );
2387
* Copy sub-region of back buffer to front buffer
2389
void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
2391
GET_CURRENT_CONTEXT(ctx);
2393
/* If we're swapping the buffer associated with the current context
2394
* we have to flush any pending rendering commands first.
2396
if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
2397
_mesa_swapbuffers(ctx);
2400
int yTop = b->height - y - height;
2403
fxMesaSwapBuffers();
2404
if (b->FXwindowHack)
2411
/* Copy Ximage from host's memory to server's window */
2412
#if defined(USE_XSHM) && !defined(XFree86Server)
2414
/* XXX assuming width and height aren't too large! */
2415
XShmPutImage( b->xm_visual->display, b->frontbuffer,
2417
b->backimage, x, yTop,
2418
x, yTop, width, height, False );
2419
/* wait for finished event??? */
2424
/* XXX assuming width and height aren't too large! */
2425
XMesaPutImage( b->xm_visual->display, b->frontbuffer,
2427
b->backimage, x, yTop,
2428
x, yTop, width, height );
2432
/* Copy pixmap to window on server */
2433
XMesaCopyArea( b->xm_visual->display,
2434
b->backpixmap, /* source drawable */
2435
b->frontbuffer, /* dest. drawable */
2437
x, yTop, width, height, /* source region */
2438
x, yTop /* dest region */
2446
* Return a pointer to the XMesa backbuffer Pixmap or XImage. This function
2447
* is a way to get "under the hood" of X/Mesa so one can manipulate the
2448
* back buffer directly.
2449
* Output: pixmap - pointer to back buffer's Pixmap, or 0
2450
* ximage - pointer to back buffer's XImage, or NULL
2451
* Return: GL_TRUE = context is double buffered
2452
* GL_FALSE = context is single buffered
2454
GLboolean XMesaGetBackBuffer( XMesaBuffer b,
2455
XMesaPixmap *pixmap,
2456
XMesaImage **ximage )
2459
if (pixmap) *pixmap = b->backpixmap;
2460
if (ximage) *ximage = b->backimage;
2472
* Return the depth buffer associated with an XMesaBuffer.
2473
* Input: b - the XMesa buffer handle
2474
* Output: width, height - size of buffer in pixels
2475
* bytesPerValue - bytes per depth value (2 or 4)
2476
* buffer - pointer to depth buffer values
2477
* Return: GL_TRUE or GL_FALSE to indicate success or failure.
2479
GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
2480
GLint *bytesPerValue, void **buffer )
2482
if (!b->mesa_buffer.DepthBuffer) {
2490
*width = b->mesa_buffer.Width;
2491
*height = b->mesa_buffer.Height;
2492
*bytesPerValue = sizeof(GLdepth);
2493
*buffer = b->mesa_buffer.DepthBuffer;
2499
void XMesaFlush( XMesaContext c )
2501
if (c && c->xm_visual) {
2502
#ifdef XFree86Server
2505
XSync( c->xm_visual->display, False );
2512
const char *XMesaGetString( XMesaContext c, int name )
2515
if (name==XMESA_VERSION) {
2518
else if (name==XMESA_EXTENSIONS) {
2528
XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d )
2531
for (b=XMesaBufferList; b; b=b->Next) {
2532
if (b->frontbuffer==d && b->display==dpy) {
2542
* Look for XMesaBuffers whose X window has been destroyed.
2543
* Deallocate any such XMesaBuffers.
2545
void XMesaGarbageCollect( void )
2547
XMesaBuffer b, next;
2548
for (b=XMesaBufferList; b; b=next) {
2550
if (b->display && b->frontbuffer && !b->pixmap_flag) {
2551
#ifdef XFree86Server
2554
XSync(b->display, False);
2555
if (!window_exists( b->display, b->frontbuffer )) {
2556
/* found a dead window, free the ancillary info */
2557
XMesaDestroyBuffer( b );
2565
void XMesaReset( void )
2567
while (XMesaBufferList)
2568
XMesaDestroyBuffer(XMesaBufferList);
2570
XMesaBufferList = NULL;
2574
unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
2575
GLfloat red, GLfloat green,
2576
GLfloat blue, GLfloat alpha )
2578
GLint r = (GLint) (red * 255.0F);
2579
GLint g = (GLint) (green * 255.0F);
2580
GLint b = (GLint) (blue * 255.0F);
2581
GLint a = (GLint) (alpha * 255.0F);
2583
switch (xmesa->pixelformat) {
2589
PACK_TRUECOLOR( p, r, g, b );
2593
return PACK_8A8B8G8R( r, g, b, a );
2595
return PACK_8R8G8B( r, g, b );
2597
return PACK_5R6G5B( r, g, b );
2601
return DITHER( x, y, r, g, b );
2604
/* 382 = (3*255)/2 */
2605
return ((r+g+b) > 382) ^ xmesa->xm_visual->bitFlip;
2607
return DITHER_HPCR(x, y, r, g, b);
2611
return LOOKUP( r, g, b );
2614
return GRAY_RGB( r, g, b );
2615
case PF_DITHER_5R6G5B:
2620
PACK_TRUEDITHER(p, x, y, r, g, b);
2624
_mesa_problem(NULL, "Bad pixel format in XMesaDitherColor");
2631
* This is typically called when the window size changes and we need
2632
* to reallocate the buffer's back/depth/stencil/accum buffers.
2634
void XMesaResizeBuffers( XMesaBuffer b )
2636
xmesa_resize_buffers( &(b->mesa_buffer) );