14642e01fSmrg/*
24642e01fSmrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
34642e01fSmrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
44642e01fSmrg *
54642e01fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
64642e01fSmrg * copy of this software and associated documentation files (the "Software"),
74642e01fSmrg * to deal in the Software without restriction, including without limitation
84642e01fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
94642e01fSmrg * and/or sell copies of the Software, and to permit persons to whom the
104642e01fSmrg * Software is furnished to do so, subject to the following conditions:
114642e01fSmrg *
124642e01fSmrg * The above copyright notice including the dates of first publication and
134642e01fSmrg * either this permission notice or a reference to
144642e01fSmrg * http://oss.sgi.com/projects/FreeB/
154642e01fSmrg * shall be included in all copies or substantial portions of the Software.
164642e01fSmrg *
174642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
184642e01fSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
194642e01fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
204642e01fSmrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
214642e01fSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
224642e01fSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
234642e01fSmrg * SOFTWARE.
244642e01fSmrg *
254642e01fSmrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
264642e01fSmrg * shall not be used in advertising or otherwise to promote the sale, use or
274642e01fSmrg * other dealings in this Software without prior written authorization from
284642e01fSmrg * Silicon Graphics, Inc.
294642e01fSmrg */
304642e01fSmrg
314642e01fSmrg#ifdef HAVE_DIX_CONFIG_H
324642e01fSmrg#include <dix-config.h>
334642e01fSmrg#endif
344642e01fSmrg
354642e01fSmrg#include <GL/glxtokens.h>
364642e01fSmrg#include <string.h>
374642e01fSmrg#include <windowstr.h>
384642e01fSmrg#include <os.h>
394642e01fSmrg#include <colormapst.h>
404642e01fSmrg
411b5d61b8Smrg#include "extinit.h"
424642e01fSmrg#include "privates.h"
434642e01fSmrg#include "glxserver.h"
444642e01fSmrg#include "glxutil.h"
454642e01fSmrg#include "glxext.h"
466747b715Smrg#include "protocol-versions.h"
474642e01fSmrg
481b5d61b8Smrg#ifdef COMPOSITE
491b5d61b8Smrg#include "compositeext.h"
501b5d61b8Smrg#endif
511b5d61b8Smrg
526747b715Smrgstatic DevPrivateKeyRec glxScreenPrivateKeyRec;
5335c4bbdfSmrg
546747b715Smrg#define glxScreenPrivateKey (&glxScreenPrivateKeyRec)
554642e01fSmrg
564642e01fSmrgconst char GLServerVersion[] = "1.4";
5735c4bbdfSmrgstatic const char GLServerExtensions[] =
5835c4bbdfSmrg    "GL_ARB_depth_texture "
5935c4bbdfSmrg    "GL_ARB_draw_buffers "
6035c4bbdfSmrg    "GL_ARB_fragment_program "
6135c4bbdfSmrg    "GL_ARB_fragment_program_shadow "
6235c4bbdfSmrg    "GL_ARB_imaging "
6335c4bbdfSmrg    "GL_ARB_multisample "
6435c4bbdfSmrg    "GL_ARB_multitexture "
6535c4bbdfSmrg    "GL_ARB_occlusion_query "
6635c4bbdfSmrg    "GL_ARB_point_parameters "
6735c4bbdfSmrg    "GL_ARB_point_sprite "
6835c4bbdfSmrg    "GL_ARB_shadow "
6935c4bbdfSmrg    "GL_ARB_shadow_ambient "
7035c4bbdfSmrg    "GL_ARB_texture_border_clamp "
7135c4bbdfSmrg    "GL_ARB_texture_compression "
7235c4bbdfSmrg    "GL_ARB_texture_cube_map "
7335c4bbdfSmrg    "GL_ARB_texture_env_add "
7435c4bbdfSmrg    "GL_ARB_texture_env_combine "
7535c4bbdfSmrg    "GL_ARB_texture_env_crossbar "
7635c4bbdfSmrg    "GL_ARB_texture_env_dot3 "
7735c4bbdfSmrg    "GL_ARB_texture_mirrored_repeat "
7835c4bbdfSmrg    "GL_ARB_texture_non_power_of_two "
7935c4bbdfSmrg    "GL_ARB_transpose_matrix "
8035c4bbdfSmrg    "GL_ARB_vertex_program "
8135c4bbdfSmrg    "GL_ARB_window_pos "
8235c4bbdfSmrg    "GL_EXT_abgr "
8335c4bbdfSmrg    "GL_EXT_bgra "
8435c4bbdfSmrg    "GL_EXT_blend_color "
8535c4bbdfSmrg    "GL_EXT_blend_equation_separate "
8635c4bbdfSmrg    "GL_EXT_blend_func_separate "
8735c4bbdfSmrg    "GL_EXT_blend_logic_op "
8835c4bbdfSmrg    "GL_EXT_blend_minmax "
8935c4bbdfSmrg    "GL_EXT_blend_subtract "
9035c4bbdfSmrg    "GL_EXT_clip_volume_hint "
9135c4bbdfSmrg    "GL_EXT_copy_texture "
9235c4bbdfSmrg    "GL_EXT_draw_range_elements "
9335c4bbdfSmrg    "GL_EXT_fog_coord "
9435c4bbdfSmrg    "GL_EXT_framebuffer_object "
9535c4bbdfSmrg    "GL_EXT_multi_draw_arrays "
9635c4bbdfSmrg    "GL_EXT_packed_pixels "
9735c4bbdfSmrg    "GL_EXT_paletted_texture "
9835c4bbdfSmrg    "GL_EXT_point_parameters "
9935c4bbdfSmrg    "GL_EXT_polygon_offset "
10035c4bbdfSmrg    "GL_EXT_rescale_normal "
10135c4bbdfSmrg    "GL_EXT_secondary_color "
10235c4bbdfSmrg    "GL_EXT_separate_specular_color "
10335c4bbdfSmrg    "GL_EXT_shadow_funcs "
10435c4bbdfSmrg    "GL_EXT_shared_texture_palette "
10535c4bbdfSmrg    "GL_EXT_stencil_two_side "
10635c4bbdfSmrg    "GL_EXT_stencil_wrap "
10735c4bbdfSmrg    "GL_EXT_subtexture "
10835c4bbdfSmrg    "GL_EXT_texture "
10935c4bbdfSmrg    "GL_EXT_texture3D "
11035c4bbdfSmrg    "GL_EXT_texture_compression_dxt1 "
11135c4bbdfSmrg    "GL_EXT_texture_compression_s3tc "
11235c4bbdfSmrg    "GL_EXT_texture_edge_clamp "
11335c4bbdfSmrg    "GL_EXT_texture_env_add "
11435c4bbdfSmrg    "GL_EXT_texture_env_combine "
11535c4bbdfSmrg    "GL_EXT_texture_env_dot3 "
11635c4bbdfSmrg    "GL_EXT_texture_filter_anisotropic "
11735c4bbdfSmrg    "GL_EXT_texture_lod "
11835c4bbdfSmrg    "GL_EXT_texture_lod_bias "
11935c4bbdfSmrg    "GL_EXT_texture_mirror_clamp "
12035c4bbdfSmrg    "GL_EXT_texture_object "
12135c4bbdfSmrg    "GL_EXT_texture_rectangle "
12235c4bbdfSmrg    "GL_EXT_vertex_array "
12335c4bbdfSmrg    "GL_3DFX_texture_compression_FXT1 "
12435c4bbdfSmrg    "GL_APPLE_packed_pixels "
12535c4bbdfSmrg    "GL_ATI_draw_buffers "
12635c4bbdfSmrg    "GL_ATI_texture_env_combine3 "
12735c4bbdfSmrg    "GL_ATI_texture_mirror_once "
12835c4bbdfSmrg    "GL_HP_occlusion_test "
12935c4bbdfSmrg    "GL_IBM_texture_mirrored_repeat "
13035c4bbdfSmrg    "GL_INGR_blend_func_separate "
13135c4bbdfSmrg    "GL_MESA_pack_invert "
13235c4bbdfSmrg    "GL_MESA_ycbcr_texture "
13335c4bbdfSmrg    "GL_NV_blend_square "
13435c4bbdfSmrg    "GL_NV_depth_clamp "
13535c4bbdfSmrg    "GL_NV_fog_distance "
13635c4bbdfSmrg    "GL_NV_fragment_program_option "
13735c4bbdfSmrg    "GL_NV_fragment_program2 "
13835c4bbdfSmrg    "GL_NV_light_max_exponent "
13935c4bbdfSmrg    "GL_NV_multisample_filter_hint "
14035c4bbdfSmrg    "GL_NV_point_sprite "
14135c4bbdfSmrg    "GL_NV_texgen_reflection "
14235c4bbdfSmrg    "GL_NV_texture_compression_vtc "
14335c4bbdfSmrg    "GL_NV_texture_env_combine4 "
14435c4bbdfSmrg    "GL_NV_texture_expand_normal "
14535c4bbdfSmrg    "GL_NV_texture_rectangle "
14635c4bbdfSmrg    "GL_NV_vertex_program2_option "
14735c4bbdfSmrg    "GL_NV_vertex_program3 "
14835c4bbdfSmrg    "GL_OES_compressed_paletted_texture "
14935c4bbdfSmrg    "GL_SGI_color_matrix "
15035c4bbdfSmrg    "GL_SGI_color_table "
15135c4bbdfSmrg    "GL_SGIS_generate_mipmap "
15235c4bbdfSmrg    "GL_SGIS_multisample "
15335c4bbdfSmrg    "GL_SGIS_point_parameters "
15435c4bbdfSmrg    "GL_SGIS_texture_border_clamp "
15535c4bbdfSmrg    "GL_SGIS_texture_edge_clamp "
15635c4bbdfSmrg    "GL_SGIS_texture_lod "
15735c4bbdfSmrg    "GL_SGIX_depth_texture "
15835c4bbdfSmrg    "GL_SGIX_shadow "
15935c4bbdfSmrg    "GL_SGIX_shadow_ambient "
16035c4bbdfSmrg    "GL_SUN_slice_accum ";
1614642e01fSmrg
1624642e01fSmrgstatic Bool
16335c4bbdfSmrgglxCloseScreen(ScreenPtr pScreen)
1644642e01fSmrg{
1654642e01fSmrg    __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
1664642e01fSmrg
1674642e01fSmrg    pScreen->CloseScreen = pGlxScreen->CloseScreen;
1684642e01fSmrg
1694642e01fSmrg    pGlxScreen->destroy(pGlxScreen);
1704642e01fSmrg
17135c4bbdfSmrg    return pScreen->CloseScreen(pScreen);
1724642e01fSmrg}
1734642e01fSmrg
1744642e01fSmrg__GLXscreen *
1754642e01fSmrgglxGetScreen(ScreenPtr pScreen)
1764642e01fSmrg{
1774642e01fSmrg    return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey);
1784642e01fSmrg}
1794642e01fSmrg
18035c4bbdfSmrgGLint
18135c4bbdfSmrgglxConvertToXVisualType(int visualType)
1824642e01fSmrg{
1834642e01fSmrg    static const int x_visual_types[] = {
18435c4bbdfSmrg        TrueColor, DirectColor,
18535c4bbdfSmrg        PseudoColor, StaticColor,
18635c4bbdfSmrg        GrayScale, StaticGray
1874642e01fSmrg    };
1884642e01fSmrg
18935c4bbdfSmrg    return ((unsigned) (visualType - GLX_TRUE_COLOR) < 6)
19035c4bbdfSmrg        ? x_visual_types[visualType - GLX_TRUE_COLOR] : -1;
1914642e01fSmrg}
1924642e01fSmrg
1934642e01fSmrg/* This code inspired by composite/compinit.c.  We could move this to
1944642e01fSmrg * mi/ and share it with composite.*/
1954642e01fSmrg
1964642e01fSmrgstatic VisualPtr
1974642e01fSmrgAddScreenVisuals(ScreenPtr pScreen, int count, int d)
1984642e01fSmrg{
19935c4bbdfSmrg    int i;
20035c4bbdfSmrg    DepthPtr depth;
2014642e01fSmrg
2024642e01fSmrg    depth = NULL;
2034642e01fSmrg    for (i = 0; i < pScreen->numDepths; i++) {
20435c4bbdfSmrg        if (pScreen->allowedDepths[i].depth == d) {
20535c4bbdfSmrg            depth = &pScreen->allowedDepths[i];
20635c4bbdfSmrg            break;
20735c4bbdfSmrg        }
2084642e01fSmrg    }
2094642e01fSmrg    if (depth == NULL)
21035c4bbdfSmrg        return NULL;
2114642e01fSmrg
2126747b715Smrg    if (ResizeVisualArray(pScreen, count, depth) == FALSE)
2136747b715Smrg        return NULL;
2144642e01fSmrg
21535c4bbdfSmrg    /* Return a pointer to the first of the added visuals. */
2164642e01fSmrg    return pScreen->visuals + pScreen->numVisuals - count;
2174642e01fSmrg}
2184642e01fSmrg
2194642e01fSmrgstatic int
2204642e01fSmrgfindFirstSet(unsigned int v)
2214642e01fSmrg{
2224642e01fSmrg    int i;
2234642e01fSmrg
2244642e01fSmrg    for (i = 0; i < 32; i++)
22535c4bbdfSmrg        if (v & (1 << i))
22635c4bbdfSmrg            return i;
2274642e01fSmrg
2284642e01fSmrg    return -1;
2294642e01fSmrg}
2304642e01fSmrg
2314642e01fSmrgstatic void
23235c4bbdfSmrginitGlxVisual(VisualPtr visual, __GLXconfig * config)
2334642e01fSmrg{
2344642e01fSmrg    int maxBits;
23535c4bbdfSmrg
2364642e01fSmrg    maxBits = max(config->redBits, max(config->greenBits, config->blueBits));
2374642e01fSmrg
2384642e01fSmrg    config->visualID = visual->vid;
2394642e01fSmrg    visual->class = glxConvertToXVisualType(config->visualType);
2404642e01fSmrg    visual->bitsPerRGBValue = maxBits;
2414642e01fSmrg    visual->ColormapEntries = 1 << maxBits;
2424642e01fSmrg    visual->nplanes = config->redBits + config->greenBits + config->blueBits;
2434642e01fSmrg
2444642e01fSmrg    visual->redMask = config->redMask;
2454642e01fSmrg    visual->greenMask = config->greenMask;
2464642e01fSmrg    visual->blueMask = config->blueMask;
2474642e01fSmrg    visual->offsetRed = findFirstSet(config->redMask);
2484642e01fSmrg    visual->offsetGreen = findFirstSet(config->greenMask);
2494642e01fSmrg    visual->offsetBlue = findFirstSet(config->blueMask);
2504642e01fSmrg}
2514642e01fSmrg
2524642e01fSmrgstatic __GLXconfig *
25335c4bbdfSmrgpickFBConfig(__GLXscreen * pGlxScreen, VisualPtr visual)
2544642e01fSmrg{
2554642e01fSmrg    __GLXconfig *best = NULL, *config;
2564642e01fSmrg    int best_score = 0;
2574642e01fSmrg
2584642e01fSmrg    for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
25935c4bbdfSmrg        int score = 0;
26035c4bbdfSmrg
26135c4bbdfSmrg        if (config->redMask != visual->redMask ||
26235c4bbdfSmrg            config->greenMask != visual->greenMask ||
26335c4bbdfSmrg            config->blueMask != visual->blueMask)
26435c4bbdfSmrg            continue;
26535c4bbdfSmrg        if (config->visualRating != GLX_NONE)
26635c4bbdfSmrg            continue;
26735c4bbdfSmrg        /* Ignore multisampled configs */
26835c4bbdfSmrg        if (config->sampleBuffers)
26935c4bbdfSmrg            continue;
27035c4bbdfSmrg        if (glxConvertToXVisualType(config->visualType) != visual->class)
27135c4bbdfSmrg            continue;
27235c4bbdfSmrg        /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */
27335c4bbdfSmrg        if (visual->nplanes == 32 && config->rgbBits != 32)
27435c4bbdfSmrg            continue;
2751b5d61b8Smrg        /* If it's the 32-bit RGBA visual, do not pick sRGB capable config.
2761b5d61b8Smrg         * This can cause issues with compositors that are not sRGB aware.
2771b5d61b8Smrg         */
2781b5d61b8Smrg        if (visual->nplanes == 32 && config->sRGBCapable == GL_TRUE)
2791b5d61b8Smrg            continue;
28035c4bbdfSmrg        /* Can't use the same FBconfig for multiple X visuals.  I think. */
28135c4bbdfSmrg        if (config->visualID != 0)
28235c4bbdfSmrg            continue;
2831b5d61b8Smrg#ifdef COMPOSITE
2841b5d61b8Smrg        if (!noCompositeExtension) {
2851b5d61b8Smrg            /* Use only duplicated configs for compIsAlternateVisuals */
2861b5d61b8Smrg            if (!!compIsAlternateVisual(pGlxScreen->pScreen, visual->vid) !=
2871b5d61b8Smrg                !!config->duplicatedForComp)
2881b5d61b8Smrg                continue;
2891b5d61b8Smrg        }
2901b5d61b8Smrg#endif
2911b5d61b8Smrg        /*
2921b5d61b8Smrg         * If possible, use the same swapmethod for all built-in visual
2931b5d61b8Smrg         * fbconfigs, to avoid getting the 32-bit composite visual when
2941b5d61b8Smrg         * requesting, for example, a SWAP_COPY fbconfig.
2951b5d61b8Smrg         */
2961b5d61b8Smrg        if (config->swapMethod == GLX_SWAP_UNDEFINED_OML)
2971b5d61b8Smrg            score += 32;
2981b5d61b8Smrg        if (config->swapMethod == GLX_SWAP_EXCHANGE_OML)
2991b5d61b8Smrg            score += 16;
30035c4bbdfSmrg        if (config->doubleBufferMode > 0)
30135c4bbdfSmrg            score += 8;
30235c4bbdfSmrg        if (config->depthBits > 0)
30335c4bbdfSmrg            score += 4;
30435c4bbdfSmrg        if (config->stencilBits > 0)
30535c4bbdfSmrg            score += 2;
30635c4bbdfSmrg        if (config->alphaBits > 0)
30735c4bbdfSmrg            score++;
30835c4bbdfSmrg
30935c4bbdfSmrg        if (score > best_score) {
31035c4bbdfSmrg            best = config;
31135c4bbdfSmrg            best_score = score;
31235c4bbdfSmrg        }
3134642e01fSmrg    }
3144642e01fSmrg
3154642e01fSmrg    return best;
3164642e01fSmrg}
3174642e01fSmrg
31835c4bbdfSmrgvoid
31935c4bbdfSmrg__glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
3204642e01fSmrg{
3214642e01fSmrg    __GLXconfig *m;
3224642e01fSmrg    __GLXconfig *config;
3234642e01fSmrg    int i;
3244642e01fSmrg
3256747b715Smrg    if (!dixRegisterPrivateKey(&glxScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
32635c4bbdfSmrg        return;
3276747b715Smrg
32835c4bbdfSmrg    pGlxScreen->pScreen = pScreen;
32935c4bbdfSmrg    pGlxScreen->GLextensions = strdup(GLServerExtensions);
3301b5d61b8Smrg    pGlxScreen->GLXextensions = NULL;
3314642e01fSmrg
3324642e01fSmrg    pGlxScreen->CloseScreen = pScreen->CloseScreen;
3334642e01fSmrg    pScreen->CloseScreen = glxCloseScreen;
3344642e01fSmrg
3354642e01fSmrg    i = 0;
3364642e01fSmrg    for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
33735c4bbdfSmrg        m->fbconfigID = FakeClientID(0);
33835c4bbdfSmrg        m->visualID = 0;
33935c4bbdfSmrg        i++;
3404642e01fSmrg    }
3414642e01fSmrg    pGlxScreen->numFBConfigs = i;
3424642e01fSmrg
3434642e01fSmrg    pGlxScreen->visuals =
34435c4bbdfSmrg        calloc(pGlxScreen->numFBConfigs, sizeof(__GLXconfig *));
3454642e01fSmrg
3464642e01fSmrg    /* First, try to choose featureful FBconfigs for the existing X visuals.
3474642e01fSmrg     * Note that if multiple X visuals end up with the same FBconfig being
3484642e01fSmrg     * chosen, the later X visuals don't get GLX visuals (because we want to
3494642e01fSmrg     * prioritize the root visual being GLX).
3504642e01fSmrg     */
3514642e01fSmrg    for (i = 0; i < pScreen->numVisuals; i++) {
35235c4bbdfSmrg        VisualPtr visual = &pScreen->visuals[i];
3534642e01fSmrg
35435c4bbdfSmrg        config = pickFBConfig(pGlxScreen, visual);
35535c4bbdfSmrg        if (config) {
35635c4bbdfSmrg            pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
35735c4bbdfSmrg            config->visualID = visual->vid;
3581b5d61b8Smrg#ifdef COMPOSITE
3591b5d61b8Smrg            if (!noCompositeExtension) {
3601b5d61b8Smrg                if (compIsAlternateVisual(pScreen, visual->vid))
3611b5d61b8Smrg                    config->visualSelectGroup++;
3621b5d61b8Smrg            }
3631b5d61b8Smrg#endif
36435c4bbdfSmrg        }
3654642e01fSmrg    }
3664642e01fSmrg
3674642e01fSmrg    /* Then, add new visuals corresponding to all FBconfigs that didn't have
3684642e01fSmrg     * an existing, appropriate visual.
3694642e01fSmrg     */
3704642e01fSmrg    for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
37135c4bbdfSmrg        int depth;
37235c4bbdfSmrg
37335c4bbdfSmrg        VisualPtr visual;
37435c4bbdfSmrg
37535c4bbdfSmrg        if (config->visualID != 0)
37635c4bbdfSmrg            continue;
37735c4bbdfSmrg
37835c4bbdfSmrg        /* Only count RGB bits and not alpha, as we're not trying to create
37935c4bbdfSmrg         * visuals for compositing (that's what the 32-bit composite visual
38035c4bbdfSmrg         * set up above is for.
38135c4bbdfSmrg         */
38235c4bbdfSmrg        depth = config->redBits + config->greenBits + config->blueBits;
3831b5d61b8Smrg#ifdef COMPOSITE
3841b5d61b8Smrg        if (!noCompositeExtension) {
3851b5d61b8Smrg            if (config->duplicatedForComp) {
3861b5d61b8Smrg                    depth += config->alphaBits;
3871b5d61b8Smrg                    config->visualSelectGroup++;
3881b5d61b8Smrg            }
3891b5d61b8Smrg        }
3901b5d61b8Smrg#endif
39135c4bbdfSmrg        /* Make sure that our FBconfig's depth can actually be displayed
39235c4bbdfSmrg         * (corresponds to an existing visual).
39335c4bbdfSmrg         */
39435c4bbdfSmrg        for (i = 0; i < pScreen->numVisuals; i++) {
39535c4bbdfSmrg            if (depth == pScreen->visuals[i].nplanes)
39635c4bbdfSmrg                break;
39735c4bbdfSmrg        }
39835c4bbdfSmrg        /* if it can't, fix up the fbconfig to not advertise window support */
39935c4bbdfSmrg        if (i == pScreen->numVisuals)
40035c4bbdfSmrg            config->drawableType &= ~(GLX_WINDOW_BIT);
40135c4bbdfSmrg
40235c4bbdfSmrg        /* fbconfig must support window drawables */
40335c4bbdfSmrg        if (!(config->drawableType & GLX_WINDOW_BIT)) {
40435c4bbdfSmrg            config->visualID = 0;
40535c4bbdfSmrg            continue;
40635c4bbdfSmrg        }
40735c4bbdfSmrg
40835c4bbdfSmrg        /* Create a new X visual for our FBconfig. */
40935c4bbdfSmrg        visual = AddScreenVisuals(pScreen, 1, depth);
41035c4bbdfSmrg        if (visual == NULL)
41135c4bbdfSmrg            continue;
41235c4bbdfSmrg
4131b5d61b8Smrg#ifdef COMPOSITE
4141b5d61b8Smrg        if (!noCompositeExtension) {
4151b5d61b8Smrg            if (config->duplicatedForComp)
4161b5d61b8Smrg                (void) CompositeRegisterAlternateVisuals(pScreen, &visual->vid, 1);
4171b5d61b8Smrg        }
4181b5d61b8Smrg#endif
41935c4bbdfSmrg        pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
42035c4bbdfSmrg        initGlxVisual(visual, config);
4214642e01fSmrg    }
4224642e01fSmrg
4234642e01fSmrg    dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen);
4241b5d61b8Smrg
4251b5d61b8Smrg    if (pGlxScreen->glvnd)
4261b5d61b8Smrg        __glXEnableExtension(pGlxScreen->glx_enable_bits, "GLX_EXT_libglvnd");
4271b5d61b8Smrg
4281b5d61b8Smrg    i = __glXGetExtensionString(pGlxScreen->glx_enable_bits, NULL);
4291b5d61b8Smrg    if (i > 0) {
4301b5d61b8Smrg        pGlxScreen->GLXextensions = xnfalloc(i);
4311b5d61b8Smrg        (void) __glXGetExtensionString(pGlxScreen->glx_enable_bits,
4321b5d61b8Smrg                                       pGlxScreen->GLXextensions);
4331b5d61b8Smrg    }
4341b5d61b8Smrg
4354642e01fSmrg}
4364642e01fSmrg
43735c4bbdfSmrgvoid
43835c4bbdfSmrg__glXScreenDestroy(__GLXscreen * screen)
4394642e01fSmrg{
4401b5d61b8Smrg    __GLXconfig *config, *next;
4411b5d61b8Smrg
4421b5d61b8Smrg    free(screen->glvnd);
4436747b715Smrg    free(screen->GLXextensions);
4446747b715Smrg    free(screen->GLextensions);
44535c4bbdfSmrg    free(screen->visuals);
4461b5d61b8Smrg
4471b5d61b8Smrg    for (config = screen->fbconfigs; config != NULL; config = next) {
4481b5d61b8Smrg        next = config->next;
4491b5d61b8Smrg        free(config);
4501b5d61b8Smrg    }
4514642e01fSmrg}
452