create_context.c revision 4becf676e0b09b421821b6895251549ec98d4e5d
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 gc = indirect_create_context(psc, cfg, share, 0); 85 86 gc->xid = xcb_generate_id(c); 87 gc->share_xid = (share != NULL) ? share->xid : 0; 88 89 /* The manual pages for glXCreateContext and glXCreateNewContext say: 90 * 91 * "NULL is returned if execution fails on the client side." 92 * 93 * If the server generates an error, the application is supposed to catch 94 * the protocol error and handle it. Part of handling the error is freeing 95 * the possibly non-NULL value returned by this function. 96 */ 97#ifdef HAVE_XCB_GLX_CREATE_CONTEXT 98 cookie = 99 xcb_glx_create_context_attribs_arb_checked(c, 100 gc->xid, 101 cfg->fbconfigID, 102 cfg->screen, 103 gc->share_xid, 104 gc->isDirect, 105 num_attribs, 106 (const uint32_t *) 107 attrib_list); 108 err = xcb_request_check(c, cookie); 109#else 110 /* This is a hugely ugly hack to make things compile on systems that lack 111 * the proper XCB version. 112 */ 113 memset(&cookie, 0, sizeof(cookie)); 114 115 err = calloc(1, sizeof(*err)); 116 err->error_code = BadRequest; 117 err->sequence = dpy->request; 118 err->resource_id = gc->xid; 119 err->minor_code = gc->majorOpcode; 120 err->major_code = 34; 121#endif 122 if (err != NULL) { 123 gc->vtable->destroy(gc); 124 gc = NULL; 125 126 __glXSendErrorForXcb(dpy, err); 127 free(err); 128 } 129 130 return (GLXContext) gc; 131} 132