Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**
  2.  * GLX initialization.  Code based on glxext.c, glx_query.c, and
  3.  * glcontextmodes.c under src/glx/.  The major difference is that DRI
  4.  * related code is stripped out.
  5.  *
  6.  * If the maintenance of this file takes too much time, we should consider
  7.  * refactoring glxext.c.
  8.  */
  9.  
  10. #include <assert.h>
  11. #include <X11/Xlib.h>
  12. #include <X11/Xproto.h>
  13. #include <X11/Xlibint.h>
  14. #include <X11/extensions/Xext.h>
  15. #include <X11/extensions/extutil.h>
  16. #include <sys/time.h>
  17.  
  18. #include "GL/glxproto.h"
  19. #include "GL/glxtokens.h"
  20. #include "GL/gl.h" /* for GL types needed by __GLcontextModes */
  21. #include "glcore.h"  /* for __GLcontextModes */
  22.  
  23. #include "glxinit.h"
  24.  
  25. #ifdef GLX_DIRECT_RENDERING
  26.  
  27. typedef struct GLXGenericGetString
  28. {
  29.    CARD8 reqType;
  30.    CARD8 glxCode;
  31.    CARD16 length B16;
  32.    CARD32 for_whom B32;
  33.    CARD32 name B32;
  34. } xGLXGenericGetStringReq;
  35.  
  36. #define sz_xGLXGenericGetStringReq 12
  37. #define X_GLXGenericGetString 0
  38.  
  39. /* Extension required boiler plate */
  40.  
  41. static char *__glXExtensionName = GLX_EXTENSION_NAME;
  42. static XExtensionInfo *__glXExtensionInfo = NULL;
  43.  
  44. static int
  45. __glXCloseDisplay(Display * dpy, XExtCodes * codes)
  46. {
  47.    return XextRemoveDisplay(__glXExtensionInfo, dpy);
  48. }
  49.  
  50. static /* const */ XExtensionHooks __glXExtensionHooks = {
  51.   NULL,                   /* create_gc */
  52.   NULL,                   /* copy_gc */
  53.   NULL,                   /* flush_gc */
  54.   NULL,                   /* free_gc */
  55.   NULL,                   /* create_font */
  56.   NULL,                   /* free_font */
  57.   __glXCloseDisplay,      /* close_display */
  58.   NULL,                   /* wire_to_event */
  59.   NULL,                   /* event_to_wire */
  60.   NULL,                   /* error */
  61.   NULL,                   /* error_string */
  62. };
  63.  
  64. static XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
  65.                                   __glXExtensionName, &__glXExtensionHooks,
  66.                                   __GLX_NUMBER_EVENTS, NULL)
  67.  
  68. static GLint
  69. _gl_convert_from_x_visual_type(int visualType)
  70. {
  71. #define NUM_VISUAL_TYPES   6
  72.    static const int glx_visual_types[NUM_VISUAL_TYPES] = {
  73.       GLX_STATIC_GRAY, GLX_GRAY_SCALE,
  74.       GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
  75.       GLX_TRUE_COLOR, GLX_DIRECT_COLOR
  76.    };
  77.  
  78.    return ((unsigned) visualType < NUM_VISUAL_TYPES)
  79.       ? glx_visual_types[visualType] : GLX_NONE;
  80. }
  81.  
  82. static void
  83. _gl_context_modes_destroy(__GLcontextModes * modes)
  84. {
  85.    while (modes != NULL) {
  86.       __GLcontextModes *const next = modes->next;
  87.  
  88.       free(modes);
  89.       modes = next;
  90.    }
  91. }
  92.  
  93. static __GLcontextModes *
  94. _gl_context_modes_create(unsigned count, size_t minimum_size)
  95. {
  96.    const size_t size = (minimum_size > sizeof(__GLcontextModes))
  97.       ? minimum_size : sizeof(__GLcontextModes);
  98.    __GLcontextModes *base = NULL;
  99.    __GLcontextModes **next;
  100.    unsigned i;
  101.  
  102.    next = &base;
  103.    for (i = 0; i < count; i++) {
  104.       *next = malloc(size);
  105.       if (*next == NULL) {
  106.          _gl_context_modes_destroy(base);
  107.          base = NULL;
  108.          break;
  109.       }
  110.  
  111.       memset(*next, 0, size);
  112.       (*next)->visualID = GLX_DONT_CARE;
  113.       (*next)->visualType = GLX_DONT_CARE;
  114.       (*next)->visualRating = GLX_NONE;
  115.       (*next)->transparentPixel = GLX_NONE;
  116.       (*next)->transparentRed = GLX_DONT_CARE;
  117.       (*next)->transparentGreen = GLX_DONT_CARE;
  118.       (*next)->transparentBlue = GLX_DONT_CARE;
  119.       (*next)->transparentAlpha = GLX_DONT_CARE;
  120.       (*next)->transparentIndex = GLX_DONT_CARE;
  121.       (*next)->xRenderable = GLX_DONT_CARE;
  122.       (*next)->fbconfigID = GLX_DONT_CARE;
  123.       (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
  124.       (*next)->bindToTextureRgb = GLX_DONT_CARE;
  125.       (*next)->bindToTextureRgba = GLX_DONT_CARE;
  126.       (*next)->bindToMipmapTexture = GLX_DONT_CARE;
  127.       (*next)->bindToTextureTargets = GLX_DONT_CARE;
  128.       (*next)->yInverted = GLX_DONT_CARE;
  129.  
  130.       next = &((*next)->next);
  131.    }
  132.  
  133.    return base;
  134. }
  135.  
  136. static char *
  137. __glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
  138. {
  139.    xGLXGenericGetStringReq *req;
  140.    xGLXSingleReply reply;
  141.    int length;
  142.    int numbytes;
  143.    char *buf;
  144.    CARD32 for_whom = screen;
  145.    CARD32 glxCode = X_GLXQueryServerString;
  146.  
  147.  
  148.    LockDisplay(dpy);
  149.  
  150.  
  151.    /* All of the GLX protocol requests for getting a string from the server
  152.     * look the same.  The exact meaning of the for_whom field is usually
  153.     * either the screen number (for glXQueryServerString) or the context tag
  154.     * (for GLXSingle).
  155.     */
  156.  
  157.    GetReq(GLXGenericGetString, req);
  158.    req->reqType = opcode;
  159.    req->glxCode = glxCode;
  160.    req->for_whom = for_whom;
  161.    req->name = name;
  162.  
  163.    _XReply(dpy, (xReply *) & reply, 0, False);
  164.  
  165.    length = reply.length * 4;
  166.    numbytes = reply.size;
  167.  
  168.    buf = malloc(numbytes);
  169.    if (buf != NULL) {
  170.       _XRead(dpy, buf, numbytes);
  171.       length -= numbytes;
  172.    }
  173.  
  174.    _XEatData(dpy, length);
  175.  
  176.    UnlockDisplay(dpy);
  177.    SyncHandle();
  178.  
  179.    return buf;
  180. }
  181.  
  182. /************************************************************************/
  183. /*
  184. ** Free the per screen configs data as well as the array of
  185. ** __glXScreenConfigs.
  186. */
  187. static void
  188. FreeScreenConfigs(__GLXdisplayPrivate * priv)
  189. {
  190.    __GLXscreenConfigs *psc;
  191.    GLint i, screens;
  192.  
  193.    /* Free screen configuration information */
  194.    screens = ScreenCount(priv->dpy);
  195.    for (i = 0; i < screens; i++) {
  196.       psc = priv->screenConfigs[i];
  197.       if (!psc)
  198.          continue;
  199.       if (psc->configs) {
  200.          _gl_context_modes_destroy(psc->configs);
  201.          psc->configs = NULL;   /* NOTE: just for paranoia */
  202.       }
  203.       free((char *) psc->serverGLXexts);
  204.    }
  205.    free((char *) priv->screenConfigs);
  206.    priv->screenConfigs = NULL;
  207. }
  208.  
  209. /*
  210. ** Release the private memory referred to in a display private
  211. ** structure.  The caller will free the extension structure.
  212. */
  213. static int
  214. __glXFreeDisplayPrivate(XExtData * extension)
  215. {
  216.    __GLXdisplayPrivate *priv;
  217.  
  218.    priv = (__GLXdisplayPrivate *) extension->private_data;
  219.    FreeScreenConfigs(priv);
  220.    free((char *) priv->serverGLXversion);
  221.    free((char *) priv);
  222.    return 0;
  223. }
  224.  
  225. /************************************************************************/
  226.  
  227. /*
  228. ** Query the version of the GLX extension.  This procedure works even if
  229. ** the client extension is not completely set up.
  230. */
  231.  
  232. #define GLX_MAJOR_VERSION 1       /* current version numbers */
  233. #define GLX_MINOR_VERSION 4
  234.  
  235. static Bool
  236. QueryVersion(Display * dpy, int opcode, int *major, int *minor)
  237. {
  238.    xGLXQueryVersionReq *req;
  239.    xGLXQueryVersionReply reply;
  240.  
  241.    /* Send the glXQueryVersion request */
  242.    LockDisplay(dpy);
  243.    GetReq(GLXQueryVersion, req);
  244.    req->reqType = opcode;
  245.    req->glxCode = X_GLXQueryVersion;
  246.    req->majorVersion = GLX_MAJOR_VERSION;
  247.    req->minorVersion = GLX_MINOR_VERSION;
  248.    _XReply(dpy, (xReply *) & reply, 0, False);
  249.    UnlockDisplay(dpy);
  250.    SyncHandle();
  251.  
  252.    if (reply.majorVersion != GLX_MAJOR_VERSION) {
  253.       /*
  254.        ** The server does not support the same major release as this
  255.        ** client.
  256.        */
  257.       return GL_FALSE;
  258.    }
  259.    *major = reply.majorVersion;
  260.    *minor = min(reply.minorVersion, GLX_MINOR_VERSION);
  261.    return GL_TRUE;
  262. }
  263.  
  264. #define __GLX_MIN_CONFIG_PROPS  18
  265. #define __GLX_MAX_CONFIG_PROPS  500
  266. #define __GLX_EXT_CONFIG_PROPS  10
  267. #define __GLX_TOTAL_CONFIG       (__GLX_MIN_CONFIG_PROPS +      \
  268.                                     2 * __GLX_EXT_CONFIG_PROPS)
  269.  
  270. static void
  271. __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
  272.                                     const INT32 * bp, Bool tagged_only,
  273.                                     Bool fbconfig_style_tags)
  274. {
  275.    int i;
  276.  
  277.    if (!tagged_only) {
  278.       /* Copy in the first set of properties */
  279.       config->visualID = *bp++;
  280.  
  281.       config->visualType = _gl_convert_from_x_visual_type(*bp++);
  282.  
  283.       config->rgbMode = *bp++;
  284.  
  285.       config->redBits = *bp++;
  286.       config->greenBits = *bp++;
  287.       config->blueBits = *bp++;
  288.       config->alphaBits = *bp++;
  289.       config->accumRedBits = *bp++;
  290.       config->accumGreenBits = *bp++;
  291.       config->accumBlueBits = *bp++;
  292.       config->accumAlphaBits = *bp++;
  293.  
  294.       config->doubleBufferMode = *bp++;
  295.       config->stereoMode = *bp++;
  296.  
  297.       config->rgbBits = *bp++;
  298.       config->depthBits = *bp++;
  299.       config->stencilBits = *bp++;
  300.       config->numAuxBuffers = *bp++;
  301.       config->level = *bp++;
  302.  
  303.       count -= __GLX_MIN_CONFIG_PROPS;
  304.    }
  305.  
  306.    /*
  307.     ** Additional properties may be in a list at the end
  308.     ** of the reply.  They are in pairs of property type
  309.     ** and property value.
  310.     */
  311.  
  312. #define FETCH_OR_SET(tag) \
  313.     config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
  314.  
  315.    for (i = 0; i < count; i += 2) {
  316.       switch (*bp++) {
  317.       case GLX_RGBA:
  318.          FETCH_OR_SET(rgbMode);
  319.          break;
  320.       case GLX_BUFFER_SIZE:
  321.          config->rgbBits = *bp++;
  322.          break;
  323.       case GLX_LEVEL:
  324.          config->level = *bp++;
  325.          break;
  326.       case GLX_DOUBLEBUFFER:
  327.          FETCH_OR_SET(doubleBufferMode);
  328.          break;
  329.       case GLX_STEREO:
  330.          FETCH_OR_SET(stereoMode);
  331.          break;
  332.       case GLX_AUX_BUFFERS:
  333.          config->numAuxBuffers = *bp++;
  334.          break;
  335.       case GLX_RED_SIZE:
  336.          config->redBits = *bp++;
  337.          break;
  338.       case GLX_GREEN_SIZE:
  339.          config->greenBits = *bp++;
  340.          break;
  341.       case GLX_BLUE_SIZE:
  342.          config->blueBits = *bp++;
  343.          break;
  344.       case GLX_ALPHA_SIZE:
  345.          config->alphaBits = *bp++;
  346.          break;
  347.       case GLX_DEPTH_SIZE:
  348.          config->depthBits = *bp++;
  349.          break;
  350.       case GLX_STENCIL_SIZE:
  351.          config->stencilBits = *bp++;
  352.          break;
  353.       case GLX_ACCUM_RED_SIZE:
  354.          config->accumRedBits = *bp++;
  355.          break;
  356.       case GLX_ACCUM_GREEN_SIZE:
  357.          config->accumGreenBits = *bp++;
  358.          break;
  359.       case GLX_ACCUM_BLUE_SIZE:
  360.          config->accumBlueBits = *bp++;
  361.          break;
  362.       case GLX_ACCUM_ALPHA_SIZE:
  363.          config->accumAlphaBits = *bp++;
  364.          break;
  365.       case GLX_VISUAL_CAVEAT_EXT:
  366.          config->visualRating = *bp++;
  367.          break;
  368.       case GLX_X_VISUAL_TYPE:
  369.          config->visualType = *bp++;
  370.          break;
  371.       case GLX_TRANSPARENT_TYPE:
  372.          config->transparentPixel = *bp++;
  373.          break;
  374.       case GLX_TRANSPARENT_INDEX_VALUE:
  375.          config->transparentIndex = *bp++;
  376.          break;
  377.       case GLX_TRANSPARENT_RED_VALUE:
  378.          config->transparentRed = *bp++;
  379.          break;
  380.       case GLX_TRANSPARENT_GREEN_VALUE:
  381.          config->transparentGreen = *bp++;
  382.          break;
  383.       case GLX_TRANSPARENT_BLUE_VALUE:
  384.          config->transparentBlue = *bp++;
  385.          break;
  386.       case GLX_TRANSPARENT_ALPHA_VALUE:
  387.          config->transparentAlpha = *bp++;
  388.          break;
  389.       case GLX_VISUAL_ID:
  390.          config->visualID = *bp++;
  391.          break;
  392.       case GLX_DRAWABLE_TYPE:
  393.          config->drawableType = *bp++;
  394.          break;
  395.       case GLX_RENDER_TYPE:
  396.          config->renderType = *bp++;
  397.          break;
  398.       case GLX_X_RENDERABLE:
  399.          config->xRenderable = *bp++;
  400.          break;
  401.       case GLX_FBCONFIG_ID:
  402.          config->fbconfigID = *bp++;
  403.          break;
  404.       case GLX_MAX_PBUFFER_WIDTH:
  405.          config->maxPbufferWidth = *bp++;
  406.          break;
  407.       case GLX_MAX_PBUFFER_HEIGHT:
  408.          config->maxPbufferHeight = *bp++;
  409.          break;
  410.       case GLX_MAX_PBUFFER_PIXELS:
  411.          config->maxPbufferPixels = *bp++;
  412.          break;
  413.       case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
  414.          config->optimalPbufferWidth = *bp++;
  415.          break;
  416.       case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
  417.          config->optimalPbufferHeight = *bp++;
  418.          break;
  419.       case GLX_VISUAL_SELECT_GROUP_SGIX:
  420.          config->visualSelectGroup = *bp++;
  421.          break;
  422.       case GLX_SWAP_METHOD_OML:
  423.          config->swapMethod = *bp++;
  424.          break;
  425.       case GLX_SAMPLE_BUFFERS_SGIS:
  426.          config->sampleBuffers = *bp++;
  427.          break;
  428.       case GLX_SAMPLES_SGIS:
  429.          config->samples = *bp++;
  430.          break;
  431.       case GLX_BIND_TO_TEXTURE_RGB_EXT:
  432.          config->bindToTextureRgb = *bp++;
  433.          break;
  434.       case GLX_BIND_TO_TEXTURE_RGBA_EXT:
  435.          config->bindToTextureRgba = *bp++;
  436.          break;
  437.       case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
  438.          config->bindToMipmapTexture = *bp++;
  439.          break;
  440.       case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
  441.          config->bindToTextureTargets = *bp++;
  442.          break;
  443.       case GLX_Y_INVERTED_EXT:
  444.          config->yInverted = *bp++;
  445.          break;
  446.       case None:
  447.          i = count;
  448.          break;
  449.       default:
  450.          break;
  451.       }
  452.    }
  453.  
  454.    config->renderType =
  455.       (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
  456.  
  457.    config->haveAccumBuffer = ((config->accumRedBits +
  458.                                config->accumGreenBits +
  459.                                config->accumBlueBits +
  460.                                config->accumAlphaBits) > 0);
  461.    config->haveDepthBuffer = (config->depthBits > 0);
  462.    config->haveStencilBuffer = (config->stencilBits > 0);
  463. }
  464.  
  465. static __GLcontextModes *
  466. createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
  467.                             int screen, GLboolean tagged_only)
  468. {
  469.    INT32 buf[__GLX_TOTAL_CONFIG], *props;
  470.    unsigned prop_size;
  471.    __GLcontextModes *modes, *m;
  472.    int i;
  473.  
  474.    if (nprops == 0)
  475.       return NULL;
  476.  
  477.    /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
  478.  
  479.    /* Check number of properties */
  480.    if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
  481.       return NULL;
  482.  
  483.    /* Allocate memory for our config structure */
  484.    modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
  485.    if (!modes)
  486.       return NULL;
  487.  
  488.    prop_size = nprops * __GLX_SIZE_INT32;
  489.    if (prop_size <= sizeof(buf))
  490.       props = buf;
  491.    else
  492.       props = malloc(prop_size);
  493.  
  494.    /* Read each config structure and convert it into our format */
  495.    m = modes;
  496.    for (i = 0; i < nvisuals; i++) {
  497.       _XRead(dpy, (char *) props, prop_size);
  498.       /* Older X servers don't send this so we default it here. */
  499.       m->drawableType = GLX_WINDOW_BIT;
  500.       __glXInitializeVisualConfigFromTags(m, nprops, props,
  501.                                      tagged_only, GL_TRUE);
  502.       m->screen = screen;
  503.       m = m->next;
  504.    }
  505.  
  506.    if (props != buf)
  507.       free(props);
  508.  
  509.    return modes;
  510. }
  511.  
  512. static GLboolean
  513. getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen)
  514. {
  515.    xGLXGetFBConfigsReq *fb_req;
  516.    xGLXGetFBConfigsSGIXReq *sgi_req;
  517.    xGLXVendorPrivateWithReplyReq *vpreq;
  518.    xGLXGetFBConfigsReply reply;
  519.    Display *dpy = priv->dpy;
  520.  
  521.    psc->serverGLXexts =
  522.       __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
  523.  
  524.    LockDisplay(dpy);
  525.  
  526.    psc->configs = NULL;
  527.    if (atof(priv->serverGLXversion) >= 1.3) {
  528.       GetReq(GLXGetFBConfigs, fb_req);
  529.       fb_req->reqType = priv->majorOpcode;
  530.       fb_req->glxCode = X_GLXGetFBConfigs;
  531.       fb_req->screen = screen;
  532.    }
  533.    else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
  534.       GetReqExtra(GLXVendorPrivateWithReply,
  535.                   sz_xGLXGetFBConfigsSGIXReq +
  536.                   sz_xGLXVendorPrivateWithReplyReq, vpreq);
  537.       sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
  538.       sgi_req->reqType = priv->majorOpcode;
  539.       sgi_req->glxCode = X_GLXVendorPrivateWithReply;
  540.       sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
  541.       sgi_req->screen = screen;
  542.    }
  543.    else
  544.       goto out;
  545.  
  546.    if (!_XReply(dpy, (xReply *) & reply, 0, False))
  547.       goto out;
  548.  
  549.    psc->configs = createConfigsFromProperties(dpy,
  550.                                               reply.numFBConfigs,
  551.                                               reply.numAttribs * 2,
  552.                                               screen, GL_TRUE);
  553.  
  554.  out:
  555.    UnlockDisplay(dpy);
  556.    return psc->configs != NULL;
  557. }
  558.  
  559. static GLboolean
  560. AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
  561. {
  562.    __GLXscreenConfigs *psc;
  563.    GLint i, screens;
  564.  
  565.    /*
  566.     ** First allocate memory for the array of per screen configs.
  567.     */
  568.    screens = ScreenCount(dpy);
  569.    priv->screenConfigs = malloc(screens * sizeof *priv->screenConfigs);
  570.    if (!priv->screenConfigs) {
  571.       return GL_FALSE;
  572.    }
  573.  
  574.    priv->serverGLXversion =
  575.       __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
  576.    if (priv->serverGLXversion == NULL) {
  577.       FreeScreenConfigs(priv);
  578.       return GL_FALSE;
  579.    }
  580.  
  581.    for (i = 0; i < screens; i++) {
  582.       psc = calloc(1, sizeof *psc);
  583.       if (!psc)
  584.          return GL_FALSE;
  585.       getFBConfigs(psc, priv, i);
  586.       priv->screenConfigs[i] = psc;
  587.    }
  588.  
  589.    SyncHandle();
  590.  
  591.    return GL_TRUE;
  592. }
  593.  
  594. _X_HIDDEN __GLXdisplayPrivate *
  595. __glXInitialize(Display * dpy)
  596. {
  597.    XExtDisplayInfo *info = __glXFindDisplay(dpy);
  598.    XExtData **privList, *private, *found;
  599.    __GLXdisplayPrivate *dpyPriv;
  600.    XEDataObject dataObj;
  601.    int major, minor;
  602.  
  603.    if (!XextHasExtension(info))
  604.       return NULL;
  605.  
  606.    /* See if a display private already exists.  If so, return it */
  607.    dataObj.display = dpy;
  608.    privList = XEHeadOfExtensionList(dataObj);
  609.    found = XFindOnExtensionList(privList, info->codes->extension);
  610.    if (found)
  611.       return (__GLXdisplayPrivate *) found->private_data;
  612.  
  613.    /* See if the versions are compatible */
  614.    if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
  615.       return NULL;
  616.  
  617.    /*
  618.     ** Allocate memory for all the pieces needed for this buffer.
  619.     */
  620.    private = malloc(sizeof(XExtData));
  621.    if (!private)
  622.       return NULL;
  623.    dpyPriv = calloc(1, sizeof(__GLXdisplayPrivate));
  624.    if (!dpyPriv) {
  625.       free(private);
  626.       return NULL;
  627.    }
  628.  
  629.    /*
  630.     ** Init the display private and then read in the screen config
  631.     ** structures from the server.
  632.     */
  633.    dpyPriv->majorOpcode = info->codes->major_opcode;
  634.    dpyPriv->dpy = dpy;
  635.  
  636.    if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
  637.       free(dpyPriv);
  638.       free(private);
  639.       return NULL;
  640.    }
  641.  
  642.    /*
  643.     ** Fill in the private structure.  This is the actual structure that
  644.     ** hangs off of the Display structure.  Our private structure is
  645.     ** referred to by this structure.  Got that?
  646.     */
  647.    private->number = info->codes->extension;
  648.    private->next = 0;
  649.    private->free_private = __glXFreeDisplayPrivate;
  650.    private->private_data = (char *) dpyPriv;
  651.    XAddToExtensionList(privList, private);
  652.  
  653.    return dpyPriv;
  654. }
  655.  
  656. #endif /* GLX_DIRECT_RENDERING */
  657.