fix some 0->NULLs
[mesa.git] / src / mesa / drivers / dri / common / glcontextmodes.c
1 /*
2 * (C) Copyright IBM Corporation 2003
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file glcontextmodes.c
27 * Utility routines for working with \c __GLcontextModes structures. At
28 * some point most or all of these functions will be moved to the Mesa
29 * code base.
30 *
31 * \author Ian Romanick <idr@us.ibm.com>
32 */
33
34 #ifdef DRI_NEW_INTERFACE_ONLY
35 # include <stdlib.h>
36 # include <string.h>
37 # include <GL/gl.h>
38 # include "dri_interface.h"
39 # include "imports.h"
40 # define __glXMemset memset
41 #else
42 # include <X11/X.h>
43 # include <GL/glx.h>
44 # include "GL/glxint.h"
45
46 # ifdef XFree86Server
47 # include "GL/glx_ansic.h"
48 extern void * __glXMalloc( size_t size );
49 extern void __glXFree( void * ptr );
50 # define _mesa_malloc(b) __glXMalloc(b)
51 # define _mesa_free(m) __glXFree(m)
52 # else
53 # include <X11/Xlibint.h>
54 # define __glXMemset memset
55 # define _mesa_malloc(b) Xmalloc(b)
56 # define _mesa_free(m) Xfree(m)
57 # endif /* XFree86Server */
58 #endif /* DRI_NEW_INTERFACE_ONLY */
59
60 #include "glcontextmodes.h"
61
62 #ifndef DRI_NEW_INTERFACE_ONLY
63 #define NUM_VISUAL_TYPES 6
64
65 /**
66 * Convert an X visual type to a GLX visual type.
67 *
68 * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.)
69 * to be converted.
70 * \return If \c visualType is a valid X visual type, a GLX visual type will
71 * be returned. Otherwise \c GLX_NONE will be returned.
72 */
73 GLint
74 _gl_convert_from_x_visual_type( int visualType )
75 {
76 static const int glx_visual_types[ NUM_VISUAL_TYPES ] = {
77 GLX_STATIC_GRAY, GLX_GRAY_SCALE,
78 GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
79 GLX_TRUE_COLOR, GLX_DIRECT_COLOR
80 };
81
82 return ( (unsigned) visualType < NUM_VISUAL_TYPES )
83 ? glx_visual_types[ visualType ] : GLX_NONE;
84 }
85
86
87 /**
88 * Convert a GLX visual type to an X visual type.
89 *
90 * \param visualType GLX visual type (i.e., \c GLX_TRUE_COLOR,
91 * \c GLX_STATIC_GRAY, etc.) to be converted.
92 * \return If \c visualType is a valid GLX visual type, an X visual type will
93 * be returned. Otherwise -1 will be returned.
94 */
95 GLint
96 _gl_convert_to_x_visual_type( int visualType )
97 {
98 static const int x_visual_types[ NUM_VISUAL_TYPES ] = {
99 TrueColor, DirectColor,
100 PseudoColor, StaticColor,
101 GrayScale, StaticGray
102 };
103
104 return ( (unsigned) (visualType - GLX_TRUE_COLOR) <= NUM_VISUAL_TYPES )
105 ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1;
106 }
107
108
109 /**
110 * Copy a GLX visual config structure to a GL context mode structure. All
111 * of the fields in \c config are copied to \c mode. Additional fields in
112 * \c mode that can be derrived from the fields of \c config (i.e.,
113 * \c haveDepthBuffer) are also filled in. The remaining fields in \c mode
114 * that cannot be derrived are set to default values.
115 *
116 * \param mode Destination GL context mode.
117 * \param config Source GLX visual config.
118 *
119 * \note
120 * The \c fbconfigID and \c visualID fields of the \c __GLcontextModes
121 * structure will be set to the \c vid of the \c __GLXvisualConfig structure.
122 */
123 void
124 _gl_copy_visual_to_context_mode( __GLcontextModes * mode,
125 const __GLXvisualConfig * config )
126 {
127 __GLcontextModes * const next = mode->next;
128
129 (void) __glXMemset( mode, 0, sizeof( __GLcontextModes ) );
130 mode->next = next;
131
132 mode->visualID = config->vid;
133 mode->visualType = _gl_convert_from_x_visual_type( config->class );
134 mode->xRenderable = GL_TRUE;
135 mode->fbconfigID = config->vid;
136 mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
137
138 mode->rgbMode = (config->rgba != 0);
139 mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
140
141 mode->colorIndexMode = !(mode->rgbMode);
142 mode->doubleBufferMode = (config->doubleBuffer != 0);
143 mode->stereoMode = (config->stereo != 0);
144
145 mode->haveAccumBuffer = ((config->accumRedSize +
146 config->accumGreenSize +
147 config->accumBlueSize +
148 config->accumAlphaSize) > 0);
149 mode->haveDepthBuffer = (config->depthSize > 0);
150 mode->haveStencilBuffer = (config->stencilSize > 0);
151
152 mode->redBits = config->redSize;
153 mode->greenBits = config->greenSize;
154 mode->blueBits = config->blueSize;
155 mode->alphaBits = config->alphaSize;
156 mode->redMask = config->redMask;
157 mode->greenMask = config->greenMask;
158 mode->blueMask = config->blueMask;
159 mode->alphaMask = config->alphaMask;
160 mode->rgbBits = config->bufferSize;
161 mode->indexBits = config->bufferSize;
162
163 mode->accumRedBits = config->accumRedSize;
164 mode->accumGreenBits = config->accumGreenSize;
165 mode->accumBlueBits = config->accumBlueSize;
166 mode->accumAlphaBits = config->accumAlphaSize;
167 mode->depthBits = config->depthSize;
168 mode->stencilBits = config->stencilSize;
169
170 mode->numAuxBuffers = config->auxBuffers;
171 mode->level = config->level;
172
173 mode->visualRating = config->visualRating;
174 mode->transparentPixel = config->transparentPixel;
175 mode->transparentRed = config->transparentRed;
176 mode->transparentGreen = config->transparentGreen;
177 mode->transparentBlue = config->transparentBlue;
178 mode->transparentAlpha = config->transparentAlpha;
179 mode->transparentIndex = config->transparentIndex;
180
181 mode->swapMethod = GLX_SWAP_UNDEFINED_OML;
182 }
183
184
185 /**
186 * Get data from a GL context mode.
187 *
188 * \param mode GL context mode whose data is to be returned.
189 * \param attribute Attribute of \c mode that is to be returned.
190 * \param value_return Location to store the data member of \c mode.
191 * \return If \c attribute is a valid attribute of \c mode, zero is
192 * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned.
193 */
194 int
195 _gl_get_context_mode_data(const __GLcontextModes *mode, int attribute,
196 int *value_return)
197 {
198 switch (attribute) {
199 case GLX_USE_GL:
200 *value_return = GL_TRUE;
201 return 0;
202 case GLX_BUFFER_SIZE:
203 *value_return = mode->rgbBits;
204 return 0;
205 case GLX_RGBA:
206 *value_return = mode->rgbMode;
207 return 0;
208 case GLX_RED_SIZE:
209 *value_return = mode->redBits;
210 return 0;
211 case GLX_GREEN_SIZE:
212 *value_return = mode->greenBits;
213 return 0;
214 case GLX_BLUE_SIZE:
215 *value_return = mode->blueBits;
216 return 0;
217 case GLX_ALPHA_SIZE:
218 *value_return = mode->alphaBits;
219 return 0;
220 case GLX_DOUBLEBUFFER:
221 *value_return = mode->doubleBufferMode;
222 return 0;
223 case GLX_STEREO:
224 *value_return = mode->stereoMode;
225 return 0;
226 case GLX_AUX_BUFFERS:
227 *value_return = mode->numAuxBuffers;
228 return 0;
229 case GLX_DEPTH_SIZE:
230 *value_return = mode->depthBits;
231 return 0;
232 case GLX_STENCIL_SIZE:
233 *value_return = mode->stencilBits;
234 return 0;
235 case GLX_ACCUM_RED_SIZE:
236 *value_return = mode->accumRedBits;
237 return 0;
238 case GLX_ACCUM_GREEN_SIZE:
239 *value_return = mode->accumGreenBits;
240 return 0;
241 case GLX_ACCUM_BLUE_SIZE:
242 *value_return = mode->accumBlueBits;
243 return 0;
244 case GLX_ACCUM_ALPHA_SIZE:
245 *value_return = mode->accumAlphaBits;
246 return 0;
247 case GLX_LEVEL:
248 *value_return = mode->level;
249 return 0;
250 case GLX_TRANSPARENT_TYPE_EXT:
251 *value_return = mode->transparentPixel;
252 return 0;
253 case GLX_TRANSPARENT_RED_VALUE:
254 *value_return = mode->transparentRed;
255 return 0;
256 case GLX_TRANSPARENT_GREEN_VALUE:
257 *value_return = mode->transparentGreen;
258 return 0;
259 case GLX_TRANSPARENT_BLUE_VALUE:
260 *value_return = mode->transparentBlue;
261 return 0;
262 case GLX_TRANSPARENT_ALPHA_VALUE:
263 *value_return = mode->transparentAlpha;
264 return 0;
265 case GLX_TRANSPARENT_INDEX_VALUE:
266 *value_return = mode->transparentIndex;
267 return 0;
268 case GLX_X_VISUAL_TYPE:
269 *value_return = mode->visualType;
270 return 0;
271 case GLX_CONFIG_CAVEAT:
272 *value_return = mode->visualRating;
273 return 0;
274 case GLX_VISUAL_ID:
275 *value_return = mode->visualID;
276 return 0;
277 case GLX_DRAWABLE_TYPE:
278 *value_return = mode->drawableType;
279 return 0;
280 case GLX_RENDER_TYPE:
281 *value_return = mode->renderType;
282 return 0;
283 case GLX_X_RENDERABLE:
284 *value_return = mode->xRenderable;
285 return 0;
286 case GLX_FBCONFIG_ID:
287 *value_return = mode->fbconfigID;
288 return 0;
289 case GLX_MAX_PBUFFER_WIDTH:
290 *value_return = mode->maxPbufferWidth;
291 return 0;
292 case GLX_MAX_PBUFFER_HEIGHT:
293 *value_return = mode->maxPbufferHeight;
294 return 0;
295 case GLX_MAX_PBUFFER_PIXELS:
296 *value_return = mode->maxPbufferPixels;
297 return 0;
298 case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
299 *value_return = mode->optimalPbufferWidth;
300 return 0;
301 case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
302 *value_return = mode->optimalPbufferHeight;
303 return 0;
304 case GLX_SWAP_METHOD_OML:
305 *value_return = mode->swapMethod;
306 return 0;
307 case GLX_SAMPLE_BUFFERS_SGIS:
308 *value_return = mode->sampleBuffers;
309 return 0;
310 case GLX_SAMPLES_SGIS:
311 *value_return = mode->samples;
312 return 0;
313
314 /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX.
315 * It is ONLY for communication between the GLX client and the GLX
316 * server.
317 */
318 case GLX_VISUAL_SELECT_GROUP_SGIX:
319 default:
320 return GLX_BAD_ATTRIBUTE;
321 }
322 }
323 #endif /* DRI_NEW_INTERFACE_ONLY */
324
325
326 /**
327 * Allocate a linked list of \c __GLcontextModes structures. The fields of
328 * each structure will be initialized to "reasonable" default values. In
329 * most cases this is the default value defined by table 3.4 of the GLX
330 * 1.3 specification. This means that most values are either initialized to
331 * zero or \c GLX_DONT_CARE (which is -1). As support for additional
332 * extensions is added, the new values will be initialized to appropriate
333 * values from the extension specification.
334 *
335 * \param count Number of structures to allocate.
336 * \param minimum_size Minimum size of a structure to allocate. This allows
337 * for differences in the version of the
338 * \c __GLcontextModes stucture used in libGL and in a
339 * DRI-based driver.
340 * \returns A pointer to the first element in a linked list of \c count
341 * stuctures on success, or \c NULL on failure.
342 *
343 * \warning Use of \c minimum_size does \b not guarantee binary compatibility.
344 * The fundamental assumption is that if the \c minimum_size
345 * specified by the driver and the size of the \c __GLcontextModes
346 * structure in libGL is the same, then the meaning of each byte in
347 * the structure is the same in both places. \b Be \b careful!
348 * Basically this means that fields have to be added in libGL and
349 * then propagated to drivers. Drivers should \b never arbitrarilly
350 * extend the \c __GLcontextModes data-structure.
351 */
352 __GLcontextModes *
353 _gl_context_modes_create( unsigned count, size_t minimum_size )
354 {
355 const size_t size = (minimum_size > sizeof( __GLcontextModes ))
356 ? minimum_size : sizeof( __GLcontextModes );
357 __GLcontextModes * base = NULL;
358 __GLcontextModes ** next;
359 unsigned i;
360
361 next = & base;
362 for ( i = 0 ; i < count ; i++ ) {
363 *next = (__GLcontextModes *) _mesa_malloc( size );
364 if ( *next == NULL ) {
365 _gl_context_modes_destroy( base );
366 base = NULL;
367 break;
368 }
369
370 (void) __glXMemset( *next, 0, size );
371 (*next)->visualID = GLX_DONT_CARE;
372 (*next)->visualType = GLX_DONT_CARE;
373 (*next)->visualRating = GLX_NONE;
374 (*next)->transparentPixel = GLX_NONE;
375 (*next)->transparentRed = GLX_DONT_CARE;
376 (*next)->transparentGreen = GLX_DONT_CARE;
377 (*next)->transparentBlue = GLX_DONT_CARE;
378 (*next)->transparentAlpha = GLX_DONT_CARE;
379 (*next)->transparentIndex = GLX_DONT_CARE;
380 (*next)->xRenderable = GLX_DONT_CARE;
381 (*next)->fbconfigID = GLX_DONT_CARE;
382 (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
383
384 next = & ((*next)->next);
385 }
386
387 return base;
388 }
389
390
391 /**
392 * Destroy a linked list of \c __GLcontextModes structures created by
393 * \c _gl_context_modes_create.
394 *
395 * \param modes Linked list of structures to be destroyed. All structres
396 * in the list will be freed.
397 */
398 void
399 _gl_context_modes_destroy( __GLcontextModes * modes )
400 {
401 while ( modes != NULL ) {
402 __GLcontextModes * const next = modes->next;
403
404 _mesa_free( modes );
405 modes = next;
406 }
407 }
408
409
410 /**
411 * Find a context mode matching a Visual ID.
412 *
413 * \param modes List list of context-mode structures to be searched.
414 * \param vid Visual ID to be found.
415 * \returns A pointer to a context-mode in \c modes if \c vid was found in
416 * the list, or \c NULL if it was not.
417 */
418
419 __GLcontextModes *
420 _gl_context_modes_find_visual( __GLcontextModes * modes, int vid )
421 {
422 while ( modes != NULL ) {
423 if ( modes->visualID == vid ) {
424 break;
425 }
426
427 modes = modes->next;
428 }
429
430 return modes;
431 }
432
433
434 /**
435 * Determine if two context-modes are the same. This is intended to be used
436 * by libGL implementations to compare to sets of driver generated FBconfigs.
437 *
438 * \param a Context-mode to be compared.
439 * \param b Context-mode to be compared.
440 * \returns \c GL_TRUE if the two context-modes are the same. \c GL_FALSE is
441 * returned otherwise.
442 */
443 GLboolean
444 _gl_context_modes_are_same( const __GLcontextModes * a,
445 const __GLcontextModes * b )
446 {
447 return( (a->rgbMode == b->rgbMode) &&
448 (a->floatMode == b->floatMode) &&
449 (a->colorIndexMode == b->colorIndexMode) &&
450 (a->doubleBufferMode == b->doubleBufferMode) &&
451 (a->stereoMode == b->stereoMode) &&
452 (a->redBits == b->redBits) &&
453 (a->greenBits == b->greenBits) &&
454 (a->blueBits == b->blueBits) &&
455 (a->alphaBits == b->alphaBits) &&
456 #if 0 /* For some reason these don't get set on the client-side in libGL. */
457 (a->redMask == b->redMask) &&
458 (a->greenMask == b->greenMask) &&
459 (a->blueMask == b->blueMask) &&
460 (a->alphaMask == b->alphaMask) &&
461 #endif
462 (a->rgbBits == b->rgbBits) &&
463 (a->indexBits == b->indexBits) &&
464 (a->accumRedBits == b->accumRedBits) &&
465 (a->accumGreenBits == b->accumGreenBits) &&
466 (a->accumBlueBits == b->accumBlueBits) &&
467 (a->accumAlphaBits == b->accumAlphaBits) &&
468 (a->depthBits == b->depthBits) &&
469 (a->stencilBits == b->stencilBits) &&
470 (a->numAuxBuffers == b->numAuxBuffers) &&
471 (a->level == b->level) &&
472 (a->pixmapMode == b->pixmapMode) &&
473 (a->visualRating == b->visualRating) &&
474
475 (a->transparentPixel == b->transparentPixel) &&
476
477 ((a->transparentPixel != GLX_TRANSPARENT_RGB) ||
478 ((a->transparentRed == b->transparentRed) &&
479 (a->transparentGreen == b->transparentGreen) &&
480 (a->transparentBlue == b->transparentBlue) &&
481 (a->transparentAlpha == b->transparentAlpha))) &&
482
483 ((a->transparentPixel != GLX_TRANSPARENT_INDEX) ||
484 (a->transparentIndex == b->transparentIndex)) &&
485
486 (a->sampleBuffers == b->sampleBuffers) &&
487 (a->samples == b->samples) &&
488 ((a->drawableType & b->drawableType) != 0) &&
489 (a->renderType == b->renderType) &&
490 (a->maxPbufferWidth == b->maxPbufferWidth) &&
491 (a->maxPbufferHeight == b->maxPbufferHeight) &&
492 (a->maxPbufferPixels == b->maxPbufferPixels) &&
493 (a->optimalPbufferWidth == b->optimalPbufferWidth) &&
494 (a->optimalPbufferHeight == b->optimalPbufferHeight) &&
495 (a->swapMethod == b->swapMethod) );
496 }