/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
**
** http://oss.sgi.com/projects/FreeB
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
**
** 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.
**
** Additional Notice Provisions: The application programming interfaces
** established by SGI in conjunction with the Original Code are The
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
** Window System(R) (Version 1.3), released October 19, 1998. This software
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
**
*/
#ifdef HAVE_DMX_CONFIG_H
#include <dmx-config.h>
#endif
#include "dmx.h"
#include "dmxwindow.h"
#include "dmxpixmap.h"
#include "dmxfont.h"
#include "dmxsync.h"
#undef Xmalloc
#undef Xcalloc
#undef Xrealloc
#undef Xfree
#define NEED_REPLIES
#define FONT_PCF
#include "glxserver.h"
#include <GL/glxtokens.h>
#include "g_disptab.h"
#include <pixmapstr.h>
#include <windowstr.h>
#include "glxutil.h"
#include "glxext.h"
#include "unpack.h"
#include "GL/glxproto.h"
#include "glxvendor.h"
#include "glxvisuals.h"
#include "glxswap.h"
#ifdef PANORAMIX
#include "panoramiXsrv.h"
extern XID *PanoramiXVisualTable;
#endif
extern __GLXFBConfig **__glXFBConfigs;
extern int __glXNumFBConfigs;
extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id );
extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid );
extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen );
extern int glxIsExtensionSupported( char *ext );
extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc);
#define BE_TO_CLIENT_ERROR(x) \
( (x) >= __glXerrorBase ? \
(x) - dmxScreen->glxErrorBase + __glXerrorBase \
: (x) )
Display *GetBackEndDisplay( __GLXclientState *cl, int s )
{
if (! cl->be_displays[s] ) {
cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) );
}
return( cl->be_displays[s] );
}
/*
** Create a GL context with the given properties.
*/
static int CreateContext(__GLXclientState *cl,
GLXContextID gcId,
VisualID vid, GLXFBConfigID fbconfigId,
int screen,
GLXContextID shareList,
int isDirect )
{
ClientPtr client = cl->client;
xGLXCreateContextReq *be_req;
xGLXCreateNewContextReq *be_new_req;
VisualPtr pVisual;
ScreenPtr pScreen;
__GLXcontext *glxc, *shareglxc;
__GLXvisualConfig *pGlxVisual;
__GLXscreenInfo *pGlxScreen;
VisualID visual = vid;
GLint i;
int from_screen = screen;
int to_screen = screen;
DMXScreenInfo *dmxScreen;
VisualID be_vid;
GLXFBConfigID be_fbconfigId;
int num_be_screens;
Display *dpy;
/*
** Check if screen exists.
*/
if (screen >= screenInfo.numScreens) {
client->errorValue = screen;
return BadValue;
}
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
/*
** Find the display list space that we want to share.
**
*/
if (shareList == None) {
shareglxc = NULL;
} else {
shareglxc = (__GLXcontext *) LookupIDByType(shareList, __glXContextRes);
if (!shareglxc) {
client->errorValue = shareList;
return __glXBadContext;
}
}
/*
** Allocate memory for the new context
*/
glxc = (__GLXcontext *) __glXMalloc(sizeof(__GLXcontext));
if (!glxc) {
return BadAlloc;
}
memset(glxc, 0, sizeof(__GLXcontext));
pScreen = screenInfo.screens[screen];
pGlxScreen = &__glXActiveScreens[screen];
if (fbconfigId != None) {
glxc->pFBConfig = glxLookupFBConfig( fbconfigId );
if (!glxc->pFBConfig) {
client->errorValue = fbconfigId;
__glXFree( glxc );
return BadValue;
}
visual = glxc->pFBConfig->associatedVisualId;
}
else {
glxc->pFBConfig = NULL;
}
if (visual != None) {
/*
** Check if the visual ID is valid for this screen.
*/
pVisual = pScreen->visuals;
for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
if (pVisual->vid == visual) {
break;
}
}
if (i == pScreen->numVisuals) {
client->errorValue = visual;
__glXFree( glxc );
return BadValue;
}
pGlxVisual = pGlxScreen->pGlxVisual;
for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
if (pGlxVisual->vid == visual) {
break;
}
}
if (i == pGlxScreen->numVisuals) {
/*
** Visual not support on this screen by this OpenGL implementation.
*/
client->errorValue = visual;
__glXFree( glxc );
return BadValue;
}
if ( glxc->pFBConfig == NULL ) {
glxc->pFBConfig = glxLookupFBConfigByVID( visual );
if ( glxc->pFBConfig == NULL ) {
/*
* visual does not have an FBConfig ???
client->errorValue = visual;
__glXFree( glxc );
return BadValue;
*/
}
}
}
else {
pVisual = NULL;
pGlxVisual = NULL;
}
glxc->pScreen = pScreen;
glxc->pGlxScreen = pGlxScreen;
glxc->pVisual = pVisual;
glxc->pGlxVisual = pGlxVisual;
/*
* allocate memory for back-end servers info
*/
num_be_screens = to_screen - from_screen + 1;
glxc->real_ids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens);
if (!glxc->real_ids) {
return BadAlloc;
}
glxc->real_vids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens);
if (!glxc->real_vids) {
return BadAlloc;
}
for (screen = from_screen; screen <= to_screen; screen++) {
int sent = 0;
pScreen = screenInfo.screens[screen];
pGlxScreen = &__glXActiveScreens[screen];
dmxScreen = &dmxScreens[screen];
if (glxc->pFBConfig) {
__GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id,
screen );
be_fbconfigId = beFBConfig->id;
}
if (pGlxVisual) {
be_vid = glxMatchGLXVisualInConfigList( pGlxVisual,
dmxScreen->glxVisuals,
dmxScreen->numGlxVisuals );
if (!be_vid) {
/* visual is not supported on the back-end server */
__glXFree( glxc->real_ids );
__glXFree( glxc->real_vids );
__glXFree( glxc );
return BadValue;
}
}
glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen));
/* send the create context request to the back-end server */
dpy = GetBackEndDisplay(cl,screen);
if (glxc->pFBConfig) {
/*Since for a certain visual both RGB and COLOR INDEX
*can be on then the only parmeter to choose the renderType
* should be the class of the colormap since all 4 first
* classes does not support RGB mode only COLOR INDEX ,
* and so TrueColor and DirectColor does not support COLOR INDEX*/
int renderType = glxc->pFBConfig->renderType;
if ( pVisual ) {
switch ( pVisual->class ){
case PseudoColor:
case StaticColor:
case GrayScale:
case StaticGray:
renderType = GLX_COLOR_INDEX_TYPE;
break;
case TrueColor:
case DirectColor:
default:
renderType = GLX_RGBA_TYPE;
break;
}
}
if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
LockDisplay(dpy);
GetReq(GLXCreateNewContext,be_new_req);
be_new_req->reqType = dmxScreen->glxMajorOpcode;
be_new_req->glxCode = X_GLXCreateNewContext;
be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
be_new_req->fbconfig = (unsigned int)be_fbconfigId;
be_new_req->screen = DefaultScreen(dpy);
be_new_req->renderType = renderType;
be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
be_new_req->isDirect = 0;
UnlockDisplay(dpy);
glxc->real_vids[screen-from_screen] = be_fbconfigId;
sent = 1;
}
else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
xGLXCreateContextWithConfigSGIXReq *ext_req;
xGLXVendorPrivateReq *vpreq;
LockDisplay(dpy);
GetReqExtra(GLXVendorPrivate,
sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq,
vpreq);
ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq;
ext_req->reqType = dmxScreen->glxMajorOpcode;
ext_req->glxCode = X_GLXVendorPrivate;
ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
ext_req->fbconfig = (unsigned int)be_fbconfigId;
ext_req->screen = DefaultScreen(dpy);
ext_req->renderType = renderType;
ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
ext_req->isDirect = 0;
UnlockDisplay(dpy);
glxc->real_vids[screen-from_screen] = be_fbconfigId;
sent = 1;
}
}
if (!sent) {
LockDisplay(dpy);
GetReq(GLXCreateContext,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXCreateContext;
be_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
be_req->visual = (unsigned int)be_vid;
be_req->screen = DefaultScreen(dpy);
be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
be_req->isDirect = 0;
UnlockDisplay(dpy);
glxc->real_vids[screen-from_screen] = be_vid;
}
SyncHandle();
}
/*
** Register this context as a resource.
*/
if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
__glXFree( glxc->real_ids );
__glXFree( glxc->real_vids );
__glXFree( glxc );
client->errorValue = gcId;
return BadAlloc;
}
/*
** Finally, now that everything is working, setup the rest of the
** context.
*/
glxc->id = gcId;
glxc->share_id = shareList;
glxc->idExists = GL_TRUE;
glxc->isCurrent = GL_FALSE;
return Success;
}
int __glXCreateContext(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
return( CreateContext(cl, req->context,req->visual, None,
req->screen, req->shareList, req->isDirect) );
}
int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
return( CreateContext(cl, req->context,None, req->fbconfig,
req->screen, req->shareList, req->isDirect) );
}
int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc;
return( CreateContext(cl, req->context, None, req->fbconfig,
req->screen, req->shareList, req->isDirect) );
}
int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXQueryMaxSwapBarriersSGIXReq *req =
(xGLXQueryMaxSwapBarriersSGIXReq *)pc;
xGLXQueryMaxSwapBarriersSGIXReply reply;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
reply.length = 0;
reply.max = QueryMaxSwapBarriersSGIX(req->screen);
if (client->swapped) {
__glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply);
} else {
WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
(char *)&reply);
}
return Success;
}
int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc;
DrawablePtr pDraw;
__GLXpixmap *pGlxPixmap = NULL;
__glXWindow *pGlxWindow = NULL;
int rc;
rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixUnknownAccess);
if (rc != Success) {
pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable,
__glXPixmapRes);
if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
}
if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable,
__glXWindowRes);
if (pGlxWindow) pDraw = pGlxWindow->pDraw;
}
if (!pDraw) {
client->errorValue = req->drawable;
return __glXBadDrawable;
}
return BindSwapBarrierSGIX(pDraw, req->barrier);
}
int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc;
DrawablePtr pDraw, pMember = NULL;
__GLXpixmap *pGlxPixmap = NULL;
__glXWindow *pGlxWindow = NULL;
int rc;
rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixUnknownAccess);
if (rc != Success) {
pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable,
__glXPixmapRes);
if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
}
if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable,
__glXWindowRes);
if (pGlxWindow) pDraw = pGlxWindow->pDraw;
}
if (!pDraw) {
client->errorValue = req->drawable;
return __glXBadDrawable;
}
if (req->member != None) {
rc = dixLookupDrawable(&pMember, req->member, client, 0,
DixUnknownAccess);
if (rc != Success) {
pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->member,
__glXPixmapRes);
if (pGlxPixmap) pMember = pGlxPixmap->pDraw;
}
if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
pGlxWindow = (__glXWindow *) LookupIDByType(req->member,
__glXWindowRes);
if (pGlxWindow) pMember = pGlxWindow->pDraw;
}
if (!pMember) {
client->errorValue = req->member;
return __glXBadDrawable;
}
}
return JoinSwapGroupSGIX(pDraw, pMember);
}
/*
** Destroy a GL context as an X resource.
*/
int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
xGLXDestroyContextReq *be_req;
GLXContextID gcId = req->context;
__GLXcontext *glxc;
int from_screen = 0;
int to_screen = 0;
int s;
glxc = (__GLXcontext *) LookupIDByType(gcId, __glXContextRes);
if (glxc) {
/*
** Just free the resource; don't actually destroy the context,
** because it might be in use. The
** destroy method will be called by the resource destruction routine
** if necessary.
*/
FreeResourceByType(gcId, __glXContextRes, FALSE);
from_screen = to_screen = glxc->pScreen->myNum;
} else {
client->errorValue = gcId;
return __glXBadContext;
}
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
/*
* send DestroyContext request to all back-end servers
*/
for (s=from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
LockDisplay(dpy);
GetReq(GLXDestroyContext,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXDestroyContext;
be_req->context = glxc->real_ids[s-from_screen];
UnlockDisplay(dpy);
SyncHandle();
}
return Success;
}
/*****************************************************************************/
/*
** For each client, the server keeps a table of all the contexts that are
** current for that client (each thread of a client may have its own current
** context). These routines add, change, and lookup contexts in the table.
*/
/*
** Add a current context, and return the tag that will be used to refer to it.
*/
static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw)
{
int i;
int num = cl->numCurrentContexts;
__GLXcontext **table = cl->currentContexts;
if (!glxc) return -1;
/*
** Try to find an empty slot and use it.
*/
for (i=0; i < num; i++) {
if (!table[i]) {
table[i] = glxc;
return i+1;
}
}
/*
** Didn't find a free slot, so we'll have to grow the table.
*/
if (!num) {
table = (__GLXcontext **) __glXMalloc(sizeof(__GLXcontext *));
cl->currentDrawables = (DrawablePtr *) __glXMalloc(sizeof(DrawablePtr));
cl->be_currentCTag = (GLXContextTag *) __glXMalloc(screenInfo.numScreens *sizeof(GLXContextTag));
} else {
table = (__GLXcontext **) __glXRealloc(table,
(num+1)*sizeof(__GLXcontext *));
cl->currentDrawables = (DrawablePtr *) __glXRealloc(
cl->currentDrawables ,
(num+1)*sizeof(DrawablePtr));
cl->be_currentCTag = (GLXContextTag *) __glXRealloc(cl->be_currentCTag,
(num+1)*screenInfo.numScreens*sizeof(GLXContextTag));
}
table[num] = glxc;
cl->currentDrawables[num] = pDraw;
cl->currentContexts = table;
cl->numCurrentContexts++;
memset(cl->be_currentCTag + num*screenInfo.numScreens, 0,
screenInfo.numScreens * sizeof(GLXContextTag));
return num+1;
}
/*
** Given a tag, change the current context for the corresponding entry.
*/
static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
GLXContextTag tag)
{
__GLXcontext **table = cl->currentContexts;
table[tag-1] = glxc;
}
/*
** Given a tag, and back-end screen number, retrives the current back-end
** tag.
*/
int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s)
{
if (tag >0) {
return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] );
}
else {
return( 0 );
}
}
/*
** Given a tag, and back-end screen number, sets the current back-end
** tag.
*/
static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag)
{
if (tag >0) {
cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag;
}
}
/*
** For this implementation we have chosen to simply use the index of the
** context's entry in the table as the context tag. A tag must be greater
** than 0.
*/
__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
{
int num = cl->numCurrentContexts;
if (tag < 1 || tag > num) {
return 0;
} else {
return cl->currentContexts[tag-1];
}
}
DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag)
{
int num = cl->numCurrentContexts;
if (tag < 1 || tag > num) {
return 0;
} else {
return cl->currentDrawables[tag-1];
}
}
/*****************************************************************************/
static void StopUsingContext(__GLXcontext *glxc)
{
if (glxc) {
if (glxc == __glXLastContext) {
/* Tell server GL library */
__glXLastContext = 0;
}
glxc->isCurrent = GL_FALSE;
if (!glxc->idExists) {
__glXFreeContext(glxc);
}
}
}
static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
{
glxc->isCurrent = GL_TRUE;
}
/*****************************************************************************/
/*
** Make an OpenGL context and drawable current.
*/
static int MakeCurrent(__GLXclientState *cl,
GLXDrawable drawable,
GLXDrawable readdrawable,
GLXContextID context,
GLXContextTag oldContextTag)
{
ClientPtr client = cl->client;
DrawablePtr pDraw = NULL;
DrawablePtr pReadDraw = NULL;
xGLXMakeCurrentReadSGIReply new_reply;
xGLXMakeCurrentReq *be_req;
xGLXMakeCurrentReply be_reply;
xGLXMakeContextCurrentReq *be_new_req;
xGLXMakeContextCurrentReply be_new_reply;
GLXDrawable drawId = drawable;
GLXDrawable readId = readdrawable;
GLXContextID contextId = context;
__GLXpixmap *pGlxPixmap = 0;
__GLXpixmap *pReadGlxPixmap = 0;
__GLXcontext *glxc, *prevglxc;
GLXContextTag tag = oldContextTag;
WindowPtr pWin = NULL;
WindowPtr pReadWin = NULL;
__glXWindow *pGlxWindow = NULL;
__glXWindow *pGlxReadWindow = NULL;
__glXPbuffer *pGlxPbuffer = NULL;
__glXPbuffer *pGlxReadPbuffer = NULL;
#ifdef PANORAMIX
PanoramiXRes *pXinDraw = NULL;
PanoramiXRes *pXinReadDraw = NULL;
#endif
int from_screen = 0;
int to_screen = 0;
int s, rc;
/*
** If one is None and the other isn't, it's a bad match.
*/
if ((drawId == None && contextId != None) ||
(drawId != None && contextId == None)) {
return BadMatch;
}
/*
** Lookup old context. If we have one, it must be in a usable state.
*/
if (tag != 0) {
prevglxc = __glXLookupContextByTag(cl, tag);
if (!prevglxc) {
/*
** Tag for previous context is invalid.
*/
return __glXBadContextTag;
}
} else {
prevglxc = 0;
}
/*
** Lookup new context. It must not be current for someone else.
*/
if (contextId != None) {
glxc = (__GLXcontext *) LookupIDByType(contextId, __glXContextRes);
if (!glxc) {
client->errorValue = contextId;
return __glXBadContext;
}
if ((glxc != prevglxc) && glxc->isCurrent) {
/* Context is current to somebody else */
return BadAccess;
}
} else {
/* Switching to no context. Ignore new drawable. */
glxc = 0;
}
if (drawId != None) {
rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
if (rc == Success) {
if (pDraw->type == DRAWABLE_WINDOW) {
/*
** Drawable is an X Window.
*/
VisualID vid;
pWin = (WindowPtr)pDraw;
vid = wVisual(pWin);
new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
new_reply.writeType = GLX_WINDOW_TYPE;
/*
** Check if window and context are similar.
*/
if ((vid != glxc->pVisual->vid) ||
(pWin->drawable.pScreen != glxc->pScreen)) {
client->errorValue = drawId;
return BadMatch;
}
from_screen = to_screen = pWin->drawable.pScreen->myNum;
} else {
/*
** An X Pixmap is not allowed as a parameter (a GLX Pixmap
** is, but it must first be created with glxCreateGLXPixmap).
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
}
if (!pDraw) {
pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
__glXPixmapRes);
if (pGlxPixmap) {
/*
** Check if pixmap and context are similar.
*/
if (pGlxPixmap->pScreen != glxc->pScreen ||
pGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
client->errorValue = drawId;
return BadMatch;
}
pDraw = pGlxPixmap->pDraw;
new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
pGlxPixmap->pGlxVisual->vid);
new_reply.writeType = GLX_PIXMAP_TYPE;
from_screen = to_screen = pGlxPixmap->pScreen->myNum;
}
}
if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
if (pGlxWindow) {
/*
** Drawable is a GLXWindow.
**
** Check if GLX window and context are similar.
*/
if (pGlxWindow->pScreen != glxc->pScreen ||
pGlxWindow->pGlxFBConfig != glxc->pFBConfig) {
client->errorValue = drawId;
return BadMatch;
}
pDraw = pGlxWindow->pDraw;
new_reply.writeVid = pGlxWindow->pGlxFBConfig->id;
new_reply.writeType = GLX_GLXWINDOW_TYPE;
}
}
if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
if (pGlxPbuffer) {
if (pGlxPbuffer->pScreen != glxc->pScreen ||
pGlxPbuffer->pFBConfig != glxc->pFBConfig) {
client->errorValue = drawId;
return BadMatch;
}
pDraw = (DrawablePtr)pGlxPbuffer;
new_reply.writeVid = pGlxPbuffer->pFBConfig->id;
new_reply.writeType = GLX_PBUFFER_TYPE;
}
}
if (!pDraw) {
/*
** Drawable is not a Window , GLXWindow or a GLXPixmap.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
} else {
pDraw = 0;
}
if (readId != None && readId != drawId ) {
rc = dixLookupDrawable(&pReadDraw, readId, client, 0,DixUnknownAccess);
if (rc == Success) {
if (pReadDraw->type == DRAWABLE_WINDOW) {
/*
** Drawable is an X Window.
*/
VisualID vid;
pReadWin = (WindowPtr)pDraw;
vid = wVisual(pReadWin);
new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
new_reply.readType = GLX_WINDOW_TYPE;
/*
** Check if window and context are similar.
*/
if ((vid != glxc->pVisual->vid) ||
(pReadWin->drawable.pScreen != glxc->pScreen)) {
client->errorValue = readId;
return BadMatch;
}
} else {
/*
** An X Pixmap is not allowed as a parameter (a GLX Pixmap
** is, but it must first be created with glxCreateGLXPixmap).
*/
client->errorValue = readId;
return __glXBadDrawable;
}
}
if (!pReadDraw) {
pReadGlxPixmap = (__GLXpixmap *) LookupIDByType(readId,
__glXPixmapRes);
if (pReadGlxPixmap) {
/*
** Check if pixmap and context are similar.
*/
if (pReadGlxPixmap->pScreen != glxc->pScreen ||
pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
client->errorValue = readId;
return BadMatch;
}
pReadDraw = pReadGlxPixmap->pDraw;
new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
pReadGlxPixmap->pGlxVisual->vid );
new_reply.readType = GLX_PIXMAP_TYPE;
}
}
if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
pGlxReadWindow = (__glXWindow *)
LookupIDByType(readId, __glXWindowRes);
if (pGlxReadWindow) {
/*
** Drawable is a GLXWindow.
**
** Check if GLX window and context are similar.
*/
if (pGlxReadWindow->pScreen != glxc->pScreen ||
pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) {
client->errorValue = readId;
return BadMatch;
}
pReadDraw = pGlxReadWindow->pDraw;
new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id;
new_reply.readType = GLX_GLXWINDOW_TYPE;
}
}
if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
pGlxReadPbuffer = (__glXPbuffer *)LookupIDByType(readId, __glXPbufferRes);
if (pGlxReadPbuffer) {
if (pGlxReadPbuffer->pScreen != glxc->pScreen ||
pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) {
client->errorValue = drawId;
return BadMatch;
}
pReadDraw = (DrawablePtr)pGlxReadPbuffer;
new_reply.readVid = pGlxReadPbuffer->pFBConfig->id;
new_reply.readType = GLX_PBUFFER_TYPE;
}
}
if (!pReadDraw) {
/*
** Drawable is neither a Window nor a GLXPixmap.
*/
client->errorValue = readId;
return __glXBadDrawable;
}
} else {
pReadDraw = pDraw;
pReadGlxPixmap = pGlxPixmap;
pReadWin = pWin;
new_reply.readVid = new_reply.writeVid;
new_reply.readType = new_reply.writeType;
}
if (prevglxc) {
if (prevglxc->pGlxPixmap) {
/*
** The previous drawable was a glx pixmap, release it.
*/
prevglxc->pGlxPixmap->refcnt--;
__glXFreeGLXPixmap( prevglxc->pGlxPixmap );
prevglxc->pGlxPixmap = 0;
}
if (prevglxc->pGlxReadPixmap &&
prevglxc->pGlxReadPixmap != prevglxc->pGlxPixmap ) {
/*
** The previous drawable was a glx pixmap, release it.
*/
prevglxc->pGlxReadPixmap->refcnt--;
__glXFreeGLXPixmap( prevglxc->pGlxReadPixmap );
prevglxc->pGlxReadPixmap = 0;
}
if (prevglxc->pGlxWindow) {
/*
** The previous drawable was a glx window, release it.
*/
prevglxc->pGlxWindow->refcnt--;
__glXFreeGLXWindow( prevglxc->pGlxWindow );
prevglxc->pGlxWindow = 0;
}
if (prevglxc->pGlxReadWindow &&
prevglxc->pGlxReadWindow != prevglxc->pGlxWindow) {
/*
** The previous drawable was a glx window, release it.
*/
prevglxc->pGlxReadWindow->refcnt--;
__glXFreeGLXWindow( prevglxc->pGlxReadWindow );
prevglxc->pGlxReadWindow = 0;
}
if (prevglxc->pGlxPbuffer) {
/*
** The previous drawable was a glx Pbuffer, release it.
*/
prevglxc->pGlxPbuffer->refcnt--;
__glXFreeGLXPbuffer( prevglxc->pGlxPbuffer );
prevglxc->pGlxPbuffer = 0;
}
if (prevglxc->pGlxReadPbuffer &&
prevglxc->pGlxReadPbuffer != prevglxc->pGlxPbuffer ) {
/*
** The previous drawable was a glx Pbuffer, release it.
*/
prevglxc->pGlxReadPbuffer->refcnt--;
__glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer );
prevglxc->pGlxReadPbuffer = 0;
}
ChangeCurrentContext(cl, glxc, tag);
ChangeCurrentContext(cl, glxc, tag);
StopUsingContext(prevglxc);
} else {
tag = AddCurrentContext(cl, glxc, pDraw);
}
if (glxc) {
glxc->pGlxPixmap = pGlxPixmap;
glxc->pGlxReadPixmap = pReadGlxPixmap;
glxc->pGlxWindow = pGlxWindow;
glxc->pGlxReadWindow = pGlxReadWindow;
glxc->pGlxPbuffer = pGlxPbuffer;
glxc->pGlxReadPbuffer = pGlxReadPbuffer;
if (pGlxPixmap) {
pGlxPixmap->refcnt++;
}
if (pReadGlxPixmap && pReadGlxPixmap != pGlxPixmap) {
pReadGlxPixmap->refcnt++;
}
if (pGlxWindow) {
pGlxWindow->refcnt++;
}
if (pGlxReadWindow && pGlxReadWindow != pGlxWindow) {
pGlxReadWindow->refcnt++;
}
if (pGlxPbuffer) {
pGlxPbuffer->refcnt++;
}
if (pGlxReadPbuffer && pGlxReadPbuffer != pGlxPbuffer) {
pGlxReadPbuffer->refcnt++;
}
StartUsingContext(cl, glxc);
new_reply.contextTag = tag;
} else {
new_reply.contextTag = 0;
}
new_reply.length = 0;
new_reply.type = X_Reply;
new_reply.sequenceNumber = client->sequence;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) {
pXinDraw = (PanoramiXRes *)
SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
}
if (pReadDraw && pReadDraw != pDraw &&
new_reply.readType != GLX_PBUFFER_TYPE) {
pXinReadDraw = (PanoramiXRes *)
SecurityLookupIDByClass(client, pReadDraw->id, XRC_DRAWABLE, DixReadAccess);
}
else {
pXinReadDraw = pXinDraw;
}
}
#endif
/* send the MakeCurrent request to all required
* back-end servers.
*/
for (s = from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
unsigned int be_draw = None;
unsigned int be_read_draw = None;
if (pGlxPixmap) {
be_draw = pGlxPixmap->be_xids[s];
}
else if (pGlxPbuffer) {
be_draw = pGlxPbuffer->be_xids[s];
}
#ifdef PANORAMIX
else if (pXinDraw) {
dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
}
#endif
else if (pGlxWindow) {
pWin = (WindowPtr)pGlxWindow->pDraw;
}
if (pWin && be_draw == None) {
be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
if (!be_draw) {
/* it might be that the window did not created yet on the */
/* back-end server (lazy window creation option), force */
/* creation of the window */
dmxCreateAndRealizeWindow( pWin, TRUE );
be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
}
}
/*
* Before sending the MakeCurrent request - sync the
* X11 connection to the back-end servers to make sure
* that drawable is already created
*/
dmxSync( dmxScreen, 1 );
if (drawId == readId) {
LockDisplay(dpy);
GetReq(GLXMakeCurrent, be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXMakeCurrent;
be_req->drawable = be_draw;
be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) {
/* The make current failed */
UnlockDisplay(dpy);
SyncHandle();
return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
}
UnlockDisplay(dpy);
SyncHandle();
SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag );
}
else {
if (pReadGlxPixmap) {
be_read_draw = pReadGlxPixmap->be_xids[s];
}
else if (pGlxReadPbuffer) {
be_read_draw = pGlxReadPbuffer->be_xids[s];
}
#ifdef PANORAMIX
else if (pXinReadDraw) {
dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client,
DixReadAccess);
}
#endif
else if (pGlxReadWindow) {
pReadWin = (WindowPtr)pGlxReadWindow->pDraw;
}
if (pReadWin && be_read_draw == None) {
be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
if (!be_read_draw) {
/* it might be that the window did not created yet on the */
/* back-end server (lazy window creation option), force */
/* creation of the window */
dmxCreateAndRealizeWindow( pReadWin, TRUE );
be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
dmxSync( dmxScreen, 1 );
}
}
if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
LockDisplay(dpy);
GetReq(GLXMakeContextCurrent, be_new_req);
be_new_req->reqType = dmxScreen->glxMajorOpcode;
be_new_req->glxCode = X_GLXMakeContextCurrent;
be_new_req->drawable = be_draw;
be_new_req->readdrawable = be_read_draw;
be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) {
/* The make current failed */
UnlockDisplay(dpy);
SyncHandle();
return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
}
UnlockDisplay(dpy);
SyncHandle();
SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag );
}
else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) {
xGLXMakeCurrentReadSGIReq *ext_req;
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXMakeCurrentReadSGIReply ext_reply;
LockDisplay(dpy);
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq,
vpreq);
ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq;
ext_req->reqType = dmxScreen->glxMajorOpcode;
ext_req->glxCode = X_GLXVendorPrivateWithReply;
ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
ext_req->drawable = be_draw;
ext_req->readable = be_read_draw;
ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) {
/* The make current failed */
UnlockDisplay(dpy);
SyncHandle();
return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
}
UnlockDisplay(dpy);
SyncHandle();
SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag );
}
else {
return BadMatch;
}
}
XFlush( dpy );
}
if (client->swapped) {
__glXSwapMakeCurrentReply(client, &new_reply);
} else {
WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply);
}
return Success;
}
int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc)
{
xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
return( MakeCurrent(cl, req->drawable, req->drawable,
req->context, req->oldContextTag ) );
}
int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
{
xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
return( MakeCurrent(cl, req->drawable, req->readdrawable,
req->context, req->oldContextTag ) );
}
int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
{
xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
return( MakeCurrent(cl, req->drawable, req->readable,
req->context, req->oldContextTag ) );
}
int __glXIsDirect(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
xGLXIsDirectReply reply;
__GLXcontext *glxc;
/*
** Find the GL context.
*/
glxc = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
if (!glxc) {
client->errorValue = req->context;
return __glXBadContext;
}
reply.isDirect = 0;
reply.length = 0;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
if (client->swapped) {
__glXSwapIsDirectReply(client, &reply);
} else {
WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
}
return Success;
}
int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
/* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */
xGLXQueryVersionReply reply;
/*
** 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.
*/
reply.majorVersion = __glXVersionMajor;
reply.minorVersion = __glXVersionMinor;
reply.length = 0;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
if (client->swapped) {
__glXSwapQueryVersionReply(client, &reply);
} else {
WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
}
return Success;
}
int __glXWaitGL(__GLXclientState *cl, GLbyte *pc)
{
xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc;
int from_screen = 0;
int to_screen = 0;
int s;
__GLXcontext *glxc = NULL;
if (req->contextTag != 0) {
glxc = __glXLookupContextByTag(cl, req->contextTag);
if (glxc) {
from_screen = to_screen = glxc->pScreen->myNum;
}
}
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
for (s=from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
LockDisplay(dpy);
GetReq(GLXWaitGL,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXWaitGL;
be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
UnlockDisplay(dpy);
SyncHandle();
XSync(dpy, False);
}
return Success;
}
int __glXWaitX(__GLXclientState *cl, GLbyte *pc)
{
xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
xGLXWaitXReq *be_req;
int from_screen = 0;
int to_screen = 0;
int s;
__GLXcontext *glxc = NULL;
if (req->contextTag != 0) {
glxc = __glXLookupContextByTag(cl, req->contextTag);
if (glxc) {
from_screen = to_screen = glxc->pScreen->myNum;
}
}
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
for (s=from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
dmxSync( dmxScreen, 1 );
LockDisplay(dpy);
GetReq(GLXWaitX,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXWaitX;
be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
UnlockDisplay(dpy);
SyncHandle();
XFlush( dpy );
}
return Success;
}
int __glXCopyContext(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXCopyContextReq *be_req;
xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
GLXContextID source = req->source;
GLXContextID dest = req->dest;
GLXContextTag tag = req->contextTag;
unsigned long mask = req->mask;
__GLXcontext *src, *dst;
int s;
int from_screen = 0;
int to_screen = 0;
/*
** Check that each context exists.
*/
src = (__GLXcontext *) LookupIDByType(source, __glXContextRes);
if (!src) {
client->errorValue = source;
return __glXBadContext;
}
dst = (__GLXcontext *) LookupIDByType(dest, __glXContextRes);
if (!dst) {
client->errorValue = dest;
return __glXBadContext;
}
/*
** They must be in the same address space, and same screen.
*/
if (src->pGlxScreen != dst->pGlxScreen) {
client->errorValue = source;
return BadMatch;
}
/*
** The destination context must not be current for any client.
*/
if (dst->isCurrent) {
client->errorValue = dest;
return BadAccess;
}
if (tag) {
__GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
if (!tagcx) {
return __glXBadContextTag;
}
if (tagcx != src) {
/*
** This would be caused by a faulty implementation of the client
** library.
*/
return BadMatch;
}
}
from_screen = to_screen = src->pScreen->myNum;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
for (s=from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
LockDisplay(dpy);
GetReq(GLXCopyContext,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXCopyContext;
be_req->source = (unsigned int)src->real_ids[s-from_screen];
be_req->dest = (unsigned int)dst->real_ids[s-from_screen];
be_req->mask = mask;
be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
UnlockDisplay(dpy);
SyncHandle();
}
return Success;
}
int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
xGLXGetVisualConfigsReply reply;
__GLXscreenInfo *pGlxScreen;
__GLXvisualConfig *pGlxVisual;
CARD32 buf[__GLX_TOTAL_CONFIG];
unsigned int screen;
int i, p;
screen = req->screen;
if (screen > screenInfo.numScreens) {
/* The client library must send a valid screen number. */
client->errorValue = screen;
return BadValue;
}
pGlxScreen = &__glXActiveScreens[screen];
reply.numVisuals = pGlxScreen->numGLXVisuals;
reply.numProps = __GLX_TOTAL_CONFIG;
reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
__GLX_TOTAL_CONFIG) >> 2;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
for (i=0; i < pGlxScreen->numVisuals; i++) {
pGlxVisual = &pGlxScreen->pGlxVisual[i];
if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) {
/* not a usable visual */
continue;
}
p = 0;
buf[p++] = pGlxVisual->vid;
buf[p++] = pGlxVisual->class;
buf[p++] = pGlxVisual->rgba;
buf[p++] = pGlxVisual->redSize;
buf[p++] = pGlxVisual->greenSize;
buf[p++] = pGlxVisual->blueSize;
buf[p++] = pGlxVisual->alphaSize;
buf[p++] = pGlxVisual->accumRedSize;
buf[p++] = pGlxVisual->accumGreenSize;
buf[p++] = pGlxVisual->accumBlueSize;
buf[p++] = pGlxVisual->accumAlphaSize;
buf[p++] = pGlxVisual->doubleBuffer;
buf[p++] = pGlxVisual->stereo;
buf[p++] = pGlxVisual->bufferSize;
buf[p++] = pGlxVisual->depthSize;
buf[p++] = pGlxVisual->stencilSize;
buf[p++] = pGlxVisual->auxBuffers;
buf[p++] = pGlxVisual->level;
/*
** Add token/value pairs for extensions.
*/
buf[p++] = GLX_VISUAL_CAVEAT_EXT;
buf[p++] = pGlxVisual->visualRating;
buf[p++] = GLX_TRANSPARENT_TYPE_EXT;
buf[p++] = pGlxVisual->transparentPixel;
buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT;
buf[p++] = pGlxVisual->transparentRed;
buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT;
buf[p++] = pGlxVisual->transparentGreen;
buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT;
buf[p++] = pGlxVisual->transparentBlue;
buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT;
buf[p++] = pGlxVisual->transparentAlpha;
buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT;
buf[p++] = pGlxVisual->transparentIndex;
buf[p++] = GLX_SAMPLES_SGIS;
buf[p++] = pGlxVisual->multiSampleSize;
buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
buf[p++] = pGlxVisual->nMultiSampleBuffers;
buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
buf[p++] = pGlxVisual->visualSelectGroup;
WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
(char *)buf);
}
return Success;
}
/*
** Create a GLX Pixmap from an X Pixmap.
*/
static int CreateGLXPixmap(__GLXclientState *cl,
VisualID visual, GLXFBConfigID fbconfigId,
int screenNum, XID pixmapId, XID glxpixmapId )
{
ClientPtr client = cl->client;
xGLXCreateGLXPixmapReq *be_req;
xGLXCreatePixmapReq *be_new_req;
DrawablePtr pDraw;
ScreenPtr pScreen;
VisualPtr pVisual;
__GLXpixmap *pGlxPixmap;
__GLXscreenInfo *pGlxScreen;
__GLXvisualConfig *pGlxVisual;
__GLXFBConfig *pFBConfig;
int i, s, rc;
int from_screen, to_screen;
#ifdef PANORAMIX
PanoramiXRes *pXinDraw = NULL;
#endif
rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP,
DixUnknownAccess);
if (rc != Success)
return rc;
/*
** Check if screen of visual matches screen of pixmap.
*/
pScreen = pDraw->pScreen;
if (screenNum != pScreen->myNum) {
return BadMatch;
}
if (fbconfigId == NULL && visual == NULL) {
return BadValue;
}
if (fbconfigId != None) {
pFBConfig = glxLookupFBConfig( fbconfigId );
if (!pFBConfig) {
client->errorValue = fbconfigId;
return BadValue;
}
visual = pFBConfig->associatedVisualId;
}
else {
pFBConfig = NULL;
}
if (visual != None) {
/*
** Find the VisualRec for this visual.
*/
pVisual = pScreen->visuals;
for (i=0; i < pScreen->numVisuals; i++, pVisual++) {
if (pVisual->vid == visual) {
break;
}
}
if (i == pScreen->numVisuals) {
client->errorValue = visual;
return BadValue;
}
/*
** Check if depth of visual matches depth of pixmap.
*/
if (pVisual->nplanes != pDraw->depth) {
client->errorValue = visual;
return BadMatch;
}
/*
** Get configuration of the visual.
*/
pGlxScreen = &__glXActiveScreens[screenNum];
pGlxVisual = pGlxScreen->pGlxVisual;
for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
if (pGlxVisual->vid == visual) {
break;
}
}
if (i == pGlxScreen->numVisuals) {
/*
** Visual not support on this screen by this OpenGL implementation.
*/
client->errorValue = visual;
return BadValue;
}
/* find the FBConfig for that visual (if any) */
if ( pFBConfig == NULL ) {
pFBConfig = glxLookupFBConfigByVID( visual );
if ( pFBConfig == NULL ) {
/*
* visual does not have an FBConfig ???
client->errorValue = visual;
return BadValue;
*/
}
}
}
else {
pVisual = NULL;
pGlxVisual = NULL;
}
pGlxPixmap = (__GLXpixmap *) __glXMalloc(sizeof(__GLXpixmap));
if (!pGlxPixmap) {
return BadAlloc;
}
pGlxPixmap->be_xids = (XID *) __glXMalloc(sizeof(XID) * screenInfo.numScreens);
if (!pGlxPixmap->be_xids) {
__glXFree( pGlxPixmap );
return BadAlloc;
}
pGlxPixmap->pDraw = pDraw;
pGlxPixmap->pGlxScreen = pGlxScreen;
pGlxPixmap->pGlxVisual = pGlxVisual;
pGlxPixmap->pFBConfig = pFBConfig;
pGlxPixmap->pScreen = pScreen;
pGlxPixmap->idExists = True;
pGlxPixmap->refcnt = 0;
/*
** Bump the ref count on the X pixmap so it won't disappear.
*/
((PixmapPtr) pDraw)->refcnt++;
/*
* send the request to the back-end server(s)
*/
from_screen = to_screen = screenNum;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
pXinDraw = (PanoramiXRes *)
SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
}
#endif
for (s=from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
Pixmap be_pixmap;
DrawablePtr pRealDraw = pDraw;
#ifdef PANORAMIX
if (pXinDraw) {
dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0,
DixUnknownAccess);
}
#endif
be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap;
/* make sure pixmap already created on back-end */
dmxSync( dmxScreen, 1 );
if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
__GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
LockDisplay(dpy);
pGlxPixmap->be_xids[s] = XAllocID(dpy);
GetReq(GLXCreatePixmap,be_new_req);
be_new_req->reqType = dmxScreen->glxMajorOpcode;
be_new_req->glxCode = X_GLXCreatePixmap;
be_new_req->screen = DefaultScreen(dpy);
be_new_req->fbconfig = be_FBConfig->id;
be_new_req->pixmap = (unsigned int)be_pixmap;
be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
be_new_req->numAttribs = 0;
UnlockDisplay(dpy);
SyncHandle();
}
else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
__GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req;
xGLXVendorPrivateReq *vpreq;
LockDisplay(dpy);
pGlxPixmap->be_xids[s] = XAllocID(dpy);
GetReqExtra(GLXVendorPrivate,
sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq,
vpreq);
ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq;
ext_req->reqType = dmxScreen->glxMajorOpcode;
ext_req->glxCode = X_GLXVendorPrivate;
ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
ext_req->screen = DefaultScreen(dpy);
ext_req->fbconfig = be_FBConfig->id;
ext_req->pixmap = (unsigned int)be_pixmap;
ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
UnlockDisplay(dpy);
SyncHandle();
}
else if (pGlxVisual) {
LockDisplay(dpy);
pGlxPixmap->be_xids[s] = XAllocID(dpy);
GetReq(GLXCreateGLXPixmap,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXCreateGLXPixmap;
be_req->screen = DefaultScreen(dpy);
be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList(
pGlxVisual,
dmxScreen->glxVisuals,
dmxScreen->numGlxVisuals );
be_req->pixmap = (unsigned int)be_pixmap;
be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
UnlockDisplay(dpy);
SyncHandle();
}
else {
client->errorValue = ( visual ? visual : fbconfigId );
__glXFree( pGlxPixmap );
return BadValue;
}
XFlush( dpy );
}
if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
__glXFree( pGlxPixmap );
return BadAlloc;
}
return Success;
}
int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
return( CreateGLXPixmap(cl, req->visual, None,
req->screen, req->pixmap, req->glxpixmap) );
}
int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
return( CreateGLXPixmap(cl, None, req->fbconfig,
req->screen, req->pixmap, req->glxpixmap) );
}
int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
XID glxpixmap = req->glxpixmap;
__GLXpixmap *pGlxPixmap;
int s;
int from_screen, to_screen;
/*
** Check if it's a valid GLX pixmap.
*/
pGlxPixmap = (__GLXpixmap *)LookupIDByType(glxpixmap, __glXPixmapRes);
if (!pGlxPixmap) {
client->errorValue = glxpixmap;
return __glXBadPixmap;
}
FreeResource(glxpixmap, FALSE);
/*
* destroy the pixmap on the back-end server(s).
*/
from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
for (s=from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
/* make sure pixmap exist in back-end */
dmxSync( dmxScreen, 1 );
LockDisplay(dpy);
GetReq(GLXDestroyGLXPixmap,req);
req->reqType = dmxScreen->glxMajorOpcode;
req->glxCode = X_GLXDestroyGLXPixmap;
req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
UnlockDisplay(dpy);
SyncHandle();
}
return Success;
}
/*****************************************************************************/
/*
** 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.
*/
int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag)
{
ClientPtr client = cl->client;
DrawablePtr pDraw;
xGLXSwapBuffersReq *be_req;
WindowPtr pWin = NULL;
__GLXpixmap *pGlxPixmap = NULL;
__GLXcontext *glxc = NULL;
#ifdef PANORAMIX
PanoramiXRes *pXinDraw = NULL;
#endif
__glXWindow *pGlxWindow = NULL;
int from_screen = 0;
int to_screen = 0;
int s, rc;
/*
** Check that the GLX drawable is valid.
*/
rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
if (rc == Success) {
from_screen = to_screen = pDraw->pScreen->myNum;
if (pDraw->type == DRAWABLE_WINDOW) {
/*
** Drawable is an X window.
*/
pWin = (WindowPtr)pDraw;
} else {
/*
** Drawable is an X pixmap, which is not allowed.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
}
if (!pDraw) {
pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
__glXPixmapRes);
if (pGlxPixmap) {
/*
** Drawable is a GLX pixmap.
*/
pDraw = pGlxPixmap->pDraw;
from_screen = to_screen = pGlxPixmap->pScreen->myNum;
}
}
if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
if (pGlxWindow) {
/*
** Drawable is a GLXWindow.
*/
pDraw = pGlxWindow->pDraw;
from_screen = to_screen = pGlxWindow->pScreen->myNum;
}
}
if (!pDraw) {
/*
** Drawable is neither a X window nor a GLX pixmap.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
if (tag) {
glxc = __glXLookupContextByTag(cl, tag);
if (!glxc) {
return __glXBadContextTag;
}
}
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
pXinDraw = (PanoramiXRes *)
SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
}
#endif
/* If requested, send a glFinish to all back-end servers before swapping. */
if (dmxGLXFinishSwap) {
for (s=from_screen; s<=to_screen; s++) {
Display *dpy = GetBackEndDisplay(cl,s);
DMXScreenInfo *dmxScreen = &dmxScreens[s];
xGLXSingleReq *finishReq;
xGLXSingleReply reply;
#define X_GLXSingle 0 /* needed by GetReq below */
LockDisplay(dpy);
GetReq(GLXSingle,finishReq);
finishReq->reqType = dmxScreen->glxMajorOpcode;
finishReq->glxCode = X_GLsop_Finish;
finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0);
(void) _XReply(dpy, (xReply*) &reply, 0, False);
UnlockDisplay(dpy);
SyncHandle();
}
}
/* If requested, send an XSync to all back-end servers before swapping. */
if (dmxGLXSyncSwap) {
for (s=from_screen; s<=to_screen; s++)
XSync(GetBackEndDisplay(cl,s), False);
}
/* send the SwapBuffers request to all back-end servers */
for (s=from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
unsigned int be_draw = 0;
if (pGlxPixmap) {
be_draw = (unsigned int)pGlxPixmap->be_xids[s];
}
#ifdef PANORAMIX
else if (pXinDraw) {
dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
}
#endif
else if (pGlxWindow) {
pWin = (WindowPtr)pGlxWindow->pDraw;
}
if (pWin && !be_draw) {
be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
if (!be_draw) {
/* it might be that the window did not created yet on the */
/* back-end server (lazy window creation option), force */
/* creation of the window */
dmxCreateAndRealizeWindow( pWin, TRUE );
be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
}
}
dmxSync( dmxScreen, 1 );
LockDisplay(dpy);
GetReq(GLXSwapBuffers,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXSwapBuffers;
be_req->drawable = be_draw;
be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 );
UnlockDisplay(dpy);
SyncHandle();
XFlush(dpy);
}
return Success;
}
int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
DrawablePtr pDraw;
xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
GLXContextTag tag = req->contextTag;
XID drawId = req->drawable;
__GLXpixmap *pGlxPixmap = NULL;
__GLXcontext *glxc = NULL;
__glXWindow *pGlxWindow = NULL;
int rc;
/*
** Check that the GLX drawable is valid.
*/
rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
if (rc == Success) {
if (pDraw->type != DRAWABLE_WINDOW) {
/*
** Drawable is an X pixmap, which is not allowed.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
}
if (!pDraw) {
pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
__glXPixmapRes);
if (pGlxPixmap) {
/*
** Drawable is a GLX pixmap.
*/
pDraw = pGlxPixmap->pDraw;
}
}
if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
if (pGlxWindow) {
/*
** Drawable is a GLXWindow.
*/
pDraw = pGlxWindow->pDraw;
}
}
if (!pDraw) {
/*
** Drawable is neither a X window nor a GLX pixmap.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
if (tag) {
glxc = __glXLookupContextByTag(cl, tag);
if (!glxc) {
return __glXBadContextTag;
}
}
if (pDraw &&
pDraw->type == DRAWABLE_WINDOW &&
DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) {
return SGSwapBuffers(cl, drawId, tag, pDraw);
}
return __glXDoSwapBuffers(cl, drawId, tag);
}
/************************************************************************/
/*
** Render and Renderlarge are not in the GLX API. They are used by the GLX
** client library to send batches of GL rendering commands.
*/
/*
** Execute all the drawing commands in a request.
*/
int __glXRender(__GLXclientState *cl, GLbyte *pc)
{
xGLXRenderReq *req;
xGLXRenderReq *be_req;
int size;
__GLXcontext *glxc;
int from_screen = 0;
int to_screen = 0;
int s;
/*
** NOTE: much of this code also appears in the byteswapping version of this
** routine, __glXSwapRender(). Any changes made here should also be
** duplicated there.
*/
req = (xGLXRenderReq *) pc;
glxc = __glXLookupContextByTag(cl, req->contextTag);
if (!glxc) {
return 0;
}
from_screen = to_screen = glxc->pScreen->myNum;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
pc += sz_xGLXRenderReq;
size = (req->length << 2) - sz_xGLXRenderReq;
/*
* just forward the request to back-end server(s)
*/
for (s=from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
LockDisplay(dpy);
GetReq(GLXRender,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXRender;
be_req->length = req->length;
be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
_XSend(dpy, (const char *)pc, size);
UnlockDisplay(dpy);
SyncHandle();
}
return Success;
}
/*
** Execute a large rendering request (one that spans multiple X requests).
*/
int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc)
{
xGLXRenderLargeReq *req;
xGLXRenderLargeReq *be_req;
__GLXcontext *glxc;
int from_screen = 0;
int to_screen = 0;
int s;
/*
** NOTE: much of this code also appears in the byteswapping version of this
** routine, __glXSwapRenderLarge(). Any changes made here should also be
** duplicated there.
*/
req = (xGLXRenderLargeReq *) pc;
glxc = __glXLookupContextByTag(cl, req->contextTag);
if (!glxc) {
return 0;
}
from_screen = to_screen = glxc->pScreen->myNum;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
pc += sz_xGLXRenderLargeReq;
/*
* just forward the request to back-end server(s)
*/
for (s=from_screen; s<=to_screen; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
GetReq(GLXRenderLarge,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXRenderLarge;
be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
be_req->length = req->length;
be_req->requestNumber = req->requestNumber;
be_req->requestTotal = req->requestTotal;
be_req->dataBytes = req->dataBytes;
Data(dpy, (const char *)pc, req->dataBytes);
UnlockDisplay(dpy);
SyncHandle();
}
return Success;
}
/************************************************************************/
int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
{
xGLXVendorPrivateReq *req;
req = (xGLXVendorPrivateReq *) pc;
switch( req->vendorCode ) {
case X_GLvop_DeleteTexturesEXT:
return __glXVForwardSingleReq( cl, pc );
break;
case X_GLXvop_SwapIntervalSGI:
if (glxIsExtensionSupported("SGI_swap_control")) {
return __glXVForwardSingleReq( cl, pc );
}
else {
return Success;
}
break;
#if 0 /* glx 1.3 */
case X_GLXvop_CreateGLXVideoSourceSGIX:
break;
case X_GLXvop_DestroyGLXVideoSourceSGIX:
break;
case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
break;
case X_GLXvop_DestroyGLXPbufferSGIX:
break;
case X_GLXvop_ChangeDrawableAttributesSGIX:
break;
#endif
case X_GLXvop_BindSwapBarrierSGIX:
return __glXBindSwapBarrierSGIX( cl, pc );
break;
case X_GLXvop_JoinSwapGroupSGIX:
return __glXJoinSwapGroupSGIX( cl, pc );
break;
case X_GLXvop_CreateContextWithConfigSGIX:
return __glXCreateContextWithConfigSGIX( cl, pc );
break;
default:
/*
** unsupported private request
*/
cl->client->errorValue = req->vendorCode;
return __glXUnsupportedPrivateRequest;
}
cl->client->errorValue = req->vendorCode;
return __glXUnsupportedPrivateRequest;
}
int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
{
xGLXVendorPrivateWithReplyReq *req;
req = (xGLXVendorPrivateWithReplyReq *) pc;
switch( req->vendorCode ) {
case X_GLvop_GetConvolutionFilterEXT:
case X_GLvop_GetConvolutionParameterfvEXT:
case X_GLvop_GetConvolutionParameterivEXT:
case X_GLvop_GetSeparableFilterEXT:
case X_GLvop_GetHistogramEXT:
case X_GLvop_GetHistogramParameterivEXT:
case X_GLvop_GetMinmaxEXT:
case X_GLvop_GetMinmaxParameterfvEXT:
case X_GLvop_GetMinmaxParameterivEXT:
case X_GLvop_AreTexturesResidentEXT:
case X_GLvop_IsTextureEXT:
return( __glXVForwardPipe0WithReply(cl, pc) );
break;
case X_GLvop_GenTexturesEXT:
return( __glXVForwardAllWithReply(cl, pc) );
break;
#if 0 /* glx1.3 */
case X_GLvop_GetDetailTexFuncSGIS:
case X_GLvop_GetSharpenTexFuncSGIS:
case X_GLvop_GetColorTableSGI:
case X_GLvop_GetColorTableParameterfvSGI:
case X_GLvop_GetColorTableParameterivSGI:
case X_GLvop_GetTexFilterFuncSGIS:
case X_GLvop_GetInstrumentsSGIX:
case X_GLvop_InstrumentsBufferSGIX:
case X_GLvop_PollInstrumentsSGIX:
case X_GLvop_FlushRasterSGIX:
case X_GLXvop_CreateGLXPbufferSGIX:
case X_GLXvop_GetDrawableAttributesSGIX:
case X_GLXvop_QueryHyperpipeNetworkSGIX:
case X_GLXvop_QueryHyperpipeConfigSGIX:
case X_GLXvop_HyperpipeConfigSGIX:
case X_GLXvop_DestroyHyperpipeConfigSGIX:
#endif
case X_GLXvop_QueryMaxSwapBarriersSGIX:
return( __glXQueryMaxSwapBarriersSGIX(cl, pc) );
break;
case X_GLXvop_GetFBConfigsSGIX:
return( __glXGetFBConfigsSGIX(cl, pc) );
break;
case X_GLXvop_MakeCurrentReadSGI:
return( __glXMakeCurrentReadSGI(cl, pc) );
break;
case X_GLXvop_QueryContextInfoEXT:
return( __glXQueryContextInfoEXT(cl,pc) );
break;
default:
/*
** unsupported private request
*/
cl->client->errorValue = req->vendorCode;
return __glXUnsupportedPrivateRequest;
}
}
int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
xGLXQueryExtensionsStringReply reply;
GLint screen;
size_t length;
int len, numbytes;
char *be_buf;
#ifdef FWD_QUERY_REQ
xGLXQueryExtensionsStringReq *be_req;
xGLXQueryExtensionsStringReply be_reply;
DMXScreenInfo *dmxScreen;
Display *dpy;
int slop;
#endif
screen = req->screen;
/*
** Check if screen exists.
*/
if ((screen < 0) || (screen >= screenInfo.numScreens)) {
client->errorValue = screen;
return BadValue;
}
#ifdef FWD_QUERY_REQ
dmxScreen = &dmxScreens[screen];
/* Send the glXQueryServerString request */
dpy = GetBackEndDisplay(cl,screen);
LockDisplay(dpy);
GetReq(GLXQueryExtensionsString,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXQueryServerString;
be_req->screen = DefaultScreen(dpy);
_XReply(dpy, (xReply*) &be_reply, 0, False);
len = (int)be_reply.length;
numbytes = (int)be_reply.n;
slop = numbytes * __GLX_SIZE_INT8 & 3;
be_buf = (char *)Xalloc(numbytes);
if (!be_buf) {
/* Throw data on the floor */
_XEatData(dpy, len);
} else {
_XRead(dpy, (char *)be_buf, numbytes);
if (slop) _XEatData(dpy,4-slop);
}
UnlockDisplay(dpy);
SyncHandle();
#else
be_buf = __glXGetServerString(GLX_EXTENSIONS);
numbytes = strlen(be_buf) + 1;
len = __GLX_PAD(numbytes) >> 2;
#endif
length = len;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
reply.length = len;
reply.n = numbytes;
if (client->swapped) {
glxSwapQueryExtensionsStringReply(client, &reply, be_buf);
} else {
WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
WriteToClient(client, (int)(length << 2), (char *)be_buf);
}
return Success;
}
int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
xGLXQueryServerStringReply reply;
int name;
GLint screen;
size_t length;
int len, numbytes;
char *be_buf;
#ifdef FWD_QUERY_REQ
xGLXQueryServerStringReq *be_req;
xGLXQueryServerStringReply be_reply;
DMXScreenInfo *dmxScreen;
Display *dpy;
int slop;
#endif
name = req->name;
screen = req->screen;
/*
** Check if screen exists.
*/
if ((screen < 0) || (screen >= screenInfo.numScreens)) {
client->errorValue = screen;
return BadValue;
}
#ifdef FWD_QUERY_REQ
dmxScreen = &dmxScreens[screen];
/* Send the glXQueryServerString request */
dpy = GetBackEndDisplay(cl,screen);
LockDisplay(dpy);
GetReq(GLXQueryServerString,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXQueryServerString;
be_req->screen = DefaultScreen(dpy);
be_req->name = name;
_XReply(dpy, (xReply*) &be_reply, 0, False);
len = (int)be_reply.length;
numbytes = (int)be_reply.n;
slop = numbytes * __GLX_SIZE_INT8 & 3;
be_buf = (char *)Xalloc(numbytes);
if (!be_buf) {
/* Throw data on the floor */
_XEatData(dpy, len);
} else {
_XRead(dpy, (char *)be_buf, numbytes);
if (slop) _XEatData(dpy,4-slop);
}
UnlockDisplay(dpy);
SyncHandle();
#else
be_buf = __glXGetServerString(name);
numbytes = strlen(be_buf) + 1;
len = __GLX_PAD(numbytes) >> 2;
#endif
length = len;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
reply.length = length;
reply.n = numbytes;
if (client->swapped) {
glxSwapQueryServerStringReply(client, &reply, be_buf);
} else {
WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
WriteToClient(client, (int)(length << 2), be_buf);
}
return Success;
}
int __glXClientInfo(__GLXclientState *cl, GLbyte *pc)
{
xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
xGLXClientInfoReq *be_req;
const char *buf;
int from_screen = 0;
int to_screen = 0;
int s;
cl->GLClientmajorVersion = req->major;
cl->GLClientminorVersion = req->minor;
if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
buf = (const char *)(req+1);
cl->GLClientextensions = strdup(buf);
to_screen = screenInfo.numScreens - 1;
for (s=from_screen; s<=to_screen; s++)
{
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = GetBackEndDisplay(cl,s);
LockDisplay(dpy);
GetReq(GLXClientInfo,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXClientInfo;
be_req->major = req->major;
be_req->minor = req->minor;
be_req->length = req->length;
be_req->numbytes = req->numbytes;
Data(dpy, buf, req->numbytes);
UnlockDisplay(dpy);
SyncHandle();
}
return Success;
}
int __glXUseXFont(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXUseXFontReq *req;
xGLXUseXFontReq *be_req;
FontPtr pFont;
__GLXcontext *glxc = NULL;
int from_screen = 0;
int to_screen = 0;
int s;
dmxFontPrivPtr pFontPriv;
DMXScreenInfo *dmxScreen;
Display *dpy;
req = (xGLXUseXFontReq *) pc;
if (req->contextTag != 0) {
glxc = __glXLookupContextByTag(cl, req->contextTag);
if (glxc) {
from_screen = to_screen = glxc->pScreen->myNum;
}
}
/*
** Font can actually be either the ID of a font or the ID of a GC
** containing a font.
*/
pFont = (FontPtr)LookupIDByType(req->font, RT_FONT);
if (!pFont) {
GC *pGC = (GC *)LookupIDByType(req->font, RT_GC);
if (!pGC) {
client->errorValue = req->font;
return BadFont;
}
pFont = pGC->font;
}
pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
for (s=from_screen; s<=to_screen; s++) {
dmxScreen = &dmxScreens[s];
dpy = GetBackEndDisplay(cl,s);
dmxSync( dmxScreen, 1 );
LockDisplay(dpy);
GetReq(GLXUseXFont,be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXUseXFont;
be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
be_req->font = pFontPriv->font[s]->fid;
be_req->first = req->first;
be_req->count = req->count;
be_req->listBase = req->listBase;
UnlockDisplay(dpy);
SyncHandle();
XSync( dpy, False );
}
return Success;
}
/*
* start GLX 1.3 here
*/
int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
xGLXGetFBConfigsReply reply;
__GLXFBConfig *pFBConfig;
CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS];
int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS;
unsigned int screen = req->screen;
int numFBConfigs, i, p;
__GLXscreenInfo *pGlxScreen;
if (screen > screenInfo.numScreens) {
/* The client library must send a valid screen number. */
client->errorValue = screen;
return BadValue;
}
pGlxScreen = &__glXActiveScreens[screen];
numFBConfigs = __glXNumFBConfigs;
reply.numFBConfigs = numFBConfigs;
reply.numAttribs = numAttribs;
reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
if (client->swapped) {
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_SHORT(&reply.sequenceNumber);
__GLX_SWAP_INT(&reply.length);
__GLX_SWAP_INT(&reply.numFBConfigs);
__GLX_SWAP_INT(&reply.numAttribs);
}
WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
for (i=0; i < numFBConfigs; i++) {
int associatedVisualId = 0;
int drawableTypeIndex;
pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ];
p = 0;
/* core attributes */
buf[p++] = GLX_FBCONFIG_ID;
buf[p++] = pFBConfig->id;
buf[p++] = GLX_BUFFER_SIZE;
buf[p++] = pFBConfig->indexBits;
buf[p++] = GLX_LEVEL;
buf[p++] = pFBConfig->level;
buf[p++] = GLX_DOUBLEBUFFER;
buf[p++] = pFBConfig->doubleBufferMode;
buf[p++] = GLX_STEREO;
buf[p++] = pFBConfig->stereoMode;
buf[p++] = GLX_AUX_BUFFERS;
buf[p++] = pFBConfig->maxAuxBuffers;
buf[p++] = GLX_RED_SIZE;
buf[p++] = pFBConfig->redBits;
buf[p++] = GLX_GREEN_SIZE;
buf[p++] = pFBConfig->greenBits;
buf[p++] = GLX_BLUE_SIZE;
buf[p++] = pFBConfig->blueBits;
buf[p++] = GLX_ALPHA_SIZE;
buf[p++] = pFBConfig->alphaBits;
buf[p++] = GLX_DEPTH_SIZE;
buf[p++] = pFBConfig->depthBits;
buf[p++] = GLX_STENCIL_SIZE;
buf[p++] = pFBConfig->stencilBits;
buf[p++] = GLX_ACCUM_RED_SIZE;
buf[p++] = pFBConfig->accumRedBits;
buf[p++] = GLX_ACCUM_GREEN_SIZE;
buf[p++] = pFBConfig->accumGreenBits;
buf[p++] = GLX_ACCUM_BLUE_SIZE;
buf[p++] = pFBConfig->accumBlueBits;
buf[p++] = GLX_ACCUM_ALPHA_SIZE;
buf[p++] = pFBConfig->accumAlphaBits;
buf[p++] = GLX_RENDER_TYPE;
buf[p++] = pFBConfig->renderType;
buf[p++] = GLX_DRAWABLE_TYPE;
drawableTypeIndex = p;
buf[p++] = pFBConfig->drawableType;
buf[p++] = GLX_X_VISUAL_TYPE;
buf[p++] = pFBConfig->visualType;
buf[p++] = GLX_CONFIG_CAVEAT;
buf[p++] = pFBConfig->visualCaveat;
buf[p++] = GLX_TRANSPARENT_TYPE;
buf[p++] = pFBConfig->transparentType;
buf[p++] = GLX_TRANSPARENT_RED_VALUE;
buf[p++] = pFBConfig->transparentRed;
buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
buf[p++] = pFBConfig->transparentGreen;
buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
buf[p++] = pFBConfig->transparentBlue;
buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
buf[p++] = pFBConfig->transparentAlpha;
buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
buf[p++] = pFBConfig->transparentIndex;
buf[p++] = GLX_MAX_PBUFFER_WIDTH;
buf[p++] = pFBConfig->maxPbufferWidth;
buf[p++] = GLX_MAX_PBUFFER_HEIGHT;
buf[p++] = pFBConfig->maxPbufferHeight;
buf[p++] = GLX_MAX_PBUFFER_PIXELS;
buf[p++] = pFBConfig->maxPbufferPixels;
/*
* find the visual of the back-end server and match a visual
* on the proxy.
* do only once - if a visual is not yet associated.
*/
if (pFBConfig->associatedVisualId == (unsigned int)-1) {
DMXScreenInfo *dmxScreen = &dmxScreens[screen];
__GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ];
__GLXvisualConfig *pGlxVisual = NULL;
int v;
int found = 0;
for (v=0; v<dmxScreen->numGlxVisuals; v++) {
if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) {
pGlxVisual = &dmxScreen->glxVisuals[v];
break;
}
}
if (pGlxVisual) {
for (v=0; v<pGlxScreen->numVisuals; v++) {
if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) {
associatedVisualId = pGlxScreen->pGlxVisual[v].vid;
found = 1;
break;
}
}
}
if (!found) {
associatedVisualId = 0;
pFBConfig->drawableType &= ~(GLX_WINDOW_BIT);
buf[drawableTypeIndex] = pFBConfig->drawableType;
}
#ifdef PANORAMIX
else if (!noPanoramiXExtension) {
/* convert the associated visualId to the panoramix one */
for (v=0; v<255; v++) {
if ( PanoramiXVisualTable[ v * MAXSCREENS + screen ] ==
associatedVisualId ) {
associatedVisualId = v;
break;
}
}
pFBConfig->associatedVisualId = associatedVisualId;
}
#endif
}
else {
associatedVisualId = pFBConfig->associatedVisualId;
}
buf[p++] = GLX_VISUAL_ID;
buf[p++] = associatedVisualId;
/* SGIS_multisample attributes */
buf[p++] = GLX_SAMPLES_SGIS;
buf[p++] = pFBConfig->multiSampleSize;
buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
buf[p++] = pFBConfig->nMultiSampleBuffers;
/* SGIX_pbuffer specific attributes */
buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX;
buf[p++] = pFBConfig->optimalPbufferWidth;
buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX;
buf[p++] = pFBConfig->optimalPbufferHeight;
buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
buf[p++] = pFBConfig->visualSelectGroup;
if (client->swapped) {
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs);
}
WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf);
}
return Success;
}
int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
{
xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc;
xGLXGetFBConfigsReq new_req;
new_req.reqType = req->reqType;
new_req.glxCode = req->glxCode;
new_req.length = req->length;
new_req.screen = req->screen;
return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) );
}
int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
int screen = req->screen;
GLXFBConfigID fbconfigId = req->fbconfig;
XID windowId = req->window;
XID glxwindowId = req->glxwindow;
DrawablePtr pDraw;
ScreenPtr pScreen;
__glXWindow *pGlxWindow;
__GLXFBConfig *pGlxFBConfig = NULL;
VisualPtr pVisual;
VisualID visId;
int i, rc;
/*
** Check if windowId is valid
*/
rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW,
DixUnknownAccess);
if (rc != Success)
return rc;
/*
** Check if screen of window matches screen of fbconfig.
*/
pScreen = pDraw->pScreen;
if (screen != pScreen->myNum) {
return BadMatch;
}
/*
** Find the FBConfigRec for this fbconfigid.
*/
if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
client->errorValue = fbconfigId;
return __glXBadFBConfig;
}
visId = pGlxFBConfig->associatedVisualId;
/*
** Check if the fbconfig supports rendering to windows
*/
if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) {
return BadMatch;
}
if (visId != None) {
/*
** Check if the visual ID is valid for this screen.
*/
pVisual = pScreen->visuals;
for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
if (pVisual->vid == visId) {
break;
}
}
if (i == pScreen->numVisuals) {
client->errorValue = visId;
return BadValue;
}
/*
** Check if color buffer depth of fbconfig matches depth
** of window.
*/
if (pVisual->nplanes != pDraw->depth) {
return BadMatch;
}
} else
/*
** The window was created with no visual that corresponds
** to fbconfig
*/
return BadMatch;
/*
** Check if there is already a fbconfig associated with this window
*/
if ( LookupIDByType(glxwindowId, __glXWindowRes) ) {
client->errorValue = glxwindowId;
return BadAlloc;
}
pGlxWindow = (__glXWindow *) xalloc(sizeof(__glXWindow));
if (!pGlxWindow) {
return BadAlloc;
}
/*
** Register this GLX window as a resource
*/
if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) {
return BadAlloc;
}
pGlxWindow->pDraw = pDraw;
pGlxWindow->type = GLX_GLXWINDOW_TYPE;
pGlxWindow->idExists = True;
pGlxWindow->refcnt = 0;
pGlxWindow->pGlxFBConfig = pGlxFBConfig;
pGlxWindow->pScreen = pScreen;
return Success;
}
int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
XID glxwindow = req->glxwindow;
/*
** Check if it's a valid GLX window.
*/
if (!LookupIDByType(glxwindow, __glXWindowRes)) {
client->errorValue = glxwindow;
return __glXBadDrawable;
}
/*
** The glx window destructor will check whether it's current before
** freeing anything.
*/
FreeResource(glxwindow, RT_NONE);
return Success;
}
int __glXQueryContext(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
__GLXcontext *ctx;
xGLXQueryContextReq *req;
xGLXQueryContextReply reply;
int nProps;
int *sendBuf, *pSendBuf;
int nReplyBytes;
req = (xGLXQueryContextReq *)pc;
ctx = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
if (!ctx) {
client->errorValue = req->context;
return __glXBadContext;
}
nProps = 3;
reply.length = nProps << 1;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
reply.n = nProps;
nReplyBytes = reply.length << 2;
sendBuf = (int *)xalloc(nReplyBytes);
pSendBuf = sendBuf;
*pSendBuf++ = GLX_FBCONFIG_ID;
*pSendBuf++ = (int)(ctx->pFBConfig->id);
*pSendBuf++ = GLX_RENDER_TYPE;
*pSendBuf++ = (int)(ctx->pFBConfig->renderType);
*pSendBuf++ = GLX_SCREEN;
*pSendBuf++ = (int)(ctx->pScreen->myNum);
if (client->swapped) {
__glXSwapQueryContextReply(client, &reply, sendBuf);
} else {
WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply);
WriteToClient(client, nReplyBytes, (char *)sendBuf);
}
xfree((char *)sendBuf);
return Success;
}
int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
__GLXcontext *ctx;
xGLXQueryContextInfoEXTReq *req;
xGLXQueryContextInfoEXTReply reply;
int nProps;
int *sendBuf, *pSendBuf;
int nReplyBytes;
req = (xGLXQueryContextInfoEXTReq *)pc;
ctx = (__GLXcontext *) SecurityLookupIDByType(client, req->context, __glXContextRes, DixReadAccess);
if (!ctx) {
client->errorValue = req->context;
return __glXBadContext;
}
nProps = 4;
reply.length = nProps << 1;
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
reply.n = nProps;
nReplyBytes = reply.length << 2;
sendBuf = (int *)xalloc(nReplyBytes);
pSendBuf = sendBuf;
*pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
*pSendBuf++ = (int)(ctx->share_id);
*pSendBuf++ = GLX_VISUAL_ID_EXT;
*pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0);
*pSendBuf++ = GLX_SCREEN_EXT;
*pSendBuf++ = (int)(ctx->pScreen->myNum);
*pSendBuf++ = GLX_FBCONFIG_ID;
*pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0);
if (client->swapped) {
__glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
} else {
WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
WriteToClient(client, nReplyBytes, (char *)sendBuf);
}
xfree((char *)sendBuf);
return Success;
}
int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc;
xGLXCreatePbufferReq *be_req;
int screen = req->screen;
GLXFBConfigID fbconfigId = req->fbconfig;
GLXPbuffer pbuffer = req->pbuffer;
__glXPbuffer *pGlxPbuffer;
int numAttribs = req->numAttribs;
int *attr;
ScreenPtr pScreen;
__GLXFBConfig *pGlxFBConfig;
__GLXFBConfig *be_pGlxFBConfig;
XID be_xid;
Display *dpy;
DMXScreenInfo *dmxScreen;
int s;
int from_screen, to_screen;
/*
** Look up screen and FBConfig.
*/
if (screen > screenInfo.numScreens) {
/* The client library must send a valid screen number. */
client->errorValue = screen;
return BadValue;
}
pScreen = screenInfo.screens[screen];
/*
** Find the FBConfigRec for this fbconfigid.
*/
if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
client->errorValue = fbconfigId;
return __glXBadFBConfig;
}
/*
** Create the GLX part of the Pbuffer.
*/
pGlxPbuffer = (__glXPbuffer *) xalloc(sizeof(__glXPbuffer));
if (!pGlxPbuffer) {
return BadAlloc;
}
pGlxPbuffer->be_xids = (XID *) xalloc( sizeof(XID) * screenInfo.numScreens );
if (!pGlxPbuffer->be_xids) {
xfree(pGlxPbuffer);
return BadAlloc;
}
/*
* Allocate an XID on the back-end server(s) and send him the request
*/
from_screen = to_screen = screen;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
for (s=from_screen; s<=to_screen; s++) {
dpy = GetBackEndDisplay(cl,s);
be_xid = XAllocID(dpy);
dmxScreen = &dmxScreens[s];
be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s );
attr = (int *)( req+1 );
LockDisplay(dpy);
GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXCreatePbuffer;
be_req->screen = be_pGlxFBConfig->screen;
be_req->fbconfig = be_pGlxFBConfig->id;
be_req->pbuffer = be_xid;
be_req->numAttribs = numAttribs;
/* Send attributes */
if ( attr != NULL ) {
CARD32 *pc = (CARD32 *)(be_req + 1);
while (numAttribs-- > 0) {
*pc++ = *attr++; /* token */
*pc++ = *attr++; /* value */
}
}
UnlockDisplay(dpy);
SyncHandle();
pGlxPbuffer->be_xids[s] = be_xid;
}
pGlxPbuffer->idExists = True;
pGlxPbuffer->refcnt = 0;
pGlxPbuffer->pFBConfig = pGlxFBConfig;
pGlxPbuffer->pScreen = pScreen;
/*
** Register the resource.
*/
if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) {
return BadAlloc;
}
return Success;
}
int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
{
ClientPtr client = cl->client;
xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
xGLXDestroyPbufferReq *be_req;
GLXPbuffer pbuffer = req->pbuffer;
Display *dpy;
int screen;
DMXScreenInfo *dmxScreen;
__glXPbuffer *pGlxPbuffer;
int s;
int from_screen, to_screen;
/*
** Check if it's a valid Pbuffer
*/
pGlxPbuffer = (__glXPbuffer *)LookupIDByType(pbuffer, __glXPbufferRes);
if (!pGlxPbuffer) {
client->errorValue = pbuffer;
return __glXBadPbuffer;
}
screen = pGlxPbuffer->pScreen->myNum;
from_screen = to_screen = screen;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
for (s=from_screen; s<=to_screen; s++) {
dpy = GetBackEndDisplay(cl,s);
dmxScreen = &dmxScreens[s];
/* send the destroy request to the back-end server */
LockDisplay(dpy);
GetReq(GLXDestroyPbuffer, be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXDestroyPbuffer;
be_req->pbuffer = pGlxPbuffer->be_xids[s];
UnlockDisplay(dpy);
SyncHandle();
}
FreeResource(pbuffer, RT_NONE);
return Success;
}
int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
{
xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
xGLXGetDrawableAttributesReq *be_req;
xGLXGetDrawableAttributesReply reply;
ClientPtr client = cl->client;
GLXDrawable drawId = req->drawable;
GLXDrawable be_drawable = 0;
DrawablePtr pDraw = NULL;
Display *dpy;
int screen, rc;
DMXScreenInfo *dmxScreen;
CARD32 *attribs = NULL;
int attribs_size;
#ifdef PANORAMIX
PanoramiXRes *pXinDraw = NULL;
#endif
if (drawId != None) {
rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
if (rc == Success) {
if (pDraw->type == DRAWABLE_WINDOW) {
WindowPtr pWin = (WindowPtr)pDraw;
be_drawable = 0;
screen = pWin->drawable.pScreen->myNum;
}
else {
/*
** Drawable is not a Window , GLXWindow or a GLXPixmap.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
}
if (!pDraw) {
__GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
__glXPixmapRes);
if (pGlxPixmap) {
pDraw = pGlxPixmap->pDraw;
screen = pGlxPixmap->pScreen->myNum;
be_drawable = pGlxPixmap->be_xids[screen];
}
}
if (!pDraw) {
__glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
if (pGlxWindow) {
pDraw = pGlxWindow->pDraw;
screen = pGlxWindow->pScreen->myNum;
be_drawable = 0;
}
}
if (!pDraw) {
__glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
if (pGlxPbuffer) {
pDraw = (DrawablePtr)pGlxPbuffer;
screen = pGlxPbuffer->pScreen->myNum;
be_drawable = pGlxPbuffer->be_xids[screen];
}
}
if (!pDraw) {
/*
** Drawable is not a Window , GLXWindow or a GLXPixmap.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
}
/* if the drawable is a window or GLXWindow -
* we need to find the base id on the back-end server
*/
if (!be_drawable) {
WindowPtr pWin = (WindowPtr)pDraw;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
pXinDraw = (PanoramiXRes *)
SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
if (!pXinDraw) {
client->errorValue = drawId;
return __glXBadDrawable;
}
dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
DixReadAccess);
}
#endif
if (pWin) {
be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
if (!be_drawable) {
/* it might be that the window did not created yet on the */
/* back-end server (lazy window creation option), force */
/* creation of the window */
dmxCreateAndRealizeWindow( pWin, TRUE );
be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
}
}
else {
client->errorValue = drawId;
return __glXBadDrawable;
}
}
/* send the request to the back-end server */
dpy = GetBackEndDisplay(cl,screen);
dmxScreen = &dmxScreens[screen];
/* make sure drawable exists on back-end */
dmxSync( dmxScreen, 1 );
LockDisplay(dpy);
GetReq(GLXGetDrawableAttributes, be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXGetDrawableAttributes;
be_req->drawable = be_drawable;
be_req->length = req->length;
if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
UnlockDisplay(dpy);
SyncHandle();
return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
}
if (reply.numAttribs) {
attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32;
attribs = (CARD32 *) Xalloc(attribs_size);
if (attribs == NULL) {
UnlockDisplay(dpy);
SyncHandle();
return BadAlloc;
}
_XRead(dpy, (char *) attribs, attribs_size);
}
UnlockDisplay(dpy);
SyncHandle();
/* send the reply back to the client */
reply.sequenceNumber = client->sequence;
if (client->swapped) {
__glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs);
}
else {
WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply);
WriteToClient(client, attribs_size, (char *)attribs);
}
Xfree(attribs);
return Success;
}
int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
{
xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc;
xGLXChangeDrawableAttributesReq *be_req;
ClientPtr client = cl->client;
GLXDrawable drawId = req->drawable;
GLXDrawable be_drawable = 0;
DrawablePtr pDraw = NULL;
Display *dpy;
int screen, rc;
DMXScreenInfo *dmxScreen;
char *attrbuf;
#ifdef PANORAMIX
PanoramiXRes *pXinDraw = NULL;
PanoramiXRes *pXinReadDraw = NULL;
#endif
if (drawId != None) {
rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess);
if (rc == Success) {
if (pDraw->type == DRAWABLE_WINDOW) {
WindowPtr pWin = (WindowPtr)pDraw;
be_drawable = 0;
screen = pWin->drawable.pScreen->myNum;
}
else {
/*
** Drawable is not a Window , GLXWindow or a GLXPixmap.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
}
if (!pDraw) {
__GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
__glXPixmapRes);
if (pGlxPixmap) {
pDraw = pGlxPixmap->pDraw;
screen = pGlxPixmap->pScreen->myNum;
be_drawable = pGlxPixmap->be_xids[screen];
}
}
if (!pDraw) {
__glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
if (pGlxWindow) {
pDraw = pGlxWindow->pDraw;
screen = pGlxWindow->pScreen->myNum;
be_drawable = 0;
}
}
if (!pDraw) {
__glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
if (pGlxPbuffer) {
pDraw = (DrawablePtr)pGlxPbuffer;
screen = pGlxPbuffer->pScreen->myNum;
be_drawable = pGlxPbuffer->be_xids[screen];
}
}
if (!pDraw) {
/*
** Drawable is not a Window , GLXWindow or a GLXPixmap.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
}
/* if the drawable is a window or GLXWindow -
* we need to find the base id on the back-end server
*/
if (!be_drawable) {
WindowPtr pWin = (WindowPtr)pDraw;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
pXinDraw = (PanoramiXRes *)
SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
if (!pXinDraw) {
client->errorValue = drawId;
return __glXBadDrawable;
}
dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
DixReadAccess);
}
#endif
if (pWin) {
be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
if (!be_drawable) {
/* it might be that the window did not created yet on the */
/* back-end server (lazy window creation option), force */
/* creation of the window */
dmxCreateAndRealizeWindow( pWin, TRUE );
be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
}
}
else {
client->errorValue = drawId;
return __glXBadDrawable;
}
}
/* send the request to the back-end server */
dpy = GetBackEndDisplay(cl,screen);
dmxScreen = &dmxScreens[screen];
/* make sure drawable exists on back-end */
dmxSync( dmxScreen, 1 );
LockDisplay(dpy);
GetReqExtra(GLXChangeDrawableAttributes,
2 * req->numAttribs * __GLX_SIZE_CARD32, be_req);
be_req->reqType = dmxScreen->glxMajorOpcode;
be_req->glxCode = X_GLXChangeDrawableAttributes;
be_req->drawable = be_drawable;
be_req->numAttribs = req->numAttribs;
be_req->length = req->length;
UnlockDisplay(dpy);
SyncHandle();
return Success;
}
int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag)
{
ClientPtr client = cl->client;
xGLXRenderLargeReq *req;
GLint maxSize, amount;
GLint totalRequests, requestNumber;
GLint dataLen;
GLbyte *data;
__GLXcontext *glxc;
int s;
int from_screen, to_screen;
maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq);
dataLen = cl->largeCmdBytesTotal;
totalRequests = (dataLen / maxSize);
if (dataLen % maxSize) totalRequests++;
glxc = __glXLookupContextByTag(cl, contextTag);
if (!glxc) {
client->errorValue = contextTag;
return __glXBadContext;
}
from_screen = to_screen = glxc->pScreen->myNum;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
from_screen = 0;
to_screen = screenInfo.numScreens - 1;
}
#endif
/*
** Send enough requests until the whole array is sent.
*/
requestNumber = 1;
data = cl->largeCmdBuf;
while (dataLen > 0) {
amount = dataLen;
if (amount > maxSize) {
amount = maxSize;
}
for (s=from_screen; s<=to_screen; s++) {
Display *dpy = GetBackEndDisplay(cl,s);
DMXScreenInfo *dmxScreen = &dmxScreens[s];
LockDisplay(dpy);
GetReq(GLXRenderLarge,req);
req->reqType = dmxScreen->glxMajorOpcode;
req->glxCode = X_GLXRenderLarge;
req->contextTag = GetCurrentBackEndTag(cl,contextTag,s);
req->length += (amount + 3) >> 2;
req->requestNumber = requestNumber++;
req->requestTotal = totalRequests;
req->dataBytes = amount;
Data(dpy, ((const char*)data), amount);
dataLen -= amount;
data = ((GLbyte *) data) + amount;
UnlockDisplay(dpy);
SyncHandle();
}
}
return Success;
}
|