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