xserver-multidpi/hw/dmx/glxProxy/glxcmds.c
Keith Packard 9838b7032e Introduce a consistent coding style
This is strictly the application of the script 'x-indent-all.sh'
from util/modular. Compared to the patch that Daniel posted in
January, I've added a few indent flags:

	-bap
	-psl
	-T PrivatePtr
	-T pmWait
	-T _XFUNCPROTOBEGIN
	-T _XFUNCPROTOEND
	-T _X_EXPORT

The typedefs were needed to make the output of sdksyms.sh match the
previous output, otherwise, the code is formatted badly enough that
sdksyms.sh generates incorrect output.

The generated code was compared with the previous version and found to
be essentially identical -- "assert" line numbers and BUILD_TIME were
the only differences found.

The comparison was done with this script:

dir1=$1
dir2=$2

for dir in $dir1 $dir2; do
	(cd $dir && find . -name '*.o' | while read file; do
		dir=`dirname $file`
		base=`basename $file .o`
		dump=$dir/$base.dump
		objdump -d $file > $dump
	done)
done

find $dir1 -name '*.dump' | while read dump; do
	otherdump=`echo $dump | sed "s;$dir1;$dir2;"`
	diff -u $dump $otherdump
done

Signed-off-by: Keith Packard <keithp@keithp.com>
Acked-by: Daniel Stone <daniel@fooishbar.org>
Acked-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2012-03-21 13:54:42 -07:00

3824 lines
112 KiB
C

/*
* 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.
*/
#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"
#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"
#include "glxcmds.h"
#ifdef PANORAMIX
#include "panoramiXsrv.h"
#endif
extern __GLXFBConfig **__glXFBConfigs;
extern int __glXNumFBConfigs;
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) )
static __GLXFBConfig *
glxLookupFBConfig(GLXFBConfigID id)
{
int i, j;
for (i = 0, j = 0; i < __glXNumFBConfigs;
i++, j += (__glXNumActiveScreens + 1)) {
if (__glXFBConfigs[j]->id == id)
return __glXFBConfigs[j];
}
return NULL;
}
static __GLXFBConfig *
glxLookupFBConfigByVID(VisualID vid)
{
int i, j;
for (i = 0, j = 0; i < __glXNumFBConfigs;
i++, j += (__glXNumActiveScreens + 1)) {
if (__glXFBConfigs[j]->associatedVisualId == vid)
return __glXFBConfigs[j];
}
return NULL;
}
static __GLXFBConfig *
glxLookupBackEndFBConfig(GLXFBConfigID id, int screen)
{
int i;
int j;
for (i = 0, j = 0; i < __glXNumFBConfigs;
i++, j += (__glXNumActiveScreens + 1)) {
if (__glXFBConfigs[j]->id == id)
return __glXFBConfigs[j + screen + 1];
}
return NULL;
}
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 = 0;
GLXFBConfigID be_fbconfigId = 0;
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 {
dixLookupResourceByType((pointer *) &shareglxc, shareList,
__glXContextRes, NullClient, DixUnknownAccess);
if (!shareglxc) {
client->errorValue = shareList;
return __glXBadContext;
}
}
/*
** Allocate memory for the new context
*/
glxc = calloc(1, sizeof(__GLXcontext));
if (!glxc) {
return BadAlloc;
}
pScreen = screenInfo.screens[screen];
pGlxScreen = &__glXActiveScreens[screen];
if (fbconfigId != None) {
glxc->pFBConfig = glxLookupFBConfig(fbconfigId);
if (!glxc->pFBConfig) {
client->errorValue = fbconfigId;
free(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;
free(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;
free(glxc);
return BadValue;
}
if (glxc->pFBConfig == NULL) {
glxc->pFBConfig = glxLookupFBConfigByVID(visual);
if (glxc->pFBConfig == NULL) {
/*
* visual does not have an FBConfig ???
client->errorValue = visual;
free( 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 *) malloc(sizeof(XID) * num_be_screens);
if (!glxc->real_ids) {
return BadAlloc;
}
glxc->real_vids = (XID *) malloc(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 */
free(glxc->real_ids);
free(glxc->real_vids);
free(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)) {
free(glxc->real_ids);
free(glxc->real_vids);
free(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, DixGetAttrAccess);
if (rc != Success) {
dixLookupResourceByType((pointer *) &pGlxPixmap, req->drawable,
__glXPixmapRes, NullClient, DixUnknownAccess);
if (pGlxPixmap)
pDraw = pGlxPixmap->pDraw;
}
if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
dixLookupResourceByType((pointer *) &pGlxWindow, req->drawable,
__glXWindowRes, NullClient, DixUnknownAccess);
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, DixManageAccess);
if (rc != Success) {
dixLookupResourceByType((pointer *) &pGlxPixmap, req->drawable,
__glXPixmapRes, NullClient, DixUnknownAccess);
if (pGlxPixmap)
pDraw = pGlxPixmap->pDraw;
}
if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
dixLookupResourceByType((pointer *) &pGlxWindow, req->drawable,
__glXWindowRes, NullClient, DixUnknownAccess);
if (pGlxWindow)
pDraw = pGlxWindow->pDraw;
}
if (!pDraw) {
client->errorValue = req->drawable;
return __glXBadDrawable;
}
if (req->member != None) {
rc = dixLookupDrawable(&pMember, req->member, client, 0,
DixGetAttrAccess);
if (rc != Success) {
dixLookupResourceByType((pointer *) &pGlxPixmap, req->member,
__glXPixmapRes, NullClient,
DixUnknownAccess);
if (pGlxPixmap)
pMember = pGlxPixmap->pDraw;
}
if (!pMember && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
dixLookupResourceByType((pointer *) &pGlxWindow, req->member,
__glXWindowRes, NullClient,
DixUnknownAccess);
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;
dixLookupResourceByType((pointer *) &glxc, gcId, __glXContextRes,
NullClient, DixUnknownAccess);
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 **) malloc(sizeof(__GLXcontext *));
cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr));
cl->be_currentCTag =
(GLXContextTag *) malloc(screenInfo.numScreens *
sizeof(GLXContextTag));
}
else {
table = (__GLXcontext **) realloc(table,
(num + 1) * sizeof(__GLXcontext *));
cl->currentDrawables = (DrawablePtr *) realloc(cl->currentDrawables,
(num +
1) *
sizeof(DrawablePtr));
cl->be_currentCTag =
(GLXContextTag *) realloc(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) {
dixLookupResourceByType((pointer *) &glxc, contextId, __glXContextRes,
NullClient, DixUnknownAccess);
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, DixWriteAccess);
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) {
dixLookupResourceByType((pointer *) &pGlxPixmap, drawId,
__glXPixmapRes, NullClient,
DixUnknownAccess);
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)) {
dixLookupResourceByType((pointer *) &pGlxWindow, drawId,
__glXWindowRes, NullClient,
DixUnknownAccess);
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)) {
dixLookupResourceByType((pointer *) &pGlxPbuffer, drawId,
__glXPbufferRes, NullClient,
DixUnknownAccess);
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, DixReadAccess);
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) {
dixLookupResourceByType((pointer *) &pReadGlxPixmap, readId,
__glXPixmapRes, NullClient,
DixUnknownAccess);
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)) {
dixLookupResourceByType((pointer *) &pGlxReadWindow, readId,
__glXWindowRes, NullClient,
DixUnknownAccess);
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)) {
dixLookupResourceByType((pointer *) &pGlxReadPbuffer, readId,
__glXPbufferRes, NullClient,
DixUnknownAccess);
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) {
/*
** 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) {
/*
** 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) {
/*
** 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->refcnt++;
}
if (pGlxWindow) {
pGlxWindow->refcnt++;
}
if (pGlxReadWindow) {
pGlxReadWindow->refcnt++;
}
if (pGlxPbuffer) {
pGlxPbuffer->refcnt++;
}
if (pGlxReadPbuffer) {
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) {
dixLookupResourceByClass((pointer *) &pXinDraw,
pDraw->id, XRC_DRAWABLE,
client, DixReadAccess);
}
if (pReadDraw && pReadDraw != pDraw &&
new_reply.readType != GLX_PBUFFER_TYPE) {
dixLookupResourceByClass((pointer *) &pXinReadDraw,
pReadDraw->id, XRC_DRAWABLE,
client, 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.
*/
dixLookupResourceByType((pointer *) &glxc, req->context, __glXContextRes,
NullClient, DixUnknownAccess);
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.
*/
dixLookupResourceByType((pointer *) &src, source, __glXContextRes,
NullClient, DixUnknownAccess);
if (!src) {
client->errorValue = source;
return __glXBadContext;
}
dixLookupResourceByType((pointer *) &dst, dest, __glXContextRes,
NullClient, DixUnknownAccess);
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,
DixAddAccess);
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 == 0 && visual == 0) {
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;
pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum];
}
pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap));
if (!pGlxPixmap) {
return BadAlloc;
}
pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens);
if (!pGlxPixmap->be_xids) {
free(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;
dixLookupResourceByClass((pointer *) &pXinDraw,
pDraw->id, XRC_DRAWABLE,
client, 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,
DixAddAccess);
}
#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);
free(pGlxPixmap);
return BadValue;
}
XFlush(dpy);
}
if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
free(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.
*/
dixLookupResourceByType((pointer *) &pGlxPixmap, glxpixmap,
__glXPixmapRes, NullClient, DixUnknownAccess);
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, DixWriteAccess);
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) {
dixLookupResourceByType((pointer *) &pGlxPixmap, drawId,
__glXPixmapRes, NullClient, DixUnknownAccess);
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)) {
dixLookupResourceByType((pointer *) &pGlxWindow, drawId,
__glXWindowRes, NullClient, DixUnknownAccess);
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;
dixLookupResourceByClass((pointer *) &pXinDraw,
pDraw->id, XRC_DRAWABLE,
client, 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, DixWriteAccess);
if (rc == Success) {
if (pDraw->type != DRAWABLE_WINDOW) {
/*
** Drawable is an X pixmap, which is not allowed.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
}
if (!pDraw) {
dixLookupResourceByType((pointer *) &pGlxPixmap, drawId,
__glXPixmapRes, NullClient, DixUnknownAccess);
if (pGlxPixmap) {
/*
** Drawable is a GLX pixmap.
*/
pDraw = pGlxPixmap->pDraw;
}
}
if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
dixLookupResourceByType((pointer *) &pGlxWindow, drawId,
__glXWindowRes, NullClient, DixUnknownAccess);
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 *) malloc(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 *) malloc(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;
free(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.
*/
dixLookupResourceByType((pointer *) &pFont, req->font, RT_FONT,
NullClient, DixUnknownAccess);
if (!pFont) {
GC *pGC;
dixLookupResourceByType((pointer *) &pGC, req->font,
RT_GC, NullClient, DixUnknownAccess);
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 */
pFBConfig->associatedVisualId =
PanoramiXTranslateVisualID(screen, v);
}
#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_DECLARE_SWAP_ARRAY_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;
pointer val;
/*
** Check if windowId is valid
*/
rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW,
DixAddAccess);
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 (Success == dixLookupResourceByType(&val,
glxwindowId, __glXWindowRes,
NullClient, DixUnknownAccess)) {
client->errorValue = glxwindowId;
return BadAlloc;
}
pGlxWindow = (__glXWindow *) malloc(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;
pointer val;
/*
** Check if it's a valid GLX window.
*/
if (Success != dixLookupResourceByType(&val,
glxwindow, __glXWindowRes,
NullClient, DixUnknownAccess)) {
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;
dixLookupResourceByType((pointer *) &ctx, req->context, __glXContextRes,
NullClient, DixUnknownAccess);
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 *) malloc(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);
}
free((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;
dixLookupResourceByType((pointer *) &ctx,
req->context, __glXContextRes,
client, 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 *) malloc(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);
}
free((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 *) malloc(sizeof(__glXPbuffer));
if (!pGlxPbuffer) {
return BadAlloc;
}
pGlxPbuffer->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens);
if (!pGlxPbuffer->be_xids) {
free(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
*/
dixLookupResourceByType((pointer *) &pGlxPbuffer, pbuffer,
__glXPbufferRes, NullClient, DixUnknownAccess);
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 = 0;
#ifdef PANORAMIX
PanoramiXRes *pXinDraw = NULL;
#endif
if (drawId != None) {
rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
if (rc == Success && 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;
dixLookupResourceByType((pointer *) &pGlxPixmap,
drawId, __glXPixmapRes,
NullClient, DixUnknownAccess);
if (pGlxPixmap) {
pDraw = pGlxPixmap->pDraw;
screen = pGlxPixmap->pScreen->myNum;
be_drawable = pGlxPixmap->be_xids[screen];
}
}
if (!pDraw) {
__glXWindow *pGlxWindow;
dixLookupResourceByType((pointer *) &pGlxWindow,
drawId, __glXWindowRes,
NullClient, DixUnknownAccess);
if (pGlxWindow) {
pDraw = pGlxWindow->pDraw;
screen = pGlxWindow->pScreen->myNum;
be_drawable = 0;
}
}
if (!pDraw) {
__glXPbuffer *pGlxPbuffer;
dixLookupResourceByType((pointer *) &pGlxPbuffer,
drawId, __glXPbufferRes,
NullClient, DixUnknownAccess);
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) {
if (Success != dixLookupResourceByClass((pointer *) &pXinDraw,
pDraw->id, XRC_DRAWABLE,
client, DixReadAccess)) {
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 *) malloc(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);
}
free(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;
if (drawId != None) {
rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess);
if (rc == Success && pDraw->type == DRAWABLE_WINDOW) {
be_drawable = 0;
screen = pDraw->pScreen->myNum;
}
else {
/*
** Drawable is not a Window , GLXWindow or a GLXPixmap.
*/
client->errorValue = drawId;
return __glXBadDrawable;
}
if (!pDraw) {
__GLXpixmap *pGlxPixmap;
dixLookupResourceByType((pointer *) &pGlxPixmap,
drawId, __glXPixmapRes,
NullClient, DixUnknownAccess);
if (pGlxPixmap) {
pDraw = pGlxPixmap->pDraw;
screen = pGlxPixmap->pScreen->myNum;
be_drawable = pGlxPixmap->be_xids[screen];
}
}
if (!pDraw) {
__glXWindow *pGlxWindow;
dixLookupResourceByType((pointer *) &pGlxWindow,
drawId, __glXWindowRes,
NullClient, DixUnknownAccess);
if (pGlxWindow) {
pDraw = pGlxWindow->pDraw;
screen = pGlxWindow->pScreen->myNum;
be_drawable = 0;
}
}
if (!pDraw) {
__glXPbuffer *pGlxPbuffer;
dixLookupResourceByType((pointer *) &pGlxPbuffer,
drawId, __glXPbufferRes,
NullClient, DixUnknownAccess);
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) {
PanoramiXRes *pXinDraw;
if (Success != dixLookupResourceByClass((pointer *) &pXinDraw,
pDraw->id, XRC_DRAWABLE,
client, DixReadAccess)) {
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;
}