• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
glXCreateContextAttribsARB(Display * dpy,GLXFBConfig config,GLXContext share_context,Bool direct,const int * attrib_list)37 glXCreateContextAttribsARB(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