2003-11-14 17:48:57 +01:00
|
|
|
/*
|
Update to SGI FreeB 2.0.
Under the terms of version 1.1, "once Covered Code has been published
under a particular version of the License, Recipient may, for the
duration of the License, continue to use it under the terms of that
version, or choose to use such Covered Code under the terms of any
subsequent version published by SGI."
FreeB 2.0 license refers to "dates of first publication". They are here
taken to be 1991-2000, as noted in the original license text:
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
Official FreeB 2.0 text:
http://oss.sgi.com/projects/FreeB/SGIFreeSWLicB.2.0.pdf
As always, this code has not been tested for conformance with the OpenGL
specification. OpenGL conformance testing is available from
http://khronos.org/ and is required for use of the OpenGL logo in
product advertising and promotion.
2008-09-19 18:02:28 +02:00
|
|
|
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
|
|
|
|
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice including the dates of first publication and
|
|
|
|
* either this permission notice or a reference to
|
|
|
|
* http://oss.sgi.com/projects/FreeB/
|
|
|
|
* shall be included in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
|
|
|
*
|
|
|
|
* Except as contained in this notice, the name of Silicon Graphics, Inc.
|
|
|
|
* shall not be used in advertising or otherwise to promote the sale, use or
|
|
|
|
* other dealings in this Software without prior written authorization from
|
|
|
|
* Silicon Graphics, Inc.
|
|
|
|
*/
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2005-07-03 09:02:09 +02:00
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
|
|
#include <dix-config.h>
|
|
|
|
#endif
|
|
|
|
|
2006-02-10 23:00:30 +01:00
|
|
|
#include <string.h>
|
2006-03-17 02:47:25 +01:00
|
|
|
#include <assert.h>
|
2006-02-10 23:00:30 +01:00
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
#include "glxserver.h"
|
|
|
|
#include <GL/glxtokens.h>
|
2018-01-10 19:05:42 +01:00
|
|
|
#include <X11/extensions/presenttokens.h>
|
2003-11-14 17:48:57 +01:00
|
|
|
#include <unpack.h>
|
|
|
|
#include <pixmapstr.h>
|
|
|
|
#include <windowstr.h>
|
|
|
|
#include "glxutil.h"
|
|
|
|
#include "glxext.h"
|
2006-03-21 23:32:13 +01:00
|
|
|
#include "indirect_dispatch.h"
|
2006-08-23 22:30:13 +02:00
|
|
|
#include "indirect_table.h"
|
|
|
|
#include "indirect_util.h"
|
2016-03-23 20:26:23 +01:00
|
|
|
#include "protocol-versions.h"
|
2018-01-10 19:05:45 +01:00
|
|
|
#include "glxvndabi.h"
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-11-09 22:33:54 +01:00
|
|
|
static char GLXServerVendorName[] = "SGI";
|
|
|
|
|
2011-12-16 23:42:51 +01:00
|
|
|
_X_HIDDEN int
|
2012-03-21 20:55:09 +01:00
|
|
|
validGlxScreen(ClientPtr client, int screen, __GLXscreen ** pGlxScreen,
|
|
|
|
int *err)
|
2007-10-18 21:51:11 +02:00
|
|
|
{
|
|
|
|
/*
|
2012-03-21 20:55:09 +01:00
|
|
|
** Check if screen exists.
|
|
|
|
*/
|
2010-07-03 20:42:26 +02:00
|
|
|
if (screen < 0 || screen >= screenInfo.numScreens) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = screen;
|
|
|
|
*err = BadValue;
|
|
|
|
return FALSE;
|
2007-10-18 21:51:11 +02:00
|
|
|
}
|
|
|
|
*pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
|
2005-10-06 00:39:41 +02:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-12-16 23:42:51 +01:00
|
|
|
_X_HIDDEN int
|
2012-03-21 20:55:09 +01:00
|
|
|
validGlxFBConfig(ClientPtr client, __GLXscreen * pGlxScreen, XID id,
|
|
|
|
__GLXconfig ** config, int *err)
|
2007-10-18 21:51:11 +02:00
|
|
|
{
|
2008-03-27 00:28:09 +01:00
|
|
|
__GLXconfig *m;
|
2007-10-18 21:51:11 +02:00
|
|
|
|
|
|
|
for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
|
2012-03-21 20:55:09 +01:00
|
|
|
if (m->fbconfigID == id) {
|
|
|
|
*config = m;
|
|
|
|
return TRUE;
|
|
|
|
}
|
2007-10-18 21:51:11 +02:00
|
|
|
|
|
|
|
client->errorValue = id;
|
|
|
|
*err = __glXError(GLXBadFBConfig);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-03-21 20:55:09 +01:00
|
|
|
validGlxVisual(ClientPtr client, __GLXscreen * pGlxScreen, XID id,
|
|
|
|
__GLXconfig ** config, int *err)
|
2007-10-18 21:51:11 +02:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < pGlxScreen->numVisuals; i++)
|
2012-03-21 20:55:09 +01:00
|
|
|
if (pGlxScreen->visuals[i]->visualID == id) {
|
|
|
|
*config = pGlxScreen->visuals[i];
|
|
|
|
return TRUE;
|
|
|
|
}
|
2007-10-18 21:51:11 +02:00
|
|
|
|
|
|
|
client->errorValue = id;
|
|
|
|
*err = BadValue;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-03-21 20:55:09 +01:00
|
|
|
validGlxFBConfigForWindow(ClientPtr client, __GLXconfig * config,
|
|
|
|
DrawablePtr pDraw, int *err)
|
2007-10-18 21:51:11 +02:00
|
|
|
{
|
|
|
|
ScreenPtr pScreen = pDraw->pScreen;
|
|
|
|
VisualPtr pVisual = NULL;
|
|
|
|
XID vid;
|
|
|
|
int i;
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
vid = wVisual((WindowPtr) pDraw);
|
2007-10-18 21:51:11 +02:00
|
|
|
for (i = 0; i < pScreen->numVisuals; i++) {
|
2012-03-21 20:55:09 +01:00
|
|
|
if (pScreen->visuals[i].vid == vid) {
|
|
|
|
pVisual = &pScreen->visuals[i];
|
|
|
|
break;
|
|
|
|
}
|
2007-10-18 21:51:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: What exactly should we check here... */
|
2008-03-27 00:28:09 +01:00
|
|
|
if (pVisual->class != glxConvertToXVisualType(config->visualType) ||
|
2012-03-21 20:55:09 +01:00
|
|
|
!(config->drawableType & GLX_WINDOW_BIT)) {
|
|
|
|
client->errorValue = pDraw->id;
|
|
|
|
*err = BadMatch;
|
|
|
|
return FALSE;
|
2007-10-18 21:51:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2011-12-16 23:42:51 +01:00
|
|
|
_X_HIDDEN int
|
2009-04-02 23:24:12 +02:00
|
|
|
validGlxContext(ClientPtr client, XID id, int access_mode,
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLXcontext ** context, int *err)
|
2009-04-02 23:24:12 +02:00
|
|
|
{
|
2018-01-10 19:05:45 +01:00
|
|
|
/* no ghost contexts */
|
2018-05-07 23:21:19 +02:00
|
|
|
if (id & SERVER_BIT) {
|
|
|
|
*err = __glXError(GLXBadContext);
|
2018-01-10 19:05:45 +01:00
|
|
|
return FALSE;
|
2018-05-07 23:21:19 +02:00
|
|
|
}
|
2018-01-10 19:05:45 +01:00
|
|
|
|
2013-12-15 10:05:51 +01:00
|
|
|
*err = dixLookupResourceByType((void **) context, id,
|
2012-03-21 20:55:09 +01:00
|
|
|
__glXContextRes, client, access_mode);
|
2011-03-21 16:59:29 +01:00
|
|
|
if (*err != Success || (*context)->idExists == GL_FALSE) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = id;
|
|
|
|
if (*err == BadValue || *err == Success)
|
|
|
|
*err = __glXError(GLXBadContext);
|
|
|
|
return FALSE;
|
2009-04-02 23:24:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
Add Windows-DRI extension
If windowsdriproto headers are available, build a Windows-DRI extension,
which supports requests to enable local clients to directly render GL to a
Windows drawable:
- a query to check if WGL is being used on a screen
- a query to map a fbconfigID to a native pixelformatindex
- a query to map a drawable to a native handle
Windows-DRI can only be useful if we are using WGL, so make an note if WGL
is active on a screen.
Make validGlxDrawable() public
Adjust glxWinSetPixelFormat() so it doesn't require a context, just a
screen and config.
That enables factoring out the deferred drawable creation code as
glxWinDeferredCreateDrawable()
Enhance glxWinDeferredCreateDrawable(), so that pixmaps are placed into a
file mapping, so they exist in memory which can be shared with the direct
rendering process.
Currently, this file mapping is accessed by a name generated from the XID.
This will not be unique across multiple server instances. It would perhaps
be better, although more complicated, to use an anonymous file mapping, and
then duplicate the handle for the direct rendering process.
Use glxWinDeferredCreateDrawable() to ensure the native handle exists for
the Windows-DRI query to map a drawable to native handle.
v2:
Various printf format warning fixes
v3:
Fix format warnings on x86
Move some uninteresting windows-dri output to debug log level
v4:
check for windowsdriproto when --enable-windowsdri
use windowsdriproto_CFLAGS
Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
2014-07-24 13:29:41 +02:00
|
|
|
int
|
2009-04-07 19:58:53 +02:00
|
|
|
validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLXdrawable ** drawable, int *err)
|
2009-04-07 19:58:53 +02:00
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
2013-12-15 10:05:51 +01:00
|
|
|
rc = dixLookupResourceByType((void **) drawable, id,
|
2012-03-21 20:55:09 +01:00
|
|
|
__glXDrawableRes, client, access_mode);
|
2009-04-07 19:58:53 +02:00
|
|
|
if (rc != Success && rc != BadValue) {
|
2012-03-21 20:55:09 +01:00
|
|
|
*err = rc;
|
|
|
|
client->errorValue = id;
|
|
|
|
return FALSE;
|
2009-04-07 19:58:53 +02:00
|
|
|
}
|
|
|
|
|
2010-04-16 11:55:32 +02:00
|
|
|
/* If the ID of the glx drawable we looked up doesn't match the id
|
|
|
|
* we looked for, it's because we looked it up under the X
|
|
|
|
* drawable ID (see DoCreateGLXDrawable). */
|
2009-04-07 19:58:53 +02:00
|
|
|
if (rc == BadValue ||
|
2012-03-21 20:55:09 +01:00
|
|
|
(*drawable)->drawId != id ||
|
|
|
|
(type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
|
|
|
|
client->errorValue = id;
|
|
|
|
switch (type) {
|
|
|
|
case GLX_DRAWABLE_WINDOW:
|
|
|
|
*err = __glXError(GLXBadWindow);
|
|
|
|
return FALSE;
|
|
|
|
case GLX_DRAWABLE_PIXMAP:
|
|
|
|
*err = __glXError(GLXBadPixmap);
|
|
|
|
return FALSE;
|
|
|
|
case GLX_DRAWABLE_PBUFFER:
|
|
|
|
*err = __glXError(GLXBadPbuffer);
|
|
|
|
return FALSE;
|
|
|
|
case GLX_DRAWABLE_ANY:
|
|
|
|
*err = __glXError(GLXBadDrawable);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-04-07 19:58:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-03-17 01:35:18 +01:00
|
|
|
void
|
2012-03-21 20:55:09 +01:00
|
|
|
__glXContextDestroy(__GLXcontext * context)
|
2006-03-17 01:35:18 +01:00
|
|
|
{
|
2014-04-18 03:18:49 +02:00
|
|
|
lastGLContext = NULL;
|
2006-03-17 01:35:18 +01:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
static void
|
|
|
|
__glXdirectContextDestroy(__GLXcontext * context)
|
2006-03-12 01:11:34 +01:00
|
|
|
{
|
2006-03-17 01:35:18 +01:00
|
|
|
__glXContextDestroy(context);
|
2010-05-05 20:44:06 +02:00
|
|
|
free(context);
|
2006-03-12 01:11:34 +01:00
|
|
|
}
|
|
|
|
|
2014-12-01 22:06:17 +01:00
|
|
|
static int
|
|
|
|
__glXdirectContextLoseCurrent(__GLXcontext * context)
|
|
|
|
{
|
|
|
|
return GL_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-12-16 23:42:51 +01:00
|
|
|
_X_HIDDEN __GLXcontext *
|
2012-03-21 20:55:09 +01:00
|
|
|
__glXdirectContextCreate(__GLXscreen * screen,
|
|
|
|
__GLXconfig * modes, __GLXcontext * shareContext)
|
2006-03-12 01:11:34 +01:00
|
|
|
{
|
|
|
|
__GLXcontext *context;
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
context = calloc(1, sizeof(__GLXcontext));
|
2006-03-12 01:11:34 +01:00
|
|
|
if (context == NULL)
|
2012-03-21 20:55:09 +01:00
|
|
|
return NULL;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2017-11-14 21:15:01 +01:00
|
|
|
context->config = modes;
|
2006-03-12 01:11:34 +01:00
|
|
|
context->destroy = __glXdirectContextDestroy;
|
2014-12-01 22:06:17 +01:00
|
|
|
context->loseCurrent = __glXdirectContextLoseCurrent;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
2004-06-16 11:25:21 +02:00
|
|
|
/**
|
|
|
|
* Create a GL context with the given properties. This routine is used
|
|
|
|
* to implement \c glXCreateContext, \c glXCreateNewContext, and
|
2017-07-31 15:06:47 +02:00
|
|
|
* \c glXCreateContextWithConfigSGIX. This works because of the hack way
|
2004-06-16 11:25:21 +02:00
|
|
|
* that GLXFBConfigs are implemented. Basically, the FBConfigID is the
|
|
|
|
* same as the VisualID.
|
|
|
|
*/
|
|
|
|
|
2007-10-14 20:59:12 +02:00
|
|
|
static int
|
2012-03-21 20:55:09 +01:00
|
|
|
DoCreateContext(__GLXclientState * cl, GLXContextID gcId,
|
|
|
|
GLXContextID shareList, __GLXconfig * config,
|
|
|
|
__GLXscreen * pGlxScreen, GLboolean isDirect)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
__GLXcontext *glxc, *shareglxc;
|
2009-04-02 23:24:12 +02:00
|
|
|
int err;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
/*
|
2014-10-31 00:45:12 +01:00
|
|
|
** Find the display list space that we want to share.
|
2012-03-21 20:55:09 +01:00
|
|
|
**
|
|
|
|
** NOTE: In a multithreaded X server, we would need to keep a reference
|
2014-10-31 00:45:12 +01:00
|
|
|
** count for each display list so that if one client detroyed a list that
|
|
|
|
** another client was using, the list would not really be freed until it
|
|
|
|
** was no longer in use. Since this sample implementation has no support
|
|
|
|
** for multithreaded servers, we don't do this.
|
2012-03-21 20:55:09 +01:00
|
|
|
*/
|
2003-11-14 17:48:57 +01:00
|
|
|
if (shareList == None) {
|
2012-03-21 20:55:09 +01:00
|
|
|
shareglxc = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!validGlxContext(client, shareList, DixReadAccess,
|
|
|
|
&shareglxc, &err))
|
|
|
|
return err;
|
|
|
|
|
2011-12-05 19:55:20 +01:00
|
|
|
/* Page 26 (page 32 of the PDF) of the GLX 1.4 spec says:
|
|
|
|
*
|
|
|
|
* "The server context state for all sharing contexts must exist
|
|
|
|
* in a single address space or a BadMatch error is generated."
|
|
|
|
*
|
|
|
|
* If the share context is indirect, force the new context to also be
|
|
|
|
* indirect. If the shard context is direct but the new context
|
|
|
|
* cannot be direct, generate BadMatch.
|
|
|
|
*/
|
|
|
|
if (shareglxc->isDirect && !isDirect) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = shareList;
|
|
|
|
return BadMatch;
|
|
|
|
}
|
2011-12-05 19:55:20 +01:00
|
|
|
else if (!shareglxc->isDirect) {
|
2012-03-21 20:55:09 +01:00
|
|
|
/*
|
|
|
|
** Create an indirect context regardless of what the client asked
|
|
|
|
** for; this way we can share display list space with shareList.
|
|
|
|
*/
|
|
|
|
isDirect = GL_FALSE;
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-03-21 20:55:09 +01:00
|
|
|
** Allocate memory for the new context
|
|
|
|
*/
|
2011-12-05 19:56:07 +01:00
|
|
|
if (!isDirect) {
|
2014-04-23 18:52:17 +02:00
|
|
|
/* Only allow creating indirect GLX contexts if allowed by
|
|
|
|
* server command line. Indirect GLX is of limited use (since
|
|
|
|
* it's only GL 1.4), it's slower than direct contexts, and
|
|
|
|
* it's a massive attack surface for buffer overflow type
|
|
|
|
* errors.
|
|
|
|
*/
|
|
|
|
if (!enableIndirectGLX) {
|
|
|
|
client->errorValue = isDirect;
|
|
|
|
return BadValue;
|
|
|
|
}
|
|
|
|
|
2011-12-05 19:56:07 +01:00
|
|
|
/* Without any attributes, the only error that the driver should be
|
|
|
|
* able to generate is BadAlloc. As result, just drop the error
|
|
|
|
* returned from the driver on the floor.
|
|
|
|
*/
|
|
|
|
glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc,
|
|
|
|
0, NULL, &err);
|
|
|
|
}
|
2006-03-12 01:11:34 +01:00
|
|
|
else
|
2012-03-21 20:55:09 +01:00
|
|
|
glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
|
2003-11-14 17:48:57 +01:00
|
|
|
if (!glxc) {
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadAlloc;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2011-12-11 00:09:57 +01:00
|
|
|
/* Initialize the GLXcontext structure.
|
2012-03-21 20:55:09 +01:00
|
|
|
*/
|
2003-11-14 17:48:57 +01:00
|
|
|
glxc->pGlxScreen = pGlxScreen;
|
2008-03-27 00:28:09 +01:00
|
|
|
glxc->config = config;
|
2003-11-14 17:48:57 +01:00
|
|
|
glxc->id = gcId;
|
|
|
|
glxc->share_id = shareList;
|
|
|
|
glxc->idExists = GL_TRUE;
|
|
|
|
glxc->isDirect = isDirect;
|
|
|
|
glxc->renderMode = GL_RENDER;
|
|
|
|
|
2012-07-05 00:21:07 +02:00
|
|
|
/* The GLX_ARB_create_context_robustness spec says:
|
|
|
|
*
|
|
|
|
* "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
|
|
|
|
* is GLX_NO_RESET_NOTIFICATION_ARB."
|
|
|
|
*
|
|
|
|
* Without using glXCreateContextAttribsARB, there is no way to specify a
|
|
|
|
* non-default reset notification strategy.
|
|
|
|
*/
|
|
|
|
glxc->resetNotificationStrategy = GLX_NO_RESET_NOTIFICATION_ARB;
|
|
|
|
|
2015-05-19 17:31:25 +02:00
|
|
|
#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
|
|
|
|
/* The GLX_ARB_context_flush_control spec says:
|
|
|
|
*
|
|
|
|
* "The default value [for GLX_CONTEXT_RELEASE_BEHAVIOR] is
|
|
|
|
* CONTEXT_RELEASE_BEHAVIOR_FLUSH, and may in some cases be changed
|
|
|
|
* using platform-specific context creation extensions."
|
|
|
|
*
|
|
|
|
* Without using glXCreateContextAttribsARB, there is no way to specify a
|
|
|
|
* non-default release behavior.
|
|
|
|
*/
|
|
|
|
glxc->releaseBehavior = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB;
|
|
|
|
#endif
|
|
|
|
|
2011-12-11 00:15:18 +01:00
|
|
|
/* Add the new context to the various global tables of GLX contexts.
|
2011-12-11 00:09:57 +01:00
|
|
|
*/
|
2011-12-11 00:15:18 +01:00
|
|
|
if (!__glXAddContext(glxc)) {
|
2011-12-11 00:09:57 +01:00
|
|
|
(*glxc->destroy) (glxc);
|
|
|
|
client->errorValue = gcId;
|
|
|
|
return BadAlloc;
|
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CreateContext(__GLXclientState * cl, GLbyte * pc)
|
2004-06-16 11:25:21 +02:00
|
|
|
{
|
|
|
|
xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
|
2008-03-27 00:28:09 +01:00
|
|
|
__GLXconfig *config;
|
2007-10-18 21:51:11 +02:00
|
|
|
__GLXscreen *pGlxScreen;
|
|
|
|
int err;
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
|
|
|
|
return DoCreateContext(cl, req->context, req->shareList,
|
2012-03-21 20:55:09 +01:00
|
|
|
config, pGlxScreen, req->isDirect);
|
2007-10-18 21:51:11 +02:00
|
|
|
}
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CreateNewContext(__GLXclientState * cl, GLbyte * pc)
|
2004-06-16 11:25:21 +02:00
|
|
|
{
|
|
|
|
xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
|
2008-03-27 00:28:09 +01:00
|
|
|
__GLXconfig *config;
|
2007-10-18 21:51:11 +02:00
|
|
|
__GLXscreen *pGlxScreen;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
return DoCreateContext(cl, req->context, req->shareList,
|
2012-03-21 20:55:09 +01:00
|
|
|
config, pGlxScreen, req->isDirect);
|
2007-10-18 21:51:11 +02:00
|
|
|
}
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CreateContextWithConfigSGIX(__GLXclientState * cl, GLbyte * pc)
|
2004-06-16 11:25:21 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2012-03-21 20:55:09 +01:00
|
|
|
xGLXCreateContextWithConfigSGIXReq *req =
|
|
|
|
(xGLXCreateContextWithConfigSGIXReq *) pc;
|
2008-03-27 00:28:09 +01:00
|
|
|
__GLXconfig *config;
|
2007-10-18 21:51:11 +02:00
|
|
|
__GLXscreen *pGlxScreen;
|
|
|
|
int err;
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq);
|
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
|
|
|
|
return DoCreateContext(cl, req->context, req->shareList,
|
2012-03-21 20:55:09 +01:00
|
|
|
config, pGlxScreen, req->isDirect);
|
2007-10-18 21:51:11 +02:00
|
|
|
}
|
2011-03-21 16:59:29 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_DestroyContext(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
|
|
|
|
__GLXcontext *glxc;
|
2009-04-02 23:24:12 +02:00
|
|
|
int err;
|
|
|
|
|
|
|
|
if (!validGlxContext(cl->client, req->context, DixDestroyAccess,
|
2012-03-21 20:55:09 +01:00
|
|
|
&glxc, &err))
|
|
|
|
return err;
|
2009-04-02 23:24:12 +02:00
|
|
|
|
2014-04-18 13:17:04 +02:00
|
|
|
glxc->idExists = GL_FALSE;
|
2018-01-10 19:05:45 +01:00
|
|
|
if (glxc->currentClient) {
|
|
|
|
XID ghost = FakeClientID(glxc->currentClient->index);
|
|
|
|
|
|
|
|
if (!AddResource(ghost, __glXContextRes, glxc))
|
|
|
|
return BadAlloc;
|
|
|
|
ChangeResourceValue(glxc->id, __glXContextRes, NULL);
|
|
|
|
glxc->id = ghost;
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeResourceByType(req->context, __glXContextRes, FALSE);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2011-03-21 16:59:29 +01:00
|
|
|
return Success;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLXcontext *
|
|
|
|
__glXLookupContextByTag(__GLXclientState * cl, GLXContextTag tag)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2018-01-10 19:05:45 +01:00
|
|
|
return glxServer.getContextTagPrivate(cl->client, tag);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2017-11-14 21:15:02 +01:00
|
|
|
static __GLXconfig *
|
|
|
|
inferConfigForWindow(__GLXscreen *pGlxScreen, WindowPtr pWin)
|
|
|
|
{
|
|
|
|
int i, vid = wVisual(pWin);
|
|
|
|
|
|
|
|
for (i = 0; i < pGlxScreen->numVisuals; i++)
|
|
|
|
if (pGlxScreen->visuals[i]->visualID == vid)
|
|
|
|
return pGlxScreen->visuals[i];
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-11-25 20:29:01 +01:00
|
|
|
/**
|
2009-04-07 19:58:53 +02:00
|
|
|
* This is a helper function to handle the legacy (pre GLX 1.3) cases
|
|
|
|
* where passing an X window to glXMakeCurrent is valid. Given a
|
|
|
|
* resource ID, look up the GLX drawable if available, otherwise, make
|
|
|
|
* sure it's an X window and create a GLX drawable one the fly.
|
2003-11-25 20:29:01 +01:00
|
|
|
*/
|
2007-08-24 01:07:52 +02:00
|
|
|
static __GLXdrawable *
|
2012-03-21 20:55:09 +01:00
|
|
|
__glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
|
|
|
|
int *error)
|
2003-11-25 20:29:01 +01:00
|
|
|
{
|
|
|
|
DrawablePtr pDraw;
|
2006-06-29 10:25:54 +02:00
|
|
|
__GLXdrawable *pGlxDraw;
|
2017-11-14 21:15:02 +01:00
|
|
|
__GLXconfig *config;
|
|
|
|
__GLXscreen *pGlxScreen;
|
2006-12-15 22:36:29 +01:00
|
|
|
int rc;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2009-04-07 19:58:53 +02:00
|
|
|
if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
|
2012-03-21 20:55:09 +01:00
|
|
|
DixWriteAccess, &pGlxDraw, &rc)) {
|
2017-11-14 21:15:02 +01:00
|
|
|
if (glxc != NULL &&
|
|
|
|
glxc->config != NULL &&
|
|
|
|
glxc->config != pGlxDraw->config) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = drawId;
|
|
|
|
*error = BadMatch;
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-06-29 10:25:54 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
return pGlxDraw;
|
2006-06-29 10:25:54 +02:00
|
|
|
}
|
|
|
|
|
2010-06-24 13:24:58 +02:00
|
|
|
/* No active context and an unknown drawable, bail. */
|
|
|
|
if (glxc == NULL) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = drawId;
|
|
|
|
*error = BadMatch;
|
|
|
|
return NULL;
|
2010-06-24 13:24:58 +02:00
|
|
|
}
|
|
|
|
|
2009-04-07 19:58:53 +02:00
|
|
|
/* The drawId wasn't a GLX drawable. Make sure it's a window and
|
|
|
|
* create a GLXWindow for it. Check that the drawable screen
|
|
|
|
* matches the context screen and that the context fbconfig is
|
|
|
|
* compatible with the window visual. */
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2008-02-28 22:43:43 +01:00
|
|
|
rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
|
2007-08-24 01:07:52 +02:00
|
|
|
if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = drawId;
|
|
|
|
*error = __glXError(GLXBadDrawable);
|
|
|
|
return NULL;
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
|
2017-11-14 21:15:02 +01:00
|
|
|
pGlxScreen = glxc->pGlxScreen;
|
|
|
|
if (pDraw->pScreen != pGlxScreen->pScreen) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = pDraw->pScreen->myNum;
|
|
|
|
*error = BadMatch;
|
|
|
|
return NULL;
|
2006-06-29 10:25:54 +02:00
|
|
|
}
|
|
|
|
|
2017-11-14 21:15:02 +01:00
|
|
|
config = glxc->config;
|
|
|
|
if (!config)
|
|
|
|
config = inferConfigForWindow(pGlxScreen, (WindowPtr)pDraw);
|
|
|
|
if (!config) {
|
|
|
|
/*
|
|
|
|
* If we get here, we've tried to bind a no-config context to a
|
|
|
|
* window without a corresponding fbconfig, presumably because
|
|
|
|
* we don't support GL on it (PseudoColor perhaps). From GLX Section
|
|
|
|
* 3.3.7 "Rendering Contexts":
|
|
|
|
*
|
|
|
|
* "If draw or read are not compatible with ctx a BadMatch error
|
|
|
|
* is generated."
|
|
|
|
*/
|
|
|
|
*error = BadMatch;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!validGlxFBConfigForWindow(client, config, pDraw, error))
|
2012-03-21 20:55:09 +01:00
|
|
|
return NULL;
|
2006-06-29 10:25:54 +02:00
|
|
|
|
2017-11-14 21:15:02 +01:00
|
|
|
pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, drawId,
|
|
|
|
GLX_DRAWABLE_WINDOW, drawId, config);
|
2013-07-08 23:01:13 +02:00
|
|
|
if (!pGlxDraw) {
|
|
|
|
*error = BadAlloc;
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-06-29 10:25:54 +02:00
|
|
|
|
|
|
|
/* since we are creating the drawablePrivate, drawId should be new */
|
|
|
|
if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
|
2012-03-21 20:55:09 +01:00
|
|
|
*error = BadAlloc;
|
|
|
|
return NULL;
|
2006-06-29 10:25:54 +02:00
|
|
|
}
|
|
|
|
|
2007-08-24 01:07:52 +02:00
|
|
|
return pGlxDraw;
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
|
2007-10-14 20:59:12 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
** Make an OpenGL context and drawable current.
|
|
|
|
*/
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2018-01-10 19:05:45 +01:00
|
|
|
int
|
|
|
|
xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId,
|
|
|
|
XID contextId, GLXContextTag newContextTag)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2018-01-10 19:05:45 +01:00
|
|
|
__GLXclientState *cl = glxGetClient(client);
|
|
|
|
__GLXcontext *glxc = NULL, *prevglxc = NULL;
|
2006-03-12 01:11:34 +01:00
|
|
|
__GLXdrawable *drawPriv = NULL;
|
|
|
|
__GLXdrawable *readPriv = NULL;
|
2009-04-02 23:24:12 +02:00
|
|
|
int error;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2017-03-20 18:08:19 +01:00
|
|
|
/* Drawables but no context makes no sense */
|
|
|
|
if (!contextId && (drawId || readId))
|
|
|
|
return BadMatch;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2017-03-20 18:08:19 +01:00
|
|
|
/* If either drawable is null, the other must be too */
|
|
|
|
if ((drawId == None) != (readId == None))
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadMatch;
|
|
|
|
|
2018-01-10 19:05:45 +01:00
|
|
|
/* Look up old context. If we have one, it must be in a usable state. */
|
2003-11-14 17:48:57 +01:00
|
|
|
if (tag != 0) {
|
2018-01-10 19:05:45 +01:00
|
|
|
prevglxc = glxServer.getContextTagPrivate(client, tag);
|
|
|
|
if (!prevglxc)
|
2012-03-21 20:55:09 +01:00
|
|
|
return __glXError(GLXBadContextTag);
|
2018-01-10 19:05:45 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if (prevglxc->renderMode != GL_RENDER) {
|
|
|
|
/* Oops. Not in render mode render. */
|
|
|
|
client->errorValue = prevglxc->id;
|
|
|
|
return __glXError(GLXBadContextState);
|
|
|
|
}
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2018-01-10 19:05:45 +01:00
|
|
|
/* Look up new context. It must not be current for someone else. */
|
2003-11-14 17:48:57 +01:00
|
|
|
if (contextId != None) {
|
2012-03-21 20:55:09 +01:00
|
|
|
int status;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error))
|
|
|
|
return error;
|
2018-01-10 19:05:45 +01:00
|
|
|
|
|
|
|
if ((glxc != prevglxc) && glxc->currentClient)
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadAccess;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2017-03-20 18:08:19 +01:00
|
|
|
if (drawId) {
|
|
|
|
drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
|
|
|
|
if (drawPriv == NULL)
|
|
|
|
return status;
|
|
|
|
}
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2017-03-20 18:08:19 +01:00
|
|
|
if (readId) {
|
|
|
|
readPriv = __glXGetDrawable(glxc, readId, client, &status);
|
|
|
|
if (readPriv == NULL)
|
|
|
|
return status;
|
|
|
|
}
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
if (prevglxc) {
|
2018-01-10 19:05:45 +01:00
|
|
|
/* Flush the previous context if needed. */
|
2017-11-14 21:59:35 +01:00
|
|
|
Bool need_flush = !prevglxc->isDirect;
|
2015-05-19 17:31:25 +02:00
|
|
|
#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
|
|
|
|
if (prevglxc->releaseBehavior == GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB)
|
|
|
|
need_flush = GL_FALSE;
|
|
|
|
#endif
|
2016-03-31 22:56:44 +02:00
|
|
|
if (need_flush) {
|
2018-01-10 19:05:45 +01:00
|
|
|
if (!__glXForceCurrent(cl, tag, (int *) &error))
|
2012-03-21 20:55:09 +01:00
|
|
|
return error;
|
2018-01-10 19:05:45 +01:00
|
|
|
glFlush();
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 19:05:45 +01:00
|
|
|
/* Make the previous context not current. */
|
|
|
|
if (!(*prevglxc->loseCurrent) (prevglxc))
|
2012-03-21 20:55:09 +01:00
|
|
|
return __glXError(GLXBadContext);
|
2018-01-10 19:05:45 +01:00
|
|
|
|
2014-04-18 03:18:49 +02:00
|
|
|
lastGLContext = NULL;
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!prevglxc->isDirect) {
|
|
|
|
prevglxc->drawPriv = NULL;
|
|
|
|
prevglxc->readPriv = NULL;
|
|
|
|
}
|
|
|
|
}
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2018-01-10 19:05:45 +01:00
|
|
|
if (glxc && !glxc->isDirect) {
|
2012-03-21 20:55:09 +01:00
|
|
|
glxc->drawPriv = drawPriv;
|
|
|
|
glxc->readPriv = readPriv;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* make the context current */
|
2014-04-18 03:23:51 +02:00
|
|
|
lastGLContext = glxc;
|
2012-03-21 20:55:09 +01:00
|
|
|
if (!(*glxc->makeCurrent) (glxc)) {
|
2014-04-18 03:23:51 +02:00
|
|
|
lastGLContext = NULL;
|
2012-03-21 20:55:09 +01:00
|
|
|
glxc->drawPriv = NULL;
|
|
|
|
glxc->readPriv = NULL;
|
|
|
|
return __glXError(GLXBadContext);
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
glx: Fix memory leak in context garbage collection (v2)
I broke this, back in:
commit a48dadc98a28c969741979b70b7a639f24f4cbbd
Author: Adam Jackson <ajax@redhat.com>
Date: Mon Mar 21 11:59:29 2011 -0400
glx: Reimplement context tags
In that, I changed the glx client state to not explicitly track the list
of current contexts for the client (since that was what we were deriving
tags from). The bug was that I removed the code for same from
glxClientCallback without noticing that it had the side effect of
effectively de-currenting those contexts, so that ContextGone could free
them. So, if you had a client exit with a context still current, the
context's memory would leak. Not a huge deal for direct clients, but
viciously bad for indirect, since the swrast context state at the bottom
of Mesa is like 15M.
Fix this by promoting Bool isCurrent to ClientPtr currentClient, so that
we have a back-pointer to chase when walking the list of contexts when
ClientStateGone happens.
v2: Explicitly call __glXFreeContext on the ClientStateGone path. Our
current context might be one we got from EXT_import_context and whose
creating client has since died. Without the explicit call, the creating
client's FreeClientResources would not free the context because it's
still current, and the using client's FreeClientResources would not free
the context because it's not an XID it created. This matches the logic
from a48dadc.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
2013-08-03 15:47:55 +02:00
|
|
|
glxc->currentClient = client;
|
2018-01-10 19:05:45 +01:00
|
|
|
glxServer.setContextTagPrivate(client, newContextTag, glxc);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 19:05:45 +01:00
|
|
|
if (prevglxc) {
|
|
|
|
prevglxc->currentClient = NULL;
|
|
|
|
if (!prevglxc->idExists) {
|
|
|
|
FreeResourceByType(prevglxc->id, __glXContextRes, FALSE);
|
|
|
|
}
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_MakeCurrent(__GLXclientState * cl, GLbyte * pc)
|
2007-10-14 20:59:12 +02:00
|
|
|
{
|
2018-01-10 19:05:45 +01:00
|
|
|
return BadImplementation;
|
2007-10-14 20:59:12 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_MakeContextCurrent(__GLXclientState * cl, GLbyte * pc)
|
2007-10-14 20:59:12 +02:00
|
|
|
{
|
2018-01-10 19:05:45 +01:00
|
|
|
return BadImplementation;
|
2007-10-14 20:59:12 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_MakeCurrentReadSGI(__GLXclientState * cl, GLbyte * pc)
|
2007-10-14 20:59:12 +02:00
|
|
|
{
|
2018-01-10 19:05:45 +01:00
|
|
|
return BadImplementation;
|
2007-10-14 20:59:12 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_IsDirect(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
|
|
|
|
xGLXIsDirectReply reply;
|
|
|
|
__GLXcontext *glxc;
|
2009-04-02 23:24:12 +02:00
|
|
|
int err;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2009-04-02 23:24:12 +02:00
|
|
|
if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-07-10 04:12:43 +02:00
|
|
|
reply = (xGLXIsDirectReply) {
|
|
|
|
.type = X_Reply,
|
|
|
|
.sequenceNumber = client->sequence,
|
|
|
|
.length = 0,
|
|
|
|
.isDirect = glxc->isDirect
|
|
|
|
};
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
if (client->swapped) {
|
2017-08-16 20:49:17 +02:00
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
|
|
__GLX_SWAP_INT(&reply.length);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2017-08-16 20:49:17 +02:00
|
|
|
WriteToClient(client, sz_xGLXIsDirectReply, &reply);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_QueryVersion(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
|
|
|
|
xGLXQueryVersionReply reply;
|
|
|
|
GLuint major, minor;
|
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_SIZE_MATCH(xGLXQueryVersionReq);
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
major = req->majorVersion;
|
|
|
|
minor = req->minorVersion;
|
2012-03-21 20:55:09 +01:00
|
|
|
(void) major;
|
|
|
|
(void) minor;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
/*
|
2012-03-21 20:55:09 +01:00
|
|
|
** Server should take into consideration the version numbers sent by the
|
|
|
|
** client if it wants to work with older clients; however, in this
|
|
|
|
** implementation the server just returns its version number.
|
|
|
|
*/
|
2012-07-10 04:12:43 +02:00
|
|
|
reply = (xGLXQueryVersionReply) {
|
|
|
|
.type = X_Reply,
|
|
|
|
.sequenceNumber = client->sequence,
|
|
|
|
.length = 0,
|
2016-03-23 20:26:23 +01:00
|
|
|
.majorVersion = SERVER_GLX_MAJOR_VERSION,
|
|
|
|
.minorVersion = SERVER_GLX_MINOR_VERSION
|
2012-07-10 04:12:43 +02:00
|
|
|
};
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
if (client->swapped) {
|
2017-08-16 20:49:17 +02:00
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
|
|
__GLX_SWAP_INT(&reply.length);
|
|
|
|
__GLX_SWAP_INT(&reply.majorVersion);
|
|
|
|
__GLX_SWAP_INT(&reply.minorVersion);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2017-08-16 20:49:17 +02:00
|
|
|
|
|
|
|
WriteToClient(client, sz_xGLXQueryVersionReply, &reply);
|
2003-11-14 17:48:57 +01:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_WaitGL(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc;
|
2010-07-03 20:47:55 +02:00
|
|
|
GLXContextTag tag;
|
2009-02-16 12:39:34 +01:00
|
|
|
__GLXcontext *glxc = NULL;
|
2003-11-14 17:48:57 +01:00
|
|
|
int error;
|
2009-02-16 12:39:34 +01:00
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
tag = req->contextTag;
|
2009-02-16 12:39:34 +01:00
|
|
|
if (tag) {
|
2012-03-21 20:55:09 +01:00
|
|
|
glxc = __glXLookupContextByTag(cl, tag);
|
|
|
|
if (!glxc)
|
|
|
|
return __glXError(GLXBadContextTag);
|
|
|
|
|
|
|
|
if (!__glXForceCurrent(cl, req->contextTag, &error))
|
|
|
|
return error;
|
2009-02-16 12:39:34 +01:00
|
|
|
|
2013-07-10 16:00:46 +02:00
|
|
|
glFinish();
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2009-02-16 12:39:34 +01:00
|
|
|
|
|
|
|
if (glxc && glxc->drawPriv->waitGL)
|
2012-03-21 20:55:09 +01:00
|
|
|
(*glxc->drawPriv->waitGL) (glxc->drawPriv);
|
2009-02-16 12:39:34 +01:00
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_WaitX(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
|
2010-07-03 20:47:55 +02:00
|
|
|
GLXContextTag tag;
|
2009-02-16 12:39:34 +01:00
|
|
|
__GLXcontext *glxc = NULL;
|
2003-11-14 17:48:57 +01:00
|
|
|
int error;
|
2009-02-16 12:39:34 +01:00
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
tag = req->contextTag;
|
2009-02-16 12:39:34 +01:00
|
|
|
if (tag) {
|
2012-03-21 20:55:09 +01:00
|
|
|
glxc = __glXLookupContextByTag(cl, tag);
|
|
|
|
if (!glxc)
|
|
|
|
return __glXError(GLXBadContextTag);
|
|
|
|
|
|
|
|
if (!__glXForceCurrent(cl, req->contextTag, &error))
|
|
|
|
return error;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2009-02-16 12:39:34 +01:00
|
|
|
|
2009-04-19 21:15:22 +02:00
|
|
|
if (glxc && glxc->drawPriv->waitX)
|
2012-03-21 20:55:09 +01:00
|
|
|
(*glxc->drawPriv->waitX) (glxc->drawPriv);
|
2009-02-16 12:39:34 +01:00
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CopyContext(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
|
2010-07-03 20:47:55 +02:00
|
|
|
GLXContextID source;
|
|
|
|
GLXContextID dest;
|
|
|
|
GLXContextTag tag;
|
|
|
|
unsigned long mask;
|
2003-11-14 17:48:57 +01:00
|
|
|
__GLXcontext *src, *dst;
|
|
|
|
int error;
|
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
source = req->source;
|
|
|
|
dest = req->dest;
|
|
|
|
tag = req->contextTag;
|
|
|
|
mask = req->mask;
|
2009-04-02 23:24:12 +02:00
|
|
|
if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error))
|
2012-03-21 20:55:09 +01:00
|
|
|
return error;
|
2009-04-02 23:24:12 +02:00
|
|
|
if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error))
|
2012-03-21 20:55:09 +01:00
|
|
|
return error;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
/*
|
2012-03-21 20:55:09 +01:00
|
|
|
** They must be in the same address space, and same screen.
|
|
|
|
** NOTE: no support for direct rendering contexts here.
|
|
|
|
*/
|
|
|
|
if (src->isDirect || dst->isDirect || (src->pGlxScreen != dst->pGlxScreen)) {
|
|
|
|
client->errorValue = source;
|
|
|
|
return BadMatch;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-03-21 20:55:09 +01:00
|
|
|
** The destination context must not be current for any client.
|
|
|
|
*/
|
glx: Fix memory leak in context garbage collection (v2)
I broke this, back in:
commit a48dadc98a28c969741979b70b7a639f24f4cbbd
Author: Adam Jackson <ajax@redhat.com>
Date: Mon Mar 21 11:59:29 2011 -0400
glx: Reimplement context tags
In that, I changed the glx client state to not explicitly track the list
of current contexts for the client (since that was what we were deriving
tags from). The bug was that I removed the code for same from
glxClientCallback without noticing that it had the side effect of
effectively de-currenting those contexts, so that ContextGone could free
them. So, if you had a client exit with a context still current, the
context's memory would leak. Not a huge deal for direct clients, but
viciously bad for indirect, since the swrast context state at the bottom
of Mesa is like 15M.
Fix this by promoting Bool isCurrent to ClientPtr currentClient, so that
we have a back-pointer to chase when walking the list of contexts when
ClientStateGone happens.
v2: Explicitly call __glXFreeContext on the ClientStateGone path. Our
current context might be one we got from EXT_import_context and whose
creating client has since died. Without the explicit call, the creating
client's FreeClientResources would not free the context because it's
still current, and the using client's FreeClientResources would not free
the context because it's not an XID it created. This matches the logic
from a48dadc.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
2013-08-03 15:47:55 +02:00
|
|
|
if (dst->currentClient) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = dest;
|
|
|
|
return BadAccess;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag) {
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
|
|
|
|
|
|
|
|
if (!tagcx) {
|
|
|
|
return __glXError(GLXBadContextTag);
|
|
|
|
}
|
|
|
|
if (tagcx != src) {
|
|
|
|
/*
|
|
|
|
** This would be caused by a faulty implementation of the client
|
|
|
|
** library.
|
|
|
|
*/
|
|
|
|
return BadMatch;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
** In this case, glXCopyContext is in both GL and X streams, in terms
|
|
|
|
** of sequentiality.
|
|
|
|
*/
|
|
|
|
if (__glXForceCurrent(cl, tag, &error)) {
|
|
|
|
/*
|
|
|
|
** Do whatever is needed to make sure that all preceding requests
|
|
|
|
** in both streams are completed before the copy is executed.
|
|
|
|
*/
|
2013-07-10 16:00:46 +02:00
|
|
|
glFinish();
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
return error;
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
/*
|
2012-03-21 20:55:09 +01:00
|
|
|
** Issue copy. The only reason for failure is a bad mask.
|
|
|
|
*/
|
|
|
|
if (!(*dst->copy) (dst, src, mask)) {
|
|
|
|
client->errorValue = mask;
|
|
|
|
return BadValue;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2009-05-29 23:27:46 +02:00
|
|
|
enum {
|
|
|
|
GLX_VIS_CONFIG_UNPAIRED = 18,
|
2013-03-11 10:21:28 +01:00
|
|
|
GLX_VIS_CONFIG_PAIRED = 22
|
2009-05-29 23:27:46 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED
|
|
|
|
};
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2007-10-18 21:51:11 +02:00
|
|
|
xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
|
2003-11-14 17:48:57 +01:00
|
|
|
ClientPtr client = cl->client;
|
|
|
|
xGLXGetVisualConfigsReply reply;
|
2006-03-12 01:11:34 +01:00
|
|
|
__GLXscreen *pGlxScreen;
|
2008-03-27 00:28:09 +01:00
|
|
|
__GLXconfig *modes;
|
2009-05-29 23:27:46 +02:00
|
|
|
CARD32 buf[GLX_VIS_CONFIG_TOTAL];
|
2007-10-18 21:51:11 +02:00
|
|
|
int p, i, err;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2004-06-16 11:25:21 +02:00
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_DECLARE_SWAP_ARRAY_VARIABLES;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-07-10 04:12:43 +02:00
|
|
|
reply = (xGLXGetVisualConfigsReply) {
|
|
|
|
.type = X_Reply,
|
|
|
|
.sequenceNumber = client->sequence,
|
|
|
|
.length = (pGlxScreen->numVisuals *
|
|
|
|
__GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2,
|
|
|
|
.numVisuals = pGlxScreen->numVisuals,
|
|
|
|
.numProps = GLX_VIS_CONFIG_TOTAL
|
|
|
|
};
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2007-10-14 20:59:12 +02:00
|
|
|
if (client->swapped) {
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
|
|
__GLX_SWAP_INT(&reply.length);
|
|
|
|
__GLX_SWAP_INT(&reply.numVisuals);
|
|
|
|
__GLX_SWAP_INT(&reply.numProps);
|
2004-06-16 11:25:21 +02:00
|
|
|
}
|
|
|
|
|
2012-05-13 09:03:35 +02:00
|
|
|
WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
for (i = 0; i < pGlxScreen->numVisuals; i++) {
|
2012-03-21 20:55:09 +01:00
|
|
|
modes = pGlxScreen->visuals[i];
|
|
|
|
|
|
|
|
p = 0;
|
|
|
|
buf[p++] = modes->visualID;
|
|
|
|
buf[p++] = glxConvertToXVisualType(modes->visualType);
|
|
|
|
buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE;
|
|
|
|
|
|
|
|
buf[p++] = modes->redBits;
|
|
|
|
buf[p++] = modes->greenBits;
|
|
|
|
buf[p++] = modes->blueBits;
|
|
|
|
buf[p++] = modes->alphaBits;
|
|
|
|
buf[p++] = modes->accumRedBits;
|
|
|
|
buf[p++] = modes->accumGreenBits;
|
|
|
|
buf[p++] = modes->accumBlueBits;
|
|
|
|
buf[p++] = modes->accumAlphaBits;
|
|
|
|
|
|
|
|
buf[p++] = modes->doubleBufferMode;
|
|
|
|
buf[p++] = modes->stereoMode;
|
|
|
|
|
|
|
|
buf[p++] = modes->rgbBits;
|
|
|
|
buf[p++] = modes->depthBits;
|
|
|
|
buf[p++] = modes->stencilBits;
|
|
|
|
buf[p++] = modes->numAuxBuffers;
|
|
|
|
buf[p++] = modes->level;
|
|
|
|
|
|
|
|
assert(p == GLX_VIS_CONFIG_UNPAIRED);
|
2014-10-31 00:45:12 +01:00
|
|
|
/*
|
2012-03-21 20:55:09 +01:00
|
|
|
** Add token/value pairs for extensions.
|
|
|
|
*/
|
|
|
|
buf[p++] = GLX_VISUAL_CAVEAT_EXT;
|
|
|
|
buf[p++] = modes->visualRating;
|
|
|
|
buf[p++] = GLX_TRANSPARENT_TYPE;
|
|
|
|
buf[p++] = modes->transparentPixel;
|
|
|
|
buf[p++] = GLX_TRANSPARENT_RED_VALUE;
|
|
|
|
buf[p++] = modes->transparentRed;
|
|
|
|
buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
|
|
|
|
buf[p++] = modes->transparentGreen;
|
|
|
|
buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
|
|
|
|
buf[p++] = modes->transparentBlue;
|
|
|
|
buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
|
|
|
|
buf[p++] = modes->transparentAlpha;
|
|
|
|
buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
|
|
|
|
buf[p++] = modes->transparentIndex;
|
|
|
|
buf[p++] = GLX_SAMPLES_SGIS;
|
|
|
|
buf[p++] = modes->samples;
|
|
|
|
buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
|
|
|
|
buf[p++] = modes->sampleBuffers;
|
2017-01-19 23:20:49 +01:00
|
|
|
buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
|
|
|
|
buf[p++] = modes->visualSelectGroup;
|
2013-03-11 10:21:28 +01:00
|
|
|
/* Add attribute only if its value is not default. */
|
|
|
|
if (modes->sRGBCapable != GL_FALSE) {
|
|
|
|
buf[p++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT;
|
|
|
|
buf[p++] = modes->sRGBCapable;
|
|
|
|
}
|
2017-01-19 23:20:49 +01:00
|
|
|
/* Pad with zeroes, so that attributes count is constant. */
|
2013-03-11 10:21:28 +01:00
|
|
|
while (p < GLX_VIS_CONFIG_TOTAL) {
|
|
|
|
buf[p++] = 0;
|
|
|
|
buf[p++] = 0;
|
|
|
|
}
|
2012-03-21 20:55:09 +01:00
|
|
|
|
|
|
|
assert(p == GLX_VIS_CONFIG_TOTAL);
|
|
|
|
if (client->swapped) {
|
|
|
|
__GLX_SWAP_INT_ARRAY(buf, p);
|
|
|
|
}
|
2012-05-13 09:03:35 +02:00
|
|
|
WriteToClient(client, __GLX_SIZE_CARD32 * p, buf);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2013-07-09 17:19:11 +02:00
|
|
|
#define __GLX_TOTAL_FBCONFIG_ATTRIBS (44)
|
2005-07-06 09:16:19 +02:00
|
|
|
#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
|
2004-06-16 11:25:21 +02:00
|
|
|
/**
|
|
|
|
* Send the set of GLXFBConfigs to the client. There is not currently
|
|
|
|
* and interface into the driver on the server-side to get GLXFBConfigs,
|
|
|
|
* so we "invent" some based on the \c __GLXvisualConfig structures that
|
|
|
|
* the driver does supply.
|
2014-10-31 00:45:12 +01:00
|
|
|
*
|
2004-06-16 11:25:21 +02:00
|
|
|
* The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
|
|
|
|
* is the same, so this routine pulls double duty.
|
|
|
|
*/
|
|
|
|
|
2007-10-14 20:59:12 +02:00
|
|
|
static int
|
2012-03-21 20:55:09 +01:00
|
|
|
DoGetFBConfigs(__GLXclientState * cl, unsigned screen)
|
2004-06-16 11:25:21 +02:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
xGLXGetFBConfigsReply reply;
|
2006-03-12 01:11:34 +01:00
|
|
|
__GLXscreen *pGlxScreen;
|
2005-07-06 09:16:19 +02:00
|
|
|
CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
|
2007-10-18 21:51:11 +02:00
|
|
|
int p, err;
|
2008-03-27 00:28:09 +01:00
|
|
|
__GLXconfig *modes;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2004-06-16 11:25:21 +02:00
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_DECLARE_SWAP_ARRAY_VARIABLES;
|
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2012-07-10 04:12:43 +02:00
|
|
|
reply = (xGLXGetFBConfigsReply) {
|
|
|
|
.type = X_Reply,
|
|
|
|
.sequenceNumber = client->sequence,
|
|
|
|
.length = __GLX_FBCONFIG_ATTRIBS_LENGTH * pGlxScreen->numFBConfigs,
|
|
|
|
.numFBConfigs = pGlxScreen->numFBConfigs,
|
|
|
|
.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS
|
|
|
|
};
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2007-10-15 19:10:10 +02:00
|
|
|
if (client->swapped) {
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
|
|
__GLX_SWAP_INT(&reply.length);
|
|
|
|
__GLX_SWAP_INT(&reply.numFBConfigs);
|
|
|
|
__GLX_SWAP_INT(&reply.numAttribs);
|
2004-06-16 11:25:21 +02:00
|
|
|
}
|
|
|
|
|
2012-05-13 09:03:35 +02:00
|
|
|
WriteToClient(client, sz_xGLXGetFBConfigsReply, &reply);
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) {
|
2012-03-21 20:55:09 +01:00
|
|
|
p = 0;
|
2004-06-16 11:25:21 +02:00
|
|
|
|
|
|
|
#define WRITE_PAIR(tag,value) \
|
|
|
|
do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
WRITE_PAIR(GLX_VISUAL_ID, modes->visualID);
|
|
|
|
WRITE_PAIR(GLX_FBCONFIG_ID, modes->fbconfigID);
|
2016-03-30 20:04:04 +02:00
|
|
|
WRITE_PAIR(GLX_X_RENDERABLE,
|
|
|
|
(modes->drawableType & (GLX_WINDOW_BIT | GLX_PIXMAP_BIT)
|
|
|
|
? GL_TRUE
|
|
|
|
: GL_FALSE));
|
2012-03-21 20:55:09 +01:00
|
|
|
|
|
|
|
WRITE_PAIR(GLX_RGBA,
|
|
|
|
(modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE);
|
|
|
|
WRITE_PAIR(GLX_RENDER_TYPE, modes->renderType);
|
|
|
|
WRITE_PAIR(GLX_DOUBLEBUFFER, modes->doubleBufferMode);
|
|
|
|
WRITE_PAIR(GLX_STEREO, modes->stereoMode);
|
|
|
|
|
|
|
|
WRITE_PAIR(GLX_BUFFER_SIZE, modes->rgbBits);
|
|
|
|
WRITE_PAIR(GLX_LEVEL, modes->level);
|
|
|
|
WRITE_PAIR(GLX_AUX_BUFFERS, modes->numAuxBuffers);
|
|
|
|
WRITE_PAIR(GLX_RED_SIZE, modes->redBits);
|
|
|
|
WRITE_PAIR(GLX_GREEN_SIZE, modes->greenBits);
|
|
|
|
WRITE_PAIR(GLX_BLUE_SIZE, modes->blueBits);
|
|
|
|
WRITE_PAIR(GLX_ALPHA_SIZE, modes->alphaBits);
|
|
|
|
WRITE_PAIR(GLX_ACCUM_RED_SIZE, modes->accumRedBits);
|
|
|
|
WRITE_PAIR(GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits);
|
|
|
|
WRITE_PAIR(GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits);
|
|
|
|
WRITE_PAIR(GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits);
|
|
|
|
WRITE_PAIR(GLX_DEPTH_SIZE, modes->depthBits);
|
|
|
|
WRITE_PAIR(GLX_STENCIL_SIZE, modes->stencilBits);
|
|
|
|
WRITE_PAIR(GLX_X_VISUAL_TYPE, modes->visualType);
|
|
|
|
WRITE_PAIR(GLX_CONFIG_CAVEAT, modes->visualRating);
|
|
|
|
WRITE_PAIR(GLX_TRANSPARENT_TYPE, modes->transparentPixel);
|
|
|
|
WRITE_PAIR(GLX_TRANSPARENT_RED_VALUE, modes->transparentRed);
|
|
|
|
WRITE_PAIR(GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen);
|
|
|
|
WRITE_PAIR(GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue);
|
|
|
|
WRITE_PAIR(GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha);
|
|
|
|
WRITE_PAIR(GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex);
|
|
|
|
WRITE_PAIR(GLX_SWAP_METHOD_OML, modes->swapMethod);
|
|
|
|
WRITE_PAIR(GLX_SAMPLES_SGIS, modes->samples);
|
|
|
|
WRITE_PAIR(GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers);
|
2013-07-09 17:19:11 +02:00
|
|
|
WRITE_PAIR(GLX_VISUAL_SELECT_GROUP_SGIX, modes->visualSelectGroup);
|
2012-03-21 20:55:09 +01:00
|
|
|
WRITE_PAIR(GLX_DRAWABLE_TYPE, modes->drawableType);
|
|
|
|
WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb);
|
|
|
|
WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba);
|
|
|
|
WRITE_PAIR(GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture);
|
|
|
|
WRITE_PAIR(GLX_BIND_TO_TEXTURE_TARGETS_EXT,
|
|
|
|
modes->bindToTextureTargets);
|
2013-10-31 23:39:22 +01:00
|
|
|
/* can't report honestly until mesa is fixed */
|
|
|
|
WRITE_PAIR(GLX_Y_INVERTED_EXT, GLX_DONT_CARE);
|
2013-07-09 17:19:11 +02:00
|
|
|
if (modes->drawableType & GLX_PBUFFER_BIT) {
|
|
|
|
WRITE_PAIR(GLX_MAX_PBUFFER_WIDTH, modes->maxPbufferWidth);
|
|
|
|
WRITE_PAIR(GLX_MAX_PBUFFER_HEIGHT, modes->maxPbufferHeight);
|
|
|
|
WRITE_PAIR(GLX_MAX_PBUFFER_PIXELS, modes->maxPbufferPixels);
|
|
|
|
WRITE_PAIR(GLX_OPTIMAL_PBUFFER_WIDTH_SGIX,
|
|
|
|
modes->optimalPbufferWidth);
|
|
|
|
WRITE_PAIR(GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX,
|
|
|
|
modes->optimalPbufferHeight);
|
|
|
|
}
|
2013-03-11 10:21:28 +01:00
|
|
|
/* Add attribute only if its value is not default. */
|
|
|
|
if (modes->sRGBCapable != GL_FALSE) {
|
|
|
|
WRITE_PAIR(GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, modes->sRGBCapable);
|
|
|
|
}
|
|
|
|
/* Pad the remaining place with zeroes, so that attributes count is constant. */
|
|
|
|
while (p < __GLX_FBCONFIG_ATTRIBS_LENGTH) {
|
|
|
|
WRITE_PAIR(0, 0);
|
|
|
|
}
|
|
|
|
assert(p == __GLX_FBCONFIG_ATTRIBS_LENGTH);
|
2012-03-21 20:55:09 +01:00
|
|
|
|
|
|
|
if (client->swapped) {
|
|
|
|
__GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
|
|
|
|
}
|
|
|
|
WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
|
|
|
|
(char *) buf);
|
2004-06-16 11:25:21 +02:00
|
|
|
}
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_GetFBConfigs(__GLXclientState * cl, GLbyte * pc)
|
2004-06-16 11:25:21 +02:00
|
|
|
{
|
|
|
|
xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2007-10-15 19:10:10 +02:00
|
|
|
return DoGetFBConfigs(cl, req->screen);
|
2004-06-16 11:25:21 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_GetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc)
|
2004-06-16 11:25:21 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2004-06-16 11:25:21 +02:00
|
|
|
xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2011-01-23 13:35:54 +01:00
|
|
|
/* work around mesa bug, don't use REQUEST_SIZE_MATCH */
|
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq);
|
2007-10-15 19:10:10 +02:00
|
|
|
return DoGetFBConfigs(cl, req->screen);
|
2004-06-16 11:25:21 +02:00
|
|
|
}
|
|
|
|
|
2009-04-09 19:16:37 +02:00
|
|
|
GLboolean
|
2012-03-21 20:55:09 +01:00
|
|
|
__glXDrawableInit(__GLXdrawable * drawable,
|
|
|
|
__GLXscreen * screen, DrawablePtr pDraw, int type,
|
|
|
|
XID drawId, __GLXconfig * config)
|
2009-04-09 19:16:37 +02:00
|
|
|
{
|
|
|
|
drawable->pDraw = pDraw;
|
|
|
|
drawable->type = type;
|
|
|
|
drawable->drawId = drawId;
|
|
|
|
drawable->config = config;
|
|
|
|
drawable->eventMask = 0;
|
|
|
|
|
|
|
|
return GL_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-03-21 20:55:09 +01:00
|
|
|
__glXDrawableRelease(__GLXdrawable * drawable)
|
2009-04-09 19:16:37 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
static int
|
|
|
|
DoCreateGLXDrawable(ClientPtr client, __GLXscreen * pGlxScreen,
|
|
|
|
__GLXconfig * config, DrawablePtr pDraw, XID drawableId,
|
|
|
|
XID glxDrawableId, int type)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2007-08-24 01:07:52 +02:00
|
|
|
__GLXdrawable *pGlxDraw;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (pGlxScreen->pScreen != pDraw->pScreen)
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadMatch;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2010-04-29 22:36:10 +02:00
|
|
|
pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
|
2012-03-21 20:55:09 +01:00
|
|
|
drawableId, type,
|
|
|
|
glxDrawableId, config);
|
2007-08-24 01:07:52 +02:00
|
|
|
if (pGlxDraw == NULL)
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadAlloc;
|
2007-08-24 01:07:52 +02:00
|
|
|
|
2016-03-07 23:20:28 +01:00
|
|
|
if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw))
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadAlloc;
|
2007-08-24 01:07:52 +02:00
|
|
|
|
2011-03-28 18:30:09 +02:00
|
|
|
/*
|
|
|
|
* Windows aren't refcounted, so track both the X and the GLX window
|
|
|
|
* so we get called regardless of destruction order.
|
|
|
|
*/
|
|
|
|
if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW &&
|
2016-03-07 23:20:28 +01:00
|
|
|
!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw))
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadAlloc;
|
2010-04-16 11:55:32 +02:00
|
|
|
|
2007-08-27 20:23:50 +02:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-03-21 20:55:09 +01:00
|
|
|
DoCreateGLXPixmap(ClientPtr client, __GLXscreen * pGlxScreen,
|
|
|
|
__GLXconfig * config, XID drawableId, XID glxDrawableId)
|
2007-08-27 20:23:50 +02:00
|
|
|
{
|
|
|
|
DrawablePtr pDraw;
|
|
|
|
int err;
|
|
|
|
|
2008-02-28 22:43:43 +01:00
|
|
|
err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess);
|
2009-04-02 23:30:19 +02:00
|
|
|
if (err != Success) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = drawableId;
|
|
|
|
return err;
|
2009-04-02 23:30:19 +02:00
|
|
|
}
|
|
|
|
if (pDraw->type != DRAWABLE_PIXMAP) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = drawableId;
|
|
|
|
return BadPixmap;
|
2007-08-27 20:23:50 +02:00
|
|
|
}
|
|
|
|
|
2010-04-29 22:36:10 +02:00
|
|
|
err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
|
2012-03-21 20:55:09 +01:00
|
|
|
glxDrawableId, GLX_DRAWABLE_PIXMAP);
|
2007-08-27 20:23:50 +02:00
|
|
|
|
2013-10-08 21:02:44 +02:00
|
|
|
if (err == Success)
|
|
|
|
((PixmapPtr) pDraw)->refcnt++;
|
2011-03-28 18:30:09 +02:00
|
|
|
|
2007-08-27 20:23:50 +02:00
|
|
|
return err;
|
2006-06-29 10:35:45 +02:00
|
|
|
}
|
|
|
|
|
2007-08-24 01:07:52 +02:00
|
|
|
static void
|
2009-04-07 19:58:53 +02:00
|
|
|
determineTextureTarget(ClientPtr client, XID glxDrawableID,
|
2012-03-21 20:55:09 +01:00
|
|
|
CARD32 *attribs, CARD32 numAttribs)
|
2006-06-29 10:35:45 +02:00
|
|
|
{
|
2007-08-01 18:13:18 +02:00
|
|
|
GLenum target = 0;
|
2009-04-01 23:42:33 +02:00
|
|
|
GLenum format = 0;
|
2009-04-07 19:58:53 +02:00
|
|
|
int i, err;
|
2007-08-24 01:07:52 +02:00
|
|
|
__GLXdrawable *pGlxDraw;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2009-04-07 19:58:53 +02:00
|
|
|
if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP,
|
2012-03-21 20:55:09 +01:00
|
|
|
DixWriteAccess, &pGlxDraw, &err))
|
|
|
|
/* We just added it in CreatePixmap, so we should never get here. */
|
|
|
|
return;
|
2004-06-16 11:25:21 +02:00
|
|
|
|
2007-08-01 18:13:18 +02:00
|
|
|
for (i = 0; i < numAttribs; i++) {
|
2012-03-21 20:55:09 +01:00
|
|
|
if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
|
|
|
|
switch (attribs[2 * i + 1]) {
|
|
|
|
case GLX_TEXTURE_2D_EXT:
|
|
|
|
target = GL_TEXTURE_2D;
|
|
|
|
break;
|
|
|
|
case GLX_TEXTURE_RECTANGLE_EXT:
|
|
|
|
target = GL_TEXTURE_RECTANGLE_ARB;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
|
|
|
|
format = attribs[2 * i + 1];
|
|
|
|
}
|
|
|
|
|
2007-08-01 18:13:18 +02:00
|
|
|
if (!target) {
|
2012-03-21 20:55:09 +01:00
|
|
|
int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
|
|
|
|
|
|
|
|
if (h & (h - 1) || w & (w - 1))
|
|
|
|
target = GL_TEXTURE_RECTANGLE_ARB;
|
|
|
|
else
|
|
|
|
target = GL_TEXTURE_2D;
|
2007-08-01 18:13:18 +02:00
|
|
|
}
|
|
|
|
|
2007-08-24 01:07:52 +02:00
|
|
|
pGlxDraw->target = target;
|
2009-04-01 23:42:33 +02:00
|
|
|
pGlxDraw->format = format;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CreateGLXPixmap(__GLXclientState * cl, GLbyte * pc)
|
2004-06-16 11:25:21 +02:00
|
|
|
{
|
|
|
|
xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
|
2008-03-27 00:28:09 +01:00
|
|
|
__GLXconfig *config;
|
2007-10-18 21:51:11 +02:00
|
|
|
__GLXscreen *pGlxScreen;
|
|
|
|
int err;
|
2007-08-24 01:07:52 +02:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
|
|
|
|
return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
|
2012-03-21 20:55:09 +01:00
|
|
|
req->pixmap, req->glxpixmap);
|
2004-06-16 11:25:21 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CreatePixmap(__GLXclientState * cl, GLbyte * pc)
|
2004-06-16 11:25:21 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2004-06-16 11:25:21 +02:00
|
|
|
xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
|
2008-03-27 00:28:09 +01:00
|
|
|
__GLXconfig *config;
|
2007-10-18 21:51:11 +02:00
|
|
|
__GLXscreen *pGlxScreen;
|
2007-08-24 01:07:52 +02:00
|
|
|
int err;
|
|
|
|
|
2010-11-10 22:39:54 +01:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq);
|
|
|
|
if (req->numAttribs > (UINT32_MAX >> 3)) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = req->numAttribs;
|
|
|
|
return BadValue;
|
2010-11-10 22:39:54 +01:00
|
|
|
}
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3);
|
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
|
|
|
|
err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
|
2012-03-21 20:55:09 +01:00
|
|
|
req->pixmap, req->glxpixmap);
|
2007-08-24 01:07:52 +02:00
|
|
|
if (err != Success)
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-08-24 01:07:52 +02:00
|
|
|
|
2009-04-07 19:58:53 +02:00
|
|
|
determineTextureTarget(cl->client, req->glxpixmap,
|
2012-03-21 20:55:09 +01:00
|
|
|
(CARD32 *) (req + 1), req->numAttribs);
|
2007-08-24 01:07:52 +02:00
|
|
|
|
|
|
|
return Success;
|
2004-06-16 11:25:21 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState * cl, GLbyte * pc)
|
2004-06-16 11:25:21 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2012-03-21 20:55:09 +01:00
|
|
|
xGLXCreateGLXPixmapWithConfigSGIXReq *req =
|
|
|
|
(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
|
2008-03-27 00:28:09 +01:00
|
|
|
__GLXconfig *config;
|
2007-10-18 21:51:11 +02:00
|
|
|
__GLXscreen *pGlxScreen;
|
|
|
|
int err;
|
2007-08-24 01:07:52 +02:00
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq);
|
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
|
|
|
|
return DoCreateGLXPixmap(cl->client, pGlxScreen,
|
2012-03-21 20:55:09 +01:00
|
|
|
config, req->pixmap, req->glxpixmap);
|
2004-06-16 11:25:21 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
static int
|
|
|
|
DoDestroyDrawable(__GLXclientState * cl, XID glxdrawable, int type)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2007-08-24 01:07:52 +02:00
|
|
|
__GLXdrawable *pGlxDraw;
|
2009-04-07 19:58:53 +02:00
|
|
|
int err;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2009-04-07 19:58:53 +02:00
|
|
|
if (!validGlxDrawable(cl->client, glxdrawable, type,
|
2012-03-21 20:55:09 +01:00
|
|
|
DixDestroyAccess, &pGlxDraw, &err))
|
|
|
|
return err;
|
2007-10-22 18:28:03 +02:00
|
|
|
|
2007-08-24 01:07:52 +02:00
|
|
|
FreeResource(glxdrawable, FALSE);
|
2006-06-28 21:59:01 +02:00
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_DestroyGLXPixmap(__GLXclientState * cl, GLbyte * pc)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
|
|
|
xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
|
|
|
|
|
2007-08-27 20:23:50 +02:00
|
|
|
return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
|
2006-06-28 21:59:01 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_DestroyPixmap(__GLXclientState * cl, GLbyte * pc)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2006-06-28 21:59:01 +02:00
|
|
|
xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
|
|
|
|
|
2011-01-23 13:35:54 +01:00
|
|
|
/* should be REQUEST_SIZE_MATCH, but mesa's glXDestroyPixmap used to set
|
|
|
|
* length to 3 instead of 2 */
|
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXDestroyPixmapReq);
|
2010-07-03 20:47:55 +02:00
|
|
|
|
2007-08-27 20:23:50 +02:00
|
|
|
return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
|
2006-06-28 21:59:01 +02:00
|
|
|
}
|
|
|
|
|
2007-08-27 20:23:50 +02:00
|
|
|
static int
|
|
|
|
DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
|
2012-03-21 20:55:09 +01:00
|
|
|
int width, int height, XID glxDrawableId)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLXconfig *config;
|
|
|
|
__GLXscreen *pGlxScreen;
|
|
|
|
PixmapPtr pPixmap;
|
|
|
|
int err;
|
2006-06-28 21:59:01 +02:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-08-27 20:23:50 +02:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
|
2012-03-21 20:55:09 +01:00
|
|
|
width, height,
|
|
|
|
config->rgbBits, 0);
|
2012-11-10 00:05:27 +01:00
|
|
|
if (!pPixmap)
|
|
|
|
return BadAlloc;
|
2007-08-27 20:23:50 +02:00
|
|
|
|
2010-04-16 11:55:33 +02:00
|
|
|
/* Assign the pixmap the same id as the pbuffer and add it as a
|
|
|
|
* resource so it and the DRI2 drawable will be reclaimed when the
|
|
|
|
* pbuffer is destroyed. */
|
|
|
|
pPixmap->drawable.id = glxDrawableId;
|
|
|
|
if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap))
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadAlloc;
|
2010-04-16 11:55:33 +02:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
|
2012-03-21 20:55:09 +01:00
|
|
|
glxDrawableId, glxDrawableId,
|
|
|
|
GLX_DRAWABLE_PBUFFER);
|
2007-08-27 20:23:50 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CreatePbuffer(__GLXclientState * cl, GLbyte * pc)
|
2007-08-27 20:23:50 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2012-03-21 20:55:09 +01:00
|
|
|
xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
|
|
|
|
CARD32 *attrs;
|
|
|
|
int width, height, i;
|
2007-08-27 20:23:50 +02:00
|
|
|
|
2010-11-10 22:39:54 +01:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq);
|
|
|
|
if (req->numAttribs > (UINT32_MAX >> 3)) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = req->numAttribs;
|
|
|
|
return BadValue;
|
2010-11-10 22:39:54 +01:00
|
|
|
}
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3);
|
|
|
|
|
2007-08-27 20:23:50 +02:00
|
|
|
attrs = (CARD32 *) (req + 1);
|
|
|
|
width = 0;
|
|
|
|
height = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < req->numAttribs; i++) {
|
2012-03-21 20:55:09 +01:00
|
|
|
switch (attrs[i * 2]) {
|
|
|
|
case GLX_PBUFFER_WIDTH:
|
|
|
|
width = attrs[i * 2 + 1];
|
|
|
|
break;
|
|
|
|
case GLX_PBUFFER_HEIGHT:
|
|
|
|
height = attrs[i * 2 + 1];
|
|
|
|
break;
|
|
|
|
case GLX_LARGEST_PBUFFER:
|
|
|
|
/* FIXME: huh... */
|
|
|
|
break;
|
|
|
|
}
|
2007-08-27 20:23:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
|
2012-03-21 20:55:09 +01:00
|
|
|
width, height, req->pbuffer);
|
2006-06-28 21:59:01 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CreateGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc)
|
2007-08-24 03:40:01 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2007-08-24 03:40:01 +02:00
|
|
|
xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
|
|
|
|
|
2011-01-23 17:05:26 +01:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq);
|
2010-07-03 20:47:55 +02:00
|
|
|
|
2012-11-09 23:52:12 +01:00
|
|
|
/*
|
|
|
|
* We should really handle attributes correctly, but this extension
|
|
|
|
* is so rare I have difficulty caring.
|
|
|
|
*/
|
2007-08-27 20:23:50 +02:00
|
|
|
return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
|
2012-03-21 20:55:09 +01:00
|
|
|
req->width, req->height, req->pbuffer);
|
2007-08-24 03:40:01 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_DestroyPbuffer(__GLXclientState * cl, GLbyte * pc)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2006-06-28 21:59:01 +02:00
|
|
|
xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
|
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq);
|
|
|
|
|
2007-08-27 20:23:50 +02:00
|
|
|
return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
|
2006-06-28 21:59:01 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_DestroyGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc)
|
2007-08-24 03:40:01 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2007-08-24 03:40:01 +02:00
|
|
|
xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
|
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq);
|
|
|
|
|
2007-08-27 20:23:50 +02:00
|
|
|
return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
|
2007-08-24 03:40:01 +02:00
|
|
|
}
|
|
|
|
|
2007-08-27 20:43:48 +02:00
|
|
|
static int
|
|
|
|
DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
|
2012-03-21 20:55:09 +01:00
|
|
|
int numAttribs, CARD32 *attribs)
|
2007-08-27 20:43:48 +02:00
|
|
|
{
|
|
|
|
__GLXdrawable *pGlxDraw;
|
2009-04-07 19:58:53 +02:00
|
|
|
int i, err;
|
|
|
|
|
|
|
|
if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY,
|
2012-03-21 20:55:09 +01:00
|
|
|
DixSetAttrAccess, &pGlxDraw, &err))
|
|
|
|
return err;
|
2007-08-27 20:43:48 +02:00
|
|
|
|
|
|
|
for (i = 0; i < numAttribs; i++) {
|
2012-03-21 20:55:09 +01:00
|
|
|
switch (attribs[i * 2]) {
|
|
|
|
case GLX_EVENT_MASK:
|
|
|
|
/* All we do is to record the event mask so we can send it
|
|
|
|
* back when queried. We never actually clobber the
|
|
|
|
* pbuffers, so we never need to send out the event. */
|
|
|
|
pGlxDraw->eventMask = attribs[i * 2 + 1];
|
|
|
|
break;
|
|
|
|
}
|
2007-08-27 20:43:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_ChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2006-06-28 21:59:01 +02:00
|
|
|
xGLXChangeDrawableAttributesReq *req =
|
2012-03-21 20:55:09 +01:00
|
|
|
(xGLXChangeDrawableAttributesReq *) pc;
|
2006-06-28 21:59:01 +02:00
|
|
|
|
2010-11-10 22:39:54 +01:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq);
|
|
|
|
if (req->numAttribs > (UINT32_MAX >> 3)) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = req->numAttribs;
|
|
|
|
return BadValue;
|
2010-11-10 22:39:54 +01:00
|
|
|
}
|
2011-01-23 13:35:54 +01:00
|
|
|
#if 0
|
|
|
|
/* mesa sends an additional 8 bytes */
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3);
|
2011-01-23 13:35:54 +01:00
|
|
|
#else
|
2012-03-21 20:55:09 +01:00
|
|
|
if (((sizeof(xGLXChangeDrawableAttributesReq) +
|
|
|
|
(req->numAttribs << 3)) >> 2) < client->req_len)
|
|
|
|
return BadLength;
|
2011-01-23 13:35:54 +01:00
|
|
|
#endif
|
2010-07-03 20:47:55 +02:00
|
|
|
|
2007-08-27 20:43:48 +02:00
|
|
|
return DoChangeDrawableAttributes(cl->client, req->drawable,
|
2012-03-21 20:55:09 +01:00
|
|
|
req->numAttribs, (CARD32 *) (req + 1));
|
2006-06-28 21:59:01 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc)
|
2007-08-24 03:40:01 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2007-08-24 03:40:01 +02:00
|
|
|
xGLXChangeDrawableAttributesSGIXReq *req =
|
2012-03-21 20:55:09 +01:00
|
|
|
(xGLXChangeDrawableAttributesSGIXReq *) pc;
|
2007-08-24 03:40:01 +02:00
|
|
|
|
2010-11-10 22:39:54 +01:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq);
|
|
|
|
if (req->numAttribs > (UINT32_MAX >> 3)) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = req->numAttribs;
|
|
|
|
return BadValue;
|
2010-11-10 22:39:54 +01:00
|
|
|
}
|
2012-03-21 20:55:09 +01:00
|
|
|
REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq,
|
|
|
|
req->numAttribs << 3);
|
2010-07-03 20:47:55 +02:00
|
|
|
|
2007-08-27 20:43:48 +02:00
|
|
|
return DoChangeDrawableAttributes(cl->client, req->drawable,
|
2012-03-21 20:55:09 +01:00
|
|
|
req->numAttribs, (CARD32 *) (req + 1));
|
2007-08-24 03:40:01 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CreateWindow(__GLXclientState * cl, GLbyte * pc)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
2012-03-21 20:55:09 +01:00
|
|
|
xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
|
|
|
|
__GLXconfig *config;
|
|
|
|
__GLXscreen *pGlxScreen;
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
DrawablePtr pDraw;
|
|
|
|
int err;
|
2007-08-27 20:23:50 +02:00
|
|
|
|
2010-11-10 22:39:54 +01:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq);
|
|
|
|
if (req->numAttribs > (UINT32_MAX >> 3)) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = req->numAttribs;
|
|
|
|
return BadValue;
|
2010-11-10 22:39:54 +01:00
|
|
|
}
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3);
|
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
|
2008-02-28 22:43:43 +01:00
|
|
|
err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess);
|
2007-08-27 20:23:50 +02:00
|
|
|
if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = req->window;
|
|
|
|
return BadWindow;
|
2007-08-27 20:23:50 +02:00
|
|
|
}
|
2006-06-29 10:35:45 +02:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2007-10-18 21:51:11 +02:00
|
|
|
|
|
|
|
return DoCreateGLXDrawable(client, pGlxScreen, config,
|
2012-03-21 20:55:09 +01:00
|
|
|
pDraw, req->window,
|
|
|
|
req->glxwindow, GLX_DRAWABLE_WINDOW);
|
2006-06-28 21:59:01 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_DestroyWindow(__GLXclientState * cl, GLbyte * pc)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2006-06-28 21:59:01 +02:00
|
|
|
xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
|
|
|
|
|
2011-01-23 13:35:54 +01:00
|
|
|
/* mesa's glXDestroyWindow used to set length to 3 instead of 2 */
|
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq);
|
2010-07-03 20:47:55 +02:00
|
|
|
|
2007-08-27 20:23:50 +02:00
|
|
|
return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
|
2006-06-28 21:59:01 +02:00
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
** NOTE: There is no portable implementation for swap buffers as of
|
|
|
|
** this time that is of value. Consequently, this code must be
|
|
|
|
** implemented by somebody other than SGI.
|
|
|
|
*/
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_SwapBuffers(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
|
2010-07-03 20:47:55 +02:00
|
|
|
GLXContextTag tag;
|
|
|
|
XID drawId;
|
2003-11-14 17:48:57 +01:00
|
|
|
__GLXcontext *glxc = NULL;
|
2006-06-29 10:25:54 +02:00
|
|
|
__GLXdrawable *pGlxDraw;
|
2003-11-14 17:48:57 +01:00
|
|
|
int error;
|
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
tag = req->contextTag;
|
|
|
|
drawId = req->drawable;
|
2003-11-14 17:48:57 +01:00
|
|
|
if (tag) {
|
2012-03-21 20:55:09 +01:00
|
|
|
glxc = __glXLookupContextByTag(cl, tag);
|
|
|
|
if (!glxc) {
|
|
|
|
return __glXError(GLXBadContextTag);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
** The calling thread is swapping its current drawable. In this case,
|
|
|
|
** glxSwapBuffers is in both GL and X streams, in terms of
|
|
|
|
** sequentiality.
|
|
|
|
*/
|
|
|
|
if (__glXForceCurrent(cl, tag, &error)) {
|
|
|
|
/*
|
|
|
|
** Do whatever is needed to make sure that all preceding requests
|
|
|
|
** in both streams are completed before the swap is executed.
|
|
|
|
*/
|
2013-07-10 16:00:46 +02:00
|
|
|
glFinish();
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
return error;
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2007-08-24 01:07:52 +02:00
|
|
|
pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
|
|
|
|
if (pGlxDraw == NULL)
|
2012-03-21 20:55:09 +01:00
|
|
|
return error;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2007-08-24 01:07:52 +02:00
|
|
|
if (pGlxDraw->type == DRAWABLE_WINDOW &&
|
2012-03-21 20:55:09 +01:00
|
|
|
(*pGlxDraw->swapBuffers) (cl->client, pGlxDraw) == GL_FALSE)
|
|
|
|
return __glXError(GLXBadDrawable);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2007-10-14 20:59:12 +02:00
|
|
|
static int
|
2012-03-21 20:55:09 +01:00
|
|
|
DoQueryContext(__GLXclientState * cl, GLXContextID gcId)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
__GLXcontext *ctx;
|
|
|
|
xGLXQueryContextInfoEXTReply reply;
|
2017-11-14 21:15:01 +01:00
|
|
|
int nProps = 5;
|
2013-07-02 16:30:40 +02:00
|
|
|
int sendBuf[nProps * 2];
|
2003-11-14 17:48:57 +01:00
|
|
|
int nReplyBytes;
|
2009-04-02 23:24:12 +02:00
|
|
|
int err;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2009-04-02 23:24:12 +02:00
|
|
|
if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-07-10 04:12:43 +02:00
|
|
|
reply = (xGLXQueryContextInfoEXTReply) {
|
|
|
|
.type = X_Reply,
|
|
|
|
.sequenceNumber = client->sequence,
|
|
|
|
.length = nProps << 1,
|
|
|
|
.n = nProps
|
|
|
|
};
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
nReplyBytes = reply.length << 2;
|
2013-07-02 16:30:40 +02:00
|
|
|
sendBuf[0] = GLX_SHARE_CONTEXT_EXT;
|
|
|
|
sendBuf[1] = (int) (ctx->share_id);
|
|
|
|
sendBuf[2] = GLX_VISUAL_ID_EXT;
|
2017-11-14 21:15:03 +01:00
|
|
|
sendBuf[3] = (int) (ctx->config ? ctx->config->visualID : 0);
|
2013-07-02 16:30:40 +02:00
|
|
|
sendBuf[4] = GLX_SCREEN_EXT;
|
|
|
|
sendBuf[5] = (int) (ctx->pGlxScreen->pScreen->myNum);
|
2017-11-14 21:15:01 +01:00
|
|
|
sendBuf[6] = GLX_FBCONFIG_ID;
|
2017-11-14 21:15:03 +01:00
|
|
|
sendBuf[7] = (int) (ctx->config ? ctx->config->fbconfigID : 0);
|
2017-11-14 21:15:01 +01:00
|
|
|
sendBuf[8] = GLX_RENDER_TYPE;
|
2017-11-14 21:15:03 +01:00
|
|
|
sendBuf[9] = (int) (ctx->config ? ctx->config->renderType : GLX_DONT_CARE);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
if (client->swapped) {
|
2017-08-16 20:49:17 +02:00
|
|
|
int length = reply.length;
|
|
|
|
|
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_DECLARE_SWAP_ARRAY_VARIABLES;
|
|
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
|
|
__GLX_SWAP_INT(&reply.length);
|
|
|
|
__GLX_SWAP_INT(&reply.n);
|
|
|
|
WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply);
|
|
|
|
__GLX_SWAP_INT_ARRAY((int *) sendBuf, length);
|
|
|
|
WriteToClient(client, length << 2, sendBuf);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2012-03-21 20:55:09 +01:00
|
|
|
else {
|
2012-05-13 09:03:35 +02:00
|
|
|
WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply);
|
|
|
|
WriteToClient(client, nReplyBytes, sendBuf);
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_QueryContextInfoEXT(__GLXclientState * cl, GLbyte * pc)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2006-06-28 21:59:01 +02:00
|
|
|
xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
|
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq);
|
|
|
|
|
2006-06-28 21:59:01 +02:00
|
|
|
return DoQueryContext(cl, req->context);
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_QueryContext(__GLXclientState * cl, GLbyte * pc)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
|
|
|
xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
|
|
|
|
|
|
|
|
return DoQueryContext(cl, req->context);
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_BindTexImageEXT(__GLXclientState * cl, GLbyte * pc)
|
2006-03-12 01:11:34 +01:00
|
|
|
{
|
|
|
|
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
|
2012-03-21 20:55:09 +01:00
|
|
|
ClientPtr client = cl->client;
|
|
|
|
__GLXcontext *context;
|
|
|
|
__GLXdrawable *pGlxDraw;
|
|
|
|
GLXDrawable drawId;
|
|
|
|
int buffer;
|
|
|
|
int error;
|
|
|
|
CARD32 num_attribs;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2011-01-26 13:06:53 +01:00
|
|
|
if ((sizeof(xGLXVendorPrivateReq) + 12) >> 2 > client->req_len)
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadLength;
|
2010-07-03 20:47:55 +02:00
|
|
|
|
2006-03-12 01:11:34 +01:00
|
|
|
pc += __GLX_VENDPRIV_HDR_SIZE;
|
|
|
|
|
|
|
|
drawId = *((CARD32 *) (pc));
|
2012-03-21 20:55:09 +01:00
|
|
|
buffer = *((INT32 *) (pc + 4));
|
2011-01-26 13:06:53 +01:00
|
|
|
num_attribs = *((CARD32 *) (pc + 8));
|
|
|
|
if (num_attribs > (UINT32_MAX >> 3)) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = num_attribs;
|
|
|
|
return BadValue;
|
2011-01-26 13:06:53 +01:00
|
|
|
}
|
|
|
|
REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 12 + (num_attribs << 3));
|
2006-03-12 01:11:34 +01:00
|
|
|
|
|
|
|
if (buffer != GLX_FRONT_LEFT_EXT)
|
2012-03-21 20:55:09 +01:00
|
|
|
return __glXError(GLXBadPixmap);
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
context = __glXForceCurrent(cl, req->contextTag, &error);
|
2006-03-12 01:11:34 +01:00
|
|
|
if (!context)
|
2012-03-21 20:55:09 +01:00
|
|
|
return error;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2009-04-07 19:58:53 +02:00
|
|
|
if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
|
2012-03-21 20:55:09 +01:00
|
|
|
DixReadAccess, &pGlxDraw, &error))
|
|
|
|
return error;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2017-06-16 21:44:49 +02:00
|
|
|
if (!context->bindTexImage)
|
2012-03-21 20:55:09 +01:00
|
|
|
return __glXError(GLXUnsupportedPrivateRequest);
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2017-06-16 21:44:49 +02:00
|
|
|
return context->bindTexImage(context, buffer, pGlxDraw);
|
2006-03-12 01:11:34 +01:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_ReleaseTexImageEXT(__GLXclientState * cl, GLbyte * pc)
|
2006-03-12 01:11:34 +01:00
|
|
|
{
|
|
|
|
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
|
2012-03-21 20:55:09 +01:00
|
|
|
ClientPtr client = cl->client;
|
|
|
|
__GLXdrawable *pGlxDraw;
|
|
|
|
__GLXcontext *context;
|
|
|
|
GLXDrawable drawId;
|
|
|
|
int buffer;
|
|
|
|
int error;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8);
|
|
|
|
|
2006-03-12 01:11:34 +01:00
|
|
|
pc += __GLX_VENDPRIV_HDR_SIZE;
|
|
|
|
|
|
|
|
drawId = *((CARD32 *) (pc));
|
2012-03-21 20:55:09 +01:00
|
|
|
buffer = *((INT32 *) (pc + 4));
|
|
|
|
|
|
|
|
context = __glXForceCurrent(cl, req->contextTag, &error);
|
2006-03-12 01:11:34 +01:00
|
|
|
if (!context)
|
2012-03-21 20:55:09 +01:00
|
|
|
return error;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2009-04-07 19:58:53 +02:00
|
|
|
if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
|
2012-03-21 20:55:09 +01:00
|
|
|
DixReadAccess, &pGlxDraw, &error))
|
|
|
|
return error;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2017-06-16 21:44:49 +02:00
|
|
|
if (!context->releaseTexImage)
|
2012-03-21 20:55:09 +01:00
|
|
|
return __glXError(GLXUnsupportedPrivateRequest);
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2017-06-16 21:44:49 +02:00
|
|
|
return context->releaseTexImage(context, buffer, pGlxDraw);
|
2006-03-12 01:11:34 +01:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc)
|
2006-07-06 08:28:55 +02:00
|
|
|
{
|
|
|
|
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
|
2012-03-21 20:55:09 +01:00
|
|
|
GLXContextTag tag = req->contextTag;
|
|
|
|
__GLXcontext *glxc = NULL;
|
|
|
|
__GLXdrawable *pGlxDraw;
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
GLXDrawable drawId;
|
|
|
|
int error;
|
|
|
|
int x, y, width, height;
|
2006-07-06 08:28:55 +02:00
|
|
|
|
|
|
|
(void) client;
|
|
|
|
(void) req;
|
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20);
|
|
|
|
|
2006-07-06 08:28:55 +02:00
|
|
|
pc += __GLX_VENDPRIV_HDR_SIZE;
|
|
|
|
|
|
|
|
drawId = *((CARD32 *) (pc));
|
2012-03-21 20:55:09 +01:00
|
|
|
x = *((INT32 *) (pc + 4));
|
|
|
|
y = *((INT32 *) (pc + 8));
|
|
|
|
width = *((INT32 *) (pc + 12));
|
|
|
|
height = *((INT32 *) (pc + 16));
|
2006-07-06 08:28:55 +02:00
|
|
|
|
2006-07-07 03:22:34 +02:00
|
|
|
if (tag) {
|
2012-03-21 20:55:09 +01:00
|
|
|
glxc = __glXLookupContextByTag(cl, tag);
|
|
|
|
if (!glxc) {
|
|
|
|
return __glXError(GLXBadContextTag);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
** The calling thread is swapping its current drawable. In this case,
|
|
|
|
** glxSwapBuffers is in both GL and X streams, in terms of
|
|
|
|
** sequentiality.
|
|
|
|
*/
|
|
|
|
if (__glXForceCurrent(cl, tag, &error)) {
|
|
|
|
/*
|
|
|
|
** Do whatever is needed to make sure that all preceding requests
|
|
|
|
** in both streams are completed before the swap is executed.
|
|
|
|
*/
|
2013-07-10 16:00:46 +02:00
|
|
|
glFinish();
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
return error;
|
|
|
|
}
|
2006-07-07 03:22:34 +02:00
|
|
|
}
|
|
|
|
|
2007-08-24 01:07:52 +02:00
|
|
|
pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
|
2007-10-16 12:46:07 +02:00
|
|
|
if (!pGlxDraw)
|
2012-03-21 20:55:09 +01:00
|
|
|
return error;
|
2006-07-07 03:22:34 +02:00
|
|
|
|
|
|
|
if (pGlxDraw == NULL ||
|
2012-03-21 20:55:09 +01:00
|
|
|
pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
|
|
|
|
pGlxDraw->copySubBuffer == NULL)
|
|
|
|
return __glXError(GLXBadDrawable);
|
2006-07-07 03:22:34 +02:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
(*pGlxDraw->copySubBuffer) (pGlxDraw, x, y, width, height);
|
2006-07-07 03:22:34 +02:00
|
|
|
|
|
|
|
return Success;
|
2006-07-06 08:28:55 +02:00
|
|
|
}
|
|
|
|
|
2015-05-18 19:00:02 +02:00
|
|
|
/* hack for old glxext.h */
|
|
|
|
#ifndef GLX_STEREO_TREE_EXT
|
|
|
|
#define GLX_STEREO_TREE_EXT 0x20F5
|
|
|
|
#endif
|
|
|
|
|
2006-03-12 01:11:34 +01:00
|
|
|
/*
|
|
|
|
** Get drawable attributes
|
|
|
|
*/
|
|
|
|
static int
|
2012-03-21 20:55:09 +01:00
|
|
|
DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
|
2006-03-12 01:11:34 +01:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
xGLXGetDrawableAttributesReply reply;
|
2014-12-02 20:52:35 +01:00
|
|
|
__GLXdrawable *pGlxDraw = NULL;
|
|
|
|
DrawablePtr pDraw;
|
2015-05-18 19:00:02 +02:00
|
|
|
CARD32 attributes[18];
|
2014-12-02 20:47:45 +01:00
|
|
|
int num = 0, error;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2009-04-07 19:58:53 +02:00
|
|
|
if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
|
2014-12-02 20:52:35 +01:00
|
|
|
DixGetAttrAccess, &pGlxDraw, &error)) {
|
|
|
|
/* hack for GLX 1.2 naked windows */
|
|
|
|
int err = dixLookupWindow((WindowPtr *)&pDraw, drawId, client,
|
|
|
|
DixGetAttrAccess);
|
|
|
|
if (err != Success)
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
if (pGlxDraw)
|
|
|
|
pDraw = pGlxDraw->pDraw;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2016-03-10 18:29:34 +01:00
|
|
|
#define ATTRIB(a, v) do { \
|
|
|
|
attributes[2*num] = (a); \
|
|
|
|
attributes[2*num+1] = (v); \
|
|
|
|
num++; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
ATTRIB(GLX_Y_INVERTED_EXT, GL_FALSE);
|
|
|
|
ATTRIB(GLX_WIDTH, pDraw->width);
|
|
|
|
ATTRIB(GLX_HEIGHT, pDraw->height);
|
2016-03-03 22:50:02 +01:00
|
|
|
ATTRIB(GLX_SCREEN, pDraw->pScreen->myNum);
|
2014-12-02 20:52:35 +01:00
|
|
|
if (pGlxDraw) {
|
2016-03-10 18:29:34 +01:00
|
|
|
ATTRIB(GLX_TEXTURE_TARGET_EXT,
|
|
|
|
pGlxDraw->target == GL_TEXTURE_2D ?
|
|
|
|
GLX_TEXTURE_2D_EXT : GLX_TEXTURE_RECTANGLE_EXT);
|
|
|
|
ATTRIB(GLX_EVENT_MASK, pGlxDraw->eventMask);
|
|
|
|
ATTRIB(GLX_FBCONFIG_ID, pGlxDraw->config->fbconfigID);
|
2014-12-02 20:52:35 +01:00
|
|
|
if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) {
|
2016-03-10 18:29:34 +01:00
|
|
|
ATTRIB(GLX_PRESERVED_CONTENTS, GL_TRUE);
|
2014-12-02 20:52:35 +01:00
|
|
|
}
|
2015-05-18 19:00:02 +02:00
|
|
|
if (pGlxDraw->type == GLX_DRAWABLE_WINDOW) {
|
|
|
|
ATTRIB(GLX_STEREO_TREE_EXT, 0);
|
|
|
|
}
|
2012-11-09 23:52:12 +01:00
|
|
|
}
|
2016-03-10 18:29:34 +01:00
|
|
|
#undef ATTRIB
|
2012-11-09 23:07:20 +01:00
|
|
|
|
|
|
|
reply = (xGLXGetDrawableAttributesReply) {
|
|
|
|
.type = X_Reply,
|
|
|
|
.sequenceNumber = client->sequence,
|
2014-12-02 20:47:45 +01:00
|
|
|
.length = num << 1,
|
|
|
|
.numAttribs = num
|
2012-11-09 23:07:20 +01:00
|
|
|
};
|
2006-03-12 01:11:34 +01:00
|
|
|
|
|
|
|
if (client->swapped) {
|
2017-08-16 20:49:17 +02:00
|
|
|
int length = reply.length;
|
|
|
|
|
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_DECLARE_SWAP_ARRAY_VARIABLES;
|
|
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
|
|
__GLX_SWAP_INT(&reply.length);
|
|
|
|
__GLX_SWAP_INT(&reply.numAttribs);
|
|
|
|
WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply);
|
|
|
|
__GLX_SWAP_INT_ARRAY((int *) attributes, length);
|
|
|
|
WriteToClient(client, length << 2, attributes);
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
else {
|
2012-05-13 09:03:35 +02:00
|
|
|
WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply);
|
|
|
|
WriteToClient(client, reply.length * sizeof(CARD32), attributes);
|
2006-03-12 01:11:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_GetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
|
2006-03-12 01:11:34 +01:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2012-03-21 20:55:09 +01:00
|
|
|
xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *) pc;
|
2006-03-12 01:11:34 +01:00
|
|
|
|
2011-01-23 13:35:54 +01:00
|
|
|
/* this should be REQUEST_SIZE_MATCH, but mesa sends an additional 4 bytes */
|
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq);
|
2010-07-03 20:47:55 +02:00
|
|
|
|
2007-08-24 03:40:01 +02:00
|
|
|
return DoGetDrawableAttributes(cl, req->drawable);
|
2006-03-12 01:11:34 +01:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_GetDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc)
|
2006-06-28 21:59:01 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2007-08-24 03:40:01 +02:00
|
|
|
xGLXGetDrawableAttributesSGIXReq *req =
|
2012-03-21 20:55:09 +01:00
|
|
|
(xGLXGetDrawableAttributesSGIXReq *) pc;
|
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq);
|
|
|
|
|
2006-06-28 21:59:01 +02:00
|
|
|
return DoGetDrawableAttributes(cl, req->drawable);
|
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Render and Renderlarge are not in the GLX API. They are used by the GLX
|
|
|
|
** client library to send batches of GL rendering commands.
|
|
|
|
*/
|
|
|
|
|
2018-01-10 19:05:48 +01:00
|
|
|
/*
|
|
|
|
** Reset state used to keep track of large (multi-request) commands.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
ResetLargeCommandStatus(__GLXcontext *cx)
|
|
|
|
{
|
|
|
|
cx->largeCmdBytesSoFar = 0;
|
|
|
|
cx->largeCmdBytesTotal = 0;
|
|
|
|
cx->largeCmdRequestsSoFar = 0;
|
|
|
|
cx->largeCmdRequestsTotal = 0;
|
|
|
|
}
|
|
|
|
|
2007-10-14 20:59:12 +02:00
|
|
|
/*
|
|
|
|
** Execute all the drawing commands in a request.
|
|
|
|
*/
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_Render(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
xGLXRenderReq *req;
|
2012-03-21 20:55:09 +01:00
|
|
|
ClientPtr client = cl->client;
|
2003-11-14 17:48:57 +01:00
|
|
|
int left, cmdlen, error;
|
|
|
|
int commandsDone;
|
|
|
|
CARD16 opcode;
|
|
|
|
__GLXrenderHeader *hdr;
|
|
|
|
__GLXcontext *glxc;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2006-08-24 01:47:00 +02:00
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXRenderReq);
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
req = (xGLXRenderReq *) pc;
|
2007-10-14 20:59:12 +02:00
|
|
|
if (client->swapped) {
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLX_SWAP_SHORT(&req->length);
|
|
|
|
__GLX_SWAP_INT(&req->contextTag);
|
2006-08-24 01:47:00 +02:00
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
glxc = __glXForceCurrent(cl, req->contextTag, &error);
|
|
|
|
if (!glxc) {
|
2012-03-21 20:55:09 +01:00
|
|
|
return error;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
commandsDone = 0;
|
|
|
|
pc += sz_xGLXRenderReq;
|
|
|
|
left = (req->length << 2) - sz_xGLXRenderReq;
|
|
|
|
while (left > 0) {
|
2006-08-24 01:05:37 +02:00
|
|
|
__GLXrenderSizeData entry;
|
2014-11-10 18:13:41 +01:00
|
|
|
int extra = 0;
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLXdispatchRenderProcPtr proc;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (left < sizeof(__GLXrenderHeader))
|
|
|
|
return BadLength;
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Verify that the header length and the overall length agree.
|
|
|
|
** Also, each command must be word aligned.
|
|
|
|
*/
|
|
|
|
hdr = (__GLXrenderHeader *) pc;
|
|
|
|
if (client->swapped) {
|
|
|
|
__GLX_SWAP_SHORT(&hdr->length);
|
|
|
|
__GLX_SWAP_SHORT(&hdr->opcode);
|
|
|
|
}
|
|
|
|
cmdlen = hdr->length;
|
|
|
|
opcode = hdr->opcode;
|
|
|
|
|
2014-11-10 18:13:41 +01:00
|
|
|
if (left < cmdlen)
|
|
|
|
return BadLength;
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/*
|
|
|
|
** Check for core opcodes and grab entry data.
|
|
|
|
*/
|
|
|
|
err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry);
|
|
|
|
proc = (__GLXdispatchRenderProcPtr)
|
|
|
|
__glXGetProtocolDecodeFunction(&Render_dispatch_info,
|
|
|
|
opcode, client->swapped);
|
|
|
|
|
|
|
|
if ((err < 0) || (proc == NULL)) {
|
|
|
|
client->errorValue = commandsDone;
|
|
|
|
return __glXError(GLXBadRenderRequest);
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2014-11-10 18:13:41 +01:00
|
|
|
if (cmdlen < entry.bytes) {
|
|
|
|
return BadLength;
|
|
|
|
}
|
|
|
|
|
2006-08-24 01:05:37 +02:00
|
|
|
if (entry.varsize) {
|
2003-11-14 17:48:57 +01:00
|
|
|
/* variable size command */
|
2012-03-21 20:55:09 +01:00
|
|
|
extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE,
|
2014-11-10 18:13:48 +01:00
|
|
|
client->swapped,
|
|
|
|
left - __GLX_RENDER_HDR_SIZE);
|
2003-11-14 17:48:57 +01:00
|
|
|
if (extra < 0) {
|
2014-11-10 18:13:36 +01:00
|
|
|
return BadLength;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-10 18:13:41 +01:00
|
|
|
|
|
|
|
if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) {
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Skip over the header and execute the command. We allow the
|
|
|
|
** caller to trash the command memory. This is useful especially
|
|
|
|
** for things that require double alignment - they can just shift
|
|
|
|
** the data towards lower memory (trashing the header) by 4 bytes
|
|
|
|
** and achieve the required alignment.
|
|
|
|
*/
|
|
|
|
(*proc) (pc + __GLX_RENDER_HDR_SIZE);
|
|
|
|
pc += cmdlen;
|
|
|
|
left -= cmdlen;
|
|
|
|
commandsDone++;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-14 20:59:12 +02:00
|
|
|
** Execute a large rendering request (one that spans multiple X requests).
|
2003-11-14 17:48:57 +01:00
|
|
|
*/
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
xGLXRenderLargeReq *req;
|
2012-03-21 20:55:09 +01:00
|
|
|
ClientPtr client = cl->client;
|
2006-08-24 01:47:00 +02:00
|
|
|
size_t dataBytes;
|
2003-11-14 17:48:57 +01:00
|
|
|
__GLXrenderLargeHeader *hdr;
|
|
|
|
__GLXcontext *glxc;
|
|
|
|
int error;
|
|
|
|
CARD16 opcode;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2006-08-24 01:47:00 +02:00
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2014-11-10 18:13:43 +01:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq);
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
req = (xGLXRenderLargeReq *) pc;
|
2007-10-14 20:59:12 +02:00
|
|
|
if (client->swapped) {
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLX_SWAP_SHORT(&req->length);
|
|
|
|
__GLX_SWAP_INT(&req->contextTag);
|
|
|
|
__GLX_SWAP_INT(&req->dataBytes);
|
|
|
|
__GLX_SWAP_SHORT(&req->requestNumber);
|
|
|
|
__GLX_SWAP_SHORT(&req->requestTotal);
|
2006-08-24 01:47:00 +02:00
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
glxc = __glXForceCurrent(cl, req->contextTag, &error);
|
|
|
|
if (!glxc) {
|
2012-03-21 20:55:09 +01:00
|
|
|
return error;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2014-11-10 18:13:43 +01:00
|
|
|
if (safe_pad(req->dataBytes) < 0)
|
|
|
|
return BadLength;
|
2003-11-14 17:48:57 +01:00
|
|
|
dataBytes = req->dataBytes;
|
|
|
|
|
|
|
|
/*
|
2012-03-21 20:55:09 +01:00
|
|
|
** Check the request length.
|
|
|
|
*/
|
2014-11-10 18:13:43 +01:00
|
|
|
if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = req->length;
|
|
|
|
/* Reset in case this isn't 1st request. */
|
2018-01-10 19:05:48 +01:00
|
|
|
ResetLargeCommandStatus(glxc);
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadLength;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
pc += sz_xGLXRenderLargeReq;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2018-01-10 19:05:48 +01:00
|
|
|
if (glxc->largeCmdRequestsSoFar == 0) {
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLXrenderSizeData entry;
|
2014-11-10 18:13:43 +01:00
|
|
|
int extra = 0;
|
2014-11-10 18:13:48 +01:00
|
|
|
int left = (req->length << 2) - sz_xGLXRenderLargeReq;
|
2015-10-19 08:12:50 +02:00
|
|
|
int cmdlen;
|
2012-03-21 20:55:09 +01:00
|
|
|
int err;
|
|
|
|
|
|
|
|
/*
|
|
|
|
** This is the first request of a multi request command.
|
|
|
|
** Make enough space in the buffer, then copy the entire request.
|
|
|
|
*/
|
|
|
|
if (req->requestNumber != 1) {
|
|
|
|
client->errorValue = req->requestNumber;
|
|
|
|
return __glXError(GLXBadLargeRequest);
|
|
|
|
}
|
|
|
|
|
2014-11-10 18:13:43 +01:00
|
|
|
if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE)
|
|
|
|
return BadLength;
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
hdr = (__GLXrenderLargeHeader *) pc;
|
|
|
|
if (client->swapped) {
|
|
|
|
__GLX_SWAP_INT(&hdr->length);
|
|
|
|
__GLX_SWAP_INT(&hdr->opcode);
|
|
|
|
}
|
|
|
|
opcode = hdr->opcode;
|
2014-11-10 18:13:43 +01:00
|
|
|
if ((cmdlen = safe_pad(hdr->length)) < 0)
|
|
|
|
return BadLength;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
** Check for core opcodes and grab entry data.
|
|
|
|
*/
|
|
|
|
err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry);
|
|
|
|
if (err < 0) {
|
|
|
|
client->errorValue = opcode;
|
|
|
|
return __glXError(GLXBadLargeRequest);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry.varsize) {
|
|
|
|
/*
|
|
|
|
** If it's a variable-size command (a command whose length must
|
|
|
|
** be computed from its parameters), all the parameters needed
|
|
|
|
** will be in the 1st request, so it's okay to do this.
|
|
|
|
*/
|
|
|
|
extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE,
|
2014-11-10 18:13:48 +01:00
|
|
|
client->swapped,
|
|
|
|
left - __GLX_RENDER_LARGE_HDR_SIZE);
|
2012-03-21 20:55:09 +01:00
|
|
|
if (extra < 0) {
|
2014-11-10 18:13:36 +01:00
|
|
|
return BadLength;
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-10 18:13:43 +01:00
|
|
|
|
|
|
|
/* the +4 is safe because we know entry.bytes is small */
|
|
|
|
if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) {
|
|
|
|
return BadLength;
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
2014-11-10 18:13:43 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/*
|
|
|
|
** Make enough space in the buffer, then copy the entire request.
|
|
|
|
*/
|
2018-01-10 19:05:48 +01:00
|
|
|
if (glxc->largeCmdBufSize < cmdlen) {
|
|
|
|
GLbyte *newbuf = glxc->largeCmdBuf;
|
2013-07-02 16:35:19 +02:00
|
|
|
|
|
|
|
if (!(newbuf = realloc(newbuf, cmdlen)))
|
|
|
|
return BadAlloc;
|
|
|
|
|
2018-01-10 19:05:48 +01:00
|
|
|
glxc->largeCmdBuf = newbuf;
|
|
|
|
glxc->largeCmdBufSize = cmdlen;
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
2018-01-10 19:05:48 +01:00
|
|
|
memcpy(glxc->largeCmdBuf, pc, dataBytes);
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2018-01-10 19:05:48 +01:00
|
|
|
glxc->largeCmdBytesSoFar = dataBytes;
|
|
|
|
glxc->largeCmdBytesTotal = cmdlen;
|
|
|
|
glxc->largeCmdRequestsSoFar = 1;
|
|
|
|
glxc->largeCmdRequestsTotal = req->requestTotal;
|
2012-03-21 20:55:09 +01:00
|
|
|
return Success;
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/*
|
|
|
|
** We are receiving subsequent (i.e. not the first) requests of a
|
|
|
|
** multi request command.
|
|
|
|
*/
|
2014-11-10 18:13:43 +01:00
|
|
|
int bytesSoFar; /* including this packet */
|
2012-03-21 20:55:09 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
** Check the request number and the total request count.
|
|
|
|
*/
|
2018-01-10 19:05:48 +01:00
|
|
|
if (req->requestNumber != glxc->largeCmdRequestsSoFar + 1) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = req->requestNumber;
|
2018-01-10 19:05:48 +01:00
|
|
|
ResetLargeCommandStatus(glxc);
|
2012-03-21 20:55:09 +01:00
|
|
|
return __glXError(GLXBadLargeRequest);
|
|
|
|
}
|
2018-01-10 19:05:48 +01:00
|
|
|
if (req->requestTotal != glxc->largeCmdRequestsTotal) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = req->requestTotal;
|
2018-01-10 19:05:48 +01:00
|
|
|
ResetLargeCommandStatus(glxc);
|
2012-03-21 20:55:09 +01:00
|
|
|
return __glXError(GLXBadLargeRequest);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Check that we didn't get too much data.
|
|
|
|
*/
|
2018-01-10 19:05:48 +01:00
|
|
|
if ((bytesSoFar = safe_add(glxc->largeCmdBytesSoFar, dataBytes)) < 0) {
|
2014-11-10 18:13:43 +01:00
|
|
|
client->errorValue = dataBytes;
|
2018-01-10 19:05:48 +01:00
|
|
|
ResetLargeCommandStatus(glxc);
|
2014-11-10 18:13:43 +01:00
|
|
|
return __glXError(GLXBadLargeRequest);
|
|
|
|
}
|
|
|
|
|
2018-01-10 19:05:48 +01:00
|
|
|
if (bytesSoFar > glxc->largeCmdBytesTotal) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = dataBytes;
|
2018-01-10 19:05:48 +01:00
|
|
|
ResetLargeCommandStatus(glxc);
|
2012-03-21 20:55:09 +01:00
|
|
|
return __glXError(GLXBadLargeRequest);
|
|
|
|
}
|
2014-11-10 18:13:43 +01:00
|
|
|
|
2018-01-10 19:05:48 +01:00
|
|
|
memcpy(glxc->largeCmdBuf + glxc->largeCmdBytesSoFar, pc, dataBytes);
|
|
|
|
glxc->largeCmdBytesSoFar += dataBytes;
|
|
|
|
glxc->largeCmdRequestsSoFar++;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2018-01-10 19:05:48 +01:00
|
|
|
if (req->requestNumber == glxc->largeCmdRequestsTotal) {
|
2012-03-21 20:55:09 +01:00
|
|
|
__GLXdispatchRenderProcPtr proc;
|
|
|
|
|
|
|
|
/*
|
|
|
|
** This is the last request; it must have enough bytes to complete
|
|
|
|
** the command.
|
|
|
|
*/
|
2014-11-10 18:13:43 +01:00
|
|
|
/* NOTE: the pad macro below is needed because the client library
|
|
|
|
** pads the total byte count, but not the per-request byte counts.
|
|
|
|
** The Protocol Encoding says the total byte count should not be
|
|
|
|
** padded, so a proposal will be made to the ARB to relax the
|
|
|
|
** padding constraint on the total byte count, thus preserving
|
|
|
|
** backward compatibility. Meanwhile, the padding done below
|
|
|
|
** fixes a bug that did not allow large commands of odd sizes to
|
|
|
|
** be accepted by the server.
|
2012-03-21 20:55:09 +01:00
|
|
|
*/
|
2018-01-10 19:05:48 +01:00
|
|
|
if (safe_pad(glxc->largeCmdBytesSoFar) != glxc->largeCmdBytesTotal) {
|
2012-03-21 20:55:09 +01:00
|
|
|
client->errorValue = dataBytes;
|
2018-01-10 19:05:48 +01:00
|
|
|
ResetLargeCommandStatus(glxc);
|
2012-03-21 20:55:09 +01:00
|
|
|
return __glXError(GLXBadLargeRequest);
|
|
|
|
}
|
2018-01-10 19:05:48 +01:00
|
|
|
hdr = (__GLXrenderLargeHeader *) glxc->largeCmdBuf;
|
2012-03-21 20:55:09 +01:00
|
|
|
/*
|
|
|
|
** The opcode and length field in the header had already been
|
|
|
|
** swapped when the first request was received.
|
|
|
|
**
|
|
|
|
** Use the opcode to index into the procedure table.
|
|
|
|
*/
|
|
|
|
opcode = hdr->opcode;
|
|
|
|
|
|
|
|
proc = (__GLXdispatchRenderProcPtr)
|
|
|
|
__glXGetProtocolDecodeFunction(&Render_dispatch_info, opcode,
|
|
|
|
client->swapped);
|
|
|
|
if (proc == NULL) {
|
|
|
|
client->errorValue = opcode;
|
|
|
|
return __glXError(GLXBadLargeRequest);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Skip over the header and execute the command.
|
|
|
|
*/
|
2018-01-10 19:05:48 +01:00
|
|
|
(*proc) (glxc->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
|
2012-03-21 20:55:09 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
** Reset for the next RenderLarge series.
|
|
|
|
*/
|
2018-01-10 19:05:48 +01:00
|
|
|
ResetLargeCommandStatus(glxc);
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/*
|
|
|
|
** This is neither the first nor the last request.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
return Success;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
** No support is provided for the vendor-private requests other than
|
|
|
|
** allocating the entry points in the dispatch table.
|
|
|
|
*/
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_VendorPrivate(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2006-08-23 22:30:13 +02:00
|
|
|
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
|
|
|
|
GLint vendorcode = req->vendorCode;
|
|
|
|
__GLXdispatchVendorPrivProcPtr proc;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2006-08-23 22:30:13 +02:00
|
|
|
proc = (__GLXdispatchVendorPrivProcPtr)
|
2012-03-21 20:55:09 +01:00
|
|
|
__glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info,
|
|
|
|
vendorcode, 0);
|
2006-08-23 22:30:13 +02:00
|
|
|
if (proc != NULL) {
|
2017-08-22 18:19:56 +02:00
|
|
|
return (*proc) (cl, (GLbyte *) req);
|
2004-06-16 11:25:21 +02:00
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
cl->client->errorValue = req->vendorCode;
|
2006-06-29 06:05:01 +02:00
|
|
|
return __glXError(GLXUnsupportedPrivateRequest);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc)
|
2006-08-23 22:30:13 +02:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2006-08-23 22:30:13 +02:00
|
|
|
xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
|
|
|
|
GLint vendorcode = req->vendorCode;
|
|
|
|
__GLXdispatchVendorPrivProcPtr proc;
|
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
|
2006-08-23 22:30:13 +02:00
|
|
|
|
|
|
|
proc = (__GLXdispatchVendorPrivProcPtr)
|
2012-03-21 20:55:09 +01:00
|
|
|
__glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info,
|
|
|
|
vendorcode, 0);
|
2006-08-23 22:30:13 +02:00
|
|
|
if (proc != NULL) {
|
2012-03-21 20:55:09 +01:00
|
|
|
return (*proc) (cl, (GLbyte *) req);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
cl->client->errorValue = vendorcode;
|
2006-06-29 06:05:01 +02:00
|
|
|
return __glXError(GLXUnsupportedPrivateRequest);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
|
|
|
|
xGLXQueryExtensionsStringReply reply;
|
2007-10-18 21:51:11 +02:00
|
|
|
__GLXscreen *pGlxScreen;
|
2003-11-14 17:48:57 +01:00
|
|
|
size_t n, length;
|
|
|
|
char *buf;
|
2007-10-18 21:51:11 +02:00
|
|
|
int err;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
n = strlen(pGlxScreen->GLXextensions) + 1;
|
2003-11-14 17:48:57 +01:00
|
|
|
length = __GLX_PAD(n) >> 2;
|
2012-07-10 04:12:43 +02:00
|
|
|
reply = (xGLXQueryExtensionsStringReply) {
|
|
|
|
.type = X_Reply,
|
|
|
|
.sequenceNumber = client->sequence,
|
|
|
|
.length = length,
|
|
|
|
.n = n
|
|
|
|
};
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
/* Allocate buffer to make sure it's a multiple of 4 bytes big. */
|
2012-07-10 04:12:42 +02:00
|
|
|
buf = calloc(length, 4);
|
2006-03-17 02:47:25 +01:00
|
|
|
if (buf == NULL)
|
2003-11-14 17:48:57 +01:00
|
|
|
return BadAlloc;
|
2007-10-18 21:51:11 +02:00
|
|
|
memcpy(buf, pGlxScreen->GLXextensions, n);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
if (client->swapped) {
|
2017-08-16 20:49:17 +02:00
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_DECLARE_SWAP_ARRAY_VARIABLES;
|
|
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
|
|
__GLX_SWAP_INT(&reply.length);
|
|
|
|
__GLX_SWAP_INT(&reply.n);
|
|
|
|
WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply);
|
|
|
|
__GLX_SWAP_INT_ARRAY((int *) buf, length);
|
|
|
|
WriteToClient(client, length << 2, buf);
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
else {
|
2012-05-13 09:03:35 +02:00
|
|
|
WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply);
|
|
|
|
WriteToClient(client, (int) (length << 2), buf);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2010-05-05 20:44:06 +02:00
|
|
|
free(buf);
|
2003-11-14 17:48:57 +01:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2016-03-16 16:38:13 +01:00
|
|
|
#ifndef GLX_VENDOR_NAMES_EXT
|
|
|
|
#define GLX_VENDOR_NAMES_EXT 0x20F6
|
|
|
|
#endif
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
ClientPtr client = cl->client;
|
|
|
|
xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
|
|
|
|
xGLXQueryServerStringReply reply;
|
|
|
|
size_t n, length;
|
|
|
|
const char *ptr;
|
|
|
|
char *buf;
|
2007-05-31 05:25:03 +02:00
|
|
|
__GLXscreen *pGlxScreen;
|
2007-10-18 21:51:11 +02:00
|
|
|
int err;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2007-10-18 21:51:11 +02:00
|
|
|
if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
|
2012-03-21 20:55:09 +01:00
|
|
|
return err;
|
|
|
|
|
|
|
|
switch (req->name) {
|
|
|
|
case GLX_VENDOR:
|
2012-11-09 22:33:54 +01:00
|
|
|
ptr = GLXServerVendorName;
|
2012-03-21 20:55:09 +01:00
|
|
|
break;
|
|
|
|
case GLX_VERSION:
|
2016-03-23 20:26:23 +01:00
|
|
|
ptr = "1.4";
|
2012-03-21 20:55:09 +01:00
|
|
|
break;
|
|
|
|
case GLX_EXTENSIONS:
|
|
|
|
ptr = pGlxScreen->GLXextensions;
|
|
|
|
break;
|
2016-03-16 16:38:13 +01:00
|
|
|
case GLX_VENDOR_NAMES_EXT:
|
|
|
|
if (pGlxScreen->glvnd) {
|
|
|
|
ptr = pGlxScreen->glvnd;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* else fall through */
|
2012-03-21 20:55:09 +01:00
|
|
|
default:
|
|
|
|
return BadValue;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2006-03-17 02:47:25 +01:00
|
|
|
n = strlen(ptr) + 1;
|
2003-11-14 17:48:57 +01:00
|
|
|
length = __GLX_PAD(n) >> 2;
|
2012-07-10 04:12:43 +02:00
|
|
|
reply = (xGLXQueryServerStringReply) {
|
|
|
|
.type = X_Reply,
|
|
|
|
.sequenceNumber = client->sequence,
|
|
|
|
.length = length,
|
|
|
|
.n = n
|
|
|
|
};
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2012-07-10 04:12:42 +02:00
|
|
|
buf = calloc(length, 4);
|
2006-03-17 02:47:25 +01:00
|
|
|
if (buf == NULL) {
|
2003-11-14 17:48:57 +01:00
|
|
|
return BadAlloc;
|
|
|
|
}
|
2006-03-17 02:47:25 +01:00
|
|
|
memcpy(buf, ptr, n);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
if (client->swapped) {
|
2017-08-16 20:49:17 +02:00
|
|
|
__GLX_DECLARE_SWAP_VARIABLES;
|
|
|
|
__GLX_SWAP_SHORT(&reply.sequenceNumber);
|
|
|
|
__GLX_SWAP_INT(&reply.length);
|
|
|
|
__GLX_SWAP_INT(&reply.n);
|
|
|
|
WriteToClient(client, sz_xGLXQueryServerStringReply, &reply);
|
|
|
|
/** no swap is needed for an array of chars **/
|
|
|
|
/* __GLX_SWAP_INT_ARRAY((int *)buf, length); */
|
|
|
|
WriteToClient(client, length << 2, buf);
|
2012-03-21 20:55:09 +01:00
|
|
|
}
|
|
|
|
else {
|
2012-05-13 09:03:35 +02:00
|
|
|
WriteToClient(client, sz_xGLXQueryServerStringReply, &reply);
|
2012-03-21 20:55:09 +01:00
|
|
|
WriteToClient(client, (int) (length << 2), buf);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2010-05-05 20:44:06 +02:00
|
|
|
free(buf);
|
2003-11-14 17:48:57 +01:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
int
|
|
|
|
__glXDisp_ClientInfo(__GLXclientState * cl, GLbyte * pc)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2010-07-03 20:47:55 +02:00
|
|
|
ClientPtr client = cl->client;
|
2003-11-14 17:48:57 +01:00
|
|
|
xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
|
|
|
|
const char *buf;
|
2012-03-21 20:55:09 +01:00
|
|
|
|
2010-07-03 20:47:55 +02:00
|
|
|
REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq);
|
|
|
|
|
2012-03-21 20:55:09 +01:00
|
|
|
buf = (const char *) (req + 1);
|
2010-07-03 20:47:55 +02:00
|
|
|
if (!memchr(buf, 0, (client->req_len << 2) - sizeof(xGLXClientInfoReq)))
|
2012-03-21 20:55:09 +01:00
|
|
|
return BadLength;
|
2010-07-03 20:47:55 +02:00
|
|
|
|
2010-06-06 10:28:30 +02:00
|
|
|
free(cl->GLClientextensions);
|
2010-06-04 11:58:58 +02:00
|
|
|
cl->GLClientextensions = strdup(buf);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
2013-11-22 07:48:31 +01:00
|
|
|
|
|
|
|
#include <GL/glxtokens.h>
|
|
|
|
|
|
|
|
void
|
|
|
|
__glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust,
|
|
|
|
CARD64 msc, CARD32 sbc)
|
|
|
|
{
|
|
|
|
ClientPtr client = clients[CLIENT_ID(drawable->drawId)];
|
|
|
|
|
|
|
|
xGLXBufferSwapComplete2 wire = {
|
|
|
|
.type = __glXEventBase + GLX_BufferSwapComplete
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!client)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
|
|
|
|
return;
|
|
|
|
|
|
|
|
wire.event_type = type;
|
|
|
|
wire.drawable = drawable->drawId;
|
|
|
|
wire.ust_hi = ust >> 32;
|
|
|
|
wire.ust_lo = ust & 0xffffffff;
|
|
|
|
wire.msc_hi = msc >> 32;
|
|
|
|
wire.msc_lo = msc & 0xffffffff;
|
|
|
|
wire.sbc = sbc;
|
|
|
|
|
|
|
|
WriteEventsToClient(client, 1, (xEvent *) &wire);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if PRESENT
|
|
|
|
static void
|
2014-09-04 17:36:07 +02:00
|
|
|
__glXpresentCompleteNotify(WindowPtr window, CARD8 present_kind, CARD8 present_mode,
|
|
|
|
CARD32 serial, uint64_t ust, uint64_t msc)
|
2013-11-22 07:48:31 +01:00
|
|
|
{
|
|
|
|
__GLXdrawable *drawable;
|
|
|
|
int glx_type;
|
|
|
|
int rc;
|
|
|
|
|
2014-09-04 17:36:07 +02:00
|
|
|
if (present_kind != PresentCompleteKindPixmap)
|
|
|
|
return;
|
|
|
|
|
2013-12-15 10:05:51 +01:00
|
|
|
rc = dixLookupResourceByType((void **) &drawable, window->drawable.id,
|
2013-11-22 07:48:31 +01:00
|
|
|
__glXDrawableRes, serverClient, DixGetAttrAccess);
|
|
|
|
|
|
|
|
if (rc != Success)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (present_mode == PresentCompleteModeFlip)
|
|
|
|
glx_type = GLX_FLIP_COMPLETE_INTEL;
|
|
|
|
else
|
|
|
|
glx_type = GLX_BLIT_COMPLETE_INTEL;
|
2014-10-31 00:45:12 +01:00
|
|
|
|
2013-11-22 07:48:31 +01:00
|
|
|
__glXsendSwapEvent(drawable, glx_type, ust, msc, serial);
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <present.h>
|
|
|
|
|
|
|
|
void
|
|
|
|
__glXregisterPresentCompleteNotify(void)
|
|
|
|
{
|
|
|
|
present_register_complete_notify(__glXpresentCompleteNotify);
|
|
|
|
}
|
|
|
|
#endif
|