diff options
author | Ian Romanick <[email protected]> | 2011-11-28 17:50:07 -0800 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2012-01-02 12:41:44 -0800 |
commit | 6ccda72bf87a27844f8b9807fc080984f48af1cf (patch) | |
tree | 34c561ad269f206c88ea0763467ac2562fb482e8 | |
parent | fc7ac4da7dfb64aa192ef8cff44cb762beace4c1 (diff) |
glx: Add __glX_send_client_info super function
This function picks the correct client-info protocol (based on the
server's GLX version and set of extensions) and sends it to the
server.
Signed-off-by: Ian Romanick <[email protected]>
-rw-r--r-- | src/glx/Makefile | 1 | ||||
-rw-r--r-- | src/glx/clientinfo.c | 156 | ||||
-rw-r--r-- | src/glx/glxclient.h | 3 |
3 files changed, 160 insertions, 0 deletions
diff --git a/src/glx/Makefile b/src/glx/Makefile index 183ffb188ad..69d7c7c57bf 100644 --- a/src/glx/Makefile +++ b/src/glx/Makefile @@ -10,6 +10,7 @@ EXTRA_DEFINES = $(EXTRA_DEFINES_XF86VIDMODE) -D_REENTRANT \ SOURCES = \ clientattrib.c \ + clientinfo.c \ compsize.c \ eval.c \ glxconfig.c \ diff --git a/src/glx/clientinfo.c b/src/glx/clientinfo.c new file mode 100644 index 00000000000..429e9a3bfa7 --- /dev/null +++ b/src/glx/clientinfo.c @@ -0,0 +1,156 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <string.h> +#include <ctype.h> + +#include "glxclient.h" +#include <xcb/glx.h> +#include <X11/Xlib-xcb.h> + +_X_HIDDEN void +__glX_send_client_info(struct glx_display *glx_dpy) +{ + const unsigned ext_length = strlen("GLX_ARB_create_context"); + const unsigned prof_length = strlen("_profile"); + char *gl_extension_string; + int gl_extension_length; + xcb_connection_t *c; + Bool any_screen_has_ARB_create_context = False; + Bool any_screen_has_ARB_create_context_profile = False; + unsigned i; + static const uint32_t gl_versions[] = { + 1, 4, + }; + static const uint32_t gl_versions_profiles[] = { + 1, 4, 0x00000000, + }; + static const char glx_extensions[] = + "GLX_ARB_create_context GLX_ARB_create_context_profile"; + + /* There are three possible flavors of the client info structure that the + * client could send to the server. The version sent depends on the + * combination of GLX versions and extensions supported by the client and + * the server. + * + * Server supports Client sends + * ---------------------------------------------------------------------- + * GLX version = 1.0 Nothing. + * + * GLX version >= 1.1 struct GLXClientInfo + * + * GLX version >= 1.4 and + * GLX_ARB_create_context struct glXSetClientInfoARB + * + * GLX version >= 1.4 and + * GLX_ARB_create_context_profile struct glXSetClientInfo2ARB + * + * GLX_ARB_create_context and GLX_ARB_create_context_profile use FBConfigs, + * and these only exist in GLX 1.4 or with GLX_SGIX_fbconfig. I can't + * imagine an implementation that supports GLX_SGIX_fbconfig and + * GLX_ARB_create_context but not GLX 1.4. Making GLX 1.4 a hard + * requirement in this case does not seem like a limitation. + * + * This library currently only supports struct GLXClientInfo. + */ + + if (glx_dpy->majorVersion == 1 && glx_dpy->minorVersion == 0) + return; + + /* Determine whether any screen on the server supports either of the + * create-context extensions. + */ + for (i = 0; i < ScreenCount(glx_dpy->dpy); i++) { + struct glx_screen *src = glx_dpy->screens[i]; + + const char *haystack = src->serverGLXexts; + while (haystack != NULL) { + char *match = strstr(haystack, "GLX_ARB_create_context"); + + if (match == NULL) + break; + + match += ext_length; + + switch (match[0]) { + case '\0': + case ' ': + any_screen_has_ARB_create_context = True; + break; + + case '_': + if (strncmp(match, "_profile", prof_length) == 0 + && (match[prof_length] == '\0' + || match[prof_length] == ' ')) { + any_screen_has_ARB_create_context_profile = True; + match += prof_length; + } + break; + } + + haystack = match; + } + } + + gl_extension_string = __glXGetClientGLExtensionString(); + gl_extension_length = strlen(gl_extension_string) + 1; + + c = XGetXCBConnection(glx_dpy->dpy); + + /* Depending on the GLX verion and the available extensions on the server, + * send the correct "flavor" of protocol to the server. + * + * THE ORDER IS IMPORTANT. We want to send the most recent version of the + * protocol that the server can support. + */ + if (glx_dpy->majorVersion == 1 && glx_dpy->minorVersion == 4 + && any_screen_has_ARB_create_context_profile) { + xcb_glx_set_client_info_2arb(c, + GLX_MAJOR_VERSION, GLX_MINOR_VERSION, + sizeof(gl_versions_profiles) + / (3 * sizeof(gl_versions_profiles[0])), + gl_extension_length, + strlen(glx_extensions) + 1, + gl_versions_profiles, + gl_extension_string, + glx_extensions); + } else if (glx_dpy->majorVersion == 1 && glx_dpy->minorVersion == 4 + && any_screen_has_ARB_create_context) { + xcb_glx_set_client_info_arb(c, + GLX_MAJOR_VERSION, GLX_MINOR_VERSION, + sizeof(gl_versions) + / (2 * sizeof(gl_versions[0])), + gl_extension_length, + strlen(glx_extensions) + 1, + gl_versions, + gl_extension_string, + glx_extensions); + } else { + xcb_glx_client_info(c, + GLX_MAJOR_VERSION, GLX_MINOR_VERSION, + gl_extension_length, + gl_extension_string); + } + + Xfree(gl_extension_string); +} diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 109206f6ba0..0011d39391d 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -726,6 +726,9 @@ extern void __glXFreeVertexArrayState(struct glx_context *); */ extern void __glXClientInfo(Display * dpy, int opcode); +_X_HIDDEN void +__glX_send_client_info(struct glx_display *glx_dpy); + /************************************************************************/ /* |