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 Xfree(gl_extension_string); 156 } 157