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 <limits.h> 25#include "glxclient.h" 26#include "glx_error.h" 27#include <xcb/glx.h> 28#include <X11/Xlib-xcb.h> 29 30#include <assert.h> 31 32#if INT_MAX != 2147483647 33#error This code requires sizeof(uint32_t) == sizeof(int). 34#endif 35 36_X_HIDDEN GLXContext 37glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, 38 GLXContext share_context, Bool direct, 39 const int *attrib_list) 40{ 41 xcb_connection_t *const c = XGetXCBConnection(dpy); 42 struct glx_config *const cfg = (struct glx_config *) config; 43 struct glx_context *const share = (struct glx_context *) share_context; 44 struct glx_context *gc = NULL; 45 unsigned num_attribs = 0; 46 struct glx_screen *psc; 47 xcb_generic_error_t *err; 48 xcb_void_cookie_t cookie; 49 unsigned dummy_err = 0; 50 51 52 if (dpy == NULL || cfg == NULL) 53 return NULL; 54 55 /* This means that either the caller passed the wrong display pointer or 56 * one of the internal GLX data structures (probably the fbconfig) has an 57 * error. There is nothing sensible to do, so return an error. 58 */ 59 psc = GetGLXScreenConfigs(dpy, cfg->screen); 60 if (psc == NULL) 61 return NULL; 62 63 assert(cfg->screen == psc->scr); 64 65 /* Count the number of attributes specified by the application. All 66 * attributes appear in pairs, except the terminating None. 67 */ 68 if (attrib_list != NULL) { 69 for (/* empty */; attrib_list[num_attribs * 2] != 0; num_attribs++) 70 /* empty */ ; 71 } 72 73 if (direct && psc->vtable->create_context_attribs) { 74 /* GLX drops the error returned by the driver. The expectation is that 75 * an error will also be returned by the server. The server's error 76 * will be delivered to the application. 77 */ 78 gc = psc->vtable->create_context_attribs(psc, cfg, share, num_attribs, 79 (const uint32_t *) attrib_list, 80 &dummy_err); 81 } 82 83 if (gc == NULL) { 84#ifdef GLX_USE_APPLEGL 85 gc = applegl_create_context(psc, cfg, share, 0); 86#else 87 gc = indirect_create_context(psc, cfg, share, 0); 88#endif 89 } 90 91 gc->xid = xcb_generate_id(c); 92 gc->share_xid = (share != NULL) ? share->xid : 0; 93 94 /* The manual pages for glXCreateContext and glXCreateNewContext say: 95 * 96 * "NULL is returned if execution fails on the client side." 97 * 98 * If the server generates an error, the application is supposed to catch 99 * the protocol error and handle it. Part of handling the error is freeing 100 * the possibly non-NULL value returned by this function. 101 */ 102 cookie = 103 xcb_glx_create_context_attribs_arb_checked(c, 104 gc->xid, 105 cfg->fbconfigID, 106 cfg->screen, 107 gc->share_xid, 108 gc->isDirect, 109 num_attribs, 110 (const uint32_t *) 111 attrib_list); 112 err = xcb_request_check(c, cookie); 113 if (err != NULL) { 114 gc->vtable->destroy(gc); 115 gc = NULL; 116 117 __glXSendErrorForXcb(dpy, err); 118 free(err); 119 } 120 121 return (GLXContext) gc; 122} 123