Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2011 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21.  * DEALINGS IN THE SOFTWARE.
  22.  */
  23.  
  24. #include <string.h>
  25. #include <ctype.h>
  26.  
  27. #include "glxclient.h"
  28. #include <xcb/glx.h>
  29. #include <X11/Xlib-xcb.h>
  30.  
  31. _X_HIDDEN void
  32. __glX_send_client_info(struct glx_display *glx_dpy)
  33. {
  34.    const unsigned ext_length = strlen("GLX_ARB_create_context");
  35.    const unsigned prof_length = strlen("_profile");
  36.    char *gl_extension_string;
  37.    int gl_extension_length;
  38.    xcb_connection_t *c;
  39.    Bool any_screen_has_ARB_create_context = False;
  40.    Bool any_screen_has_ARB_create_context_profile = False;
  41.    unsigned i;
  42.    static const uint32_t gl_versions[] = {
  43.       1, 4,
  44.    };
  45.    static const uint32_t gl_versions_profiles[] = {
  46.       1, 4, 0x00000000,
  47.    };
  48.    static const char glx_extensions[] =
  49.       "GLX_ARB_create_context GLX_ARB_create_context_profile";
  50.  
  51.    /* There are three possible flavors of the client info structure that the
  52.     * client could send to the server.  The version sent depends on the
  53.     * combination of GLX versions and extensions supported by the client and
  54.     * the server.
  55.     *
  56.     * Server supports                  Client sends
  57.     * ----------------------------------------------------------------------
  58.     * GLX version = 1.0                Nothing.
  59.     *
  60.     * GLX version >= 1.1               struct GLXClientInfo
  61.     *
  62.     * GLX version >= 1.4 and
  63.     * GLX_ARB_create_context           struct glXSetClientInfoARB
  64.     *
  65.     * GLX version >= 1.4 and
  66.     * GLX_ARB_create_context_profile   struct glXSetClientInfo2ARB
  67.     *
  68.     * GLX_ARB_create_context and GLX_ARB_create_context_profile use FBConfigs,
  69.     * and these only exist in GLX 1.4 or with GLX_SGIX_fbconfig.  I can't
  70.     * imagine an implementation that supports GLX_SGIX_fbconfig and
  71.     * GLX_ARB_create_context but not GLX 1.4.  Making GLX 1.4 a hard
  72.     * requirement in this case does not seem like a limitation.
  73.     *
  74.     * This library currently only supports struct GLXClientInfo.
  75.     */
  76.  
  77.    if (glx_dpy->majorVersion == 1 && glx_dpy->minorVersion == 0)
  78.       return;
  79.  
  80.    /* Determine whether any screen on the server supports either of the
  81.     * create-context extensions.
  82.     */
  83.    for (i = 0; i < ScreenCount(glx_dpy->dpy); i++) {
  84.       struct glx_screen *src = glx_dpy->screens[i];
  85.  
  86.       const char *haystack = src->serverGLXexts;
  87.       while (haystack != NULL) {
  88.          char *match = strstr(haystack, "GLX_ARB_create_context");
  89.  
  90.          if (match == NULL)
  91.             break;
  92.  
  93.          match += ext_length;
  94.  
  95.          switch (match[0]) {
  96.          case '\0':
  97.          case ' ':
  98.             any_screen_has_ARB_create_context = True;
  99.             break;
  100.  
  101.          case '_':
  102.             if (strncmp(match, "_profile", prof_length) == 0
  103.                     && (match[prof_length] == '\0'
  104.                         || match[prof_length] == ' ')) {
  105.                any_screen_has_ARB_create_context_profile = True;
  106.                match += prof_length;
  107.             }
  108.             break;
  109.          }
  110.  
  111.          haystack = match;
  112.       }
  113.    }
  114.  
  115.    gl_extension_string = __glXGetClientGLExtensionString();
  116.    gl_extension_length = strlen(gl_extension_string) + 1;
  117.  
  118.    c = XGetXCBConnection(glx_dpy->dpy);
  119.  
  120.    /* Depending on the GLX verion and the available extensions on the server,
  121.     * send the correct "flavor" of protocol to the server.
  122.     *
  123.     * THE ORDER IS IMPORTANT.  We want to send the most recent version of the
  124.     * protocol that the server can support.
  125.     */
  126.    if (glx_dpy->majorVersion == 1 && glx_dpy->minorVersion == 4
  127.        && any_screen_has_ARB_create_context_profile) {
  128.       xcb_glx_set_client_info_2arb(c,
  129.                                   GLX_MAJOR_VERSION, GLX_MINOR_VERSION,
  130.                                    sizeof(gl_versions_profiles)
  131.                                    / (3 * sizeof(gl_versions_profiles[0])),
  132.                                   gl_extension_length,
  133.                                   strlen(glx_extensions) + 1,
  134.                                   gl_versions_profiles,
  135.                                   gl_extension_string,
  136.                                   glx_extensions);
  137.    } else if (glx_dpy->majorVersion == 1 && glx_dpy->minorVersion == 4
  138.               && any_screen_has_ARB_create_context) {
  139.       xcb_glx_set_client_info_arb(c,
  140.                                   GLX_MAJOR_VERSION, GLX_MINOR_VERSION,
  141.                                   sizeof(gl_versions)
  142.                                   / (2 * sizeof(gl_versions[0])),
  143.                                   gl_extension_length,
  144.                                   strlen(glx_extensions) + 1,
  145.                                   gl_versions,
  146.                                   gl_extension_string,
  147.                                   glx_extensions);
  148.    } else {
  149.       xcb_glx_client_info(c,
  150.                           GLX_MAJOR_VERSION, GLX_MINOR_VERSION,
  151.                           gl_extension_length,
  152.                           gl_extension_string);
  153.    }
  154.  
  155.    free(gl_extension_string);
  156. }
  157.