16ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick/* 26ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * Copyright © 2011 Intel Corporation 36ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 46ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * Permission is hereby granted, free of charge, to any person obtaining a 56ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * copy of this software and associated documentation files (the "Software"), 66ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * to deal in the Software without restriction, including without limitation 76ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * and/or sell copies of the Software, and to permit persons to whom the 96ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * Software is furnished to do so, subject to the following conditions: 106ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 116ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * The above copyright notice and this permission notice (including the next 126ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * paragraph) shall be included in all copies or substantial portions of the 136ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * Software. 146ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 156ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 166ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 176ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 186ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 196ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 206ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 216ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * DEALINGS IN THE SOFTWARE. 226ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick */ 236ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 246ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick#include <string.h> 256ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick#include <ctype.h> 266ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 276ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick#include "glxclient.h" 286ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick#include <xcb/glx.h> 296ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick#include <X11/Xlib-xcb.h> 306ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 316ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick_X_HIDDEN void 326ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick__glX_send_client_info(struct glx_display *glx_dpy) 336ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick{ 346ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick const unsigned ext_length = strlen("GLX_ARB_create_context"); 356ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick const unsigned prof_length = strlen("_profile"); 366ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick char *gl_extension_string; 376ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick int gl_extension_length; 386ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick xcb_connection_t *c; 396ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick Bool any_screen_has_ARB_create_context = False; 406ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick Bool any_screen_has_ARB_create_context_profile = False; 416ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick unsigned i; 426ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick static const uint32_t gl_versions[] = { 436ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 1, 4, 446ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick }; 456ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick static const uint32_t gl_versions_profiles[] = { 466ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 1, 4, 0x00000000, 476ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick }; 486ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick static const char glx_extensions[] = 496ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick "GLX_ARB_create_context GLX_ARB_create_context_profile"; 506ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 516ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick /* There are three possible flavors of the client info structure that the 526ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * client could send to the server. The version sent depends on the 536ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * combination of GLX versions and extensions supported by the client and 546ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * the server. 556ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 566ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * Server supports Client sends 576ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * ---------------------------------------------------------------------- 586ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * GLX version = 1.0 Nothing. 596ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 606ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * GLX version >= 1.1 struct GLXClientInfo 616ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 626ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * GLX version >= 1.4 and 636ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * GLX_ARB_create_context struct glXSetClientInfoARB 646ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 656ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * GLX version >= 1.4 and 666ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * GLX_ARB_create_context_profile struct glXSetClientInfo2ARB 676ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 686ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * GLX_ARB_create_context and GLX_ARB_create_context_profile use FBConfigs, 696ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * and these only exist in GLX 1.4 or with GLX_SGIX_fbconfig. I can't 706ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * imagine an implementation that supports GLX_SGIX_fbconfig and 716ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * GLX_ARB_create_context but not GLX 1.4. Making GLX 1.4 a hard 726ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * requirement in this case does not seem like a limitation. 736ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 746ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * This library currently only supports struct GLXClientInfo. 756ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick */ 766ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 776ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick if (glx_dpy->majorVersion == 1 && glx_dpy->minorVersion == 0) 786ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick return; 796ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 806ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick /* Determine whether any screen on the server supports either of the 816ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * create-context extensions. 826ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick */ 836ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick for (i = 0; i < ScreenCount(glx_dpy->dpy); i++) { 846ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick struct glx_screen *src = glx_dpy->screens[i]; 856ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 866ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick const char *haystack = src->serverGLXexts; 876ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick while (haystack != NULL) { 886ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick char *match = strstr(haystack, "GLX_ARB_create_context"); 896ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 906ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick if (match == NULL) 916ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick break; 926ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 936ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick match += ext_length; 946ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 956ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick switch (match[0]) { 966ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick case '\0': 976ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick case ' ': 986ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick any_screen_has_ARB_create_context = True; 996ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick break; 1006ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 1016ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick case '_': 1026ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick if (strncmp(match, "_profile", prof_length) == 0 1036ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick && (match[prof_length] == '\0' 1046ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick || match[prof_length] == ' ')) { 1056ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick any_screen_has_ARB_create_context_profile = True; 1066ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick match += prof_length; 1076ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick } 1086ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick break; 1096ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick } 1106ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 1116ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick haystack = match; 1126ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick } 1136ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick } 1146ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 1156ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_extension_string = __glXGetClientGLExtensionString(); 116d530745169282469b2dd8221629ef948ff31bcf3Juha-Pekka Heikkila if (gl_extension_string == NULL) { 117d530745169282469b2dd8221629ef948ff31bcf3Juha-Pekka Heikkila return; 118d530745169282469b2dd8221629ef948ff31bcf3Juha-Pekka Heikkila } 119d530745169282469b2dd8221629ef948ff31bcf3Juha-Pekka Heikkila 1206ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_extension_length = strlen(gl_extension_string) + 1; 1216ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 1226ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick c = XGetXCBConnection(glx_dpy->dpy); 1236ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 1246ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick /* Depending on the GLX verion and the available extensions on the server, 1256ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * send the correct "flavor" of protocol to the server. 1266ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * 1276ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * THE ORDER IS IMPORTANT. We want to send the most recent version of the 1286ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick * protocol that the server can support. 1296ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick */ 1306ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick if (glx_dpy->majorVersion == 1 && glx_dpy->minorVersion == 4 1316ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick && any_screen_has_ARB_create_context_profile) { 1326ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick xcb_glx_set_client_info_2arb(c, 1336ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick GLX_MAJOR_VERSION, GLX_MINOR_VERSION, 1346ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick sizeof(gl_versions_profiles) 1356ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick / (3 * sizeof(gl_versions_profiles[0])), 1366ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_extension_length, 1376ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick strlen(glx_extensions) + 1, 1386ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_versions_profiles, 1396ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_extension_string, 1406ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick glx_extensions); 1416ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick } else if (glx_dpy->majorVersion == 1 && glx_dpy->minorVersion == 4 1426ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick && any_screen_has_ARB_create_context) { 1436ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick xcb_glx_set_client_info_arb(c, 1446ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick GLX_MAJOR_VERSION, GLX_MINOR_VERSION, 1456ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick sizeof(gl_versions) 1466ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick / (2 * sizeof(gl_versions[0])), 1476ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_extension_length, 1486ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick strlen(glx_extensions) + 1, 1496ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_versions, 1506ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_extension_string, 1516ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick glx_extensions); 1526882381a2efbdf06b7002d11468c94b9964c2bc8Eric Anholt } else { 1536ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick xcb_glx_client_info(c, 1546ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick GLX_MAJOR_VERSION, GLX_MINOR_VERSION, 1556ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_extension_length, 1566ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick gl_extension_string); 1576ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick } 1586ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick 1597c7b7b068b1d0dc8e14b87dab5dbd4108f874f74Matt Turner free(gl_extension_string); 1606ccda72bf87a27844f8b9807fc080984f48af1cfIan Romanick} 161