blob: f2c1884b8a5ce953be72b737bfbf57c2b41eba55 [file] [log] [blame]
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001/*
Adam Jacksondc8058c2008-09-19 17:16:53 -04002 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
29 */
Adam Jacksoncb3610e2004-10-25 21:09:16 +000030
31/**
32 * \file glxcmds.c
33 * Client-side GLX interface.
34 */
35
Adam Jacksoncb3610e2004-10-25 21:09:16 +000036#include "glxclient.h"
Adam Jacksoncb3610e2004-10-25 21:09:16 +000037#include "glapi.h"
Adam Jacksoncb3610e2004-10-25 21:09:16 +000038#include "glxextensions.h"
Chia-I Wue8c7d752010-12-26 18:24:13 +080039#include "indirect.h"
George Sapountzisdf04ffb2008-04-18 17:28:34 +030040
41#ifdef GLX_DIRECT_RENDERING
Jeremy Huddlestonad503c42010-04-01 11:01:31 -070042#ifdef GLX_USE_APPLEGL
43#include "apple_glx_context.h"
44#include "apple_glx.h"
45#include "glx_error.h"
46#else
Adam Jacksoncb3610e2004-10-25 21:09:16 +000047#include <sys/time.h>
Jon TURNEY2b9dac32010-04-21 12:58:54 +010048#ifdef XF86VIDMODE
George Sapountzisdf04ffb2008-04-18 17:28:34 +030049#include <X11/extensions/xf86vmode.h>
Jon TURNEY2b9dac32010-04-21 12:58:54 +010050#endif
George Sapountzisdf04ffb2008-04-18 17:28:34 +030051#include "xf86dri.h"
Jeremy Huddleston80b280d2010-04-02 01:35:19 -070052#endif
Ian Romanick2b4e0092010-02-04 15:39:36 -080053#else
George Sapountzisdf04ffb2008-04-18 17:28:34 +030054#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +000055
RALOVICH, Kristóf9c7aaa72008-11-04 10:59:39 +010056#if defined(USE_XCB)
57#include <X11/Xlib-xcb.h>
58#include <xcb/xcb.h>
59#include <xcb/glx.h>
60#endif
61
Ian Romanick26d2ce02009-11-06 14:52:49 -080062static const char __glXGLXClientVendorName[] = "Mesa Project and SGI";
Adam Jacksoncb3610e2004-10-25 21:09:16 +000063static const char __glXGLXClientVersion[] = "1.4";
Kristian Høgsberg4a22ae82007-01-07 08:12:01 -050064
Jeremy Huddleston80b280d2010-04-02 01:35:19 -070065#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Kristian Høgsberg4a22ae82007-01-07 08:12:01 -050066
Adam Jacksoncb3610e2004-10-25 21:09:16 +000067/**
68 * Get the __DRIdrawable for the drawable associated with a GLXContext
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020069 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +000070 * \param dpy The display associated with \c drawable.
71 * \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved.
Kristian Høgsberg4a22ae82007-01-07 08:12:01 -050072 * \param scrn_num If non-NULL, the drawables screen is stored there
Adam Jacksoncb3610e2004-10-25 21:09:16 +000073 * \returns A pointer to the context's __DRIdrawable on success, or NULL if
74 * the drawable is not associated with a direct-rendering context.
75 */
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -040076_X_HIDDEN __GLXDRIdrawable *
Kristian Høgsbergeeaab202010-07-22 22:36:37 -040077GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable)
Adam Jacksoncb3610e2004-10-25 21:09:16 +000078{
Kristian Høgsbergc356f582010-07-28 11:16:00 -040079 struct glx_display *priv = __glXInitialize(dpy);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020080 __GLXDRIdrawable *pdraw;
Adam Jacksoncb3610e2004-10-25 21:09:16 +000081
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020082 if (priv == NULL)
83 return NULL;
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -040084
Kristian Høgsbergeeaab202010-07-22 22:36:37 -040085 if (__glxHashLookup(priv->drawHash, drawable, (void *) &pdraw) == 0)
Kristian Høgsberge3e81962010-07-19 21:15:50 -040086 return pdraw;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020087
88 return NULL;
Adam Jacksoncb3610e2004-10-25 21:09:16 +000089}
Kristian Høgsberg4a22ae82007-01-07 08:12:01 -050090
Adam Jacksoncb3610e2004-10-25 21:09:16 +000091#endif
92
Jesse Barnes4df13762011-05-06 10:31:24 -070093_X_HIDDEN struct glx_drawable *
94GetGLXDrawable(Display *dpy, GLXDrawable drawable)
95{
96 struct glx_display *priv = __glXInitialize(dpy);
97 struct glx_drawable *glxDraw;
98
99 if (priv == NULL)
100 return NULL;
101
102 if (__glxHashLookup(priv->glXDrawHash, drawable, (void *) &glxDraw) == 0)
103 return glxDraw;
104
105 return NULL;
106}
107
108_X_HIDDEN int
109InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, XID xDrawable,
110 GLXDrawable drawable)
111{
112 struct glx_display *priv = __glXInitialize(dpy);
113
114 if (!priv)
115 return -1;
116
117 glxDraw->xDrawable = xDrawable;
118 glxDraw->drawable = drawable;
119 glxDraw->lastEventSbc = 0;
120 glxDraw->eventSbcWrap = 0;
121
122 return __glxHashInsert(priv->glXDrawHash, drawable, glxDraw);
123}
124
125_X_HIDDEN void
126DestroyGLXDrawable(Display *dpy, GLXDrawable drawable)
127{
128 struct glx_display *priv = __glXInitialize(dpy);
129 struct glx_drawable *glxDraw;
130
131 if (!priv)
132 return;
133
134 glxDraw = GetGLXDrawable(dpy, drawable);
135 __glxHashDelete(priv->glXDrawHash, drawable);
136 free(glxDraw);
137}
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000138
139/**
140 * Get the GLX per-screen data structure associated with a GLX context.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200141 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000142 * \param dpy Display for which the GLX per-screen information is to be
143 * retrieved.
144 * \param scrn Screen on \c dpy for which the GLX per-screen information is
145 * to be retrieved.
146 * \returns A pointer to the GLX per-screen data if \c dpy and \c scrn
147 * specify a valid GLX screen, or NULL otherwise.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200148 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000149 * \todo Should this function validate that \c scrn is within the screen
150 * number range for \c dpy?
151 */
152
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400153static struct glx_screen *
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200154GetGLXScreenConfigs(Display * dpy, int scrn)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000155{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400156 struct glx_display *const priv = __glXInitialize(dpy);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000157
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200158 return (priv
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400159 && priv->screens !=
160 NULL) ? priv->screens[scrn] : NULL;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000161}
162
163
164static int
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400165GetGLXPrivScreenConfig(Display * dpy, int scrn, struct glx_display ** ppriv,
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400166 struct glx_screen ** ppsc)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000167{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200168 /* Initialize the extension, if needed . This has the added value
169 * of initializing/allocating the display private
170 */
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000171
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200172 if (dpy == NULL) {
173 return GLX_NO_EXTENSION;
174 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000175
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200176 *ppriv = __glXInitialize(dpy);
177 if (*ppriv == NULL) {
178 return GLX_NO_EXTENSION;
179 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000180
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200181 /* Check screen number to see if its valid */
182 if ((scrn < 0) || (scrn >= ScreenCount(dpy))) {
183 return GLX_BAD_SCREEN;
184 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000185
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200186 /* Check to see if the GL is supported on this screen */
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400187 *ppsc = (*ppriv)->screens[scrn];
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200188 if ((*ppsc)->configs == NULL) {
189 /* No support for GL on this screen regardless of visual */
190 return GLX_BAD_VISUAL;
191 }
192
193 return Success;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000194}
195
196
197/**
198 * Determine if a \c GLXFBConfig supplied by the application is valid.
199 *
200 * \param dpy Application supplied \c Display pointer.
201 * \param config Application supplied \c GLXFBConfig.
202 *
203 * \returns If the \c GLXFBConfig is valid, the a pointer to the matching
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400204 * \c struct glx_config structure is returned. Otherwise, \c NULL
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000205 * is returned.
206 */
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400207static struct glx_config *
208ValidateGLXFBConfig(Display * dpy, GLXFBConfig fbconfig)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000209{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400210 struct glx_display *const priv = __glXInitialize(dpy);
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400211 int num_screens = ScreenCount(dpy);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200212 unsigned i;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400213 struct glx_config *config;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000214
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200215 if (priv != NULL) {
216 for (i = 0; i < num_screens; i++) {
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400217 for (config = priv->screens[i]->configs; config != NULL;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400218 config = config->next) {
219 if (config == (struct glx_config *) fbconfig) {
220 return config;
221 }
222 }
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200223 }
224 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000225
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200226 return NULL;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000227}
228
Kristian Høgsberg31819832010-07-22 21:24:14 -0400229_X_HIDDEN Bool
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400230glx_context_init(struct glx_context *gc,
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400231 struct glx_screen *psc, struct glx_config *config)
Kristian Høgsberg31819832010-07-22 21:24:14 -0400232{
233 gc->majorOpcode = __glXSetupForCommand(psc->display->dpy);
234 if (!gc->majorOpcode)
235 return GL_FALSE;
236
237 gc->screen = psc->scr;
238 gc->psc = psc;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400239 gc->config = config;
Kristian Høgsberg31819832010-07-22 21:24:14 -0400240 gc->isDirect = GL_TRUE;
Kristian Høgsbergc491e582010-07-28 15:33:09 -0400241 gc->currentContextTag = -1;
Kristian Høgsberg31819832010-07-22 21:24:14 -0400242
243 return GL_TRUE;
244}
245
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000246
247/**
Adam Jackson3869be72011-04-29 16:30:50 -0400248 * Create a new context.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200249 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000250 * \param renderType For FBConfigs, what is the rendering type?
251 */
252
253static GLXContext
Adam Jackson3869be72011-04-29 16:30:50 -0400254CreateContext(Display *dpy, int generic_id, struct glx_config *config,
255 GLXContext shareList_user, Bool allowDirect,
Ian Romanick7bcfb662010-02-04 16:37:59 -0800256 unsigned code, int renderType, int screen)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000257{
nobledb5dc4072010-08-19 14:06:21 -0400258 struct glx_context *gc;
259 struct glx_screen *psc;
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400260 struct glx_context *shareList = (struct glx_context *) shareList_user;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200261 if (dpy == NULL)
262 return NULL;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000263
nobledb5dc4072010-08-19 14:06:21 -0400264 psc = GetGLXScreenConfigs(dpy, screen);
265 if (psc == NULL)
266 return NULL;
267
Ian Romanickd46d30f2010-02-04 17:06:18 -0800268 if (generic_id == None)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200269 return NULL;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000270
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -0400271 gc = NULL;
Jeremy Huddleston1885cf22011-06-05 18:50:55 -0400272#ifdef GLX_USE_APPLEGL
273 gc = applegl_create_context(psc, config, shareList, renderType);
274#else
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -0400275 if (allowDirect && psc->vtable->create_context)
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400276 gc = psc->vtable->create_context(psc, config, shareList, renderType);
Kristian Høgsberg31819832010-07-22 21:24:14 -0400277 if (!gc)
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400278 gc = indirect_create_context(psc, config, shareList, renderType);
Jeremy Huddleston1885cf22011-06-05 18:50:55 -0400279#endif
Kristian Høgsberg31819832010-07-22 21:24:14 -0400280 if (!gc)
281 return NULL;
Kristian Høgsberg643b2af2010-05-21 10:36:56 -0400282
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800283 LockDisplay(dpy);
284 switch (code) {
285 case X_GLXCreateContext: {
286 xGLXCreateContextReq *req;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000287
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800288 /* Send the glXCreateContext request */
289 GetReq(GLXCreateContext, req);
290 req->reqType = gc->majorOpcode;
291 req->glxCode = X_GLXCreateContext;
292 req->context = gc->xid = XAllocID(dpy);
Ian Romanickd46d30f2010-02-04 17:06:18 -0800293 req->visual = generic_id;
Ian Romanickc3db1d62010-02-04 17:01:42 -0800294 req->screen = screen;
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800295 req->shareList = shareList ? shareList->xid : None;
Kristian Høgsbergc491e582010-07-28 15:33:09 -0400296 req->isDirect = gc->isDirect;
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800297 break;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200298 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000299
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800300 case X_GLXCreateNewContext: {
301 xGLXCreateNewContextReq *req;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000302
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800303 /* Send the glXCreateNewContext request */
304 GetReq(GLXCreateNewContext, req);
305 req->reqType = gc->majorOpcode;
306 req->glxCode = X_GLXCreateNewContext;
307 req->context = gc->xid = XAllocID(dpy);
Ian Romanickd46d30f2010-02-04 17:06:18 -0800308 req->fbconfig = generic_id;
Ian Romanickc3db1d62010-02-04 17:01:42 -0800309 req->screen = screen;
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800310 req->renderType = renderType;
311 req->shareList = shareList ? shareList->xid : None;
Kristian Høgsbergc491e582010-07-28 15:33:09 -0400312 req->isDirect = gc->isDirect;
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800313 break;
314 }
Ian Romanick8bffadb2010-02-04 16:28:52 -0800315
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800316 case X_GLXvop_CreateContextWithConfigSGIX: {
317 xGLXVendorPrivateWithReplyReq *vpreq;
318 xGLXCreateContextWithConfigSGIXReq *req;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000319
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800320 /* Send the glXCreateNewContext request */
321 GetReqExtra(GLXVendorPrivateWithReply,
322 sz_xGLXCreateContextWithConfigSGIXReq -
323 sz_xGLXVendorPrivateWithReplyReq, vpreq);
324 req = (xGLXCreateContextWithConfigSGIXReq *) vpreq;
325 req->reqType = gc->majorOpcode;
326 req->glxCode = X_GLXVendorPrivateWithReply;
327 req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
328 req->context = gc->xid = XAllocID(dpy);
Ian Romanickd46d30f2010-02-04 17:06:18 -0800329 req->fbconfig = generic_id;
Ian Romanickc3db1d62010-02-04 17:01:42 -0800330 req->screen = screen;
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800331 req->renderType = renderType;
332 req->shareList = shareList ? shareList->xid : None;
Kristian Høgsbergc491e582010-07-28 15:33:09 -0400333 req->isDirect = gc->isDirect;
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800334 break;
335 }
Ian Romanick8bffadb2010-02-04 16:28:52 -0800336
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800337 default:
338 /* What to do here? This case is the sign of an internal error. It
339 * should never be reachable.
340 */
341 break;
342 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000343
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800344 UnlockDisplay(dpy);
345 SyncHandle();
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000346
Ian Romanickbc7b2f02010-02-04 16:46:46 -0800347 gc->imported = GL_FALSE;
Brian Paul521e4b92009-09-29 10:24:27 -0600348 gc->renderType = renderType;
349
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400350 return (GLXContext) gc;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000351}
352
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400353_X_EXPORT GLXContext
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200354glXCreateContext(Display * dpy, XVisualInfo * vis,
355 GLXContext shareList, Bool allowDirect)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000356{
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400357 struct glx_config *config = NULL;
Ian Romanick52cf8db2010-02-04 16:59:10 -0800358 int renderType = 0;
359
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700360#if defined(GLX_DIRECT_RENDERING) || defined(GLX_USE_APPLEGL)
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400361 struct glx_screen *const psc = GetGLXScreenConfigs(dpy, vis->screen);
Ian Romanick52cf8db2010-02-04 16:59:10 -0800362
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400363 config = glx_config_find_visual(psc->visuals, vis->visualid);
364 if (config == NULL) {
Ian Romanick52cf8db2010-02-04 16:59:10 -0800365 xError error;
366
367 error.errorCode = BadValue;
368 error.resourceID = vis->visualid;
369 error.sequenceNumber = dpy->request;
370 error.type = X_Error;
371 error.majorCode = __glXSetupForCommand(dpy);
372 error.minorCode = X_GLXCreateContext;
373 _XError(dpy, &error);
374 return None;
375 }
376
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400377 renderType = config->rgbMode ? GLX_RGBA_TYPE : GLX_COLOR_INDEX_TYPE;
Ian Romanick52cf8db2010-02-04 16:59:10 -0800378#endif
379
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400380 return CreateContext(dpy, vis->visualid, config, shareList, allowDirect,
Ian Romanick52cf8db2010-02-04 16:59:10 -0800381 X_GLXCreateContext, renderType, vis->screen);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000382}
383
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200384_X_HIDDEN void
Kristian Høgsbergc796bb02010-07-22 23:45:18 -0400385glx_send_destroy_context(Display *dpy, XID xid)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000386{
Kristian Høgsbergc796bb02010-07-22 23:45:18 -0400387 CARD8 opcode = __glXSetupForCommand(dpy);
388 xGLXDestroyContextReq *req;
389
390 LockDisplay(dpy);
391 GetReq(GLXDestroyContext, req);
392 req->reqType = opcode;
393 req->glxCode = X_GLXDestroyContext;
394 req->context = xid;
395 UnlockDisplay(dpy);
396 SyncHandle();
397}
398
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000399/*
400** Destroy the named context
401*/
Adam Jackson9e2bc5d2011-06-02 16:29:59 -0400402
403_X_EXPORT void
404glXDestroyContext(Display * dpy, GLXContext ctx)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000405{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400406 struct glx_context *gc = (struct glx_context *) ctx;
407
Kristian Høgsbergc796bb02010-07-22 23:45:18 -0400408 if (!gc)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200409 return;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000410
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200411 __glXLock();
Brian Paul5e6a6a22009-10-22 18:19:01 -0600412 if (gc->currentDpy) {
413 /* This context is bound to some thread. According to the man page,
414 * we should not actually delete the context until it's unbound.
415 * Note that we set gc->xid = None above. In MakeContextCurrent()
416 * we check for that and delete the context there.
417 */
Kristian Høgsbergd77bb8e2010-07-23 22:05:21 -0400418 if (!gc->imported)
419 glx_send_destroy_context(dpy, gc->xid);
Kristian Høgsbergc796bb02010-07-22 23:45:18 -0400420 gc->xid = None;
Brian Paul5e6a6a22009-10-22 18:19:01 -0600421 __glXUnlock();
422 return;
423 }
Kristian Høgsbergc796bb02010-07-22 23:45:18 -0400424 __glXUnlock();
Brian Paul5e6a6a22009-10-22 18:19:01 -0600425
Jeremy Huddleston816b8ac2011-06-13 12:13:44 -0700426 gc->vtable->destroy(gc);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000427}
Adam Jackson489ccef2004-12-15 17:18:06 +0000428
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000429/*
430** Return the major and minor version #s for the GLX extension
431*/
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400432_X_EXPORT Bool
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200433glXQueryVersion(Display * dpy, int *major, int *minor)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000434{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400435 struct glx_display *priv;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000436
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200437 /* Init the extension. This fetches the major and minor version. */
438 priv = __glXInitialize(dpy);
439 if (!priv)
440 return GL_FALSE;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000441
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200442 if (major)
443 *major = priv->majorVersion;
444 if (minor)
445 *minor = priv->minorVersion;
446 return GL_TRUE;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000447}
448
449/*
450** Query the existance of the GLX extension
451*/
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400452_X_EXPORT Bool
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200453glXQueryExtension(Display * dpy, int *errorBase, int *eventBase)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000454{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200455 int major_op, erb, evb;
456 Bool rv;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000457
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200458 rv = XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_op, &evb, &erb);
459 if (rv) {
460 if (errorBase)
461 *errorBase = erb;
462 if (eventBase)
463 *eventBase = evb;
464 }
465 return rv;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000466}
467
Kristian Høgsberg7b7845a2010-07-22 22:24:00 -0400468/*
469** Put a barrier in the token stream that forces the GL to finish its
470** work before X can proceed.
471*/
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400472_X_EXPORT void
Kristian Høgsberg7b7845a2010-07-22 22:24:00 -0400473glXWaitGL(void)
474{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400475 struct glx_context *gc = __glXGetCurrentContext();
Kristian Høgsberg7b7845a2010-07-22 22:24:00 -0400476
Kristian Høgsberg3ea3f5e2010-09-07 14:32:28 -0400477 if (gc && gc->vtable->wait_gl)
Kristian Høgsberg7b7845a2010-07-22 22:24:00 -0400478 gc->vtable->wait_gl(gc);
479}
480
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000481/*
482** Put a barrier in the token stream that forces X to finish its
483** work before GL can proceed.
484*/
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400485_X_EXPORT void
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200486glXWaitX(void)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000487{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400488 struct glx_context *gc = __glXGetCurrentContext();
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000489
Kristian Høgsberg3ea3f5e2010-09-07 14:32:28 -0400490 if (gc && gc->vtable->wait_x)
Kristian Høgsberg7b7845a2010-07-22 22:24:00 -0400491 gc->vtable->wait_x(gc);
492}
493
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400494_X_EXPORT void
Kristian Høgsberg7b7845a2010-07-22 22:24:00 -0400495glXUseXFont(Font font, int first, int count, int listBase)
496{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400497 struct glx_context *gc = __glXGetCurrentContext();
Kristian Høgsberg7b7845a2010-07-22 22:24:00 -0400498
Kristian Høgsberg3ea3f5e2010-09-07 14:32:28 -0400499 if (gc && gc->vtable->use_x_font)
Kristian Høgsberg7b7845a2010-07-22 22:24:00 -0400500 gc->vtable->use_x_font(gc, font, first, count, listBase);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000501}
502
503/************************************************************************/
504
505/*
506** Copy the source context to the destination context using the
507** attribute "mask".
508*/
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400509_X_EXPORT void
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400510glXCopyContext(Display * dpy, GLXContext source_user,
511 GLXContext dest_user, unsigned long mask)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000512{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400513 struct glx_context *source = (struct glx_context *) source_user;
514 struct glx_context *dest = (struct glx_context *) dest_user;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700515#ifdef GLX_USE_APPLEGL
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400516 struct glx_context *gc = __glXGetCurrentContext();
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700517 int errorcode;
518 bool x11error;
519
Jeremy Huddleston80b280d2010-04-02 01:35:19 -0700520 if(apple_glx_copy_context(gc->driContext, source->driContext, dest->driContext,
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700521 mask, &errorcode, &x11error)) {
522 __glXSendError(dpy, errorcode, 0, X_GLXCopyContext, x11error);
523 }
524
525#else
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200526 xGLXCopyContextReq *req;
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400527 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200528 GLXContextTag tag;
529 CARD8 opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000530
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200531 opcode = __glXSetupForCommand(dpy);
532 if (!opcode) {
533 return;
534 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000535
Jeremy Huddleston80b280d2010-04-02 01:35:19 -0700536#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Kristian Høgsbergc491e582010-07-28 15:33:09 -0400537 if (gc->isDirect) {
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200538 /* NOT_DONE: This does not work yet */
539 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000540#endif
541
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200542 /*
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000543 ** If the source is the current context, send its tag so that the context
544 ** can be flushed before the copy.
545 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200546 if (source == gc && dpy == gc->currentDpy) {
547 tag = gc->currentContextTag;
548 }
549 else {
550 tag = 0;
551 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000552
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200553 /* Send the glXCopyContext request */
554 LockDisplay(dpy);
555 GetReq(GLXCopyContext, req);
556 req->reqType = opcode;
557 req->glxCode = X_GLXCopyContext;
558 req->source = source ? source->xid : None;
559 req->dest = dest ? dest->xid : None;
560 req->mask = mask;
561 req->contextTag = tag;
562 UnlockDisplay(dpy);
563 SyncHandle();
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700564#endif /* GLX_USE_APPLEGL */
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000565}
566
567
568/**
569 * Determine if a context uses direct rendering.
570 *
571 * \param dpy Display where the context was created.
572 * \param contextID ID of the context to be tested.
573 *
574 * \returns \c GL_TRUE if the context is direct rendering or not.
575 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200576static Bool
577__glXIsDirect(Display * dpy, GLXContextID contextID)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000578{
RALOVICH, Kristóf9c7aaa72008-11-04 10:59:39 +0100579#if !defined(USE_XCB)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200580 xGLXIsDirectReq *req;
581 xGLXIsDirectReply reply;
RALOVICH, Kristóf9c7aaa72008-11-04 10:59:39 +0100582#endif
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200583 CARD8 opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000584
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200585 opcode = __glXSetupForCommand(dpy);
586 if (!opcode) {
587 return GL_FALSE;
588 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000589
RALOVICH, Kristóf9c7aaa72008-11-04 10:59:39 +0100590#ifdef USE_XCB
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200591 xcb_connection_t *c = XGetXCBConnection(dpy);
592 xcb_glx_is_direct_reply_t *reply = xcb_glx_is_direct_reply(c,
593 xcb_glx_is_direct
594 (c, contextID),
595 NULL);
RALOVICH, Kristóf9c7aaa72008-11-04 10:59:39 +0100596
Ian Romanick7c2f1162011-12-06 17:15:26 -0800597 const Bool is_direct = (reply != NULL && reply->is_direct) ? True : False;
RALOVICH, Kristóf9c7aaa72008-11-04 10:59:39 +0100598 free(reply);
599
600 return is_direct;
601#else
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200602 /* Send the glXIsDirect request */
603 LockDisplay(dpy);
604 GetReq(GLXIsDirect, req);
605 req->reqType = opcode;
606 req->glxCode = X_GLXIsDirect;
607 req->context = contextID;
608 _XReply(dpy, (xReply *) & reply, 0, False);
609 UnlockDisplay(dpy);
610 SyncHandle();
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000611
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200612 return reply.isDirect;
RALOVICH, Kristóf9c7aaa72008-11-04 10:59:39 +0100613#endif /* USE_XCB */
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000614}
615
Ian Romanickc39bf5e2005-07-24 06:29:14 +0000616/**
617 * \todo
618 * Shouldn't this function \b always return \c GL_FALSE when
619 * \c GLX_DIRECT_RENDERING is not defined? Do we really need to bother with
620 * the GLX protocol here at all?
621 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400622_X_EXPORT Bool
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400623glXIsDirect(Display * dpy, GLXContext gc_user)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000624{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400625 struct glx_context *gc = (struct glx_context *) gc_user;
626
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200627 if (!gc) {
628 return GL_FALSE;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200629 }
Kristian Høgsbergc491e582010-07-28 15:33:09 -0400630 else if (gc->isDirect) {
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200631 return GL_TRUE;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200632 }
Jeremy Huddlestona18702f2010-05-01 13:59:30 -0700633#ifdef GLX_USE_APPLEGL /* TODO: indirect on darwin */
634 return GL_FALSE;
635#else
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200636 return __glXIsDirect(dpy, gc->xid);
Jeremy Huddlestona18702f2010-05-01 13:59:30 -0700637#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000638}
639
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400640_X_EXPORT GLXPixmap
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200641glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000642{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700643#ifdef GLX_USE_APPLEGL
644 int screen = vis->screen;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400645 struct glx_screen *const psc = GetGLXScreenConfigs(dpy, screen);
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400646 const struct glx_config *config;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700647
Jeremy Huddlestonb7f0ed82011-06-05 18:19:59 -0400648 config = glx_config_find_visual(psc->visuals, vis->visualid);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700649
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400650 if(apple_glx_pixmap_create(dpy, vis->screen, pixmap, config))
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700651 return None;
652
653 return pixmap;
654#else
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200655 xGLXCreateGLXPixmapReq *req;
Jesse Barnes4df13762011-05-06 10:31:24 -0700656 struct glx_drawable *glxDraw;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200657 GLXPixmap xid;
658 CARD8 opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000659
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200660 opcode = __glXSetupForCommand(dpy);
661 if (!opcode) {
662 return None;
663 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000664
Jesse Barnes4df13762011-05-06 10:31:24 -0700665 glxDraw = Xmalloc(sizeof(*glxDraw));
666 if (!glxDraw)
667 return None;
668
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200669 /* Send the glXCreateGLXPixmap request */
670 LockDisplay(dpy);
671 GetReq(GLXCreateGLXPixmap, req);
672 req->reqType = opcode;
673 req->glxCode = X_GLXCreateGLXPixmap;
674 req->screen = vis->screen;
675 req->visual = vis->visualid;
676 req->pixmap = pixmap;
677 req->glxpixmap = xid = XAllocID(dpy);
678 UnlockDisplay(dpy);
679 SyncHandle();
Michel Dänzeredb11782009-08-30 12:43:37 +0200680
Jesse Barnes4df13762011-05-06 10:31:24 -0700681 if (InitGLXDrawable(dpy, glxDraw, pixmap, req->glxpixmap)) {
682 free(glxDraw);
683 return None;
684 }
685
Jeremy Huddleston80b280d2010-04-02 01:35:19 -0700686#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Michel Dänzer9053bb02009-08-30 13:06:18 +0200687 do {
688 /* FIXME: Maybe delay __DRIdrawable creation until the drawable
689 * is actually bound to a context... */
Michel Dänzeredb11782009-08-30 12:43:37 +0200690
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400691 struct glx_display *const priv = __glXInitialize(dpy);
Michel Dänzer9053bb02009-08-30 13:06:18 +0200692 __GLXDRIdrawable *pdraw;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400693 struct glx_screen *psc;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400694 struct glx_config *config;
Michel Dänzeredb11782009-08-30 12:43:37 +0200695
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400696 psc = priv->screens[vis->screen];
Michel Dänzer9053bb02009-08-30 13:06:18 +0200697 if (psc->driScreen == NULL)
Adam Jackson48331042011-03-31 20:43:57 +0000698 return xid;
699
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400700 config = glx_config_find_visual(psc->visuals, vis->visualid);
Adam Jackson776a2a52011-06-01 11:33:48 -0400701 pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config);
Michel Dänzer9053bb02009-08-30 13:06:18 +0200702 if (pdraw == NULL) {
703 fprintf(stderr, "failed to create pixmap\n");
Adam Jackson48331042011-03-31 20:43:57 +0000704 xid = None;
Michel Dänzer9053bb02009-08-30 13:06:18 +0200705 break;
706 }
Michel Dänzeredb11782009-08-30 12:43:37 +0200707
Adam Jackson776a2a52011-06-01 11:33:48 -0400708 if (__glxHashInsert(priv->drawHash, xid, pdraw)) {
Michel Dänzer9053bb02009-08-30 13:06:18 +0200709 (*pdraw->destroyDrawable) (pdraw);
Adam Jackson48331042011-03-31 20:43:57 +0000710 xid = None;
711 break;
Michel Dänzer9053bb02009-08-30 13:06:18 +0200712 }
713 } while (0);
Adam Jackson48331042011-03-31 20:43:57 +0000714
715 if (xid == None) {
716 xGLXDestroyGLXPixmapReq *dreq;
717 LockDisplay(dpy);
718 GetReq(GLXDestroyGLXPixmap, dreq);
719 dreq->reqType = opcode;
720 dreq->glxCode = X_GLXDestroyGLXPixmap;
721 dreq->glxpixmap = xid;
722 UnlockDisplay(dpy);
723 SyncHandle();
724 }
Michel Dänzeredb11782009-08-30 12:43:37 +0200725#endif
726
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200727 return xid;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700728#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000729}
730
731/*
732** Destroy the named pixmap
733*/
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400734_X_EXPORT void
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200735glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000736{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700737#ifdef GLX_USE_APPLEGL
738 if(apple_glx_pixmap_destroy(dpy, glxpixmap))
739 __glXSendError(dpy, GLXBadPixmap, glxpixmap, X_GLXDestroyPixmap, false);
740#else
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200741 xGLXDestroyGLXPixmapReq *req;
742 CARD8 opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000743
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200744 opcode = __glXSetupForCommand(dpy);
745 if (!opcode) {
746 return;
747 }
748
749 /* Send the glXDestroyGLXPixmap request */
750 LockDisplay(dpy);
751 GetReq(GLXDestroyGLXPixmap, req);
752 req->reqType = opcode;
753 req->glxCode = X_GLXDestroyGLXPixmap;
754 req->glxpixmap = glxpixmap;
755 UnlockDisplay(dpy);
756 SyncHandle();
Michel Dänzer9dfce362009-06-19 11:19:07 +0200757
Jesse Barnes4df13762011-05-06 10:31:24 -0700758 DestroyGLXDrawable(dpy, glxpixmap);
759
Jeremy Huddleston80b280d2010-04-02 01:35:19 -0700760#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200761 {
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400762 struct glx_display *const priv = __glXInitialize(dpy);
Kristian Høgsbergeeaab202010-07-22 22:36:37 -0400763 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap);
Michel Dänzer9dfce362009-06-19 11:19:07 +0200764
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200765 if (pdraw != NULL) {
766 (*pdraw->destroyDrawable) (pdraw);
Kristian Høgsberge3e81962010-07-19 21:15:50 -0400767 __glxHashDelete(priv->drawHash, glxpixmap);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200768 }
769 }
Michel Dänzer9dfce362009-06-19 11:19:07 +0200770#endif
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700771#endif /* GLX_USE_APPLEGL */
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000772}
773
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400774_X_EXPORT void
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200775glXSwapBuffers(Display * dpy, GLXDrawable drawable)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000776{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700777#ifdef GLX_USE_APPLEGL
Jeremy Huddleston279e4712011-06-05 18:22:47 -0400778 struct glx_context * gc = __glXGetCurrentContext();
Jeremy Huddleston80b280d2010-04-02 01:35:19 -0700779 if(gc && apple_glx_is_current_drawable(dpy, gc->driContext, drawable)) {
780 apple_glx_swap_buffers(gc->driContext);
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700781 } else {
782 __glXSendError(dpy, GLXBadCurrentWindow, 0, X_GLXSwapBuffers, false);
783 }
784#else
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400785 struct glx_context *gc;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200786 GLXContextTag tag;
787 CARD8 opcode;
Brian Paulb7f802e2009-01-18 09:59:07 -0700788#ifdef USE_XCB
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200789 xcb_connection_t *c;
Brian Paulb7f802e2009-01-18 09:59:07 -0700790#else
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200791 xGLXSwapBuffersReq *req;
Brian Paulb7f802e2009-01-18 09:59:07 -0700792#endif
793
Eric Anholt4d01bea2011-02-14 18:38:33 -0800794 gc = __glXGetCurrentContext();
795
Jeremy Huddleston80b280d2010-04-02 01:35:19 -0700796#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Brian Paule975e182011-08-19 08:36:22 -0600797 {
798 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000799
Brian Paule975e182011-08-19 08:36:22 -0600800 if (pdraw != NULL) {
801 if (gc && drawable == gc->currentDrawable) {
802 glFlush();
803 }
804
805 (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0);
806 return;
Eric Anholt4d01bea2011-02-14 18:38:33 -0800807 }
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200808 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000809#endif
810
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200811 opcode = __glXSetupForCommand(dpy);
812 if (!opcode) {
813 return;
814 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000815
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200816 /*
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000817 ** The calling thread may or may not have a current context. If it
818 ** does, send the context tag so the server can do a flush.
819 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200820 if ((gc != NULL) && (dpy == gc->currentDpy) &&
821 ((drawable == gc->currentDrawable)
822 || (drawable == gc->currentReadable))) {
823 tag = gc->currentContextTag;
824 }
825 else {
826 tag = 0;
827 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000828
RALOVICH, Kristófff3fa922008-11-04 17:30:21 +0100829#ifdef USE_XCB
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200830 c = XGetXCBConnection(dpy);
831 xcb_glx_swap_buffers(c, tag, drawable);
832 xcb_flush(c);
RALOVICH, Kristófff3fa922008-11-04 17:30:21 +0100833#else
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200834 /* Send the glXSwapBuffers request */
835 LockDisplay(dpy);
836 GetReq(GLXSwapBuffers, req);
837 req->reqType = opcode;
838 req->glxCode = X_GLXSwapBuffers;
839 req->drawable = drawable;
840 req->contextTag = tag;
841 UnlockDisplay(dpy);
842 SyncHandle();
843 XFlush(dpy);
RALOVICH, Kristófff3fa922008-11-04 17:30:21 +0100844#endif /* USE_XCB */
Jeremy Huddlestonad503c42010-04-01 11:01:31 -0700845#endif /* GLX_USE_APPLEGL */
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000846}
847
848
849/*
850** Return configuration information for the given display, screen and
851** visual combination.
852*/
Kristian Høgsberg38c51a72010-07-28 10:20:41 -0400853_X_EXPORT int
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200854glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute,
855 int *value_return)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000856{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400857 struct glx_display *priv;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -0400858 struct glx_screen *psc;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400859 struct glx_config *config;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200860 int status;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000861
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200862 status = GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc);
863 if (status == Success) {
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400864 config = glx_config_find_visual(psc->visuals, vis->visualid);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000865
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200866 /* Lookup attribute after first finding a match on the visual */
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400867 if (config != NULL) {
868 return glx_config_get(config, attribute, value_return);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200869 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000870
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200871 status = GLX_BAD_VISUAL;
872 }
873
874 /*
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000875 ** If we can't find the config for this visual, this visual is not
876 ** supported by the OpenGL implementation on the server.
877 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200878 if ((status == GLX_BAD_VISUAL) && (attribute == GLX_USE_GL)) {
879 *value_return = GL_FALSE;
880 status = Success;
881 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000882
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200883 return status;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000884}
885
886/************************************************************************/
887
888static void
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400889init_fbconfig_for_chooser(struct glx_config * config,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200890 GLboolean fbconfig_style_tags)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000891{
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400892 memset(config, 0, sizeof(struct glx_config));
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200893 config->visualID = (XID) GLX_DONT_CARE;
894 config->visualType = GLX_DONT_CARE;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000895
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200896 /* glXChooseFBConfig specifies different defaults for these two than
897 * glXChooseVisual.
898 */
899 if (fbconfig_style_tags) {
900 config->rgbMode = GL_TRUE;
901 config->doubleBufferMode = GLX_DONT_CARE;
902 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000903
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200904 config->visualRating = GLX_DONT_CARE;
905 config->transparentPixel = GLX_NONE;
906 config->transparentRed = GLX_DONT_CARE;
907 config->transparentGreen = GLX_DONT_CARE;
908 config->transparentBlue = GLX_DONT_CARE;
909 config->transparentAlpha = GLX_DONT_CARE;
910 config->transparentIndex = GLX_DONT_CARE;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000911
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200912 config->drawableType = GLX_WINDOW_BIT;
913 config->renderType =
914 (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
915 config->xRenderable = GLX_DONT_CARE;
916 config->fbconfigID = (GLXFBConfigID) (GLX_DONT_CARE);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000917
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200918 config->swapMethod = GLX_DONT_CARE;
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000919}
920
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200921#define MATCH_DONT_CARE( param ) \
922 do { \
Ian Romanick71a6fb12010-02-04 15:59:51 -0800923 if ( ((int) a-> param != (int) GLX_DONT_CARE) \
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200924 && (a-> param != b-> param) ) { \
925 return False; \
926 } \
927 } while ( 0 )
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000928
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200929#define MATCH_MINIMUM( param ) \
930 do { \
Ian Romanick71a6fb12010-02-04 15:59:51 -0800931 if ( ((int) a-> param != (int) GLX_DONT_CARE) \
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200932 && (a-> param > b-> param) ) { \
933 return False; \
934 } \
935 } while ( 0 )
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000936
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200937#define MATCH_EXACT( param ) \
938 do { \
939 if ( a-> param != b-> param) { \
940 return False; \
941 } \
942 } while ( 0 )
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000943
Kristian Høgsbergedb52532010-04-08 22:09:11 -0400944/* Test that all bits from a are contained in b */
945#define MATCH_MASK(param) \
946 do { \
947 if ((a->param & ~b->param) != 0) \
948 return False; \
949 } while (0);
950
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000951/**
952 * Determine if two GLXFBConfigs are compatible.
953 *
954 * \param a Application specified config to test.
955 * \param b Server specified config to test against \c a.
956 */
957static Bool
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -0400958fbconfigs_compatible(const struct glx_config * const a,
959 const struct glx_config * const b)
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000960{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200961 MATCH_DONT_CARE(doubleBufferMode);
962 MATCH_DONT_CARE(visualType);
963 MATCH_DONT_CARE(visualRating);
964 MATCH_DONT_CARE(xRenderable);
965 MATCH_DONT_CARE(fbconfigID);
966 MATCH_DONT_CARE(swapMethod);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000967
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200968 MATCH_MINIMUM(rgbBits);
969 MATCH_MINIMUM(numAuxBuffers);
970 MATCH_MINIMUM(redBits);
971 MATCH_MINIMUM(greenBits);
972 MATCH_MINIMUM(blueBits);
973 MATCH_MINIMUM(alphaBits);
974 MATCH_MINIMUM(depthBits);
975 MATCH_MINIMUM(stencilBits);
976 MATCH_MINIMUM(accumRedBits);
977 MATCH_MINIMUM(accumGreenBits);
978 MATCH_MINIMUM(accumBlueBits);
979 MATCH_MINIMUM(accumAlphaBits);
980 MATCH_MINIMUM(sampleBuffers);
981 MATCH_MINIMUM(maxPbufferWidth);
982 MATCH_MINIMUM(maxPbufferHeight);
983 MATCH_MINIMUM(maxPbufferPixels);
984 MATCH_MINIMUM(samples);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000985
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200986 MATCH_DONT_CARE(stereoMode);
987 MATCH_EXACT(level);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000988
Kristian Høgsbergedb52532010-04-08 22:09:11 -0400989 MATCH_MASK(drawableType);
990 MATCH_MASK(renderType);
Adam Jacksoncb3610e2004-10-25 21:09:16 +0000991
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200992 /* There is a bug in a few of the XFree86 DDX drivers. They contain
993 * visuals with a "transparent type" of 0 when they really mean GLX_NONE.
994 * Technically speaking, it is a bug in the DDX driver, but there is
995 * enough of an installed base to work around the problem here. In any
996 * case, 0 is not a valid value of the transparent type, so we'll treat 0
997 * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and
998 * 0 from the server to be a match to maintain backward compatibility with
999 * the (broken) drivers.
1000 */
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001001
Ian Romanick71a6fb12010-02-04 15:59:51 -08001002 if (a->transparentPixel != (int) GLX_DONT_CARE && a->transparentPixel != 0) {
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001003 if (a->transparentPixel == GLX_NONE) {
1004 if (b->transparentPixel != GLX_NONE && b->transparentPixel != 0)
1005 return False;
1006 }
1007 else {
1008 MATCH_EXACT(transparentPixel);
1009 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001010
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001011 switch (a->transparentPixel) {
1012 case GLX_TRANSPARENT_RGB:
1013 MATCH_DONT_CARE(transparentRed);
1014 MATCH_DONT_CARE(transparentGreen);
1015 MATCH_DONT_CARE(transparentBlue);
1016 MATCH_DONT_CARE(transparentAlpha);
1017 break;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001018
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001019 case GLX_TRANSPARENT_INDEX:
1020 MATCH_DONT_CARE(transparentIndex);
1021 break;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001022
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001023 default:
1024 break;
1025 }
1026 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001027
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001028 return True;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001029}
1030
1031
1032/* There's some trickly language in the GLX spec about how this is supposed
1033 * to work. Basically, if a given component size is either not specified
1034 * or the requested size is zero, it is supposed to act like PERFER_SMALLER.
1035 * Well, that's really hard to do with the code as-is. This behavior is
1036 * closer to correct, but still not technically right.
1037 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001038#define PREFER_LARGER_OR_ZERO(comp) \
1039 do { \
1040 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1041 if ( ((*a)-> comp) == 0 ) { \
1042 return -1; \
1043 } \
1044 else if ( ((*b)-> comp) == 0 ) { \
1045 return 1; \
1046 } \
1047 else { \
1048 return ((*b)-> comp) - ((*a)-> comp) ; \
1049 } \
1050 } \
1051 } while( 0 )
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001052
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001053#define PREFER_LARGER(comp) \
1054 do { \
1055 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1056 return ((*b)-> comp) - ((*a)-> comp) ; \
1057 } \
1058 } while( 0 )
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001059
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001060#define PREFER_SMALLER(comp) \
1061 do { \
1062 if ( ((*a)-> comp) != ((*b)-> comp) ) { \
1063 return ((*a)-> comp) - ((*b)-> comp) ; \
1064 } \
1065 } while( 0 )
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001066
1067/**
1068 * Compare two GLXFBConfigs. This function is intended to be used as the
1069 * compare function passed in to qsort.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001070 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001071 * \returns If \c a is a "better" config, according to the specification of
1072 * SGIX_fbconfig, a number less than zero is returned. If \c b is
1073 * better, then a number greater than zero is return. If both are
1074 * equal, zero is returned.
1075 * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1076 */
1077static int
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001078fbconfig_compare(struct glx_config **a, struct glx_config **b)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001079{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001080 /* The order of these comparisons must NOT change. It is defined by
1081 * the GLX 1.3 spec and ARB_multisample.
1082 */
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001083
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001084 PREFER_SMALLER(visualSelectGroup);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001085
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001086 /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and
1087 * GLX_NON_CONFORMANT_CONFIG. It just so happens that this is the
1088 * numerical sort order of the enums (0x8000, 0x8001, and 0x800D).
1089 */
1090 PREFER_SMALLER(visualRating);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001091
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001092 /* This isn't quite right. It is supposed to compare the sum of the
1093 * components the user specifically set minimums for.
1094 */
1095 PREFER_LARGER_OR_ZERO(redBits);
1096 PREFER_LARGER_OR_ZERO(greenBits);
1097 PREFER_LARGER_OR_ZERO(blueBits);
1098 PREFER_LARGER_OR_ZERO(alphaBits);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001099
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001100 PREFER_SMALLER(rgbBits);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001101
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001102 if (((*a)->doubleBufferMode != (*b)->doubleBufferMode)) {
1103 /* Prefer single-buffer.
1104 */
1105 return (!(*a)->doubleBufferMode) ? -1 : 1;
1106 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001107
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001108 PREFER_SMALLER(numAuxBuffers);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001109
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001110 PREFER_LARGER_OR_ZERO(depthBits);
1111 PREFER_SMALLER(stencilBits);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001112
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001113 /* This isn't quite right. It is supposed to compare the sum of the
1114 * components the user specifically set minimums for.
1115 */
1116 PREFER_LARGER_OR_ZERO(accumRedBits);
1117 PREFER_LARGER_OR_ZERO(accumGreenBits);
1118 PREFER_LARGER_OR_ZERO(accumBlueBits);
1119 PREFER_LARGER_OR_ZERO(accumAlphaBits);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001120
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001121 PREFER_SMALLER(visualType);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001122
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001123 /* None of the multisample specs say where this comparison should happen,
1124 * so I put it near the end.
1125 */
1126 PREFER_SMALLER(sampleBuffers);
1127 PREFER_SMALLER(samples);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001128
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001129 /* None of the pbuffer or fbconfig specs say that this comparison needs
1130 * to happen at all, but it seems like it should.
1131 */
1132 PREFER_LARGER(maxPbufferWidth);
1133 PREFER_LARGER(maxPbufferHeight);
1134 PREFER_LARGER(maxPbufferPixels);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001135
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001136 return 0;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001137}
1138
1139
1140/**
1141 * Selects and sorts a subset of the supplied configs based on the attributes.
1142 * This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig,
1143 * and \c glXChooseFBConfigSGIX.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001144 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001145 * \param configs Array of pointers to possible configs. The elements of
1146 * this array that do not meet the criteria will be set to
1147 * NULL. The remaining elements will be sorted according to
1148 * the various visual / FBConfig selection rules.
1149 * \param num_configs Number of elements in the \c configs array.
1150 * \param attribList Attributes used select from \c configs. This array is
1151 * terminated by a \c None tag. The array can either take
1152 * the form expected by \c glXChooseVisual (where boolean
1153 * tags do not have a value) or by \c glXChooseFBConfig
1154 * (where every tag has a value).
1155 * \param fbconfig_style_tags Selects whether \c attribList is in
1156 * \c glXChooseVisual style or
1157 * \c glXChooseFBConfig style.
1158 * \returns The number of valid elements left in \c configs.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001159 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001160 * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
1161 */
1162static int
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001163choose_visual(struct glx_config ** configs, int num_configs,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001164 const int *attribList, GLboolean fbconfig_style_tags)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001165{
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001166 struct glx_config test_config;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001167 int base;
1168 int i;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001169
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001170 /* This is a fairly direct implementation of the selection method
1171 * described by GLX_SGIX_fbconfig. Start by culling out all the
1172 * configs that are not compatible with the selected parameter
1173 * list.
1174 */
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001175
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001176 init_fbconfig_for_chooser(&test_config, fbconfig_style_tags);
1177 __glXInitializeVisualConfigFromTags(&test_config, 512,
1178 (const INT32 *) attribList,
1179 GL_TRUE, fbconfig_style_tags);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001180
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001181 base = 0;
1182 for (i = 0; i < num_configs; i++) {
1183 if (fbconfigs_compatible(&test_config, configs[i])) {
1184 configs[base] = configs[i];
1185 base++;
1186 }
1187 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001188
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001189 if (base == 0) {
1190 return 0;
1191 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001192
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001193 if (base < num_configs) {
1194 (void) memset(&configs[base], 0, sizeof(void *) * (num_configs - base));
1195 }
1196
1197 /* After the incompatible configs are removed, the resulting
1198 * list is sorted according to the rules set out in the various
1199 * specifications.
1200 */
1201
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001202 qsort(configs, base, sizeof(struct glx_config *),
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001203 (int (*)(const void *, const void *)) fbconfig_compare);
1204 return base;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001205}
1206
1207
1208
1209
1210/*
1211** Return the visual that best matches the template. Return None if no
1212** visual matches the template.
1213*/
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001214_X_EXPORT XVisualInfo *
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001215glXChooseVisual(Display * dpy, int screen, int *attribList)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001216{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001217 XVisualInfo *visualList = NULL;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001218 struct glx_display *priv;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001219 struct glx_screen *psc;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001220 struct glx_config test_config;
1221 struct glx_config *config;
1222 struct glx_config *best_config = NULL;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001223
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001224 /*
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001225 ** Get a list of all visuals, return if list is empty
1226 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001227 if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
1228 return None;
1229 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001230
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001231
1232 /*
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001233 ** Build a template from the defaults and the attribute list
1234 ** Free visual list and return if an unexpected token is encountered
1235 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001236 init_fbconfig_for_chooser(&test_config, GL_FALSE);
1237 __glXInitializeVisualConfigFromTags(&test_config, 512,
1238 (const INT32 *) attribList,
1239 GL_TRUE, GL_FALSE);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001240
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001241 /*
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001242 ** Eliminate visuals that don't meet minimum requirements
1243 ** Compute a score for those that do
1244 ** Remember which visual, if any, got the highest score
Michel Dänzer46b81b02009-05-12 08:01:22 +02001245 ** If no visual is acceptable, return None
1246 ** Otherwise, create an XVisualInfo list with just the selected X visual
1247 ** and return this.
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001248 */
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001249 for (config = psc->visuals; config != NULL; config = config->next) {
1250 if (fbconfigs_compatible(&test_config, config)
1251 && ((best_config == NULL) ||
1252 (fbconfig_compare (&config, &best_config) < 0))) {
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001253 XVisualInfo visualTemplate;
1254 XVisualInfo *newList;
1255 int i;
Michel Dänzer46b81b02009-05-12 08:01:22 +02001256
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001257 visualTemplate.screen = screen;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001258 visualTemplate.visualid = config->visualID;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001259 newList = XGetVisualInfo(dpy, VisualScreenMask | VisualIDMask,
1260 &visualTemplate, &i);
Michel Dänzer46b81b02009-05-12 08:01:22 +02001261
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001262 if (newList) {
1263 Xfree(visualList);
1264 visualList = newList;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001265 best_config = config;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001266 }
1267 }
1268 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001269
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001270#ifdef GLX_USE_APPLEGL
1271 if(visualList && getenv("LIBGL_DUMP_VISUALID")) {
1272 printf("visualid 0x%lx\n", visualList[0].visualid);
1273 }
1274#endif
1275
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001276 return visualList;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001277}
1278
1279
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001280_X_EXPORT const char *
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001281glXQueryExtensionsString(Display * dpy, int screen)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001282{
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001283 struct glx_screen *psc;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001284 struct glx_display *priv;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001285
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001286 if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
1287 return NULL;
1288 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001289
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001290 if (!psc->effectiveGLXexts) {
1291 if (!psc->serverGLXexts) {
1292 psc->serverGLXexts =
1293 __glXQueryServerString(dpy, priv->majorOpcode, screen,
1294 GLX_EXTENSIONS);
1295 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001296
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001297 __glXCalculateUsableExtensions(psc,
Jeremy Huddleston80b280d2010-04-02 01:35:19 -07001298#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001299 (psc->driScreen != NULL),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001300#else
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001301 GL_FALSE,
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001302#endif
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001303 priv->minorVersion);
1304 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001305
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001306 return psc->effectiveGLXexts;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001307}
1308
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001309_X_EXPORT const char *
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001310glXGetClientString(Display * dpy, int name)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001311{
Ian Romanick26b2bee2010-02-04 15:47:54 -08001312 (void) dpy;
1313
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001314 switch (name) {
1315 case GLX_VENDOR:
1316 return (__glXGLXClientVendorName);
1317 case GLX_VERSION:
1318 return (__glXGLXClientVersion);
1319 case GLX_EXTENSIONS:
1320 return (__glXGetClientExtensions());
1321 default:
1322 return NULL;
1323 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001324}
1325
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001326_X_EXPORT const char *
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001327glXQueryServerString(Display * dpy, int screen, int name)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001328{
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001329 struct glx_screen *psc;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001330 struct glx_display *priv;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001331 const char **str;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001332
1333
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001334 if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
1335 return NULL;
1336 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001337
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001338 switch (name) {
1339 case GLX_VENDOR:
1340 str = &priv->serverGLXvendor;
1341 break;
1342 case GLX_VERSION:
1343 str = &priv->serverGLXversion;
1344 break;
1345 case GLX_EXTENSIONS:
1346 str = &psc->serverGLXexts;
1347 break;
1348 default:
1349 return NULL;
1350 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001351
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001352 if (*str == NULL) {
1353 *str = __glXQueryServerString(dpy, priv->majorOpcode, screen, name);
1354 }
1355
1356 return *str;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001357}
1358
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001359void
1360__glXClientInfo(Display * dpy, int opcode)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001361{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001362 char *ext_str = __glXGetClientGLExtensionString();
1363 int size = strlen(ext_str) + 1;
RALOVICH, Kristóf66db1b62008-11-04 12:41:55 +01001364
1365#ifdef USE_XCB
1366 xcb_connection_t *c = XGetXCBConnection(dpy);
1367 xcb_glx_client_info(c,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001368 GLX_MAJOR_VERSION, GLX_MINOR_VERSION, size, ext_str);
RALOVICH, Kristóf66db1b62008-11-04 12:41:55 +01001369#else
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001370 xGLXClientInfoReq *req;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001371
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001372 /* Send the glXClientInfo request */
1373 LockDisplay(dpy);
1374 GetReq(GLXClientInfo, req);
1375 req->reqType = opcode;
1376 req->glxCode = X_GLXClientInfo;
1377 req->major = GLX_MAJOR_VERSION;
1378 req->minor = GLX_MINOR_VERSION;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001379
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001380 req->length += (size + 3) >> 2;
1381 req->numbytes = size;
1382 Data(dpy, ext_str, size);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001383
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001384 UnlockDisplay(dpy);
1385 SyncHandle();
RALOVICH, Kristóf66db1b62008-11-04 12:41:55 +01001386#endif /* USE_XCB */
1387
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001388 Xfree(ext_str);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001389}
1390
1391
1392/*
1393** EXT_import_context
1394*/
1395
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001396_X_EXPORT Display *
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001397glXGetCurrentDisplay(void)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001398{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001399 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001400 if (NULL == gc)
1401 return NULL;
1402 return gc->currentDpy;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001403}
1404
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001405_X_EXPORT
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001406GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
1407 glXGetCurrentDisplay)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001408
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001409#ifndef GLX_USE_APPLEGL
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001410_X_EXPORT GLXContext
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001411glXImportContextEXT(Display *dpy, GLXContextID contextID)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001412{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001413 struct glx_display *priv = __glXInitialize(dpy);
Ian Romanick5a849e82011-12-07 11:15:14 -08001414 struct glx_screen *psc = NULL;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001415 xGLXQueryContextReply reply;
1416 CARD8 opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001417 struct glx_context *ctx;
Ian Romanick5a849e82011-12-07 11:15:14 -08001418
1419 /* This GLX implementation knows about 5 different properties, so
1420 * allow the server to send us one of each.
1421 */
1422 int propList[5 * 2], *pProp, nPropListBytes;
1423 int numProps;
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001424 int i, renderType;
1425 XID share;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001426 struct glx_config *mode;
Ian Romanick5a849e82011-12-07 11:15:14 -08001427 uint32_t fbconfigID = 0;
1428 uint32_t visualID = 0;
1429 uint32_t screen;
1430 Bool got_screen = False;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001431
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001432 if (contextID == None || __glXIsDirect(dpy, contextID))
1433 return NULL;
1434
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001435 opcode = __glXSetupForCommand(dpy);
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001436 if (!opcode)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001437 return 0;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001438
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001439 /* Send the glXQueryContextInfoEXT request */
1440 LockDisplay(dpy);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001441
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001442 if (priv->majorVersion > 1 || priv->minorVersion >= 3) {
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001443 xGLXQueryContextReq *req;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001444
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001445 GetReq(GLXQueryContext, req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001446
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001447 req->reqType = opcode;
1448 req->glxCode = X_GLXQueryContext;
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001449 req->context = contextID;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001450 }
1451 else {
1452 xGLXVendorPrivateReq *vpreq;
1453 xGLXQueryContextInfoEXTReq *req;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001454
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001455 GetReqExtra(GLXVendorPrivate,
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001456 sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
1457 vpreq);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001458 req = (xGLXQueryContextInfoEXTReq *) vpreq;
1459 req->reqType = opcode;
1460 req->glxCode = X_GLXVendorPrivateWithReply;
1461 req->vendorCode = X_GLXvop_QueryContextInfoEXT;
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001462 req->context = contextID;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001463 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001464
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001465 _XReply(dpy, (xReply *) & reply, 0, False);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001466
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001467 if (reply.n <= __GLX_MAX_CONTEXT_PROPS)
1468 nPropListBytes = reply.n * 2 * sizeof propList[0];
1469 else
1470 nPropListBytes = 0;
1471 _XRead(dpy, (char *) propList, nPropListBytes);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001472 UnlockDisplay(dpy);
1473 SyncHandle();
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001474
Ian Romanick5a849e82011-12-07 11:15:14 -08001475 numProps = nPropListBytes / (2 * sizeof(propList[0]));
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001476 share = None;
1477 mode = NULL;
1478 renderType = 0;
1479 pProp = propList;
1480
Ian Romanick5a849e82011-12-07 11:15:14 -08001481 for (i = 0, pProp = propList; i < numProps; i++, pProp += 2)
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001482 switch (pProp[0]) {
Ian Romanick5a849e82011-12-07 11:15:14 -08001483 case GLX_SCREEN:
1484 screen = pProp[1];
1485 got_screen = True;
1486 break;
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001487 case GLX_SHARE_CONTEXT_EXT:
1488 share = pProp[1];
1489 break;
1490 case GLX_VISUAL_ID_EXT:
Ian Romanick5a849e82011-12-07 11:15:14 -08001491 visualID = pProp[1];
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001492 break;
1493 case GLX_FBCONFIG_ID:
Ian Romanick5a849e82011-12-07 11:15:14 -08001494 fbconfigID = pProp[1];
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001495 break;
1496 case GLX_RENDER_TYPE:
1497 renderType = pProp[1];
1498 break;
1499 }
1500
Ian Romanick5a849e82011-12-07 11:15:14 -08001501 if (!got_screen)
1502 return NULL;
1503
1504 psc = GetGLXScreenConfigs(dpy, screen);
1505 if (psc == NULL)
1506 return NULL;
1507
1508 if (fbconfigID != 0) {
1509 mode = glx_config_find_fbconfig(psc->configs, fbconfigID);
1510 } else if (visualID != 0) {
1511 mode = glx_config_find_visual(psc->visuals, visualID);
1512 }
1513
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001514 if (mode == NULL)
1515 return NULL;
1516
1517 ctx = indirect_create_context(psc, mode, NULL, renderType);
1518 if (ctx == NULL)
1519 return NULL;
1520
1521 ctx->xid = contextID;
1522 ctx->imported = GL_TRUE;
1523 ctx->share_xid = share;
1524
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001525 return (GLXContext) ctx;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001526}
1527
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001528#endif
1529
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001530_X_EXPORT int
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001531glXQueryContext(Display * dpy, GLXContext ctx_user, int attribute, int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001532{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001533 struct glx_context *ctx = (struct glx_context *) ctx_user;
1534
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001535 switch (attribute) {
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001536 case GLX_SHARE_CONTEXT_EXT:
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001537 *value = ctx->share_xid;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001538 break;
1539 case GLX_VISUAL_ID_EXT:
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001540 *value = ctx->config ? ctx->config->visualID : None;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001541 break;
1542 case GLX_SCREEN:
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001543 *value = ctx->screen;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001544 break;
1545 case GLX_FBCONFIG_ID:
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001546 *value = ctx->config ? ctx->config->fbconfigID : None;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001547 break;
1548 case GLX_RENDER_TYPE:
Kristian Høgsberg6ec39db2010-07-23 16:15:31 -04001549 *value = ctx->renderType;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001550 break;
1551 default:
1552 return GLX_BAD_ATTRIBUTE;
1553 }
1554 return Success;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001555}
1556
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001557_X_EXPORT
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001558GLX_ALIAS(int, glXQueryContextInfoEXT,
1559 (Display * dpy, GLXContext ctx, int attribute, int *value),
1560 (dpy, ctx, attribute, value), glXQueryContext)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001561
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001562_X_EXPORT GLXContextID glXGetContextIDEXT(const GLXContext ctx_user)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001563{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001564 struct glx_context *ctx = (struct glx_context *) ctx_user;
1565
Ian Romanick3b9b4222011-12-07 11:37:01 -08001566 return (ctx == NULL) ? None : ctx->xid;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001567}
1568
Adam Jackson9e2bc5d2011-06-02 16:29:59 -04001569_X_EXPORT
1570GLX_ALIAS_VOID(glXFreeContextEXT, (Display *dpy, GLXContext ctx), (dpy, ctx),
1571 glXDestroyContext);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001572
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001573_X_EXPORT GLXFBConfig *
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001574glXChooseFBConfig(Display * dpy, int screen,
1575 const int *attribList, int *nitems)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001576{
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001577 struct glx_config **config_list;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001578 int list_size;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001579
1580
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001581 config_list = (struct glx_config **)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001582 glXGetFBConfigs(dpy, screen, &list_size);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001583
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001584 if ((config_list != NULL) && (list_size > 0) && (attribList != NULL)) {
1585 list_size = choose_visual(config_list, list_size, attribList, GL_TRUE);
1586 if (list_size == 0) {
1587 XFree(config_list);
1588 config_list = NULL;
1589 }
1590 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001591
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001592 *nitems = list_size;
1593 return (GLXFBConfig *) config_list;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001594}
1595
1596
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001597_X_EXPORT GLXContext
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001598glXCreateNewContext(Display * dpy, GLXFBConfig fbconfig,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001599 int renderType, GLXContext shareList, Bool allowDirect)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001600{
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001601 struct glx_config *config = (struct glx_config *) fbconfig;
Ian Romanick7bcfb662010-02-04 16:37:59 -08001602
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001603 return CreateContext(dpy, config->fbconfigID, config, shareList,
1604 allowDirect, X_GLXCreateNewContext, renderType,
1605 config->screen);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001606}
1607
1608
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001609_X_EXPORT GLXDrawable
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001610glXGetCurrentReadDrawable(void)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001611{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001612 struct glx_context *gc = __glXGetCurrentContext();
1613
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001614 return gc->currentReadable;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001615}
1616
1617
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001618_X_EXPORT GLXFBConfig *
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001619glXGetFBConfigs(Display * dpy, int screen, int *nelements)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001620{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001621 struct glx_display *priv = __glXInitialize(dpy);
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001622 struct glx_config **config_list = NULL;
1623 struct glx_config *config;
1624 unsigned num_configs = 0;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001625 int i;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001626
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001627 *nelements = 0;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001628 if (priv && (priv->screens != NULL)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001629 && (screen >= 0) && (screen <= ScreenCount(dpy))
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001630 && (priv->screens[screen]->configs != NULL)
1631 && (priv->screens[screen]->configs->fbconfigID
Ian Romanick71a6fb12010-02-04 15:59:51 -08001632 != (int) GLX_DONT_CARE)) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001633
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001634 for (config = priv->screens[screen]->configs; config != NULL;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001635 config = config->next) {
1636 if (config->fbconfigID != (int) GLX_DONT_CARE) {
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001637 num_configs++;
1638 }
1639 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001640
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001641 config_list = Xmalloc(num_configs * sizeof *config_list);
1642 if (config_list != NULL) {
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001643 *nelements = num_configs;
1644 i = 0;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001645 for (config = priv->screens[screen]->configs; config != NULL;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001646 config = config->next) {
1647 if (config->fbconfigID != (int) GLX_DONT_CARE) {
1648 config_list[i] = config;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001649 i++;
1650 }
1651 }
1652 }
1653 }
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001654
1655 return (GLXFBConfig *) config_list;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001656}
1657
1658
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001659_X_EXPORT int
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001660glXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001661 int attribute, int *value)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001662{
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001663 struct glx_config *config = ValidateGLXFBConfig(dpy, fbconfig);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001664
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001665 if (config == NULL)
1666 return GLXBadFBConfig;
1667
1668 return glx_config_get(config, attribute, value);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001669}
1670
1671
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001672_X_EXPORT XVisualInfo *
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001673glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig fbconfig)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001674{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001675 XVisualInfo visualTemplate;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001676 struct glx_config *config = (struct glx_config *) fbconfig;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001677 int count;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001678
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001679 /*
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001680 ** Get a list of all visuals, return if list is empty
1681 */
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001682 visualTemplate.visualid = config->visualID;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001683 return XGetVisualInfo(dpy, VisualIDMask, &visualTemplate, &count);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001684}
1685
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001686#ifndef GLX_USE_APPLEGL
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001687/*
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001688** GLX_SGI_swap_control
1689*/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001690static int
1691__glXSwapIntervalSGI(int interval)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001692{
1693 xGLXVendorPrivateReq *req;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001694 struct glx_context *gc = __glXGetCurrentContext();
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001695 struct glx_screen *psc;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001696 Display *dpy;
1697 CARD32 *interval_ptr;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001698 CARD8 opcode;
1699
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001700 if (gc == NULL) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001701 return GLX_BAD_CONTEXT;
1702 }
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001703
1704 if (interval <= 0) {
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001705 return GLX_BAD_VALUE;
1706 }
1707
Jesse Barnesefc82e72009-11-10 13:28:01 -08001708 psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
1709
Vinson Lee16f568a2010-04-01 00:10:28 -07001710#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergc491e582010-07-28 15:33:09 -04001711 if (gc->isDirect && psc->driScreen && psc->driScreen->setSwapInterval) {
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04001712 __GLXDRIdrawable *pdraw =
1713 GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
Jesse Barnesefc82e72009-11-10 13:28:01 -08001714 psc->driScreen->setSwapInterval(pdraw, interval);
1715 return 0;
1716 }
Vinson Lee16f568a2010-04-01 00:10:28 -07001717#endif
Jesse Barnesefc82e72009-11-10 13:28:01 -08001718
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001719 dpy = gc->currentDpy;
1720 opcode = __glXSetupForCommand(dpy);
1721 if (!opcode) {
1722 return 0;
1723 }
1724
1725 /* Send the glXSwapIntervalSGI request */
1726 LockDisplay(dpy);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001727 GetReqExtra(GLXVendorPrivate, sizeof(CARD32), req);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001728 req->reqType = opcode;
1729 req->glxCode = X_GLXVendorPrivate;
1730 req->vendorCode = X_GLXvop_SwapIntervalSGI;
1731 req->contextTag = gc->currentContextTag;
1732
Ian Romanicka70d5642006-08-30 23:15:02 +00001733 interval_ptr = (CARD32 *) (req + 1);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001734 *interval_ptr = interval;
1735
1736 UnlockDisplay(dpy);
1737 SyncHandle();
1738 XFlush(dpy);
1739
1740 return 0;
1741}
1742
1743
1744/*
1745** GLX_MESA_swap_control
1746*/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001747static int
1748__glXSwapIntervalMESA(unsigned int interval)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001749{
Kristian Høgsberg089fc372010-07-19 16:39:53 -04001750#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001751 struct glx_context *gc = __glXGetCurrentContext();
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001752
Kristian Høgsbergc491e582010-07-28 15:33:09 -04001753 if (gc != NULL && gc->isDirect) {
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001754 struct glx_screen *psc;
Jesse Barnesefc82e72009-11-10 13:28:01 -08001755
1756 psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
1757 if (psc->driScreen && psc->driScreen->setSwapInterval) {
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04001758 __GLXDRIdrawable *pdraw =
1759 GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
Kristian Høgsberg089fc372010-07-19 16:39:53 -04001760 return psc->driScreen->setSwapInterval(pdraw, interval);
Jesse Barnesefc82e72009-11-10 13:28:01 -08001761 }
1762 }
Vinson Lee16f568a2010-04-01 00:10:28 -07001763#endif
Jesse Barnesefc82e72009-11-10 13:28:01 -08001764
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001765 return GLX_BAD_CONTEXT;
1766}
Brian Paul841a8232006-03-09 16:25:46 +00001767
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001768
1769static int
1770__glXGetSwapIntervalMESA(void)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001771{
Kristian Høgsberg089fc372010-07-19 16:39:53 -04001772#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001773 struct glx_context *gc = __glXGetCurrentContext();
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001774
Kristian Høgsbergc491e582010-07-28 15:33:09 -04001775 if (gc != NULL && gc->isDirect) {
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001776 struct glx_screen *psc;
Jesse Barnesefc82e72009-11-10 13:28:01 -08001777
1778 psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
1779 if (psc->driScreen && psc->driScreen->getSwapInterval) {
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04001780 __GLXDRIdrawable *pdraw =
1781 GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
Jesse Barnesefc82e72009-11-10 13:28:01 -08001782 return psc->driScreen->getSwapInterval(pdraw);
1783 }
1784 }
Vinson Lee67776f62010-04-02 00:12:59 -07001785#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001786
1787 return 0;
1788}
1789
1790
1791/*
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001792** GLX_SGI_video_sync
1793*/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001794static int
1795__glXGetVideoSyncSGI(unsigned int *count)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001796{
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001797 int64_t ust, msc, sbc;
1798 int ret;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001799 struct glx_context *gc = __glXGetCurrentContext();
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001800 struct glx_screen *psc;
Vinson Lee67776f62010-04-02 00:12:59 -07001801#ifdef GLX_DIRECT_RENDERING
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001802 __GLXDRIdrawable *pdraw;
Vinson Lee67776f62010-04-02 00:12:59 -07001803#endif
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001804
Vinson Lee16f568a2010-04-01 00:10:28 -07001805 if (!gc)
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001806 return GLX_BAD_CONTEXT;
1807
Vinson Lee16f568a2010-04-01 00:10:28 -07001808#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergc491e582010-07-28 15:33:09 -04001809 if (!gc->isDirect)
Vinson Lee16f568a2010-04-01 00:10:28 -07001810 return GLX_BAD_CONTEXT;
1811#endif
1812
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001813 psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen);
Vinson Lee67776f62010-04-02 00:12:59 -07001814#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04001815 pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
Vinson Lee67776f62010-04-02 00:12:59 -07001816#endif
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001817
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001818 /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
1819 * FIXME: there should be a GLX encoding for this call. I can find no
1820 * FIXME: documentation for the GLX encoding.
1821 */
Vinson Lee67776f62010-04-02 00:12:59 -07001822#ifdef GLX_DIRECT_RENDERING
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001823 if (psc->driScreen && psc->driScreen->getDrawableMSC) {
1824 ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc);
1825 *count = (unsigned) msc;
1826 return (ret == True) ? 0 : GLX_BAD_CONTEXT;
1827 }
Vinson Lee67776f62010-04-02 00:12:59 -07001828#endif
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001829
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001830 return GLX_BAD_CONTEXT;
1831}
1832
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001833static int
1834__glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001835{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001836 struct glx_context *gc = __glXGetCurrentContext();
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001837 struct glx_screen *psc;
Vinson Lee67776f62010-04-02 00:12:59 -07001838#ifdef GLX_DIRECT_RENDERING
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001839 __GLXDRIdrawable *pdraw;
Vinson Lee67776f62010-04-02 00:12:59 -07001840#endif
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001841 int64_t ust, msc, sbc;
1842 int ret;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001843
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001844 if (divisor <= 0 || remainder < 0)
1845 return GLX_BAD_VALUE;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001846
Vinson Lee16f568a2010-04-01 00:10:28 -07001847 if (!gc)
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001848 return GLX_BAD_CONTEXT;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001849
Vinson Lee16f568a2010-04-01 00:10:28 -07001850#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergc491e582010-07-28 15:33:09 -04001851 if (!gc->isDirect)
Vinson Lee16f568a2010-04-01 00:10:28 -07001852 return GLX_BAD_CONTEXT;
1853#endif
1854
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001855 psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
Vinson Lee67776f62010-04-02 00:12:59 -07001856#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04001857 pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
Vinson Lee67776f62010-04-02 00:12:59 -07001858#endif
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001859
Vinson Lee67776f62010-04-02 00:12:59 -07001860#ifdef GLX_DIRECT_RENDERING
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001861 if (psc->driScreen && psc->driScreen->waitForMSC) {
1862 ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc,
1863 &sbc);
1864 *count = (unsigned) msc;
1865 return (ret == True) ? 0 : GLX_BAD_CONTEXT;
1866 }
Vinson Lee67776f62010-04-02 00:12:59 -07001867#endif
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07001868
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001869 return GLX_BAD_CONTEXT;
1870}
1871
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001872#endif /* GLX_USE_APPLEGL */
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001873
1874/*
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001875** GLX_SGIX_fbconfig
1876** Many of these functions are aliased to GLX 1.3 entry points in the
1877** GLX_functions table.
1878*/
1879
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001880_X_EXPORT
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001881GLX_ALIAS(int, glXGetFBConfigAttribSGIX,
1882 (Display * dpy, GLXFBConfigSGIX config, int attribute, int *value),
1883 (dpy, config, attribute, value), glXGetFBConfigAttrib)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001884
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001885_X_EXPORT GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX,
Brian Paulef9cd842009-09-29 09:58:47 -06001886 (Display * dpy, int screen, int *attrib_list,
1887 int *nelements), (dpy, screen, attrib_list, nelements),
1888 glXChooseFBConfig)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001889
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001890_X_EXPORT GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX,
Brian Paulef9cd842009-09-29 09:58:47 -06001891 (Display * dpy, GLXFBConfigSGIX config),
1892 (dpy, config), glXGetVisualFromFBConfig)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001893
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001894_X_EXPORT GLXPixmap
Brian Paulef9cd842009-09-29 09:58:47 -06001895glXCreateGLXPixmapWithConfigSGIX(Display * dpy,
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001896 GLXFBConfigSGIX fbconfig,
Brian Paulef9cd842009-09-29 09:58:47 -06001897 Pixmap pixmap)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001898{
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001899#ifndef GLX_USE_APPLEGL
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001900 xGLXVendorPrivateWithReplyReq *vpreq;
1901 xGLXCreateGLXPixmapWithConfigSGIXReq *req;
1902 GLXPixmap xid = None;
1903 CARD8 opcode;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001904 struct glx_screen *psc;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001905#endif
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001906 struct glx_config *config = (struct glx_config *) fbconfig;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001907
1908
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001909 if ((dpy == NULL) || (config == NULL)) {
1910 return None;
1911 }
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001912#ifdef GLX_USE_APPLEGL
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001913 if(apple_glx_pixmap_create(dpy, config->screen, pixmap, config))
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001914 return None;
1915 return pixmap;
1916#else
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001917
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001918 psc = GetGLXScreenConfigs(dpy, config->screen);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001919 if ((psc != NULL)
1920 && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
1921 opcode = __glXSetupForCommand(dpy);
1922 if (!opcode) {
1923 return None;
1924 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001925
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001926 /* Send the glXCreateGLXPixmapWithConfigSGIX request */
1927 LockDisplay(dpy);
1928 GetReqExtra(GLXVendorPrivateWithReply,
1929 sz_xGLXCreateGLXPixmapWithConfigSGIXReq -
1930 sz_xGLXVendorPrivateWithReplyReq, vpreq);
1931 req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) vpreq;
1932 req->reqType = opcode;
1933 req->glxCode = X_GLXVendorPrivateWithReply;
1934 req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001935 req->screen = config->screen;
1936 req->fbconfig = config->fbconfigID;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001937 req->pixmap = pixmap;
1938 req->glxpixmap = xid = XAllocID(dpy);
1939 UnlockDisplay(dpy);
1940 SyncHandle();
1941 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001942
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001943 return xid;
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001944#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001945}
1946
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001947_X_EXPORT GLXContext
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001948glXCreateContextWithConfigSGIX(Display * dpy,
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001949 GLXFBConfigSGIX fbconfig, int renderType,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001950 GLXContext shareList, Bool allowDirect)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001951{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001952 GLXContext gc = NULL;
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001953 struct glx_config *config = (struct glx_config *) fbconfig;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001954 struct glx_screen *psc;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001955
1956
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001957 if ((dpy == NULL) || (config == NULL)) {
1958 return None;
1959 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001960
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001961 psc = GetGLXScreenConfigs(dpy, config->screen);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001962 if ((psc != NULL)
1963 && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001964 gc = CreateContext(dpy, config->fbconfigID, config, shareList,
Ian Romanick22430292010-02-04 16:43:46 -08001965 allowDirect,
Ian Romanick7bcfb662010-02-04 16:37:59 -08001966 X_GLXvop_CreateContextWithConfigSGIX, renderType,
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001967 config->screen);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001968 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001969
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001970 return gc;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001971}
1972
1973
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04001974_X_EXPORT GLXFBConfigSGIX
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001975glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001976{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001977 struct glx_display *priv;
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04001978 struct glx_screen *psc = NULL;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001979
Stéphane Marchesinfc48de42011-05-26 17:19:03 -07001980 if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) == Success)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001981 && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)
Ian Romanick71a6fb12010-02-04 15:59:51 -08001982 && (psc->configs->fbconfigID != (int) GLX_DONT_CARE)) {
Kristian Høgsberg6ddf66e2010-07-28 10:07:52 -04001983 return (GLXFBConfigSGIX) glx_config_find_visual(psc->configs,
1984 vis->visualid);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001985 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001986
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001987 return NULL;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001988}
1989
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07001990#ifndef GLX_USE_APPLEGL
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001991/*
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001992** GLX_SGIX_swap_group
1993*/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001994static void
1995__glXJoinSwapGroupSGIX(Display * dpy, GLXDrawable drawable,
1996 GLXDrawable member)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00001997{
1998 (void) dpy;
1999 (void) drawable;
2000 (void) member;
2001}
2002
2003
2004/*
2005** GLX_SGIX_swap_barrier
2006*/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002007static void
2008__glXBindSwapBarrierSGIX(Display * dpy, GLXDrawable drawable, int barrier)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002009{
2010 (void) dpy;
2011 (void) drawable;
2012 (void) barrier;
2013}
2014
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002015static Bool
2016__glXQueryMaxSwapBarriersSGIX(Display * dpy, int screen, int *max)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002017{
2018 (void) dpy;
2019 (void) screen;
2020 (void) max;
2021 return False;
2022}
2023
2024
2025/*
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002026** GLX_OML_sync_control
2027*/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002028static Bool
2029__glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
2030 int64_t * ust, int64_t * msc, int64_t * sbc)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002031{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04002032 struct glx_display * const priv = __glXInitialize(dpy);
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04002033 int ret;
Vinson Lee67776f62010-04-02 00:12:59 -07002034#ifdef GLX_DIRECT_RENDERING
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002035 __GLXDRIdrawable *pdraw;
Vinson Lee67776f62010-04-02 00:12:59 -07002036#endif
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04002037 struct glx_screen *psc;
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002038
2039 if (!priv)
2040 return False;
2041
Vinson Lee67776f62010-04-02 00:12:59 -07002042#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04002043 pdraw = GetGLXDRIDrawable(dpy, drawable);
2044 psc = pdraw ? pdraw->psc : NULL;
2045 if (pdraw && psc->driScreen->getDrawableMSC) {
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002046 ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc);
2047 return ret;
2048 }
Vinson Lee67776f62010-04-02 00:12:59 -07002049#endif
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002050
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002051 return False;
2052}
2053
Jeremy Huddleston80b280d2010-04-02 01:35:19 -07002054#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Kristian Høgsberg3d28a262008-03-08 22:28:01 -05002055_X_HIDDEN GLboolean
Kristian Høgsberg7a66e542010-07-21 14:09:49 -04002056__glxGetMscRate(__GLXDRIdrawable *glxDraw,
2057 int32_t * numerator, int32_t * denominator)
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002058{
2059#ifdef XF86VIDMODE
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04002060 struct glx_screen *psc;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002061 XF86VidModeModeLine mode_line;
2062 int dot_clock;
2063 int i;
Ian Romanick26b2bee2010-02-04 15:47:54 -08002064
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002065 psc = glxDraw->psc;
2066 if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
2067 XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line)) {
2068 unsigned n = dot_clock * 1000;
2069 unsigned d = mode_line.vtotal * mode_line.htotal;
2070
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002071# define V_INTERLACE 0x010
2072# define V_DBLSCAN 0x020
2073
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002074 if (mode_line.flags & V_INTERLACE)
2075 n *= 2;
2076 else if (mode_line.flags & V_DBLSCAN)
2077 d *= 2;
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002078
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002079 /* The OML_sync_control spec requires that if the refresh rate is a
2080 * whole number, that the returned numerator be equal to the refresh
2081 * rate and the denominator be 1.
2082 */
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002083
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002084 if (n % d == 0) {
2085 n /= d;
2086 d = 1;
2087 }
2088 else {
2089 static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002090
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002091 /* This is a poor man's way to reduce a fraction. It's far from
2092 * perfect, but it will work well enough for this situation.
2093 */
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002094
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002095 for (i = 0; f[i] != 0; i++) {
2096 while (n % f[i] == 0 && d % f[i] == 0) {
2097 d /= f[i];
2098 n /= f[i];
2099 }
2100 }
2101 }
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002102
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002103 *numerator = n;
2104 *denominator = d;
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002105
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002106 return True;
2107 }
2108 else
Kristian Høgsberg57d3f712010-09-07 14:23:00 -04002109#endif
Ian Romanick26b2bee2010-02-04 15:47:54 -08002110
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002111 return False;
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002112}
2113#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002114
2115/**
2116 * Determine the refresh rate of the specified drawable and display.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002117 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002118 * \param dpy Display whose refresh rate is to be determined.
2119 * \param drawable Drawable whose refresh rate is to be determined.
2120 * \param numerator Numerator of the refresh rate.
2121 * \param demoninator Denominator of the refresh rate.
2122 * \return If the refresh rate for the specified display and drawable could
2123 * be calculated, True is returned. Otherwise False is returned.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002124 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002125 * \note This function is implemented entirely client-side. A lot of other
2126 * functionality is required to export GLX_OML_sync_control, so on
2127 * XFree86 this function can be called for direct-rendering contexts
2128 * when GLX_OML_sync_control appears in the client extension string.
2129 */
2130
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002131_X_HIDDEN GLboolean
2132__glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
2133 int32_t * numerator, int32_t * denominator)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002134{
2135#if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04002136 __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002137
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002138 if (draw == NULL)
2139 return False;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002140
Kristian Høgsberg7a66e542010-07-21 14:09:49 -04002141 return __glxGetMscRate(draw, numerator, denominator);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002142#else
Kristian Høgsberg286ce272007-11-06 14:34:15 -05002143 (void) dpy;
2144 (void) drawable;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002145 (void) numerator;
2146 (void) denominator;
2147#endif
2148 return False;
2149}
2150
2151
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002152static int64_t
2153__glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
2154 int64_t target_msc, int64_t divisor, int64_t remainder)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002155{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04002156 struct glx_context *gc = __glXGetCurrentContext();
Vinson Lee67776f62010-04-02 00:12:59 -07002157#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04002158 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04002159 struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
Vinson Lee67776f62010-04-02 00:12:59 -07002160#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002161
Vinson Lee67776f62010-04-02 00:12:59 -07002162 if (!gc) /* no GLX for this */
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002163 return -1;
2164
Vinson Lee16f568a2010-04-01 00:10:28 -07002165#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergc491e582010-07-28 15:33:09 -04002166 if (!pdraw || !gc->isDirect)
Vinson Lee16f568a2010-04-01 00:10:28 -07002167 return -1;
2168#endif
2169
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002170 /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2171 * error", but it also says "It [glXSwapBuffersMscOML] will return a value
2172 * of -1 if the function failed because of errors detected in the input
2173 * parameters"
2174 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002175 if (divisor < 0 || remainder < 0 || target_msc < 0)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002176 return -1;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002177 if (divisor > 0 && remainder >= divisor)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002178 return -1;
2179
Jesse Barnes8f4f2a02010-03-22 16:39:11 -07002180 if (target_msc == 0 && divisor == 0 && remainder == 0)
2181 remainder = 1;
2182
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002183#ifdef GLX_DIRECT_RENDERING
2184 if (psc->driScreen && psc->driScreen->swapBuffers)
2185 return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor,
2186 remainder);
2187#endif
2188
2189 return -1;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002190}
2191
2192
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002193static Bool
2194__glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
2195 int64_t target_msc, int64_t divisor,
2196 int64_t remainder, int64_t * ust,
2197 int64_t * msc, int64_t * sbc)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002198{
Vinson Lee67776f62010-04-02 00:12:59 -07002199#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04002200 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04002201 struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002202 int ret;
Jon TURNEYae9487c2010-08-09 14:47:26 +01002203#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002204
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002205
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002206 /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
2207 * error", but the return type in the spec is Bool.
2208 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002209 if (divisor < 0 || remainder < 0 || target_msc < 0)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002210 return False;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002211 if (divisor > 0 && remainder >= divisor)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002212 return False;
2213
Vinson Lee67776f62010-04-02 00:12:59 -07002214#ifdef GLX_DIRECT_RENDERING
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002215 if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) {
2216 ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder,
2217 ust, msc, sbc);
2218 return ret;
2219 }
Vinson Lee67776f62010-04-02 00:12:59 -07002220#endif
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002221
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002222 return False;
2223}
2224
2225
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002226static Bool
2227__glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
2228 int64_t target_sbc, int64_t * ust,
2229 int64_t * msc, int64_t * sbc)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002230{
Vinson Lee67776f62010-04-02 00:12:59 -07002231#ifdef GLX_DIRECT_RENDERING
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04002232 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04002233 struct glx_screen *psc = pdraw ? pdraw->psc : NULL;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002234 int ret;
Jon TURNEYae9487c2010-08-09 14:47:26 +01002235#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002236
2237 /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE
2238 * error", but the return type in the spec is Bool.
2239 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002240 if (target_sbc < 0)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002241 return False;
Vinson Lee67776f62010-04-02 00:12:59 -07002242
2243#ifdef GLX_DIRECT_RENDERING
kleinerm251bf292010-02-19 12:28:26 -08002244 if (pdraw && psc->driScreen && psc->driScreen->waitForSBC) {
Jesse Barnesdaf7fe62009-09-15 23:23:09 -07002245 ret = psc->driScreen->waitForSBC(pdraw, target_sbc, ust, msc, sbc);
2246 return ret;
2247 }
Vinson Lee67776f62010-04-02 00:12:59 -07002248#endif
2249
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002250 return False;
2251}
2252
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002253/*@}*/
2254
2255
2256/**
2257 * Mesa extension stubs. These will help reduce portability problems.
2258 */
2259/*@{*/
2260
2261/**
2262 * Release all buffers associated with the specified GLX drawable.
2263 *
2264 * \todo
2265 * This function was intended for stand-alone Mesa. The issue there is that
2266 * the library doesn't get any notification when a window is closed. In
2267 * DRI there is a similar but slightly different issue. When GLX 1.3 is
2268 * supported, there are 3 different functions to destroy a drawable. It
2269 * should be possible to create GLX protocol (or have it determine which
2270 * protocol to use based on the type of the drawable) to have one function
2271 * do the work of 3. For the direct-rendering case, this function could
2272 * just call the driver's \c __DRIdrawableRec::destroyDrawable function.
2273 * This would reduce the frequency with which \c __driGarbageCollectDrawables
2274 * would need to be used. This really should be done as part of the new DRI
2275 * interface work.
2276 *
2277 * \sa http://oss.sgi.com/projects/ogl-sample/registry/MESA/release_buffers.txt
2278 * __driGarbageCollectDrawables
2279 * glXDestroyGLXPixmap
2280 * glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow
2281 * glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX
2282 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002283static Bool
2284__glXReleaseBuffersMESA(Display * dpy, GLXDrawable d)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002285{
2286 (void) dpy;
2287 (void) d;
2288 return False;
2289}
2290
2291
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04002292_X_EXPORT GLXPixmap
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002293glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual,
2294 Pixmap pixmap, Colormap cmap)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002295{
2296 (void) dpy;
2297 (void) visual;
2298 (void) pixmap;
2299 (void) cmap;
2300 return 0;
2301}
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002302
Ian Romanickfc5b57b2006-08-29 15:38:19 +00002303/*@}*/
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002304
Ian Romanickfc5b57b2006-08-29 15:38:19 +00002305
2306/**
2307 * GLX_MESA_copy_sub_buffer
2308 */
Brian Paulf2ad1b62006-03-31 15:48:04 +00002309#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002310static void
2311__glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
2312 int x, int y, int width, int height)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002313{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002314 xGLXVendorPrivateReq *req;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04002315 struct glx_context *gc;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002316 GLXContextTag tag;
2317 CARD32 *drawable_ptr;
2318 INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
2319 CARD8 opcode;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002320
Kristian Høgsberg2235b1c2010-07-26 15:50:02 -04002321#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Kristian Høgsbergeeaab202010-07-22 22:36:37 -04002322 __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002323 if (pdraw != NULL) {
Kristian Høgsberg66fc35c2010-07-28 10:28:43 -04002324 struct glx_screen *psc = pdraw->psc;
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002325 if (psc->driScreen->copySubBuffer != NULL) {
2326 glFlush();
2327 (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height);
2328 }
Brian Paulf2ad1b62006-03-31 15:48:04 +00002329
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002330 return;
2331 }
Brian Paulf2ad1b62006-03-31 15:48:04 +00002332#endif
2333
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002334 opcode = __glXSetupForCommand(dpy);
2335 if (!opcode)
2336 return;
Brian Paulf2ad1b62006-03-31 15:48:04 +00002337
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002338 /*
Brian Paulf2ad1b62006-03-31 15:48:04 +00002339 ** The calling thread may or may not have a current context. If it
2340 ** does, send the context tag so the server can do a flush.
2341 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002342 gc = __glXGetCurrentContext();
2343 if ((gc != NULL) && (dpy == gc->currentDpy) &&
2344 ((drawable == gc->currentDrawable) ||
2345 (drawable == gc->currentReadable))) {
2346 tag = gc->currentContextTag;
2347 }
2348 else {
2349 tag = 0;
2350 }
Brian Paulf2ad1b62006-03-31 15:48:04 +00002351
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002352 LockDisplay(dpy);
2353 GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32) * 4, req);
2354 req->reqType = opcode;
2355 req->glxCode = X_GLXVendorPrivate;
2356 req->vendorCode = X_GLXvop_CopySubBufferMESA;
2357 req->contextTag = tag;
Brian Paulf2ad1b62006-03-31 15:48:04 +00002358
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002359 drawable_ptr = (CARD32 *) (req + 1);
2360 x_ptr = (INT32 *) (drawable_ptr + 1);
2361 y_ptr = (INT32 *) (drawable_ptr + 2);
2362 w_ptr = (INT32 *) (drawable_ptr + 3);
2363 h_ptr = (INT32 *) (drawable_ptr + 4);
Brian Paulf2ad1b62006-03-31 15:48:04 +00002364
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002365 *drawable_ptr = drawable;
2366 *x_ptr = x;
2367 *y_ptr = y;
2368 *w_ptr = width;
2369 *h_ptr = height;
Brian Paulf2ad1b62006-03-31 15:48:04 +00002370
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002371 UnlockDisplay(dpy);
2372 SyncHandle();
Brian Paulf2ad1b62006-03-31 15:48:04 +00002373}
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002374
Kristian Høgsberg643b2af2010-05-21 10:36:56 -04002375/*@{*/
2376static void
2377__glXBindTexImageEXT(Display * dpy,
2378 GLXDrawable drawable, int buffer, const int *attrib_list)
2379{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04002380 struct glx_context *gc = __glXGetCurrentContext();
Kristian Høgsberg643b2af2010-05-21 10:36:56 -04002381
Kristian Høgsberg3ea3f5e2010-09-07 14:32:28 -04002382 if (gc == NULL || gc->vtable->bind_tex_image == NULL)
Kristian Høgsberg643b2af2010-05-21 10:36:56 -04002383 return;
2384
2385 gc->vtable->bind_tex_image(dpy, drawable, buffer, attrib_list);
2386}
2387
2388static void
2389__glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer)
2390{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04002391 struct glx_context *gc = __glXGetCurrentContext();
Kristian Høgsberg643b2af2010-05-21 10:36:56 -04002392
Kristian Høgsberg3ea3f5e2010-09-07 14:32:28 -04002393 if (gc == NULL || gc->vtable->release_tex_image == NULL)
Kristian Høgsberg643b2af2010-05-21 10:36:56 -04002394 return;
2395
2396 gc->vtable->release_tex_image(dpy, drawable, buffer);
2397}
2398
Ian Romanickfc5b57b2006-08-29 15:38:19 +00002399/*@}*/
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002400
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07002401#endif /* GLX_USE_APPLEGL */
2402
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002403/**
2404 * \c strdup is actually not a standard ANSI C or POSIX routine.
2405 * Irix will not define it if ANSI mode is in effect.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002406 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002407 * \sa strdup
2408 */
Kristian Høgsberg3d28a262008-03-08 22:28:01 -05002409_X_HIDDEN char *
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002410__glXstrdup(const char *str)
2411{
2412 char *copy;
2413 copy = (char *) Xmalloc(strlen(str) + 1);
2414 if (!copy)
2415 return NULL;
2416 strcpy(copy, str);
2417 return copy;
2418}
2419
2420/*
2421** glXGetProcAddress support
2422*/
2423
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002424struct name_address_pair
2425{
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002426 const char *Name;
2427 GLvoid *Address;
2428};
2429
2430#define GLX_FUNCTION(f) { # f, (GLvoid *) f }
2431#define GLX_FUNCTION2(n,f) { # n, (GLvoid *) f }
2432
2433static const struct name_address_pair GLX_functions[] = {
2434 /*** GLX_VERSION_1_0 ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002435 GLX_FUNCTION(glXChooseVisual),
2436 GLX_FUNCTION(glXCopyContext),
2437 GLX_FUNCTION(glXCreateContext),
2438 GLX_FUNCTION(glXCreateGLXPixmap),
2439 GLX_FUNCTION(glXDestroyContext),
2440 GLX_FUNCTION(glXDestroyGLXPixmap),
2441 GLX_FUNCTION(glXGetConfig),
2442 GLX_FUNCTION(glXGetCurrentContext),
2443 GLX_FUNCTION(glXGetCurrentDrawable),
2444 GLX_FUNCTION(glXIsDirect),
2445 GLX_FUNCTION(glXMakeCurrent),
2446 GLX_FUNCTION(glXQueryExtension),
2447 GLX_FUNCTION(glXQueryVersion),
2448 GLX_FUNCTION(glXSwapBuffers),
2449 GLX_FUNCTION(glXUseXFont),
2450 GLX_FUNCTION(glXWaitGL),
2451 GLX_FUNCTION(glXWaitX),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002452
2453 /*** GLX_VERSION_1_1 ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002454 GLX_FUNCTION(glXGetClientString),
2455 GLX_FUNCTION(glXQueryExtensionsString),
2456 GLX_FUNCTION(glXQueryServerString),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002457
2458 /*** GLX_VERSION_1_2 ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002459 GLX_FUNCTION(glXGetCurrentDisplay),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002460
2461 /*** GLX_VERSION_1_3 ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002462 GLX_FUNCTION(glXChooseFBConfig),
2463 GLX_FUNCTION(glXCreateNewContext),
2464 GLX_FUNCTION(glXCreatePbuffer),
2465 GLX_FUNCTION(glXCreatePixmap),
2466 GLX_FUNCTION(glXCreateWindow),
2467 GLX_FUNCTION(glXDestroyPbuffer),
2468 GLX_FUNCTION(glXDestroyPixmap),
2469 GLX_FUNCTION(glXDestroyWindow),
2470 GLX_FUNCTION(glXGetCurrentReadDrawable),
2471 GLX_FUNCTION(glXGetFBConfigAttrib),
2472 GLX_FUNCTION(glXGetFBConfigs),
2473 GLX_FUNCTION(glXGetSelectedEvent),
2474 GLX_FUNCTION(glXGetVisualFromFBConfig),
2475 GLX_FUNCTION(glXMakeContextCurrent),
2476 GLX_FUNCTION(glXQueryContext),
2477 GLX_FUNCTION(glXQueryDrawable),
2478 GLX_FUNCTION(glXSelectEvent),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002479
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07002480#ifndef GLX_USE_APPLEGL
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002481 /*** GLX_SGI_swap_control ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002482 GLX_FUNCTION2(glXSwapIntervalSGI, __glXSwapIntervalSGI),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002483
2484 /*** GLX_SGI_video_sync ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002485 GLX_FUNCTION2(glXGetVideoSyncSGI, __glXGetVideoSyncSGI),
2486 GLX_FUNCTION2(glXWaitVideoSyncSGI, __glXWaitVideoSyncSGI),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002487
2488 /*** GLX_SGI_make_current_read ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002489 GLX_FUNCTION2(glXMakeCurrentReadSGI, glXMakeContextCurrent),
2490 GLX_FUNCTION2(glXGetCurrentReadDrawableSGI, glXGetCurrentReadDrawable),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002491
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002492 /*** GLX_EXT_import_context ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002493 GLX_FUNCTION(glXFreeContextEXT),
2494 GLX_FUNCTION(glXGetContextIDEXT),
2495 GLX_FUNCTION2(glXGetCurrentDisplayEXT, glXGetCurrentDisplay),
2496 GLX_FUNCTION(glXImportContextEXT),
2497 GLX_FUNCTION2(glXQueryContextInfoEXT, glXQueryContext),
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07002498#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002499
2500 /*** GLX_SGIX_fbconfig ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002501 GLX_FUNCTION2(glXGetFBConfigAttribSGIX, glXGetFBConfigAttrib),
2502 GLX_FUNCTION2(glXChooseFBConfigSGIX, glXChooseFBConfig),
2503 GLX_FUNCTION(glXCreateGLXPixmapWithConfigSGIX),
2504 GLX_FUNCTION(glXCreateContextWithConfigSGIX),
2505 GLX_FUNCTION2(glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig),
2506 GLX_FUNCTION(glXGetFBConfigFromVisualSGIX),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002507
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07002508#ifndef GLX_USE_APPLEGL
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002509 /*** GLX_SGIX_pbuffer ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002510 GLX_FUNCTION(glXCreateGLXPbufferSGIX),
2511 GLX_FUNCTION(glXDestroyGLXPbufferSGIX),
2512 GLX_FUNCTION(glXQueryGLXPbufferSGIX),
2513 GLX_FUNCTION(glXSelectEventSGIX),
2514 GLX_FUNCTION(glXGetSelectedEventSGIX),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002515
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002516 /*** GLX_SGIX_swap_group ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002517 GLX_FUNCTION2(glXJoinSwapGroupSGIX, __glXJoinSwapGroupSGIX),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002518
2519 /*** GLX_SGIX_swap_barrier ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002520 GLX_FUNCTION2(glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX),
2521 GLX_FUNCTION2(glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002522
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002523 /*** GLX_MESA_copy_sub_buffer ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002524 GLX_FUNCTION2(glXCopySubBufferMESA, __glXCopySubBufferMESA),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002525
2526 /*** GLX_MESA_pixmap_colormap ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002527 GLX_FUNCTION(glXCreateGLXPixmapMESA),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002528
2529 /*** GLX_MESA_release_buffers ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002530 GLX_FUNCTION2(glXReleaseBuffersMESA, __glXReleaseBuffersMESA),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002531
2532 /*** GLX_MESA_swap_control ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002533 GLX_FUNCTION2(glXSwapIntervalMESA, __glXSwapIntervalMESA),
2534 GLX_FUNCTION2(glXGetSwapIntervalMESA, __glXGetSwapIntervalMESA),
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07002535#endif
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002536
2537 /*** GLX_ARB_get_proc_address ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002538 GLX_FUNCTION(glXGetProcAddressARB),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002539
2540 /*** GLX 1.4 ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002541 GLX_FUNCTION2(glXGetProcAddress, glXGetProcAddressARB),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002542
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07002543#ifndef GLX_USE_APPLEGL
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002544 /*** GLX_OML_sync_control ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002545 GLX_FUNCTION2(glXWaitForSbcOML, __glXWaitForSbcOML),
2546 GLX_FUNCTION2(glXWaitForMscOML, __glXWaitForMscOML),
2547 GLX_FUNCTION2(glXSwapBuffersMscOML, __glXSwapBuffersMscOML),
2548 GLX_FUNCTION2(glXGetMscRateOML, __glXGetMscRateOML),
2549 GLX_FUNCTION2(glXGetSyncValuesOML, __glXGetSyncValuesOML),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002550
Brian Paul42725d62006-02-07 00:39:56 +00002551 /*** GLX_EXT_texture_from_pixmap ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002552 GLX_FUNCTION2(glXBindTexImageEXT, __glXBindTexImageEXT),
2553 GLX_FUNCTION2(glXReleaseTexImageEXT, __glXReleaseTexImageEXT),
Jeremy Huddlestonad503c42010-04-01 11:01:31 -07002554#endif
Brian Paul42725d62006-02-07 00:39:56 +00002555
Jeremy Huddleston80b280d2010-04-02 01:35:19 -07002556#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002557 /*** DRI configuration ***/
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002558 GLX_FUNCTION(glXGetScreenDriver),
2559 GLX_FUNCTION(glXGetDriverConfig),
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002560#endif
2561
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002562 {NULL, NULL} /* end of list */
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002563};
2564
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002565static const GLvoid *
2566get_glx_proc_address(const char *funcName)
2567{
2568 GLuint i;
2569
2570 /* try static functions */
2571 for (i = 0; GLX_functions[i].Name; i++) {
2572 if (strcmp(GLX_functions[i].Name, funcName) == 0)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002573 return GLX_functions[i].Address;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002574 }
2575
2576 return NULL;
2577}
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002578
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002579/**
2580 * Get the address of a named GL function. This is the pre-GLX 1.4 name for
2581 * \c glXGetProcAddress.
2582 *
2583 * \param procName Name of a GL or GLX function.
2584 * \returns A pointer to the named function
2585 *
2586 * \sa glXGetProcAddress
2587 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04002588_X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002589{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002590 typedef void (*gl_function) (void);
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002591 gl_function f;
2592
2593
2594 /* Search the table of GLX and internal functions first. If that
2595 * fails and the supplied name could be a valid core GL name, try
2596 * searching the core GL function table. This check is done to prevent
2597 * DRI based drivers from searching the core GL function table for
2598 * internal API functions.
2599 */
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002600 f = (gl_function) get_glx_proc_address((const char *) procName);
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002601 if ((f == NULL) && (procName[0] == 'g') && (procName[1] == 'l')
2602 && (procName[2] != 'X')) {
Chia-I Wue8c7d752010-12-26 18:24:13 +08002603#ifdef GLX_SHARED_GLAPI
2604 f = (gl_function) __indirect_get_proc_address((const char *) procName);
2605#endif
2606 if (!f)
2607 f = (gl_function) _glapi_get_proc_address((const char *) procName);
Jeremy Huddleston559e4f82011-06-15 00:27:55 -07002608 if (!f) {
2609 struct glx_context *gc = __glXGetCurrentContext();
2610
2611 if (gc != NULL && gc->vtable->get_proc_address != NULL)
2612 f = gc->vtable->get_proc_address((const char *) procName);
2613 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002614 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002615 return f;
2616}
2617
2618/**
2619 * Get the address of a named GL function. This is the GLX 1.4 name for
2620 * \c glXGetProcAddressARB.
2621 *
2622 * \param procName Name of a GL or GLX function.
2623 * \returns A pointer to the named function
2624 *
2625 * \sa glXGetProcAddressARB
2626 */
Kristian Høgsberg38c51a72010-07-28 10:20:41 -04002627_X_EXPORT void (*glXGetProcAddress(const GLubyte * procName)) (void)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002628#if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED)
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002629 __attribute__ ((alias("glXGetProcAddressARB")));
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002630#else
2631{
2632 return glXGetProcAddressARB(procName);
2633}
2634#endif /* __GNUC__ */
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002635
2636
Jeremy Huddleston80b280d2010-04-02 01:35:19 -07002637#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002638/**
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002639 * Get the unadjusted system time (UST). Currently, the UST is measured in
2640 * microseconds since Epoc. The actual resolution of the UST may vary from
2641 * system to system, and the units may vary from release to release.
2642 * Drivers should not call this function directly. They should instead use
2643 * \c glXGetProcAddress to obtain a pointer to the function.
2644 *
2645 * \param ust Location to store the 64-bit UST
2646 * \returns Zero on success or a negative errno value on failure.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002647 *
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002648 * \sa glXGetProcAddress, PFNGLXGETUSTPROC
2649 *
2650 * \since Internal API version 20030317.
2651 */
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002652_X_HIDDEN int
2653__glXGetUST(int64_t * ust)
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002654{
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002655 struct timeval tv;
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002656
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02002657 if (ust == NULL) {
2658 return -EFAULT;
2659 }
2660
2661 if (gettimeofday(&tv, NULL) == 0) {
2662 ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
2663 return 0;
2664 }
2665 else {
2666 return -errno;
2667 }
Adam Jacksoncb3610e2004-10-25 21:09:16 +00002668}
2669#endif /* GLX_DIRECT_RENDERING */