13464ebd5Sriastradh/*
23464ebd5Sriastradh * (C) Copyright IBM Corporation 2003
33464ebd5Sriastradh * All Rights Reserved.
43464ebd5Sriastradh *
53464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a
63464ebd5Sriastradh * copy of this software and associated documentation files (the "Software"),
73464ebd5Sriastradh * to deal in the Software without restriction, including without limitation
83464ebd5Sriastradh * on the rights to use, copy, modify, merge, publish, distribute, sub
93464ebd5Sriastradh * license, and/or sell copies of the Software, and to permit persons to whom
103464ebd5Sriastradh * the Software is furnished to do so, subject to the following conditions:
113464ebd5Sriastradh *
123464ebd5Sriastradh * The above copyright notice and this permission notice (including the next
133464ebd5Sriastradh * paragraph) shall be included in all copies or substantial portions of the
143464ebd5Sriastradh * Software.
153464ebd5Sriastradh *
163464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
173464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
183464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
193464ebd5Sriastradh * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
203464ebd5Sriastradh * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
213464ebd5Sriastradh * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
223464ebd5Sriastradh * USE OR OTHER DEALINGS IN THE SOFTWARE.
233464ebd5Sriastradh */
243464ebd5Sriastradh
253464ebd5Sriastradh/**
263464ebd5Sriastradh * \file glxconfig.c
273464ebd5Sriastradh * Utility routines for working with \c struct glx_config structures.  At
283464ebd5Sriastradh * some point most or all of these functions will be moved to the Mesa
293464ebd5Sriastradh * code base.
303464ebd5Sriastradh *
313464ebd5Sriastradh * \author Ian Romanick <idr@us.ibm.com>
323464ebd5Sriastradh */
333464ebd5Sriastradh
343464ebd5Sriastradh#include <GL/glx.h>
353464ebd5Sriastradh#include <stdlib.h>
363464ebd5Sriastradh#include <string.h>
373464ebd5Sriastradh
383464ebd5Sriastradh#include "glxconfig.h"
393464ebd5Sriastradh
403464ebd5Sriastradh#define NUM_VISUAL_TYPES   6
413464ebd5Sriastradh
423464ebd5Sriastradh/**
433464ebd5Sriastradh * Get data from a GLX config
443464ebd5Sriastradh *
453464ebd5Sriastradh * \param mode         GL context mode whose data is to be returned.
463464ebd5Sriastradh * \param attribute    Attribute of \c mode that is to be returned.
473464ebd5Sriastradh * \param value_return Location to store the data member of \c mode.
483464ebd5Sriastradh * \return  If \c attribute is a valid attribute of \c mode, zero is
493464ebd5Sriastradh *          returned.  Otherwise \c GLX_BAD_ATTRIBUTE is returned.
503464ebd5Sriastradh */
513464ebd5Sriastradh_X_HIDDEN int
523464ebd5Sriastradhglx_config_get(struct glx_config * mode, int attribute, int *value_return)
533464ebd5Sriastradh{
543464ebd5Sriastradh   switch (attribute) {
553464ebd5Sriastradh   case GLX_USE_GL:
563464ebd5Sriastradh      *value_return = GL_TRUE;
573464ebd5Sriastradh      return 0;
583464ebd5Sriastradh   case GLX_BUFFER_SIZE:
593464ebd5Sriastradh      *value_return = mode->rgbBits;
603464ebd5Sriastradh      return 0;
613464ebd5Sriastradh   case GLX_RGBA:
627ec681f3Smrg      *value_return = !(mode->renderType & GLX_COLOR_INDEX_BIT);
633464ebd5Sriastradh      return 0;
643464ebd5Sriastradh   case GLX_RED_SIZE:
653464ebd5Sriastradh      *value_return = mode->redBits;
663464ebd5Sriastradh      return 0;
673464ebd5Sriastradh   case GLX_GREEN_SIZE:
683464ebd5Sriastradh      *value_return = mode->greenBits;
693464ebd5Sriastradh      return 0;
703464ebd5Sriastradh   case GLX_BLUE_SIZE:
713464ebd5Sriastradh      *value_return = mode->blueBits;
723464ebd5Sriastradh      return 0;
733464ebd5Sriastradh   case GLX_ALPHA_SIZE:
743464ebd5Sriastradh      *value_return = mode->alphaBits;
753464ebd5Sriastradh      return 0;
763464ebd5Sriastradh   case GLX_DOUBLEBUFFER:
773464ebd5Sriastradh      *value_return = mode->doubleBufferMode;
783464ebd5Sriastradh      return 0;
793464ebd5Sriastradh   case GLX_STEREO:
803464ebd5Sriastradh      *value_return = mode->stereoMode;
813464ebd5Sriastradh      return 0;
823464ebd5Sriastradh   case GLX_AUX_BUFFERS:
833464ebd5Sriastradh      *value_return = mode->numAuxBuffers;
843464ebd5Sriastradh      return 0;
853464ebd5Sriastradh   case GLX_DEPTH_SIZE:
863464ebd5Sriastradh      *value_return = mode->depthBits;
873464ebd5Sriastradh      return 0;
883464ebd5Sriastradh   case GLX_STENCIL_SIZE:
893464ebd5Sriastradh      *value_return = mode->stencilBits;
903464ebd5Sriastradh      return 0;
913464ebd5Sriastradh   case GLX_ACCUM_RED_SIZE:
923464ebd5Sriastradh      *value_return = mode->accumRedBits;
933464ebd5Sriastradh      return 0;
943464ebd5Sriastradh   case GLX_ACCUM_GREEN_SIZE:
953464ebd5Sriastradh      *value_return = mode->accumGreenBits;
963464ebd5Sriastradh      return 0;
973464ebd5Sriastradh   case GLX_ACCUM_BLUE_SIZE:
983464ebd5Sriastradh      *value_return = mode->accumBlueBits;
993464ebd5Sriastradh      return 0;
1003464ebd5Sriastradh   case GLX_ACCUM_ALPHA_SIZE:
1013464ebd5Sriastradh      *value_return = mode->accumAlphaBits;
1023464ebd5Sriastradh      return 0;
1033464ebd5Sriastradh   case GLX_LEVEL:
1043464ebd5Sriastradh      *value_return = mode->level;
1053464ebd5Sriastradh      return 0;
1063464ebd5Sriastradh#ifndef GLX_USE_APPLEGL               /* This isn't supported by CGL. */
1073464ebd5Sriastradh   case GLX_TRANSPARENT_TYPE_EXT:
1083464ebd5Sriastradh      *value_return = mode->transparentPixel;
1093464ebd5Sriastradh      return 0;
1103464ebd5Sriastradh#endif
1113464ebd5Sriastradh   case GLX_TRANSPARENT_RED_VALUE:
1123464ebd5Sriastradh      *value_return = mode->transparentRed;
1133464ebd5Sriastradh      return 0;
1143464ebd5Sriastradh   case GLX_TRANSPARENT_GREEN_VALUE:
1153464ebd5Sriastradh      *value_return = mode->transparentGreen;
1163464ebd5Sriastradh      return 0;
1173464ebd5Sriastradh   case GLX_TRANSPARENT_BLUE_VALUE:
1183464ebd5Sriastradh      *value_return = mode->transparentBlue;
1193464ebd5Sriastradh      return 0;
1203464ebd5Sriastradh   case GLX_TRANSPARENT_ALPHA_VALUE:
1213464ebd5Sriastradh      *value_return = mode->transparentAlpha;
1223464ebd5Sriastradh      return 0;
1233464ebd5Sriastradh   case GLX_TRANSPARENT_INDEX_VALUE:
1243464ebd5Sriastradh      *value_return = mode->transparentIndex;
1253464ebd5Sriastradh      return 0;
1263464ebd5Sriastradh   case GLX_X_VISUAL_TYPE:
1273464ebd5Sriastradh      *value_return = mode->visualType;
1283464ebd5Sriastradh      return 0;
1293464ebd5Sriastradh   case GLX_CONFIG_CAVEAT:
1303464ebd5Sriastradh      *value_return = mode->visualRating;
1313464ebd5Sriastradh      return 0;
1323464ebd5Sriastradh   case GLX_VISUAL_ID:
1333464ebd5Sriastradh      *value_return = mode->visualID;
1343464ebd5Sriastradh      return 0;
1353464ebd5Sriastradh   case GLX_DRAWABLE_TYPE:
1363464ebd5Sriastradh      *value_return = mode->drawableType;
1373464ebd5Sriastradh      return 0;
1383464ebd5Sriastradh   case GLX_RENDER_TYPE:
1393464ebd5Sriastradh      *value_return = mode->renderType;
1403464ebd5Sriastradh      return 0;
1413464ebd5Sriastradh   case GLX_X_RENDERABLE:
1423464ebd5Sriastradh      *value_return = mode->xRenderable;
1433464ebd5Sriastradh      return 0;
1443464ebd5Sriastradh   case GLX_FBCONFIG_ID:
1453464ebd5Sriastradh      *value_return = mode->fbconfigID;
1463464ebd5Sriastradh      return 0;
1473464ebd5Sriastradh   case GLX_MAX_PBUFFER_WIDTH:
1483464ebd5Sriastradh      *value_return = mode->maxPbufferWidth;
1493464ebd5Sriastradh      return 0;
1503464ebd5Sriastradh   case GLX_MAX_PBUFFER_HEIGHT:
1513464ebd5Sriastradh      *value_return = mode->maxPbufferHeight;
1523464ebd5Sriastradh      return 0;
1533464ebd5Sriastradh   case GLX_MAX_PBUFFER_PIXELS:
1543464ebd5Sriastradh      *value_return = mode->maxPbufferPixels;
1553464ebd5Sriastradh      return 0;
1563464ebd5Sriastradh#ifndef GLX_USE_APPLEGL               /* These aren't supported by CGL. */
1573464ebd5Sriastradh   case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
1583464ebd5Sriastradh      *value_return = mode->optimalPbufferWidth;
1593464ebd5Sriastradh      return 0;
1603464ebd5Sriastradh   case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
1613464ebd5Sriastradh      *value_return = mode->optimalPbufferHeight;
1623464ebd5Sriastradh      return 0;
1633464ebd5Sriastradh   case GLX_SWAP_METHOD_OML:
1643464ebd5Sriastradh      *value_return = mode->swapMethod;
1653464ebd5Sriastradh      return 0;
1663464ebd5Sriastradh#endif
1673464ebd5Sriastradh   case GLX_SAMPLE_BUFFERS_SGIS:
1683464ebd5Sriastradh      *value_return = mode->sampleBuffers;
1693464ebd5Sriastradh      return 0;
1703464ebd5Sriastradh   case GLX_SAMPLES_SGIS:
1713464ebd5Sriastradh      *value_return = mode->samples;
1723464ebd5Sriastradh      return 0;
1733464ebd5Sriastradh   case GLX_BIND_TO_TEXTURE_RGB_EXT:
1743464ebd5Sriastradh      *value_return = mode->bindToTextureRgb;
1753464ebd5Sriastradh      return 0;
1763464ebd5Sriastradh   case GLX_BIND_TO_TEXTURE_RGBA_EXT:
1773464ebd5Sriastradh      *value_return = mode->bindToTextureRgba;
1783464ebd5Sriastradh      return 0;
1793464ebd5Sriastradh   case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
1803464ebd5Sriastradh      *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE :
1813464ebd5Sriastradh         GL_FALSE;
1823464ebd5Sriastradh      return 0;
1833464ebd5Sriastradh   case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
1843464ebd5Sriastradh      *value_return = mode->bindToTextureTargets;
1853464ebd5Sriastradh      return 0;
1863464ebd5Sriastradh   case GLX_Y_INVERTED_EXT:
1873464ebd5Sriastradh      *value_return = mode->yInverted;
1883464ebd5Sriastradh      return 0;
1893464ebd5Sriastradh
1903464ebd5Sriastradh   case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:
1913464ebd5Sriastradh      *value_return = mode->sRGBCapable;
1923464ebd5Sriastradh      return 0;
1933464ebd5Sriastradh
1943464ebd5Sriastradh      /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX.
1953464ebd5Sriastradh       * It is ONLY for communication between the GLX client and the GLX
1963464ebd5Sriastradh       * server.
1973464ebd5Sriastradh       */
1983464ebd5Sriastradh   case GLX_VISUAL_SELECT_GROUP_SGIX:
1993464ebd5Sriastradh   default:
2003464ebd5Sriastradh      return GLX_BAD_ATTRIBUTE;
2013464ebd5Sriastradh   }
2023464ebd5Sriastradh}
2033464ebd5Sriastradh
2043464ebd5Sriastradh
2053464ebd5Sriastradh/**
2063464ebd5Sriastradh * Allocate a linked list of \c struct glx_config structures.  The fields of
2073464ebd5Sriastradh * each structure will be initialized to "reasonable" default values.  In
2083464ebd5Sriastradh * most cases this is the default value defined by table 3.4 of the GLX
2093464ebd5Sriastradh * 1.3 specification.  This means that most values are either initialized to
2103464ebd5Sriastradh * zero or \c GLX_DONT_CARE (which is -1).  As support for additional
2113464ebd5Sriastradh * extensions is added, the new values will be initialized to appropriate
2123464ebd5Sriastradh * values from the extension specification.
2133464ebd5Sriastradh *
2143464ebd5Sriastradh * \param count         Number of structures to allocate.
2153464ebd5Sriastradh * \returns A pointer to the first element in a linked list of \c count
2163464ebd5Sriastradh *          stuctures on success, or \c NULL on failure.
2173464ebd5Sriastradh */
2183464ebd5Sriastradh_X_HIDDEN struct glx_config *
2193464ebd5Sriastradhglx_config_create_list(unsigned count)
2203464ebd5Sriastradh{
2213464ebd5Sriastradh   const size_t size = sizeof(struct glx_config);
2223464ebd5Sriastradh   struct glx_config *base = NULL;
2233464ebd5Sriastradh   struct glx_config **next;
2243464ebd5Sriastradh   unsigned i;
2253464ebd5Sriastradh
2263464ebd5Sriastradh   next = &base;
2273464ebd5Sriastradh   for (i = 0; i < count; i++) {
2287ec681f3Smrg      *next = calloc(1, size);
2293464ebd5Sriastradh      if (*next == NULL) {
2303464ebd5Sriastradh	 glx_config_destroy_list(base);
2313464ebd5Sriastradh	 base = NULL;
2323464ebd5Sriastradh	 break;
2333464ebd5Sriastradh      }
2343464ebd5Sriastradh
2353464ebd5Sriastradh      (*next)->visualID = GLX_DONT_CARE;
2363464ebd5Sriastradh      (*next)->visualType = GLX_DONT_CARE;
2373464ebd5Sriastradh      (*next)->visualRating = GLX_NONE;
2383464ebd5Sriastradh      (*next)->transparentPixel = GLX_NONE;
2393464ebd5Sriastradh      (*next)->transparentRed = GLX_DONT_CARE;
2403464ebd5Sriastradh      (*next)->transparentGreen = GLX_DONT_CARE;
2413464ebd5Sriastradh      (*next)->transparentBlue = GLX_DONT_CARE;
2423464ebd5Sriastradh      (*next)->transparentAlpha = GLX_DONT_CARE;
2433464ebd5Sriastradh      (*next)->transparentIndex = GLX_DONT_CARE;
2443464ebd5Sriastradh      (*next)->xRenderable = GLX_DONT_CARE;
2453464ebd5Sriastradh      (*next)->fbconfigID = GLX_DONT_CARE;
2463464ebd5Sriastradh      (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
2473464ebd5Sriastradh      (*next)->bindToTextureRgb = GLX_DONT_CARE;
2483464ebd5Sriastradh      (*next)->bindToTextureRgba = GLX_DONT_CARE;
2493464ebd5Sriastradh      (*next)->bindToMipmapTexture = GLX_DONT_CARE;
2503464ebd5Sriastradh      (*next)->bindToTextureTargets = GLX_DONT_CARE;
2513464ebd5Sriastradh      (*next)->yInverted = GLX_DONT_CARE;
2527ec681f3Smrg      (*next)->sRGBCapable = GL_FALSE;
2533464ebd5Sriastradh
2543464ebd5Sriastradh      next = &((*next)->next);
2553464ebd5Sriastradh   }
2563464ebd5Sriastradh
2573464ebd5Sriastradh   return base;
2583464ebd5Sriastradh}
2593464ebd5Sriastradh
2603464ebd5Sriastradh_X_HIDDEN void
2613464ebd5Sriastradhglx_config_destroy_list(struct glx_config *configs)
2623464ebd5Sriastradh{
2633464ebd5Sriastradh   while (configs != NULL) {
2643464ebd5Sriastradh      struct glx_config *const next = configs->next;
2653464ebd5Sriastradh
2663464ebd5Sriastradh      free(configs);
2673464ebd5Sriastradh      configs = next;
2683464ebd5Sriastradh   }
2693464ebd5Sriastradh}
2703464ebd5Sriastradh
2713464ebd5Sriastradh
2723464ebd5Sriastradh/**
2733464ebd5Sriastradh * Find a context mode matching a Visual ID.
2743464ebd5Sriastradh *
2753464ebd5Sriastradh * \param modes  List list of context-mode structures to be searched.
2763464ebd5Sriastradh * \param vid    Visual ID to be found.
2773464ebd5Sriastradh * \returns A pointer to a context-mode in \c modes if \c vid was found in
2783464ebd5Sriastradh *          the list, or \c NULL if it was not.
2793464ebd5Sriastradh */
2803464ebd5Sriastradh
2813464ebd5Sriastradh_X_HIDDEN struct glx_config *
2823464ebd5Sriastradhglx_config_find_visual(struct glx_config *configs, int vid)
2833464ebd5Sriastradh{
2843464ebd5Sriastradh   struct glx_config *c;
2853464ebd5Sriastradh
2863464ebd5Sriastradh   for (c = configs; c != NULL; c = c->next)
2873464ebd5Sriastradh      if (c->visualID == vid)
2883464ebd5Sriastradh	 return c;
2893464ebd5Sriastradh
2903464ebd5Sriastradh   return NULL;
2913464ebd5Sriastradh}
2923464ebd5Sriastradh
2933464ebd5Sriastradh_X_HIDDEN struct glx_config *
2943464ebd5Sriastradhglx_config_find_fbconfig(struct glx_config *configs, int fbid)
2953464ebd5Sriastradh{
2963464ebd5Sriastradh   struct glx_config *c;
2973464ebd5Sriastradh
2983464ebd5Sriastradh   for (c = configs; c != NULL; c = c->next)
2993464ebd5Sriastradh      if (c->fbconfigID == fbid)
3003464ebd5Sriastradh	 return c;
3013464ebd5Sriastradh
3023464ebd5Sriastradh   return NULL;
3033464ebd5Sriastradh}
304