3835 lines
112 KiB
C
3835 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 = {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = 0,
|
|
.max = QueryMaxSwapBarriersSGIX(req->screen)
|
|
};
|
|
|
|
if (client->swapped) {
|
|
__glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply);
|
|
}
|
|
else {
|
|
WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, &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 = {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = 0
|
|
};
|
|
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;
|
|
}
|
|
|
|
#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, &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 = (xGLXIsDirectReply) {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = 0,
|
|
.isDirect = 0
|
|
};
|
|
|
|
if (client->swapped) {
|
|
__glXSwapIsDirectReply(client, &reply);
|
|
}
|
|
else {
|
|
WriteToClient(client, sz_xGLXIsDirectReply, &reply);
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
int
|
|
__glXQueryVersion(__GLXclientState * cl, GLbyte * pc)
|
|
{
|
|
ClientPtr client = cl->client;
|
|
|
|
/* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */
|
|
|
|
xGLXQueryVersionReply reply = {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = 0,
|
|
/*
|
|
** 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.
|
|
*/
|
|
.majorVersion = __glXVersionMajor,
|
|
.minorVersion = __glXVersionMinor
|
|
};
|
|
|
|
if (client->swapped) {
|
|
__glXSwapQueryVersionReply(client, &reply);
|
|
}
|
|
else {
|
|
WriteToClient(client, sz_xGLXQueryVersionReply, &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 = (xGLXGetVisualConfigsReply) {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.numVisuals = pGlxScreen->numGLXVisuals,
|
|
.numProps = __GLX_TOTAL_CONFIG,
|
|
.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
|
|
__GLX_TOTAL_CONFIG) >> 2
|
|
};
|
|
|
|
WriteToClient(client, sz_xGLXGetVisualConfigsReply, &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, 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 = (xGLXQueryExtensionsStringReply) {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = len,
|
|
.n = numbytes
|
|
};
|
|
|
|
if (client->swapped) {
|
|
glxSwapQueryExtensionsStringReply(client, &reply, be_buf);
|
|
}
|
|
else {
|
|
WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply);
|
|
WriteToClient(client, (int) (length << 2), 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 = (xGLXQueryServerStringReply) {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = length,
|
|
.n = numbytes
|
|
};
|
|
|
|
if (client->swapped) {
|
|
glxSwapQueryServerStringReply(client, &reply, be_buf);
|
|
}
|
|
else {
|
|
WriteToClient(client, sz_xGLXQueryServerStringReply, &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 = (xGLXGetFBConfigsReply) {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2,
|
|
.numFBConfigs = numFBConfigs,
|
|
.numAttribs = numAttribs
|
|
};
|
|
|
|
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, &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, 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 = (xGLXQueryContextReply) {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = nProps << 1,
|
|
.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, &reply);
|
|
WriteToClient(client, nReplyBytes, 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 = (xGLXQueryContextInfoEXTReply) {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = nProps << 1,
|
|
.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, &reply);
|
|
WriteToClient(client, nReplyBytes, 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, &reply);
|
|
WriteToClient(client, attribs_size, 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;
|
|
}
|