1848b8605Smrg/* 2848b8605Smrg * (C) Copyright IBM Corporation 2003 3848b8605Smrg * All Rights Reserved. 4848b8605Smrg * 5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6848b8605Smrg * copy of this software and associated documentation files (the "Software"), 7848b8605Smrg * to deal in the Software without restriction, including without limitation 8848b8605Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 9848b8605Smrg * license, and/or sell copies of the Software, and to permit persons to whom 10848b8605Smrg * the Software is furnished to do so, subject to the following conditions: 11848b8605Smrg * 12848b8605Smrg * The above copyright notice and this permission notice (including the next 13848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 14848b8605Smrg * Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20848b8605Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21848b8605Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22848b8605Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg/** 26848b8605Smrg * \file glxconfig.c 27848b8605Smrg * Utility routines for working with \c struct glx_config structures. At 28848b8605Smrg * some point most or all of these functions will be moved to the Mesa 29848b8605Smrg * code base. 30848b8605Smrg * 31848b8605Smrg * \author Ian Romanick <idr@us.ibm.com> 32848b8605Smrg */ 33848b8605Smrg 34848b8605Smrg#include <GL/glx.h> 35848b8605Smrg#include <stdlib.h> 36848b8605Smrg#include <string.h> 37848b8605Smrg 38848b8605Smrg#include "glxconfig.h" 39848b8605Smrg 40848b8605Smrg#define NUM_VISUAL_TYPES 6 41848b8605Smrg 42848b8605Smrg/** 43848b8605Smrg * Get data from a GLX config 44848b8605Smrg * 45848b8605Smrg * \param mode GL context mode whose data is to be returned. 46848b8605Smrg * \param attribute Attribute of \c mode that is to be returned. 47848b8605Smrg * \param value_return Location to store the data member of \c mode. 48848b8605Smrg * \return If \c attribute is a valid attribute of \c mode, zero is 49848b8605Smrg * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned. 50848b8605Smrg */ 51848b8605Smrg_X_HIDDEN int 52848b8605Smrgglx_config_get(struct glx_config * mode, int attribute, int *value_return) 53848b8605Smrg{ 54848b8605Smrg switch (attribute) { 55848b8605Smrg case GLX_USE_GL: 56848b8605Smrg *value_return = GL_TRUE; 57848b8605Smrg return 0; 58848b8605Smrg case GLX_BUFFER_SIZE: 59848b8605Smrg *value_return = mode->rgbBits; 60848b8605Smrg return 0; 61848b8605Smrg case GLX_RGBA: 62848b8605Smrg *value_return = mode->rgbMode; 63848b8605Smrg return 0; 64848b8605Smrg case GLX_RED_SIZE: 65848b8605Smrg *value_return = mode->redBits; 66848b8605Smrg return 0; 67848b8605Smrg case GLX_GREEN_SIZE: 68848b8605Smrg *value_return = mode->greenBits; 69848b8605Smrg return 0; 70848b8605Smrg case GLX_BLUE_SIZE: 71848b8605Smrg *value_return = mode->blueBits; 72848b8605Smrg return 0; 73848b8605Smrg case GLX_ALPHA_SIZE: 74848b8605Smrg *value_return = mode->alphaBits; 75848b8605Smrg return 0; 76848b8605Smrg case GLX_DOUBLEBUFFER: 77848b8605Smrg *value_return = mode->doubleBufferMode; 78848b8605Smrg return 0; 79848b8605Smrg case GLX_STEREO: 80848b8605Smrg *value_return = mode->stereoMode; 81848b8605Smrg return 0; 82848b8605Smrg case GLX_AUX_BUFFERS: 83848b8605Smrg *value_return = mode->numAuxBuffers; 84848b8605Smrg return 0; 85848b8605Smrg case GLX_DEPTH_SIZE: 86848b8605Smrg *value_return = mode->depthBits; 87848b8605Smrg return 0; 88848b8605Smrg case GLX_STENCIL_SIZE: 89848b8605Smrg *value_return = mode->stencilBits; 90848b8605Smrg return 0; 91848b8605Smrg case GLX_ACCUM_RED_SIZE: 92848b8605Smrg *value_return = mode->accumRedBits; 93848b8605Smrg return 0; 94848b8605Smrg case GLX_ACCUM_GREEN_SIZE: 95848b8605Smrg *value_return = mode->accumGreenBits; 96848b8605Smrg return 0; 97848b8605Smrg case GLX_ACCUM_BLUE_SIZE: 98848b8605Smrg *value_return = mode->accumBlueBits; 99848b8605Smrg return 0; 100848b8605Smrg case GLX_ACCUM_ALPHA_SIZE: 101848b8605Smrg *value_return = mode->accumAlphaBits; 102848b8605Smrg return 0; 103848b8605Smrg case GLX_LEVEL: 104848b8605Smrg *value_return = mode->level; 105848b8605Smrg return 0; 106848b8605Smrg#ifndef GLX_USE_APPLEGL /* This isn't supported by CGL. */ 107848b8605Smrg case GLX_TRANSPARENT_TYPE_EXT: 108848b8605Smrg *value_return = mode->transparentPixel; 109848b8605Smrg return 0; 110848b8605Smrg#endif 111848b8605Smrg case GLX_TRANSPARENT_RED_VALUE: 112848b8605Smrg *value_return = mode->transparentRed; 113848b8605Smrg return 0; 114848b8605Smrg case GLX_TRANSPARENT_GREEN_VALUE: 115848b8605Smrg *value_return = mode->transparentGreen; 116848b8605Smrg return 0; 117848b8605Smrg case GLX_TRANSPARENT_BLUE_VALUE: 118848b8605Smrg *value_return = mode->transparentBlue; 119848b8605Smrg return 0; 120848b8605Smrg case GLX_TRANSPARENT_ALPHA_VALUE: 121848b8605Smrg *value_return = mode->transparentAlpha; 122848b8605Smrg return 0; 123848b8605Smrg case GLX_TRANSPARENT_INDEX_VALUE: 124848b8605Smrg *value_return = mode->transparentIndex; 125848b8605Smrg return 0; 126848b8605Smrg case GLX_X_VISUAL_TYPE: 127848b8605Smrg *value_return = mode->visualType; 128848b8605Smrg return 0; 129848b8605Smrg case GLX_CONFIG_CAVEAT: 130848b8605Smrg *value_return = mode->visualRating; 131848b8605Smrg return 0; 132848b8605Smrg case GLX_VISUAL_ID: 133848b8605Smrg *value_return = mode->visualID; 134848b8605Smrg return 0; 135848b8605Smrg case GLX_DRAWABLE_TYPE: 136848b8605Smrg *value_return = mode->drawableType; 137848b8605Smrg return 0; 138848b8605Smrg case GLX_RENDER_TYPE: 139848b8605Smrg *value_return = mode->renderType; 140848b8605Smrg return 0; 141848b8605Smrg case GLX_X_RENDERABLE: 142848b8605Smrg *value_return = mode->xRenderable; 143848b8605Smrg return 0; 144848b8605Smrg case GLX_FBCONFIG_ID: 145848b8605Smrg *value_return = mode->fbconfigID; 146848b8605Smrg return 0; 147848b8605Smrg case GLX_MAX_PBUFFER_WIDTH: 148848b8605Smrg *value_return = mode->maxPbufferWidth; 149848b8605Smrg return 0; 150848b8605Smrg case GLX_MAX_PBUFFER_HEIGHT: 151848b8605Smrg *value_return = mode->maxPbufferHeight; 152848b8605Smrg return 0; 153848b8605Smrg case GLX_MAX_PBUFFER_PIXELS: 154848b8605Smrg *value_return = mode->maxPbufferPixels; 155848b8605Smrg return 0; 156848b8605Smrg#ifndef GLX_USE_APPLEGL /* These aren't supported by CGL. */ 157848b8605Smrg case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: 158848b8605Smrg *value_return = mode->optimalPbufferWidth; 159848b8605Smrg return 0; 160848b8605Smrg case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: 161848b8605Smrg *value_return = mode->optimalPbufferHeight; 162848b8605Smrg return 0; 163848b8605Smrg case GLX_SWAP_METHOD_OML: 164848b8605Smrg *value_return = mode->swapMethod; 165848b8605Smrg return 0; 166848b8605Smrg#endif 167848b8605Smrg case GLX_SAMPLE_BUFFERS_SGIS: 168848b8605Smrg *value_return = mode->sampleBuffers; 169848b8605Smrg return 0; 170848b8605Smrg case GLX_SAMPLES_SGIS: 171848b8605Smrg *value_return = mode->samples; 172848b8605Smrg return 0; 173848b8605Smrg case GLX_BIND_TO_TEXTURE_RGB_EXT: 174848b8605Smrg *value_return = mode->bindToTextureRgb; 175848b8605Smrg return 0; 176848b8605Smrg case GLX_BIND_TO_TEXTURE_RGBA_EXT: 177848b8605Smrg *value_return = mode->bindToTextureRgba; 178848b8605Smrg return 0; 179848b8605Smrg case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 180848b8605Smrg *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE : 181848b8605Smrg GL_FALSE; 182848b8605Smrg return 0; 183848b8605Smrg case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 184848b8605Smrg *value_return = mode->bindToTextureTargets; 185848b8605Smrg return 0; 186848b8605Smrg case GLX_Y_INVERTED_EXT: 187848b8605Smrg *value_return = mode->yInverted; 188848b8605Smrg return 0; 189848b8605Smrg 190848b8605Smrg case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT: 191848b8605Smrg *value_return = mode->sRGBCapable; 192848b8605Smrg return 0; 193848b8605Smrg 194848b8605Smrg /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX. 195848b8605Smrg * It is ONLY for communication between the GLX client and the GLX 196848b8605Smrg * server. 197848b8605Smrg */ 198848b8605Smrg case GLX_VISUAL_SELECT_GROUP_SGIX: 199848b8605Smrg default: 200848b8605Smrg return GLX_BAD_ATTRIBUTE; 201848b8605Smrg } 202848b8605Smrg} 203848b8605Smrg 204848b8605Smrg 205848b8605Smrg/** 206848b8605Smrg * Allocate a linked list of \c struct glx_config structures. The fields of 207848b8605Smrg * each structure will be initialized to "reasonable" default values. In 208848b8605Smrg * most cases this is the default value defined by table 3.4 of the GLX 209848b8605Smrg * 1.3 specification. This means that most values are either initialized to 210848b8605Smrg * zero or \c GLX_DONT_CARE (which is -1). As support for additional 211848b8605Smrg * extensions is added, the new values will be initialized to appropriate 212848b8605Smrg * values from the extension specification. 213848b8605Smrg * 214848b8605Smrg * \param count Number of structures to allocate. 215848b8605Smrg * \param minimum_size Minimum size of a structure to allocate. This allows 216848b8605Smrg * for differences in the version of the 217848b8605Smrg * \c struct glx_config stucture used in libGL and in a 218848b8605Smrg * DRI-based driver. 219848b8605Smrg * \returns A pointer to the first element in a linked list of \c count 220848b8605Smrg * stuctures on success, or \c NULL on failure. 221848b8605Smrg */ 222848b8605Smrg_X_HIDDEN struct glx_config * 223848b8605Smrgglx_config_create_list(unsigned count) 224848b8605Smrg{ 225848b8605Smrg const size_t size = sizeof(struct glx_config); 226848b8605Smrg struct glx_config *base = NULL; 227848b8605Smrg struct glx_config **next; 228848b8605Smrg unsigned i; 229848b8605Smrg 230848b8605Smrg next = &base; 231848b8605Smrg for (i = 0; i < count; i++) { 232848b8605Smrg *next = malloc(size); 233848b8605Smrg if (*next == NULL) { 234848b8605Smrg glx_config_destroy_list(base); 235848b8605Smrg base = NULL; 236848b8605Smrg break; 237848b8605Smrg } 238848b8605Smrg 239848b8605Smrg (void) memset(*next, 0, size); 240848b8605Smrg (*next)->visualID = GLX_DONT_CARE; 241848b8605Smrg (*next)->visualType = GLX_DONT_CARE; 242848b8605Smrg (*next)->visualRating = GLX_NONE; 243848b8605Smrg (*next)->transparentPixel = GLX_NONE; 244848b8605Smrg (*next)->transparentRed = GLX_DONT_CARE; 245848b8605Smrg (*next)->transparentGreen = GLX_DONT_CARE; 246848b8605Smrg (*next)->transparentBlue = GLX_DONT_CARE; 247848b8605Smrg (*next)->transparentAlpha = GLX_DONT_CARE; 248848b8605Smrg (*next)->transparentIndex = GLX_DONT_CARE; 249848b8605Smrg (*next)->xRenderable = GLX_DONT_CARE; 250848b8605Smrg (*next)->fbconfigID = GLX_DONT_CARE; 251848b8605Smrg (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; 252848b8605Smrg (*next)->bindToTextureRgb = GLX_DONT_CARE; 253848b8605Smrg (*next)->bindToTextureRgba = GLX_DONT_CARE; 254848b8605Smrg (*next)->bindToMipmapTexture = GLX_DONT_CARE; 255848b8605Smrg (*next)->bindToTextureTargets = GLX_DONT_CARE; 256848b8605Smrg (*next)->yInverted = GLX_DONT_CARE; 257848b8605Smrg (*next)->sRGBCapable = GLX_DONT_CARE; 258848b8605Smrg 259848b8605Smrg next = &((*next)->next); 260848b8605Smrg } 261848b8605Smrg 262848b8605Smrg return base; 263848b8605Smrg} 264848b8605Smrg 265848b8605Smrg_X_HIDDEN void 266848b8605Smrgglx_config_destroy_list(struct glx_config *configs) 267848b8605Smrg{ 268848b8605Smrg while (configs != NULL) { 269848b8605Smrg struct glx_config *const next = configs->next; 270848b8605Smrg 271848b8605Smrg free(configs); 272848b8605Smrg configs = next; 273848b8605Smrg } 274848b8605Smrg} 275848b8605Smrg 276848b8605Smrg 277848b8605Smrg/** 278848b8605Smrg * Find a context mode matching a Visual ID. 279848b8605Smrg * 280848b8605Smrg * \param modes List list of context-mode structures to be searched. 281848b8605Smrg * \param vid Visual ID to be found. 282848b8605Smrg * \returns A pointer to a context-mode in \c modes if \c vid was found in 283848b8605Smrg * the list, or \c NULL if it was not. 284848b8605Smrg */ 285848b8605Smrg 286848b8605Smrg_X_HIDDEN struct glx_config * 287848b8605Smrgglx_config_find_visual(struct glx_config *configs, int vid) 288848b8605Smrg{ 289848b8605Smrg struct glx_config *c; 290848b8605Smrg 291848b8605Smrg for (c = configs; c != NULL; c = c->next) 292848b8605Smrg if (c->visualID == vid) 293848b8605Smrg return c; 294848b8605Smrg 295848b8605Smrg return NULL; 296848b8605Smrg} 297848b8605Smrg 298848b8605Smrg_X_HIDDEN struct glx_config * 299848b8605Smrgglx_config_find_fbconfig(struct glx_config *configs, int fbid) 300848b8605Smrg{ 301848b8605Smrg struct glx_config *c; 302848b8605Smrg 303848b8605Smrg for (c = configs; c != NULL; c = c->next) 304848b8605Smrg if (c->fbconfigID == fbid) 305848b8605Smrg return c; 306848b8605Smrg 307848b8605Smrg return NULL; 308848b8605Smrg} 309